Avant de documenter l'éditeur d'archétypes, nous devons d'abord mieux définir ce qu'est un archétype.
L'origine des archétype est assez savante : les Australiens du projet openEHR ont théorisé l'intérêt qu'il y avait à ne pas "calcifier" le modèle de données d'une application sous la forme d'une base de données complexe et des milliers de lignes de codes qui l'animent, mais au contraire d'exprimer ce qui peut être "narré" par cette application sous une forme très souple et aisément modifiable sans modification du logiciel.
De façon imagée, on pourrait dire que celui qui commande des milliers de formulaires après un long processus d'imprimerie risque fort de se rendre compte rapidement qu'il serait utile de les faire évoluer, mais qu'il faudra, tant bien que mal, bricoler l'existant. A contrario, s'il a commandé un jeu de tampons encreurs avec lequel il compose au vol ses formulaires, il lui suffit de faire graver un nouveau tampon à chaque fois qu'il souhaite définir ou faire évoluer une partie de ses documents.
L'adaptation du concept à Episodus a été d'autant plus naturelle que sa description en arbres, proche du langage naturel, est déjà complètement détachée de tout modèle rigide.
On peut donc imaginer un archétype comme un moule qui permet de fabriquer facilement un arbre ou un segment d'arbre. Nous allons voir que ce "moule" est composé de trois parties :
Nous allons détailler ces trois composants en prenant pour exemple un archétype simple de saisie de consultation dont l'interface utilisateur est visible ci-dessous. Les archétypes sont matérialisés sous forme de fichier XML, aussi allons nous décrire ces blocs dans un formalisme de balises.
Les archétypes sont matérialisés sous forme de fichier XML, aussi allons nous décrire ces blocs dans un formalisme de balises.
Le bloc de XML qui représente l'arbre type du formulaire de consultation est le suivant :
<items> <item code="GCONS1"> <item code="0SOA01"> </item> <item code="0SOA23"> <item code="0BIOM1"> <item code="VPOID1"> <item code="2KG001/£N0;03" /> </item> <item code="VTAIL1"> <item code="2CM001/£N0;03" /> </item> <item code="VIMC02"> <item code="2KGM21/£N0;03" /> </item> <item code="VPEOM1"> <item code="2CM001/£N0;03" /> </item> <item code="VPRE01"> <item code="2MMHG1/£N0;03" /> </item> <item code="VPAP11"> <item code="2MMHG1/£N0;03" /> </item> <item code="VFRCA1"> <item code="2BAPM2/£N0;03" /> </item> </item> <item code="GEXPH2"> </item> </item> <item code="0SOA42"> </item> <item code="0SOA11"> </item> </item> </items>
L'élément racine, GCONS1, est le code Lexique qui correspond au concept "consultation". Les branches mères (0SOA01, 0SOA23, 0SOA42 et 0SOA11) correspondent aux 4 chapitres du SOAP.
Au sein de cet archétype, seul le chapitre "Observation" du SOAP (0SOA23) a été développé, avec un chapitre "biométrie" (0BIOM1) et un chapitre "examen physique" (GEXPH2).
La biométrie est constituée du poids (VPOID1) exprimé en kg (2KG001), de la taille (VTAIL1) en cm (2CM001), de l'indice de masse corporelle (VIMC02) en kg/m2 (2KGM21), du périmètre ombilical (VPEOM1) en cm, des pressions artérielles systolique et diastolique (VPRE01 et VPAP11) en mmHg (2MMHG1) et de la fréquence cardiaque (VFRCA1) en bpm (2BAPM2).
Le bloc qui décrit la fenêtre de saisie est le suivant :
<dialogbox type="dialog" coords="0 0 497 345" style="DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION" class="bordlg" caption="$NAME" fontsize="8" fonttype="MS Sans Serif"> <control value='CONTROL "", -1, "BorShade", BSS_RGROUP | BSS_CAPTION | BSS_CENTER | WS_CHILD | WS_VISIBLE, 4, 4, 124, 123' /> <control value='CONTROL "Poids", -1, "Borstatic", SS_LEFT | WS_CHILD | WS_VISIBLE, 8, 7, 60, 10' data="GCONS1/0SOA23/0BIOM1/VPOID1" /> <control value='CONTROL "", 101, "edit", ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 70, 7, 29, 10' data="GCONS1/0SOA23/0BIOM1/VPOID1/2KG001/£N0;03:CALCIMC" filling="SF|F=0BIOM|D=020000" /> <control value='CONTROL "kg", -1, "Borstatic", SS_LEFT | WS_CHILD | WS_VISIBLE, 104, 7, 22, 10' data="2KG001" /> <control value='CONTROL "Taille", -1, "Borstatic", SS_LEFT | WS_CHILD | WS_VISIBLE, 8, 20, 60, 10' data="GCONS1/0SOA23/0BIOM1/VTAIL1" /> <control value='CONTROL "", 102, "edit", ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 70, 20, 29, 10' data="GCONS1/0SOA23/0BIOM1/VTAIL1/2CM001/£N0;03:CALCIMC" filling="SF|F=0BIOM|D=020000" /> <control value='CONTROL "cm", -1, "Borstatic", SS_LEFT | WS_CHILD | WS_VISIBLE, 104, 20, 22, 10' data="2CM001" /> <control value='CONTROL "IMC", -1, "Borstatic", SS_LEFT | WS_CHILD | WS_VISIBLE, 8, 33, 60, 10' data="GCONS1/0SOA23/0BIOM1/VIMC02" /> <control value='CONTROL "", 103, "edit", ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 70, 33, 29, 10' data="GCONS1/0SOA23/0BIOM1/VIMC02/2KGM21/£N0;03" /> <control value='CONTROL "kg/m²", -1, "Borstatic", SS_LEFT | WS_CHILD | WS_VISIBLE, 104, 33, 22, 10' data="2KGM21" /> <control value='CONTROL "Périmètre ombilical", -1, "Borstatic", SS_LEFT | WS_CHILD | WS_VISIBLE, 8, 46, 60, 10' data="GCONS1/0SOA23/0BIOM1/VPEOM1" /> <control value='CONTROL "", 104, "edit", ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 70, 46, 29, 10' data="GCONS1/0SOA23/0BIOM1/VPEOM1/2CM001/£N0;03" filling="SF|F=0BIOM|D=020000" /> <control value='CONTROL "cm", -1, "Borstatic", SS_LEFT | WS_CHILD | WS_VISIBLE, 104, 46, 22, 10' data="2CM001" /> <control value='CONTROL "PAS", -1, "Borstatic", SS_LEFT | WS_CHILD | WS_VISIBLE, 8, 67, 60, 10' data="VPRE01" /> <control value='CONTROL "", 105, "edit", ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 70, 67, 29, 10' data="GCONS1/0SOA23/0BIOM1/VPRE01/2MMHG1/£N0;03" filling="SF|F=0BIOM|D=020000" /> <control value='CONTROL "mmHg", -1, "Borstatic", SS_LEFT | WS_CHILD | WS_VISIBLE, 104, 67, 22, 10' data="2MMHG1" /> <control value='CONTROL "PAD", -1, "Borstatic", SS_LEFT | WS_CHILD | WS_VISIBLE, 8, 79, 60, 10' data="VPAP11" /> <control value='CONTROL "", 106, "edit", ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 70, 79, 29, 10' data="GCONS1/0SOA23/0BIOM1/VPAP11/2MMHG1/£N0;03" filling="SF|F=0BIOM|D=020000" /> <control value='CONTROL "mmHg", -1, "Borstatic", SS_LEFT | WS_CHILD | WS_VISIBLE, 104, 79, 22, 10' data="2MMHG1" /> <control value='CONTROL "FC", -1, "Borstatic", SS_LEFT | WS_CHILD | WS_VISIBLE, 8, 100, 60, 10' data="VFRCA1" /> <control value='CONTROL "", 107, "edit", ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 70, 100, 29, 10' data="GCONS1/0SOA23/0BIOM1/VFRCA1/2BAPM2/£N0;03" filling="SF|F=0BIOM|D=020000" /> <control value='CONTROL "bpm", -1, "Borstatic", SS_LEFT | WS_CHILD | WS_VISIBLE, 104, 100, 22, 10' data="2BAPM2" /> <control value='CONTROL "Motif de contact", -1, "Borstatic", SS_LEFT | WS_CHILD | WS_VISIBLE, 132, 4, 350, 10' /> <control value='CONTROL "", 301, "SysTreeView32", TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS | TVS_SHOWSELALWAYS | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 132, 14, 350, 34' data="GCONS1/0SOA01" /> <control value='CONTROL "Examen clinique", -1, "Borstatic", SS_LEFT | WS_CHILD | WS_VISIBLE, 132, 48, 350, 10' /> <control value='CONTROL "", 302, "SysTreeView32", TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS | TVS_SHOWSELALWAYS | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 132, 58, 350, 34' data="GCONS1/0SOA23/GEXPH2" /> <control value='CONTROL "Diagnostic", -1, "Borstatic", SS_LEFT | WS_CHILD | WS_VISIBLE, 132, 92, 350, 10' /> <control value='CONTROL "", 303, "SysTreeView32", TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS | TVS_SHOWSELALWAYS | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 132, 102, 350, 174' data="GCONS1/0SOA42:ADDALLLINES" /> <control value='CONTROL "Procédure", -1, "Borstatic", SS_LEFT | WS_CHILD | WS_VISIBLE, 132, 276, 350, 10' /> <control value='CONTROL "", 304, "SysTreeView32", TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS | TVS_SHOWSELALWAYS | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 132, 286, 350, 54' data="GCONS1/0SOA11" /> </dialogbox>
La première ligne (<dialogbox ... >) décrit la fenêtre (sa taille, son style, le type et la taille de la police de caractères utilisée), tandis que les autres lignes (<control ... />) correspondent aux éléments de dialogue.
Les éléments de dialogue peuvent être passifs (comme un texte (Borstatic) ou une boite de groupe (BorShade)) ou bien actifs comme une case à cocher, un bouton radio, un champ de saisie textuelle (edit) ou une arborescence de saisie d'arbre (SysTreeView32).
La saisie du poids du patient est matérialisé par trois éléments de dialogue : deux textes passifs (<control value='CONTROL "Poids" ... > et <control value='CONTROL "kg" ... >) qui encadrent un élément actif que nous allons détailler.
Le champ de saisie de la donnée chiffrée (<control value='CONTROL "", 101, "edit" ... >) est constitué de trois paramètres : value, data et filling.
Le paramètre value décrit l'élément d'interface : c'est un champ de saisie (edit) avec une description de style (ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP), une position en x,y (70, 7) et une taille (29, 10) représentant largeur et hauteur.
Le paramètre data permet de connecter cet élément d'interface avec l'élément d'arbre qu'il "anime". La chaine "GCONS1/0SOA23/0BIOM1/VPOID1/2KG001/£N0;03" représente sans ambiguité le chemin qui va de la racine de l'arbre à la feuille 2KG001/£N0;03 qui matérialise une donnée chiffrée exprimée en kg.
Le paramètre filling n'est présent que si on souhaite activer automatiquement cet élément en fonction du contenu du dossier patient (par exemple, ici, en initialisant le champ de saisie avec la plus récente valeur de poids enregistrée).
La chaine de paramètres (SF|F=0BIOM|D=020000) contient trois parties :
Le bloc de paramètres de publication est le suivant :
<presentation value=' [[IF GCONS1/0SOA01]<b>[LABEL 0SOA01]</b> : [TREEVALUE GCONS1/0SOA01]<br> ] [[IF GCONS1/0SOA23]<b>[LABEL 0SOA23]</b> : <ul> [[IF GCONS1/0SOA23/0BIOM1] <li><b>[LABEL 0BIOM1]<br> :<br> <table width="100%" border="0"> <tr> <td width="50%" align="right" valign="center"> <table border="1"> <tr> <td>[LABEL VPOID1]</td> <td>[VALUE GCONS1/0SOA23/0BIOM1/VPOID1]</td> </tr> <tr> <td>[LABEL VTAIL1]</td> <td>[VALUE GCONS1/0SOA23/0BIOM1/VTAIL1]</td> </tr> <tr> <td>[LABEL VIMC02]</td> <td>[VALUE GCONS1/0SOA23/0BIOM1/VIMC02]</td> </tr> <tr> <td>[LABEL VPEOM1]</td> <td>[VALUE GCONS1/0SOA23/0BIOM1/VPEOM1]</td> </tr> </table> </td> <td width="50%" align="left" valign="center"> <table border="1"> <tr> <td>[LABEL VPRE01]</td> <td>[VALUE GCONS1/0SOA23/0BIOM1/VPRE01]</td> </tr> <tr> <td>[LABEL VPAP11]</td> <td>[VALUE GCONS1/0SOA23/0BIOM1/VPAP11]</td> </tr> <tr> <td>[LABEL VFRCA1]</td> <td>[VALUE GCONS1/0SOA23/0BIOM1/VFRCA1]</td> </tr> </table> </td> </tr> </table> </li> ] [[IF GCONS1/0SOA23/GEXPH2]<li><b>[LABEL GEXPH2]</b> : [TREEVALUE GCONS1/0SOA23/GEXPH2]</li> ] </ul> ] [[IF GCONS1/0SOA42]<b>[LABEL 0SOA42]</b> : [TREEVALUE GCONS1/0SOA42]<br> ] [[IF GCONS1/0SOA11]<b>[LABEL 0SOA11]</b> : [TREEVALUE GCONS1/0SOA11]<br> ] ' />
Il s'agit principalement d'un bloc de HTML qui utilise les informations du document pour composer une page HTML "à façon".
Un bloc comme "[[IF GCONS1/0SOA01] Motif ]" n'affichera "Motif" que si le chemin "GCONS1/0SOA01" existe dans le document ; le bloc "[[IF GCONS1/0SOA01] Motif [ELSE] Absence de motif ]" affichera "Absence de motif" dans le cas contraire.
Le bloc "[LABEL VPOID1]" affichera le mot "poids" dans la langue de l'utilisateur. "[VALUE GCONS1/0SOA23/0BIOM1/VPOID1]" affichera la valeur du poids telle que renseignée dans le document (par exemple "70 kg"). Dans la même veine, "[TREEVALUE GCONS1/0SOA42]" affichera intégralement l'arbre contenu dans le chapitre "Diagnostic".
Maintenant que nous avons vu ce qu'est un archétype (un moyen particulièrement souple, évolutif et partageable pour représenter ce qu'on souhaite raconter, y compris l'interface de saisie et la façon de le publier), il est temps de décrire comment fonctionne l'éditeur.
L'éditeur se lance à partir du menu "Outils" puis "Outils système"
La première fenêtre d'interface vous permet de choisir entre la création d'un nouvel archétype ou la modification d'un archétype existant.
Si nous choisissons de créer un nouvel archétype, l'éditeur ouvre deux fenêtres. La première (l'Éditeur d'arbre) permet de rédiger l'arbre type, la seconde (l'Éditeur d'interface) de créer l'interface utilisateur qui en permet la saisie (un Éditeur de publication apparaitra dans une version ultérieure).
Nous commençons logiquement par rédiger l'arbre.
Les utilisateurs de la consultation d'Episodus ne seront pas dépaysés : saisie à la main jusqu'à ce que le terme voulu apparaisse dans la fenêtre du Lexique, puis flêche basse pour se positionner sur le terme et touche <Entrée> pour valider (ou bien double-click avec la souris, mais tellement plus long).
Une fois l'arbre construit, il faut créer les éléments d'interface qui l'animent. Il en existe deux sortes : les contrôles statiques, qui n'interviennent pas dans la construction de l'arbre et les contrôles actifs qui pilotent un fragment de branche.
Pour créer un contrôle statique, il suffit de faire un click droit sur une zone vide de l'éditeur d'interface et de valider l'entrée de menu "Nouveau contrôle statique" (voir image ci-dessous).
La boite de dialogue qui s'ouvre vous permet de choisir le type du contrôle, son titre, sa taille, sa position et ses propriétés.
Les contrôles actifs se construisent depuis le segment d'arbre qu'ils pilotent, par click droit sur l'élément puis sélection du menu "Créer un contrôle".
La fenêtre de saisie des paramètres est presque semblable à celle des contrôles statiques, mais pour des types de contrôles qui permettent l'activation (bouton, case à cocher ou bouton radio) ou la saisie d'informations (champ d'édition ou arbre).
En itérant le processus pour chaque feuille de l'arbre on obtient un archétype prêt à l'utilisation.