Salome HOME
documentation html - première version
authorcrouzet <crouzet>
Fri, 5 Dec 2003 14:12:14 +0000 (14:12 +0000)
committercrouzet <crouzet>
Fri, 5 Dec 2003 14:12:14 +0000 (14:12 +0000)
doc/dev_guide.html [new file with mode: 0644]
doc/dev_guide.txt [new file with mode: 0644]

diff --git a/doc/dev_guide.html b/doc/dev_guide.html
new file mode 100644 (file)
index 0000000..6ef44b4
--- /dev/null
@@ -0,0 +1,576 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.3.0: http://docutils.sourceforge.net/" />
+<title>Guide pour le développement d'un module SALOME 2 en C++</title>
+<link rel="stylesheet" href="default.css" type="text/css" />
+</head>
+<body>
+<div class="document" id="guide-pour-le-d-veloppement-d-un-module-salome-2-en-c">
+<h1 class="title">Guide pour le développement d'un module SALOME 2 en C++</h1>
+<table class="docinfo" frame="void" rules="none">
+<col class="docinfo-name" />
+<col class="docinfo-content" />
+<tbody valign="top">
+<tr class="field"><th class="docinfo-name">Auteur:</th><td class="field-body">Crouzet N.</td>
+</tr>
+</tbody>
+</table>
+<div class="contents topic" id="contents">
+<p class="topic-title"><a name="contents">Contents</a></p>
+<ul class="auto-toc simple">
+<li><a class="reference" href="#pr-sentation" id="id1" name="id1">1   Présentation</a></li>
+<li><a class="reference" href="#les-tapes-de-construction-du-module-exemple" id="id2" name="id2">2   Les étapes de construction du module exemple</a></li>
+<li><a class="reference" href="#cr-ation-de-l-arborescence-du-module" id="id3" name="id3">3   Création de l'arborescence du module</a></li>
+<li><a class="reference" href="#interface-idl" id="id4" name="id4">4   Interface idl</a></li>
+<li><a class="reference" href="#impl-mentation-c" id="id5" name="id5">5   Implémentation C++</a><ul class="auto-toc">
+<li><a class="reference" href="#les-sources" id="id6" name="id6">5.1   Les sources</a></li>
+<li><a class="reference" href="#makefile" id="id7" name="id7">5.2   Makefile</a></li>
+</ul>
+</li>
+<li><a class="reference" href="#pilotage-du-composant-depuis-python-mode-tui" id="id8" name="id8">6   Pilotage du composant depuis Python (mode TUI)</a></li>
+<li><a class="reference" href="#interface-graphique" id="id9" name="id9">7   Interface graphique</a><ul class="auto-toc">
+<li><a class="reference" href="#introduction" id="id10" name="id10">7.1   Introduction</a></li>
+<li><a class="reference" href="#choix-des-widgets" id="id11" name="id11">7.2   Choix des widgets</a><ul class="auto-toc">
+<li><a class="reference" href="#description-xml" id="id12" name="id12">7.2.1   Description xml</a></li>
+<li><a class="reference" href="#convention" id="id13" name="id13">7.2.2   Convention</a></li>
+</ul>
+</li>
+<li><a class="reference" href="#impl-mentation-de-l-ihm" id="id14" name="id14">7.3   Implémentation de l'IHM</a><ul class="auto-toc">
+<li><a class="reference" href="#gestion-des-v-nements" id="id15" name="id15">7.3.1   Gestion des évènements</a></li>
+<li><a class="reference" href="#classes-disponibles" id="id16" name="id16">7.3.2   Classes disponibles</a></li>
+<li><a class="reference" href="#gestion-du-multi-linguisme" id="id17" name="id17">7.3.3   Gestion du multi-linguisme</a></li>
+</ul>
+</li>
+</ul>
+</li>
+<li><a class="reference" href="#r-gles-syntaxiques-de-nommage" id="id18" name="id18">8   Règles syntaxiques de nommage</a></li>
+</ul>
+</div>
+<div class="section" id="pr-sentation">
+<h1><a class="toc-backref" href="#id1" name="pr-sentation">1   Présentation</a></h1>
+<p>Ce document a pour objectif de décrire les différentes étapes
+du développement d'un module SALOME 2 en C++.
+Il fait suite au document &quot;Guide pour le développement d'un module SALOME 2 en
+Python&quot;, qui documente de module PYHELLO, et en reprend la démarche :
+construction pas à pas d'un module HELLO.
+Comme de nombreux points ne sont pas repris, il est recommendé de lire ce
+document préalablement.</p>
+</div>
+<div class="section" id="les-tapes-de-construction-du-module-exemple">
+<h1><a class="toc-backref" href="#id2" name="les-tapes-de-construction-du-module-exemple">2   Les étapes de construction du module exemple</a></h1>
+<p>Le composant choisi pour illustrer le processus de construction en C++
+est le même que celui choisi pour illustrer la construction du module python :
+il implémentera donc la même interface idl Corba.
+Il sera complété par un GUI graphique écrit en Qt.</p>
+<p>Les différentes étapes du développement seront les suivantes :</p>
+<blockquote>
+<ul class="simple">
+<li>créer une arborescence de module</li>
+<li>créer un composant SALOME 2 chargeable par un container C++</li>
+<li>configurer le module pour que le composant soit connu de SALOME</li>
+<li>ajouter un GUI graphique</li>
+<li>rendre le composant utilisable dans le superviseur</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="cr-ation-de-l-arborescence-du-module">
+<h1><a class="toc-backref" href="#id3" name="cr-ation-de-l-arborescence-du-module">3   Création de l'arborescence du module</a></h1>
+<p>Dans un premier temps, on se contentera de mettre dans le module exemple un composant
+SALOME écrit en C++ qui sera chargeable par un container C++.
+Il suffit donc d'une interface idl et d'une implantation C++ du composant.
+Pour mettre en oeuvre ceci dans un module SALOME 2, il nous faut reproduire l'arborescence de
+fichier standard suivante:</p>
+<pre class="literal-block">
++ HELLO1_SRC
+  + build_configure
+  + configure.in.base
+  + Makefile.in
+  + adm_local
+    + unix
+      + make_commence.in
+      + make_omniorb.in
+      + config_files
+  + bin
+    + VERSION
+    + runAppli.in
+    + runSalome.py
+  + idl
+    + Makefile.in
+    + HELLO_Gen.idl
+  + src
+    + Makefile.in
+    + HELLO
+      + Makefile.in
+      + HELLO.cxx 
+      + HELLO.hxx 
+  + doc
+</pre>
+<p>Pour cela, on recopie l'arborescence de PYHELLO, et on modifie où nécessaire
+PYHELLO en HELLO:</p>
+<pre class="literal-block">
+cp -r PYHELLO1_SRC HELLO1_SRC
+cd HELLO1_SRC
+mv idl/PYHELLO_Gen.idl idl/HELLO_Gen.idl
+mv src/PYHELLO src/HELLO
+</pre>
+</div>
+<div class="section" id="interface-idl">
+<h1><a class="toc-backref" href="#id4" name="interface-idl">4   Interface idl</a></h1>
+<p>Dans le répertoire idl, nous modifions le fichier idl HELLO_Gen.idl : le
+module défini est renommé HELLO_ORB, et l'interface en HELLO_Gen.
+Le service rendu reste le même : à partir d'une chaine de caractères
+fournie comme unique argument, retour d'une chaine de caractères obtenue
+par concaténation de &quot;Hello, &quot; et de la chaine d'entrée.
+Ce service est spécifié par la fonction makeBanner.</p>
+<p>Un utilitaire de documentation basé sur doxygen a été mis en place pour
+compiler une documentation des services corba à partir de commentaires se
+trouvant dans les fichiers idl. Nous rajouter donc à notre idl quelques
+commentaires, en respectant le formalisme doxygen.
+Un commentaire doxygen commence par &quot;/<em>!&quot; et se finit pas &quot;</em>/&quot;.
+Pour structurer un minimum les pages générées, on les regroupes par module ou
+sujet. Dans notre exemple, nous utilisons la directive:</p>
+<pre class="literal-block">
+\ingroup EXAMPLES 
+</pre>
+<p>spécifiant que la documentation générée fait partie du groupe EXAMPLES.
+(pour plus d'information sur doxygen, consulter le site www.doxygen.org).</p>
+<p>Pour finir, nous mettons à jour le Makefile avec le nouveau nom de composant:</p>
+<pre class="literal-block">
+IDL_FILES = HELLO_Gen.idl
+</pre>
+</div>
+<div class="section" id="impl-mentation-c">
+<h1><a class="toc-backref" href="#id5" name="impl-mentation-c">5   Implémentation C++</a></h1>
+<div class="section" id="les-sources">
+<h2><a class="toc-backref" href="#id6" name="les-sources">5.1   Les sources</a></h2>
+<p>L'implémentation C++ de notre module CORBA HELLO (interface idl HELLO_Gen) est faite dans le répertoire
+/src/HELLO:</p>
+<pre class="literal-block">
+HELLO.hxx
+HELLO.cxx
+</pre>
+<p>Au début du header de notre module (HELLO.hxx), les inclusions suivantes sont
+nécessaires:</p>
+<pre class="literal-block">
+#include &lt;SALOMEconfig.h&gt;
+#include CORBA_SERVER_HEADER(HELLO_Gen)
+#include &quot;SALOME_Component_i.hxx&quot;
+</pre>
+<p>Le fichier SALOMEconfig.h contient un certain nombre de définitions utiles
+pour assurer l'indépendance du code par rapport à la version de CORBA
+utilisée. SALOME_Component_i.hxx contient l'interface de la classe
+d'implémentation C++ du composant de base Salome (idl Engines::Component).
+Enfin, la macro CORBA_SERVER_HEADER assure l'indépendance des noms de fichiers
+d'inclusion par rapport à l'implémentation de l'ORB CORBA.</p>
+<p>Après cela, nous définissons une classe d'implémentation, nommée HELLO, dérivant de
+POA_HELLO_ORB::HELLO_Gen (classe abstraite générée automatiquement par CORBA lors de la
+compilation de l'idl) et de Engines_Component_i (car l'interface idl HELLO_Gen
+dérive de Engines::Component comme tout composant Salome2). Cette classe
+contient un constructeur dont les arguments sont imposés par CORBA, un
+destructeur virtuel, et une méthode makeBanner fournissant le service souhaité:</p>
+<pre class="literal-block">
+class HELLO:
+  public POA_HELLO_ORB::HELLO_Gen,
+  public Engines_Component_i
+{
+public:
+    HELLO(CORBA::ORB_ptr orb,
+            PortableServer::POA_ptr poa,
+            PortableServer::ObjectId * contId,
+            const char *instanceName,
+            const char *interfaceName);
+    virtual ~HELLO();
+    char* makeBanner(const char* name);
+};
+</pre>
+<p>La fonction makeBanner prend comme argument et renvoit un char*, projection C++ du type CORBA/IDL
+string. 
+La documentation complète du mapping c++ de l'IDL est fournie par l'OMG sur
+son site internet : <a class="reference" href="http://www.omg.org/cgi-bin/doc?ptc/00-01-02">http://www.omg.org/cgi-bin/doc?ptc/00-01-02</a>.</p>
+<p>Enfin, nous fournissons l'interface (normalisé) de la fonction HELLOEngine_factory, qui
+sera appelée par le &quot;FactoryServer C++&quot; pour charger le composant HELLO:</p>
+<pre class="literal-block">
+extern &quot;C&quot;
+    PortableServer::ObjectId * HELLOEngine_factory(
+            CORBA::ORB_ptr orb,
+            PortableServer::POA_ptr poa,
+            PortableServer::ObjectId * contId,
+            const char *instanceName,
+            const char *interfaceName);
+</pre>
+<p>Dans le fichier source (HELLO.cxx) se trouvent les définitions 
+du constructeur et de la fonction d'instanciation
+HELLOEngine_factory (toutes deux normalisées!), et de makeBanner:</p>
+<pre class="literal-block">
+char* HELLO::makeBanner(const char* name)
+{
+    string banner=&quot;Hello, &quot;;
+    banner+=name;
+    return CORBA::string_dup(banner.c_str());
+}
+</pre>
+<p>Dans cette fonction, l'emploi de string_dup (fonction déclarée dans le
+namespace CORBA) n'est pas obligatoire (on aurait pu utiliser l'opérateur new),
+mais conseillé car ces fonctions permettent aux ORB d'utiliser des mécanismes
+spéciaux de gestion de la mémoire sans avoir à redéfinir les opérateurs new
+globaux.</p>
+</div>
+<div class="section" id="makefile">
+<h2><a class="toc-backref" href="#id7" name="makefile">5.2   Makefile</a></h2>
+<p>Dans le makefile, il faut définir certaines cibles:</p>
+<pre class="literal-block">
+VPATH=.:&#64;srcdir&#64;:&#64;top_srcdir&#64;/idl
+LIB = libHELLOEngine.la
+LIB_SRC = HELLO.cxx
+LIB_SERVER_IDL = HELLO_Gen.idl
+LIB_CLIENT_IDL = SALOME_Component.idl SALOME_Exception.idl Logger.idl
+CPPFLAGS += -I${KERNEL_ROOT_DIR}/include/salome
+LDFLAGS+= -lSalomeContainer -lOpUtil -L${KERNEL_ROOT_DIR}/lib/salome
+</pre>
+<p>Passons en revue chacune de ces cibles.
+- LIB contient le nom <em>normalisé</em> (lib&lt;Nom_Module&gt;Engine.la) le nom de la
+librairie, LIB_SRC définit le nom des fichiers sources, et VPATH les
+repertoire où l'on peut les trouver.
+- LIB_SERVER_IDL contient le nom des fichiers idl implémentés par le module.
+- LIB_CLIENT_IDL contient le nom des idl où sont définis les services CORBA
+utilisés par le module. HELLO utilise Logger.idl via les macros &quot;MESSAGE&quot;,
+SALOME_Component.idl et SALOME_Exception.idl via l'héritage de HELLO_ORB::
+- Il faut ajouter à CPPFLAGS le chemin pour les fichiers includes utilisés
+(SALOMEconfig.h, SALOME_Component_i.hxx et utilities.h se trouvent dans
+${KERNEL_ROOT_DIR}/include/salome)::
+- La classe HELLO utilise les librairies lib (pour Engines_Component_i) et
+libOptUtil (pour PortableServer et Salome_Exception). On indique donc le nom
+de ces librairies et leur chemin dans LDFLAGS.
+D'autres librairies sont souvent utiles, par exemple libsalomeDS si on
+implémente la persistence, ou libSalomeNS si on utilise le naming service.</p>
+</div>
+</div>
+<div class="section" id="pilotage-du-composant-depuis-python-mode-tui">
+<h1><a class="toc-backref" href="#id8" name="pilotage-du-composant-depuis-python-mode-tui">6   Pilotage du composant depuis Python (mode TUI)</a></h1>
+<p>Lors de la compilation du module, la cible lib du Makefile dans /idl a
+provoqué la génération d'un stub python (souche côté client générée à partir
+de l'idl et offrant une interface dans le langage client - ici python.
+Concrètement, un module python HELLO_ORB contenant une classe
+_objref_HELLO_Gen sont créés, permettant de faire appel aux services de notre
+module C++ depuis python. Mettons ceci en application. Pour cela, nous lançons
+Salome en mode TUI:</p>
+<pre class="literal-block">
+cd $HELLO_ROOT_DIR/bin/salome
+python -i runSalome.py --modules=HELLO --xterm --logger --containers=cpp,python --killall
+</pre>
+<p>Depuis la fenêtre python, nous importons le module LifeCycle, et utilisons ses
+services pour charger notre composant Dans la conteneur C++ FactoryServer:</p>
+<pre class="literal-block">
+&gt;&gt;&gt; import LifeCycleCORBA
+&gt;&gt;&gt; lcc = LifeCycleCORBA.LifeCycleCORBA(clt.orb)
+&gt;&gt;&gt; import HELLO_ORB
+&gt;&gt;&gt; hello = lcc.FindOrLoadComponent(&quot;FactoryServer&quot;, &quot;HELLO&quot;)
+</pre>
+<p>L'import de HELLO_ORB est nécessaire avant l'appel de FindOrLoadComponent,
+pour permettre de retourner un objet typé (opération de &quot;narrowing&quot;). Sinon,
+l'objet retourné est générique de type Engines::Component. Vérifions que notre
+objet hello est correctement typé, et appelons le service makeBanner:</p>
+<pre class="literal-block">
+&gt;&gt;&gt; print hello
+&lt;HELLO_ORB._objref_HELLO_Gen instance at 0x8274e94&gt;
+&gt;&gt;&gt; mybanner=hello.makeBanner(&quot;Nicolas&quot;)
+&gt;&gt;&gt; print mybanner
+Hello, Nicolas
+</pre>
+<p>Les commandes précédentes ont été regroupées dans la fonction test du script
+/bin/runSalome.py.</p>
+</div>
+<div class="section" id="interface-graphique">
+<h1><a class="toc-backref" href="#id9" name="interface-graphique">7   Interface graphique</a></h1>
+<div class="section" id="introduction">
+<h2><a class="toc-backref" href="#id10" name="introduction">7.1   Introduction</a></h2>
+<p>Pour aller plus loin dans l'intégration de notre module, nous allons ajouter
+une interface graphique (développée en Qt), s'intégrant dans l'interface
+applicative de Salome (IAPP).
+On ne détaillera pas ici le fonctionnement de l'IAPP de Salome, mais pour
+résumer, l'IAPP gère une boucle d'évènements (clics souris, clavier, etc), et
+redirige après traitement ces évènements vers le module actif (le principe est
+qu'à un instant donné, <em>un</em> module est actif. Lorsqu'un module est activé, son
+IHM est chargée dynamiquement).
+Le programmeur de la GUI d'un module a donc à charge de définir les méthodes
+permettant de traiter correctement les évènements transmis. Parmi ces
+méthodes, citons les principales : OnGUIEvent(), OnMousePress(), OnMouseMove(),
+OnKeyPress(), DefinePopup(), CustomPopup().</p>
+</div>
+<div class="section" id="choix-des-widgets">
+<h2><a class="toc-backref" href="#id11" name="choix-des-widgets">7.2   Choix des widgets</a></h2>
+<div class="section" id="description-xml">
+<h3><a class="toc-backref" href="#id12" name="description-xml">7.2.1   Description xml</a></h3>
+<p>La description des items de notre module se fait dans le fichier XML
+/ressources/HELLO_en.xml. Ce fichier est utilisé par l'IAPP pour charger
+dynamiquement l'IHM du module quand celle-ci est activée.
+Le principe est de définir par des balises les menus et boutons souhaités, et
+d'y associer des ID, qui seront récupérés par les fonctions gérant les
+évènemements IHM. Plusieures possibilités sont offertes:</p>
+<ul>
+<li><p class="first">ajout d'items à des menus déjà existant, auquel cas il faut reprendre les
+balises du menu pré-existant, et y ajouter les nouveaux items. Dans
+l'exemple qui suis, on ajoute le Menu <strong>Hello</strong> et l'item <strong>MyNewItem</strong> au
+menu File, dont l'ID vaut 1:</p>
+<pre class="literal-block">
+&lt;menu-item label-id=&quot;File&quot; item-id=&quot;1&quot; pos-id=&quot;&quot;&gt;
+     &lt;submenu label-id=&quot;Hello&quot; item-id=&quot;19&quot; pos-id=&quot;8&quot;&gt;
+        &lt;popup-item item-id=&quot;190&quot; pos-id=&quot;&quot; label-id=&quot;MyNewItem&quot; icon-id=&quot;&quot; tooltip-id=&quot;&quot; accel-id=&quot;&quot; toggle-id=&quot;&quot; execute-action=&quot;&quot;/&gt;
+      &lt;/submenu&gt;
+      &lt;endsubmenu /&gt;
+&lt;/menu-item&gt;
+</pre>
+</li>
+<li><p class="first">Création de nouveaux menus. Pour le module HELLO, nous ajoutons un menu
+HELLO, avec un unique item de label &quot;Get banner&quot;:</p>
+<pre class="literal-block">
+&lt;menubar&gt;
+ &lt;menu-item label-id=&quot;HELLO&quot; item-id=&quot;90&quot; pos-id=&quot;3&quot;&gt;
+  &lt;popup-item item-id=&quot;901&quot; label-id=&quot;Get banner&quot; icon-id=&quot;&quot; tooltip-id=&quot;Get HELLO banner&quot; accel-id=&quot;&quot; toggle-id=&quot;&quot; execute-action=&quot;&quot;/&gt;
+ &lt;/menu-item&gt;
+&lt;/menubar&gt;
+</pre>
+</li>
+<li><p class="first">Ajout d'un bouton dans la barre à boutons. Dans l'exemple suivant, nous
+créons un deuxième point d'entrée pour notre action &quot;Get banner&quot;, sous forme
+d'un bouton associé au même ID &quot;901&quot;. L'icône est spécifiée par la le champ
+icon-id, qui doit être un fichier graphique 20x20 pixels au format png:</p>
+<pre class="literal-block">
+&lt;toolbar label-id=&quot;HELLO&quot;&gt;
+ &lt;toolbutton-item item-id=&quot;901&quot; label-id=&quot;Get banner&quot; icon-id=&quot;ExecHELLO.png&quot;
+tooltip-id=&quot;Get HELLO banner&quot; accel-id=&quot;&quot; toggle-id=&quot;&quot; execute-action=&quot;&quot;/&gt;
+&lt;/toolbar&gt;
+</pre>
+</li>
+</ul>
+</div>
+<div class="section" id="convention">
+<h3><a class="toc-backref" href="#id13" name="convention">7.2.2   Convention</a></h3>
+<p>A chaque menu ou item est associé un ID. Les numéros entre 1 et 40 sont
+réservés à l'IAPP. Les numéros d'ID suivent une certaine règle, quoique
+celle-ci ne soit pas obligatoire. Au menu &quot;HELLO&quot; est associé l'ID 90. Son
+unique item &quot;Get banner&quot; a l'ID 901. Un deuxième item aurait l'ID 902, et un
+sous item l'ID 9021.</p>
+</div>
+</div>
+<div class="section" id="impl-mentation-de-l-ihm">
+<h2><a class="toc-backref" href="#id14" name="impl-mentation-de-l-ihm">7.3   Implémentation de l'IHM</a></h2>
+<p>L'implémentation C++ de l'IHM est faite dans le répertoire /src/HELLOGUI.
+Le header HELLOGUI.h déclare de la classe HELLOGUI, et
+contient des directives Qt (Q_OBJECT). De ce fait, il doit être processé par
+le compilateur moc (Qt Meta Model Compiler). Pour cette raison, l'extension du
+fichier est .h et dans le Makefile nous ajoutons la cible:</p>
+<pre class="literal-block">
+LIB_MOC = HELLOGUI.h
+</pre>
+<p>Le fichier source HELLO.cxx contient la définition des fonctions membres, et
+le Makefile permet de construire une librairie libHELLOGUI (le nom est
+normalisé poour permettre le chargement dynamique : lib&lt;NomModule&gt;GUI.</p>
+<div class="section" id="gestion-des-v-nements">
+<h3><a class="toc-backref" href="#id15" name="gestion-des-v-nements">7.3.1   Gestion des évènements</a></h3>
+<p>Pour l'IHM d'HELLO, nous définissons la fonction HELLOGUI::OnGUIEvent, qui
+sera appelé à chaque évènement. Cette fonction contient essentiellement une
+structure switch permettant de traiter l'ID reçu en argument:</p>
+<pre class="literal-block">
+switch (theCommandID)
+  {
+  case 901:
+    // Traitement de &quot;Get banner&quot;
+    ...
+  case 190:
+    // Traitement de &quot;MyNewItem&quot;
+    ...
+  }
+</pre>
+<p>Le traitement standard consiste à récupérer des données d'entrée (ici, le
+prénom via une fenêtre de dialogue QInputDialog::getText), à récupérer une
+poignée sur le composant CORBA interfacé afin d'appeler le service souhaité
+(ici, getBanner), et d'afficher le résultat obtenu ().</p>
+</div>
+<div class="section" id="classes-disponibles">
+<h3><a class="toc-backref" href="#id16" name="classes-disponibles">7.3.2   Classes disponibles</a></h3>
+<p>Pour les dialogues avec l'utilisateur, il est possible d'utiliser n'importe
+quelle classe fournie par Qt (<a class="reference" href="http://doc.trolltech.com/3.2/classes.html">http://doc.trolltech.com/3.2/classes.html</a>). 
+Cependant, lorque c'eset possible, il est préférable d'utiliser les fonctions
+QAD (Qt Application Desktop), définies dans KERNEL_SRC/src/SALOMEGUI, qui
+encapsulent les fonctions Qt correspondantes et gèrent mieux les
+communications avec l'IAPP. Ainsi, dans HELLOGUI, nous utilisons la classe
+QAD_MessageBox en lieu et place de la classe Qt QMessageBox.</p>
+</div>
+<div class="section" id="gestion-du-multi-linguisme">
+<h3><a class="toc-backref" href="#id17" name="gestion-du-multi-linguisme">7.3.3   Gestion du multi-linguisme</a></h3>
+<p>Qt fournit un outil d'aide au support du multi-linguisme. Celui-ci est
+repris dans salome. Le principe est simple : toutes les chaînes de caractères
+utilisées pour les labels des menus et les dialogues avec l'utilisateur 
+sont encapsulés dans des appels à la fonction Qt tr() (pour translate), qui
+prend en argument un nom de label. Par exemple, pour demander à l'utilisateur
+de rentrer un prénom, nous utilisons la fonction getText, où les deux premiers
+arguments sont des labels encapsulés par tr():</p>
+<pre class="literal-block">
+myName = QInputDialog::getText( tr(&quot;QUE_HELLO_LABEL&quot;), tr(&quot;QUE_HELLO_NAME&quot;),
+                                QLineEdit::Normal, QString::null, &amp;ok);
+</pre>
+<p>Le nom des label est préfixé à titre indicatif par trois lettres et un underscore. Les codes
+suivants sont utilisés:</p>
+<pre class="literal-block">
+- MEN_ : label menu
+- BUT_ : label bouton
+- TOT_ : aide tooltip
+- ERR_ : message d'erreur
+- WRN_ : message d'alerte
+- INF_ : message d'information
+- QUE_ : question
+- PRP_ : prompt dans la barre des status
+</pre>
+<p>La traduction des labels encapsulés par tr() est faite pour différents
+langages cibles (par exemple français et anglais) dans des fichiers nommés &quot;&lt;nom_module&gt;_msg_&lt;langage&gt;.po&quot;. 
+&lt;langage&gt; correspond au code du langage, on a choisi <strong>en</strong> pour l'anglais et
+<strong>fr</strong> pour le français. Ce fichier doit contenir pour chaque clé sa
+traduction, par exemple:</p>
+<pre class="literal-block">
+msgid &quot;HELLOGUI::INF_HELLO_BANNER&quot;
+msgstr &quot;HELLO Information&quot;
+</pre>
+<p>Le squelette de ce fichier peut être généré par l'utilitaire Qt findtr:</p>
+<pre class="literal-block">
+findtr HELLOGUI.cxx &gt; HELLO_msg_en.po
+</pre>
+<p>puis éditer le fichier HELLO_msg_en.po pour remplir les traductions.
+Ces fichiers sont ensuite compilés par l'utilitaire <strong>msg2qm</strong> pour générer
+des binaires <em>.qm</em>. Pour cela, il faut remplir la cible LIB_MOC dans le
+Makefile:</p>
+<pre class="literal-block">
+PO_FILES =  HELLO_msg_en.po HELLO_msg_fr.po
+</pre>
+<p>Pour l'utilisateur final, le choix du langage se fait au niveau de chaque
+module dans le fichier ressources/config, en utilisant la commande:</p>
+<pre class="literal-block">
+langage=&lt;langage&gt;
+</pre>
+</div>
+</div>
+</div>
+<div class="section" id="r-gles-syntaxiques-de-nommage">
+<h1><a class="toc-backref" href="#id18" name="r-gles-syntaxiques-de-nommage">8   Règles syntaxiques de nommage</a></h1>
+<p>Dans ce qui précède, nous avons utilisé un certain nombre de règles de
+nommage. Le présent chapitre se propose de faire le point sur ces règles.
+Celles-ci ne sont pas toutes obligatoires, mais simplifient la compréhension
+si on les suit!</p>
+<table class="table" frame="border" rules="all">
+<colgroup>
+<col width="21%" />
+<col width="20%" />
+<col width="17%" />
+<col width="42%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th>Règle</th>
+<th>Formalisme</th>
+<th>Exemple HELLO</th>
+<th>Commentaire</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>Nom du module</td>
+<td>&lt;Module&gt;</td>
+<td>HELLO</td>
+<td>C'est le nom qui figure dans le
+catalogue des modules</td>
+</tr>
+<tr><td>Base CVS</td>
+<td>&lt;Module&gt;</td>
+<td>EXAMPLES</td>
+<td>Si la base cvs contient plusieurs
+modules, on prend un autre nom</td>
+</tr>
+<tr><td>Repertoire source</td>
+<td>&lt;Module&gt;_SRC</td>
+<td>HELLO1_SRC</td>
+<td>L'indice 1 est utilisé car on prévoit
+plusieurs version du module</td>
+</tr>
+<tr><td>Fichier idl</td>
+<td>&lt;Module&gt;_Gen.idl</td>
+<td>HELLO_Gen.idl</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>Nom du module
+CORBA</td>
+<td>&lt;Module&gt;_ORB</td>
+<td>HELLO_ORB</td>
+<td>On évite d'utiliser le nom du module
+(conflits)</td>
+</tr>
+<tr><td>Nom de
+l'interface CORBA</td>
+<td>&lt;Module&gt;_Gen</td>
+<td>HELLO_Gen</td>
+<td>La compilation de l'idl génère une
+classe abstraite
+POA_&lt;Module&gt;_ORB::&lt;Module&gt;_Gen</td>
+</tr>
+<tr><td>fichier source</td>
+<td>&lt;Module&gt;.cxx</td>
+<td>HELLO.cxx</td>
+<td>Dans le répertoire /src/&lt;Module&gt;</td>
+</tr>
+<tr><td>Classe
+d'implémentation</td>
+<td>&lt;Module&gt;</td>
+<td>HELLO</td>
+<td>Cette classe hérite de
+POA_HELLO_ORB::HELLO_Gen</td>
+</tr>
+<tr><td>Fonction
+d'instanciation</td>
+<td>&lt;Module&gt;_
+Engine_factory</td>
+<td>HELLO_Engine
+factory</td>
+<td>Cette fonction est appelée par
+le FactoryServer de Salome</td>
+</tr>
+<tr><td>Catalogue des
+modules</td>
+<td>&lt;Module&gt;Catalog
+.xml</td>
+<td>HELLOCatalog
+.xml</td>
+<td>Dans /ressources</td>
+</tr>
+<tr><td>Nom de la
+librairie C++</td>
+<td>lib&lt;Module&gt;Engine</td>
+<td>libHELLOEngine</td>
+<td>Dans le répertoire /src/&lt;Module&gt;</td>
+</tr>
+<tr><td>Librairie C++
+de l'IHM</td>
+<td>lib&lt;Module&gt;GUI</td>
+<td>libHELLOGUI</td>
+<td>Dans le répertoire /src/&lt;Module&gt;GUI</td>
+</tr>
+<tr><td>Variable
+d'environnement</td>
+<td>&lt;Module&gt;_ROOT_DIR</td>
+<td>HELLO_ROOT_DIR</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td><p class="last">...</p>
+</td>
+<td><p class="last">...</p>
+</td>
+<td><p class="last">...</p>
+</td>
+<td><p class="last">...</p>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+</body>
+</html>
diff --git a/doc/dev_guide.txt b/doc/dev_guide.txt
new file mode 100644 (file)
index 0000000..ee2f3b2
--- /dev/null
@@ -0,0 +1,477 @@
+===========================================================
+Guide pour le développement d'un module SALOME 2 en C++
+===========================================================
+
+:Auteur: Crouzet N.
+
+.. contents::
+.. sectnum::
+
+Présentation
+=========================
+Ce document a pour objectif de décrire les différentes étapes
+du développement d'un module SALOME 2 en C++.
+Il fait suite au document "Guide pour le développement d'un module SALOME 2 en
+Python", qui documente de module PYHELLO, et en reprend la démarche :
+construction pas à pas d'un module HELLO.
+Comme de nombreux points ne sont pas repris, il est recommendé de lire ce
+document préalablement.
+
+
+Les étapes de construction du module exemple
+====================================================
+Le composant choisi pour illustrer le processus de construction en C++
+est le même que celui choisi pour illustrer la construction du module python :
+il implémentera donc la même interface idl Corba.
+Il sera complété par un GUI graphique écrit en Qt.
+
+Les différentes étapes du développement seront les suivantes :
+
+  - créer une arborescence de module
+  - créer un composant SALOME 2 chargeable par un container C++
+  - configurer le module pour que le composant soit connu de SALOME
+  - ajouter un GUI graphique
+  - rendre le composant utilisable dans le superviseur
+
+Création de l'arborescence du module
+=======================================
+Dans un premier temps, on se contentera de mettre dans le module exemple un composant
+SALOME écrit en C++ qui sera chargeable par un container C++.
+Il suffit donc d'une interface idl et d'une implantation C++ du composant.
+Pour mettre en oeuvre ceci dans un module SALOME 2, il nous faut reproduire l'arborescence de
+fichier standard suivante::
+
+  + HELLO1_SRC
+    + build_configure
+    + configure.in.base
+    + Makefile.in
+    + adm_local
+      + unix
+        + make_commence.in
+        + make_omniorb.in
+        + config_files
+    + bin
+      + VERSION
+      + runAppli.in
+      + runSalome.py
+    + idl
+      + Makefile.in
+      + HELLO_Gen.idl
+    + src
+      + Makefile.in
+      + HELLO
+        + Makefile.in
+        + HELLO.cxx 
+        + HELLO.hxx 
+    + doc
+
+Pour cela, on recopie l'arborescence de PYHELLO, et on modifie où nécessaire
+PYHELLO en HELLO::
+
+    cp -r PYHELLO1_SRC HELLO1_SRC
+    cd HELLO1_SRC
+    mv idl/PYHELLO_Gen.idl idl/HELLO_Gen.idl
+    mv src/PYHELLO src/HELLO
+
+
+Interface idl
+==================
+Dans le répertoire idl, nous modifions le fichier idl HELLO_Gen.idl : le
+module défini est renommé HELLO_ORB, et l'interface en HELLO_Gen.
+Le service rendu reste le même : à partir d'une chaine de caractères
+fournie comme unique argument, retour d'une chaine de caractères obtenue
+par concaténation de "Hello, " et de la chaine d'entrée.
+Ce service est spécifié par la fonction makeBanner.
+
+Un utilitaire de documentation basé sur doxygen a été mis en place pour
+compiler une documentation des services corba à partir de commentaires se
+trouvant dans les fichiers idl. Nous rajouter donc à notre idl quelques
+commentaires, en respectant le formalisme doxygen.
+Un commentaire doxygen commence par "/*!" et se finit pas "*/".
+Pour structurer un minimum les pages générées, on les regroupes par module ou
+sujet. Dans notre exemple, nous utilisons la directive::
+
+    \ingroup EXAMPLES 
+
+spécifiant que la documentation générée fait partie du groupe EXAMPLES.
+(pour plus d'information sur doxygen, consulter le site www.doxygen.org).
+
+Pour finir, nous mettons à jour le Makefile avec le nouveau nom de composant::
+    
+    IDL_FILES = HELLO_Gen.idl
+
+
+Implémentation C++
+==================
+
+Les sources
+-----------
+
+L'implémentation C++ de notre module CORBA HELLO (interface idl HELLO_Gen) est faite dans le répertoire
+/src/HELLO::
+
+    HELLO.hxx
+    HELLO.cxx
+
+Au début du header de notre module (HELLO.hxx), les inclusions suivantes sont
+nécessaires::
+
+    #include <SALOMEconfig.h>
+    #include CORBA_SERVER_HEADER(HELLO_Gen)
+    #include "SALOME_Component_i.hxx"
+
+Le fichier SALOMEconfig.h contient un certain nombre de définitions utiles
+pour assurer l'indépendance du code par rapport à la version de CORBA
+utilisée. SALOME_Component_i.hxx contient l'interface de la classe
+d'implémentation C++ du composant de base Salome (idl Engines::Component).
+Enfin, la macro CORBA_SERVER_HEADER assure l'indépendance des noms de fichiers
+d'inclusion par rapport à l'implémentation de l'ORB CORBA.
+
+Après cela, nous définissons une classe d'implémentation, nommée HELLO, dérivant de
+POA_HELLO_ORB::HELLO_Gen (classe abstraite générée automatiquement par CORBA lors de la
+compilation de l'idl) et de Engines_Component_i (car l'interface idl HELLO_Gen
+dérive de Engines::Component comme tout composant Salome2). Cette classe
+contient un constructeur dont les arguments sont imposés par CORBA, un
+destructeur virtuel, et une méthode makeBanner fournissant le service souhaité::
+
+    class HELLO:
+      public POA_HELLO_ORB::HELLO_Gen,
+      public Engines_Component_i
+    {
+    public:
+       HELLO(CORBA::ORB_ptr orb,
+               PortableServer::POA_ptr poa,
+               PortableServer::ObjectId * contId,
+               const char *instanceName,
+               const char *interfaceName);
+       virtual ~HELLO();
+       char* makeBanner(const char* name);
+    };
+
+La fonction makeBanner prend comme argument et renvoit un char*, projection C++ du type CORBA/IDL
+string. 
+La documentation complète du mapping c++ de l'IDL est fournie par l'OMG sur
+son site internet : http://www.omg.org/cgi-bin/doc?ptc/00-01-02.
+
+Enfin, nous fournissons l'interface (normalisé) de la fonction HELLOEngine_factory, qui
+sera appelée par le "FactoryServer C++" pour charger le composant HELLO::
+
+    extern "C"
+       PortableServer::ObjectId * HELLOEngine_factory(
+               CORBA::ORB_ptr orb,
+               PortableServer::POA_ptr poa,
+               PortableServer::ObjectId * contId,
+               const char *instanceName,
+               const char *interfaceName);
+
+Dans le fichier source (HELLO.cxx) se trouvent les définitions 
+du constructeur et de la fonction d'instanciation
+HELLOEngine_factory (toutes deux normalisées!), et de makeBanner::
+
+    char* HELLO::makeBanner(const char* name)
+    {
+       string banner="Hello, ";
+       banner+=name;
+       return CORBA::string_dup(banner.c_str());
+    }
+
+Dans cette fonction, l'emploi de string_dup (fonction déclarée dans le
+namespace CORBA) n'est pas obligatoire (on aurait pu utiliser l'opérateur new),
+mais conseillé car ces fonctions permettent aux ORB d'utiliser des mécanismes
+spéciaux de gestion de la mémoire sans avoir à redéfinir les opérateurs new
+globaux.
+
+Makefile
+--------
+
+Dans le makefile, il faut définir certaines cibles::
+
+    VPATH=.:@srcdir@:@top_srcdir@/idl
+    LIB = libHELLOEngine.la
+    LIB_SRC = HELLO.cxx
+    LIB_SERVER_IDL = HELLO_Gen.idl
+    LIB_CLIENT_IDL = SALOME_Component.idl SALOME_Exception.idl Logger.idl
+    CPPFLAGS += -I${KERNEL_ROOT_DIR}/include/salome
+    LDFLAGS+= -lSalomeContainer -lOpUtil -L${KERNEL_ROOT_DIR}/lib/salome
+
+Passons en revue chacune de ces cibles.
+- LIB contient le nom *normalisé* (lib<Nom_Module>Engine.la) le nom de la
+librairie, LIB_SRC définit le nom des fichiers sources, et VPATH les
+repertoire où l'on peut les trouver.
+- LIB_SERVER_IDL contient le nom des fichiers idl implémentés par le module.
+- LIB_CLIENT_IDL contient le nom des idl où sont définis les services CORBA
+utilisés par le module. HELLO utilise Logger.idl via les macros "MESSAGE",
+SALOME_Component.idl et SALOME_Exception.idl via l'héritage de HELLO_ORB::
+- Il faut ajouter à CPPFLAGS le chemin pour les fichiers includes utilisés
+(SALOMEconfig.h, SALOME_Component_i.hxx et utilities.h se trouvent dans
+${KERNEL_ROOT_DIR}/include/salome)::
+- La classe HELLO utilise les librairies lib (pour Engines_Component_i) et
+libOptUtil (pour PortableServer et Salome_Exception). On indique donc le nom
+de ces librairies et leur chemin dans LDFLAGS.
+D'autres librairies sont souvent utiles, par exemple libsalomeDS si on
+implémente la persistence, ou libSalomeNS si on utilise le naming service.
+
+
+Pilotage du composant depuis Python (mode TUI)
+==============================================
+
+Lors de la compilation du module, la cible lib du Makefile dans /idl a
+provoqué la génération d'un stub python (souche côté client générée à partir
+de l'idl et offrant une interface dans le langage client - ici python.
+Concrètement, un module python HELLO_ORB contenant une classe
+_objref_HELLO_Gen sont créés, permettant de faire appel aux services de notre
+module C++ depuis python. Mettons ceci en application. Pour cela, nous lançons
+Salome en mode TUI::
+
+    cd $HELLO_ROOT_DIR/bin/salome
+    python -i runSalome.py --modules=HELLO --xterm --logger --containers=cpp,python --killall
+
+Depuis la fenêtre python, nous importons le module LifeCycle, et utilisons ses
+services pour charger notre composant Dans la conteneur C++ FactoryServer::
+
+    >>> import LifeCycleCORBA
+    >>> lcc = LifeCycleCORBA.LifeCycleCORBA(clt.orb)
+    >>> import HELLO_ORB
+    >>> hello = lcc.FindOrLoadComponent("FactoryServer", "HELLO")
+
+L'import de HELLO_ORB est nécessaire avant l'appel de FindOrLoadComponent,
+pour permettre de retourner un objet typé (opération de "narrowing"). Sinon,
+l'objet retourné est générique de type Engines::Component. Vérifions que notre
+objet hello est correctement typé, et appelons le service makeBanner::
+
+    >>> print hello
+    <HELLO_ORB._objref_HELLO_Gen instance at 0x8274e94>
+    >>> mybanner=hello.makeBanner("Nicolas")
+    >>> print mybanner
+    Hello, Nicolas
+
+Les commandes précédentes ont été regroupées dans la fonction test du script
+/bin/runSalome.py.
+
+
+Interface graphique
+===================
+
+Introduction
+------------
+
+Pour aller plus loin dans l'intégration de notre module, nous allons ajouter
+une interface graphique (développée en Qt), s'intégrant dans l'interface
+applicative de Salome (IAPP).
+On ne détaillera pas ici le fonctionnement de l'IAPP de Salome, mais pour
+résumer, l'IAPP gère une boucle d'évènements (clics souris, clavier, etc), et
+redirige après traitement ces évènements vers le module actif (le principe est
+qu'à un instant donné, *un* module est actif. Lorsqu'un module est activé, son
+IHM est chargée dynamiquement).
+Le programmeur de la GUI d'un module a donc à charge de définir les méthodes
+permettant de traiter correctement les évènements transmis. Parmi ces
+méthodes, citons les principales : OnGUIEvent(), OnMousePress(), OnMouseMove(),
+OnKeyPress(), DefinePopup(), CustomPopup().
+
+Choix des widgets
+-----------------
+
+Description xml
+```````````````
+La description des items de notre module se fait dans le fichier XML
+/ressources/HELLO_en.xml. Ce fichier est utilisé par l'IAPP pour charger
+dynamiquement l'IHM du module quand celle-ci est activée.
+Le principe est de définir par des balises les menus et boutons souhaités, et
+d'y associer des ID, qui seront récupérés par les fonctions gérant les
+évènemements IHM. Plusieures possibilités sont offertes:
+
+- ajout d'items à des menus déjà existant, auquel cas il faut reprendre les
+  balises du menu pré-existant, et y ajouter les nouveaux items. Dans
+  l'exemple qui suis, on ajoute le Menu **Hello** et l'item **MyNewItem** au
+  menu File, dont l'ID vaut 1::
+
+    <menu-item label-id="File" item-id="1" pos-id="">
+        <submenu label-id="Hello" item-id="19" pos-id="8">
+           <popup-item item-id="190" pos-id="" label-id="MyNewItem" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+         </submenu>
+         <endsubmenu />
+    </menu-item>
+
+- Création de nouveaux menus. Pour le module HELLO, nous ajoutons un menu
+  HELLO, avec un unique item de label "Get banner"::
+
+    <menubar>
+     <menu-item label-id="HELLO" item-id="90" pos-id="3">
+      <popup-item item-id="901" label-id="Get banner" icon-id="" tooltip-id="Get HELLO banner" accel-id="" toggle-id="" execute-action=""/>
+     </menu-item>
+    </menubar>
+
+- Ajout d'un bouton dans la barre à boutons. Dans l'exemple suivant, nous
+  créons un deuxième point d'entrée pour notre action "Get banner", sous forme
+  d'un bouton associé au même ID "901". L'icône est spécifiée par la le champ
+  icon-id, qui doit être un fichier graphique 20x20 pixels au format png::
+
+    <toolbar label-id="HELLO">
+     <toolbutton-item item-id="901" label-id="Get banner" icon-id="ExecHELLO.png"
+    tooltip-id="Get HELLO banner" accel-id="" toggle-id="" execute-action=""/>
+    </toolbar>
+
+Convention
+``````````
+A chaque menu ou item est associé un ID. Les numéros entre 1 et 40 sont
+réservés à l'IAPP. Les numéros d'ID suivent une certaine règle, quoique
+celle-ci ne soit pas obligatoire. Au menu "HELLO" est associé l'ID 90. Son
+unique item "Get banner" a l'ID 901. Un deuxième item aurait l'ID 902, et un
+sous item l'ID 9021.
+
+
+Implémentation de l'IHM
+-----------------------
+
+L'implémentation C++ de l'IHM est faite dans le répertoire /src/HELLOGUI.
+Le header HELLOGUI.h déclare de la classe HELLOGUI, et
+contient des directives Qt (Q_OBJECT). De ce fait, il doit être processé par
+le compilateur moc (Qt Meta Model Compiler). Pour cette raison, l'extension du
+fichier est .h et dans le Makefile nous ajoutons la cible::
+
+       LIB_MOC = HELLOGUI.h
+
+Le fichier source HELLO.cxx contient la définition des fonctions membres, et
+le Makefile permet de construire une librairie libHELLOGUI (le nom est
+normalisé poour permettre le chargement dynamique : lib<NomModule>GUI.
+
+Gestion des évènements
+``````````````````````
+Pour l'IHM d'HELLO, nous définissons la fonction HELLOGUI::OnGUIEvent, qui
+sera appelé à chaque évènement. Cette fonction contient essentiellement une
+structure switch permettant de traiter l'ID reçu en argument::
+
+  switch (theCommandID)
+    {
+    case 901:
+      // Traitement de "Get banner"
+      ...
+    case 190:
+      // Traitement de "MyNewItem"
+      ...
+    }
+
+Le traitement standard consiste à récupérer des données d'entrée (ici, le
+prénom via une fenêtre de dialogue QInputDialog::getText), à récupérer une
+poignée sur le composant CORBA interfacé afin d'appeler le service souhaité
+(ici, getBanner), et d'afficher le résultat obtenu ().
+
+Classes disponibles
+````````````````````
+Pour les dialogues avec l'utilisateur, il est possible d'utiliser n'importe
+quelle classe fournie par Qt (http://doc.trolltech.com/3.2/classes.html). 
+Cependant, lorque c'eset possible, il est préférable d'utiliser les fonctions
+QAD (Qt Application Desktop), définies dans KERNEL_SRC/src/SALOMEGUI, qui
+encapsulent les fonctions Qt correspondantes et gèrent mieux les
+communications avec l'IAPP. Ainsi, dans HELLOGUI, nous utilisons la classe
+QAD_MessageBox en lieu et place de la classe Qt QMessageBox.
+
+
+Gestion du multi-linguisme
+``````````````````````````
+Qt fournit un outil d'aide au support du multi-linguisme. Celui-ci est
+repris dans salome. Le principe est simple : toutes les chaînes de caractères
+utilisées pour les labels des menus et les dialogues avec l'utilisateur 
+sont encapsulés dans des appels à la fonction Qt tr() (pour translate), qui
+prend en argument un nom de label. Par exemple, pour demander à l'utilisateur
+de rentrer un prénom, nous utilisons la fonction getText, où les deux premiers
+arguments sont des labels encapsulés par tr()::
+
+        myName = QInputDialog::getText( tr("QUE_HELLO_LABEL"), tr("QUE_HELLO_NAME"),
+                                        QLineEdit::Normal, QString::null, &ok);
+
+Le nom des label est préfixé à titre indicatif par trois lettres et un underscore. Les codes
+suivants sont utilisés::
+
+ - MEN_ : label menu
+ - BUT_ : label bouton
+ - TOT_ : aide tooltip
+ - ERR_ : message d'erreur
+ - WRN_ : message d'alerte
+ - INF_ : message d'information
+ - QUE_ : question
+ - PRP_ : prompt dans la barre des status
+
+
+La traduction des labels encapsulés par tr() est faite pour différents
+langages cibles (par exemple français et anglais) dans des fichiers nommés "<nom_module>_msg_<langage>.po". 
+<langage> correspond au code du langage, on a choisi **en** pour l'anglais et
+**fr** pour le français. Ce fichier doit contenir pour chaque clé sa
+traduction, par exemple::
+
+    msgid "HELLOGUI::INF_HELLO_BANNER"
+    msgstr "HELLO Information"
+
+Le squelette de ce fichier peut être généré par l'utilitaire Qt findtr::
+
+    findtr HELLOGUI.cxx > HELLO_msg_en.po
+
+puis éditer le fichier HELLO_msg_en.po pour remplir les traductions.
+Ces fichiers sont ensuite compilés par l'utilitaire **msg2qm** pour générer
+des binaires *.qm*. Pour cela, il faut remplir la cible LIB_MOC dans le
+Makefile::
+
+    PO_FILES =  HELLO_msg_en.po HELLO_msg_fr.po
+
+Pour l'utilisateur final, le choix du langage se fait au niveau de chaque
+module dans le fichier ressources/config, en utilisant la commande::
+
+    langage=<langage>
+
+
+
+Règles syntaxiques de nommage
+=============================
+
+Dans ce qui précède, nous avons utilisé un certain nombre de règles de
+nommage. Le présent chapitre se propose de faire le point sur ces règles.
+Celles-ci ne sont pas toutes obligatoires, mais simplifient la compréhension
+si on les suit!
+
++-------------------+------------------+----------------+---------------------------------------+
+| Règle             | Formalisme       | Exemple HELLO  | Commentaire                           |
++===================+==================+================+=======================================+
+| Nom du module     | <Module>         | HELLO          | C'est le nom qui figure dans le       |
+|                   |                  |                | catalogue des modules                 |
++-------------------+------------------+----------------+---------------------------------------+
+| Base CVS          | <Module>         | EXAMPLES       | Si la base cvs contient plusieurs     | 
+|                   |                  |                | modules, on prend un autre nom        |
++-------------------+------------------+----------------+---------------------------------------+
+| Repertoire source | <Module>_SRC     | HELLO1_SRC     | L'indice 1 est utilisé car on prévoit |
+|                   |                  |                | plusieurs version du module           |
++-------------------+------------------+----------------+---------------------------------------+
+| Fichier idl       | <Module>_Gen.idl | HELLO_Gen.idl  |                                       |
+|                   |                  |                |                                       |
++-------------------+------------------+----------------+---------------------------------------+
+| Nom du module     | <Module>_ORB     | HELLO_ORB      | On évite d'utiliser le nom du module  |
+| CORBA             |                  |                | (conflits)                            |
++-------------------+------------------+----------------+---------------------------------------+
+| Nom de            | <Module>_Gen     | HELLO_Gen      | La compilation de l'idl génère une    |
+| l'interface CORBA |                  |                | classe abstraite                      |
+|                   |                  |                | POA_<Module>_ORB::<Module>_Gen        |
++-------------------+------------------+----------------+---------------------------------------+
+| fichier source    | <Module>.cxx     | HELLO.cxx      | Dans le répertoire /src/<Module>      |
+|                   |                  |                |                                       |
++-------------------+------------------+----------------+---------------------------------------+
+| Classe            | <Module>         | HELLO          | Cette classe hérite de                |
+| d'implémentation  |                  |                | POA_HELLO_ORB::HELLO_Gen              |
++-------------------+------------------+----------------+---------------------------------------+
+| Fonction          | <Module>_        | HELLO_Engine   | Cette fonction est appelée par        |
+| d'instanciation   | Engine_factory   | factory        | le FactoryServer de Salome            |
++-------------------+------------------+----------------+---------------------------------------+
+| Catalogue des     | <Module>Catalog  | HELLOCatalog   | Dans /ressources                      |
+| modules           | .xml             | .xml           |                                       |
++-------------------+------------------+----------------+---------------------------------------+
+| Nom de la         | lib<Module>Engine| libHELLOEngine | Dans le répertoire /src/<Module>      |
+| librairie C++     |                  |                |                                       |
++-------------------+------------------+----------------+---------------------------------------+
+| Librairie C++     | lib<Module>GUI   | libHELLOGUI    | Dans le répertoire /src/<Module>GUI   |
+| de l'IHM          |                  |                |                                       |
++-------------------+------------------+----------------+---------------------------------------+
+| Variable          | <Module>_ROOT_DIR| HELLO_ROOT_DIR |                                       |
+| d'environnement   |                  |                |                                       |
++-------------------+------------------+----------------+---------------------------------------+
+| ...               | ...              | ...            | ...                                   |
+|                   |                  |                |                                       |
++-------------------+------------------+----------------+---------------------------------------+
+