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)
Il existe plusieurs manières de créer un widget de type Text :
Ressources d'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 :
Le petit programme text.c présente un exemple d'utilisation de cette fonction.
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 :
La fonction XmTextReplace() permet de remplacer tout ou partie du texte qui se trouve dans un TextWidget.
Paramètres de cette fonction :
Pour insèrer du texte, il faut utiliser la fonction XmTextInsert().
Elle accepte trois paramètres :
Pour rechercher un texte dans un Text widget, il faut utiliser la fonction XmTextFindString().
Cette fonction possède les paramètres suivants :
XmTextFindString() renvoie une valeur de type Boolean : True si la chaîne a été trouvée dans le texte, False sinon.
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 :
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().
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 :
Les verifyCallbacks peuvent être utilisés pour la saisie de mots de passe par exemple...