Text editing is a key task in many applications. For example, Single-line editors are a convenient and flexible means of string data entry for many applications. Indeed, the FileSelectionDialog widget (Chapter 9) and other composite widgets have a single text widget as constituent components. More complete multi-line text entry may also be required for many applications.
Motif, conveniently provides a fully functional text widget. This saves the application programmer a lot of work, since tasks such as cut and paste editing, text search and insertion are provided within the widget class.
Note: Coupled with other advanced facilities such as FileSelection widgets etc., we could easily assemble our own fully working text editor application program from component widget classes and little other code.
Motif 1.2 provides two classes of text widgets:
Both the above widgets use the (standard C) String data type as the base structure for all text operations. This is different from most other Motif widgets. Motif 2.0 provides an additional text widget, CSText , which is basically similar to the Text widget except that the XmString data type is used in text processing.
We will study the Text widget in detail in this Chapter. The TextField is, essentially, a simpler version of this and will therefore only be addressed when appropriate. In fact, we can actually make the Text widget a single line type by setting the resource XmNeditMode to XmSINGLE_LINE_EDIT .
There are a variety of ways to create a Text widget:
<Xm/Text.h>
header file for all Text widget
applications. There are corresponding <Xm/TextF.h>
and <Xm/CSText.h>
header files for the TextField amd CSText widgets
respectively.
There are various resources that can be usefully set for a Text widget:
The Text widget is a dynamic structure and text may be inserted into the widget at any time. There are many text editing and insertion functions that will be introduced shortly. The simplest operation is actually setting the text that will be used by the Text widget.
The function XmTextSetString() puts a specified ordinary (C type) string into a specified widget. It has two arguments:
Fig. 10.1 ScrolledText Widget
#include <Xm/Xm.h> #include <Xm/Text.h> #include <Xm/MainW.h> #include <Xm/CascadeB.h> #include <stdio.h> #include <sys/stat.h> #include <sys/types.h> /* Prototype Callback and other functions */ void quit_call(), help_call(), read_file(Widget);
main(int argc, char *argv[]) { Widget top_wid, main_w, menu_bar, menu, quit, help, text_wid; XtAppContext app; Arg args[4]; /* 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 */ XtSetArg(args[0], XmNrows, 30); XtSetArg(args[1], XmNcolumns, 80); XtSetArg(args[2], XmNeditable, False); XtSetArg(args[3], XmNeditMode, XmMULTI_LINE_EDIT); text_wid = XmCreateScrolledText(main_w, "text_wid", args, 4); 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); }
Motif provides many functions that allow the editing of the text (String) stored in the widget. Text can be searched, inserted and replaced.
To replace all or parts of the text in a Text widget use the XmTextReplace() function. It has four arguments:
No matter how long the specified replacement text string is, text is only replaced (character-by-character) between the 2 positions. However, if the start and end positions are equal then text is inserted after the given position.
An alternative method to insert text , is to use the XmTextInsert() function. This takes 3 arguments:
To Search for a string in the Text widget , use the XmTextFindString() function with the following arguments:
XmTextFindString() returns a Boolean value which is False if no string was found.
To obtain text (in full) from a Text widget use the XmTextGetString() function to return a String for a specified widget. An example use of this function is to save text stored in the Text widget to a file. This can be simply achieved by:
The function XmTextGetSubstring() can be used to get a portion of text from a widget. It takes 5 arguments:
Similar functions exist for both the TextField and the CSText widgets. An example of these functions in use with the TextField widget is given is Section 10.7.
Similar functions exist for both the TextField and the CSText widgets. An example of these functions in use with the TextField widget is given is Section 10.7.
Behind almost all of the Text widget functions, described above, lie default callback resources. These control the basic text editing facilities: cut and paste, searching etc. However, there may be occasions when the application may need greater control over things. Several callback resources are provided for this purpose. Briefly theses are:
We can use verifyCallbacks for checking user inputs -- for example for password verification.
The test_for_echo.c program (Section 8.3) illustrates the use of some of the editing and scrolling functions described. The program basically operates as follows:
Exercise 7025
Modify the text.c (Section 10.3) so that it employs a FileSelection widget to allow the user to select a file, which it then reads and displays in a ScrolledText Widget .
MORE EXERCISES