Les widgets de type Text


Table des matières :


Introduction :


MOTIF fournit deux types de Text widgets :

XmText
Ce widget est un petit éditeur de texte multilignes.
XmTextField
Un éditeur comportant une seule ligne.

Dans certaines applications, l'édition de texte occupe une place très importante. Le fait que MOTIF fournisse de puissants outils de ce type facilite grandement la vie du programmeur. Par exemple, dans Netscape, lorsque vous utilisez l'option "View Source" une fenêtre contenant un éditeur de texte simplifié vous propose d'éditer le code HTML de la page courante. Il s'agit d'un Text widget de MOTIF!

Remarque : si on couple les Text widgets avec d'autres widgets déjà étudiés comme le FileSelectionDialog, on peut aisément écrire son propre éditeur de texte (il ne sera pas ridicule, surtout comparé à textedit!)

Nous étudierons surtout le widget Text étant donné que le widget de type TextField n'en est qu'une version très simplifiée. (De plus, si on positionne la ressource XmNeditMode du widget Text avec la valeur XmSINGLE_LINE_EDIT, on transforme le widget Text en widget de type TextField)


Création d'un Widget de type Text


Il existe plusieurs manières de créer un widget de type Text :

Ressources d'un Text widget :

XmNrows
Nombre de lignes visibles.
XmNcolumns
Nombre de colonnes visibles.
XmNeditable
Valeurs possibles : True ou False selon que l'édition du texte est autorisée ou pas.
XmNscrollHorizontal
Valeurs possibles : True ou False selon que l'on autorise le scrolling horizontal du texte lorsque la longueur des lignes excède la largeur de la fenêtre d'édition.
XmNscrollVertical
Valeurs possibles : True ou False selon que l'on autorise le scrolling vertical du texte lorsque le texte ne contient plus dans la page en hauteur.
XmNeditMode
Valeurs possibles : XmSINGLE_LINE_EDIT ou XmMULTI_LINE_EDIT selon que l'on désire éditer du texte sur une ou plusieurs lignes.


Mettre du texte dans un Text widget :


La fonction XmTextSetString() met une chaîne de caractère ordinaire (au sens du langage C) dans un Text widget.

Elle accepte deux paramètres :

  1. L'ID du Text widget.
  2. La chaîne de caractères à éditer.

Le petit programme text.c présente un exemple d'utilisation de cette fonction.


Le programme text.c


Ce programme est un petit exemple d'utilisation de Text widget. Il crée un widget de type ScrolledText et affiche à l'intérieur son propre source C : le contenu du programme text.c

L'édition n'est pas autorisée (lors de la création, la ressource XmNeditable vaut False).

Voici un dump d'écran de l'exécution de ce petit programme :

L'exécutable se trouve dans :

    /home/profs/cours/minfo/motif/text/text

Remarque : pour compiler sans erreur il faut inclure le fichier <Xm/Text.h>



#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <Xm/Xm.h>
#include <Xm/Text.h>
#include <Xm/MainW.h>
#include <Xm/CascadeB.h>
#include <Xm/RowColumn.h>

/*--------------------------*/
main(int argc, char *argv[])
/*--------------------------*/
{   
  Widget        top_wid, main_w, menu_bar, 
                menu, quit, help, text_wid;
  XtAppContext  app;
  void          quit_call(), help_call(), read_file();
  Arg           args[10];
  int n;

  /* initialize */
  top_wid = XtVaAppInitialize(&app, "Text",
                       NULL, 0, &argc, argv, NULL, NULL);


  main_w = XtVaCreateManagedWidget("main_w",
                       xmMainWindowWidgetClass, top_wid,
                       /* XmNscrollingPolicy,   XmVARIABLE, */
                       NULL);
   
  menu_bar = XmCreateMenuBar(main_w, "main_list", 
                       NULL, 0);        
  XtManageChild(menu_bar);
      
  /* create quit widget + callback */
        
  quit = XtVaCreateManagedWidget( "Quit",
                       xmCascadeButtonWidgetClass, menu_bar,
                       XmNmnemonic, 'Q',
                       NULL);

  XtAddCallback(quit, XmNactivateCallback, 
                quit_call, NULL);

  /* Create ScrolledText -- this is work area for the 
     MainWindow */
    
  n=0;
  XtSetArg(args[n], XmNrows,      30); n++;
  XtSetArg(args[n], XmNcolumns,   80); n++;
  XtSetArg(args[n], XmNeditable,  False); n++;
  XtSetArg(args[n], XmNeditMode,  XmMULTI_LINE_EDIT); n++;
  text_wid = XmCreateScrolledText(main_w, "text_wid", 
                                  args, n);
  XtManageChild(text_wid);

  /*  read file and put data in text widget */
  read_file(text_wid);
    
  XtRealizeWidget(top_wid);
  XtAppMainLoop(app);
}

/*---------------------------*/
void read_file(Widget  text_wid)
/*---------------------------*/
{
  static char *filename = "text.c";
  char  *text;
  struct stat statb;
  FILE *fp;

  /* check file is a regular text file and open it */

  if ((stat(filename, &statb) == -1) 
       || !(fp = fopen(filename, "r"))) {
    fprintf(stderr, "Cannot open file: %s\n", filename);
    XtFree(filename);
    return;
  }

  /* Map file text in the TextWidget */    
    
  if (!(text = XtMalloc((unsigned)(statb.st_size+1)))) {   
    fprintf(stderr, "Can't alloc enough space for %s", 
            filename);
    XtFree(filename);
    fclose(fp);
    return;
  }


  if (!fread(text, sizeof(char), statb.st_size+1, fp))
    fprintf(stderr, "File read error\n");

  text[statb.st_size] = 0; /* be sure to NULL-terminate */

  /* insert file contents in TextWidget */
  XmTextSetString(text_wid, text);
  
  /* free memory 
   */
  XtFree(text);
  XtFree(filename);
  fclose(fp);
}

/*--------------*/
void quit_call()
/*--------------*/
{   
  printf("Quitting program\n");
  exit(0);
}


EXERCICE : à partir du programme text.c, écrire le programme file_lister.c permettant à l'aide d'un FileSelectionDialog de lister dans un ScrolledText widget le contenu de n'importe quel programme source C.

Dump d'écran du programme (à écrire) file_lister.c :


Edition de texte dans un Text Widget


Attention, je travaille encore sur cette partie du cours...

Remplacement de texte :

La fonction XmTextReplace() permet de remplacer tout ou partie du texte qui se trouve dans un TextWidget.

Paramètres de cette fonction :

Widget
L'ID du Text widget.
StartPosition (de type XmTextPosition)
Un long int (défini dans <Xm/Text.h>) mesuré en bytes. Indique le point d'insertion du texte.
EndPosition (de type XmTextPosition)
Même type que le paramètre précédent. Quelques remarques :

NewText
La chaîne de caractères (au sens du langage C) qui va remplacer le texte situé entre les deux positions StartPosition et EndPosition.

Insertion de texte :

Pour insèrer du texte, il faut utiliser la fonction XmTextInsert().

Elle accepte trois paramètres :

Widget
L'ID du Text widget.
InsertPosition (de type XmTextPosition)
Un long int (défini dans <Xm/Text.h>) mesuré en bytes. Indique le point d'insertion du texte.
String
La chaîne de caractères (au sens du langage C) à insèrer.

Rechercher un texte :

Pour rechercher un texte dans un Text widget, il faut utiliser la fonction XmTextFindString().

Cette fonction possède les paramètres suivants :

Widget
L'ID du Text widget.
StartPosition (de type XmTextPosition)
Un long int (défini dans <Xm/Text.h> mesuré en bytes. Indique la position dans le texte à partir de laquelle la recherche va s'effectuer.
String
La chaîne de caractères que l'on recherche.
SearchDirection
Sens de la recherche. Valeurs possibles : XmTEXT_FORWARD ou XmTEXT_BACKWARD
Position
Un pointeur de type XmTextPosition retourné par la fonction de recherche. Indique à quelle position la chaîne de caractères a été trouvée.

XmTextFindString() renvoie une valeur de type Boolean : True si la chaîne a été trouvée dans le texte, False sinon.

Sauvegarder le contenu d'un Text widget dans un fichier :

La fonction XmTextGetString() permet d'obtenir le contenu d'un Text widget.

Ainsi, pour sauvegarder le contenu d'un Text widget dans un fichier, il suffit simplement de :

Contrôle de l'affichage du texte :

Pour afficher le texte à une position donnée, il faut utiliser la fonction XmTextShowPosition().

Pour positionner une ligne du texte en haut de la fenêtre du ScrolledText widget, il faut utiliser la fonction XmTextSetTopCharacter().

Pour positionner le point d'insertion (le curseur) à une position donnée, il faut utiliser la fonction XmTextSetInsertionPosition().


Callbacks des Text widgets


Attention, je travaille encore sur cette partie du cours.....

Par défaut, un Text widget contient des fonctions d'édition de texte très simples. Si l'on désire un meilleur contrôle sur l'édition, il faut utiliser des fonctions de callback.

MOTIF fournit de nombreuses ressources pour les callbacks des Text widgets. Voici les principales :

XmNactivateCallback
Uniquement pour les TextField ou les Text widgets d'une seule ligne. Ce callback est appelé lorsque l'utilisateur appuie sur la touche Enter.
XmNverifyCallback
Appelé avant un changement dans le texte.
XmNvalueChangedCallback
Appelé après un changement dans le texte.
XmNmotionCallback
Appelé lorsque l'utilisateur a déplacé le curseur ou bien lorsqu'il a effectué une sélection à la souris.
XmNfocusCallback
Appelé lorsque le text widget obtient le focus du clavier.
XmNlosingFocusCallback
Appelé lorsque le text widget perd le focus du clavier.

Les verifyCallbacks peuvent être utilisés pour la saisie de mots de passe par exemple...


michel.buffa@essi.fr