/*** DTB_USER_CODE_START vvv Add file header below vvv ***/
/*
 * CDE - Common Desktop Environment
 *
 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
 *
 * These libraries and programs are free software; you can
 * redistribute them and/or modify them under the terms of the GNU
 * Lesser General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * These libraries and programs are distributed in the hope that
 * they will be useful, but WITHOUT ANY WARRANTY; without even the
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE. See the GNU Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with these libraries and programs; if not, write
 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
 * Floor, Boston, MA 02110-1301 USA
 */
/*** DTB_USER_CODE_END   ^^^ Add file header above ^^^ ***/

/*
 * File: conn_stubs.c
 * Contains: Module callbacks and connection functions
 *
 * This file was generated by dtcodegen, from module conn
 *
 * Any text may be added between the DTB_USER_CODE_START and
 * DTB_USER_CODE_END comments (even non-C code). Descriptive comments
 * are provided only as an aid.
 *
 *  ** EDIT ONLY WITHIN SECTIONS MARKED WITH DTB_USER_CODE COMMENTS.  **
 *  ** ALL OTHER MODIFICATIONS WILL BE OVERWRITTEN. DO NOT MODIFY OR  **
 *  ** DELETE THE GENERATED COMMENTS!                                 **
 */

#include <stdint.h>
#include <stdio.h>
#include <Xm/Xm.h>
#include "dtb_utils.h"
#include "dtbuilder.h"
#include "conn_ui.h"


/**************************************************************************
 *** DTB_USER_CODE_START
 ***
 *** All necessary header files have been included.
 ***
 *** Add include files, types, macros, externs, and user functions here.
 ***/


#include <sys/param.h>
#include "dtbuilder.h"
#include "conn_ui.h"

#include "palette_ui.h"
#include "prop.h"

#include <ab_private/connP.h>

#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#include <X11/cursorfont.h>
#include <Xm/List.h>
#include <Xm/PushB.h>
#include <Xm/RowColumn.h>
#include <Xm/ToggleB.h>
#include <Xm/TextF.h>
#include <Xm/Text.h>

#include <ab_private/obj.h>
#include <ab_private/trav.h>
#include <ab_private/objxm.h>

#include <ab_private/abobj.h>
#include <ab_private/abobj_set.h>
#include <ab_private/abobj_list.h>
#include <ab_private/brws.h>
#include <ab_private/proj.h>
#include <ab_private/istr.h>
#include <ab_private/ab.h>
#include <ab_private/ui_util.h>
#include "dtb_utils.h"

/*
 * Declarations of global widgets used by callbacks.
 */

static Widget	src_menu	= NULL;
static Widget	target_menu	= NULL;
static Widget	when_menu	= NULL;
static Widget	action_menu	= NULL;
static Widget	view_menu	= NULL;

static Widget	when_pulldown	= NULL;
static Widget	action_pulldown	= NULL;

static Widget	src_list	= NULL;
static Widget	target_list	= NULL;
static Widget	connection_list	= NULL;

static Widget	arg_rowcol	= NULL;
static Widget	arg_label	= NULL;
static Widget	arg_field	= NULL;

static Widget	connect_button	= NULL;
static Widget	change_button	= NULL;
static Widget	cancel_button	= NULL;
static Widget	delete_button	= NULL;

static Widget	std_action_item = NULL;
static Widget	call_function_item = NULL;
static Widget	execute_code_item = NULL;
static Widget	on_item_help_item = NULL;
static Widget	help_volume_item = NULL;

static Widget	location_rowcol	= NULL;
static Widget	location_field	= NULL;
static Widget	volume_rowcol	= NULL;
static Widget	volume_field	= NULL;
static Widget	action_type_opmenu = NULL;

static Widget	exec_code_dialog = NULL;
static Widget	exec_code_textpane = NULL;

static Widget	ConnP_view_source_obj = NULL; /* View:'s "Source Object" PushButton */
static long	ConnP_view_filter = -1;

static STRING	CodeFragBuf = NULL;
static STRING	action_type_labels[ACTION_TYPE_NUM_VALUES];		

static AB_WHEN		DefaultWhen = AB_WHEN_UNDEF;
static AB_FUNC_TYPE	DefaultFuncType = AB_FUNC_UNDEF;

/*
 * End declarations of global widgets
 */

static void		init_exec_code_dialog(
			    DtbConnExecCodeDialogInfo   instance
			);

static void		populate_src_menu(
			    Widget	widget,
			    XtPointer	client_data,
			    XtPointer	call_data
			);
static void		populate_target_menu(
			    Widget	widget,
			    XtPointer	client_data,
			    XtPointer	call_data
			);
static void		populate_when_menu(
			    Widget	widget,
			    XtPointer	client_data,
			    XtPointer	call_data
			);
static void		populate_action_menu(
			    Widget	widget,
			    XtPointer	client_data,
			    XtPointer	call_data
			);
static void		populate_view_menu(
			    Widget	widget,
			    XtPointer	client_data,
			    XtPointer	call_data
			);
static void		populate_list(
			    Widget		list,
			    ABObj		cur_selection,
			    BOOL                invoke_cb
			);
static void		populate_connection_list(
			    ABObj	cur_action_obj
			);
static void		change_src_type(
			    Widget	w,
			    XtPointer	client_data,
			    XtPointer	call_data
			);
static void		change_target_type(
			    Widget	w,
			    XtPointer	client_data,
			    XtPointer	call_data
			);
static void		change_arg_sensitivity(
			    Widget	w,
			    XtPointer	client_data,
			    XtPointer	call_data
			);
static void		set_view_filter(
			    Widget	w,
			    XtPointer	client_data,
			    XtPointer	call_data
			);
static BOOL		is_action_type(
			    ABObj	obj,
			    int		filter
			);
static void		update_cur_src(
			    Widget	w,
			    XtPointer	client_data,
			    XtPointer	call_data
			);
static void		update_cur_target(
			    Widget	w,
			    XtPointer	client_data,
			    XtPointer	call_data
			);
static void		select_connection(
			    Widget	w,
			    XtPointer	client_data,
			    XtPointer	call_data
			);

static void		setup_source(
			    AB_OBJECT_TYPE	source_type,
			    int			source_subtype,
			    ABObj		source
			);
static void		setup_target(
			    AB_OBJECT_TYPE	target_type,
			    int			target_subtype,
			    ABObj		target
			);
static int		get_cur_when(
			    void
			);
static AB_BUILTIN_ACTION get_cur_act(
			    void
			);
static void		set_cur_when(
			    AB_WHEN	new_when
			);
static void		set_cur_act(
			    AB_BUILTIN_ACTION	new_act
			);
static ABObj		get_cur_connection(
			    void
			);
static void		set_standard_action_type(
			    void
			);
static void		set_call_function_action_type(
			    void
			);
static void		set_execute_code_action_type(
			    void
			);
static void 		set_on_item_help_action_type(
			    void
			);
static void 		set_access_help_vol_action_type(
			    void
			);

static void 		set_conn_controls(
			    BOOL        state
			);
static void  		hide_execute_code_win(
			    void
			);
static BOOL  		verify_builtin_arg_string(
			    AB_BUILTIN_ACTION c_act,
			    ABObj             c_target,
			    Widget            field
			);
static void 		update_on_src_type_change(
			    AB_OBJECT_TYPE      obj_type,
			    int                 obj_subtype
			);
static void 		update_on_target_type_change(
			    AB_OBJECT_TYPE      obj_type,
			    int                 obj_subtype
			);
static void		update_conn_ed_controls(void);
static AB_FUNC_TYPE	get_cur_func_type(void);

static BOOL 		src_list_test(
			    ABObj test_obj
			);
static BOOL 		target_list_test(
			    ABObj test_obj
			);
static void 		set_ctrls_for_src(
			    BOOL	state
			);
static void 		set_ctrls_for_target(
			    BOOL	state
			);


extern void
conn_init(void)
{
    conn_strings_init();

    obj_add_destroy_callback(connP_update_on_obj_destroy, NULL);
}

extern void
conn_popup_dialog(
    Widget	widget,
    XtPointer	client_data,
    XtPointer	call_data
)
{
    extern Widget	AB_toplevel;

    if (AB_conn_dialog == (Widget)NULL)
    {
	dtbConnConnDialogInfo_clear(&dtb_conn_conn_dialog);
	(void)dtb_conn_conn_dialog_initialize(&dtb_conn_conn_dialog,
					      AB_toplevel);
	AB_conn_dialog = dtb_conn_conn_dialog.conn_dialog_shellform;

        /* 
         * Setup dialog to participate in dtbuilder window protocol
         */  
        ab_register_window(AB_conn_dialog, AB_WIN_DIALOG,
                WindowHidden, AB_toplevel, AB_WPOS_TILE_HORIZONTAL,
		conn_cancelCB, (XtPointer)&dtb_conn_conn_dialog);  

	/*
	 * These callbacks only operate on the Connections Editor dialog
	 * i.e. update lists
	 *
	 * If any code is added to them that is independent of 
	 * the Connections Editor, then the callback registration
	 * may have to be done in conn_init().
	 */
	obj_add_rename_callback(connP_update_on_obj_rename, NULL);
	obj_add_update_callback(connP_update_on_show_status, NULL);
    }
    XtManageChild(AB_conn_dialog);
    ab_show_window(AB_conn_dialog);
    update_conn_ed_controls();
}

static void
init_exec_code_dialog(
    DtbConnExecCodeDialogInfo   instance
)
{
    exec_code_dialog = instance->exec_code_dialog_shellform;
    exec_code_textpane = instance->exec_code_textpane;

    ab_register_window(exec_code_dialog, AB_WIN_DIALOG,
                WindowHidden, AB_conn_dialog, AB_WPOS_STACK_CENTER,
                NULL, NULL);
}

static void
populate_src_menu(
    Widget	widget,
    XtPointer	client_data,
    XtPointer	call_data
)
{
    int	i;

    for (i = 0; i < ConnP_num_conn_objs; i++)
    {
	Widget	w;

	w = XtVaCreateManagedWidget("src_menu_push",
		xmPushButtonWidgetClass, widget,
		XtVaTypedArg, XmNlabelString, XtRString,
		    ConnP_conn_objs[i].label, strlen(ConnP_conn_objs[i].label)+1,
		NULL);
	XtAddCallback(w, XmNactivateCallback,
			(XtCallbackProc)change_src_type,
			(XtPointer)&(ConnP_conn_objs[i]));
    }
}

static void
populate_target_menu(
    Widget	widget,
    XtPointer	client_data,
    XtPointer	call_data
)
{
    int	i;

    for (i = 0; i < ConnP_num_conn_objs; i++)
    {
	Widget	w = NULL;

        /* Application and Message objects can never be a 
	 * target, so don't put them in the Target Object 
	 * Type option menu. 
         */ 
        if ( (ConnP_conn_objs[i].obj_type != AB_TYPE_MESSAGE) && 
	     (ConnP_conn_objs[i].obj_type != AB_TYPE_PROJECT) &&
	     (ConnP_conn_objs[i].obj_type != AB_TYPE_MENU) 
	   )
        { 
	    w = XtVaCreateManagedWidget("target_menu_push",
			xmPushButtonWidgetClass, widget,
			XtVaTypedArg, XmNlabelString, XtRString,
				ConnP_conn_objs[i].label,
				strlen(ConnP_conn_objs[i].label)+1,
				NULL);
	    XtAddCallback(w, XmNactivateCallback,
			(XtCallbackProc)change_target_type,
			(XtPointer)&(ConnP_conn_objs[i]));
	}
    }
}

static void
populate_when_menu(
    Widget	widget,
    XtPointer	client_data,
    XtPointer	call_data
)
{
    int		num_labels;
    int		i;
    char	**labels;
    Widget	*w_list = NULL;

    when_pulldown = widget;

    labels = connP_get_when_labels(&num_labels);
    if (num_labels > 0)
    {
	w_list = (Widget *)XtMalloc(sizeof(Widget) * (num_labels + 1));
	for (i = 0; i < num_labels; i++)
	{
	    Widget	w;

	    w = XtVaCreateWidget("when_menu_push",
		    xmPushButtonWidgetClass, when_pulldown,
		    XtVaTypedArg, XmNlabelString, XtRString,
			labels[i], strlen(labels[i])+1,
		    NULL);
	    w_list[i] = w;
	}
	w_list[i] = NULL;
    }
    XtVaSetValues(when_pulldown, XmNuserData, (XtPointer)w_list, NULL);
    connP_ui_source_type_update(connP_get_source_type(),
				connP_get_source_subtype());
}

static void
populate_action_menu(
    Widget	widget,
    XtPointer	client_data,
    XtPointer	call_data
)
{
    int		num_labels;
    int		i;
    char	**labels;
    Widget	*w_list = NULL;

    action_pulldown = widget;

    labels = connP_get_act_labels(&num_labels);
    if (num_labels > 0)
    {
	w_list = (Widget *)XtMalloc(sizeof(Widget) * (num_labels + 1));
	for (i = 0; i < num_labels; i++)
	{
	    Widget	w;

	    w = XtVaCreateWidget("action_menu_push",
		    xmPushButtonWidgetClass, action_pulldown,
		    XtVaTypedArg, XmNlabelString, XtRString,
			labels[i], strlen(labels[i])+1,
		    NULL);
	    XtAddCallback(w, XmNactivateCallback,
			  change_arg_sensitivity, (XtPointer)NULL);
	    w_list[i] = w;
	}
	w_list[i] = NULL;
    }
    XtVaSetValues(action_pulldown, XmNuserData, (XtPointer)w_list, NULL);
    connP_ui_target_type_update(connP_get_target_type(),
				connP_get_target_subtype());
}

static void
populate_view_menu(
    Widget	widget,
    XtPointer	client_data,
    XtPointer	call_data
)
{
    long	i;
    Widget	w;


    w = XtVaCreateManagedWidget("view_menu_push",
	    xmPushButtonWidgetClass, widget,
	    XtVaTypedArg, XmNlabelString, XtRString,
		"Source Object", sizeof("Source Object"),
	    NULL);
    XtAddCallback(w, XmNactivateCallback, set_view_filter, (XtPointer)-1);
    ConnP_view_source_obj = w;

    for (i = 0; i < ConnP_num_conn_objs; i++)
    {
	w = XtVaCreateManagedWidget("view_menu_push",
		xmPushButtonWidgetClass, widget,
		XtVaTypedArg, XmNlabelString, XtRString,
		   ConnP_conn_objs[i].label, strlen(ConnP_conn_objs[i].label)+1,
		NULL);
	XtAddCallback(w, XmNactivateCallback, set_view_filter, (XtPointer)i);
    }
}

static void
setup_source(
    AB_OBJECT_TYPE	source_type,
    int			source_subtype,
    ABObj		source
)
{
    long	i = connP_get_obj_type_index(source_type, source_subtype);

    if (i < 0) return;

    XtVaSetValues(XmOptionButtonGadget(src_menu),
	XtVaTypedArg, XmNlabelString, XtRString,
	    ConnP_conn_objs[i].label, strlen(ConnP_conn_objs[i].label)+1,
	NULL);
    populate_list(src_list, source, FALSE);
}

static void
setup_target(
    AB_OBJECT_TYPE	target_type,
    int			target_subtype,
    ABObj		target
)
{
    long	i = connP_get_obj_type_index(target_type, target_subtype);

    if (i < 0) return;

    XtVaSetValues(XmOptionButtonGadget(target_menu),
	XtVaTypedArg, XmNlabelString, XtRString,
	    ConnP_conn_objs[i].label, strlen(ConnP_conn_objs[i].label)+1,
	NULL);
    populate_list(target_list, target, FALSE);
}

static void
populate_list(
    Widget		list,
    ABObj		cur_selection,
    BOOL		invoke_cb
)
{
    ABObj	project = proj_get_project();
    STRING	select_item = NULL;
    int		iRet = -1;
    
    if (list == NULL || project == NULL)
	return;

    if (list == src_list)
	abobj_list_load(list, project, src_list_test);
    else
	abobj_list_load(list, project, target_list_test);

    /* If the current object is in the list, then select
     * (highlight) it and call the callback associated
     * with selecting a list item. If all the items remain
     * deselected, then we have to make sure to make the
     * appropriate things inactive.
     */
    if (cur_selection)
    {
	select_item = abobj_get_moduled_name(cur_selection);
	iRet = ui_list_select_item(list, select_item, invoke_cb);
    }

    /* If cur_selection is NOT in the list, grey out the
     * the right controls.
     */
    if ((iRet < 0) || (cur_selection == NULL))
    {
	if (list == target_list)
	{
	    if (get_cur_func_type() == AB_FUNC_BUILTIN)
		set_ctrls_for_target(FALSE);
	    else 
		set_ctrls_for_target(TRUE);
	}
	else if (list == src_list)
	    set_ctrls_for_src(FALSE);
    }
}


static BOOL
src_list_test(
    ABObj	test_obj
)
{
    AB_OBJECT_TYPE      obj_type = obj_get_type(test_obj);
    int                 obj_subtype = obj_get_subtype(test_obj);
    AB_OBJECT_TYPE      cur_obj_type = connP_get_source_type();
    int                 cur_obj_subtype = connP_get_source_subtype();
    ABObj		mod = obj_get_module(test_obj);
    BOOL		ret = FALSE;
    
    if ((cur_obj_type == AB_TYPE_PROJECT) &&
	(obj_type == cur_obj_type))
    {
	ret = TRUE;
    }
    else if ((mod != NULL) && obj_has_flag(mod, MappedFlag) 
	     && obj_is_defined(mod)) 
    {
	if (connP_objtype_needs_subtype(cur_obj_type, cur_obj_subtype))
	{
	    if (!obj_is_sub(test_obj) &&
		obj_is_defined(test_obj) && 
		(obj_type == cur_obj_type) &&
		(obj_subtype == cur_obj_subtype))
	    {
		ret = TRUE;
	    }
	}
	else
	{
	    /* If the object is not a container (i.e. group,
	     * menubar, panedwindow, etc.), and the object
	     * doesn't need a subtype, either because it 
	     * doesn't have one (i.e. AB_TYPE_PROJECT) or
	     * because all object subtypes should appear
	     * under one catetory (i.e. AB_TYPE_CHOICE shows
	     * optionmenus, radioboxes, and checkboxes), then
	     * search for all those objects based solely on
	     * the object type - don't care about subtype.
	     * If the object is a container and it doesn't
	     * need a subtype, then its one of AB_CONT_FOOTER,
	     * AB_CONT_BUTTON_PANEL, AB_CONT_RELATIVE,
	     * AB_CONT_TOOL_BAR, so only count those objects.
	     */
	    if (!obj_is_container(test_obj) && 
		!obj_is_sub(test_obj) && 
		obj_is_defined(test_obj) && 
		obj_type == cur_obj_type)
	    {
	  	ret = TRUE;
	    }
	    else if (obj_is_container(test_obj) &&
		     (cur_obj_type == AB_TYPE_CONTAINER) 
		     && !obj_is_sub(test_obj) &&
		     obj_is_defined(test_obj) &&
		     (  (obj_subtype == AB_CONT_FOOTER) ||
			(obj_subtype == AB_CONT_BUTTON_PANEL)||
			(obj_subtype == AB_CONT_RELATIVE) ||
			(obj_subtype == AB_CONT_TOOL_BAR))) 
	    {
		ret = TRUE;
	    }
	}
    }
    return ret;
}

static BOOL
target_list_test(
    ABObj	test_obj
)
{
    AB_OBJECT_TYPE      obj_type = obj_get_type(test_obj);
    int                 obj_subtype = obj_get_subtype(test_obj);
    AB_OBJECT_TYPE      cur_obj_type = connP_get_target_type();
    int                 cur_obj_subtype = connP_get_target_subtype();
    ABObj		mod = obj_get_module(test_obj);
    BOOL		ret = FALSE;
    
    if ((mod != NULL) && obj_has_flag(mod, MappedFlag) 
	&& obj_is_defined(mod)) 
    {
	if (connP_objtype_needs_subtype(cur_obj_type, cur_obj_subtype))
	{
	    if (!obj_is_sub(test_obj) &&
		obj_is_defined(test_obj) && 
		(obj_type == cur_obj_type) &&
		(obj_subtype == cur_obj_subtype))
	    {
		ret = TRUE;
	    }
	}
	else
	{
	    /* If the object is not a container (i.e. group,
	     * menubar, panedwindow, etc.), and the object
	     * doesn't need a subtype, either because it 
	     * doesn't have one (i.e. AB_TYPE_PROJECT) or
	     * because all object subtypes should appear
	     * under one catetory (i.e. AB_TYPE_CHOICE shows
	     * optionmenus, radioboxes, and checkboxes), then
	     * search for all those objects based solely on
	     * the object type - don't care about subtype.
	     * If the object is a container and it doesn't
	     * need a subtype, then it's one of AB_CONT_FOOTER,
	     * AB_CONT_BUTTON_PANEL, AB_CONT_RELATIVE,
	     * AB_CONT_TOOL_BAR, so only count those objects.
	     */
	    if (!obj_is_container(test_obj) && 
		!obj_is_sub(test_obj) && 
		obj_is_defined(test_obj) && 
		obj_type == cur_obj_type)
	    {
	  	ret = TRUE;
	    }
	    else if (obj_is_container(test_obj) &&
		     (cur_obj_type == AB_TYPE_CONTAINER) 
		     && !obj_is_sub(test_obj) &&
		     obj_is_defined(test_obj) &&
		     (  (obj_subtype == AB_CONT_FOOTER) ||
			(obj_subtype == AB_CONT_BUTTON_PANEL)||
			(obj_subtype == AB_CONT_RELATIVE) ||
			(obj_subtype == AB_CONT_TOOL_BAR))) 
	    {
		ret = TRUE;
	    }
	}
    }
    return ret;
}

static void
populate_connection_list(
    ABObj	cur_action_obj
)
{
    ABObj		project = proj_get_project();
    ABObj		obj = NULL, selected_conn = NULL;
    AB_TRAVERSAL	trav;
    ABObj		*obj_list = (ABObj *)NULL;
    int			count;
    
    XtSetSensitive(change_button, FALSE);
    XtSetSensitive(delete_button, FALSE);

    if (connection_list == NULL || project == NULL)
	return;

    /* Save the currently selected connection in the View list */
    selected_conn = get_cur_connection();

    XtVaGetValues(connection_list, XmNuserData, (XtPointer)&obj_list, NULL);
    if (obj_list != NULL)
	XtFree((char *)obj_list);
    obj_list = (ABObj *)NULL;
    XtVaSetValues(connection_list, XmNuserData, (XtPointer)obj_list, NULL);

    XmListDeselectAllItems(connection_list);
    XmListDeleteAllItems(connection_list);
 
    /*
    if (connP_get_source() != NULL &&
	obj_get_type(connP_get_source()) != connP_get_source_type())
        return;
    */

    count = 0;
    for (trav_open(&trav, project, AB_TRAV_ACTIONS);
        (obj = trav_next(&trav)) != NULL; )
    {
	if (!is_action_type(obj, ConnP_view_filter))
	    continue;
	count++;
    }
    trav_close(&trav);

    if (count == 0)
    {
	XtSetSensitive(connection_list, FALSE);
	return;
    }
    else
    {
	XtSetSensitive(connection_list, TRUE);
    }

    obj_list = (ABObj *)XtMalloc(sizeof(ABObj) * (count+1));
    if (obj_list == (ABObj *)NULL)
	return;

    count = 0;
    for (trav_open(&trav, project, AB_TRAV_ACTIONS);
        (obj = trav_next(&trav)) != NULL; )
    {
	XmString	xm_item_str;
	
	if (is_action_type(obj, ConnP_view_filter))
	{
	    STRING	item_str = connP_make_conn_string(obj);

	    xm_item_str = XmStringCreateLocalized(item_str);
	    XmListAddItem(connection_list, xm_item_str, 0);
	    XmStringFree(xm_item_str);
	    if ((cur_action_obj == obj) || 
		(selected_conn && (selected_conn == obj))) 
	    {
		ui_list_select_item(connection_list, item_str, FALSE);
		XtSetSensitive(change_button, TRUE);
		XtSetSensitive(delete_button, TRUE);
	    }

	    obj_list[count++] = obj;
	}
    }
    trav_close(&trav);
    obj_list[count] = (ABObj)NULL;
    XtVaSetValues(connection_list, XmNuserData, (XtPointer)obj_list, NULL);

}

static BOOL
is_action_type(
    ABObj	obj,
    int		filter
)
{
    BOOL	ret_val = (BOOL)FALSE;
    ABObj	mod;

    if (!obj_is_project(obj->info.action.from))
    {
    	mod = obj_get_module(obj->info.action.from);

    	if (mod == NULL || !obj_has_flag(mod, MappedFlag))
	    goto cret;
    }

    if (filter == -1)
    {
	ret_val = obj->info.action.from == connP_get_source();
    }
    else
    {
	AB_OBJECT_TYPE	obj_type = ConnP_conn_objs[filter].obj_type;
	int	obj_subtype = ConnP_conn_objs[filter].obj_subtype;

	ret_val = obj_get_type(obj->info.action.from) == obj_type;
	if (obj_subtype != -1)
	    ret_val &= (obj_get_subtype(obj->info.action.from) == obj_subtype);
    }
cret:
    return(ret_val);
}

static void
change_src_type(
    Widget	w,
    XtPointer	client_data,
    XtPointer	call_data
)
{
    ConnObj	*objtype_desc = (ConnObj *)client_data;

    if (objtype_desc == (ConnObj *)NULL)
	return;

    update_on_src_type_change(objtype_desc->obj_type,
                          objtype_desc->obj_subtype);

    /* Reset the current source to be NULL */
    conn_set_source((ABObj) NULL);

    /* Reset the connections list */
    connP_set_connection(NULL);
    populate_connection_list(connP_get_connection());

    /* Make When option menu inactive */
    set_ctrls_for_src(FALSE);
    
    set_conn_controls(FALSE);
}

static void
change_target_type(
    Widget	w,
    XtPointer	client_data,
    XtPointer	call_data
)
{
    ConnObj	*objtype_desc = (ConnObj *)client_data;

    if (objtype_desc == (ConnObj *)NULL)
	return;

    update_on_target_type_change(objtype_desc->obj_type,
                          objtype_desc->obj_subtype);

    /* Reset the current target to be NULL */
    conn_set_target((ABObj) NULL);

    /* Make action option menu and argument field inactive */
    set_ctrls_for_target(FALSE);

    if (!connP_conn_is_possible())
	set_conn_controls(FALSE);
}

static void
change_arg_sensitivity(
    Widget	w,
    XtPointer	client_data,
    XtPointer	call_data
)
{
    int			act_cand = get_cur_act();
    AB_BUILTIN_ACTION	act_type = AB_STDACT_UNDEF;

    if (act_cand < 0 || act_cand >= AB_BUILTIN_ACTION_NUM_VALUES)
	return;

    XmTextFieldSetString(arg_field, "");

    act_type = (AB_BUILTIN_ACTION)act_cand;
    if (connP_action_needs_arg(act_type))
    {
	XtSetSensitive(arg_label, TRUE);
	XtSetSensitive(arg_field, TRUE);
	XmProcessTraversal(arg_field, XmTRAVERSE_CURRENT);
    }
    else
    {
	XtSetSensitive(arg_label, FALSE);
	XtSetSensitive(arg_field, FALSE);
    }
}

static void
set_view_filter(
    Widget	w,
    XtPointer	client_data,
    XtPointer	call_data
)
{
    if (ConnP_view_filter != (long)client_data)
    {
	ConnP_view_filter = (long)client_data;
	populate_connection_list(NULL);
    }
}

/* This is the browseSelect callback for the Source
 * object list.
 */
static void
update_cur_src(
    Widget	w,
    XtPointer	client_data,
    XtPointer	call_data
)
{
    XmListCallbackStruct	*list_cl = (XmListCallbackStruct *)call_data;
    ABObj                       module = (ABObj) NULL;
    ABObj			selected_obj = (ABObj) NULL;
    STRING			name = NULL;

    if (list_cl->reason != XmCR_BROWSE_SELECT)
    {
	return;
    }

    if (name = objxm_xmstr_to_str(list_cl->item))
    {
        abobj_moduled_name_extract(name, &module, &selected_obj);
 	if (selected_obj == NULL)
	    abobj_project_name_extract(name, &selected_obj);
        util_free(name);

        if (selected_obj)
        {
	    conn_set_source(selected_obj);

	    /* If the object is a message, then we have to do
	     * some special processing for the "When" optionmenu.
	     * The reason is that the "When" optionmenu can
	     * change when different message objects are selected
	     * from the Source Object List.  If a particular
	     * message does not have a certain button, then that
	     * "when" (i.e. Click Action1) is made inactive, so
	     * another "when" should be shown instead.
	     */
	    if (obj_is_message(selected_obj))
	    {
	    	if (obj_has_action1_button(selected_obj))
	    	{
		    XtVaSetValues(XmOptionButtonGadget(when_menu),
                    XtVaTypedArg, XmNlabelString, XtRString,
                        ConnP_conn_whens[0].label,
                        strlen(ConnP_conn_whens[0].label)+1, NULL);
	    	}
	    	else if (obj_has_action2_button(selected_obj))
	    	{
                    XtVaSetValues(XmOptionButtonGadget(when_menu),
                    XtVaTypedArg, XmNlabelString, XtRString,
                        ConnP_conn_whens[1].label,
                        strlen(ConnP_conn_whens[1].label)+1, NULL);
	    	}
	    	else if (obj_has_action3_button(selected_obj))
	    	{
                    XtVaSetValues(XmOptionButtonGadget(when_menu),
                    XtVaTypedArg, XmNlabelString, XtRString,
                        ConnP_conn_whens[2].label,
                        strlen(ConnP_conn_whens[2].label)+1, NULL);
	    	}
	    	else if (obj_has_cancel_button(selected_obj))
	    	{
                    XtVaSetValues(XmOptionButtonGadget(when_menu),
                    XtVaTypedArg, XmNlabelString, XtRString,
                        ConnP_conn_whens[3].label,
                        strlen(ConnP_conn_whens[3].label)+1, NULL);
	    	}
	    }

	    /* If the currently selected object is a choice item,
	     * then we have to check if it is a radio/checkbox
	     * item or an optionmenu item.  If it's a radio/checkbox
	     * item, then set the "When" to be "Toggled" ["Activated"
	     * is made inactive in connP_update_when_menu()]. If the
	     * the item is an optionmenu item, then make the "When"
	     * ["Toggled" is made inactive in connP_update_when_menu()].
	     */
	    if (obj_is_choice_item(selected_obj))
	    {
	    	if (obj_is_option_menu(obj_get_root(obj_get_parent(selected_obj))))
                    XtVaSetValues(XmOptionButtonGadget(when_menu),
                    XtVaTypedArg, XmNlabelString, XtRString,
                        ConnP_conn_whens[2].label,
                        strlen(ConnP_conn_whens[2].label)+1, NULL);
	    	else
                    XtVaSetValues(XmOptionButtonGadget(when_menu),
                    XtVaTypedArg, XmNlabelString, XtRString,
                        ConnP_conn_whens[3].label,
                        strlen(ConnP_conn_whens[3].label)+1, NULL);
	    }
            connP_set_connection(NULL);
            populate_connection_list(connP_get_connection());

            set_ctrls_for_src(TRUE);

            if (connP_conn_is_possible())
	    	set_conn_controls(TRUE);
            else
	    	set_conn_controls(FALSE);
	}
    }
}

static void
update_cur_target(
    Widget	w,
    XtPointer	client_data,
    XtPointer	call_data
)
{
    XmListCallbackStruct	*list_cl = (XmListCallbackStruct *)call_data;
    ABObj                       module = (ABObj) NULL;
    ABObj                       selected_obj = (ABObj) NULL;
    STRING                      name = NULL;
    AB_WHEN             	g_when = AB_WHEN_UNDEF;
    AB_FUNC_TYPE        	g_func = AB_FUNC_UNDEF;
    AB_BUILTIN_ACTION   	g_act = AB_STDACT_UNDEF;

    if (list_cl->reason != XmCR_BROWSE_SELECT)
	return;

    if (name = objxm_xmstr_to_str(list_cl->item))
    {
        abobj_moduled_name_extract(name, &module, &selected_obj);
        util_free(name);

        if (selected_obj)
        {
	    conn_set_target(selected_obj);

	    /* Get the default action. It can change depending
	     * upon the source and target objects.
	     */
	    connP_guess_when_action(connP_get_source_type(),
		connP_get_source_subtype(),
                connP_get_target_type(),
                connP_get_target_subtype(),
                &g_when, &g_func, &g_act);

	    if (g_act != get_cur_act())
	        set_cur_act(g_act);

	    set_ctrls_for_target(TRUE);

	    if (connP_conn_is_possible())
		set_conn_controls(TRUE);
	    else
		set_conn_controls(FALSE);
	}
    }
}

static void
select_connection(
    Widget	w,
    XtPointer	client_data,
    XtPointer	call_data
)
{
    XmListCallbackStruct	*list_cl = (XmListCallbackStruct *)call_data;
    ABObj			*obj_list = (ABObj *)NULL;
    ABObj			cur_action = NULL;
    AB_ACTION_INFO		*cur_info;

    if (list_cl->reason != XmCR_BROWSE_SELECT)
	return;

    XtVaGetValues(w, XmNuserData, &obj_list, NULL);
    if (obj_list == NULL)
	return;
    if (list_cl->item_position > 0)
	cur_action = obj_list[list_cl->item_position-1];

    if (cur_action == NULL || !obj_is_action(cur_action))
	return;

    cur_info = &(cur_action->info.action);

    if (cur_info->from == NULL)
	return;

    XtSetSensitive(change_button, TRUE);
    XtSetSensitive(delete_button, TRUE);

    if (connP_get_source_type() != obj_get_type(cur_info->from))
    {
	if (connP_objtype_needs_subtype(obj_get_type(cur_info->from),
		obj_get_subtype(cur_info->from)))
	{
	    if (connP_get_source_subtype() != obj_get_subtype(cur_info->from))
	    {
		conn_set_source(cur_info->from);
		setup_source(connP_get_source_type(),
			     connP_get_source_subtype(),
			     connP_get_source());
	    }
	}
	else
	{
	    conn_set_source(cur_info->from);
	    setup_source(connP_get_source_type(),
			 connP_get_source_subtype(),
			 connP_get_source());
	}
    }
    else
    {
	conn_set_source(cur_info->from);
	ui_list_select_item(src_list, 
		abobj_get_moduled_name(cur_info->from), FALSE);
    }

    set_cur_when(cur_info->when);
    set_ctrls_for_src(TRUE);

    switch (cur_info->func_type)
    {
      case AB_FUNC_BUILTIN:
	if (cur_info->to == NULL)
	    return;
	if (connP_get_target_type() != obj_get_type(cur_info->to))
	{
	    if (connP_objtype_needs_subtype(obj_get_type(cur_info->to),
			obj_get_subtype(cur_info->to)))
	    {
		if (connP_get_target_subtype() != obj_get_subtype(cur_info->to))
		{
		    conn_set_target(cur_info->to);
		    setup_target(connP_get_target_type(),
				connP_get_target_subtype(), 
				connP_get_target());
		}
	    }
	    else
	    {
		conn_set_target(cur_info->to);
		setup_target(connP_get_target_type(),
			     connP_get_target_subtype(), 
			     connP_get_target());
	    }
	}
	else
	{
	    conn_set_target(cur_info->to);
	    ui_list_select_item(target_list, 
		abobj_get_moduled_name(cur_info->to), FALSE);
	}
	
	set_cur_act(cur_info->func_value.builtin);
	set_ctrls_for_target(TRUE);

	if (connP_get_action_type() != AB_FUNC_BUILTIN)
	{
            ui_optionmenu_change_label(action_type_opmenu,
                	action_type_labels[ACTION_TYPE_PREDEFINED]);
            set_standard_action_type();
	}

	switch (connP_action_needs_arg(cur_info->func_value.builtin))
	{
	    case AB_ARG_STRING:
	    {
		ISTRING	istr_val;

	    	istr_val = cur_info->arg_value.sval;
	    	/*
	     	 * Populate arg entries
	     	 */
	    	if (istr_val != NULL)
		    XtVaSetValues(arg_field, XmNvalue,
				istr_string(istr_val), NULL);
	    	else
		    XtVaSetValues(arg_field, XmNvalue, "", NULL);
	    }
	    break;

	    case AB_ARG_INT:
	    {
		char	str_val[MAXPATHLEN];
	
		*str_val = 0;
		sprintf(str_val, "%d", cur_info->arg_value.ival);
		XtVaSetValues(arg_field, XmNvalue, str_val, NULL);
	    }
	    break;
	}
	break;

      case AB_FUNC_USER_DEF:
      {
	STRING		cur_func_name = NULL;
	STRING		func_name = obj_get_func_name(cur_action);

 	XtVaGetValues(arg_field, XmNvalue, &cur_func_name, NULL);

	set_ctrls_for_target(TRUE);

	if (connP_get_action_type() != AB_FUNC_USER_DEF)
	{
            ui_optionmenu_change_label(action_type_opmenu,
			action_type_labels[ACTION_TYPE_CALLFUNC]);
	    set_call_function_action_type();
	}
	if (strcmp(cur_func_name, func_name) != 0)
	{
	    if (func_name != (STRING) NULL)
		XtVaSetValues(arg_field, XmNvalue, func_name, NULL);
	}
	break;
      }

      case AB_FUNC_CODE_FRAG:
      {
	STRING	code_frag = obj_get_func_code(cur_action);

	set_ctrls_for_target(TRUE);

	if (connP_get_action_type() != AB_FUNC_CODE_FRAG)
	{
            ui_optionmenu_change_label(action_type_opmenu, 
			action_type_labels[ACTION_TYPE_EXECUTE_CODE]); 
            set_execute_code_action_type(); 
	}
	if (!util_strempty(code_frag))
	{
	    char	*newline = NULL;
	    STRING	first_line = NULL;

            XmTextSetString(exec_code_textpane, code_frag);
	    newline = strchr(code_frag, '\n');
	    if (newline)
	    {
		*newline = '\0';
	    }
	    first_line = (STRING)util_malloc(strlen(code_frag) + 4);
	    if (first_line)
	    {
		strcpy(first_line, code_frag);
		strcat(first_line, "...");
		XmTextFieldSetString(arg_field, first_line);
		util_free(first_line);
	    }

 	    /* Put back the newline character */
	    if (newline) *newline = '\n';
        }
	else
	    XmTextFieldSetString(arg_field, "");

	ab_show_window(exec_code_dialog);
	
	break;
      }

      case AB_FUNC_ON_ITEM_HELP:
        if (connP_get_action_type() != AB_FUNC_ON_ITEM_HELP)
        {
            ui_optionmenu_change_label(action_type_opmenu,
		    action_type_labels[ACTION_TYPE_ON_ITEM_HELP]);
            set_on_item_help_action_type();
	}
	break;

      case AB_FUNC_HELP_VOLUME:
      {
	    STRING  help_loc = obj_get_func_help_location(cur_action);
	    STRING  help_vol = obj_get_func_help_volume(cur_action);

	    if (connP_get_action_type() != AB_FUNC_HELP_VOLUME)
	    {
            	ui_optionmenu_change_label(action_type_opmenu,
			action_type_labels[ACTION_TYPE_HELP_VOLUME]);
	    }
            set_access_help_vol_action_type();

            if (help_loc != (STRING) NULL)
                XmTextFieldSetString(location_field, help_loc);
            if (help_vol != (STRING) NULL)
                XmTextFieldSetString(volume_field, help_vol);
	break;
      }
    }
}



static int
get_cur_when(
    void
)
{
    Widget	label_wid = XmOptionButtonGadget(when_menu);
    XmString	xm_when_label	= (XmString)NULL;
    char	*when_label = NULL;
    int	i;

    XtVaGetValues(label_wid, XmNlabelString, &xm_when_label, NULL);
    if (xm_when_label != NULL) {
	when_label = objxm_xmstr_to_str(xm_when_label);

	for (i = 0; i < ConnP_num_conn_whens; i++) {
	    if (!strcmp(when_label, ConnP_conn_whens[i].label)) {
		XtFree(when_label);
		return((int)ConnP_conn_whens[i].when_type);
	    }
	}
    }

    /*
     * Should never happen
     */
    XtFree(when_label);
    return(-1);
}

static AB_BUILTIN_ACTION
get_cur_act(
    void
)
{
    Widget	label_wid = XmOptionButtonGadget(action_menu);
    XmString	xm_act_label	= (XmString)NULL;
    char	*act_label = NULL;
    int	i;

    XtVaGetValues(label_wid, XmNlabelString, &xm_act_label, NULL);
    if (xm_act_label != NULL) {
	act_label = objxm_xmstr_to_str(xm_act_label);

	for (i = 0; i < ConnP_num_conn_acts; i++) {
	    if (!strcmp(act_label, ConnP_conn_acts[i].label)) {
		XtFree(act_label);
		return(ConnP_conn_acts[i].act_type);
	    }
	}
    }

    /*
     * Should never happen
     */
    XtFree(act_label);
    return((AB_BUILTIN_ACTION)-1);
}

static void
set_cur_when(
    AB_WHEN	new_when
)
{
    int	i;

    for (i = 0; i < ConnP_num_conn_whens; i++)
    {
	if (new_when == ConnP_conn_whens[i].when_type)
	    break;
    }

    if (i < ConnP_num_conn_whens)
    {
	XtVaSetValues(XmOptionButtonGadget(when_menu),
	    XtVaTypedArg, XmNlabelString, XtRString,
		ConnP_conn_whens[i].label, strlen(ConnP_conn_whens[i].label)+1,
	    NULL);
    }

}
static void
set_cur_act(
    AB_BUILTIN_ACTION	new_act
)
{
    int	i;

    for (i = 0; i < ConnP_num_conn_acts; i++)
	if (new_act == ConnP_conn_acts[i].act_type)
	    break;

    if (i < ConnP_num_conn_acts)
    {
	XtVaSetValues(XmOptionButtonGadget(action_menu),
	    XtVaTypedArg, XmNlabelString, XtRString,
		ConnP_conn_acts[i].label, strlen(ConnP_conn_acts[i].label)+1,
	    NULL);
	change_arg_sensitivity(arg_field, (XtPointer)NULL, (XtPointer)NULL);
    }

}

extern void
connP_ui_source_type_update(
    AB_OBJECT_TYPE	new_type,
    int			new_subtype
)
{
    Widget	*w_list = NULL;
    int		i;
    AB_WHEN             g_when = AB_WHEN_UNDEF;
    AB_FUNC_TYPE        g_func = AB_FUNC_UNDEF;
    AB_BUILTIN_ACTION   g_act = AB_STDACT_UNDEF;

    if (when_pulldown == NULL)
    {
	return;
    }

    XtVaGetValues(when_pulldown,
	    XmNuserData,	&w_list,
	    NULL);

    if (w_list == NULL)
    {
	return;
    }

    for (i = 0; w_list[i] != NULL; i++)
    {
	XtUnmanageChild(w_list[i]);
    }

    for (i = 0; i < ConnP_num_conn_whens; i++)
    {
	XtManageChild(w_list[ConnP_conn_whens[i].when_type - 1]);
    }
}

extern void
connP_ui_target_type_update(
    AB_OBJECT_TYPE	new_type,
    int			new_subtype
)
{
    Widget	*w_list = NULL;
    int		i;

    if (action_pulldown == NULL)
	return;

    XtVaGetValues(action_pulldown,
	    XmNuserData,	&w_list,
	    NULL);

    if (w_list == NULL)
	return;

    for (i = 0; w_list[i] != NULL; i++)
	XtUnmanageChild(w_list[i]);

    for (i = 0; i < ConnP_num_conn_acts; i++)
	XtManageChild(w_list[ConnP_conn_acts[i].act_type - 1]);
}

static ABObj
get_cur_connection(
    void
)
{
    XmString		*sel_items = NULL;
    int			sel_count = 0;
    ABObj		*obj_list = (ABObj *) NULL;
    int			pos = 0;
    ABObj		ab_action = NULL;

    if (connection_list == NULL)
	return(NULL);

    /*
     * Look for selected connection
     */
    XtVaGetValues(connection_list,
	    XmNselectedItemCount,	&sel_count,
	    XmNselectedItems,		&sel_items,
	    XmNuserData,		&obj_list,
	NULL);
    
    if (sel_count != 1 || obj_list == NULL)
    {
	return(NULL);
    }

    pos = XmListItemPos(connection_list, sel_items[0]);
    if (pos <= 0)
    {
	return(NULL);
    }
    ab_action = obj_list[pos-1];
    return(ab_action); 
}

static void
set_standard_action_type(
    void
)
{
    XmString	xm_label_str;
    long		i = 0;
    BOOL	found = FALSE;

    connP_set_action_type(AB_FUNC_BUILTIN);

    XtSetSensitive(target_menu, TRUE);
    XtSetSensitive(target_list, TRUE);
    XtManageChild(action_menu);

    /* It's possible that the target list has a selected
     * item even though it is insensitive. That means
     * that when the Action Type is set back to Predefined
     * and the target list becomes active again, then the
     * action optionmenu has to have the right default
     * action showing for the target object type selected.
     */
    if (ui_list_get_selected_pos(target_list) > 0)
    {
	/* If the current predefined action is not appropriate
	 * for the current target object type, then change
	 * it to the default action. This shouldn't happen
	 * though, I think. 
	 */
	for (i = 0; i < ConnP_num_conn_acts; i++)
	    if (get_cur_act() == ConnP_conn_acts[i].act_type) 
		found = TRUE;
	if (!found)
	{
	    i = -1;
	    i = connP_get_obj_type_index(connP_get_target_type(),
			connP_get_target_subtype());
	    if (i >= 0)
	    	set_cur_act(ConnP_conn_objs[i].default_act);
	}
	set_ctrls_for_target(TRUE);
    }
    else	/* No target object selected */
    {
	set_ctrls_for_target(FALSE);
    }

    XtManageChild(arg_rowcol);
    XmTextFieldSetString(arg_field, "");
    XmTextFieldSetEditable(arg_field, True);
    XtUnmanageChild(location_rowcol);
    XtUnmanageChild(volume_rowcol);
    hide_execute_code_win();

    xm_label_str = XmStringCreateLocalized(CATGETS(Dtb_project_catd,
100, 54, ARGUMENT_LABEL));
    XtVaSetValues(arg_label, XmNlabelString, xm_label_str, NULL);
    XmStringFree(xm_label_str);

    if (connP_conn_is_possible())
        set_conn_controls(TRUE);
    else
        set_conn_controls(FALSE);
}

static void
set_call_function_action_type(
    void
)
{
    XmString	xm_label_str;

    connP_set_action_type(AB_FUNC_USER_DEF);

    XtSetSensitive(target_menu, FALSE);
    XtSetSensitive(target_list, FALSE);
    XtManageChild(arg_rowcol);
    XmTextFieldSetEditable(arg_field, True);
    XmTextFieldSetString(arg_field, "");
    XtUnmanageChild(action_menu);
    XtUnmanageChild(volume_rowcol);
    XtUnmanageChild(location_rowcol);
    hide_execute_code_win();

    xm_label_str = XmStringCreateLocalized(CATGETS(Dtb_project_catd,
			100, 55, FUNCTION_LABEL));
    XtVaSetValues(arg_label, XmNlabelString, xm_label_str, NULL);
    XmStringFree(xm_label_str);

    XtSetSensitive(arg_label, TRUE);
    XtSetSensitive(arg_field, TRUE);
    XmProcessTraversal(arg_field, XmTRAVERSE_CURRENT);

    if (connP_conn_is_possible())
        set_conn_controls(TRUE);
    else
        set_conn_controls(FALSE);
}

static void
set_execute_code_action_type(
    void
)
{
    XmString	xm_label_str;

    connP_set_action_type(AB_FUNC_CODE_FRAG);

    XtSetSensitive(target_menu, FALSE);
    XtSetSensitive(target_list, FALSE);
    XtManageChild(arg_rowcol);
    XmTextFieldSetEditable(arg_field, False);
    XmTextFieldSetString(arg_field, "");
    XtUnmanageChild(action_menu);
    XtUnmanageChild(volume_rowcol);
    XtUnmanageChild(location_rowcol);

    xm_label_str = XmStringCreateLocalized(CATGETS(Dtb_project_catd,
			100, 56, CODE_LABEL));
    XtVaSetValues(arg_label, XmNlabelString, xm_label_str, NULL);
    XmStringFree(xm_label_str);

    XtSetSensitive(arg_label, TRUE);
    XtSetSensitive(arg_field, TRUE);
    XmProcessTraversal(arg_field, XmTRAVERSE_CURRENT);

    if (connP_conn_is_possible())
        set_conn_controls(TRUE);
    else
        set_conn_controls(FALSE);
}

static void
set_on_item_help_action_type(
    void
)
{
    connP_set_action_type(AB_FUNC_ON_ITEM_HELP);

    XtSetSensitive(target_menu, FALSE);
    XtSetSensitive(target_list, FALSE);
    XtUnmanageChild(action_menu);
    XtUnmanageChild(arg_rowcol);
    XtUnmanageChild(volume_rowcol);
    XtUnmanageChild(location_rowcol);
    hide_execute_code_win();

    if (connP_conn_is_possible())
        set_conn_controls(TRUE);
    else
        set_conn_controls(FALSE);
}

static void
set_access_help_vol_action_type(
    void 
) 
{ 
    connP_set_action_type(AB_FUNC_HELP_VOLUME); 

    XtSetSensitive(target_menu, FALSE); 
    XtSetSensitive(target_list, FALSE); 
    XtUnmanageChild(action_menu); 
    XtUnmanageChild(arg_rowcol); 
    XtManageChild(volume_rowcol); 
    XmTextFieldSetString(volume_field, "");
    XtManageChild(location_rowcol); 
    XmTextFieldSetString(location_field, "");
    hide_execute_code_win();

    if (connP_conn_is_possible())
        set_conn_controls(TRUE);
    else
        set_conn_controls(FALSE);
} 

extern int
connP_update_on_obj_destroy(
    ObjEvDestroyInfo	info
)
{
    ABObj		obj = info->obj,
			project;
    AB_OBJECT_TYPE	ab_type;

    ab_type = obj_get_type(obj);
    if (ab_type == AB_TYPE_UNDEF || ab_type == AB_TYPE_UNKNOWN)
	return 0;

    project = obj_get_project(obj);

    if (!project)
	return (0);

    /*
     * If entire project is being destroyed, skip the cleanup
     */
    if (!obj_has_flag(project, BeingDestroyedFlag))
        connP_destroy_connections_for(obj);

    if (AB_conn_dialog != (Widget)NULL)
    {
        if (obj == connP_get_source())
	{
	    conn_set_source(NULL);
	    set_ctrls_for_src(FALSE);
	}
        if (obj == connP_get_target())
	{
	    conn_set_target(NULL);
	    set_ctrls_for_target(FALSE);
	}
   	if (connP_obj_part_of_conn(obj, connP_get_connection()))
	{
	    connP_set_connection(NULL);
	}

        /*
         * If obj is salient and its type is the same as that of
         * the current source or target type in the conn-mgr,
         * update the manager window
         */
	abobj_list_obj_destroyed(src_list, info->obj, src_list_test);
	abobj_list_obj_destroyed(target_list, info->obj, target_list_test);
	populate_connection_list(connP_get_connection());

	if (connP_conn_is_possible())
	    set_conn_controls(TRUE);
	else
	    set_conn_controls(FALSE);
    }

    return 0;
}

extern int
connP_update_on_obj_rename(
    ObjEvAttChangeInfo    info
)
{
    ABObj		obj = info->obj;
    AB_OBJECT_TYPE	ab_type = AB_TYPE_UNDEF;
    ABObj       	module = obj_get_module(obj);
    int			iRet = 0;

    if ((obj != NULL) && (AB_conn_dialog != (Widget)NULL))
    {
	ab_type = obj_get_type(obj);
	if ((ab_type != AB_TYPE_UNDEF) && (ab_type != AB_TYPE_UNKNOWN)
	    && !obj_is_project(obj))
	{
	    /* Replace the items in the Source and Target lists
	     * whose module name has changed or the object name
	     * has changed.
	     */
	    abobj_list_obj_renamed(src_list, obj, 
		istr_string(info->old_name), src_list_test);
	    abobj_list_obj_renamed(target_list, obj, 
		istr_string(info->old_name), target_list_test);

	    /* Update the Connections list. An object's name 
	     * or an object's module name may have changed
	     * and if it is part of a connection that is showing
	     * in the list, it has to be replaced.
	     */
	    populate_connection_list(connP_get_connection());
	}
    }

    return iRet;
}

/* Handles module show/hide and Undo of deleted object */
extern int
connP_update_on_show_status(
    ObjEvUpdateInfo	info
)
{
    ABObj	obj = info->obj;
    ABObj	conn = NULL, cur_conn_src_mod = NULL;
    ABObj	cur_conn_target_mod = NULL;
    ABObj	src_mod = NULL, target_mod = NULL;
    int		iRet = 0;

    util_dprintf(3, "object updated: %s\n", obj_get_name(info->obj));

    if ((obj != NULL) && (AB_conn_dialog != (Widget) NULL))
    {
	/* Update the Source, Target, and Connections lists */

	abobj_list_obj_updated(src_list, info, src_list_test);
	abobj_list_obj_updated(target_list, info, target_list_test);
	populate_connection_list(connP_get_connection());

	/* A module is being hidden */
	if (obj_is_module(obj) && !obj_has_flag(obj, MappedFlag))
	{
	    src_mod = obj_get_module(connP_get_source());
	    if (src_mod == obj)
	    {
		conn_set_source(NULL);
		set_ctrls_for_src(FALSE);
	    }
	    target_mod = obj_get_module(connP_get_target());
	    if (target_mod == obj)
	    {
		conn_set_target(NULL);
		if (connP_get_action_type() == AB_FUNC_BUILTIN) 
		    set_ctrls_for_target(FALSE);
		else
		    set_ctrls_for_target(TRUE);
	    }

	    if (conn = connP_get_connection())
	    {
		cur_conn_src_mod = obj_get_module(obj_get_from(conn));
	    	cur_conn_target_mod = obj_get_module(obj_get_to(conn));
	    	if ((obj == cur_conn_src_mod) || 
		    (obj == cur_conn_target_mod))
		{
		    connP_set_connection(NULL);
	  	}
	    }
            if (connP_conn_is_possible())
		set_conn_controls(TRUE);
            else
		set_conn_controls(FALSE);
	}
    }

    return(iRet);
}


BOOL
connP_conn_is_possible(void)
{
    BOOL        ConnIsPossible = FALSE;
    ABObj	source = NULL,
		target = NULL;
 
    source = connP_get_source();
    target = connP_get_target();

    switch (connP_get_action_type())
    {
        case AB_FUNC_BUILTIN:
            if ( (source != NULL) && (target != NULL) )
	    {
		/* If the source object is a message
		 * but the message doesn't have an
		 * Action1, Action2, Action3, or a
		 * Cancel button, then a connection
		 * cannot be made on that message.
		 */
		if (obj_is_message(source))
		{
		   if ( obj_has_action1_button(source) ||
			obj_has_action2_button(source) ||
			obj_has_action3_button(source) ||
			obj_has_cancel_button(source)
		      ) 
		    {
			ConnIsPossible = TRUE; 
		    }
		}
		else
		{
                    ConnIsPossible = TRUE; 
		}
	    }
            break;

        case AB_FUNC_USER_DEF:
        case AB_FUNC_CODE_FRAG:
            if (source != NULL)
	    {
                if (obj_is_message(source))
                {
                   if ( obj_has_action1_button(source) ||
                        obj_has_action2_button(source) ||
                        obj_has_action3_button(source) ||
                        obj_has_cancel_button(source)
                      )
                    {
                        ConnIsPossible = TRUE;
                    }  
		}
		else
		{
                    ConnIsPossible = TRUE;
		}
	    }
            break;

        case AB_FUNC_ON_ITEM_HELP:
        case AB_FUNC_HELP_VOLUME:
	    if ((source != NULL) && obj_is_menu_item(source))
	    {
		ConnIsPossible = TRUE;
	    }
        default:
            break;
    }
 
    return (ConnIsPossible);
}

static void
set_conn_controls(
    BOOL	state
)
{
    XtSetSensitive(connect_button, state);
}

/*
** validate a builtin connection's AB_ARG_STRING
**
** called from connP_make_connection()
*/
static BOOL
verify_builtin_arg_string(
    AB_BUILTIN_ACTION c_act,
    ABObj             c_target,
    Widget            field
)
{
    BOOL rval = False;
    
    if (!c_act || !c_target || !field ||
	(connP_get_action_type() != AB_FUNC_BUILTIN) ||
	(connP_action_needs_arg(c_act) != AB_ARG_STRING))
    {
	return False;
    }
    
    switch (c_act)
    {
    case AB_STDACT_DISABLE:
    case AB_STDACT_ENABLE:
    case AB_STDACT_HIDE:
	rval = True;
	break;
	
    case AB_STDACT_SET_LABEL:
	/*
	** cmvc 7896: set-label conn doesn't work on graphic
	*/
	switch (obj_get_label_type(c_target))
	{
	case AB_LABEL_GLYPH:
	    /* validate graphic filename */
	    if (prop_graphic_filename_ok(field, False))
		rval = True;
	    break;

	case AB_LABEL_ARROW_DOWN:	/* are these really valid? */
	case AB_LABEL_ARROW_LEFT:
	case AB_LABEL_ARROW_RIGHT:
	case AB_LABEL_ARROW_UP:
	case AB_LABEL_DRAWN:
	case AB_LABEL_SEPARATOR:
	    rval = True;
	    break;

	case AB_LABEL_STRING:
	    rval = True;
	    break;

	case AB_LABEL_UNDEF:
	case AB_LABEL_TYPE_NUM_VALUES:
	default:
	    break;
	}
	break;
	
    case AB_STDACT_SET_TEXT:
    case AB_STDACT_SET_VALUE:
    case AB_STDACT_SHOW:
	rval = True;
	break;
	
    case AB_STDACT_UNDEF:
    case AB_BUILTIN_ACTION_NUM_VALUES:
    default:
	rval = False;
	break;
    }
    
    return rval;
}

/*** DTB_USER_CODE_END
 ***
 *** End of user code section
 ***
 **************************************************************************/



void 
conn_cancelCB(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/
    DtbConnConnDialogInfo dtbSource = (DtbConnConnDialogInfo)clientData;
    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/

    /* If secondary Execute code dialog is open, close it also
     * to ensure correct window state tracking
     */
    if (exec_code_dialog && ab_window_is_open(exec_code_dialog))
	ui_win_show(exec_code_dialog, False, XtGrabNone);

    ui_win_show(AB_conn_dialog, False, XtGrabNone);

    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_make_connection(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/

    char	*str_value = (char *)NULL;
    ABObj	ab_action  = (ABObj)NULL;
    ABObj	c_source;
    ABObj	c_target;
    AB_WHEN     c_when;
    BOOL	is_cross_module = (BOOL)FALSE;
    STRING	vol_value = NULL,
		loc_value = NULL;
    BOOL        valid     = False;

    if ((c_source = connP_get_source()) == NULL ||
        connP_get_source_type() != obj_get_type(c_source))
        return;

    c_when = (AB_WHEN)get_cur_when();

    switch (connP_get_action_type())
    {
      case AB_FUNC_BUILTIN:
	if ((c_target = connP_get_target()) != NULL &&
	    connP_get_target_type() == obj_get_type(c_target))
	{
	    AB_BUILTIN_ACTION   c_act = (AB_BUILTIN_ACTION)get_cur_act();

	    ab_action = obj_create(AB_TYPE_ACTION, NULL);

	    switch (connP_action_needs_arg(c_act))
	    {
	      case AB_ARG_UNDEF:
		break;

	      case AB_ARG_STRING:
		if (!verify_builtin_arg_string(c_act, c_target, arg_field))
		    return;
		  
		XtVaGetValues(arg_field, XmNvalue, &str_value, NULL);
		if (str_value != (char *)NULL)
		    connP_set_conn_arg(ab_action, AB_ARG_STRING, str_value);
		break;

	      case AB_ARG_INT:
		if (!prop_number_ok(arg_field, "Argument Field", 
			obj_get_min_value(c_target), 
			obj_get_max_value(c_target)))
		{
		    return;	
		}
		XtVaGetValues(arg_field, XmNvalue, &str_value, NULL);
		if (str_value != (char *)NULL)
		    connP_set_conn_arg(ab_action, AB_ARG_INT, str_value);
		break;

	      default:
		break;
	    }
	    connP_make_builtin_conn(ab_action, c_source, c_target, c_when,
					c_act);

	    /* Set SaveNeeded flag */ 
	    if (obj_get_module(c_source) == obj_get_module(c_target))
	    {
		abobj_set_save_needed(obj_get_module(c_source), TRUE);
	    }
	    else
	    {
		abobj_set_save_needed(obj_get_project(c_source), TRUE);
		is_cross_module = TRUE;
	    }
	}
	break;

      case AB_FUNC_USER_DEF:
	/*
	 * Populate function name
	 */
	XtVaGetValues(arg_field, XmNvalue, &str_value, NULL);
	if (!util_strempty(str_value))
	{
	    ab_action = obj_create(AB_TYPE_ACTION, NULL);
	    connP_make_user_def_conn(ab_action, c_source, c_when, str_value);

	    /* Set SaveNeeded flag */ 
	    abobj_set_save_needed(obj_is_project(c_source)? c_source :
		obj_get_module(c_source), TRUE);
	}
	else
	{
	    dtb_conn_no_func_msg_initialize(&dtb_conn_no_func_msg);
	    (void)dtb_show_modal_message(dtb_get_toplevel_widget(),
			&dtb_conn_no_func_msg, NULL, NULL, NULL);
 	}
	break;

      case AB_FUNC_CODE_FRAG:
	/*
	 * Populate code fragment
	 */
	str_value = CodeFragBuf;
	if (!util_strempty(str_value))
	{
	    ab_action = obj_create(AB_TYPE_ACTION, NULL);
	    connP_make_code_frag_conn(ab_action, c_source, c_when, str_value);

	    /* Set SaveNeeded flag */ 
	    abobj_set_save_needed(obj_is_project(c_source)? c_source :
		obj_get_module(c_source), TRUE);
	}
	break;

      case AB_FUNC_ON_ITEM_HELP:
	ab_action = obj_create(AB_TYPE_ACTION, NULL);
	connP_make_on_item_help_conn(ab_action, c_source, c_when);

        /* Set SaveNeeded flag */
        abobj_set_save_needed(obj_get_module(c_source), TRUE);
	break;

      case AB_FUNC_HELP_VOLUME:
	XtVaGetValues(volume_field, XmNvalue, &vol_value, NULL);
	XtVaGetValues(location_field, XmNvalue, &loc_value, NULL);
	ab_action = obj_create(AB_TYPE_ACTION, NULL);
	connP_make_help_vol_conn(ab_action, c_source, 
				c_when, vol_value, loc_value);

        /* Set SaveNeeded flag */
        abobj_set_save_needed(obj_get_module(c_source), TRUE);
	break;
    }

    if (ab_action != (ABObj)NULL)
    {
	if (is_cross_module)
	{
	    obj_add_action(obj_get_project(c_source), ab_action);
	}
	else
	{
	    obj_add_action(obj_is_project(c_source)? c_source : 
		obj_get_module(c_source), ab_action);
	}
	connP_set_connection(ab_action);
	/* 
	 * cmvc 4359 - make View: be Source Object, if it is not already or
	 * if the View: is not the Source: connection being made.
	 */
	if (!((ConnP_view_filter == -1) ||
	      (ConnP_view_filter == connP_get_obj_type_index(connP_get_source_type(), connP_get_source_subtype())))
	   )
	{  
	    ConnP_view_filter = -1;
	    XtVaSetValues(view_menu,
		XmNmenuHistory, ConnP_view_source_obj,
		NULL);
	}
	populate_connection_list(connP_get_connection());
    }

    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/
    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_change_connection(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/

    ABObj		ab_action;
    AB_WHEN		c_when;
    AB_BUILTIN_ACTION	c_act;
    ABObj		c_source;
    ABObj		c_target;
    BOOL		is_changed;
    AB_FUNC_TYPE	cur_func_type;
    char		*str_value = (char *)NULL;
    STRING		loc_value = (STRING) NULL,
    			vol_value = (STRING) NULL;
    ISTRING		istr_value = (ISTRING)NULL,
    			istr_loc_value = (ISTRING)NULL,
    			istr_vol_value = (ISTRING)NULL;

    if ((ab_action = get_cur_connection()) == NULL)
	return;
    if ((c_source = connP_get_source()) == NULL)
	return;
    if (connP_get_source_type() != obj_get_type(c_source))
	return;
    
    c_when = (AB_WHEN)get_cur_when();

    /*
     * Match contents of selected action with
     * current selections on the connections manager.
     */
 
    is_changed = FALSE;
    cur_func_type = connP_get_action_type();
    switch (cur_func_type)
    {
      /**************************************************
       * Switching the action (function) type to	*
       * Predefined Action.				*
       **************************************************/
      case AB_FUNC_BUILTIN:
	c_act = get_cur_act();
	if ((c_target = connP_get_target()) == NULL ||
	    connP_get_target_type() != obj_get_type(c_target))
	    return;

	switch (ab_action->info.action.func_type)
	{
	  /* Switching func type from predefined action
	   * to predefined action.
	   */
	  case AB_FUNC_BUILTIN:
	   if (connP_action_needs_arg(c_act) == AB_ARG_INT)
	   {
              if (!prop_number_ok(arg_field, "Argument Field",
                        obj_get_min_value(c_target),
                        obj_get_max_value(c_target)))
	      {
		return;
	      }
	    }
	    str_value = XmTextFieldGetString(arg_field);
	    is_changed = connP_change_in_builtin(ab_action,
			    c_source, c_target, c_when,
			    get_cur_act(), str_value);
	    if (!util_strempty(str_value))
		XtFree(str_value);
	    break;

	  /* Switching func type from call-function to 
	   * predefined action.
	   */
	  case AB_FUNC_USER_DEF:
	    is_changed = TRUE;
	    if (ab_action->info.action.func_value.func_name != (ISTRING)NULL)
		istr_destroy(ab_action->info.action.func_value.func_name);
	    connP_make_builtin_conn(ab_action, c_source, c_target, 
			c_when, c_act);
	    break;

	  /* Switching func type from execute-code to 
	   * predefined action.
	   */
	  case AB_FUNC_CODE_FRAG:
	    is_changed = TRUE;
	    XmTextFieldSetString(arg_field, "");
	    XmTextSetString(exec_code_textpane, "");
	    if (ab_action->info.action.func_value.code_frag != (ISTRING)NULL)
		istr_destroy(ab_action->info.action.func_value.code_frag);
	    connP_make_builtin_conn(ab_action, c_source, c_target, 
			c_when, c_act);
	    break;
	
	  /* Switching func type from activate-on-item-help to 
	   * predefined action.
	   */
	  case AB_FUNC_ON_ITEM_HELP:
	    is_changed = TRUE;
            connP_make_builtin_conn(ab_action, c_source, c_target,
			c_when, c_act);
            break;

	  /* Switching func type from access-help-volume to 
	   * predefined action.
	   */
          case AB_FUNC_HELP_VOLUME:
            is_changed = TRUE;
            if (ab_action->info.action.location != (ISTRING)NULL)
		istr_destroy(ab_action->info.action.location);
            if (ab_action->info.action.volume_id != (ISTRING)NULL)
		istr_destroy(ab_action->info.action.volume_id);
            connP_make_builtin_conn(ab_action, c_source, c_target, 
			c_when, c_act);   
	    XmTextFieldSetString(location_field, "");
	    XmTextFieldSetString(volume_field, "");
            break;
	}
	if (is_changed == TRUE)
	{
	    if (obj_get_module(c_source) == obj_get_module(c_target))
	    {
                abobj_set_save_needed(obj_is_project(c_source)? 
			c_source : obj_get_module(c_source), TRUE);
	    }
	    else        /* This is a cross-module connection */
	    {
            	abobj_set_save_needed(obj_is_project(c_source)? 
			c_source : obj_get_module(c_source), TRUE);
	    }
	}
	break;

      /************************************************** 
       * Switching the action (function) type to        *
       * Call-Function .                             	*     
       **************************************************/
      case AB_FUNC_USER_DEF:
	str_value = XmTextFieldGetString(arg_field);
	if (str_value == (char *)NULL)
	    return;

	switch (ab_action->info.action.func_type)
	{
	  /* Switching func type from call-function to
	   * call-function.
	   */
	  case AB_FUNC_USER_DEF:
	    istr_value = istr_create(str_value);
	    if (ab_action->info.action.func_value.func_name != istr_value)
	    {
		is_changed = TRUE;
		istr_destroy(ab_action->info.action.func_value.func_name);
	    }
	    if (c_when != obj_get_when(ab_action))
		is_changed = TRUE;

	    if (is_changed)
	    {
		connP_make_user_def_conn(ab_action, c_source, c_when, str_value);
            	abobj_set_save_needed(obj_is_project(c_source)? 
			c_source : obj_get_module(c_source), TRUE);
	    }
	    break;

	  /* Switching func type from Predefined-action to
	   * Call-Function.
	   */
	  case AB_FUNC_BUILTIN:
	    connP_builtin_remove_arg(ab_action);
	    is_changed = TRUE;
	    connP_make_user_def_conn(ab_action, c_source, c_when, str_value);
            abobj_set_save_needed(obj_is_project(c_source)? c_source :
                obj_get_module(c_source), TRUE);
	    break;

	  /* Switching func type from Execute-code to
	   * Call-Function.
	   */
	  case AB_FUNC_CODE_FRAG:
	    is_changed = TRUE;
	    XmTextFieldSetString(arg_field, "");
	    XmTextSetString(exec_code_textpane, "");
	    if (ab_action->info.action.func_value.code_frag != (ISTRING)NULL)
		istr_destroy(ab_action->info.action.func_value.code_frag);
	    connP_make_user_def_conn(ab_action, c_source, c_when, str_value);
            abobj_set_save_needed(obj_is_project(c_source)? c_source :
                obj_get_module(c_source), TRUE);
	    break;

          /* Switching func type from activate-on-item-help to
           * call-function.
           */
          case AB_FUNC_ON_ITEM_HELP:
            is_changed = TRUE;
            connP_make_user_def_conn(ab_action, c_source, c_when, str_value);
	    abobj_set_save_needed(obj_is_project(c_source)? 
		c_source : obj_get_module(c_source), TRUE);
            break;

	  /* Switching func type from access-help-volume to
           * call-function.
           */
          case AB_FUNC_HELP_VOLUME:
            is_changed = TRUE;
	    if (ab_action->info.action.location != (ISTRING) NULL)
		istr_destroy(ab_action->info.action.location);
	    if (ab_action->info.action.volume_id != (ISTRING) NULL)
		istr_destroy(ab_action->info.action.volume_id);
            connP_make_user_def_conn(ab_action, c_source, c_when, str_value);        
            abobj_set_save_needed(obj_is_project(c_source)? 
                c_source : obj_get_module(c_source), TRUE);
	    XmTextFieldSetString(location_field, "");
	    XmTextFieldSetString(volume_field, "");
            break;
	}

	XtFree(str_value);
	break;

      /**************************************************  
       * Switching the action (function) type to        * 
       * Execute-Code.                                  *
       **************************************************/ 
      case AB_FUNC_CODE_FRAG:
	str_value = CodeFragBuf;
	if (str_value == (STRING) NULL)
	    return;

	switch (ab_action->info.action.func_type)
	{
          /* Switching func type from Predefined Action to
           * Execute Code.
           */
	  case AB_FUNC_BUILTIN:
	    connP_builtin_remove_arg(ab_action);
	    is_changed = TRUE;
	    connP_make_code_frag_conn(ab_action, c_source, c_when, str_value);
	    abobj_set_save_needed(obj_is_project(c_source)? c_source :
		    obj_get_module(c_source), TRUE);
	    break;

          /* Switching func type from Call-Function to
           * Execute Code.
           */
	  case AB_FUNC_USER_DEF:
	    if (ab_action->info.action.func_value.func_name != (ISTRING)NULL)
		istr_destroy(ab_action->info.action.func_value.func_name);
	    is_changed = TRUE;
	    connP_make_code_frag_conn(ab_action, c_source, c_when, str_value);
	    abobj_set_save_needed(obj_is_project(c_source)? c_source :
		    obj_get_module(c_source), TRUE);
	    break;

          /* Switching func type from Execute Code to
           * Execute Code.
           */
	  case AB_FUNC_CODE_FRAG:
	    istr_value = istr_create(str_value);
	    if (ab_action->info.action.func_value.code_frag != istr_value)
	    {
		is_changed = TRUE;
		istr_destroy(ab_action->info.action.func_value.code_frag);
	    }
	    if (c_when != obj_get_when(ab_action))
		is_changed = TRUE;

	    if (is_changed)
	    {
		connP_make_code_frag_conn(ab_action, c_source, c_when, str_value);
            	abobj_set_save_needed(obj_is_project(c_source)? 
			c_source : obj_get_module(c_source), TRUE);
  	    }
	    break;

          /* Switching func type from activate-on-item-help to
           * Execute Code.
           */
          case AB_FUNC_ON_ITEM_HELP:
            is_changed = TRUE;
            connP_make_code_frag_conn(ab_action, c_source, c_when, str_value);
            abobj_set_save_needed(obj_is_project(c_source)? 
			c_source : obj_get_module(c_source), TRUE);
            break;
 
          /* Switching func type from access-help-volume to
           * Execute Code.
           */
          case AB_FUNC_HELP_VOLUME:
            is_changed = TRUE;
            if (ab_action->info.action.location != (ISTRING)NULL)
                istr_destroy(ab_action->info.action.location);
            if (ab_action->info.action.volume_id != (ISTRING)NULL)
		istr_destroy(ab_action->info.action.volume_id);
            connP_make_code_frag_conn(ab_action, c_source, c_when, str_value);
            abobj_set_save_needed(obj_is_project(c_source)? 
			c_source : obj_get_module(c_source), TRUE);
	    XmTextFieldSetString(location_field, "");
	    XmTextFieldSetString(volume_field, "");
            break;
	}

	XtFree(str_value);
	break;

      /**************************************************  
       * Switching the action (function) type to        *  
       * 'Activate On-Item Help'.                       * 
       **************************************************/  
      case AB_FUNC_ON_ITEM_HELP:
        switch (ab_action->info.action.func_type)
        {
          /* Switching func type from activate-on-item-help
           * to activate-on-item-help.
           */
          case AB_FUNC_ON_ITEM_HELP:
	    if (c_when != obj_get_when(ab_action))
	    {
		is_changed = TRUE;
		connP_make_on_item_help_conn(ab_action, c_source, c_when);
		abobj_set_save_needed(obj_is_project(c_source)? 
		    c_source : obj_get_module(c_source), TRUE);
	    }
            break;

	  /* Switching func type from call-function to
	   * activate-on-item-help.
	   */
          case AB_FUNC_USER_DEF:
            is_changed = TRUE;
	    if (ab_action->info.action.func_value.func_name != (ISTRING) NULL)
		istr_destroy(ab_action->info.action.func_value.func_name);
	    connP_make_on_item_help_conn(ab_action, c_source, c_when);
	    abobj_set_save_needed(obj_is_project(c_source)? c_source :
                        obj_get_module(c_source), TRUE);
	    XmTextFieldSetString(arg_field, "");
            break;
             
	  /* Switching func type from predefined-action to
	   * activate-on-item-help.
	   */
          case AB_FUNC_BUILTIN:
            is_changed = TRUE;
            connP_builtin_remove_arg(ab_action);
            connP_make_on_item_help_conn(ab_action, c_source, c_when);
            abobj_set_save_needed(obj_is_project(c_source)? 
		c_source : obj_get_module(c_source), TRUE);
	    XmTextFieldSetString(arg_field, "");
            break;
 
	  /* Switching func type from execute-code to
	   * activate-on-item-help.
	   */
          case AB_FUNC_CODE_FRAG:
            is_changed = TRUE;
            if (ab_action->info.action.func_value.code_frag != (ISTRING)NULL)
		istr_destroy(ab_action->info.action.func_value.code_frag);
	    connP_make_on_item_help_conn(ab_action, c_source, c_when);
            abobj_set_save_needed(obj_is_project(c_source)? 
		c_source : obj_get_module(c_source), TRUE);
	    XmTextFieldSetString(arg_field, "");
	    XmTextSetString(exec_code_textpane, "");
            break;

          /* Switching func type from access-help-volume to
           * activate-on-item-help.
           */
          case AB_FUNC_HELP_VOLUME:
            is_changed = TRUE;
            if (ab_action->info.action.location != (ISTRING) NULL)
		istr_destroy(ab_action->info.action.location);
            if (ab_action->info.action.volume_id != (ISTRING) NULL)
		istr_destroy(ab_action->info.action.volume_id);
	    connP_make_on_item_help_conn(ab_action, c_source, c_when);
            abobj_set_save_needed(obj_is_project(c_source)?
		c_source : obj_get_module(c_source), TRUE);
	    XmTextFieldSetString(location_field, "");
	    XmTextFieldSetString(volume_field, "");
            break;
        }
        break;

      /**************************************************
       * Switching the action (function) type to        *
       * 'Access Help Volume'.                          *
       **************************************************/
      case AB_FUNC_HELP_VOLUME:
        loc_value = XmTextFieldGetString(location_field);
        vol_value = XmTextFieldGetString(volume_field);
        if (loc_value == (STRING)NULL || (vol_value == (STRING)NULL))
            return;

        switch (ab_action->info.action.func_type)
        {
          /* Switching func type from call-function to
           * access-help-volume.
           */
          case AB_FUNC_USER_DEF:
            is_changed = TRUE;
            if (ab_action->info.action.func_value.func_name != (ISTRING) NULL)
		istr_destroy(ab_action->info.action.func_value.func_name);
            connP_make_help_vol_conn(ab_action, c_source, c_when,
				vol_value, loc_value);
            abobj_set_save_needed(obj_is_project(c_source)?
		c_source : obj_get_module(c_source), TRUE);
	    XmTextFieldSetString(arg_field, "");
            break;

          /* Switching func type from predefined-action to
           * access-help-volume.
           */
          case AB_FUNC_BUILTIN:
            is_changed = TRUE;
            connP_builtin_remove_arg(ab_action);
            connP_make_help_vol_conn(ab_action, c_source, c_when,
                		vol_value, loc_value);
            abobj_set_save_needed(obj_is_project(c_source)?
                c_source : obj_get_module(c_source), TRUE);
	    XmTextFieldSetString(arg_field, "");
            break;

          /* Switching func type from execute-code to
           * access-help-volume.
           */
          case AB_FUNC_CODE_FRAG:
            is_changed = TRUE;
            if (ab_action->info.action.func_value.code_frag != (ISTRING)NULL)
		istr_destroy(ab_action->info.action.func_value.code_frag);
            connP_make_help_vol_conn(ab_action, c_source, c_when,
                		vol_value, loc_value);
            abobj_set_save_needed(obj_is_project(c_source)?
                c_source : obj_get_module(c_source), TRUE);
	    XmTextFieldSetString(arg_field, "");
	    XmTextSetString(exec_code_textpane, "");
            break;
               
          /* Switching func type from access-help-volume to
           * access-help-volume.
           */
          case AB_FUNC_HELP_VOLUME:
            istr_loc_value = istr_create(loc_value);
            istr_vol_value = istr_create(vol_value);
            if (ab_action->info.action.location != istr_loc_value)
            {
                is_changed = TRUE;
		istr_destroy(ab_action->info.action.location);
            }
            if (ab_action->info.action.volume_id != istr_vol_value)
            { 
                is_changed = TRUE;
                istr_destroy(ab_action->info.action.volume_id);
            }   
	    if (c_when != obj_get_when(ab_action))
	    	is_changed = TRUE;

	    if (is_changed)
	    {
                connP_make_help_vol_conn(ab_action, c_source, c_when,
                		vol_value, loc_value);
		abobj_set_save_needed(obj_is_project(c_source)? 
                    c_source : obj_get_module(c_source), TRUE);
	    }
            break;
	}
	XtFree(loc_value);
	XtFree(vol_value);
	break;
    }
    if (is_changed == TRUE)
    {
	connP_set_connection(ab_action);
	populate_connection_list(connP_get_connection());
    }

    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/
    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_delete_connection(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/

    ABObj		ab_action;
    ABObj		source, target;

    if ((ab_action = get_cur_connection()) == NULL)
	return;

    source = ab_action->info.action.from;
    target = ab_action->info.action.to;

    /* Set the SaveNeededFlag on the module, if it is an
     * intra-module connection.  Otherwise set it on the 
     * project, since it is a cross-module connection which 
     * is stored in the .bip file. 
     */  
    if ( obj_get_module(source) == obj_get_module(target) ) 
    {
        abobj_set_save_needed(obj_is_project(source)? source :
                obj_get_module(source), TRUE);
    }
    else        /* This is a cross-module connection */
    {
        abobj_set_save_needed(obj_is_project(source)? source : 
                obj_get_module(source), TRUE); 
    }

    obj_destroy(ab_action);
    connP_set_connection(NULL);
    populate_connection_list(connP_get_connection());

    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/
    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_register_connect_button(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    DtbConnConnDialogInfo	dtbSource = (DtbConnConnDialogInfo)callData;
    
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/

    /* Make Connect button initially inactive */
    XtSetSensitive(dtbSource->connect_button, FALSE);
    connect_button = dtbSource->connect_button;

    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/
    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_register_change_button(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    DtbConnConnDialogInfo	dtbSource = (DtbConnConnDialogInfo)callData;
    
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/
    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/

    /* Make Change button initially inactive */
    XtSetSensitive(dtbSource->change_button, FALSE);
    change_button = dtbSource->change_button;

    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_register_cancel_button(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    DtbConnConnDialogInfo	dtbSource = (DtbConnConnDialogInfo)callData;
    
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/
    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/

    cancel_button = dtbSource->cancel_button;

    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_register_delete_button(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    DtbConnConnDialogInfo	dtbSource = (DtbConnConnDialogInfo)callData;
    
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/

    /* Make Delete button initially inactive */
    XtSetSensitive(dtbSource->delete_button, FALSE);
    delete_button = dtbSource->delete_button;

    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/
    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_register_source_choices(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    DtbConnConnDialogInfo	dtbSource = (DtbConnConnDialogInfo)callData;
    
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/

    /*
     * jit - Workaround for dtcodegen bug:
     *          does not set XmNsubMenuId if Option Menu has 0 items
     */
    XtVaSetValues(widget, XmNsubMenuId, dtbSource->source_choices_menu, NULL);

    src_menu = dtbSource->source_choices;
    populate_src_menu(dtbSource->source_choices_menu, NULL, NULL);

    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/
    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_register_target_choices(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    DtbConnConnDialogInfo	dtbSource = (DtbConnConnDialogInfo)callData;
    
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/

    /*
     * jit - Workaround for dtcodegen bug:
     *          does not set XmNsubMenuId if Option Menu has 0 items
     */
    XtVaSetValues(widget, XmNsubMenuId, dtbSource->target_choices_menu, NULL);

    target_menu = dtbSource->target_choices;
    populate_target_menu(dtbSource->target_choices_menu, NULL, NULL);

    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/
    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_register_when_choices(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    DtbConnConnDialogInfo	dtbSource = (DtbConnConnDialogInfo)callData;
    
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/

    /*
     * jit - Workaround for dtcodegen bug:
     *          does not set XmNsubMenuId if Option Menu has 0 items
     */
    XtVaSetValues(widget, XmNsubMenuId, dtbSource->when_choices_menu, NULL);

    when_menu = dtbSource->when_choices;
    populate_when_menu(dtbSource->when_choices_menu, NULL, NULL);
    XtAddCallback(XtParent(dtbSource->when_choices_menu),
                XmNpopupCallback, connP_update_when_menu,
                (XtPointer) NULL);

    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/
    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_register_predef_act_choices(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    DtbConnConnDialogInfo	dtbSource = (DtbConnConnDialogInfo)callData;
    
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/

    /*
     * jit - Workaround for dtcodegen bug:
     *          does not set XmNsubMenuId if Option Menu has 0 items
     */
    XtVaSetValues(widget, XmNsubMenuId, dtbSource->predef_act_choices_menu, NULL)
;

    action_menu = dtbSource->predef_act_choices;
    populate_action_menu(dtbSource->predef_act_choices_menu, NULL, NULL);
    XtAddCallback(XtParent(dtbSource->predef_act_choices_menu),
                XmNpopupCallback, connP_update_action_menu,
                (XtPointer) NULL);

    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/
    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_register_view_choices(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    DtbConnConnDialogInfo	dtbSource = (DtbConnConnDialogInfo)callData;
    
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/

    /*
     * jit - Workaround for dtcodegen bug:
     *          does not set XmNsubMenuId if Option Menu has 0 items
     */
    XtVaSetValues(widget, XmNsubMenuId, dtbSource->view_choices_menu, NULL);

    view_menu = dtbSource->view_choices;
    populate_view_menu(dtbSource->view_choices_menu, NULL, NULL);

    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/
    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_register_source_list(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    DtbConnConnDialogInfo	dtbSource = (DtbConnConnDialogInfo)callData;
    
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/

    src_list = dtbSource->source_list;
    XtAddCallback(dtbSource->source_list, XmNbrowseSelectionCallback,
                  update_cur_src, NULL);

    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/
    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_register_target_list(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    DtbConnConnDialogInfo	dtbSource = (DtbConnConnDialogInfo)callData;
    
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/

    target_list = dtbSource->target_list;
    XtAddCallback(dtbSource->target_list, XmNbrowseSelectionCallback,
                  update_cur_target, NULL);

    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/
    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_register_conn_list(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    DtbConnConnDialogInfo	dtbSource = (DtbConnConnDialogInfo)callData;
    
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/

    connection_list = dtbSource->conn_list;
    XtAddCallback(dtbSource->conn_list, XmNbrowseSelectionCallback,
                  select_connection, NULL);

    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/
    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_register_arg_field(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    DtbConnConnDialogInfo	dtbSource = (DtbConnConnDialogInfo)callData;
    
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/

    arg_rowcol = dtbSource->arg_field_rowcolumn;
    arg_label = dtbSource->arg_field_label;
    arg_field = dtbSource->arg_field;

    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/
    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_register_action_Predefined_item(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    DtbConnConnDialogInfo	dtbSource = (DtbConnConnDialogInfo)callData;
    
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/

    std_action_item = dtbSource->action_type_choices_items.Predefined_item;

    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/
    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_register_action_Call_Function_item(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    DtbConnConnDialogInfo	dtbSource = (DtbConnConnDialogInfo)callData;
    
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/

    call_function_item =
        dtbSource->action_type_choices_items.Call_Function_item;

    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/
    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_register_action_Execute_Code_item(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    DtbConnConnDialogInfo	dtbSource = (DtbConnConnDialogInfo)callData;
    
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/

    execute_code_item =
        dtbSource->action_type_choices_items.Execute_Code_item;

    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/
    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_show_execute_code(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/

    DtbConnExecCodeDialogInfo   dtbSource = &dtb_conn_exec_code_dialog;

    if (!(dtbSource->initialized))
    {
        dtb_conn_exec_code_dialog_initialize(dtbSource, dtb_palette_ab_palette_main.ab_palette_main);
	init_exec_code_dialog(dtbSource);
    }

    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/

    set_execute_code_action_type();
    ab_show_window(exec_code_dialog);

    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_register_action_on_item_help_item(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    DtbConnConnDialogInfo	dtbSource = (DtbConnConnDialogInfo)callData;
    
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/
    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/

    on_item_help_item = widget;

    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_register_action_help_vol_item(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    DtbConnConnDialogInfo	dtbSource = (DtbConnConnDialogInfo)callData;
    
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/
    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/
    
    help_volume_item = widget;

    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_register_loc_textf(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    DtbConnConnDialogInfo	dtbSource = (DtbConnConnDialogInfo)callData;
    
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/
    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/

    location_rowcol = dtbSource->loc_textf_rowcolumn;
    location_field = dtbSource->loc_textf;

    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_register_vol_textf(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    DtbConnConnDialogInfo	dtbSource = (DtbConnConnDialogInfo)callData;
    
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/
    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/

    volume_rowcol = dtbSource->vol_textf_rowcolumn;
    volume_field = dtbSource->vol_textf;

    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_register_action_type_opmenu(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    DtbConnConnDialogInfo	dtbSource = (DtbConnConnDialogInfo)callData;
    
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/
    
    XmString	xmstr = NULL;
    STRING	label = NULL;

    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/

    action_type_opmenu = widget;
    
    XtVaGetValues(std_action_item, XmNlabelString, &xmstr, NULL);
    action_type_labels[ACTION_TYPE_PREDEFINED] = objxm_xmstr_to_str(xmstr);
    xmstr = NULL;
    
    XtVaGetValues(call_function_item, XmNlabelString, &xmstr, NULL);
    action_type_labels[ACTION_TYPE_CALLFUNC] = objxm_xmstr_to_str(xmstr);
    xmstr = NULL;
    
    XtVaGetValues(execute_code_item, XmNlabelString, &xmstr, NULL);
    action_type_labels[ACTION_TYPE_EXECUTE_CODE] = objxm_xmstr_to_str(xmstr);
    xmstr = NULL;

    XtVaGetValues(on_item_help_item, XmNlabelString, &xmstr, NULL);
    action_type_labels[ACTION_TYPE_ON_ITEM_HELP] = objxm_xmstr_to_str(xmstr);
    xmstr = NULL;

    XtVaGetValues(help_volume_item, XmNlabelString, &xmstr, NULL);
    action_type_labels[ACTION_TYPE_HELP_VOLUME] = objxm_xmstr_to_str(xmstr);
    xmstr = NULL;

    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_enable_std_actions(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/
    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/

    set_standard_action_type();

    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_enable_call_function(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/
    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/

    set_call_function_action_type();

    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_enable_on_item_help(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/
    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/

    set_on_item_help_action_type();
    if (connP_conn_is_possible())
        set_conn_controls(TRUE);
    else
        set_conn_controls(FALSE);

    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_enable_access_help_vol(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/
    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/

    set_access_help_vol_action_type();
    if (connP_conn_is_possible())
        set_conn_controls(TRUE);
    else
        set_conn_controls(FALSE);

    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_exec_code_okCB(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/

    STRING	code_frag = NULL;
    STRING      first_line = NULL;
    char        *newline = NULL;
    DtbConnExecCodeDialogInfo	dtbSource =
			(DtbConnExecCodeDialogInfo) clientData;

    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/

    code_frag = XmTextGetString(exec_code_textpane);
    if (!util_strempty(code_frag))
    {
	if (CodeFragBuf)
	    util_free(CodeFragBuf);
	CodeFragBuf = strdup(code_frag);

	newline = strchr(code_frag, '\n');
	if (newline)
	{
            *newline = '\0';
	}
	first_line = (STRING)util_malloc(strlen(code_frag) + 4);
	if (first_line)
	{
	    strcpy(first_line, code_frag);
	    strcat(first_line, "...");
	    XmTextFieldSetString(arg_field, first_line);
	    util_free(first_line);
	}
    }
    else
    {
	if (CodeFragBuf)
	    util_free(CodeFragBuf);
	if (code_frag)
	    CodeFragBuf = strdup(code_frag);
	else
	    CodeFragBuf = NULL;
	XmTextFieldSetString(arg_field, "");
    }

    XtFree(code_frag);
    ui_win_show(exec_code_dialog, False, XtGrabNone);
            
    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_exec_code_applyCB(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/

    STRING	code_frag = NULL;
    STRING	first_line = NULL;
    char        *newline = NULL;

    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/

    code_frag = XmTextGetString(exec_code_textpane);
    if (!util_strempty(code_frag))
    {
        if (CodeFragBuf)
            util_free(CodeFragBuf);
        CodeFragBuf = strdup(code_frag);

    	newline = strchr(code_frag, '\n'); 
	if (newline)
	{
            *newline = '\0';
	}
	first_line = (STRING)util_malloc(strlen(code_frag) + 4);
	if (first_line)
	{
	    strcpy(first_line, code_frag);
	    strcat(first_line, "...");
	    XmTextFieldSetString(arg_field, first_line);
	    util_free(first_line);
	}
    }  
    else
    {
        if (CodeFragBuf)
            util_free(CodeFragBuf);
        if (code_frag)
            CodeFragBuf = strdup(code_frag);
        else 
            CodeFragBuf = NULL; 
	XmTextFieldSetString(arg_field, "");
    }

    XtFree(code_frag);

    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
exec_code_cancelCB(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/
    DtbConnExecCodeDialogInfo   dtbSource = (DtbConnExecCodeDialogInfo)clientData;
    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/
    ui_win_show(exec_code_dialog, False, XtGrabNone);
    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}


void 
connP_clear_exec_dlg(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/
    /*** DTB_USER_CODE_END   ^^^ Add C variables and code above ^^^ ***/
    
    /*** DTB_USER_CODE_START vvv Add C code below vvv ***/

    XmTextSetString(exec_code_textpane, "");

    /*** DTB_USER_CODE_END   ^^^ Add C code above ^^^ ***/
}



/**************************************************************************
 *** DTB_USER_CODE_START
 ***
 *** All automatically-generated data and functions have been defined.
 ***
 *** Add new functions here, or at the top of the file.
 ***/

/*
** This function checks to see if a show-help connection can be allowed
** between any source/target object pair.  The rule it implements is that
** the source object must be a push or drawn button that is a child of the
** target dialog;
*/
BOOL
allow_show_help_connection(
        ABObj src_obj,
        ABObj target_obj
)
{
    AB_OBJECT_TYPE      src_type;
    AB_OBJECT_TYPE      target_type;
    int                 src_subtype;

    if( (src_obj == (ABObj)NULL) || (target_obj == (ABObj)NULL)) return(FALSE);

    src_type    = obj_get_type(src_obj);
    target_type = obj_get_type(target_obj);
    src_subtype = obj_get_subtype(src_obj);

    if( (target_type == AB_TYPE_DIALOG) &&
        (src_type == AB_TYPE_BUTTON)  &&
        ((src_subtype == AB_BUT_PUSH) || (src_subtype == AB_BUT_DRAWN) ) &&
        (obj_get_parent_of_type(src_obj,AB_TYPE_DIALOG) == target_obj) ) {
            return(TRUE);
    }
    else return(FALSE);
}

static void 
hide_execute_code_win(void)
{
    DtbConnExecCodeDialogInfo   instance = &dtb_conn_exec_code_dialog;
 
    if (!(instance->initialized))
    {
        dtb_conn_exec_code_dialog_initialize(instance, dtb_palette_ab_palette_main.ab_palette_main);
	init_exec_code_dialog(instance);
    }
    ui_win_show(exec_code_dialog, False, XtGrabNone);
}

/* This function is the popupCallback for the "When" optionmenu.
 * It makes certain "whens" active or inactive depending upon
 * the object type and the specific object selected in the list.
 */
void
connP_update_when_menu(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    ABObj       cur_obj = connP_get_source();
    Widget      *w_list = NULL;

    XtVaGetValues(when_pulldown, XmNuserData, &w_list, NULL);

    if (w_list == NULL)
    {
        return;
    }

    switch (connP_get_source_type())
    {
	/* If the current source object type is Choice Item,
	 * then we have to check if the currently selected
	 * object is a radiobox/checkbox item or if it is an
	 * optionmenu item. If it is a radiobox/checkbox item
	 * then "Toggled" should become active and "Activated"
	 * should become inactive - vice versa if currently
	 * selected object is an optionmenu item.
	 */
	case AB_TYPE_ITEM:
	    if (obj_is_choice_item(cur_obj)) 
	    {
		if (obj_is_option_menu(obj_get_root(obj_get_parent(cur_obj))))
		{
		    XtSetSensitive(w_list[ConnP_conn_whens[2].when_type-1], True);
		    XtSetSensitive(w_list[ConnP_conn_whens[3].when_type-1], False);
		}
		else
		{
		    XtSetSensitive(w_list[ConnP_conn_whens[2].when_type-1], False);
		    XtSetSensitive(w_list[ConnP_conn_whens[3].when_type-1], True);
		}
	    }
	    break;

        case AB_TYPE_MESSAGE:
            if (cur_obj != NULL)
            {
                if (!obj_has_action1_button(cur_obj))
                   XtSetSensitive(w_list[ConnP_conn_whens[0].when_type-1],
                                 False);
                else
                   XtSetSensitive(w_list[ConnP_conn_whens[0].when_type-1],
                                 True);
                if (!obj_has_action2_button(cur_obj))
                   XtSetSensitive(w_list[ConnP_conn_whens[1].when_type-1],
                                 False);
                else
                   XtSetSensitive(w_list[ConnP_conn_whens[1].when_type-1],
                                 True);
                if (!obj_has_action3_button(cur_obj))
                   XtSetSensitive(w_list[ConnP_conn_whens[2].when_type-1],
                                 False);
                else
                   XtSetSensitive(w_list[ConnP_conn_whens[2].when_type-1],
                                 True);
                if (!obj_has_cancel_button(cur_obj))
                   XtSetSensitive(w_list[ConnP_conn_whens[3].when_type-1],
                                 False);
                else
                   XtSetSensitive(w_list[ConnP_conn_whens[3].when_type-1],
                                 True);
            }
 
            break;
 
        default:
            break;
    }
       
}

/* This function is the popupCallback for the "Action Type"
 * optionmenu.
 */
void
connP_update_action_menu(
    Widget widget,
    XtPointer clientData,
    XtPointer callData
)
{
    ABObj		src_obj = connP_get_source();
    ABObj       	target_obj = connP_get_target();
    AB_OBJECT_TYPE      target_type = connP_get_target_type();
    Widget      	*w_list = NULL;

    XtVaGetValues(action_pulldown, XmNuserData, &w_list, NULL);

    if (w_list == NULL)
        return;

    switch (target_type)
    {
	/* If any target object of these types don't have
	 * a label, then set "Set Label" action inactive.
	 */
	case AB_TYPE_CHOICE:
	case AB_TYPE_COMBO_BOX:
	case AB_TYPE_LIST:
	case AB_TYPE_SPIN_BOX:
	case AB_TYPE_SCALE:
	case AB_TYPE_TEXT_FIELD:
	    if (!obj_has_label(target_obj))
		XtSetSensitive(w_list[AB_STDACT_SET_LABEL-1], False);
	    else
		XtSetSensitive(w_list[AB_STDACT_SET_LABEL-1], True);
        default:
            break;
    }
}

void
conn_override_default_when(
    AB_WHEN	when
)
{
    DefaultWhen = when;
}

void
conn_reset_default_when(void)
{
    DefaultWhen = AB_WHEN_UNDEF;
}

void
conn_override_default_action_type(
    AB_FUNC_TYPE     func_type
)
{
    DefaultFuncType = func_type;
}
 
void
conn_reset_default_action_type(void)
{
    DefaultFuncType = AB_FUNC_UNDEF;
}

static void
update_on_src_type_change(
    AB_OBJECT_TYPE	obj_type,
    int			obj_subtype
)
{
    AB_WHEN		g_when = AB_WHEN_UNDEF;
    AB_FUNC_TYPE        g_func = AB_FUNC_UNDEF;
    AB_BUILTIN_ACTION   g_act = AB_STDACT_UNDEF;
    
    if (obj_type == (AB_OBJECT_TYPE) NULL)
        return;
 
    /* Update the When option menu */
    connP_set_source_type(obj_type, obj_subtype);

    /* Get the default when and action type */
    (void)connP_guess_when_action(obj_type, obj_subtype,
		connP_get_target_type(),
		connP_get_target_subtype(),
		&g_when, &g_func, &g_act);

    /* Set the default when */
    if (DefaultWhen != AB_WHEN_UNDEF)
        g_when = DefaultWhen;

    if (g_when != get_cur_when())
        set_cur_when(g_when);

    /* Set the default Action Type */
    if (DefaultFuncType != AB_FUNC_UNDEF)
	g_func = DefaultFuncType;

    if (g_func == AB_FUNC_USER_DEF)
    {   
        ui_optionmenu_change_label(action_type_opmenu,
                action_type_labels[ACTION_TYPE_CALLFUNC]);
        set_call_function_action_type();
    }   
    else
    {  
        ui_optionmenu_change_label(action_type_opmenu,
                action_type_labels[ACTION_TYPE_PREDEFINED]);
        set_standard_action_type();
    }
 
    /* Update the Source object list and select the current
     * source object (if there is one) in the list.
     */
    populate_list(src_list, connP_get_source(), TRUE);
}

static void
update_on_target_type_change(
    AB_OBJECT_TYPE	obj_type,
    int			obj_subtype
)
{
    AB_WHEN		g_when = AB_WHEN_UNDEF;
    AB_FUNC_TYPE        g_func = AB_FUNC_UNDEF;
    AB_BUILTIN_ACTION   g_act = AB_STDACT_UNDEF;
    
    if (obj_type == (AB_OBJECT_TYPE) NULL)
        return;
 
    /* Update the Action option menu */
    connP_set_target_type(obj_type, obj_subtype);

    /* Get the default pre-defined action */
    (void)connP_guess_when_action(connP_get_source_type(),
                                connP_get_source_subtype(),
                                obj_type, obj_subtype,
                                &g_when, &g_func, &g_act);

    if (g_act != get_cur_act())
	set_cur_act(g_act);

    /* Update the Target object list and select the current
     * source object (if there is one) in the list.
     */
    populate_list(target_list, connP_get_target(), TRUE);
}

static void
update_conn_ed_controls(void)
{
    AB_WHEN             g_when = AB_WHEN_UNDEF;
    AB_FUNC_TYPE        g_func = AB_FUNC_UNDEF;
    AB_BUILTIN_ACTION   g_act = AB_STDACT_UNDEF;
    AB_OBJECT_TYPE      source_type = AB_TYPE_UNDEF; 
    int			source_subtype = -1;
    AB_OBJECT_TYPE      target_type = AB_TYPE_UNDEF; 
    int			target_subtype = -1;
    long 		i = -1, j = -1;

    source_type = connP_get_source_type();
    source_subtype = connP_get_source_subtype();
    i = connP_get_obj_type_index(source_type, source_subtype);

    target_type = connP_get_target_type();
    target_subtype = connP_get_target_subtype();
    j = connP_get_obj_type_index(target_type, target_subtype);

    if ((i < 0) || (j < 0)) return;

    /* Update the Source option menu */
    XtVaSetValues(XmOptionButtonGadget(src_menu),
        XtVaTypedArg, XmNlabelString, XtRString,
            ConnP_conn_objs[i].label, strlen(ConnP_conn_objs[i].label)+1,
        NULL);
    update_on_src_type_change(source_type, source_subtype);

    /* Update the Target option menu */
    XtVaSetValues(XmOptionButtonGadget(target_menu),
        XtVaTypedArg, XmNlabelString, XtRString,
            ConnP_conn_objs[j].label, strlen(ConnP_conn_objs[j].label)+1,
        NULL);
    update_on_target_type_change(target_type, target_subtype);

    if (connP_conn_is_possible())
        set_conn_controls(TRUE);
    else
        set_conn_controls(FALSE);
}

static AB_FUNC_TYPE
get_cur_func_type(void)
{
    Widget      label_wid = XmOptionButtonGadget(action_type_opmenu);
    XmString    xm_act_label    = (XmString)NULL;
    char        *act_label = NULL;
    int        i = -1;
    AB_FUNC_TYPE	func_type = AB_FUNC_UNDEF;
 
    XtVaGetValues(label_wid, XmNlabelString, &xm_act_label, NULL);
    if (xm_act_label != NULL) {
	act_label = objxm_xmstr_to_str(xm_act_label);
 
	for (i = 0; i < ACTION_TYPE_NUM_VALUES; i++) {
	    if (!strcmp(act_label, action_type_labels[i])) {
		break;
	    }
	}
    }

    switch (i)
    {
	case ACTION_TYPE_PREDEFINED:
	    func_type = AB_FUNC_BUILTIN;    
	    break;
	case ACTION_TYPE_CALLFUNC:
	    func_type = AB_FUNC_USER_DEF;
	    break;
	case ACTION_TYPE_EXECUTE_CODE:
	    func_type = AB_FUNC_CODE_FRAG;    
	    break;
	case ACTION_TYPE_ON_ITEM_HELP:
	    func_type = AB_FUNC_ON_ITEM_HELP;    
	    break;
	case ACTION_TYPE_HELP_VOLUME:
	    func_type = AB_FUNC_HELP_VOLUME;    
	    break;
	default:
	    func_type = AB_FUNC_UNDEF;
	    break;
    }
    
    XtFree(act_label);
    return(func_type);
}

BOOL
connP_obj_part_of_conn(
    ABObj	obj,
    ABObj	conn_obj
)
{
    BOOL	ret = FALSE;

    if (obj && conn_obj)
    {
	if (obj_get_from(conn_obj) == obj)
	    ret = TRUE;
	else if (obj_get_to(conn_obj) == obj)
	    ret = TRUE;
    }
    return ret;
}

static void
set_ctrls_for_src(
    BOOL	state
)
{
    Widget      when_opmenu = XmOptionButtonGadget(when_menu);

    XtSetSensitive(when_opmenu, state);
}

static void
set_ctrls_for_target(
    BOOL	state
) 
{
    Widget      	act_opmenu = XmOptionButtonGadget(action_menu);
    AB_FUNC_TYPE	cat = connP_get_action_type();

    switch (cat)
    {
	case AB_FUNC_BUILTIN:
	    XtSetSensitive(act_opmenu, state); 
	    /* If setting the action option menu active,
	     * then we have to look at the action to
	     * determine if the argument field should
	     * also become active.
  	     */
	    if (state)
	    {
		change_arg_sensitivity(arg_field, 
			(XtPointer) NULL, (XtPointer) NULL);
	    }
	    else
	    {
	    	XtSetSensitive(arg_label, state);
	    	XtSetSensitive(arg_field, state);
	    }
	break;

	case AB_FUNC_USER_DEF:
	case AB_FUNC_CODE_FRAG:
	    XtSetSensitive(arg_label, state);
	    XtSetSensitive(arg_field, state);
	break;
	
	default: break;
    }
}

/*** DTB_USER_CODE_END
 ***
 *** End of user code section
 ***
 **************************************************************************/


