home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!olivea!pagesat!netsys!agate!ucbvax!lilbit.UUCP!prakash
- From: prakash@lilbit.UUCP (Prakash Baskaran)
- Newsgroups: comp.windows.x.motif
- Subject: Re: Text widgets - solution with one stroke "delay"
- Message-ID: <9301222210.AA04057@lilbit.tdtech.com>
- Date: 22 Jan 93 17:10:10 GMT
- Sender: daemon@ucbvax.BERKELEY.EDU
- Distribution: inet
- Organization: The Internet
- Lines: 473
-
- >
- > On Jan 21, 5:49pm, Prakash Baskaran wrote:
- >
- > 2. As the user moves around in the text widget using arrow keys or
- > mouse, I would like to show the x,y ( column and line number) in the
- > text widget. Any good ways to do these?
- >
-
- Hello:
-
- I used to following technique to solve the problem. It works allright
- -execpt- that I get the answer one "stroke" later. I am using
- XmNmotionVerifyCallback to return the x, y position of my cursor. And
- I get x,y position for the previous click or movement for my current
- movement and the current positions are printed for the next movement.
- Obviously I am missing something trivial. Can any one guess what it
- is ?
-
- The following is the editor.c of the volume 6, where I have inserted my
- code. Though I get the x,y positions, I guess it would take lots of
- time for bigger texts.
-
- prakash
-
- _____________________________________________________________________________
-
- Prakash Baskaran
- T.D. Technologies, Inc. 12000 Fairhill Rd, #616
- 12608 Cedar Rd. Cleveland, OH 44120
- Cleveland Hts, OH 44106 (216) 791 3554
- (216) 371 9777
-
- lilbit!prakash@skybridge.scl.cwru.edu
-
- Disclaimer: Ya... It's all mine.
- _____________________________________________________________________________
-
-
-
-
- _________
- cut here
- ____________________________
-
- /* Written by Dan Heller. Copyright 1991, O'Reilly && Associates.
- * This program is freely distributable without licensing fees and
- * is provided without guarantee or warrantee expressed or implied.
- * This program is -not- in the public domain.
- */
-
- /* editor.c -- create a full-blown Motif editor application complete
- * with a menubar, facilities to read and write files, text search
- * and replace, clipboard support and so forth.
- */
- #include <Xm/Text.h>
- #include <Xm/LabelG.h>
- #include <Xm/PushBG.h>
- #include <Xm/RowColumn.h>
- #include <Xm/MainW.h>
- #include <Xm/PanedW.h>
- #include <Xm/FileSB.h>
- #include <X11/Xos.h>
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
-
- Widget text_w, search_w, replace_w, text_output;
-
- char *select_to_beginning ( pos, w )
- XmTextPosition pos;
- Widget w;
- {
- char *full_text;
- char *sel_text;
-
- full_text = XmTextGetString ( w );
- sel_text = (char *) malloc ( (pos) * sizeof (char) );
- strncpy ( sel_text, full_text, pos);
- return (sel_text);
- }
-
- void get_number_of_lines_and_chars (selection, lines, chars, pos)
- char *selection;
- int *lines, *chars, pos;
- {
- int i;
-
- for ( i=0; i<pos; i++ )
- {
- if (selection[i] == '\n')
- {
- (*lines)++;
- (*chars) = 0;
- }
- (*chars)++;
- }
- }
-
- void cursor_moved (cb, w, cbs )
- Widget cb, w;
- XmTextVerifyCallbackStruct *cbs;
- {
- char *selection;
- int lines = 0, chars = 0;
-
- if (cbs->reason != XmCR_MOVING_INSERT_CURSOR ) return;
-
- selection = select_to_beginning ( cbs->currInsert, w );
- get_number_of_lines_and_chars (selection, &lines, &chars, cbs->currInsert);
- printf ("x:y = %d, %d\n", lines, chars);
- XtFree ( selection );
- }
-
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- XtAppContext app;
- Widget toplevel, main_w, menubar, pane, rowcol, pb;
- void file_cb(), cut_paste(), search_cb();
- Arg args[5];
- XmString new, save, quit, quit_acc, file, edit, cut,
- clear, copy, paste, search, next, find, replace;
-
- toplevel = XtVaAppInitialize(&app, "Demos",
- NULL, 0, &argc, argv, NULL, NULL);
-
- main_w = XtVaCreateWidget("main_w",
- xmMainWindowWidgetClass, toplevel, NULL);
-
- /* Create a simple MenuBar that contains three menus */
- file = XmStringCreateSimple("File");
- edit = XmStringCreateSimple("Edit");
- search = XmStringCreateSimple("Search");
- menubar = XmVaCreateSimpleMenuBar(main_w, "menubar",
- XmVaCASCADEBUTTON, file, 'F',
- XmVaCASCADEBUTTON, edit, 'E',
- XmVaCASCADEBUTTON, search, 'S',
- NULL);
- XmStringFree(file);
- XmStringFree(edit);
- XmStringFree(search);
-
- /* First menu is the File menu -- callback is file_cb() */
- new = XmStringCreateSimple("New ...");
- save = XmStringCreateSimple("Save ...");
- quit = XmStringCreateSimple("Quit");
- quit_acc = XmStringCreateSimple("Ctrl-C");
- XmVaCreateSimplePulldownMenu(menubar, "file_menu", 0, file_cb,
- XmVaPUSHBUTTON, new, 'N', NULL, NULL,
- XmVaPUSHBUTTON, save, 'S', NULL, NULL,
- XmVaSEPARATOR,
- XmVaPUSHBUTTON, quit, 'Q', "Ctrl<Key>c", quit_acc,
- NULL);
- XmStringFree(new);
- XmStringFree(save);
- XmStringFree(quit);
- XmStringFree(quit_acc);
-
- /* ...create the "Edit" menu -- callback is cut_paste() */
- cut = XmStringCreateSimple("Cut"); /* create a simple */
- copy = XmStringCreateSimple("Copy"); /* pulldown menu that */
- clear = XmStringCreateSimple("Clear"); /* has these menu */
- paste = XmStringCreateSimple("Paste"); /* items in it. */
- XmVaCreateSimplePulldownMenu(menubar, "edit_menu", 1, cut_paste,
- XmVaPUSHBUTTON, cut, 'C', NULL, NULL,
- XmVaPUSHBUTTON, copy, 'o', NULL, NULL,
- XmVaPUSHBUTTON, paste, 'P', NULL, NULL,
- XmVaSEPARATOR,
- XmVaPUSHBUTTON, clear, 'l', NULL, NULL,
- NULL);
- XmStringFree(cut);
- XmStringFree(copy);
- XmStringFree(paste);
-
- /* create the "Search" menu -- callback is search_cb() */
- next = XmStringCreateSimple("Find Next");
- find = XmStringCreateSimple("Show All");
- replace = XmStringCreateSimple("Replace Text");
- XmVaCreateSimplePulldownMenu(menubar, "search_menu", 2, search_cb,
- XmVaPUSHBUTTON, next, 'F', NULL, NULL,
- XmVaPUSHBUTTON, find, 'S', NULL, NULL,
- XmVaPUSHBUTTON, replace, 'R', NULL, NULL,
- XmVaSEPARATOR,
- XmVaPUSHBUTTON, clear, 'C', NULL, NULL,
- NULL);
- XmStringFree(next);
- XmStringFree(find);
- XmStringFree(replace);
- XmStringFree(clear);
-
- XtManageChild(menubar);
-
- /* create a standard vertical PanedWindow... */
- pane = XtVaCreateWidget("pane",
- xmPanedWindowWidgetClass, main_w, NULL);
-
- /* create horizontal RowColumn inside the pane... */
- rowcol = XtVaCreateWidget("rowcol",
- xmRowColumnWidgetClass, pane,
- XmNorientation, XmHORIZONTAL,
- XmNpacking, XmPACK_TIGHT,
- NULL);
- /* Create two Text widgets with Labels... */
- XtVaCreateManagedWidget("Search Pattern:",
- xmLabelGadgetClass, rowcol, NULL);
- search_w = XtVaCreateManagedWidget("search_text",
- xmTextWidgetClass, rowcol, NULL);
- XtVaCreateManagedWidget(" Replace Pattern:",
- xmLabelGadgetClass, rowcol, NULL);
- replace_w = XtVaCreateManagedWidget("replace_text",
- xmTextWidgetClass, rowcol, NULL);
- XtManageChild(rowcol);
-
- text_output = XtVaCreateManagedWidget("text_out",
- xmTextWidgetClass, pane,
- XmNeditable, False,
- XmNcursorPositionVisible, False,
- XmNshadowThickness, 0,
- XmNsensitive, False,
- NULL);
-
- XtSetArg(args[0], XmNrows, 10);
- XtSetArg(args[1], XmNcolumns, 80);
- XtSetArg(args[2], XmNeditMode, XmMULTI_LINE_EDIT);
- text_w = XmCreateScrolledText(pane, "text_w", args, 3);
- XtManageChild(text_w);
-
- XtAddCallback ( text_w, XmNmotionVerifyCallback, cursor_moved, text_w);
-
- XtManageChild(pane);
- XtManageChild(main_w);
-
- XtRealizeWidget(toplevel);
- XtAppMainLoop(app);
- }
-
- /* callback routine for "Ok" button in FileSelectionDialogs */
- void
- open_file(dialog, save, cbs)
- Widget dialog;
- int save; /* actually, item_no from "new" or "save" */
- XmFileSelectionBoxCallbackStruct *cbs;
- {
- char buf[BUFSIZ], *filename, *text;
- struct stat statb;
- long len;
- FILE *fp;
-
- if (!XmStringGetLtoR(cbs->value,
- XmSTRING_DEFAULT_CHARSET, &filename))
- return; /* must have been an internal error */
-
- if (!*filename) {
- XtFree(filename);
- XBell(XtDisplay(text_w), 50);
- XmTextSetString(text_output, "Choose a file.");
- return; /* nothing typed */
- }
-
- if (save) {
- if (!(fp = fopen(filename, "w"))) {
- perror(filename);
- sprintf(buf, "Can't save to %s.", filename);
- XmTextSetString(text_output, buf);
- XtFree(filename);
- return;
- }
- /* saving -- get text from Text widget... */
- text = XmTextGetString(text_w);
- len = XmTextGetLastPosition(text_w);
- /* write it to file (check for error) */
- if (fwrite(text, sizeof(char), len, fp) != len)
- strcpy(buf, "Warning: did not write entire file!");
- else {
- /* make sure a newline terminates file */
- if (text[len-1] != '\n')
- fputc('\n', fp);
- sprintf(buf, "Saved %ld bytes to %s.", len, filename);
- }
- } else {
- /* 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_w, text);
- }
- }
- XmTextSetString(text_output, buf); /* purge output message */
-
- /* free all allocated space. */
- XtFree(text);
- XtFree(filename);
- fclose(fp);
- }
-
- /* a menu item from the "File" pulldown menu was selected */
- void
- file_cb(w, item_no, cbs)
- Widget w;
- int item_no; /* pulldown menu item number */
- XmAnyCallbackStruct *cbs; /* unused here */
- {
- static Widget open_dialog, save_dialog;
- Widget dialog = NULL;
- XmString str, title;
-
- if (item_no == 2)
- exit(0);
-
- if (item_no == 0 && open_dialog)
- dialog = open_dialog;
- else if (item_no == 1 && 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_w, "Files", NULL, 0);
- XtAddCallback(dialog, XmNcancelCallback, XtUnmanageChild, NULL);
- XtAddCallback(dialog, XmNokCallback, open_file, item_no);
- if (item_no == 0) {
- str = XmStringCreateSimple("Open");
- title = XmStringCreateSimple("Open File");
- open_dialog = dialog;
- } else {
- str = XmStringCreateSimple("Save");
- title = XmStringCreateSimple("Save File");
- save_dialog = dialog;
- }
- XtVaSetValues(dialog,
- XmNokLabelString, str,
- XmNdialogTitle, title,
- NULL);
- XmStringFree(str);
- XmStringFree(title);
- XtManageChild(dialog);
- }
-
- /* a menu item from the "Search" pulldown menu was selected */
- void
- search_cb(w, item_no, cbs)
- Widget w;
- int item_no; /* pulldown menu item number */
- XmAnyCallbackStruct *cbs; /* unused here */
- {
- #define FIND_NEXT 0
- #define FIND_ALL 1
- #define REPLACE 2
- #define CLEAR 3
- char *search_pat, *p, *string, *new_pat, buf[32];
- XmTextPosition pos = 0;
- int len, nfound = 0;
- int search_len, pattern_len;
-
- if (item_no == CLEAR) {
- pos = XmTextGetLastPosition(text_w);
- XmTextSetHighlight(text_w, 0, pos, XmHIGHLIGHT_NORMAL);
- return;
- }
-
- if (!(string = XmTextGetString(text_w)) || !*string) {
- XmTextSetString(text_output, "No text to search.");
- return;
- }
- if (!(search_pat = XmTextGetString(search_w)) || !*search_pat) {
- XmTextSetString(text_output, "Specify a search pattern.");
- XtFree(string);
- return;
- }
-
- new_pat = XmTextGetString(replace_w);
- search_len = strlen(search_pat);
- pattern_len = strlen(new_pat);
-
- /* start searching at current cursor position + 1 */
- if (item_no == FIND_NEXT)
- pos = XmTextGetCursorPosition(text_w) + 1;
- for (p = &string[pos]; p = index(p, *search_pat); p++)
- if (!strncmp(p, search_pat, search_len)) {
- nfound++;
- /* get the position where pattern was found */
- pos = (XmTextPosition)(p-string);
- if (item_no == REPLACE) {
- /* replace the text position + strlen(new_pat) */
- XmTextReplace(text_w, pos, pos + search_len, new_pat);
- /* "string" has changed -- get the new value */
- XtFree(string);
- string = XmTextGetString(text_w);
- /* continue search -after- replacement */
- p = &string[pos + pattern_len];
- } else if (item_no == FIND_ALL)
- XmTextSetHighlight(text_w, pos, pos+search_len,
- XmHIGHLIGHT_SELECTED);
- else
- break;
- }
- if (item_no == FIND_NEXT && nfound == 0) {
- /* search from beginning till we've passed "pos" */
- for (p = string; p = index(p, *search_pat); p++)
- if (p - string > pos ||
- !strncmp(p, search_pat, search_len)) {
- nfound++;
- break;
- }
- }
- if (nfound == 0)
- XmTextSetString(text_output, "Pattern not found.");
- else {
- switch (item_no) {
- case FIND_NEXT :
- pos = (XmTextPosition)(p - string);
- sprintf(buf, "Pattern found at position %ld.", pos);
- XmTextSetInsertionPosition(text_w, pos);
- break;
- case FIND_ALL :
- sprintf(buf, "Found %d occurrences.", nfound);
- break;
- case REPLACE :
- default :
- sprintf(buf, "Made %d replacements.", nfound);
- }
- XmTextSetString(text_output, buf);
- }
- XtFree(string);
- XtFree(search_pat);
- XtFree(new_pat);
- }
-
- /* the callback routine for the items in the edit menu */
- void
- cut_paste(widget, num)
- Widget widget; /* the menu item (pushbutton) that was selected */
- int num; /* the menu item number */
- {
- Boolean result = True;
-
- switch (num) {
- case 0 : result = XmTextCut(text_w, CurrentTime); break;
- case 1 : result = XmTextCopy(text_w, CurrentTime); break;
- case 2 : result = XmTextPaste(text_w);
- case 3 : XmTextClearSelection(text_w, CurrentTime); break;
- }
- if (result == False)
- XmTextSetString(text_output, "There is no selection.");
- else
- XmTextSetString(text_output, NULL);
- }
-