1595 lines
44 KiB
C
1595 lines
44 KiB
C
/*
|
|
* 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 <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,
|
|
int *add_enum,
|
|
int edit_count,
|
|
WidgetList edit_item,
|
|
int *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, (XtArgVal)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, (XtArgVal)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, ¤t_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,
|
|
*new_iobj_list;
|
|
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;
|
|
int 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);
|
|
|
|
}
|