Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtappbuilder / src / ab / pal_list.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23
24 /*
25  *      $XConsortium: pal_list.c /main/5 1996/08/08 18:02:00 mustafa $
26  *
27  * @(#)pal_list.c       1.41 15 Feb 1994      cde_app_builder/src/ab
28  *
29  *      RESTRICTED CONFIDENTIAL INFORMATION:
30  *
31  *      The information in this document is subject to special
32  *      restrictions in a confidential disclosure agreement between
33  *      HP, IBM, Sun, USL, SCO and Univel.  Do not distribute this
34  *      document outside HP, IBM, Sun, USL, SCO, or Univel without
35  *      Sun's specific written approval.  This document and all copies
36  *      and derivative works thereof must be returned or destroyed at
37  *      Sun's request.
38  *
39  *      Copyright 1993 Sun Microsystems, Inc.  All rights reserved.
40  *
41  */
42
43
44 /*
45  * pal_list.c - Implements Palette List object functionality
46  */
47 #include <stdio.h>
48 #include <Xm/Xm.h>
49 #include <ab_private/obj_notify.h>
50 #include <ab_private/objxm.h>
51 #include <ab_private/ab.h>
52 #include <ab_private/pal.h>
53 #include <ab_private/prop.h>
54 #include <ab_private/abobj.h>
55 #include <ab_private/abobj_set.h>
56 #include <ab_private/abobj_edit.h>
57 #include <ab_private/ui_util.h>
58 #include "list_ui.h"
59
60 const    int    list_init_width  = 130;
61
62 typedef struct  PROP_LIST_SETTINGS
63 {
64     Widget                      prop_sheet;
65     PropFieldSettingRec         name;
66     PropOptionsSettingRec       sel_mode;
67     PropGeometrySettingRec      pos;
68     PropRadioSettingRec         wth_policy;
69     PropGeometrySettingRec      wth;
70     PropOptionsSettingRec       hgt_metric;
71     PropGeometrySettingRec      hgt;
72     PropOptionsSettingRec       label_type;
73     PropFieldSettingRec         label;
74     PropOptionsSettingRec       label_pos;
75     PropCheckboxSettingRec      init_state;
76     PropColorSettingRec         bg_color;
77     PropColorSettingRec         fg_color;
78     PropMenunameSettingRec      menuname;
79     PropFieldSettingRec         menu_title;
80     PropFieldSettingRec         item_label;
81     PropCheckboxSettingRec      item_state;
82     PropItemsSettingRec         items;
83     ABObj                       current_obj;
84 } PropListSettingsRec, *PropListSettings;
85
86 /*************************************************************************
87 **                                                                      **
88 **       Private Function Declarations                                  **
89 **                                                                      **
90 **************************************************************************/
91 /*
92  * Methods
93  */
94 static int      list_initialize(
95                     ABObj   obj
96                 );
97 static Widget   list_prop_init(
98                     Widget  parent,
99                     AB_PROP_TYPE type
100                 );
101 static int      list_prop_activate(
102                     AB_PROP_TYPE type,
103                     BOOL         active
104                 );
105 static int      list_prop_clear(
106                     AB_PROP_TYPE type
107                 );
108 static int      list_prop_load(
109                     ABObj        obj,
110                     AB_PROP_TYPE type,
111                     unsigned long loadkey
112                 );
113 static int      list_prop_apply(
114                     AB_PROP_TYPE type
115                 );
116 static BOOL     list_prop_pending(
117                     AB_PROP_TYPE type
118                 );
119 static BOOL     verify_props(
120                     AB_PROP_TYPE type
121                 );
122 static void     turnoff_changebars(
123                     AB_PROP_TYPE type
124                 );
125
126 /*
127  * ABObj callbacks
128  */
129 static int      prop_list_install_obj_destroy_CB(void);
130
131 static int      prop_list_obj_destroy_CB(
132                     ObjEvDestroyInfo destroyInfo
133                 );
134
135 /*
136  * Xt Callbacks
137  */
138 static void     wth_policyCB(
139                     Widget      widget,
140                     XtPointer   clientdata,
141                     XmToggleButtonCallbackStruct *state
142                 );
143
144
145 /*************************************************************************
146 **                                                                      **
147 **       Data                                                            **
148 **                                                                      **
149 **************************************************************************/
150 PalItemInfo list_palitem_rec = {
151
152     /* type             */  AB_TYPE_LIST,
153     /* name             */  "List",
154     /* animation pixmaps*/  NULL,
155     /* number of pixmaps*/  0,
156     /* rev_prop_frame   */  NULL,
157     /* fix_prop_dialog  */  NULL,
158     /* initialize       */  list_initialize,
159     /* is_a_test        */  obj_is_list,
160     /* prop_initialize  */  list_prop_init,
161     /* prop_activate    */  list_prop_activate,
162     /* prop_clear       */  list_prop_clear,
163     /* prop_load        */  list_prop_load,
164     /* prop_apply       */  list_prop_apply,
165     /* prop_pending     */  list_prop_pending
166
167 };
168
169 PalItemInfo *ab_list_palitem = &list_palitem_rec;
170 PropListSettingsRec prop_list_settings_rec[AB_PROP_TYPE_NUM_VALUES];
171
172
173 /*************************************************************************
174 **                                                                      **
175 **       Function Definitions                                           **
176 **                                                                      **
177 **************************************************************************/
178 static int
179 list_initialize(
180     ABObj    obj
181 )
182 {
183     AB_LIST_INFO *info = &(obj->info.list);
184     ABObj       module = obj_get_module(obj);
185     ABObj       iobj;
186     String  items[2];
187     int         i;
188
189     obj_set_unique_name(obj, "list");
190
191     obj_set_num_rows(obj, 4);
192     obj_set_height(obj, -1);
193     obj_set_width(obj, list_init_width);
194     obj_set_selection_mode(obj, AB_SELECT_BROWSE);
195     obj_set_is_initially_visible(obj, True);
196     obj_set_is_initially_active(obj, True);
197
198     /* Add initial items to list */
199     items[0] = catgets(Dtb_project_catd, 6, 70, "itemA");
200     items[1] = catgets(Dtb_project_catd, 6, 71, "itemB");
201     for (i=0; i < XtNumber(items); i++)
202     {
203         iobj = obj_create(AB_TYPE_ITEM, NULL);
204         obj_set_subtype(iobj, AB_ITEM_FOR_LIST);
205         obj_append_child(obj, iobj);
206         abobj_set_item_name(iobj, obj_get_module(obj), obj_get_name(obj), items[i]);
207         obj_set_label(iobj, items[i]);
208         obj_set_is_initially_selected(iobj, False);
209     }
210     obj_set_attachment(obj, AB_CP_NORTH, AB_ATTACH_POINT, NULL, obj->y);
211     obj_set_attachment(obj, AB_CP_WEST,  AB_ATTACH_POINT, NULL, obj->x);
212
213     return OK;
214
215 }
216
217
218 static Widget
219 list_prop_init(
220     Widget    parent,
221     AB_PROP_TYPE type
222 )
223 {
224     DtbListPropDialogInfoRec    rev_list_prop_dialog; /* Revolving Props */
225     DtbListPropDialogInfo       cgen = &dtb_list_prop_dialog; /* Codegen structure */
226     DtbRevolvPropDialogInfo     rpd = &(dtb_revolv_prop_dialog);
227     PropListSettingsRec         *pls = &(prop_list_settings_rec[type]);
228     Widget                      item[8];
229     int                         item_val[8];
230     Widget                      item2[8];
231     int                         item2_val[8];
232     int                         n, j;
233     int                         i;
234
235     if (type == AB_PROP_REVOLVING)
236     {
237         /* Cloning Trick:
238          * Only the Attributes ControlPanel needs to be created within
239          * the existing Revolving Prop dialog, so fill out all other
240          * fields with the Revolving Prop dialog equivelents, so the
241          * dtb initialize proc will skip those non-NULL fields...
242          */
243         dtbListPropDialogInfo_clear(&rev_list_prop_dialog);
244
245         cgen = &(rev_list_prop_dialog);
246         cgen->prop_dialog = rpd->prop_dialog;
247         cgen->prop_dialog_shellform = rpd->prop_dialog_shellform;
248         cgen->prop_dialog_panedwin = rpd->prop_dialog_panedwin;
249         cgen->prop_dialog_form = rpd->prop_dialog_form;
250         cgen->objlist_panel = rpd->objlist_panel;
251         cgen->objlist_label = rpd->objlist_label2;
252         cgen->objlist_scrolledwin = rpd->objlist_scrolledwin;
253         cgen->objlist = rpd->objlist;
254         cgen->attrs_ctrlpanel_frame = rpd->attrs_ctrlpanel_frame;
255         cgen->activate_panel = rpd->activate_panel;
256         cgen->apply_button = rpd->apply_button;
257         cgen->ok_button = rpd->ok_button;
258         cgen->cancel_button = rpd->cancel_button;
259         cgen->reset_button = rpd->reset_button;
260         cgen->help_button = rpd->help_button;
261
262         /*
263          * Get notification of object destruction!
264          */
265         prop_list_install_obj_destroy_CB();
266
267     }
268     else /* AB_PROP_FIXED - create entire dialog*/
269         cgen = &dtb_list_prop_dialog;
270
271     if (dtb_list_prop_dialog_initialize(cgen, parent) == 0)
272     {
273         pls->prop_sheet = cgen->attrs_ctrlpanel;
274         pls->current_obj = NULL;
275
276         if (type == AB_PROP_REVOLVING)
277                 XtVaSetValues(parent,
278                         XmNuserData, pls->current_obj,
279                         NULL);
280
281         /* Dialog/Object List */
282         if (type == AB_PROP_FIXED)
283         {
284             prop_fixed_dialog_init(ab_list_palitem,
285                         cgen->prop_dialog_shellform, cgen->objlist);
286             prop_activate_panel_init(type, ab_list_palitem,
287                         cgen->ok_button, cgen->apply_button,
288                         cgen->reset_button, cgen->cancel_button,
289                         cgen->help_button);
290         }
291
292         /* Alternate Editor Buttons */
293         prop_editors_panel_init(type, ab_list_palitem,
294             cgen->attach_button, cgen->conn_button, cgen->helptxt_button);
295
296         /*
297           * Prop Sheet Settings....
298          */
299
300         /* Name */
301         prop_field_init(&(pls->name), cgen->name_field_label,
302                 cgen->name_field, cgen->name_cb);
303
304         /* Label, Type, Position */
305         n = 0;
306         item[n] = cgen->labeltype_rbox_items.String_item;
307         item_val[n] = AB_LABEL_STRING; n++;
308         item[n] = cgen->labeltype_rbox_items.Graphic_item;
309         item_val[n] = AB_LABEL_GLYPH; n++;
310         prop_options_init(&(pls->label_type), cgen->labeltype_rbox_label,
311                 cgen->labeltype_rbox, cgen->labeltype_rbox_menu,
312                 n, item, (XtPointer*)item_val,
313                 cgen->labeltype_cb);
314
315         prop_field_init(&(pls->label), cgen->label_field_label,
316                 cgen->label_field, cgen->label_cb);
317
318         prop_label_field_init(&(pls->label), cgen->graphic_hint, item, n);
319
320         n = 0;
321         item[n] = cgen->labelpos_rbox_items.Above_item;
322         item_val[n] = AB_CP_NORTH; n++;
323         item[n] = cgen->labelpos_rbox_items.Left_item;
324         item_val[n] = AB_CP_WEST; n++;
325         prop_options_init(&(pls->label_pos), cgen->labelpos_rbox_label,
326                 cgen->labelpos_rbox, cgen->labelpos_rbox_menu,
327                 n, item, (XtPointer*)item_val,
328                 cgen->labeltype_cb);
329
330         /* Selection Mode */
331         n = 0;
332         item[n] = cgen->selmode_rbox_items.Single_Select_item;
333         item_val[n] = AB_SELECT_SINGLE; n++;
334         item[n] = cgen->selmode_rbox_items.Browse_Select_item;
335         item_val[n] = AB_SELECT_BROWSE; n++;
336         item[n] = cgen->selmode_rbox_items.Multiple_Select_item;
337         item_val[n] = AB_SELECT_MULTIPLE; n++;
338         item[n] = cgen->selmode_rbox_items.Browse_Multiple_Select_item;
339         item_val[n] = AB_SELECT_BROWSE_MULTIPLE; n++;
340         prop_options_init(&(pls->sel_mode), cgen->selmode_rbox_label,
341                                 cgen->selmode_rbox, cgen->selmode_rbox_menu,
342                                 n, item, (XtPointer*)item_val,
343                                 cgen->selmode_cb);
344
345         /* Position */
346         prop_geomfield_init(&(pls->pos), cgen->pos_label,
347                             cgen->x_field_label, cgen->x_field,
348                             cgen->y_field_label, cgen->y_field,
349                             NULL, NULL, NULL, NULL,
350                             cgen->pos_cb);
351
352         /* Width */
353         n = 0;
354         item[n] = cgen->wpolicy_rbox_items.Longest_Item_item;
355         item_val[n] = SIZE_OF_CONTENTS_KEY; n++;
356         item[n] = cgen->wpolicy_rbox_items.Fixed_item;
357         item_val[n] = SIZE_FIXED_KEY; n++;
358         prop_radiobox_init(&(pls->wth_policy), cgen->wpolicy_rbox_label,
359                 cgen->wpolicy_rbox, n, item, (XtPointer*)item_val,
360                 cgen->wpolicy_cb);
361
362         for(i=0; i < n; i++)
363             XtAddCallback(item[i], XmNvalueChangedCallback,
364                         (XtCallbackProc)prop_size_policyCB, (XtPointer)&(pls->wth));
365
366         prop_geomfield_init(&(pls->wth), cgen->wpolicy_rbox_label,
367                             NULL, NULL, NULL, NULL,
368                             cgen->width_field_label, cgen->width_field,
369                             NULL, NULL,
370                             cgen->wpolicy_cb);
371
372         /* Height */
373         prop_geomfield_init(&(pls->hgt), cgen->hgt_opmenu_label,
374                             NULL, NULL, NULL, NULL,
375                             NULL, NULL,
376                             cgen->height_field_label, cgen->height_field,
377                             cgen->hgt_cb);
378
379         n = 0;
380         item[n] = cgen->hgt_opmenu_items.Lines_item;
381         item_val[n] = SIZE_IN_CHARS_KEY; n++;
382         item[n] = cgen->hgt_opmenu_items.Pixels_item;
383         item_val[n] = SIZE_IN_PIXELS_KEY; n++;
384         prop_options_init(&(pls->hgt_metric), cgen->hgt_opmenu_label,
385                            cgen->hgt_opmenu,
386                            cgen->hgt_opmenu_menu,
387                            n, item, (XtPointer*)item_val,
388                            cgen->hgt_cb);
389
390         /* Initial State */
391         n = 0;
392         item[n] = cgen->istate_ckbox_items.Visible_item;
393         item_val[n] = AB_STATE_VISIBLE; n++;
394         item[n] = cgen->istate_ckbox_items.Active_item;
395         item_val[n] = AB_STATE_ACTIVE; n++;
396         prop_checkbox_init(&(pls->init_state), cgen->istate_ckbox_label,
397                 cgen->istate_ckbox, n, item, item_val,
398                 cgen->istate_cb);
399
400         /* Color */
401         prop_colorfield_init(&(pls->bg_color), cgen->bg_mbutton,
402                 cgen->bg_mbutton_bg_mbutton_menu_items.None_item,
403                 cgen->bg_mbutton_bg_mbutton_menu_items.Color_Chooser_item,
404                 cgen->bg_swatch, cgen->bg_field, cgen->bg_cb);
405
406         prop_colorfield_init(&(pls->fg_color), cgen->fg_mbutton,
407                 cgen->fg_mbutton_fg_mbutton_menu_items.None_item,
408                 cgen->fg_mbutton_fg_mbutton_menu_items.Color_Chooser_item,
409                 cgen->fg_swatch, cgen->fg_field, cgen->fg_cb);
410
411         /* Menu Title */
412         prop_field_init(&(pls->menu_title), cgen->menutitle_field_label,
413                             cgen->menutitle_field, cgen->menutitle_cb);
414
415         /* Menu Name Setting */
416         prop_menuname_init(&(pls->menuname), type, cgen->menu_label,
417                         cgen->menu_mbutton, cgen->menu_field,
418                         cgen->name_field, cgen->menu_cb,
419                         &(pls->menu_title),
420                         &(pls->current_obj), True);
421
422         /* Item Editor....*/
423
424         /* Item Label */
425         prop_field_init(&(pls->item_label), cgen->itemlabel_label,
426                 cgen->itemlabel_field, cgen->itemlist_cb);
427
428         /* Item State */
429         n = 0;
430         item[n] = cgen->itemstate_ckbox_items.Selected_item;
431         item_val[n] = AB_STATE_SELECTED; n++;
432         prop_checkbox_init(&(pls->item_state), NULL,
433                 cgen->itemstate_ckbox, n, item, item_val,
434                 cgen->itemlist_cb);
435
436         /* Store Items->Insert menu items in array */
437         n = 0;
438         item[n] = cgen->item_edit_mbutton_editmenu_items.Add_Before_item;
439         item_val[n] = INSERT_BEFORE; n++;
440         item[n] = cgen->item_edit_mbutton_editmenu_items.Add_After_item;
441         item_val[n] = INSERT_AFTER; n++;
442
443         /* Store Items->Edit menu_items.items in array */
444         j = 0;
445         item2[j] = cgen->item_edit_mbutton_editmenu_items.Cut_item;
446         item2_val[j] = AB_EDIT_CUT; j++;
447         item2[j] = cgen->item_edit_mbutton_editmenu_items.Copy_item;
448         item2_val[j] = AB_EDIT_COPY; j++;
449         item2[j] = cgen->item_edit_mbutton_editmenu_items.Paste_item;
450         item2_val[j] = AB_EDIT_PASTE; j++;
451         item2[j] = cgen->item_edit_mbutton_editmenu_items.Delete_item;
452         item2_val[j] = AB_EDIT_DELETE; j++;
453         item2[j] = cgen->item_edit_mbutton_editmenu_items.Change_item;
454         item2_val[j] = EDIT_CHANGE; j++;
455
456         /* Hook up Item Editing mechanism to Item List */
457         prop_item_editor_init(&(pls->items), AB_ITEM_FOR_LIST,
458                 cgen->itemlist, cgen->itemlist_cb,
459                 cgen->item_add_button,
460                 n, item, item_val, /* Insert */
461                 j, item2, item2_val,/* Edit */
462                 &(pls->item_label), NULL/*label_type*/, NULL/*graphic_hint*/,
463                 NULL/*mnemonic*/, NULL/*accel*/, NULL/*line_style*/,
464                 &(pls->item_state), NULL/*submenu*/,
465                 &(pls->current_obj));
466
467         prop_changebars_cleared(pls->prop_sheet);
468
469         return (cgen->prop_dialog_shellform);
470     }
471     else
472         return NULL;
473
474 }
475
476 static int
477 list_prop_activate(
478     AB_PROP_TYPE type,
479     BOOL         active
480 )
481 {
482     ui_set_active(prop_list_settings_rec[type].prop_sheet, active);
483
484     return OK;
485
486 }
487
488 static int
489 list_prop_clear(
490     AB_PROP_TYPE type
491 )
492 {
493     PropListSettingsRec *pls = &(prop_list_settings_rec[type]);
494
495     if (pls->current_obj == NULL)
496         return OK;
497
498     /* Clear Name */
499     prop_field_set_value(&(pls->name), "", False);
500
501     /* Clear Label Type/Position */
502     prop_options_set_value(&(pls->label_type), (XtPointer)AB_LABEL_STRING, False);
503     prop_options_set_value(&(pls->label_pos), (XtPointer)AB_CP_WEST, False);
504
505     /* Clear Label */
506     ui_set_label_string(pls->label.label, "Label:");
507     prop_field_set_value(&(pls->label), "", False);
508
509     /* Clear Selection Mode */
510     prop_options_set_value(&(pls->sel_mode), (XtPointer)AB_SELECT_SINGLE, False);
511
512     /* Clear Position */
513     prop_geomfield_clear(&(pls->pos), GEOM_X);
514     prop_geomfield_clear(&(pls->pos), GEOM_Y);
515
516     /* Clear Width */
517     prop_radiobox_set_value(&(pls->wth_policy),
518                             (XtPointer)SIZE_FIXED_KEY, False);
519     prop_geomfield_clear(&(pls->wth), GEOM_WIDTH);
520
521     /* Clear Height */
522     prop_geomfield_clear(&(pls->hgt), GEOM_HEIGHT);
523
524     /* Clear Initial State */
525     prop_checkbox_set_value(&(pls->init_state), AB_STATE_VISIBLE, True, False);
526     prop_checkbox_set_value(&(pls->init_state), AB_STATE_ACTIVE, True, False);
527
528     /* Clear Color */
529     prop_colorfield_set_value(&(pls->bg_color), "", False);
530     prop_colorfield_set_value(&(pls->fg_color), "", False);
531
532     /* Clear Menu Name/Title */
533     prop_menuname_set_value(&(pls->menuname), "", False);
534     prop_field_set_value(&(pls->menu_title), "", False);
535
536     /* Clear Items */
537     prop_item_editor_clear(&(pls->items));
538
539     pls->current_obj = NULL;
540
541     turnoff_changebars(type);
542
543     return OK;
544 }
545
546
547 static int
548 list_prop_load(
549     ABObjPtr     obj,
550     AB_PROP_TYPE type,
551     unsigned long loadkey
552 )
553 {
554     PropListSettingsRec *pls = &(prop_list_settings_rec[type]);
555     int                 height;
556     BOOL                load_all = (loadkey & LoadAll);
557     BOOL                editable;
558
559     if (obj == NULL)
560     {
561         if (pls->current_obj != NULL)
562             obj = pls->current_obj;
563         else
564             return ERROR;
565     }
566     else if (!obj_is_list(obj))
567         return ERROR;
568     else
569         pls->current_obj = obj;
570
571     /* Load Name */
572     if (load_all || loadkey & LoadName)
573         prop_field_set_value(&(pls->name), obj_get_name(obj), False);
574
575     if (load_all)
576     {
577         /* Load Label Type/Position */
578         prop_options_set_value(&(pls->label_type), (XtPointer)obj->label_type, False);
579         prop_options_set_value(&(pls->label_pos), (XtPointer)obj_get_label_position(obj), False);
580
581         /* Load Label */
582         prop_setup_label_field(&(pls->label), NULL,
583                                 obj->label_type, obj_get_label(obj), AB_LINE_UNDEF);
584
585         /* Load Selection Mode */
586         prop_options_set_value(&(pls->sel_mode),
587                 (XtPointer)((AB_SELECT_TYPE)obj_get_selection_mode(obj)), False);
588
589         /* Load Initial State */
590         prop_checkbox_set_value(&(pls->init_state), AB_STATE_VISIBLE,
591                 obj_is_initially_visible(obj), False);
592         prop_checkbox_set_value(&(pls->init_state), AB_STATE_ACTIVE,
593                 obj_is_initially_active(obj), False);
594
595         /* Load Color */
596         prop_colorfield_set_value(&(pls->bg_color), obj_get_bg_color(obj), False);
597         prop_colorfield_set_value(&(pls->fg_color), obj_get_fg_color(obj), False);
598
599         /* Load Menu Name/Title */
600         prop_menuname_set_value(&(pls->menuname), obj_get_menu_name(obj), False);
601         prop_field_set_value(&(pls->menu_title), obj_get_menu_title(obj), False);
602
603         /* Load Items */
604         prop_item_editor_load(&(pls->items), obj);
605
606         turnoff_changebars(type);
607     }
608
609     /* Load Position */
610     if (load_all || loadkey & LoadPosition)
611         prop_load_obj_position(obj, &(pls->pos));
612
613     /* Load Size */
614     if (load_all || loadkey & LoadSize)
615     {
616         /* Load Width */
617         editable = abobj_width_resizable(obj);
618         prop_radiobox_set_value(&(pls->wth_policy), editable?
619                                 (XtPointer)SIZE_FIXED_KEY :
620                                 (XtPointer)SIZE_OF_CONTENTS_KEY, False);
621
622         ui_set_active(pls->wth.w_field, editable);
623         ui_set_active(pls->wth.w_label, editable);
624
625         prop_geomfield_set_value(&(pls->wth), GEOM_WIDTH,
626                 abobj_get_comp_width(obj), False);
627
628         /* Load Height */
629         if (obj_get_num_rows(obj) == -1) /* Size in Pixels */
630         {
631             prop_options_set_value(&(pls->hgt_metric), (XtPointer)SIZE_IN_PIXELS_KEY, False);
632             height = abobj_get_comp_height(obj);
633         }
634         else /* Size in Chars */
635         {
636             prop_options_set_value(&(pls->hgt_metric), (XtPointer)SIZE_IN_CHARS_KEY, False);
637             height = obj_get_num_rows(obj);
638         }
639         prop_geomfield_set_value(&(pls->hgt), GEOM_HEIGHT, height, False);
640     }
641
642     return OK;
643
644 }
645
646 static int
647 list_prop_apply(
648     AB_PROP_TYPE   type
649 )
650 {
651     PropListSettingsRec         *pls = &(prop_list_settings_rec[type]);
652     ABObj                       szObj;
653     STRING                      value;
654     int                         width_policy, metric, new_w, new_h;
655     BOOL                        size_chg = False;
656     BOOL                        reset_bg = False;
657     BOOL                        reset_fg = False;
658
659     if (!verify_props(type))
660         return ERROR;
661
662     if (prop_changed(pls->name.changebar))
663     {
664         value = prop_field_get_value(&(pls->name));
665         abobj_set_name(pls->current_obj, value);
666         util_free(value);
667     }
668     if (prop_changed(pls->label.changebar) ||
669         prop_changed(pls->label_type.changebar))
670     {
671         value = prop_field_get_value(&(pls->label));
672
673         abobj_set_label(pls->current_obj,
674             (AB_LABEL_TYPE)prop_options_get_value(&(pls->label_type)),
675                         value);
676         util_free(value);
677
678         abobj_set_label_position(pls->current_obj,
679                 (AB_COMPASS_POINT)prop_options_get_value(&(pls->label_pos)));
680
681         size_chg = True;
682     }
683     if (prop_changed(pls->sel_mode.changebar))
684     {
685         abobj_set_selection_mode(pls->current_obj,
686             (AB_SELECT_TYPE)prop_options_get_value(&(pls->sel_mode)));
687     }
688     if (prop_changed(pls->pos.changebar))
689     {
690         if (abobj_is_movable(pls->current_obj))
691             abobj_set_xy(pls->current_obj,
692                 prop_geomfield_get_value(&(pls->pos), GEOM_X),
693                 prop_geomfield_get_value(&(pls->pos), GEOM_Y));
694     }
695     if (prop_changed(pls->wth_policy.changebar))
696     {
697         width_policy = prop_radiobox_get_value(&(pls->wth_policy));
698         abobj_set_size_policy(pls->current_obj, width_policy == SIZE_FIXED_KEY);
699
700         if (width_policy == SIZE_FIXED_KEY)
701         {
702             new_w = prop_geomfield_get_value(&(pls->wth), GEOM_WIDTH);
703             abobj_set_pixel_width(pls->current_obj, new_w, 0);
704         }
705         size_chg = True;
706     }
707     if (prop_changed(pls->hgt.changebar))
708     {
709         metric = (int)prop_options_get_value(&(pls->hgt_metric));
710         new_h = prop_geomfield_get_value(&(pls->hgt), GEOM_HEIGHT);
711
712         abobj_set_num_rows(pls->current_obj,
713                 metric == SIZE_IN_CHARS_KEY? new_h : -1);
714
715         abobj_set_pixel_height(pls->current_obj,
716                 metric == SIZE_IN_PIXELS_KEY? new_h : -1, 0);
717
718         size_chg = True;
719     }
720     if (prop_changed(pls->init_state.changebar))
721     {
722         abobj_set_visible(pls->current_obj,
723                 prop_checkbox_get_value(&(pls->init_state), AB_STATE_VISIBLE));
724         abobj_set_active(pls->current_obj,
725                 prop_checkbox_get_value(&(pls->init_state), AB_STATE_ACTIVE));
726     }
727     if (prop_changed(pls->fg_color.changebar))
728     {
729         value = prop_colorfield_get_value(&(pls->fg_color));
730         abobj_set_foreground_color(pls->current_obj, value);
731         if (util_strempty(value))
732             reset_fg = True;
733         util_free(value);
734         prop_colorfield_set_value(&(pls->fg_color),
735                 obj_get_fg_color(pls->current_obj), False);
736     }
737     if (prop_changed(pls->bg_color.changebar))
738     {
739         value = prop_colorfield_get_value(&(pls->bg_color));
740         abobj_set_background_color(pls->current_obj, value);
741         if (util_strempty(value))
742             reset_bg = True;
743         util_free(value);
744         prop_colorfield_set_value(&(pls->bg_color),
745                 obj_get_bg_color(pls->current_obj), False);
746     }
747     if (prop_changed(pls->menuname.changebar))
748     {
749         value = prop_menuname_get_value(&(pls->menuname));
750         abobj_set_menu_name(pls->current_obj, value);
751         util_free(value);
752         prop_menuname_set_value(&(pls->menuname),
753                 obj_get_menu_name(pls->current_obj), False);
754     }
755     if (prop_changed(pls->menu_title.changebar))
756     {
757         value = prop_field_get_value(&(pls->menu_title));
758         abobj_set_menu_title(pls->current_obj, value);
759         util_free(value);
760     }
761     if (prop_changed(pls->items.changebar))
762     {
763         /* Ensure edits to current item are saved before apply */
764         prop_item_change(&(pls->items), False);
765         prop_item_editor_apply(&(pls->items));
766         size_chg = True;
767     }
768
769     abobj_tree_instantiate_changes(pls->current_obj);
770
771     if (reset_bg || reset_fg) /* Set back to No Color */
772         abobj_reset_colors(pls->current_obj, reset_bg, reset_fg);
773
774     if (size_chg)
775     {
776         /* Need to force XmList to be fixed width, since often it's
777          * finicky and snaps back to the width of the longest item...
778          */
779         if (obj_get_width(pls->current_obj) != -1)
780         {
781             szObj = objxm_comp_get_subobj(pls->current_obj, AB_CFG_SIZE_OBJ);
782             XtVaSetValues(objxm_get_widget(szObj),
783                 XmNwidth, obj_get_width(pls->current_obj),
784                 NULL);
785         }
786         abobj_force_dang_form_resize(pls->current_obj);
787     }
788     turnoff_changebars(type);
789
790     return OK;
791 }
792
793 static BOOL
794 list_prop_pending(
795     AB_PROP_TYPE type
796 )
797 {
798     return(prop_changebars_pending(prop_list_settings_rec[type].prop_sheet));
799 }
800
801 static BOOL
802 verify_props(
803     AB_PROP_TYPE type
804 )
805 {
806     PropListSettingsRec *pls = &(prop_list_settings_rec[type]);
807
808     if (prop_changed(pls->name.changebar) &&
809         !prop_name_ok(pls->current_obj, pls->name.field))
810         return False;
811
812     if ((prop_changed(pls->label_type.changebar) || prop_changed(pls->label.changebar)) &&
813         prop_options_get_value(&(pls->label_type)) == (XtPointer)AB_LABEL_GLYPH &&
814         !prop_graphic_filename_ok(pls->label.field, False))
815         return False;
816
817     if (prop_changed(pls->pos.changebar) &&
818         (!prop_number_ok(pls->pos.x_field, (STRING)XFieldStr, -SHRT_MAX, SHRT_MAX) ||
819          !prop_number_ok(pls->pos.y_field, (STRING)YFieldStr, -SHRT_MAX, SHRT_MAX)))
820         return False;
821
822     if (prop_changed(pls->wth.changebar) &&
823         !prop_number_ok(pls->wth.w_field, (STRING)WFieldStr, 1, SHRT_MAX))
824         return False;
825
826     if (prop_changed(pls->hgt.changebar) &&
827         !prop_number_ok(pls->hgt.h_field, (STRING)HFieldStr, 1, SHRT_MAX))
828         return False;
829
830     if (prop_changed(pls->fg_color.changebar) && !prop_color_ok(pls->fg_color.field))
831         return False;
832
833     if (prop_changed(pls->bg_color.changebar) && !prop_color_ok(pls->bg_color.field))
834         return False;
835
836     if (prop_changed(pls->menuname.changebar) && !prop_obj_name_ok(pls->menuname.field,
837                         obj_get_module(pls->current_obj), AB_TYPE_MENU, "Menu"))
838         return False;
839
840     return True;
841 }
842
843 static void
844 turnoff_changebars(
845     AB_PROP_TYPE type
846 )
847 {
848     PropListSettingsRec *pls = &(prop_list_settings_rec[type]);
849
850     prop_set_changebar(pls->name.changebar,     PROP_CB_OFF);
851     prop_set_changebar(pls->sel_mode.changebar, PROP_CB_OFF);
852     prop_set_changebar(pls->wth_policy.changebar,PROP_CB_OFF);
853     prop_set_changebar(pls->hgt.changebar,       PROP_CB_OFF);
854     prop_set_changebar(pls->pos.changebar,       PROP_CB_OFF);
855     prop_set_changebar(pls->label_type.changebar,PROP_CB_OFF);
856     prop_set_changebar(pls->label.changebar,     PROP_CB_OFF);
857     prop_set_changebar(pls->init_state.changebar,PROP_CB_OFF);
858     prop_set_changebar(pls->bg_color.changebar,  PROP_CB_OFF);
859     prop_set_changebar(pls->fg_color.changebar,  PROP_CB_OFF);
860     prop_set_changebar(pls->menuname.changebar,  PROP_CB_OFF);
861     prop_set_changebar(pls->menu_title.changebar,  PROP_CB_OFF);
862     prop_set_changebar(pls->items.changebar,     PROP_CB_OFF);
863
864     prop_changebars_cleared(pls->prop_sheet);
865
866 }
867
868 /*
869  * Object destroy callback
870  */
871 static int
872 prop_list_install_obj_destroy_CB()
873 {
874     static BOOL callback_installed = False;
875
876     if (callback_installed)
877     {
878         return 0;
879     }
880     obj_add_destroy_callback(prop_list_obj_destroy_CB, "List Props");
881     return 0;
882 }
883
884
885 static int
886 prop_list_obj_destroy_CB(ObjEvDestroyInfo destroyInfo)
887 {
888     int                 i;
889     ABObj               doomedObj = destroyInfo->obj;
890     PropListSettingsRec *pls;
891
892     if (!obj_is_list_item(doomedObj))
893     {
894         return 0;
895     }
896
897     for (i = 0; i < AB_PROP_TYPE_NUM_VALUES; ++i)
898     {
899         pls = &(prop_list_settings_rec[i]);
900
901         if (pls->current_obj == doomedObj)
902             pls->current_obj = NULL;
903         if (pls->items.current_item == doomedObj)
904             pls->items.current_item = NULL;
905         if (pls->items.clipboard_item == doomedObj)
906             pls->items.clipboard_item = NULL;
907     }
908
909     return 0;
910 }
911 static void
912 wth_policyCB(
913     Widget      w,
914     XtPointer   clientdata,
915     XmToggleButtonCallbackStruct *state
916 )
917 {
918     AB_PROP_TYPE                type = (AB_PROP_TYPE)clientdata;
919     PropListSettingsRec         *pls = &(prop_list_settings_rec[type]);
920     XtArgVal                    value;
921
922     /* Width field should ONLY be editable if Size Policy
923      * is "Fixed"
924      */
925     if (state->set)
926     {
927         XtVaGetValues(w, XmNuserData, &value, NULL);
928         ui_field_set_editable(pls->wth.w_field, value == SIZE_FIXED_KEY);
929     }
930 }