/* srch_act.c - part of asedit program */ /* * Copyright 1991 - 1994, Andrzej Stochniol, London, UK * * ASEDIT text editor, both binary and source (hereafter, Software) is * copyrighted by Andrzej Stochniol (hereafter, AS) and ownership remains * with AS. * * AS grants you (hereafter, Licensee) a license to use the Software * for academic, research and internal business purposes only, without a * fee. Licensee may distribute the binary and source code (if released) * to third parties provided that the copyright notice and this statement * appears on all copies and that no charge is associated with such copies. * * Licensee may make derivative works. However, if Licensee distributes * any derivative work based on or derived from the Software, then * Licensee will: * (1) notify AS regarding its distribution of the derivative work, and * (2) clearly notify users that such derivative work is a modified version * and not the original ASEDIT distributed by AS. * * Any Licensee wishing to make commercial use of the Software should * contact AS to negotiate an appropriate license for such commercial use. * Commercial use includes: * (1) integration of all or part of the source code into a product for sale * or license by or on behalf of Licensee to third parties, or * (2) distribution of the binary code or source code to third parties that * need it to utilize a commercial product sold or licensed by or on * behalf of Licensee. * * A. STOCHNIOL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS * SOFTWARE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR * IMPLIED WARRANTY. IN NO EVENT SHALL A. STOCHNIOL BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * By using or copying this Software, Licensee agrees to abide by the * copyright law and all other applicable laws, and the terms of this * license. * AS shall have the right to terminate this license immediately by * written notice upon Licensee's breach of, or non-compliance with, any * of its terms. Licensee may be held legally responsible for any * copyright infringement that is caused or encouraged by Licensee's * failure to abide by the terms of this license. * * * Andrzej Stochniol (A.Stochniol@ic.ac.uk) * 30 Hatch Road * London SW16 4PN * UK */ #include #include #include #include #include #include "asedit.h" #ifdef _NO_PROTO /* prototypes for non-ANSI systems follow ... */ static void asedit_find(); static void asedit_change(); static void asedit_mark_set(); static void asedit_mark_goto(); static void asedit_undo(); static void asedit_redo(); static void asedit_forward_match(); static void asedit_backward_match(); #else /* ! _NO_PROTO, ANSI prototypes follow */ static void asedit_find(Widget w, XEvent *event, char **params, Cardinal *num_params); static void asedit_change(Widget w, XEvent *event, char **params, Cardinal *num_params); static void asedit_mark_set(Widget w, XEvent *event, char **params, Cardinal *num_params); static void asedit_mark_goto(Widget w, XEvent *event, char **params, Cardinal *num_params); static void asedit_undo(Widget w, XEvent *event, char **params, Cardinal *num_params); static void asedit_redo(Widget w, XEvent *event, char **params, Cardinal *num_params); static void asedit_forward_match(Widget w, XEvent *event, char **params, Cardinal *num_params); static void asedit_backward_match(Widget w, XEvent *event, char **params, Cardinal *num_params); #endif /* end of conditional _NO_PROTO prototypes compilation */ /* extra actions for edit text widgets */ XtActionsRec AseditExtraActionsTable[] = { {"asedit-find", (XtActionProc)asedit_find}, {"asedit-change", (XtActionProc)asedit_change}, {"asedit-mark-set", (XtActionProc)asedit_mark_set}, {"asedit-mark-goto", (XtActionProc)asedit_mark_goto}, {"asedit-undo", (XtActionProc)asedit_undo}, {"asedit-redo", (XtActionProc)asedit_redo}, {"asedit-forward-match", (XtActionProc)asedit_forward_match}, {"asedit-backward-match", (XtActionProc)asedit_backward_match}, }; Cardinal lenAseditExtraActionsTable = XtNumber(AseditExtraActionsTable); /***************************** find_string ******************************** * * finds the string search_string in the text widget "win->edit_text" */ #ifdef _NO_PROTO void find_string( win, start) aseditWindowStruct *win; Boolean start; #else /* ! _NO_PROTO */ void find_string(aseditWindowStruct *win, Boolean start) #endif { /* "start" must be True when this procedure is called to start the find process and it must be False when it is called second time when the bottom or top of the file has been reached in the previous call */ /* first_pos, last_pos - are set to show the position of the found text */ long len, position, start_position, end_position; long buf_size; String text_buffer; Arg al[2]; register int ac; Boolean search_forward= True; /* default search direction */ Boolean case_sensitive= True; Boolean whole_words_only= False; char work[256]; XmString xmstr; /* work XmString */ len = strlen(win->search_string); if(len == 0L) { show_error_message(win, (char *) lstr.sm_have_to_enter); win->found_string_start_pos = -1L; /* to avoid continuing the replace action */ return; } /* get the state of case_sensitive and whole_words_only toggles (if created) */ if(win->case_sensitive_toggle) case_sensitive = XmToggleButtonGetState (win->case_sensitive_toggle); if(win->whole_words_only_toggle) whole_words_only = XmToggleButtonGetState (win->whole_words_only_toggle); /* get the copy of the internally stored text and the cursor position (i.e. starting position) */ XtSetArg(al[0], XmNvalue, &text_buffer); XtSetArg(al[1], XmNcursorPosition, &start_position); XtGetValues(win->edit_text, al, 2); buf_size = (long) strlen(text_buffer); if(start) { /* get the state of search_forward toggle gadget (if available)*/ if (win->forward_toggle) search_forward = XmToggleButtonGadgetGetState (win->forward_toggle); /* save values for next call */ win->cntSearch.forward = search_forward; win->cntSearch.startPosition = start_position; end_position = -1L; /* search up to the edge of the file (i.e. up to the end for forward search, up to the beginning for the backward search */ } else { start_position = -1; /* start at the beginning or at the end of the file (dependent on the search direction) */ end_position = win->cntSearch.startPosition; /* do not go beyond the overall start position; finish off the search */ search_forward = win->cntSearch.forward; /* use the saved value */ } /* find a search string position in the text widget buffer; if the position is < 0 the string has not been found, therefore pop up appriopriate dialog; if position >= 0 OK go there ... */ position = find_string_pos_in_buffer(win->search_string, text_buffer, start_position, end_position, search_forward, case_sensitive, whole_words_only); if(position >= 0L) { /* set the first and last position of the text found */ win->found_string_start_pos = position; win->found_string_end_pos = position + len; /* for the forward search set the cursor to be posittioned after the string found, for the backward search - before the string found */ if(search_forward) position += len; /* set the selection for the text found */ /* XmTextSetSelection also sets the position of the insert cursor to last_pos and then invokes the widget's XmNmotionVerifyCallback */ XmTextSetSelection(win->edit_text, win->found_string_start_pos, win->found_string_end_pos, win->timestamp_search_request); /* set the cursor position; next search will start from that place */ XmTextSetInsertionPosition(win->edit_text, position); } else { win->found_string_start_pos = win->found_string_end_pos = -1; /* the search was unsuccessful */ if(!start || (win->cntSearch.forward && win->cntSearch.startPosition == 0L) || (!win->cntSearch.forward && win->cntSearch.startPosition == buf_size)) { show_error_message(win, (char *)lstr.sm_not_found); } else { /* show that a search might be continued from the edges of the file, i.e. ask a question about continuing the find process */ win->cntSearch.on = True; /* to recognise the reason for the question */ if(win->cntSearch.forward) strcpy(work, (char *)lstr.sq_doc_end); else strcpy(work, (char *)lstr.sq_doc_beg); xmstr = XmStringCreateLtoR(work, charset); if(win->continue_search_question == NULL) /* create it first */ create_continue_search_question(win); ac = 0; XtSetArg(al[ac], XmNmessageString, xmstr ); ac++; XtSetValues(win->continue_search_question, al, ac); asManageDialog(win->continue_search_question); XmStringFree(xmstr); /* free memory allocated for XmString */ } } XtFree(text_buffer); return; } /* find_string */ /***************************** change_all_found_strings ******************* * * find all strings in the text widget and change them to a new string * without asking for confirmation */ #ifdef _NO_PROTO void change_all_found_strings(win, start) aseditWindowStruct *win; Boolean start; #else /* ! _NO_PROTO */ void change_all_found_strings(aseditWindowStruct *win, Boolean start) #endif { /* "start" must be True when this procedure is called to start the process of changing of all text occurrences; and it must be False when it is called second time when the bottom or top of the file has been reached in the previous call */ long len, position, start_position, end_position; long first_pos, last_pos; /* positions of the text found */ long buf_size, new_string_len; String text_buffer; Arg al[2]; register int ac; char work[256]; XmString xmstr; /* work XmString */ len = strlen(win->search_string); new_string_len = strlen(win->new_string); if(len == 0L) { show_error_message(win, (char *) lstr.sm_have_to_enter); win->found_string_start_pos = -1L; /* to avoid continuing the replace action */ return; } if(start) { /* get the state of search_forward toggle gadget - only when the whole search is started (we don't allow the user to change it during the whole process; otherwise it would be difficult to find out when the whole process is finished) */ win->chgAll.searchForward = XmToggleButtonGadgetGetState (win->forward_toggle); /* get the state of case_sensitive and whole_words_only toggles */ win->chgAll.caseSensitive = XmToggleButtonGetState (win->case_sensitive_toggle); win->chgAll.wholeWordsOnly = XmToggleButtonGetState (win->whole_words_only_toggle); /* get the address of the internally stored text and the cursor position (i.e. starting position) */ XtSetArg(al[0], XmNvalue, &text_buffer); XtSetArg(al[1], XmNcursorPosition, &start_position); XtGetValues(win->edit_text, al, 2); win->chgAll.itemsChanged = 0; win->chgAll.startPosition = start_position; end_position = -1; /* search up to the edge of the file (i.e. up to the end for forward search, up to the beginning for the backward search */ } else { /* get the address of the internally stored text */ XtSetArg(al[0], XmNvalue, &text_buffer); XtGetValues(win->edit_text, al, 1); start_position = -1; /* start at the beginning or at the end of the file (dependent on the search direction) */ end_position = win->chgAll.startPosition; /* do not go beyond the overall start position; finish off the search */ } /* find a search string position in the text widget buffer; if the position is < 0 the string has not been found, therefore pop up appriopriate dialog; if position >= 0 OK go there ... */ position = find_string_pos_in_buffer(win->search_string, text_buffer, start_position, end_position, win->chgAll.searchForward, win->chgAll.caseSensitive, win->chgAll.wholeWordsOnly); while (position >= 0L) { /* the position returned always shows the first character of the string found, no matter if we search forward or backward so we can set the first and last position of the text found as follows: */ /* set the first and last position of the found text */ first_pos = position; last_pos = position+len; /* to speed the process of changing we do not mark the found text nor we change the cursor position during the substitution process */ XmTextReplace(win->edit_text, first_pos, last_pos, win->new_string); win->chgAll.itemsChanged++; /* increase the counter */ /* move the starting position of the search to start a new search just after the text changed (or before it for a backward search) */ if(win->chgAll.searchForward) start_position = last_pos + (new_string_len - len); else start_position = first_pos; /* update the win->chgAll.startPosition in the case when the text was changed before it (take into account a difference in the length)*/ if(position < win->chgAll.startPosition) win->chgAll.startPosition += (new_string_len - len); if(win->chgAll.startPosition < 0) win->chgAll.startPosition = 0; XtFree(text_buffer); /* get the address of the internally stored text (it may have been changed) and search again */ XtSetArg(al[0], XmNvalue, &text_buffer); XtGetValues(win->edit_text, al, 1); /* set the end_position of the search appropriately to the mode of the search (up to the edge of the file or finish off the search beyond the edge of the file) */ if(!start) end_position = win->chgAll.startPosition; /* else = -1 */ position = find_string_pos_in_buffer(win->search_string, text_buffer, start_position, end_position, win->chgAll.searchForward, win->chgAll.caseSensitive, win->chgAll.wholeWordsOnly); } /* convert the the last found position (that is = the start of the unsuccessful search) into the line & column number and display them; set the cursor position to it */ XtSetArg(al[0], XmNcursorPosition, start_position); XtSetValues(win->edit_text, al, 1); buf_size = (long) strlen(text_buffer); if(win->status_line_on) /* calculate line & column only when they are shown */ { textPosToLineColumn(text_buffer, buf_size, start_position, win->tabsize, &(win->line), &(win->column), &(win->column_ntab) ); write_ll(win->line_number, charset, "%-5ld", win->line); write_ll(win->column_number, charset, "%-4ld", win->column); } XtFree(text_buffer); if(!start || (win->chgAll.searchForward && win->chgAll.startPosition == 0L) || (!win->chgAll.searchForward && win->chgAll.startPosition == buf_size)) { /* 3 situations may generate the end of the search message: - it was a second call to this procedure to finish off the previous search starting from the beginning (or the end) up to the overall start - it was a forward search started right from the text beginning, - it was a backward search started right from the text end */ sprintf(work, (char *)lstr.sm_change_all_completed, win->chgAll.itemsChanged); xmstr = XmStringCreateLtoR(work, charset); if(win->search_end_message == NULL) /* create it first */ create_search_end_message(win); ac = 0; XtSetArg(al[ac], XmNmessageString, xmstr ); ac++; XtSetValues(win->search_end_message, al, ac); XmStringFree(xmstr); /* free memory allocated for XmString */ asManageDialog(win->search_end_message); } else { /* a question about continuing the change process is asked */ if(win->chgAll.searchForward) strcpy(work, (char *)lstr.sq_doc_end); else strcpy(work, (char *)lstr.sq_doc_beg); xmstr = XmStringCreateLtoR(work, charset); if(win->continue_search_question == NULL) /* create it first */ create_continue_search_question(win); ac = 0; XtSetArg(al[ac], XmNmessageString, xmstr ); ac++; XtSetValues(win->continue_search_question, al, ac); /* set a logical value in cntSearch to show that the change all calls continue search question */ win->cntSearch.on = False; asManageDialog(win->continue_search_question); XmStringFree(xmstr); /* free memory allocated for XmString */ } return; } /* change_all_found_strings */ /* some simple utility functions ..... (self explanatory) */ #ifdef _NO_PROTO void set_change_buttons_sensitivity(win, state) aseditWindowStruct *win; Boolean state; #else /* ! _NO_PROTO */ void set_change_buttons_sensitivity(aseditWindowStruct *win, Boolean state) #endif { /* when state = False - turn off the sensitivity of the "action" buttons of the change dialog and set the default button the cancel ("Close") button; when state = True - restore the default sensitive state of the "action" buttons and restore the default button to the Ok */ Arg al[2]; register int ac; /* set the appropriate default button */ /* DO that before setting sensitivities !!!! */ ac = 0; if(state == True) { /* in Motif 1.2.2 on SGI (IRIX5) setting default Button does not work; moreover when we set afterwards the change_verify_button to insensitive the program dumps!!! so as from 11.01. we distinguish between the old and the new method of setting the default button (the new being setting the traversal ) */ if(xmUseVersion < 1002) /* the old */ { XtSetArg(al[ac], XmNdefaultButton, win->change_verify_button); ac++; } else { XtSetSensitive(win->change_verify_button, state); /* first make it sensitive otherwise the traversal would not take place !!! */ XFlush(display); XmProcessTraversal(win->change_verify_button, XmTRAVERSE_CURRENT); } } else { /* set the deafult button to the Cancel button; otherwise when we press Enter the "change_verify_button" is activated no matter that it is actually insensitive (in Motif 1.0, 1.1) */ if(xmUseVersion < 1002) { XtSetArg(al[ac], XmNdefaultButton, win->cancel_replace_dialog_button); ac++; } else XmProcessTraversal(win->cancel_replace_dialog_button, XmTRAVERSE_CURRENT); } if(xmUseVersion < 1002) XtSetValues(win->replace_dialog, al, ac); /* set the sensitivity of the change buttons sensitivity */ XtSetSensitive(win->change_verify_button, state); XtSetSensitive(win->change_all_button, state); /* as of 1.25 we set the editable status of the text widgets as well !!! so the user will never attempt to change them during the change process */ ac = 0; XtSetArg(al[ac],XmNeditable, state); ac++; XtSetValues(win->text_to_find, al, ac); XtSetValues(win->new_text, al, ac); } /* set_change_buttons_sensitivity */ /***************************** go_to_line ******************************** * * go to a specified line in "win->edit_text" */ #ifdef _NO_PROTO void go_to_line( win, line_no, setTopCharacter) aseditWindowStruct *win; long line_no; Boolean setTopCharacter; #else /* ! _NO_PROTO */ void go_to_line(aseditWindowStruct *win, long line_no, Boolean setTopCharacter) #endif { long position, found_lines; String text_buffer; char work[326]; Arg al[3]; register int ac; /* get a copy of the internally stored text */ XtSetArg(al[0], XmNvalue, &text_buffer); XtGetValues(win->edit_text, al, 1); /* find a position of the line in the text widget buffer; if the position is < 0 the line has not been found, therefore pop up appriopriate dialog; if position >= 0 OK go there ... */ position = find_line_pos(line_no, text_buffer, &found_lines); XtFree(text_buffer); if(position >= 0L) { /* setting the topCharacter and insertionPosition via convenience functions; the XtSetValues method apparently doesn't work on AIX 1.2.3 Motif version; Note also, that we use XmTextShowPosition to defend from autoShowCursorPosition set fo False. */ XmTextSetInsertionPosition(win->edit_text, position); if(setTopCharacter) XmTextSetTopCharacter(win->edit_text, position); XmTextShowPosition(win->edit_text, position); /* display the line & column numbers (column = 1) */ win->line = line_no; /* global value of line & column */ win->column = 1; win->column_ntab = 1; write_ll(win->line_number, charset, "%-5ld", win->line); write_ls(win->column_number, charset, "%s", "1 "); } else { sprintf(work, (char *)lstr.sm_line_range, found_lines); show_error_message(win, work); } } /* go_to_line */ typedef struct { char c; char mate; int impliedDirection; } delimiterPair; enum pairImpliedDirection { IMPLIED_BACKWARD = -1, IMPLIED_NONE, IMPLIED_FORWARD}; /* Note that we might have directional and nondirectional matching. Braces, brackets and parentheses are directional; suppose we tell the editor to find the match for an opening brace ({) or bracket ([). The matching delimiter can't be located before the one you've selected so even if you've requested search backward we have to force the search forward (etc.) (so both commands Ctrl+Q, Ctrl+[ and Ctrl+Q, Ctrl+], or alternative ones, would do for directional pair maching). However, if you tell the editor to find the match for a double quote (") or a single quote ('), it doesn't know automatically which way to go. You must specify the search direction by giving the correct match pair command. If you give the command Ctrl+Q, Ctrl+[, the editor searches forward for the match; if you give the command Ctrl+Q, Ctrl+], it searches backward for the match. Note also that all pairs that are nondirectional (direction is not implied) are not nestable as well (because the left and right characters are the same). */ static delimiterPair pairs[] = { {'{', '}', IMPLIED_FORWARD}, {'(', ')', IMPLIED_FORWARD}, {'[', ']', IMPLIED_FORWARD}, {'<', '>', IMPLIED_FORWARD}, {'}', '{', IMPLIED_BACKWARD}, {')', '(', IMPLIED_BACKWARD}, {']', '[', IMPLIED_BACKWARD}, {'>', '<', IMPLIED_BACKWARD}, {'"', '"', IMPLIED_NONE}, {'`', '`', IMPLIED_NONE}, {'/', '/', IMPLIED_NONE}, {'\'', '\'', IMPLIED_NONE}, {'\\', '\\', IMPLIED_NONE}, }; /* find_mate_pos_in_buffer returns position of the found string in the character buffer; if the text has not been found (or in case of error) returns negative number; The search is started from startpos and is carried forward when "forward" is True (when "forward" is False the search direction is backward). The search is case sensitive for case_sensitive=True and only whole words are found when whole_words_only=True. The startpos and endpos should contain the range where the string should be searched for. When startpos or endpos is < 0 the default value will be assigned for it inside the procedure (i.e. beginnning or end of the file ); */ #ifdef _NO_PROTO long find_mate_pos_in_buffer(buf, c , mate, startpos, endpos, forward) char *buf; char c; char mate; long startpos; long endpos; Boolean forward; #else /* _NO_PROTO */ long find_mate_pos_in_buffer(char *buf, char c, char mate, long startpos, long endpos, Boolean forward) #endif { long pos = -1L; long buf_size = (long) strlen(buf); register long i, n; int nestLevel; if(buf_size <= 0L) return(-2L); /* setting the default value for negative startpos and/or endpos */ if(startpos < 0L) { if(forward) startpos = 0L; else startpos = buf_size; } if(endpos < 0L) { if(forward) endpos = buf_size; else endpos = 0L; } /* test (and correct) the search range */ if(endpos > buf_size) endpos=buf_size; if(startpos > buf_size) startpos=buf_size; nestLevel = 1; /* keeps track of how many delimiter levels the search enters and exits */ if(forward) { /* search forward starting from startpos position */ for( i = startpos; i < endpos; i++) { if(buf[i] == mate) nestLevel--; else if(buf[i] == c) nestLevel++; if(nestLevel == 0) { pos = i; break; /* mate found: now "i" shows position of the mate in the buffer relatively to the buffer beginning */ } } } else { /* search backward starting from startpos-1 position */ for( i = startpos-1; i >= endpos; i--) { if(buf[i] == mate) nestLevel--; else if(buf[i] == c) nestLevel++; if(nestLevel == 0) { pos = i; break; /* mateg found: now "i" shows position of the mate in the buffer relatively to the buffer beginning */ } } } return(pos); } /* find_mate_pos_in_buffer */ #ifdef _NO_PROTO void findDelimiterMate(win, forward) aseditWindowStruct *win; Boolean forward; #else /* _NO_PROTO */ void findDelimiterMate(aseditWindowStruct *win, Boolean forward) #endif { XmTextPosition pos, startpos, matepos; Arg al[1]; /* arg list */ int i, n_pairs, id = -1, status; char *txt=NULL, sub_txt[10]; char c='\0'; /* get the value of the cursor position */ XtSetArg(al[0], XmNcursorPosition, &pos); XtGetValues(win->edit_text, al, 1); if(pos >= 0) { /* the cursor is positioned just before the delimiter in question */ n_pairs = XtNumber(pairs); /* get the single character to speed the process when a user calls this procedure for a wrong character */ txt = getTextSubstring(win->edit_text, pos, 1); if(!txt) return; /* should not happen */ c = txt[0]; /* character for the pair */ XtFree(txt); /* find the pair */ for(i=0; i= 0) { /* the normal call for an existing pair; process it */ /* get the whole edit buffer now */ txt = (char *)XmTextGetString(win->edit_text); if(!txt) return; /* should not happen */ if(pairs[id].impliedDirection == IMPLIED_FORWARD) forward = True; /* reset the flag */ else if(pairs[id].impliedDirection == IMPLIED_BACKWARD) forward = False; else ; /* do no change forward flag */ if(forward) startpos = pos+1; /* starting position for search */ else startpos = pos; matepos = find_mate_pos_in_buffer(txt, pairs[id].c , pairs[id].mate, startpos, -1L, forward); if(matepos >= 0) { if(lstr.selectDelimitedText) /* select delimited text */ { if(matepos < pos) XmTextSetSelection(win->edit_text, matepos, pos+1, win->timestamp_search_request); else XmTextSetSelection(win->edit_text, pos, matepos+1, win->timestamp_search_request); } XmTextSetInsertionPosition(win->edit_text, matepos); } } if(txt) XtFree(txt); /* free the memory */ } } /* findDelimiterMate */ /************************** find_win_for_edit_text ************************ finds asedit win structure for the given edit_text windget (a win element) */ #ifdef _NO_PROTO static aseditWindowStruct * find_win_for_edit_text(edit_text) Widget edit_text; #else /* ! _NO_PROTO */ static aseditWindowStruct * find_win_for_edit_text(Widget edit_text) #endif { aseditWindowStruct *wc=NULL; /* current window */ /* DO that for all asedit windows .... */ wc = asedit_last_window; /* start from the last */ if(wc == NULL) return(wc); /* sanity check */ do /* loop until there is no previous window */ { if( wc->edit_text == edit_text) break; /* FOUND */ wc = wc->prev; } while(wc); /* if not found, returns NULL */ return(wc); } /* find_win_for_edit_text */ #ifdef _NO_PROTO static void asedit_undo(w, event, params, num_params) Widget w; XEvent *event; char **params; Cardinal *num_params; #else /* _NO_PROTO */ static void asedit_undo(Widget w, XEvent *event, char **params, Cardinal *num_params) #endif { aseditWindowStruct *win = find_win_for_edit_text(w); if(win->can_undo) { TurnWatchCursor(True); if(win) /* sanity check */ { UndoRedo(win, MENU_UNDO); } TurnWatchCursor(False); } } /* asedit_undo */ #ifdef _NO_PROTO static void asedit_redo(w, event, params, num_params) Widget w; XEvent *event; char **params; Cardinal *num_params; #else /* _NO_PROTO */ static void asedit_redo(Widget w, XEvent *event, char **params, Cardinal *num_params) #endif { aseditWindowStruct *win = find_win_for_edit_text(w); if(win->can_redo) { TurnWatchCursor(True); if(win) /* sanity check */ { UndoRedo(win, MENU_REDO); } TurnWatchCursor(False); } } /* asedit_redo */ #ifdef _NO_PROTO static void asedit_find(w, event, params, num_params) Widget w; XEvent *event; char **params; Cardinal *num_params; #else /* _NO_PROTO */ static void asedit_find(Widget w, XEvent *event, char **params, Cardinal *num_params) #endif { aseditWindowStruct *win = find_win_for_edit_text(w); TurnWatchCursor(True); if(win) /* sanity check */ { /* set the reason for managing replace_dialog */ win->search_reason = MENU_FIND; show_replace_dialog(win); } TurnWatchCursor(False); } /* asedit_find */ #ifdef _NO_PROTO static void asedit_change(w, event, params, num_params) Widget w; XEvent *event; char **params; Cardinal *num_params; #else /* _NO_PROTO */ static void asedit_change(Widget w, XEvent *event, char **params, Cardinal *num_params) #endif { aseditWindowStruct *win = find_win_for_edit_text(w); /* the change action should be performed only for editable files !! */ if(!win->file_read_only) { TurnWatchCursor(True); if(win) /* sanity check */ { /* set the reason for managing replace_dialog */ win->search_reason = MENU_CHANGE; show_replace_dialog(win); } TurnWatchCursor(False); } } /* asedit_change */ #ifdef _NO_PROTO static void asedit_mark_set(w, event, params, num_params) Widget w; XEvent *event; char **params; Cardinal *num_params; #else /* _NO_PROTO */ static void asedit_mark_set(Widget w, XEvent *event, char **params, Cardinal *num_params) #endif { aseditWindowStruct *win = find_win_for_edit_text(w); int mark=0; if(win && num_params) /* sanity check */ { mark = (int) atol(params[0]); if(mark >= 0 && mark < TOTAL_MARKS) /* sanity check */ { XmTextPosition pos; Arg al[1]; /* arg list */ /* get the value of the cursor position */ XtSetArg(al[0], XmNcursorPosition, &pos); XtGetValues(win->edit_text, al, 1); win->mark_pos[mark] = pos; win->mark_set[mark] = True; win->marks_used = True; XtSetSensitive( win->menu_mark_go_button[mark], True); } } } /* asedit_mark_set */ #ifdef _NO_PROTO static void asedit_mark_goto(w, event, params, num_params) Widget w; XEvent *event; char **params; Cardinal *num_params; #else /* _NO_PROTO */ static void asedit_mark_goto(Widget w, XEvent *event, char **params, Cardinal *num_params) #endif { aseditWindowStruct *win = find_win_for_edit_text(w); int mark=0; if(win && win->marks_used && num_params) /* sanity check */ { mark = (int) atol(params[0]); if(mark >= 0 && mark < TOTAL_MARKS) /* sanity check */ { if(win->mark_set[mark]) XmTextSetCursorPosition(win->edit_text, win->mark_pos[mark]); } } } /* asedit_mark_goto */ #ifdef _NO_PROTO static void asedit_forward_match(w, event, params, num_params) Widget w; XEvent *event; char **params; Cardinal *num_params; #else /* _NO_PROTO */ static void asedit_forward_match(Widget w, XEvent *event, char **params, Cardinal *num_params) #endif { aseditWindowStruct *win = find_win_for_edit_text(w); if(win) /* sanity check */ { /* set the timestamp needed to set selection of the delimited text */ win->timestamp_search_request = event->xkey.time; findDelimiterMate(win, True); } } /* asedit_forward_match */ #ifdef _NO_PROTO static void asedit_backward_match(w, event, params, num_params) Widget w; XEvent *event; char **params; Cardinal *num_params; #else /* _NO_PROTO */ static void asedit_backward_match(Widget w, XEvent *event, char **params, Cardinal *num_params) #endif { aseditWindowStruct *win = find_win_for_edit_text(w); int mark=0; if(win) /* sanity check */ { /* set the timestamp needed to set selection of the delimited text */ win->timestamp_search_request = event->xkey.time; findDelimiterMate(win, False); } } /* asedit_backward_match */