
/* srch_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 <stdio.h>
#include <string.h>

#include <Xm/MessageB.h>
#include <Xm/SelectioB.h>
#include <Xm/Form.h>
#include <Xm/Label.h>
#include <Xm/Text.h>
#include <Xm/Frame.h>
#include <Xm/RowColumn.h>
#include <Xm/ToggleB.h>
#include <Xm/ToggleBG.h>

#include "asedit.h"

/*****************************  CreateReplaceDialog  ************************
*
*	creates replace dialog out of a selection box
*/
#ifdef _NO_PROTO
static Widget CreateReplaceDialog(win, parent, name, arglist, argcount)
	aseditWindowStruct *win;
	Widget parent;
	String name;
	Arg arglist[];
	int argcount;
#else  /* ! _NO_PROTO */

static Widget CreateReplaceDialog( aseditWindowStruct *win,
		Widget parent, String name,
		Arg arglist[], int argcount )
#endif
{
	Widget kid[11];      		/* Children to manage */
	Arg al[15];         		/* Arg List */
	register int ac = 0;      	/* Arg Count */
	Dimension    h_space, v_space; 	/* horizontal and vertical space used
					   inside a form; !!! It *must* be defined as
					   Dimension! (when it was defined as int it worked
					   on RS6000 (Motif 1.0) but id did not work on Silicon Graphics
					   (Motif 1.1)  */

	Widget form_text;	/* special form for label and text widgets
				   it consist of two rows "label - text" lines;
				   the second line is unmanagable to use that dialog
				   as a search dialog; this give us a unique set
				   of text to find plus switches like forward etc. */

	Widget replace_dlg;		/* replace widget (local) - procedure returns it */
	Widget form;          		/* main form widget */
	Widget text_to_find_title;
	Widget options_title;
	Widget frame1;			/* frame used for option toggles */
	Widget options_row_column;
	Widget direction_title;
	Widget frame2;         		/* frame used for direction toggles */
	Widget direction_radio_box;
	Widget backward_toggle;
	Dimension width, labels_width;	


	replace_dlg = XmCreatePromptDialog(parent, name, arglist, argcount);

	/* manage the 4th button of prompt dialog */
	win->change_all_button = XmSelectionBoxGetChild (replace_dlg,
						 XmDIALOG_APPLY_BUTTON);

	/* the title for the change_verify_button will be dynamically set
	   according to the use of the button in "Find" dialog or "Change" dialog */
	win->change_verify_button = XmSelectionBoxGetChild (replace_dlg,
						 XmDIALOG_OK_BUTTON);

	/* get the cancel button .... */
	win->cancel_replace_dialog_button = XmSelectionBoxGetChild (replace_dlg,
						 XmDIALOG_CANCEL_BUTTON);



	/*      Unmanage unneeded children.    */
	ac = 0;
	kid[ac++] = XmSelectionBoxGetChild (replace_dlg, XmDIALOG_TEXT);
	kid[ac++] = XmSelectionBoxGetChild (replace_dlg,
						     XmDIALOG_SELECTION_LABEL);
	XtUnmanageChildren (kid, ac);



	/* create a form widget inside prompt dialog; inside that form
	   create appropriate control elements */

	ac = 0;
	form = XmCreateForm ( replace_dlg, "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 */


	/* when the 2 lines which contain a label and a text widget
	   each, were directly created inside a form and later the second
	   line was managed and unmanaged, when needed, we had problems and
	   the behaviour was inconsistent;
	   Therefore additional form (form_text) is created to "envelope" the
	   widgets mentioned above (19.11.1991) */
	ac = 0;
	XtSetArg(al[ac], XmNtopAttachment,   XmATTACH_FORM); ac++;
	XtSetArg(al[ac], XmNleftAttachment,  XmATTACH_FORM); ac++;
	XtSetArg(al[ac], XmNrightAttachment,   XmATTACH_FORM); ac++;
	form_text = XmCreateForm ( form, "form_text", al, ac );

	/* since 1.32 create the label and text widgets first, then set the geometry attachements */

	ac = 0;
	text_to_find_title  = XmCreateLabel ( form_text, "text_to_find_title", al, ac );
	win->new_text_title = XmCreateLabel ( form_text, "new_text_title", al, ac );
	win->text_to_find   = XmCreateText ( form_text, "text_to_find", al, ac );
	win->new_text       = XmCreateText ( form_text, "new_text", al, ac );

	
	/* since 1.32 we use labels_width to set vertically position of the text widgets */
	/* get the labels_width for the two label widgets (i.e. the max width)*/
	ac =0;
	XtSetArg(al[ac], XmNwidth, &width); 	ac++;
	XtGetValues(text_to_find_title, al, ac);
	labels_width = width;
	XtGetValues(win->new_text_title, al, ac);
	if(width > labels_width)	labels_width = width;

	/* set the 1st label attachments ... */
	ac = 0;
	XtSetArg(al[ac], XmNleftAttachment,  XmATTACH_FORM); ac++;
	XtSetArg(al[ac], XmNtopOffset, 0);		ac++;
	XtSetArg(al[ac], XmNbottomOffset, 0);		ac++;
	XtSetArg(al[ac], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET);	ac++;
	XtSetArg(al[ac], XmNtopWidget,  win->text_to_find);		ac++;
	XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET);	ac++;
	XtSetArg(al[ac], XmNbottomWidget,  win->text_to_find);			ac++;
	XtSetValues(text_to_find_title, al, ac);

	/* set the 1st text attachments ... */
	ac=0;
	XtSetArg(al[ac], XmNtopAttachment,   XmATTACH_FORM); 	ac++;
	XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); 	ac++;
	XtSetArg(al[ac], XmNleftAttachment,  XmATTACH_FORM);    ac++;
	XtSetArg(al[ac], XmNleftOffset,	     h_space+labels_width);ac++;

	if(lstr.useOldColorSetup)
	    { XtSetArg(al[ac], XmNbackground,  select_menu_background);ac++; }
	XtSetValues(win->text_to_find, al, ac);
#if (XmVersion == 1000)
	XmAddTabGroup (win->text_to_find);
#endif


	/* set the 2nd label attachments ... */
	ac = 0;
	XtSetArg(al[ac], XmNleftAttachment,  XmATTACH_FORM); ac++;
	XtSetArg(al[ac], XmNtopOffset, 0);		ac++;
	XtSetArg(al[ac], XmNbottomOffset, 0);		ac++;
	XtSetArg(al[ac], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET);	ac++;
	XtSetArg(al[ac], XmNtopWidget,  win->new_text);			ac++;
	XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET);	ac++;
	XtSetArg(al[ac], XmNbottomWidget,  win->new_text);			ac++;


	XtSetValues(win->new_text_title, al, ac);

	/* set the 2nd text attachments ... */
	ac=0;
	XtSetArg(al[ac], XmNtopAttachment,   XmATTACH_WIDGET);	ac++;
	XtSetArg(al[ac], XmNtopOffset,       v_space); 		ac++;
	XtSetArg(al[ac], XmNtopWidget,       win->text_to_find); ac++;
	XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); 	ac++;
        XtSetArg(al[ac], XmNleftAttachment,  XmATTACH_FORM);    ac++;
        XtSetArg(al[ac], XmNleftOffset,      h_space+labels_width);ac++;

	if(lstr.useOldColorSetup)
	    { XtSetArg(al[ac], XmNbackground,  select_menu_background);ac++; }


	XtSetValues(win->new_text, al, ac);
#if (XmVersion == 1000)
	XmAddTabGroup (win->new_text);
#endif

	ac = 0;
	XtSetArg(al[ac], XmNtopAttachment,   XmATTACH_WIDGET);	ac++;
	XtSetArg(al[ac], XmNtopOffset,       v_space); 		ac++;
	XtSetArg(al[ac], XmNtopWidget,       form_text); 	ac++;
	XtSetArg(al[ac], XmNleftAttachment,  XmATTACH_FORM); 	ac++;
	options_title = XmCreateLabel ( form, "options_title", al, ac );


	ac=0;
	XtSetArg(al[ac], XmNtopAttachment,   XmATTACH_WIDGET);	ac++;
	XtSetArg(al[ac], XmNtopWidget,       options_title); 	ac++;
	XtSetArg(al[ac], XmNleftAttachment,  XmATTACH_FORM); 	ac++;
	XtSetArg(al[ac], XmNrightAttachment, XmATTACH_NONE);	ac++;

	frame1 = XmCreateFrame ( form, "frame1", al, ac );

	ac=0;
	/**XtSetArg (al[ac], XmNpacking, XmPACK_COLUMN);  ac++;
	XtSetArg (al[ac], XmNnumColumns, 1);  ac++; ***/
	options_row_column = XmCreateRowColumn(frame1, "options_row_column", al, ac );
#if (XmVersion == 1000)
	XmAddTabGroup (options_row_column);
#endif

	ac=0;
	win->case_sensitive_toggle   = XmCreateToggleButton( options_row_column, "case_sensitive", al, ac );
	win->whole_words_only_toggle = XmCreateToggleButton( options_row_column, "whole_words", al, ac );

	ac = 0;
	XtSetArg(al[ac], XmNtopAttachment,   XmATTACH_WIDGET);	ac++;
	XtSetArg(al[ac], XmNtopOffset,       v_space); 		ac++;
	XtSetArg(al[ac], XmNtopWidget,       /*new_text*/
					     form_text); 	ac++;
	XtSetArg(al[ac], XmNleftAttachment,  XmATTACH_WIDGET); 	ac++;
	XtSetArg(al[ac], XmNleftOffset,      20); 		ac++;
	XtSetArg(al[ac], XmNleftWidget,      frame1); 		ac++;

	direction_title = XmCreateLabel ( form, "direction_title", al, ac );

	ac=0;
	XtSetArg(al[ac], XmNtopAttachment,   XmATTACH_WIDGET);	ac++;
	XtSetArg(al[ac], XmNtopWidget,       direction_title); 	ac++;
	XtSetArg(al[ac], XmNleftAttachment,  XmATTACH_WIDGET); 	ac++;
	XtSetArg(al[ac], XmNleftOffset,      20); 		ac++;
	XtSetArg(al[ac], XmNleftWidget,      frame1); 		ac++;
	XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); 	ac++;
	frame2 = XmCreateFrame ( form, "frame2", al, ac );
	ac=0;

	direction_radio_box = XmCreateRadioBox( frame2, "direction_radio_box", al, ac );
#if (XmVersion == 1000)
	XmAddTabGroup (direction_radio_box);
#endif
	ac=0;
	win->forward_toggle =  XmCreateToggleButtonGadget( direction_radio_box, "Forward", al, ac );
	backward_toggle = XmCreateToggleButtonGadget( direction_radio_box, "Backward", al, ac );

        checkRadioBoxSetting(direction_radio_box, 0);	/* check (& correct) the toggle button settings
							   done by the user through resources */


	/* manage the children and manage the manager parents as we ascend back up*/

	ac = 0;
	kid[ac++] = win->case_sensitive_toggle;
	kid[ac++] = win->whole_words_only_toggle;
	XtManageChildren(kid, ac);
	XtManageChild(options_row_column);

	ac = 0;
	kid[ac++] = win->forward_toggle;
	kid[ac++] = backward_toggle;
	XtManageChildren(kid, ac);
	XtManageChild(direction_radio_box);

	ac = 0;
	kid[ac++] = text_to_find_title;
	kid[ac++] = win->text_to_find;
	kid[ac++] = win->new_text;
	kid[ac++] = win->new_text_title;
	XtManageChildren(kid, ac);
	XtManageChild(form_text);

	ac = 0;
	kid[ac++] = options_title;
	kid[ac++] = frame1;
	kid[ac++] = direction_title;
	kid[ac++] = frame2;
	XtManageChildren(kid, ac);

	/* now manage the whole form (it is always better to manage the manager
	   widgets after creating all theirs children) */
	XtManageChild(form);

	return(replace_dlg);

}	/* CreateReplaceDialog */

/*****************************  show_replace_dialog  **************************
**
**  Show replace_dialog for the specified asedit window. If it does not exist yet
**  create it first as a child of menu_bar.
*/

#ifdef _NO_PROTO
void show_replace_dialog (win)
	aseditWindowStruct *win;
#else  /* ! _NO_PROTO */

void show_replace_dialog (aseditWindowStruct *win)
#endif
{
    Arg			al[5];		/*  arg list		*/
    register  int	ac = 0;		/*  arg count		*/

    if(win->replace_dialog == NULL)	/* first create the dialog */
    {
	Widget 		kids[3];	/*  children widgets 	*/

	/* create a replace dialog; the find dialog is obtained from the
	   replace dialog simply by unmanaging some widgets !!!
	   The title is dynamically assigned just before managing the widget!! */

	ac = 0;
	XtSetArg (al[ac], XmNautoUnmanage, False);    ac++;
	win->replace_dialog = CreateReplaceDialog( win, win->menu_bar, "replace_dialog", al, ac);

	XtAddCallback (win->replace_dialog, XmNokCallback,
			(XtCallbackProc)DialogOkCB, 	mk_asdat_w(win, DIALOG_FIND_OR_CHANGE) );
	XtAddCallback (win->replace_dialog, XmNcancelCallback,
			(XtCallbackProc)DialogCancelCB,mk_asdat_w(win, DIALOG_FIND_OR_CHANGE) );
	XtAddCallback (win->replace_dialog, XmNhelpCallback,
			(XtCallbackProc)HelpCB, 	mk_asdat_w(win, DIALOG_FIND_OR_CHANGE) );
	XtAddCallback (win->replace_dialog, XmNapplyCallback,
			(XtCallbackProc)DialogApplyCB, mk_asdat_w(win, DIALOG_FIND_OR_CHANGE) );
	/* set a special callback to set the focus to the text_to_find widget
	   when the dialog gets its first focus */
#ifndef XFOCUS_BUG
	XtAddCallback(win->replace_dialog, XmNfocusCallback,
			(XtCallbackProc)focusCB, (XtPointer)win->text_to_find);
#endif
    }

    if(win->search_reason == MENU_FIND)   /* find operation */
    {
	set_dialog_title(win->replace_dialog, (char *)lstr.find_dialogTitle);
	/* set appropriate title for the "OK" button ... */
	write_ls(win->change_verify_button, charset, "%s", (char *)lstr.find_next_label);

	/* unmanage unneeded elements inside replace_dialog widgets */
	XtUnmanageChild( win->new_text);
	XtUnmanageChild( win->new_text_title);
	XtUnmanageChild( win->change_all_button);
    }
    else
    {						/* replace operation */
	set_dialog_title(win->replace_dialog, (char *)lstr.change_dialogTitle);
	/* set appropriate title for the "OK" button ... */
	write_ls(win->change_verify_button, charset, "%s", (char *)lstr.find_n_verify_label);

	/* manage some elements inside replace_dialog which
	   might have been unmanaged when used as a find option */
	XtManageChild( win->new_text);
	XtManageChild( win->new_text_title);
	XtManageChild( win->change_all_button);
    }
    /* set the starting position for the search */
    ac = 0;
    XtSetArg(al[ac], XmNcursorPosition, &(win->start_search_position) ); ac++;
    XtGetValues(win->edit_text, al, ac);

    asManageDialog(win->replace_dialog);

    /* set the keyboard focus to the text_to_find each time the dialog pops-up */
#if (XmVersion == 1000)
    _XmProcessTraversal( win->text_to_find, XmTRAVERSE_CURRENT);  /** private f. in Motif 1.0***/
#else
    XmProcessTraversal( win->text_to_find, XmTRAVERSE_CURRENT);  
#endif

}   /* show_replace_dialog */

/*****************************  show_change_prompt  **************************
**
**  Show change_prompt for the specified asedit window. If it does not exist yet
**  create it first as a child of menu_bar.
*/

#ifdef _NO_PROTO
void show_change_prompt (win)
	aseditWindowStruct *win;
#else  /* ! _NO_PROTO */

void show_change_prompt (aseditWindowStruct *win)
#endif
{

    if(win->change_prompt == NULL)	/* first create the dialog */
    {
	Arg		al[5];		/*  arg list		*/
	register  int	ac = 0;		/*  arg count		*/

	/*    Create  change prompt   */
	ac = 0;
	XtSetArg(al[ac], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ac++;
	XtSetArg (al[ac], XmNautoUnmanage, False);    ac++;

	win->change_prompt = create_4buttons_dialog (win->menu_bar, "change_prompt",
			xm_question_mark, /* if you do not want use any pixmap
				specify NULL pixmap like this:  (Pixmap) NULL, ***/
			 (char *)lstr.sq_change, al, ac);

	XtAddCallback (win->change_prompt, XmNokCallback,
			(XtCallbackProc)DialogOkCB,	mk_asdat_w(win, DIALOG_CHANGE_PROMPT) );
	XtAddCallback (win->change_prompt, XmNapplyCallback,
			(XtCallbackProc)DialogApplyCB,	mk_asdat_w(win, DIALOG_CHANGE_PROMPT) );
	XtAddCallback (win->change_prompt, XmNcancelCallback,
			(XtCallbackProc)DialogCancelCB, mk_asdat_w(win, DIALOG_CHANGE_PROMPT) );
	XtAddCallback (win->change_prompt, XmNhelpCallback,
			(XtCallbackProc)HelpCB,		mk_asdat_w(win, DIALOG_CHANGE_PROMPT) );
    }
    /* make the buttons insensitive ...*/
    set_change_buttons_sensitivity(win, False);
    asManageDialog(win->change_prompt);

}   /* show_change_prompt */


/**********************  create_continue_search_question  **********************
**
**  Create continue_search_question for the specified asedit window as a child
**  of menu_bar.
*/

#ifdef _NO_PROTO
void create_continue_search_question (win)
	aseditWindowStruct *win;
#else  /* ! _NO_PROTO */

void create_continue_search_question (aseditWindowStruct *win)
#endif
{
    if(win->continue_search_question == NULL)	/* first create the dialog */
    {
	Arg		al[5];		/*  arg list		*/
	register  int	ac = 0;		/*  arg count		*/
 	XmString        xmstr;          /*  work XmString */

	/* create continue_search_question widget */
	ac = 0;
	/* text will be set dynamically */
	xmstr = XmStringCreateLtoR("Continue...", charset);
	XtSetArg(al[ac], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ac++;
	XtSetArg (al[ac], XmNautoUnmanage, False);    ac++;
	XtSetArg(al[ac], XmNmessageString, xmstr );  ac++;
	win->continue_search_question = XmCreateQuestionDialog (win->menu_bar, "continue_search_question",al,ac);
	XmStringFree(xmstr);		/* free memory allocated for XmString */

	XtAddCallback (win->continue_search_question, XmNokCallback,
			(XtCallbackProc)DialogOkCB, 	mk_asdat_w(win, QUESTION_CONTINUE_SEARCH) );
	XtAddCallback (win->continue_search_question, XmNcancelCallback,
			(XtCallbackProc)DialogCancelCB, mk_asdat_w(win, QUESTION_CONTINUE_SEARCH) );
	XtAddCallback (win->continue_search_question, XmNhelpCallback,
			(XtCallbackProc)HelpCB, 	mk_asdat_w(win, QUESTION_CONTINUE_SEARCH) );
    }

}   /* create_continue_search_question */

/**********************  create_search_end_message  **********************
**
**  Create search_end_message for the specified asedit window as a child
**  of menu_bar.
*/

#ifdef _NO_PROTO
void create_search_end_message (win)
	aseditWindowStruct *win;
#else  /* ! _NO_PROTO */

void create_search_end_message (aseditWindowStruct *win)
#endif
{
	Arg		al[5];		/*  arg list		*/
	register  int	ac = 0;		/*  arg count		*/
	XmString        xmstr;          /*  work XmString */
	Widget          kids[3];        /*  children widgets */

	/* create search_end_message */
	ac = 0;
	xmstr = XmStringCreateLtoR("Change...", charset); /* text will be set dynamically */
	XtSetArg(al[ac], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ac++;
	XtSetArg (al[ac], XmNautoUnmanage, False);    ac++;
	XtSetArg(al[ac], XmNmessageString, xmstr );  ac++;
	/* To dismiss dialog we use cancel button (label set in resources)
	   The default button needs to be set now to the Cancel button. Otherwise
	   when we press Enter the button won't change the colour to the select
	   colour etc. (the standard defaults to OK button)  - important for Motif 1.0*/
	XtSetArg(al[ac], XmNdefaultButtonType, XmDIALOG_CANCEL_BUTTON); ac++;

	win->search_end_message = XmCreateInformationDialog (win->menu_bar, "search_end_message",al,ac);
	XmStringFree(xmstr);		/* free memory allocated for XmString */

	/* unmanage unneeded buttons */
	ac=0;
	kids[ac++] = XmMessageBoxGetChild(win->search_end_message, XmDIALOG_HELP_BUTTON);
	kids[ac++] = XmMessageBoxGetChild(win->search_end_message, XmDIALOG_OK_BUTTON);
	XtUnmanageChildren (kids, ac);
	XtAddCallback (win->search_end_message, XmNcancelCallback,
			(XtCallbackProc)DialogCancelCB, mk_asdat_w(win, MESSAGE_SEARCH_END) );
	/* lets add the help callback; because the help button is not managed this help
	   is only accessible with F1 (Help) key */
	XtAddCallback (win->search_end_message, XmNhelpCallback,
			(XtCallbackProc)HelpCB, mk_asdat_w(win, MESSAGE_SEARCH_END) );

}	/* create_search_end_message */



/*****************************  show_gotoline_dialog  **************************
**
**  Show gotoline_dialog for the specified asedit window. If it does not exist yet
**  create it first as a child of menu_bar.
*/

#ifdef _NO_PROTO
void show_gotoline_dialog (win)
	aseditWindowStruct *win;
#else  /* ! _NO_PROTO */

void show_gotoline_dialog (aseditWindowStruct *win)
#endif
{
    if(win->gotoline_dialog == NULL)	/* first create the dialog */
    {
	Arg		al[5];		/*  arg list		*/
	register  int	ac = 0;		/*  arg count		*/
	Widget 		text;		/*  text widget 	*/

	/* Create go to line dialog ... */
	ac = 0;
	XtSetArg (al[ac], XmNautoUnmanage, False);    ac++;
	win->gotoline_dialog = XmCreatePromptDialog(win->menu_bar,"go_to_line", al, ac);
	XtAddCallback (win->gotoline_dialog, XmNokCallback,
			(XtCallbackProc)DialogOkCB, mk_asdat_w(win, DIALOG_GOTOLINE) );
	XtAddCallback (win->gotoline_dialog, XmNcancelCallback,
			(XtCallbackProc)DialogCancelCB, mk_asdat_w(win, DIALOG_GOTOLINE) );
	XtAddCallback (win->gotoline_dialog, XmNhelpCallback,
			(XtCallbackProc)HelpCB, mk_asdat_w(win, DIALOG_GOTOLINE) );
	/* set the colour for the editable text widget */
	text = XmSelectionBoxGetChild(win->gotoline_dialog, XmDIALOG_TEXT);
	if(lstr.useOldColorSetup)
	{
	    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)20 );	/* 20 digit number max */


	/* none of the following ways of setting traaversal works:
	  XmProcessTraversal( text, XmTRAVERSE_HOME);
					XmTRAVERSE_CURRENT
					XmTRAVERSE_NEXT_TAB_GROUP
	  They do not work because the dialog widget (and all of its ancestors)
	  does need to be realized BEFORE you call XmProcessTraversal !
	  The way around it is to register a special focus callback */
	/* set a special callback which will set the focus to the text widget
	   when the dialog gets its first focus */
#ifndef XFOCUS_BUG
	XtAddCallback(win->gotoline_dialog, XmNfocusCallback,
			(XtCallbackProc)focusCB, (XtPointer)text);
#endif
    }

    asManageDialog(win->gotoline_dialog);

    /* set the keyboard focus to the text widget each time the dialog pops-up */
#if (XmVersion == 1000)
    _XmProcessTraversal( XmSelectionBoxGetChild(win->gotoline_dialog, XmDIALOG_TEXT), 
				 XmTRAVERSE_CURRENT);  /** private f. in Motif 1.0***/
#else
    XmProcessTraversal( XmSelectionBoxGetChild(win->gotoline_dialog, XmDIALOG_TEXT), 
				XmTRAVERSE_CURRENT);  
#endif

}   /* show_gotoline_dialog */

