}
else { /* reason == FILE_OPEN */
/* make sure the file is a regular text file and open it */
if (stat (filename, &statb) == −1 ||
(statb.st_mode & S_IFMT) != S_IFREG ||
!(fp = fopen (filename, "r"))) {
perror (filename);
sprintf (buf, "Can't read %s.", filename);
XmTextSetString (text_output, buf);
XtFree (filename);
return;
}
/* put the contents of the file in the Text widget by
* allocating enough space for the entire file, reading the
* file into the space, and using XmTextSetString() to show
* the file.
*/
len = statb.st_size;
if (!(text = XtMalloc ((unsigned)(len+1)))) /* +1 for NULL */
sprintf (buf, "%s: XtMalloc(%ld) failed", len, filename);
else {
if (fread (text, sizeof (char), len, fp) != len)
sprintf (buf, "Warning: did not read entire file!");
else
sprintf (buf, "Loaded %ld bytes from %s.", len, filename);
text[len] = 0; /* NULL−terminate */
XmTextSetString (text_edit, text);
}
}
XmTextSetString (text_output, buf); /* purge output message */
/* free all allocated space. */
XtFree (text);
XtFree (filename);
fclose (fp);
XtUnmanageChild (dialog);
}
/* popdown_cb() −− callback routine for "Cancel" button. */
void
popdown_cb (w, client_data, call_data)
Widget w;
XtPointer client_data;
XtPointer call_data;
{
XtUnmanageChild (w);
}
/* file_cb() −− a menu item from the "File" pulldown menu was selected */
void
file_cb(w, client_data, call_data)
Widget w;
XtPointer client_data;
XtPointer call_data;
{
static Widget open_dialog, save_dialog;
Widget dialog = NULL;
XmString button, title;
int reason = (int) client_data;
if (reason == FILE_EXIT)
15 Text Widgets 15.4 A Text Editor
409
exit (0);
XmTextSetString (text_output, NULL); /* clear message area */
if (reason == FILE_OPEN && open_dialog)
dialog = open_dialog;
else if (reason == FILE_SAVE && save_dialog)
dialog = save_dialog;
if (dialog) {
XtManageChild (dialog);
/* make sure that dialog is raised to top of window stack */
XMapRaised (XtDisplay (dialog), XtWindow (XtParent (dialog)));
return;
}
dialog = XmCreateFileSelectionDialog (text_edit, "Files", NULL, 0);
XtAddCallback (dialog, XmNcancelCallback, popdown_cb, NULL);
XtAddCallback (dialog, XmNokCallback, file_select_cb, reason);
if (reason == FILE_OPEN) {
button = XmStringCreateLocalized ("Open");
title = XmStringCreateLocalized ("Open File");
open_dialog = dialog;
}
else { /* reason == FILE_SAVE */
button = XmStringCreateLocalized ("Save");
title = XmStringCreateLocalized ("Save File");
save_dialog = dialog;
}
XtVaSetValues (dialog,
XmNokLabelString, button,
XmNdialogTitle, title,
NULL);
XmStringFree (button);
XmStringFree (title);
XtManageChild (dialog);
}
/* search_cb() −− a menu item from the "Search" pulldown menu selected */
void
search_cb(w, client_data, call_data)
Widget w;
XtPointer client_data;
XtPointer call_data;
{
char *search_pat, *p, *string, *new_pat, buf[256];
XmTextPosition pos = 0;
int len, nfound = 0;
int search_len, pattern_len;
int reason = (int) client_data;
Boolean found = False;
XmTextSetString (text_output, NULL); /* clear message area */
if (reason == SEARCH_CLEAR) {
pos = XmTextGetLastPosition (text_edit);
XmTextSetHighlight (text_edit, 0, pos, XmHIGHLIGHT_NORMAL);
return;
}
if (!(string = XmTextGetString (text_edit)) || !*string) {
15 Text Widgets 15.4 A Text Editor
410
XmTextSetString (text_output, "No text to search.");
return;
}
if (!(search_pat = XmTextGetString (search_text)) || !*search_pat) {
XmTextSetString (text_output, "Specify a search pattern.");
XtFree (string);
return;
}
new_pat = XmTextGetString (replace_text);
search_len = strlen (search_pat);
pattern_len = strlen (new_pat);
if (reason == SEARCH_FIND_NEXT) {
pos = XmTextGetCursorPosition (text_edit) + 1;
found = XmTextFindString (text_edit, pos, search_pat,
XmTEXT_FORWARD, &pos);
if (!found)
found = XmTextFindString (text_edit, 0, search_pat,
XmTEXT_FORWARD, &pos);
if (found)
nfound++;
}
else { /* reason == SEARCH_SHOW_ALL || reason == SEARCH_REPLACE */
do {
found = XmTextFindString (text_edit, pos, search_pat,
XmTEXT_FORWARD, &pos);
if (found) {
nfound++;
if (reason == SEARCH_SHOW_ALL)
XmTextSetHighlight (text_edit, pos, pos + search_len,
XmHIGHLIGHT_SELECTED);
else
XmTextReplace (text_edit, pos, pos + search_len, new_pat);
pos++;
}
}
while (found);
}
if (nfound == 0)
XmTextSetString (text_output, "Pattern not found.");
else {
switch (reason) {
case SEARCH_FIND_NEXT :
sprintf (buf, "Pattern found at position %ld.", pos);
XmTextSetInsertionPosition (text_edit, pos);
break;
case SEARCH_SHOW_ALL :
sprintf (buf, "Found %d occurrences.", nfound);
break;
case SEARCH_REPLACE :
sprintf (buf, "Made %d replacements.", nfound);
}
XmTextSetString (text_output, buf);
}
XtFree (string);
XtFree (search_pat);
XtFree (new_pat);
}
15 Text Widgets 15.4 A Text Editor
411

Get Volume 6A: Motif Programming Manual now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.