/*
 * 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
 */
/*
 *      $XConsortium: prop_items.c /main/4 1996/08/07 19:50:46 mustafa $
 *
 * @(#)prop_items.c	1.31 11 Aug 1995 cde_app_builder/src/ab
 *
 *      RESTRICTED CONFIDENTIAL INFORMATION:
 *
 *      The information in this document is subject to special
 *      restrictions in a confidential disclosure agreement between
 *      HP, IBM, Sun, USL, SCO and Univel.  Do not distribute this
 *      document outside HP, IBM, Sun, USL, SCO, or Univel without
 *      Sun's specific written approval.  This document and all copies
 *      and derivative works thereof must be returned or destroyed at
 *      Sun's request.
 *
 *      Copyright 1993 Sun Microsystems, Inc.  All rights reserved.
 *
 */


/*
 *****************************************************************
 * prop_items.c - Implements all common property sheet functionality
 * 		  for Item-editing
 *
 *****************************************************************
 */
#ifndef _POSIX_SOURCE
#define _POSIX_SOURCE 1
#endif

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <Xm/BulletinB.h>
#include <Xm/CascadeB.h>
#include <Xm/Form.h>
#include <Xm/Frame.h>
#include <Xm/Label.h>
#include <Xm/List.h>
#include <Xm/MessageB.h>
#include <Xm/PushB.h>
#include <Xm/RowColumn.h>
#include <Xm/Separator.h>
#include <Xm/TextF.h>
#include <Xm/ToggleB.h>
#include <Dt/ComboBox.h>
#include <Dt/SpinBox.h>
#include "dtb_utils.h"
#include <ab_private/trav.h>
#include <ab_private/obj_notify.h>
#include <ab_private/objxm.h>
#include <ab_private/ab.h>
#include <ab_private/prop.h>
#include <ab_private/propP.h>
#include <ab_private/abobjP.h> 
#include <ab_private/abobj_set.h> 
#include <ab_private/ui_util.h>
#include <ab_private/x_util.h>

#define ITEM_NAME_MAX	512

#define HasItems(o) (obj_is_choice(o) || obj_is_list(o) || \
        obj_is_menubar(o) || obj_is_menu(o) || \
	obj_is_combo_box(o) || obj_is_spin_box(o))

#define PointerToRealItem(o) (o)->ui_handle

#define HasActiveState(t) ((t) == AB_ITEM_FOR_CHOICE || \
	(t) == AB_ITEM_FOR_MENUBAR || (t) == AB_ITEM_FOR_MENU)

#define HasSelectedState(t) ((t) == AB_ITEM_FOR_CHOICE || \
	(t) == AB_ITEM_FOR_LIST || (t) == AB_ITEM_FOR_COMBO_BOX || \
	(t) == AB_ITEM_FOR_SPIN_BOX)

#define HasLabelType(t) ((t) == AB_ITEM_FOR_CHOICE || \
	(t) == AB_ITEM_FOR_MENUBAR || (t) == AB_ITEM_FOR_MENU)

#define HasHelpState(t) ((t) == AB_ITEM_FOR_MENUBAR)

#define HasSubmenu(t) ((t) == AB_ITEM_FOR_MENUBAR || (t) == AB_ITEM_FOR_MENU)

#define HasMnemonic(t) ((t) == AB_ITEM_FOR_MENUBAR || (t) == AB_ITEM_FOR_MENU)

#define HasAccelerator(t) ((t) == AB_ITEM_FOR_MENU)

#define HasLabelLineStyle(t) ((t) == AB_ITEM_FOR_MENU)

#define RequiresSelection(p) (p->item_type == AB_ITEM_FOR_COMBO_BOX || \
	p->item_type == AB_ITEM_FOR_SPIN_BOX || \
        (p->item_type == AB_ITEM_FOR_CHOICE && \
	  obj_get_choice_type(*(p->current_obj_ptr)) != AB_CHOICE_NONEXCLUSIVE))
	  


static const char       *SeparatorNamebase ={"separator"};

/*************************************************************************
**                                                                      **
**       Private Function Declarations                                  **
**                                                                      **
*************************************************************************/

static void	activate_item_settings(
		    PropItemsSetting	pis,
		    BOOL		active
		);
static void     activate_menu_item_settings( 
                    PropItemsSetting     pis, 
                    BOOL                active
                ); 
static void	copy_item_to_clipboard(
		    ABObj		iobj,
		    ABObj		*item_clipboard
		);
static int	copy_item_fields(
		    ABObj		iobj,
		    ABObj		iobj_copy
		);
static BOOL	delete_selected_item(
		    PropItemsSetting	pis
		);
static int	get_current_item_pos( 
    		    PropItemsSetting    pis 
		); 
static ABObj	get_selected_item_copy(
		    Widget		itemlist,
		    int			*ppos
		);
static STRING	get_unique_default_label(
    		    Widget      	itemlist,
    		    STRING      	base
		);
static STRING	get_graphic_namebase(
		    STRING		graphic_path
		);
static ABObj	init_new_item(
    		    PropItemsSetting    pis
		);
static void	load_item(
    		    PropItemsSetting    pis,
    		    ABObj               iobj
		);
static void	setup_item_label_setting(
		    PropItemsSetting	pis,
		    AB_LABEL_TYPE	label_type,
		    STRING		label,
		    AB_LINE_TYPE	label_line_style
		);
static void	verify_and_set_item_selected(
    		    PropItemsSetting    pis,
    		    BOOL                selected
		);
/*
 * Callbacks
 */
static void     add_itemCB(
                    Widget      widget, 
                    XtPointer   client_data, 
                    XtPointer   call_data 
                ); 
static void     edit_itemCB(
                    Widget      widget,
                    XtPointer   client_data,
                    XtPointer   call_data
                );
static void	field_activateCB(
		    Widget      widget,
                    XtPointer   client_data,
                    XtPointer   call_data
                );
static void     select_itemCB(
                    Widget      widget,
                    XtPointer   client_data,
                    XtPointer   call_data
                );
static void	set_edit_menu_stateCB(
		    Widget	widget,
                    XtPointer   client_data,
                    XtPointer   call_data
                );

/*************************************************************************
**                                                                      **
**       Data Declarations                                              **
**                                                                      **
*************************************************************************/


/*************************************************************************
**                                                                      **
**       Function Definitions                                           **
**                                                                      **
*************************************************************************/

/* 
 * Initialize the mechanism to do Prop Sheet Item Editing
 */
void
prop_item_editor_init(
    PropItemsSetting	pis,
    AB_ITEM_TYPE	type,
    Widget		list,
    Widget		changebar,
    Widget		add_button,
    int			add_count,
    WidgetList		add_item,
    XtArgVal		*add_enum,
    int			edit_count,
    WidgetList		edit_item,
    XtArgVal		*edit_enum,
    PropFieldSetting    label_pfs, 
    PropOptionsSetting  label_type_pos, 
    Widget		label_graphic_hint,
    PropFieldSetting    mnemonic_pfs, 
    PropFieldSetting    accel_pfs,
    PropOptionsSetting  line_style_pos,
    PropCheckboxSetting state_pcs,
    PropMenunameSetting	menuname_pms,
    ABObj		*current_obj_ptr
)
{
    Widget		  menu_shell;
    int			  i;
   
    pis->item_type = type;
    pis->item_list = list;
    pis->item_menu = XtParent(add_item[0]);
    pis->item_label_pfs = label_pfs;
    pis->item_label_type_pos = label_type_pos;
    pis->item_mnemonic_pfs = mnemonic_pfs;
    pis->item_accel_pfs = accel_pfs;
    pis->item_line_style_pos = line_style_pos;
    pis->item_state_pcs = state_pcs;
    pis->item_menuname_pms = menuname_pms;
    pis->changebar = changebar;
    pis->current_item = NULL;
    pis->clipboard_item = NULL;
    pis->current_obj_ptr = current_obj_ptr;

    propP_changebar_init(changebar, list);

    XtVaSetValues(pis->item_list,
		XmNselectionPolicy, 	XmBROWSE_SELECT,
    		XmNautomaticSelection,	TRUE,
		NULL);

    XtVaSetValues(XtParent(pis->item_list),
                XmNrightAttachment,     XmATTACH_FORM,
                XmNrightOffset,         100,
		NULL);

    XtAddCallback(pis->item_list, XmNbrowseSelectionCallback, 
			select_itemCB, (XtPointer)pis);

    XtAddCallback(pis->item_label_pfs->field, XmNactivateCallback,
		field_activateCB, (XtPointer)pis);

    XtVaSetValues(pis->item_label_pfs->label, 
                XmNuserData, (XtArgVal)label_graphic_hint,
                XmNrecomputeSize, False,
                NULL);

    /* Set Up Add Button */
    XtVaSetValues(add_button, XmNuserData, (XtArgVal)INSERT_AFTER, NULL);
    XtAddCallback(add_button, XmNactivateCallback, add_itemCB, (XtPointer)pis);

    /* Set Up Edit MenuButton */
    for(i = 0; i < add_count; i++)
    {
	XtVaSetValues(add_item[i], XmNuserData, add_enum[i], NULL);
	XtAddCallback(add_item[i], XmNactivateCallback,
		add_itemCB, (XtPointer)pis);
    }
    for(i=0; i < edit_count; i++) 
    { 
        XtVaSetValues(edit_item[i], XmNuserData, edit_enum[i], NULL);
        XtAddCallback(edit_item[i], XmNactivateCallback, 
                edit_itemCB, (XtPointer)pis); 
    }
  
    /* Register a popup callback on the menubutton's menushell so that
     * menuitems can be made active/inactive depending on the state
     * of the item list at the time the menu is invoked.
     */
    menu_shell = ui_get_ancestor_shell(add_item[0]);
    XtAddCallback(menu_shell, XtNpopupCallback, set_edit_menu_stateCB, 
		(XtPointer)pis);

}

void
prop_item_editor_load(
    PropItemsSetting    pis,
    ABObj       	obj
)
{
    AB_TRAVERSAL trav;
    ABObj       pobj, iobj;
    ABObj       *iobj_list;
    int         num_items;
    STRING	list_ident;
    int         i;

    if (!HasItems(obj))
	return;

    /* Clear any current items from list */
    prop_item_editor_clear(pis);

    /* Load new obj's items into list */
    pobj = objxm_comp_get_subobj(obj, AB_CFG_PARENT_OBJ);

    if ((num_items = obj_get_num_items(pobj)) > 0)
    {
    	/* Store an array of copies of the items in the
     	 * list's userData
     	 */  
    	iobj_list = (ABObj *)util_malloc(num_items*sizeof(ABObj));
	activate_item_settings(pis, True);

    	for (trav_open(&trav, pobj, AB_TRAV_ITEMS_FOR_OBJ), i = 0;
            (iobj = trav_next(&trav)) != NULL; i++)
    	{
            /* Make a copy of the item's obj, so changes can
             * be made to it without affecting the real item obj
             */
            iobj_list[i] = obj_create(iobj->type, NULL);
            copy_item_fields(iobj, iobj_list[i]);

	    /* Keep track of Copy's real Item object 
	     */
	    PointerToRealItem(iobj_list[i]) = (XtPointer)iobj;

	    list_ident = prop_item_get_namebase(iobj);

            ui_list_add_item(pis->item_list, list_ident, 0);
    	}
    	trav_close(&trav);
    	XtVaSetValues(pis->item_list, XmNuserData, iobj_list, NULL);
    	XmListSelectPos(pis->item_list, 1, TRUE);
    }
    else /* No Items to load */
    	activate_item_settings(pis, False);
}

void
prop_item_editor_clear(
    PropItemsSetting	pis
)
{
    ABObj       *iobj_list;
    int         num_items;
    int         i;

    /* Destroy dup'd array of item objs */
    XtVaGetValues(pis->item_list,
                XmNuserData,  &iobj_list,
                XmNitemCount, &num_items,
                NULL);

    if (num_items > 0) /* Clear List & Array of Item copies...*/ 
    {
    	for (i=0; i < num_items; i++)
	{
	    PointerToRealItem(iobj_list[i]) = NULL;
            obj_destroy(iobj_list[i]);
	}

        util_free(iobj_list);
	XtVaSetValues(pis->item_list, XmNuserData, (XtArgVal)NULL, NULL);
        XmListDeleteAllItems(pis->item_list);
    }

    /* Clear Item Settings */
    prop_field_set_value(pis->item_label_pfs, "", False);

    if (HasLabelType(pis->item_type))
    	prop_options_set_value(pis->item_label_type_pos, (XtPointer)AB_LABEL_STRING, False);

    if (HasMnemonic(pis->item_type))
	prop_field_set_value(pis->item_mnemonic_pfs, "", False);

    if (HasAccelerator(pis->item_type))
	prop_field_set_value(pis->item_accel_pfs, "", False);

    if (HasLabelLineStyle(pis->item_type))
	prop_options_set_value(pis->item_line_style_pos, (XtPointer)AB_LINE_ETCHED_OUT, False);

    if (HasSubmenu(pis->item_type))
	prop_menuname_set_value(pis->item_menuname_pms, "", False);

    if (HasActiveState(pis->item_type))
    	prop_checkbox_set_value(pis->item_state_pcs, AB_STATE_ACTIVE , True, False);

    if (HasSelectedState(pis->item_type))
    	prop_checkbox_set_value(pis->item_state_pcs, AB_STATE_SELECTED, False, False);

    if (HasHelpState(pis->item_type))
	prop_checkbox_set_value(pis->item_state_pcs, HELP_ITEM_KEY, False, False);

    pis->current_item = NULL;

    if (pis->clipboard_item != NULL)
    {
	PointerToRealItem(pis->clipboard_item) = NULL;
    	obj_destroy(pis->clipboard_item);
    	pis->clipboard_item = NULL;
    }

}

/*
 * Transfer all changes made to item-copies inside the Item Editor
 * to the actual item objects they correspond to
 */
void
prop_item_editor_apply(
    PropItemsSetting	pis
)
{
    ABObj	current_obj;
    AB_TRAVERSAL trav;
    ABObj       *iobj_list;
    ABObj       pobj, oobj, iobj;
    Widget	*real_widget = NULL;
    int		*real_pos = NULL;
    ABObj	*real_iobj = NULL;
    BOOL	item_transfer = False;
    Widget	parent;
    STRING      item_name;
    STRING	name_base;
    int         new_num_items;
    int         num_items;
    int		current_item_pos = 0;
    int		del_count = 0;
    int         i, j;

    if ((current_obj = *(pis->current_obj_ptr)) == NULL)
	return;

    XtVaGetValues(pis->item_list,
                XmNuserData,    &iobj_list,
                XmNitemCount,   &new_num_items,
                NULL);

    pobj = objxm_comp_get_subobj(current_obj, AB_CFG_PARENT_OBJ);
    oobj = objxm_comp_get_subobj(current_obj, AB_CFG_OBJECT_OBJ);
    num_items = obj_get_num_items(pobj);

    parent = objxm_get_widget(pobj);
    if (pis->item_type == AB_ITEM_FOR_COMBO_BOX)
	parent = ui_combobox_get_list_widget(parent);

    /* Store pointers to the Live Item objects & their associated widgets
     * into linear arrays, so we can easily re-arrange them to match
     * applied changes (inserts, deletes, moves)
     */
    if (num_items > 0)
    {
    	real_iobj = (ABObj *)util_malloc(num_items*sizeof(ABObj));

	/* NOTE: don't need to store widgets for Menu Items since they 
	 *       are not instantiated during build-mode
	 */
    	switch(pis->item_type)
    	{
	    case AB_ITEM_FOR_LIST:
	    case AB_ITEM_FOR_COMBO_BOX:
	    case AB_ITEM_FOR_SPIN_BOX:
		real_pos = (int*)util_malloc(num_items*sizeof(int));
		break;
	    case AB_ITEM_FOR_MENUBAR:
	    case AB_ITEM_FOR_CHOICE:
		real_widget = (Widget*)util_malloc(num_items*sizeof(Widget));
	}
    }

    trav_open(&trav, pobj, AB_TRAV_ITEMS_FOR_OBJ);
    for (i=0; i < num_items; i++)
    {
	real_iobj[i] = trav_next(&trav);
	if (real_widget)
	{
	    /* Detach widget from item-object */
	    real_widget[i] = objxm_get_widget(real_iobj[i]);
	    abobjP_disable_build_actions(real_iobj[i], real_widget[i]);
	    objxm_set_widget(real_iobj[i], NULL);
	    objxm_free_obj_and_actions(real_widget[i]);
	}
	else if (real_pos)
	    real_pos[i] = i + 1;
    }
    trav_close(&trav);

    /* Now that we've stored them in an array, unparent them */
    for (i=0; i < num_items; i++)
	obj_unparent(real_iobj[i]);

    for (i=0; i < new_num_items; i++)
    {
	iobj = NULL;
	item_transfer = False;

	if (PointerToRealItem(iobj_list[i]) != NULL)
	{
	    /* Find real item object which corresponds to Copy */
	    for (j=0; iobj == NULL && j < num_items; j++)
	    	if (PointerToRealItem(iobj_list[i]) == real_iobj[j])
	    	{
	    	    iobj = real_iobj[j];
		    real_iobj[j] = NULL; /* Consume */
		    if (j != i)
			item_transfer = True;
	        }
	}

	if (iobj == NULL) /* none found ->We have a New object here! */
	{
            iobj = obj_create(AB_TYPE_ITEM, NULL);
            iobj->info.item.type = pis->item_type;
            PointerToRealItem(iobj_list[i]) = iobj; 
	    item_transfer = True;
  	}
	obj_append_child(pobj, iobj);

	/* 
	 * Now Transfer all attribute values of Copy to Real item obj...
  	 */

        /* Must reset Item's name in case Obj's name changed */
        name_base = prop_item_get_namebase(iobj_list[i]);
        item_name = abobj_construct_item_name(obj_get_name(current_obj),
                         name_base, "item");
 
        obj_set_name(iobj_list[i], item_name);
        obj_set_unique_name(iobj, obj_get_name(iobj_list[i]));
 
        objxm_obj_configure(iobj, OBJXM_CONFIG_BUILD, TRUE);
 
        abobj_set_label(iobj, iobj_list[i]->label_type, obj_get_label(iobj_list[i]));
        abobj_set_accelerator(iobj, obj_get_accelerator(iobj_list[i]));
        abobj_set_mnemonic(iobj, obj_get_mnemonic(iobj_list[i]));
        abobj_set_line_style(iobj, obj_get_line_style(iobj_list[i]));
 
        abobj_set_visible(iobj, obj_is_initially_visible(iobj_list[i]));
        abobj_set_menu_name(iobj, obj_get_menu_name(iobj_list[i]));
        obj_set_is_help_item(iobj, obj_is_help_item(iobj_list[i]));
        abobj_set_selected(iobj, obj_is_initially_selected(iobj_list[i]));
        abobj_set_active(iobj, obj_is_initially_active(iobj_list[i]));
 
        /* Color should be the same as the object parenting the Item */
        abobj_set_background_color(iobj, obj_get_bg_color(current_obj));
        abobj_set_foreground_color(iobj, obj_get_fg_color(current_obj));

	/* Trick to avoid sorting the actual widgets...
	 * we re-use the existing widget order, just re-assign them to
	 * new item objects (SetValues will take care of setting correct
	 * attributes).
	 */
	if (i < num_items)
	{
	    if (real_widget)
	    {
		/* Transfer widget to item object */
	        objxm_set_widget(iobj, real_widget[i]);
		objxm_store_obj_and_actions(real_widget[i], iobj);
                abobjP_enable_build_actions(iobj, real_widget[i]);

		if (item_transfer)
		{
                    /* Resources may be set differently for iobj than they were
                     * set for the previous iobj which owned this widget
                     */
		    objxm_comp_set_ui_args(iobj, OBJXM_CONFIG_BUILD, True);
		    obj_set_flag(iobj, AttrChangedFlag);
		}
	        real_widget[i] = NULL; /* Consume */
	    }
	    else if (real_pos) /* Items are not actually widgets */
	    {
		if (item_transfer)
		{
		    XmString xmitem = XmStringCreateLocalized(obj_get_label(iobj));

		    switch(pis->item_type)
		    {
		        case AB_ITEM_FOR_COMBO_BOX:
		    	case AB_ITEM_FOR_LIST:
			    if (parent)
                            	XmListReplacePositions(parent, &(real_pos[i]), &xmitem, 1);
			    else
				util_dprintf(0, 
				   "prop_item_editor_apply: ERROR parent for item %s is NULL\n",
					util_strsafe(obj_get_label(iobj)));
		  	    break;
		    	case AB_ITEM_FOR_SPIN_BOX:
                    	    DtSpinBoxDeletePos(parent, real_pos[i]);
                    	    DtSpinBoxAddItem(parent, xmitem, real_pos[i]);
			    break;
                    }
                    XmStringFree(xmitem);
		}
		real_pos[i] = 0; /* Consume */
	    }
	    obj_set_flag(iobj, InstantiatedFlag);
	}
	else /* no existing widget for Item object's position */
	    obj_clear_flag(iobj, InstantiatedFlag);

    }
    /* Do garbage collection...anything that was not consumed above
     * should be destroyed...
     */
    parent = objxm_get_widget(oobj);;

    for (i=0; i < num_items; i++) 
    {
	if (real_iobj && real_iobj[i] != NULL)
	    obj_destroy(real_iobj[i]);

	if (real_widget && real_widget[i] != NULL)
	    XtDestroyWidget(real_widget[i]);
	else if (real_pos && real_pos[i] != 0)
 	{
            if (parent && pis->item_type == AB_ITEM_FOR_LIST)
                XmListDeletePos(parent, real_pos[i - del_count]);

            else if (parent && pis->item_type == AB_ITEM_FOR_COMBO_BOX)
            	DtComboBoxDeletePos(parent, real_pos[i - del_count]);

            else if (parent && pis->item_type == AB_ITEM_FOR_SPIN_BOX)
            	DtSpinBoxDeletePos(parent, real_pos[i - del_count]);
	    del_count++;
	}
    }
    if (num_items > 0)
    {
    	util_free(real_iobj);
    	util_free(real_widget);
	util_free(real_pos);
    }

    /* ComboBox doesn't handle dynamic changes well, so re-instantiate */
    if (obj_is_combo_box(current_obj))
	obj_tree_clear_flag(current_obj, InstantiatedFlag);

    /* Ensure Item is selected in ItemList */
    current_item_pos = get_current_item_pos(pis);
    ui_list_select_pos(pis->item_list, current_item_pos, False);

}

void 
prop_item_change(  
    PropItemsSetting    pis,
    BOOL		select_next	
)  
{  
    ABObj	 current_obj;
    STRING	 newlabel = NULL, basename = NULL, graphic_path;
    BOOL	 label_type_chg = False;
    AB_LABEL_TYPE new_label_type;
    XmString	 xmitem;
    int		 current_item_pos = 0;
    ABObj	 *iobj_list;
    int		 num_items;
    int		 next_pos;

    if ((current_obj = *(pis->current_obj_ptr)) == NULL)
        return;

    if (pis->current_item)
    {
    	XtVaGetValues(pis->item_list,
                XmNuserData,    &iobj_list,
                XmNitemCount,   &num_items,
                NULL);
	current_item_pos = get_current_item_pos(pis);

	if (current_item_pos == 0)
	{
	    util_dprintf(3, "prop_item_change: could not find item in List\n");
	    return;
	}

	if (HasLabelType(pis->item_type))
	{
	    new_label_type =
		(AB_LABEL_TYPE)prop_options_get_value(pis->item_label_type_pos);
	    label_type_chg = (new_label_type != pis->current_item->label_type);
	    pis->current_item->label_type = new_label_type;
	}

	if (HasMnemonic(pis->item_type))
	    obj_set_mnemonic(pis->current_item, prop_field_get_value(pis->item_mnemonic_pfs));

	if (HasAccelerator(pis->item_type))
	    obj_set_accelerator(pis->current_item, prop_field_get_value(pis->item_accel_pfs));

	if (HasSelectedState(pis->item_type))
	    verify_and_set_item_selected(pis, 
		prop_checkbox_get_value(pis->item_state_pcs, AB_STATE_SELECTED));

	if (HasActiveState(pis->item_type))
	    obj_set_is_initially_active(pis->current_item,
		prop_checkbox_get_value(pis->item_state_pcs, AB_STATE_ACTIVE));

	if (HasHelpState(pis->item_type))
	{
	    BOOL help_item;

            if ((help_item = prop_checkbox_get_value(pis->item_state_pcs, HELP_ITEM_KEY)) == True)
            {
            	if (!prop_help_item_ok(pis->item_list, pis->current_item))
            	{
                    prop_checkbox_set_value(pis->item_state_pcs, HELP_ITEM_KEY, False, False);
                    help_item = FALSE;
            	}   
	     }
             obj_set_is_help_item(pis->current_item, help_item);
	}
	if (HasSubmenu(pis->item_type))
	{
	    STRING menuname;

            /* If valid Sub-menu, set menu_name */
            if (prop_submenu_name_ok(pis->item_menuname_pms->field, current_obj))
            {
            	menuname = ui_field_get_string(pis->item_menuname_pms->field);
            	obj_set_menu_name(pis->current_item,
                	(util_strcmp(menuname, "") == 0? NULL : menuname));
            	util_free(menuname);
            }
	}

	switch(pis->current_item->label_type)
	{
	    case AB_LABEL_SEPARATOR:
	    	/* 
	     	 * Separator Menu-items have a NULL label string, but they still
	     	 * require a string for identification in the itemlist as well
	     	 * as to base the item name
	     	 */
		newlabel = NULL;
	    	obj_set_line_style(pis->current_item,
                        (AB_LINE_TYPE)prop_options_get_value(pis->item_line_style_pos));
	    	prop_field_set_value(pis->item_label_pfs, "", False);
	    	basename = get_unique_default_label(pis->item_list, (STRING)SeparatorNamebase);
		break;

	    case AB_LABEL_GLYPH:
		if (!prop_graphic_filename_ok(pis->item_label_pfs->field, False))
		    /* Couldn't convert to Pixmap, so reset back to type String */
                    pis->current_item->label_type = AB_LABEL_STRING;
		else
		{
		    /* Strip off graphic filename path for item name */
		    graphic_path = newlabel = prop_field_get_value(pis->item_label_pfs);
		    basename = get_graphic_namebase(graphic_path);
		}
		break;
	}
	if (pis->current_item->label_type == AB_LABEL_STRING)
	    /* memory alloc'd in call below */
	    basename = newlabel = prop_field_get_value(pis->item_label_pfs);

        if (label_type_chg ||
	    !util_streq(obj_get_label(pis->current_item), newlabel))
        {
            obj_set_label(pis->current_item, newlabel);
            abobj_set_item_name(pis->current_item, obj_get_module(current_obj),
                        obj_get_name(current_obj), basename);
        
	    xmitem = XmStringCreateLocalized(basename);
            XmListReplacePositions(pis->item_list, &current_item_pos, &xmitem, 1);
            XmStringFree(xmitem);
	}

	if (pis->current_item->label_type != AB_LABEL_SEPARATOR)
            util_free(newlabel);

	/* Select the "next" item in the list */
	if (select_next)
	{
	    next_pos = current_item_pos == num_items? 1 : current_item_pos + 1;
    	    pis->current_item = iobj_list[next_pos - 1];
	    ui_list_select_pos(pis->item_list, next_pos, False);
    	    load_item(pis, iobj_list[next_pos - 1]);
	}
    }
}
  
void
prop_item_edit(
    PropItemsSetting	pis,
    AB_EDIT_TYPE        etype
)
{
    ABObj       iobj_copy;
    int         pos;
    int		new_item_pos;
 
    iobj_copy = get_selected_item_copy(pis->item_list, &pos);
 
    switch(etype)
    {
        case AB_EDIT_CUT:
            copy_item_to_clipboard(iobj_copy, &(pis->clipboard_item));
	    PointerToRealItem(pis->clipboard_item) = PointerToRealItem(iobj_copy);
            delete_selected_item(pis);
            break;
        case AB_EDIT_COPY:
            copy_item_to_clipboard(iobj_copy, &(pis->clipboard_item));
	    /* NOTE: Don't copy PointerToRealItem for a "Copy" */
            break;
        case AB_EDIT_PASTE:
            if (pis->clipboard_item != NULL)
            {
                iobj_copy = obj_create(pis->clipboard_item->type, NULL);
                copy_item_fields(pis->clipboard_item, iobj_copy);
		PointerToRealItem(iobj_copy) = PointerToRealItem(pis->clipboard_item);

                new_item_pos = prop_item_insert(pis, INSERT_AFTER, iobj_copy);
		if (new_item_pos != -1)
                    ui_list_select_pos(pis->item_list, new_item_pos, True);
		else
		{
		    PointerToRealItem(iobj_copy) = NULL;
		    obj_destroy(iobj_copy);
		    util_dprintf(3, "prop_item_edit: could not add new item to List\n");
		}
            }
            break;
        case AB_EDIT_DELETE:
            delete_selected_item(pis);
            break;
        default:
            /* catch-all case to avoid compiler warnings */
        break;
    }
}

STRING
prop_item_get_namebase(
    ABObj	iobj
)
{
    STRING	namebase = NULL;
    static char namebuf[ITEM_NAME_MAX];
    STRING      starts, graphic_path;

    switch(iobj->label_type)
    {
 	case AB_LABEL_SEPARATOR:
            snprintf(namebuf, sizeof(namebuf), "%s", obj_get_name(iobj));
            starts = strstr(namebuf, SeparatorNamebase);
            namebase = strtok(starts, "_");
	    break;
	case AB_LABEL_GLYPH:
	    graphic_path = obj_get_label(iobj);
	    namebase = get_graphic_namebase(graphic_path);
	    break;
	case AB_LABEL_STRING:
	default:
            namebase = obj_get_label(iobj);
	    break;
    }
    return namebase;
}


int
prop_item_insert(
    PropItemsSetting	pis,
    INSERT_TYPE         itype,
    ABObj       	iobj
)
{
    ABObj       *iobj_list,
                *new_iobj_list;
    int         num_items;
    int         select_pos;
    int         pos = 0;
    int         i, j;

    XtVaGetValues(pis->item_list,
                XmNitemCount, &num_items,
                XmNuserData,  &iobj_list,
                NULL);

    select_pos = ui_list_get_selected_pos(pis->item_list);
    if (select_pos != -1)
    {
        switch(itype)
        {
            case INSERT_AFTER:
                pos = select_pos + 1;
                break;
            case INSERT_BEFORE:
                pos = select_pos;
                break;
            case INSERT_TOP:
                pos = 1;
                break;
            case INSERT_BOTTOM:
                pos = num_items + 1;
                break;
            default:
                /* catch-all case to avoid compiler warnings */
            break;
        }
    }    
    else /* First Item being added to List...*/
    {
        pos = 1;
	if (RequiresSelection(pis))
	    obj_set_is_initially_selected(iobj, True);

	activate_item_settings(pis, True);
    }

    ui_list_add_item(pis->item_list, obj_get_label(iobj), pos);
    num_items++;

    new_iobj_list = (ABObj *)util_malloc(num_items * sizeof(ABObj));

    for (i = j = 0; i < num_items; i++)
    {
        if (i == (pos - 1))
            new_iobj_list[i] = iobj;
        else
            new_iobj_list[i] = iobj_list[j++];
    }
    XtVaSetValues(pis->item_list, XmNuserData, new_iobj_list, NULL);

    util_free(iobj_list);

    return (pos);

}


/*
 ****************************************************************************
 * Private Support Routines
 ****************************************************************************
 */

static int
copy_item_fields(
    ABObj	iobj,
    ABObj	iobj_copy
)
{
    if (iobj != NULL && iobj_copy != NULL)
    {
    	obj_set_subtype(iobj_copy, obj_get_subtype(iobj));
    	obj_set_name(iobj_copy, obj_get_name(iobj));
    	obj_set_label(iobj_copy, obj_get_label(iobj));
    	obj_set_is_help_item(iobj_copy, obj_is_help_item(iobj));
    	iobj_copy->label_type = iobj->label_type;
	obj_set_is_initially_visible(iobj_copy, obj_is_initially_visible(iobj));
	obj_set_is_initially_active(iobj_copy, obj_is_initially_active(iobj));
	obj_set_is_initially_selected(iobj_copy, 
			obj_is_initially_selected(iobj));
        obj_set_menu_name(iobj_copy, obj_get_menu_name(iobj));
        obj_set_accelerator(iobj_copy, obj_get_accelerator(iobj));
        obj_set_mnemonic(iobj_copy, obj_get_mnemonic(iobj));
        obj_set_line_style(iobj_copy, obj_get_line_style(iobj));
        obj_set_bg_color(iobj_copy, obj_get_bg_color(iobj));
        obj_set_fg_color(iobj_copy, obj_get_fg_color(iobj));

    	return 0;
    }
    return -1;
}

static void
copy_item_to_clipboard(
    ABObj	iobj,
    ABObj	*item_clipboard
)
{
    ABObj	old_selection;
    ABObj	new_selection;

    old_selection = *item_clipboard;

    new_selection = obj_create(iobj->type, NULL);
    copy_item_fields(iobj, new_selection); 
    *item_clipboard = new_selection;

    if (old_selection != NULL)
    {
	PointerToRealItem(old_selection) = NULL;
	obj_destroy(old_selection);
    }

}

static BOOL
delete_selected_item(
    PropItemsSetting  pis
)
{
    ABObj	current_obj;
    ABObj	*iobj_list;
    ABObj	*new_iobj_list = NULL;
    int		num_items;
    int		select_pos;
    int		i, j;

    current_obj = *(pis->current_obj_ptr);
 
    XtVaGetValues(pis->item_list,
                XmNuserData,    &iobj_list,
                NULL);

    select_pos = ui_list_get_selected_pos(pis->item_list);
 
    if (select_pos != -1)
    {
      	XtVaGetValues(pis->item_list, XmNitemCount, &num_items, NULL);
	if (num_items > 1)
	{
            new_iobj_list = (ABObj *)util_malloc((num_items - 1) * sizeof(ABObj));
	    if (new_iobj_list == NULL)
	    {
		util_dprintf(1, "delete_selected_item: malloc failed\n");
		return False;
	    }
	}

        for (i = j = 0; i < num_items; i++)
        {
            if (i == (select_pos - 1)) /* Found item-object being deleted */
	    {
		/* If the item-object being deleted is the one which is selected and
		 * it's not a Checkbox-item, then choose another item-object to
		 * be selected.
		 */
		if (num_items > 1 && 
		    obj_is_initially_selected(iobj_list[i]) &&
		    RequiresSelection(pis))
		{
		    if (i + 1 < num_items)
			obj_set_is_initially_selected(iobj_list[i+1], True);
		    else
			obj_set_is_initially_selected(iobj_list[0], True);
		}

		PointerToRealItem(iobj_list[i]) = NULL;
		obj_destroy(iobj_list[i]);
	    }
	    else
            	new_iobj_list[j++] = iobj_list[i];
    	}
    	XtVaSetValues(pis->item_list, XmNuserData, new_iobj_list, NULL);

        XmListDeletePos(pis->item_list, select_pos);
	if (num_items > 1)
	    XmListSelectPos(pis->item_list, 
		select_pos == num_items? select_pos - 1 : select_pos, TRUE);

	else /* No items left in list */
	    activate_item_settings(pis, False);

    	util_free(iobj_list);
	return TRUE;
    }   
    return FALSE;

}

static int
get_current_item_pos(
    PropItemsSetting	pis
)
{
    ABObj	*iobj_list;
    int		num_items = 0;
    int		i;
    int		current_pos = 0;

    XtVaGetValues(pis->item_list,
                XmNuserData,    &iobj_list,
                XmNitemCount,   &num_items,
                NULL);

    for(i=0; i < num_items; i++)
        if (iobj_list[i] == pis->current_item)
        {
            current_pos = i + 1;
            break;
        }

    return current_pos;
}

ABObj
get_selected_item_copy(
    Widget      list,
    int         *ppos
)
{
    ABObj       *iobj_list;
    int		select_pos;

    select_pos = ui_list_get_selected_pos(list);
    XtVaGetValues(list,
                XmNuserData,    &iobj_list,
                NULL);

    if (select_pos != -1)
    {
        *ppos = select_pos;
        return(iobj_list[(*ppos - 1)]);
    }
    return NULL;

}

static STRING
get_graphic_namebase(
    STRING      graphic_path
)
{
    static char namebase_buf[ITEM_NAME_MAX];

    if (util_strempty(graphic_path))
        return NULL;

    util_get_file_name_from_path(graphic_path, namebase_buf, ITEM_NAME_MAX);
    strcat(namebase_buf, "_graphic");

    return namebase_buf;
}

static STRING
get_unique_default_label(
    Widget	itemlist,
    STRING	base
)
{
    static char   label_buf[256];
    BOOL   	  unique = False;
    int	   	  i = 1;
    int		  pos;

    while (!unique)
    {
        sprintf(label_buf, "%s%d", base, i++);
	if (ui_list_find_item(itemlist, label_buf, &pos) == ERR_NOT_FOUND)
	    unique = True;
    }
    return label_buf;
}

static ABObj
init_new_item(
    PropItemsSetting	pis
)
{
    ABObj current_obj;
    ABObj new_iobj;
    STRING newlabel;

    if ((current_obj = *(pis->current_obj_ptr)) == NULL)
        return NULL;

    new_iobj = obj_create(AB_TYPE_ITEM, NULL);
    obj_set_subtype(new_iobj, pis->item_type);

    new_iobj->label_type = AB_LABEL_STRING;
    newlabel = get_unique_default_label(pis->item_list,
        CATGETS(Dtb_project_catd, 100, 268, "Item"));
    obj_set_label(new_iobj, newlabel);

    abobj_set_item_name(new_iobj, obj_get_module(current_obj),
                obj_get_name(current_obj), newlabel);

    if (HasSelectedState(pis->item_type))
            obj_set_is_initially_selected(new_iobj, False);
    if (HasActiveState(pis->item_type))
            obj_set_is_initially_active(new_iobj, True);
    if (HasHelpState(pis->item_type))
        obj_set_is_help_item(new_iobj, False);

    obj_set_bg_color(new_iobj, obj_get_bg_color(current_obj));
    obj_set_fg_color(new_iobj, obj_get_fg_color(current_obj));

    return(new_iobj);
}


/*
 * Load the Item obj into the item editing fields
 * (if iobj == NULL then perform a clear)
 */
static void
load_item(
    PropItemsSetting	pis,
    ABObj		iobj
)
{
    AB_LABEL_TYPE	label_type = AB_LABEL_STRING;
    STRING 		label = NULL;

    if (iobj != NULL && !obj_is_item(iobj))
	return;

    /* Load Item Label Type */
    if (HasLabelType(pis->item_type))
    {
	label_type = iobj? iobj->label_type : AB_LABEL_STRING;
    	prop_options_set_value(pis->item_label_type_pos,
                               (XtPointer)label_type, False);
    }

    /* Load Item Label (make selected & with focus) */
    if (label_type != AB_LABEL_SEPARATOR)
    {
    	label = iobj? obj_get_label(iobj) : "";
	setup_item_label_setting(pis, iobj->label_type, label, AB_LINE_UNDEF);
	ui_field_select_string(pis->item_label_pfs->field, True);
    }
    else  /* AB_LABEL_SEPARATOR */
	setup_item_label_setting(pis, iobj->label_type, 
		"", iobj? obj_get_line_style(iobj) : AB_LINE_NONE); 

    /* Load Mnenonic/Accelerator */
    if (HasMnemonic(pis->item_type))
	prop_field_set_value(pis->item_mnemonic_pfs, obj_get_mnemonic(iobj), False);

    if (HasAccelerator(pis->item_type))
	prop_field_set_value(pis->item_accel_pfs, obj_get_accelerator(iobj), False);

    /* Load Item State */
    if (HasActiveState(pis->item_type))
    	prop_checkbox_set_value(pis->item_state_pcs, AB_STATE_ACTIVE, 
		iobj? obj_is_initially_active(iobj) : True, False);

    if (HasSelectedState(pis->item_type))
    	prop_checkbox_set_value(pis->item_state_pcs, AB_STATE_SELECTED, 
		iobj? obj_is_initially_selected(iobj) : False, False);

    if (HasHelpState(pis->item_type))
	prop_checkbox_set_value(pis->item_state_pcs, HELP_ITEM_KEY, 
		iobj? obj_is_help_item(iobj) : False, False);

    /* Load Item Submenu */
    if (HasSubmenu(pis->item_type))
	prop_menuname_set_value(pis->item_menuname_pms, 
		iobj? obj_get_menu_name(iobj) : "", False);

}

static void
activate_item_settings(
    PropItemsSetting	pis,
    BOOL		active
)
{
    Widget	graphic_hint = NULL;

    ui_set_active(pis->item_label_pfs->label, active);
    if (!active)
	ui_field_set_string(pis->item_label_pfs->field, "");
    ui_field_set_editable(pis->item_label_pfs->field, active);

    if (HasLabelType(pis->item_type))
    {
	if (pis->item_label_type_pos->label)
            ui_set_active(pis->item_label_type_pos->label, active);

        ui_set_active(pis->item_label_type_pos->optionbox, active);

	XtVaGetValues(pis->item_label_pfs->label,
		XmNuserData,	&graphic_hint,
		NULL);
	if (graphic_hint)
	    ui_set_active(graphic_hint, active);
    }

    if (HasLabelLineStyle(pis->item_type))
    {
        ui_set_active(pis->item_line_style_pos->label, active);
        ui_set_active(pis->item_line_style_pos->optionbox, active);
    }

    if (pis->item_state_pcs != NULL)
    {
	if (pis->item_state_pcs->label)
	    ui_set_active(pis->item_state_pcs->label, active);
	ui_set_active(pis->item_state_pcs->checkbox, active);
    }

    activate_menu_item_settings(pis, active);
}

static void
activate_menu_item_settings(
    PropItemsSetting    pis,
    BOOL                active
)
{
    if (HasMnemonic(pis->item_type))
    {
        ui_set_active(pis->item_mnemonic_pfs->label, active);
        ui_set_active(pis->item_mnemonic_pfs->field, active);
    }
    if (HasAccelerator(pis->item_type))
    {
        ui_set_active(pis->item_accel_pfs->label, active);
        ui_set_active(pis->item_accel_pfs->field, active);
    }
    if (HasSubmenu(pis->item_type))
    {
        ui_set_active(pis->item_menuname_pms->label, active);
        ui_set_active(pis->item_menuname_pms->field, active);
        ui_set_active(pis->item_menuname_pms->menubutton, active);
    }
}


static void
setup_item_label_setting(
    PropItemsSetting	pis,
    AB_LABEL_TYPE	label_type,
    STRING		label,
    AB_LINE_TYPE	label_line_style
)
{
    BOOL	no_sep_label = True;

    prop_setup_label_field(pis->item_label_pfs, pis->item_line_style_pos,
                label_type, label, label_line_style);

    no_sep_label = (label_type != AB_LABEL_SEPARATOR);

    XtVaSetValues(pis->item_label_pfs->field, 
		XmNcursorPositionVisible, no_sep_label,
		NULL);

    activate_menu_item_settings(pis, no_sep_label);
}

static void
verify_and_set_item_selected(
    PropItemsSetting	pis,
    BOOL		selected
)
{
    ABObj	current_obj;
    ABObj	*iobj_list;
    int		num_items;
    int		i;

    XtVaGetValues(pis->item_list,
                XmNuserData,  &iobj_list,
                XmNitemCount, &num_items,
                NULL);

    current_obj = *(pis->current_obj_ptr);

    switch(pis->item_type)
    {
	case AB_ITEM_FOR_CHOICE:
	    if (obj_get_subtype(current_obj) == AB_CHOICE_NONEXCLUSIVE)
		break;
	    /* else fall through...*/
	case AB_ITEM_FOR_COMBO_BOX:
	case AB_ITEM_FOR_SPIN_BOX:
	case AB_ITEM_FOR_LIST:
	    if (selected)	
	    {
		if (pis->item_type != AB_ITEM_FOR_LIST ||
		    ((obj_get_selection_mode(current_obj) == AB_SELECT_SINGLE) ||
		     (obj_get_selection_mode(current_obj) == AB_SELECT_BROWSE)))
	  	{
		    /* make sure only 1 Item is selected at a time...*/
	    	    for (i=0; i < num_items; i++)
		   	if (iobj_list[i] != pis->current_item &&
				obj_is_initially_selected(iobj_list[i]) == True)
		           obj_set_is_initially_selected(iobj_list[i], False);
	    	}
	    }
	    break;
	default:
	    break;
		
    }
    obj_set_is_initially_selected(pis->current_item, selected);

}

/*
 ****************************************************************************
 * Callbacks
 ****************************************************************************
 */

static void
edit_itemCB(
    Widget	widget,
    XtPointer	client_data,
    XtPointer   call_data
)
{
    PropItemsSetting    pis = (PropItemsSetting)client_data; 
    int			current_item_pos = 0;
    AB_EDIT_TYPE 	etype;

    XtVaGetValues(widget, XmNuserData, &etype, NULL);

    if (etype == EDIT_CHANGE)
    {
	current_item_pos = get_current_item_pos(pis);
  	prop_item_change(pis, False);
	ui_list_select_pos(pis->item_list, current_item_pos, False);
    }
    else
    {
        prop_item_edit(pis, etype);
    	ui_field_select_string(pis->item_label_pfs->field, False);
    }
    prop_set_changebar(pis->changebar, PROP_CB_ON);
    XmProcessTraversal(pis->item_label_pfs->field, XmTRAVERSE_CURRENT);

}
static void
field_activateCB(
    Widget      widget,
    XtPointer   client_data,
    XtPointer   call_data
)
{
    PropItemsSetting	pis = (PropItemsSetting)client_data;

    prop_item_change(pis, True);

}
static void
add_itemCB(
    Widget	widget,
    XtPointer	client_data,
    XtPointer	call_data
)
{
    PropItemsSetting    pis = (PropItemsSetting)client_data;
    ABObj	 iobj_copy;
    INSERT_TYPE  itype;
    int		 new_item_pos;

    if (*(pis->current_obj_ptr) == NULL)
	return;

    XtVaGetValues(widget, XmNuserData, &itype, NULL);

    iobj_copy = init_new_item(pis);
    new_item_pos = prop_item_insert(pis, itype, iobj_copy);
    if (new_item_pos != -1)
    {
    	ui_list_select_pos(pis->item_list, new_item_pos, True);
    	pis->current_item = iobj_copy;
    	prop_set_changebar(pis->changebar, PROP_CB_ON);

    	ui_field_select_string(pis->item_label_pfs->field, True);
    }
    else /* Error in adding item to list */
    {
	PointerToRealItem(iobj_copy) = NULL;
	obj_destroy(iobj_copy);
	util_dprintf(3, "add_itemCB: could not add new item to List\n");
    }

}


static void
select_itemCB(
    Widget 	widget,
    XtPointer 	client_data,
    XtPointer   call_data
)
{
    XmListCallbackStruct *listdata = (XmListCallbackStruct *)call_data;
    PropItemsSetting	pis = (PropItemsSetting)client_data;
    ABObj	 	iobj_copy;
    int		 	pos;

    iobj_copy = get_selected_item_copy(pis->item_list, &pos);

    if (pis->current_item != NULL &&
	pis->current_item != iobj_copy)
    {
        /* Need to Save previous item's edits... */
	prop_item_change(pis, False);
    }
    load_item(pis, iobj_copy);
    pis->current_item = iobj_copy;
 
}

static void
set_edit_menu_stateCB(
    Widget      widget,
    XtPointer   client_data,
    XtPointer   call_data
)
{
    PropItemsSetting    pis = (PropItemsSetting)client_data;
    BOOL		listitem_exists = False;
    BOOL		clipboard_full = False;
    WidgetList		menu_items;
    int			num_menu_items;
    XtArgVal	item_key;
    int			i;

    listitem_exists = (pis->current_item != NULL);
    clipboard_full = (pis->clipboard_item != NULL);

    XtVaGetValues(pis->item_menu,
		XmNnumChildren,	&num_menu_items,
		XmNchildren,	&menu_items,
		NULL);

    /* Loop through the Edit menuitems, setting their sensitivity 
     * according to the state of the Item editor
     */
    for (i = 0; i < num_menu_items; i++)
    {
	XtVaGetValues(menu_items[i], XmNuserData, &item_key, NULL);

	switch(item_key)
  	{
	    case AB_EDIT_CUT:
	    case AB_EDIT_COPY:
	    case AB_EDIT_DELETE:
	    case EDIT_CHANGE:
		ui_set_active(menu_items[i], listitem_exists);
		break;
	    case AB_EDIT_PASTE:
		ui_set_active(menu_items[i], clipboard_full);
		break;
	    case INSERT_AFTER:
	    case INSERT_BEFORE:
	    default:
		break;
		/* do nothing */
	}
    }
}

void
prop_item_labeltypeCB(
    Widget   item,
    XtPointer clientdata,
    XtPointer call_data
)
{
    AB_LABEL_TYPE                value = AB_LABEL_UNDEF;
    PropItemsSetting    	 pis = (PropItemsSetting)clientdata;

    XtVaGetValues(item, XmNuserData, &value, NULL);

    setup_item_label_setting(pis, (AB_LABEL_TYPE)value, NULL, AB_LINE_UNDEF);

    if (value != AB_LABEL_SEPARATOR)
	ui_field_select_string(pis->item_label_pfs->field, True);

}
