/* tool_dlg.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 /* to define toupper function */ #include #include #include #include #include #include #include #include #include "asedit.h" #define MAX_REASONABLE_LINE_WIDTH 4095 #define MAX_DIGITS_IN_MOVE_DIALOGS 2 #define MAX_DIGITS_IN_REFORMAT_DIALOG 3 /***************************** allowOnlyNumbersCB ********************************* ** ** Process callback from number only text widgets. */ #ifdef _NO_PROTO void allowOnlyNumbersCB (w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; #else /* ! _NO_PROTO */ void allowOnlyNumbersCB (Widget w, XtPointer client_data, XtPointer call_data) #endif { XmTextVerifyCallbackStruct *cbs = (XmTextVerifyCallbackStruct *) call_data; int reason; /* reason for the callback */ unsigned char c; int max_len = (int) client_data; int i, len = XmTextGetLastPosition (w); char *sel = NULL; reason = cbs->reason; switch(reason) { case XmCR_MODIFYING_TEXT_VALUE: sel = XmTextGetSelection(w); /* get the selection; we might want to clear the selection by typing in (pendingDelete) */ if(sel) { if(strlen(sel)) max_len++; /* increase it by 1 to allow 1 char. long input when the text is selected and takes all the length*/ XtFree(sel); } if (cbs->text->length +len > max_len) { /* don't allow text longer than max_len (including clipboard/selection copies) */ cbs->doit = False; return; } /* process the following only when there is text inserted; (i.e. do not process when we press BkSp, Delete etc. */ if(cbs->text->length > 0) { for(i=0; i < cbs->text->length; i++) { /* don't allow non-digits */ c = (unsigned char)cbs->text->ptr[0]; if (!isdigit (c)) { cbs->doit = False; } } } break; default: /* an unknown client_data was received and there is no setup to handle this */ fprintf(stderr, "Warning: an unknown client_data in allowOnlyNumbersCB callback\n"); fprintf(stderr,"Detected reason = %d \n", reason); return; } } /* allowOnlyNumbersCB */ #ifdef _NO_PROTO void show_moveLeft_dialog (win) aseditWindowStruct *win; #else /* ! _NO_PROTO */ void show_moveLeft_dialog (aseditWindowStruct *win) #endif { Arg al[5]; /* arg list */ register int ac = 0; /* arg count */ Widget dialog, text; if(win->moveLeft_dialog == NULL) /* first create the dialog */ { /* create the moveLeft_dialog widget */ ac = 0; /*** XtSetArg (al[ac], XmNautoUnmanage, False); ac++; let the user decide if he wants the dialog to stay after OK ***/ dialog = XmCreatePromptDialog (win->menu_bar, "moveLeft_dialog",al,ac); XtAddCallback (dialog, XmNokCallback, (XtCallbackProc)DialogOkCB, mk_asdat_w(win, DIALOG_MOVE_LEFT) ); XtAddCallback (dialog, XmNcancelCallback, (XtCallbackProc)DialogCancelCB, mk_asdat_w(win, DIALOG_MOVE_LEFT) ); XtAddCallback (dialog, XmNhelpCallback, (XtCallbackProc)HelpCB, mk_asdat_w(win, DIALOG_MOVE_LEFT) ); text = XmSelectionBoxGetChild(dialog, XmDIALOG_TEXT); if(lstr.useOldColorSetup) { /* set the colour for the editable text widget */ ac =0; XtSetArg(al[ac], XmNbackground, select_menu_background); ac++; XtSetValues(text, al, ac); } setDefaultHomeEndTranslations(text); /* it is a child of SelectionBox so set the translations for osfBeginLine and osfEndLine to the same as for standard text widgets */ /* add modify verify callback (we will use it to allow entering only numbers) */ XtAddCallback (text, XmNmodifyVerifyCallback, (XtCallbackProc)allowOnlyNumbersCB, (XtPointer)MAX_DIGITS_IN_MOVE_DIALOGS ); /* store the dialog widget */ win->moveLeft_dialog = dialog; } asManageDialog (win->moveLeft_dialog); } /* show_moveLeft_dialog */ #ifdef _NO_PROTO void show_moveRight_dialog (win) aseditWindowStruct *win; #else /* ! _NO_PROTO */ void show_moveRight_dialog (aseditWindowStruct *win) #endif { Arg al[5]; /* arg list */ register int ac = 0; /* arg count */ Widget dialog, text; if(win->moveRight_dialog == NULL) /* first create the dialog */ { /* create the moveRight_dialog widget */ ac = 0; /*** XtSetArg (al[ac], XmNautoUnmanage, False); ac++; let the user decide if he wants the dialog to stay after OK ***/ dialog = XmCreatePromptDialog (win->menu_bar, "moveRight_dialog",al,ac); XtAddCallback (dialog, XmNokCallback, (XtCallbackProc)DialogOkCB, mk_asdat_w(win, DIALOG_MOVE_RIGHT) ); XtAddCallback (dialog, XmNcancelCallback, (XtCallbackProc)DialogCancelCB, mk_asdat_w(win, DIALOG_MOVE_RIGHT) ); XtAddCallback (dialog, XmNhelpCallback, (XtCallbackProc)HelpCB, mk_asdat_w(win, DIALOG_MOVE_RIGHT) ); text = XmSelectionBoxGetChild(dialog, XmDIALOG_TEXT); if(lstr.useOldColorSetup) { /* set the colour for the editable text widget */ ac =0; XtSetArg(al[ac], XmNbackground, select_menu_background); ac++; XtSetValues(text, al, ac); } setDefaultHomeEndTranslations(text); /* it is a child of SelectionBox so set the translations for osfBeginLine and osfEndLine to the same as for standard text widgets */ /* add modify verify callback (we will use it to allow entering only numbers) */ XtAddCallback (text, XmNmodifyVerifyCallback, (XtCallbackProc)allowOnlyNumbersCB, (XtPointer)MAX_DIGITS_IN_MOVE_DIALOGS ); /* store the dialog widget */ win->moveRight_dialog = dialog; } asManageDialog (win->moveRight_dialog); } /* show_moveLeft_dialog */ #ifdef _NO_PROTO void show_indentWith_dialog (win) aseditWindowStruct *win; #else /* ! _NO_PROTO */ void show_indentWith_dialog (aseditWindowStruct *win) #endif { Arg al[5]; /* arg list */ register int ac = 0; /* arg count */ Widget dialog, text; if(win->indentWith_dialog == NULL) /* first create the dialog */ { /* create the indentWith_dialog widget */ ac = 0; /*** XtSetArg (al[ac], XmNautoUnmanage, False); ac++; let the user decide if he wants the dialog to stay after OK ***/ dialog = XmCreatePromptDialog (win->menu_bar, "indentWith_dialog",al,ac); XtAddCallback (dialog, XmNokCallback, (XtCallbackProc)DialogOkCB, mk_asdat_w(win, DIALOG_INDENT_WITH) ); XtAddCallback (dialog, XmNcancelCallback, (XtCallbackProc)DialogCancelCB, mk_asdat_w(win, DIALOG_INDENT_WITH) ); XtAddCallback (dialog, XmNhelpCallback, (XtCallbackProc)HelpCB, mk_asdat_w(win, DIALOG_INDENT_WITH) ); text = XmSelectionBoxGetChild(dialog, XmDIALOG_TEXT); if(lstr.useOldColorSetup) { /* set the colour for the editable text widget */ ac =0; XtSetArg(al[ac], XmNbackground, select_menu_background); ac++; XtSetValues(text, al, ac); } setDefaultHomeEndTranslations(text); /* it is a child of SelectionBox so set the translations for osfBeginLine and osfEndLine to the same as for standard text widgets */ /* store the dialog widget */ win->indentWith_dialog = dialog; } asManageDialog (win->indentWith_dialog); } /* show_indentWith_dialog */ #ifdef _NO_PROTO void show_reformat_dialog (win) aseditWindowStruct *win; #else /* ! _NO_PROTO */ void show_reformat_dialog (aseditWindowStruct *win) #endif { Arg al[15]; /* arg list */ register int ac = 0; /* arg count */ Widget dialog=NULL, form, left_margin_title, right_margin_title; Widget kid[6]; int i; Dimension h_space, v_space; /* horizontal and vertical space used */ if(win->reformat_dialog == NULL) /* first create the dialog */ { /* create the reformat_dialog widget */ ac = 0; /*** XtSetArg (al[ac], XmNautoUnmanage, False); ac++; let the user decide if he wants the dialog to stay after OK ***/ dialog = XmCreateWarningDialog(win->menu_bar, "reformat_dialog", al, ac); if(dialog == NULL) return; /* safety check */ /* unmanage unneeded elements */ i = 0; kid[i++] = XmMessageBoxGetChild(dialog, XmDIALOG_MESSAGE_LABEL); kid[i++] = XmMessageBoxGetChild(dialog, XmDIALOG_SYMBOL_LABEL); XtUnmanageChildren (kid, i); /* create a form widget inside the dialog; inside that form create appropriate labels and text widgets */ ac = 0; form = XmCreateForm ( dialog, "form", al, ac ); ac = 0; XtSetArg(al[ac], XmNhorizontalSpacing, &h_space ); ac++; XtSetArg(al[ac], XmNverticalSpacing, &v_space ); ac++; XtGetValues(form, al, ac ); /* get the spacing used */ ac = 0; XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++; left_margin_title = XmCreateLabel ( form, "left_margin_title", al, ac ); ac=0; XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++; XtSetArg(al[ac], XmNleftOffset, h_space); ac++; XtSetArg(al[ac], XmNleftWidget, left_margin_title);ac++; XtSetArg(al[ac], XmNcolumns, MAX_DIGITS_IN_REFORMAT_DIALOG); ac++; if(lstr.useOldColorSetup) { XtSetArg(al[ac], XmNbackground, select_menu_background);ac++; } win->left_margin = XmCreateText ( form, "left_margin", al, ac ); #if (XmVersion == 1000) XmAddTabGroup (win->left_margin); #endif ac = 0; XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; XtSetArg(al[ac], XmNtopOffset, v_space); ac++; XtSetArg(al[ac], XmNtopWidget, win->left_margin); ac++; XtSetArg(al[ac], XmNleftAttachment, XmATTACH_NONE); ac++; XtSetArg(al[ac], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; XtSetArg(al[ac], XmNrightWidget, left_margin_title); ac++; /*don't**XtSetArg(al[ac], XmNbottomAttachment,XmATTACH_FORM); ac++; ***/ /*** @ 11.03. - Silicon Graphics - O.K. ----- XtSetArg(al[ac], XmNbottomAttachment,XmATTACH_FORM); ac++; ****/ right_margin_title = XmCreateLabel ( form, "right_margin_title", al, ac ); ac=0; XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; XtSetArg(al[ac], XmNtopOffset, v_space); ac++; XtSetArg(al[ac], XmNtopWidget, win->left_margin); ac++; XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++; XtSetArg(al[ac], XmNleftOffset, h_space); ac++; XtSetArg(al[ac], XmNleftWidget, left_margin_title); ac++; XtSetArg(al[ac], XmNcolumns, MAX_DIGITS_IN_REFORMAT_DIALOG); ac++; if(lstr.useOldColorSetup) { XtSetArg(al[ac], XmNbackground, select_menu_background);ac++; } win->right_margin = XmCreateText ( form, "right_margin", al, ac ); #if (XmVersion == 1000) XmAddTabGroup (win->right_margin); #endif /* manage the widgets */ ac = 0; kid[ac++] = left_margin_title; kid[ac++] = win->left_margin; kid[ac++] = right_margin_title; kid[ac++] = win->right_margin; XtManageChildren(kid, ac); XtManageChild(form); XtAddCallback (dialog, XmNokCallback, (XtCallbackProc)DialogOkCB, mk_asdat_w(win, DIALOG_REFORMAT) ); XtAddCallback (dialog, XmNcancelCallback, (XtCallbackProc)DialogCancelCB, mk_asdat_w(win, DIALOG_REFORMAT) ); XtAddCallback (dialog, XmNhelpCallback, (XtCallbackProc)HelpCB, mk_asdat_w(win, DIALOG_REFORMAT) ); /* set a special callback to set the focus to the right_margin widget when the dialog gets its first focus */ #ifndef XFOCUS_BUG XtAddCallback(dialog, XmNfocusCallback, (XtCallbackProc)focusCB, (XtPointer)win->right_margin); #endif /* add modify verify callback (to allow entering only numbers) */ XtAddCallback (win->left_margin, XmNmodifyVerifyCallback, (XtCallbackProc)allowOnlyNumbersCB, (XtPointer)MAX_DIGITS_IN_MOVE_DIALOGS ); /* allow 99 max */ XtAddCallback (win->right_margin, XmNmodifyVerifyCallback, (XtCallbackProc)allowOnlyNumbersCB, (XtPointer)MAX_DIGITS_IN_REFORMAT_DIALOG ); /* store the dialog widget */ win->reformat_dialog = dialog; } asManageDialog (win->reformat_dialog); /* set the keyboard focus to the right_margin each time the dialog pops-up */ #if (XmVersion == 1000) _XmProcessTraversal( win->right_margin, XmTRAVERSE_CURRENT); /** private f. in Motif 1.0***/ #else XmProcessTraversal( win->right_margin, XmTRAVERSE_CURRENT); #endif } /* show_reformat_dialog */ /***************************** FilterDialogCB ********************************* ** ** Process callback from the filter Dialog OK action. */ #ifdef _NO_PROTO void FilterDialogCB (w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; #else /* ! _NO_PROTO */ void FilterDialogCB (Widget w, XtPointer client_data, XtPointer call_data) #endif { Arg al[5]; register int ac; XmTextPosition left, right; char *filter_cmd=NULL; char *cmdInput =NULL; /* text to be filtered */ int id = get_id_from_asdat(client_data); aseditWindowStruct *win = get_win_from_asdat(client_data); XmSelectionBoxCallbackStruct *scb = (XmSelectionBoxCallbackStruct *) call_data; TurnWatchCursor(True); /* get the filter commnad string from the selection box */ XmStringGetLtoR(scb->value, charset, &filter_cmd); if(!empty_name(filter_cmd)) { /* get the selection */ cmdInput = XmTextGetSelection(win->edit_text); if((cmdInput == NULL) || (strlen(cmdInput) == 0)) { /* popup the error message about non-existent selection */ show_error_message(win, (char *)lstr.flt_no_selection); if(filter_cmd) XtFree(filter_cmd); if(cmdInput) XtFree(cmdInput); TurnWatchCursor(False); return; } XmTextGetSelectionPosition(win->edit_text, &left, &right); /* get the selection positions */ /*** note that we are not extending the selection here (to include the right line feed); here it is the total responsibility of the user ***/ if(executeShellCmd(win, filter_cmd, cmdInput, left, right, win->filterOutDepot, NULL, NULL, 0, (XmString)NULL )); { ; /* OK, do nothing extra */ } /* free allocated memory */ if(filter_cmd != NULL) XtFree(filter_cmd); /* do NOT free cmdInput; its memory will be freed when all input is processed (i.e. in processChildOutput) */ XtUnmanageChild(w); /* pop-down the dialog */ } else { /* popup the error message about empty filter command string */ show_error_message(win, (char *)lstr.flt_no_filter); if(filter_cmd != NULL) XtFree(filter_cmd); } TurnWatchCursor(False); } /* FilterDialogCB */ /***************************** FilterToggleCB ****************************** ** ** Process callbacks from toggles in the Filter dialog . */ #ifdef _NO_PROTO static void FilterToggleCB (w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; #else /* ! _NO_PROTO */ static void FilterToggleCB (Widget w, XtPointer client_data, XtPointer call_data) #endif { int id = get_id_from_asdat(client_data); aseditWindowStruct *win = get_win_from_asdat(client_data); XmToggleButtonCallbackStruct *toggle_data = (XmToggleButtonCallbackStruct *) call_data; if(toggle_data->set) /* the toggle button is set; set the dialog out flag to the supplied id value*/ win->filterOutDepot = id; else ; /* do nothing; it is a radio box (only one button is on)*/ } /* FilterToggleCB */ #ifdef _NO_PROTO void setDefaultHomeEndTranslations(w) Widget w; #else /* _NO_PROTO */ void setDefaultHomeEndTranslations(Widget w) #endif { static XtTranslations TransCompiled = NULL; static char *Trans = "Shift osfBeginLine: beginning-of-line(extend)\n\ osfBeginLine: beginning-of-line()\n\ Shift osfEndLine: end-of-line(extend)\n\ osfEndLine: end-of-line()\n"; if(TransCompiled == NULL) /* compiled it first */ TransCompiled = XtParseTranslationTable(Trans); /* be sure that TransCompiled is not NULL (safety check)*/ if(TransCompiled) XtOverrideTranslations(w, TransCompiled); } /* setDefaultHomeEndTranslations */ /***************************** show_filter_dialog ************************** ** ** Show filter_dialog for the specified asedit window. ** If filter_dialog widget does not exist yet ** create it first as a child of menu_bar. */ #ifdef _NO_PROTO void show_filter_dialog (win) aseditWindowStruct *win; #else /* ! _NO_PROTO */ void show_filter_dialog (aseditWindowStruct *win) #endif { Arg al[10]; /* arg list */ register int ac = 0; /* arg count */ Widget text; /* text widget inside the prompt dialog */ if(win->filter_dialog == NULL) { /* create filter dialog */ Widget depot_radio_box, form; Widget frame, to_current_toggle, to_new_toggle, to_dialog_toggle, depot_title; Widget kid[4]; XtSetArg (al[ac], XmNautoUnmanage, False); ac++; win->filter_dialog = XmCreatePromptDialog(win->menu_bar, "filter_dialog", al, ac); /* unmanage unneeded apply button */ kid[0] = XmSelectionBoxGetChild(win->filter_dialog, XmDIALOG_APPLY_BUTTON); XtUnmanageChild (kid[0]); XtAddCallback (win->filter_dialog, XmNokCallback, (XtCallbackProc)FilterDialogCB, mk_asdat_w(win, DIALOG_FILTER) ); XtAddCallback (win->filter_dialog, XmNcancelCallback, (XtCallbackProc)DialogCancelCB, mk_asdat_w(win, DIALOG_FILTER) ); XtAddCallback (win->filter_dialog,XmNhelpCallback, (XtCallbackProc)HelpCB, mk_asdat_w(win, DIALOG_FILTER) ); text = XmSelectionBoxGetChild(win->filter_dialog, XmDIALOG_TEXT); if(lstr.useOldColorSetup) { /* set the colour for the editable text widget */ ac =0; XtSetArg(al[ac], XmNbackground, select_menu_background); ac++; XtSetValues(text, al, ac); } setDefaultHomeEndTranslations(text); /* it is a child of SelectionBox so set the translations for osfBeginLine and osfEndLine to the same as for standard text widgets */ ac = 0; form = XmCreateForm ( win->filter_dialog, "form", al, ac ); ac = 0; XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++; depot_title = XmCreateLabel ( form, "depot_title", al, ac ); ac=0; XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; XtSetArg(al[ac], XmNtopWidget, depot_title); ac++; XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++; frame = XmCreateFrame ( form, "frame", al, ac ); ac=0; depot_radio_box = XmCreateRadioBox( frame, "depot_radio_box", al, ac ); #if (XmVersion == 1000) XmAddTabGroup (depot_radio_box); #endif /* set the first button as the default ON */ win->filterOutDepot = TO_CURRENT; ac=0; XtSetArg (al[ac], XmNset, True); ac++; to_current_toggle = XmCreateToggleButton(depot_radio_box, "to_current", al,ac); XtAddCallback (to_current_toggle, XmNvalueChangedCallback, (XtCallbackProc)FilterToggleCB, mk_asdat_w(win, TO_CURRENT) ); ac = 0; to_new_toggle = XmCreateToggleButton(depot_radio_box, "to_new", al,ac); XtAddCallback (to_new_toggle, XmNvalueChangedCallback, (XtCallbackProc)FilterToggleCB, mk_asdat_w(win, TO_NEW) ); to_dialog_toggle = XmCreateToggleButton(depot_radio_box, "to_dialog", al,ac); XtAddCallback (to_dialog_toggle, XmNvalueChangedCallback, (XtCallbackProc)FilterToggleCB, mk_asdat_w(win, TO_TEXT_DIALOG) ); /* manage the children and manage the manager parents as we ascend back up*/ ac = 0; kid[ac++] = to_current_toggle; kid[ac++] = to_new_toggle; kid[ac++] = to_dialog_toggle; XtManageChildren(kid, ac); XtManageChild(depot_radio_box); XtManageChild(frame); XtManageChild(depot_title); XtManageChild(form); /* set a special callback to set the focus to the text widget when the dialog gets its first focus */ #ifndef XFOCUS_BUG XtAddCallback(win->filter_dialog, XmNfocusCallback, (XtCallbackProc)focusCB, (XtPointer)text); #endif } text = XmSelectionBoxGetChild(win->filter_dialog, XmDIALOG_TEXT); asManageDialog(win->filter_dialog); /* set the keyboard focus to the text widget each time the dialog pops-up */ #if (XmVersion == 1000) _XmProcessTraversal( text, XmTRAVERSE_CURRENT); /** private f. in Motif 1.0 **/ #else XmProcessTraversal( text, XmTRAVERSE_CURRENT); #endif } /* show_filter_dialog */ /***************************** CommandDialogCB ********************************* ** ** Process callback from the filter Dialog OK action. */ #ifdef _NO_PROTO void CommandDialogCB (w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; #else /* ! _NO_PROTO */ void CommandDialogCB (Widget w, XtPointer client_data, XtPointer call_data) #endif { Arg al[5]; register int ac; char *cmd=NULL; XmTextPosition left, right; int id = get_id_from_asdat(client_data); aseditWindowStruct *win = get_win_from_asdat(client_data); XmSelectionBoxCallbackStruct *scb = (XmSelectionBoxCallbackStruct *) call_data; TurnWatchCursor(True); /* get the commnad string from the selection box */ XmStringGetLtoR(scb->value, charset, &cmd); if(!empty_name(cmd)) { /* the command result will replace current selection (if it is not available or its length is zero, we will put it at the current insertion point) */ if(!XmTextGetSelectionPosition(win->edit_text, &left, &right) || left==right) left = right = XmTextGetInsertionPosition(win->edit_text); if(executeShellCmd(win, cmd, NULL, left, right, win->commandOutDepot, NULL, NULL, 0, (XmString)NULL )); { ; /* OK, do nothing extra */ } XtUnmanageChild(w); /* pop-down the dialog */ } else { /* popup the error message about empty command string */ show_error_message(win, (char *)lstr.flt_no_filter); } /* free allocated memory */ if(cmd != NULL) XtFree(cmd); TurnWatchCursor(False); } /* CommandDialogCB */ /***************************** CommandToggleCB ****************************** ** ** Process callbacks from toggles in the Command dialog . */ #ifdef _NO_PROTO static void CommandToggleCB (w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; #else /* ! _NO_PROTO */ static void CommandToggleCB (Widget w, XtPointer client_data, XtPointer call_data) #endif { int id = get_id_from_asdat(client_data); aseditWindowStruct *win = get_win_from_asdat(client_data); XmToggleButtonCallbackStruct *toggle_data = (XmToggleButtonCallbackStruct *) call_data; if(toggle_data->set) /* the toggle button is set; set the dialog out flag to the supplied id value*/ win->commandOutDepot = id; else ; /* do nothing; it is a radio box (only one button is on)*/ } /* CommandToggleCB */ /***************************** show_command_dialog ************************** ** ** Show command_dialog for the specified asedit window. ** If command_dialog widget does not exist yet ** create it first as a child of menu_bar. */ #ifdef _NO_PROTO void show_command_dialog (win) aseditWindowStruct *win; #else /* ! _NO_PROTO */ void show_command_dialog (aseditWindowStruct *win) #endif { Widget text; /* text widget inside the prompt dialog */ if(win->command_dialog == NULL) { /* create command dialog */ Arg al[10]; /* arg list */ register int ac = 0; /* arg count */ Widget dialog, depot_radio_box, form; Widget frame, to_current_toggle, to_new_toggle, to_dialog_toggle, depot_title; Widget kid[4]; XtSetArg (al[ac], XmNautoUnmanage, False); ac++; dialog = XmCreatePromptDialog(win->menu_bar, "command_dialog", al, ac); /* unmanage unneeded apply button */ kid[0] = XmSelectionBoxGetChild(dialog, XmDIALOG_APPLY_BUTTON); XtUnmanageChild (kid[0]); XtAddCallback (dialog, XmNokCallback, (XtCallbackProc)CommandDialogCB, mk_asdat_w(win, DIALOG_COMMAND) ); XtAddCallback (dialog, XmNcancelCallback, (XtCallbackProc)DialogCancelCB, mk_asdat_w(win, DIALOG_COMMAND) ); XtAddCallback (dialog,XmNhelpCallback, (XtCallbackProc)HelpCB, mk_asdat_w(win, DIALOG_COMMAND) ); text = XmSelectionBoxGetChild(dialog, XmDIALOG_TEXT); if(lstr.useOldColorSetup) { /* set the colour for the editable text widget */ ac =0; XtSetArg(al[ac], XmNbackground, select_menu_background); ac++; XtSetValues(text, al, ac); } setDefaultHomeEndTranslations(text); /* it is a child of SelectionBox so set the translations for osfBeginLine and osfEndLine to the same as for standard text widgets */ ac = 0; form = XmCreateForm ( dialog, "form", al, ac ); ac = 0; XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++; depot_title = XmCreateLabel ( form, "depot_title", al, ac ); ac=0; XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; XtSetArg(al[ac], XmNtopWidget, depot_title); ac++; XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++; frame = XmCreateFrame ( form, "frame", al, ac ); ac=0; depot_radio_box = XmCreateRadioBox( frame, "depot_radio_box", al, ac ); #if (XmVersion == 1000) XmAddTabGroup (depot_radio_box); #endif /* set the first button as the default ON */ win->commandOutDepot = TO_CURRENT; ac=0; XtSetArg (al[ac], XmNset, True); ac++; to_current_toggle = XmCreateToggleButton(depot_radio_box, "to_current", al,ac); XtAddCallback (to_current_toggle, XmNvalueChangedCallback, (XtCallbackProc)CommandToggleCB, mk_asdat_w(win, TO_CURRENT) ); ac = 0; to_new_toggle = XmCreateToggleButton(depot_radio_box, "to_new", al,ac); XtAddCallback (to_new_toggle, XmNvalueChangedCallback, (XtCallbackProc)CommandToggleCB, mk_asdat_w(win, TO_NEW) ); to_dialog_toggle = XmCreateToggleButton(depot_radio_box, "to_dialog", al,ac); XtAddCallback (to_dialog_toggle, XmNvalueChangedCallback, (XtCallbackProc)CommandToggleCB, mk_asdat_w(win, TO_TEXT_DIALOG) ); /* manage the children and manage the manager parents as we ascend back up*/ ac = 0; kid[ac++] = to_current_toggle; kid[ac++] = to_new_toggle; kid[ac++] = to_dialog_toggle; XtManageChildren(kid, ac); XtManageChild(depot_radio_box); XtManageChild(frame); XtManageChild(depot_title); XtManageChild(form); /* set a special callback to set the focus to the text widget when the dialog gets its first focus */ #ifndef XFOCUS_BUG XtAddCallback(dialog, XmNfocusCallback, (XtCallbackProc)focusCB, (XtPointer)text); #endif win->command_dialog = dialog; } text = XmSelectionBoxGetChild(win->command_dialog, XmDIALOG_TEXT); asManageDialog(win->command_dialog); /***** XYZ do we need to set the keyboard focus ??? (the same for filter_dialog ??? **/ /* set the keyboard focus to the text widget each time the dialog pops-up */ #if (XmVersion == 1000) _XmProcessTraversal( text, XmTRAVERSE_CURRENT); /** private f. in Motif 1.0 **/ #else XmProcessTraversal( text, XmTRAVERSE_CURRENT); #endif } /* show_command_dialog */ /* extendRightPosToLF - extends right position to encompass the line feed; returns True when everything OK; note if the current selection ends in LF it is OK; if there are errors asks about continuing the process and returns the user answer; right: margin of the current selection; */ #ifdef _NO_PROTO static Boolean extendRightPosToLF (win, right) aseditWindowStruct *win; XmTextPosition *right; #else /* ! _NO_PROTO */ static Boolean extendRightPosToLF (aseditWindowStruct *win, XmTextPosition *right) #endif { Boolean proceed = True; char *txt = NULL; /* text from the text widget */ int i, len, lf_pos; txt = getTextSubstring(win->edit_text, *right-1, MAX_REASONABLE_LINE_WIDTH); if(txt) { len = strlen(txt); lf_pos = -1; for(i=0; i 0) { /* only change the position when we find the line feed and the selection was not already finished with line feed */ *right += lf_pos; } else if(lf_pos == -1) { /* show an error message that we can't find the newline because the line is to long or we are at the last line of a file which does not have one */ /* for simplicity use acceptChildOutput procedure */ proceed = acceptChildOutput(win->menu_bar, lstr.cant_find_lf, XmDIALOG_CANCEL_BUTTON); } XtFree(txt); } else { /* this shouldn't really happen, but lets take care of that */ proceed = acceptChildOutput(win->menu_bar, lstr.cant_find_lf, XmDIALOG_CANCEL_BUTTON); } return proceed; } /* extendRightPosToLF */ /* extendSelectionToLF - extends selection right to encompass the line feed; returns True when everything OK; note if the current selection ends in LF it is OK; if there are errors asks about continuing the process and returns the user answer; left, right: margins of the current selection; */ #ifdef _NO_PROTO Boolean extendSelectionToLF (win, left, right) aseditWindowStruct *win; XmTextPosition *left; XmTextPosition *right; #else /* ! _NO_PROTO */ Boolean extendSelectionToLF (aseditWindowStruct *win, XmTextPosition *left, XmTextPosition *right) #endif { Boolean proceed = True; XmTextPosition left_orig, right_orig; /* extend the selection to encompass the last line feed; alternatively we could extend the selection to whole lines; the important bit is to have the final line feed (sed works on complete lines!) */ left_orig = *left; right_orig= *right; if(extendRightPosToLF(win, right)) { if(*right != right_orig) XmTextSetSelection(win->edit_text, *left, *right, CurrentTime); } else proceed = False; return proceed; } /* extendSelectionToLF */ /* extendLeftPosToBOL - extends left posotion to the beginning of line; returns True when everything OK; note if the current selection starts at the beginning of line - it is OK; if there are errors asks about continuing the process and returns the user answer; left: margins of the current selection; */ #ifdef _NO_PROTO static Boolean extendLeftPosToBOL (win, left) aseditWindowStruct *win; XmTextPosition *left; #else /* ! _NO_PROTO */ static Boolean extendLeftPosToBOL (aseditWindowStruct *win, XmTextPosition *left) #endif { Boolean proceed = True; char *txt = NULL; /* text from the text widget */ int i, len, lf_last_pos; /* extend the left position to encompass the first character on the line; */ if(*left == 0) return True; /* beginning of the text */ txt = getTextSubstring(win->edit_text, *left -MAX_REASONABLE_LINE_WIDTH, *left); if(txt) { len = strlen(txt); lf_last_pos = -1; /* look for the line beginning only when we check that the selection does not start at the line beginning already */ if(txt[len-1] != '\n') { for(i=len-1; i>=0; i--) { if(txt[i] == '\n') { lf_last_pos = i; break; } } if(lf_last_pos >= 0) *left -= (len-1 - lf_last_pos); else if(lf_last_pos == -1) { /* check if we had not reach the beginning of file; if not show an error message that we can't find the newline because the line is probably to long */ if(*left == len) *left = 0; /* extend to the text beginning */ else /* show error; for simplicity use acceptChildOutput procedure */ proceed = acceptChildOutput(win->menu_bar, lstr.cant_find_lf, XmDIALOG_CANCEL_BUTTON); } } XtFree(txt); } else { /* this shouldn't really happen, but lets take care of that */ proceed = acceptChildOutput(win->menu_bar, lstr.cant_find_lf, XmDIALOG_CANCEL_BUTTON); } return proceed; } /* extendLeftPosToBOL */ /* extendSelectionToBOL - extends selection left to beginning of line; returns True when everything OK; note if the current selection starts at the beginning of line - it is OK; if there are errors asks about continuing the process and returns the user answer; left, right: margins of the current selection; */ #ifdef _NO_PROTO Boolean extendSelectionToBOL (win, left, right) aseditWindowStruct *win; XmTextPosition *left; XmTextPosition *right; #else /* ! _NO_PROTO */ Boolean extendSelectionToBOL (aseditWindowStruct *win, XmTextPosition *left, XmTextPosition *right) #endif { Boolean proceed = True; XmTextPosition left_orig, right_orig; left_orig = *left; right_orig= *right; if(extendLeftPosToBOL(win, left)) { if(*left != left_orig) XmTextSetSelection(win->edit_text, *left, *right, CurrentTime); } else proceed = False; return proceed; } /* extendSelectionToBOL */ /* extendSelectionToLines - extends selection to encompass whole lines (including final line feed); returns True when everything OK; note if the current selection ends in LF it is OK; if there are errors asks about continuing the process and returns the user answer; left, right: margins of the current selection; */ #ifdef _NO_PROTO Boolean extendSelectionToLines (win, left, right) aseditWindowStruct *win; XmTextPosition *left; XmTextPosition *right; #else /* ! _NO_PROTO */ Boolean extendSelectionToLines (aseditWindowStruct *win, XmTextPosition *left, XmTextPosition *right) #endif { Boolean proceed = True; XmTextPosition left_orig, right_orig; /* extend the selection to encompass the whole lines; we *need* the final line feed (sed works on complete lines!) */ left_orig = *left; right_orig= *right; if(extendRightPosToLF(win, right) && extendLeftPosToBOL(win, left)) { if(*right != right_orig || *left != left_orig) XmTextSetSelection(win->edit_text, *left, *right, CurrentTime); } else proceed = False; return proceed; } /* extendSelectionToLines */ /* extendSelectionToWholeFile - extends selection to the whole file (text); returns True when everything OK; left, right: margins of the current selection; */ #ifdef _NO_PROTO Boolean extendSelectionToWholeFile (win, left, right) aseditWindowStruct *win; XmTextPosition *left; XmTextPosition *right; #else /* ! _NO_PROTO */ Boolean extendSelectionToWholeFile (aseditWindowStruct *win, XmTextPosition *left, XmTextPosition *right) #endif { Boolean proceed = True; XmTextPosition left_orig, right_orig; /* extend the selection to encompass the whole file; we *need* the final line feed (sed works on complete lines!) */ left_orig = *left; right_orig= *right; *left = 0; *right = XmTextGetLastPosition(win->edit_text); if(*right != right_orig || *left != left_orig) XmTextSetSelection(win->edit_text, *left, *right, CurrentTime); return proceed; } /* extendSelectionToWholeFile */ #ifdef _NO_PROTO void changeCaseOfString(txt, change_to) char *txt; int change_to; #else /* ! _NO_PROTO */ void changeCaseOfString(char *txt, int change_to) #endif { long i, len; Boolean spaceOrDotBefore = True; /* we assume that the user wants the first letter to be capitalized (TO_TTILE_CASE) */ unsigned char c; if(txt) { len = strlen(txt); switch(change_to) { case TO_UPPER_CASE: for(i=0; i < len; i++) { *txt = toupper((unsigned char) *txt); txt++; } break; case TO_LOWER_CASE: for(i=0; i < len; i++) { *txt = tolower((unsigned char) *txt); txt++; } break; case TO_TITLE_CASE: for(i=0; i < len; i++) { c = (unsigned char) *txt; if(spaceOrDotBefore) { if(isalpha(c)) *txt = toupper(c); } txt++; if(isspace(c) || ispunct(c)) spaceOrDotBefore = True; else spaceOrDotBefore = False; } break; case TO_TOGGLE_CASE: for(i=0; i < len; i++) { c = (unsigned char) *txt; if(isupper(c)) *txt = tolower(c); else if(islower(c)) *txt = toupper(c); txt++; } break; default: fprintf(stderr, "\nUnknown change_to in changeCaseOfString"); break; } } } /* changeCaseOfString */ #ifdef _NO_PROTO void changeCaseOfSelection(win, change_to) aseditWindowStruct *win; int change_to; #else /* ! _NO_PROTO */ void changeCaseOfSelection(aseditWindowStruct *win, int change_to) #endif { char *txt; XmTextPosition left, right, insert_pos; /* get the selection */ txt = XmTextGetSelection(win->edit_text); /* the following two checks probably would never be used; appropriate commands should be greyed out when there is no primary selection in the edit area (so this procedure would NOT be called when there is no selection!) */ if(txt == NULL) return; /* no selection to process */ if(strlen(txt) == 0) { /* the widget owns primary selection but it is empty; do not process */ XtFree(txt); return; } if(!XmTextGetSelectionPosition(win->edit_text, &left, &right)) return; /* get the positions and do an extra check */ insert_pos = XmTextGetInsertionPosition(win->edit_text); /* OK, we have the selection and its position */ changeCaseOfString(txt, change_to); disableRedisplay(win); /* to prevent visual flashing */ XmTextReplace(win->edit_text, left, right, txt); /* set the selection again */ /* note that XmTextSelection position changes the insertion to the right pos. */ XmTextSetSelection(win->edit_text, left, right, CurrentTime); if(insert_pos != right) XmTextSetInsertionPosition(win->edit_text, insert_pos); enableRedisplay(win); /* free allocated memory */ if(txt) XtFree(txt); } /* changeCaseOfSelection */