Mon application s’inspire de l’exemple qui se trouve dans le dossier <msedir>/apps/i18ndemo.
L’application comporte un composant de type tstringdisp,
et trois boutons qui serviront à changer la langue.
type
tmainfo = class(tmainform)
sd_weather: tstringdisp;
bt_english: tbutton;
bt_german: tbutton;
bt_french: tbutton;Dans l’inspecteur d’objet, j’attribue une valeur à la propriété
frame.caption du composant sd_weather.
J’assigne également une valeur à la propriété text du
même composant.
J’ai également renseigné la propriété caption de la
fiche principale.
Dans main.pas j’ajoute la référence à l’unité
msei18nutils.
implementation
uses
main_mfm,
msei18nutils;Je déclare une chaîne de caractères de type
resourcestring.
uses
main_mfm,
msei18nutils;
resourcestring
rs_goodbye = 'Good bye!';Je compile mon application. Le compilateur m’informe qu’il crée un fichier main.rsj.
Writing Resource String Table file: main.rsj
Par curiosité, j’ouvre ce fichier, qui se trouve dans le même dossier que les unités compilées.
{"version":1,"strings":[
{"hash":90624273,"name":"main.rs_goodbye","sourcebytes":[71,111,111,100,32,98,121,101,33],"value":"Good bye!"}
]}
Tout semble correct. Il est temps d’ouvrir l’application MSEi18n.
L’application MSEi18n se trouve dans le dossier <msedir>/tools/i18n/. Elle est également disponible dans le dépôt codeberg.org/rchastain/msei18n.
Après avoir compilé MSEi18n, je l’ouvre, et dans le menu Settings je clique sur l’élément de menu Configure MSEi18n.
Les champs MSEDIR et COMPILER doivent être renseignés.
Dans MSEDIR, j’indique le chemin du dossier de MSEgui,
terminé par un / (ici
/home/roland/Applications/mseide-463-dev/), car les autres
macros sont construites par simple concaténation, par exemple
${MSEDIR}lib/common/. Dans COMPILER, j’indique le
compilateur Free Pascal (ici ppcx64 ; fpc
convient aussi).
Je crée un nouveau projet de traduction (un fichier TRP) en cliquant sur l’élément de menu New.
Après avoir choisi l’emplacement et le nom de mon projet, je clique sur OK.
Je vais maintenant éditer mon projet de traduction. Pour cela, je clique sur l’élément de menu Edit.
Je clique dans la colonne File, afin de créer une nouvelle
ligne dans la grille, et j’ajoute dans cette ligne le fichier
main.mfm. Dans la colonne Kind, je sélectionne
rfk_module.
Comme j’utilise dans mon application une chaîne de type
resourcestring, je vais ajouter une deuxième ligne. Pour
cela, je clique avec le bouton droit de la souris sur la première ligne,
et je choisis, dans le menu qui s’affiche, Append Row.
Dans la colonne File, j’indique main.rsj. Dans la
colonne Kind, je sélectionne rfk_resstrings.
Je remplis également les colonnes Language et Directory (une ligne pour l’allemand, une ligne pour le français).
Je ferme la fenêtre en cliquant sur OK. Je peux maintenant
traduire, d’une part les chaînes contenues dans mon fichier MFM, d’autre
part la chaîne de type resourcestring contenue dans le
fichier RSJ.
Vous noterez que j’ai coché les options flat et string only, afin de n’avoir sous les yeux que les données qui m’intéressent.
Une fois le travail de traduction achevé, je sauvegarde mon projet en cliquant sur l’élément de menu Save.
Avant de compiler le projet, je crée les dossiers devant contenir les modules, en fonction de ce que j’avais indiqué en éditant le projet.
mkdir -p de
mkdir -p frJe peux maintenant compiler le projet en cliquant sur Make. Une fenêtre s’ouvre, me permettant de vérifier que la compilation des modules par Free Pascal s’est bien passée.
Voici le contenu du dossier du projet après la compilation.
projet
├── de
│ ├── demo_de.pas
│ ├── libdemo_de.so
│ ├── main.mfm
│ ├── main_mfm.pas
│ ├── main.rsj
│ └── main_rst.pas
├── demo
├── demo.pas
├── demo.prj
├── demo.trd
├── demo.trp
├── fr
│ ├── demo_fr.pas
│ ├── libdemo_fr.so
│ ├── main.mfm
│ ├── main_mfm.pas
│ ├── main.rsj
│ └── main_rst.pas
├── libdemo_de.so
├── libdemo_fr.so
├── main.mfm
├── main_mfm.pas
├── main.pas
├── Makefile
├── MakefileWin
└── out
├── main.rsj
└── … (unités compilées)
Il est temps de terminer mon application. Je rouvre donc (si je l’avais fermé) mon projet demo.prj dans MSEide.
Je crée une méthode pour l’événement onexecute du bouton
bt_german.
Dans le corps de cette méthode, j’utilise la fonction
loadlangunit pour changer la langue, avec comme paramètre
le nom de base du module.
procedure tmainfo.onexecute_bt_german(const sender: TObject);
begin
loadlangunit('demo_de');
end;Le nom du module est formé du nom du projet (demo), d’un tiret bas et de la langue indiquée dans la colonne Language (de).
Sous Linux, loadlangunit('demo_de') cherche la
bibliothèque libdemo_de.so d’abord dans les dossiers de
bibliothèques habituels du système, puis dans le dossier de l’exécutable
; sous Windows, elle cherche demo_de.dll. C’est pourquoi
MSEi18n copie les bibliothèques dans le dossier du projet après
la compilation : voilà pourquoi libdemo_de.so et
libdemo_fr.so apparaissent deux fois dans l’arborescence
ci-dessus.
Je fais la même chose pour le français.
procedure tmainfo.onexecute_bt_french(const sender: TObject);
begin
loadlangunit('demo_fr');
end;Pour remettre l’application en anglais (la langue des chaînes de
caractères contenues dans le fichier MFM), je n’aurai qu’à appeler la
fonction loadlangunit avec une chaîne vide comme
argument.
procedure tmainfo.onexecute_bt_english(const sender: TObject);
begin
loadlangunit('');
end;Il me reste à faire quelque chose de ma chaîne
rs_goodbye de type resourcestring. Je voudrais
que mon application dise au revoir à l’utilisateur, dans la dernière
langue sélectionnée, lorsque celui-ci fermera la fenêtre.
J’ajoute donc une méthode pour l’événement onclosequery
de la classe tmainfo.
procedure tmainfo.onclosequery_mainfo(const sender: tcustommseform; var amodalresult: modalresultty);
begin
end;Dans le corps de cette méthode, j’utilise la fonction
utf8tostring pour obtenir la traduction de la chaîne
rs_goodbye.
En effet, un resourcestring est un AnsiString codé en
UTF-8, alors que MSEgui travaille avec des chaînes Unicode (le type
msestring de MSEgui correspond à
unicodestring). La fonction utf8tostring de
Free Pascal effectue la conversion, afin que les caractères spéciaux
comme ä ou é s’affichent correctement. C’est pourquoi
je déclare la variable s de type
unicodestring.
procedure tmainfo.onclosequery_mainfo(const sender: tcustommseform; var amodalresult: modalresultty);
var
s: unicodestring;
begin
s := utf8tostring(rs_goodbye);
showmessage(s);
end;C’est tout ! Je n’ai plus qu’à compiler et qu’à essayer mon application.
Si vous le souhaitez, vous pouvez télécharger le code source du projet.