Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtappbuilder / src / ab / pal_choice.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  *      $XConsortium: pal_choice.c /main/5 1996/08/08 17:51:22 mustafa $
25  *
26  * @(#)pal_choice.c     1.40 15 Feb 1994      cde_app_builder/src/ab
27  *
28  *      RESTRICTED CONFIDENTIAL INFORMATION:
29  *
30  *      The information in this document is subject to special
31  *      restrictions in a confidential disclosure agreement between
32  *      HP, IBM, Sun, USL, SCO and Univel.  Do not distribute this
33  *      document outside HP, IBM, Sun, USL, SCO, or Univel without
34  *      Sun's specific written approval.  This document and all copies
35  *      and derivative works thereof must be returned or destroyed at
36  *      Sun's request.
37  *
38  *      Copyright 1993 Sun Microsystems, Inc.  All rights reserved.
39  *
40  */
41
42
43 /*
44  * pal_choice.c - Implements Choice object functionality
45  */
46 #include <stdio.h>
47 #include <Xm/Xm.h>
48 #include <ab_private/trav.h>
49 #include <ab_private/pal.h>
50 #include <ab_private/ab.h>
51 #include <ab_private/prop.h>
52 #include <ab_private/obj_notify.h>
53 #include <ab_private/abobj.h> 
54 #include <ab_private/abobj_set.h> 
55 #include <ab_private/abobj_edit.h> 
56 #include <ab_private/ui_util.h>
57 #include "choice_ui.h"
58
59
60 typedef struct  PROP_CHOICE_SETTINGS
61 {
62     Widget                      prop_sheet;
63     PropFieldSettingRec         name;
64     PropOptionsSettingRec       choice_type;
65     PropGeometrySettingRec      pos;
66     PropOptionsSettingRec       label_type;
67     PropFieldSettingRec         label;
68     PropOptionsSettingRec       label_pos;
69     PropRadioSettingRec         row_col;
70     PropFieldSettingRec         row_col_count;
71     PropCheckboxSettingRec      init_state;
72     PropColorSettingRec         bg_color;
73     PropColorSettingRec         fg_color;
74     PropFieldSettingRec         item_label;
75     PropOptionsSettingRec       item_label_type;
76     PropCheckboxSettingRec      item_state;
77     PropItemsSettingRec         items;
78     ABObj                       current_obj;
79 } PropChoiceSettingsRec, *PropChoiceSettings;
80
81 /*************************************************************************
82 **                                                                      **
83 **       Private Function Declarations                                  **
84 **                                                                      **
85 **************************************************************************/
86 /*
87  * Methods
88  */
89 static int      choice_initialize(
90                     ABObj   obj
91                 );
92 static Widget   choice_prop_init(
93                     Widget  parent,
94                     AB_PROP_TYPE type
95                 );
96 static int      choice_prop_activate(
97                     AB_PROP_TYPE type,
98                     BOOL         active
99                 );
100 static int      choice_prop_load(
101                     ABObj        obj,
102                     AB_PROP_TYPE type,
103                     unsigned long loadkey
104                 );
105 static int      choice_prop_clear(
106                     AB_PROP_TYPE type
107                 );
108 static int      choice_prop_apply(
109                     AB_PROP_TYPE type
110                 );
111 static BOOL     choice_prop_pending(
112                     AB_PROP_TYPE type
113                 );
114
115
116 static BOOL     verify_props(
117                     AB_PROP_TYPE type
118                 );
119 static void     turnoff_changebars(
120                     AB_PROP_TYPE type
121                 );
122
123
124 static void     load_item(
125                     ABObj       iobj,
126                     AB_PROP_TYPE type
127                 );
128 static ABObj    init_new_item(
129                     AB_PROP_TYPE type
130                 );
131 static void     change_item(
132                     AB_PROP_TYPE type,
133                     ABObj        iobj
134                 );
135
136 static void     setup_type_settings(
137                     AB_PROP_TYPE        type,
138                     AB_CHOICE_TYPE      choice_type
139                 );
140 /*
141  * Xt Callbacks
142  */
143 static void     typeCB(
144                     Widget      widget,
145                     XtPointer   clientdata,
146                     XtPointer   calldata
147                 );
148 /*
149  * ABObj callbacks
150  */
151 static int      prop_choice_install_obj_destroy_CB(void);
152
153 static int      prop_choice_obj_destroy_CB(
154                     ObjEvDestroyInfo destroyInfo
155                 );
156
157 /*************************************************************************
158 **                                                                      **
159 **       Data                                                            **
160 **                                                                      **
161 **************************************************************************/
162 PalItemInfo choice_palitem_rec = {
163
164     /* type             */  AB_TYPE_CHOICE,
165     /* name             */  "Choice",
166     /* animation pixmaps*/  NULL,
167     /* number of pixmaps*/  0,
168     /* rev_prop_frame   */  NULL,
169     /* fix_prop_dialog  */  NULL,
170     /* initialize       */  choice_initialize,
171     /* is_a_test        */  obj_is_choice,
172     /* prop_initialize  */  choice_prop_init,
173     /* prop_active      */  choice_prop_activate,
174     /* prop_clear       */  choice_prop_clear,
175     /* prop_load        */  choice_prop_load,
176     /* prop_apply       */  choice_prop_apply,
177     /* prop_pending     */  choice_prop_pending
178
179 };
180
181 PalItemInfo *ab_choice_palitem = &choice_palitem_rec;
182 PropChoiceSettingsRec prop_choice_settings_rec[AB_PROP_TYPE_NUM_VALUES];
183
184 /*************************************************************************
185 **                                                                      **
186 **       Function Definitions                                           **
187 **                                                                      **
188 **************************************************************************/
189 static int
190 choice_initialize(
191     ABObj    obj
192 )
193 {
194     AB_CHOICE_TYPE choice_type;
195     ABObj       module = obj_get_module(obj);
196     ABObj       iobj;
197     String  items[2];
198     int         i;
199
200     choice_type = obj->info.choice.type;
201
202     switch(choice_type)
203     {
204         case AB_CHOICE_NONEXCLUSIVE:
205             obj_set_unique_name(obj, "checkbox");
206             obj_set_label(obj, catgets(Dtb_project_catd, 100, 253, "Choice:"));
207             break;
208         case AB_CHOICE_OPTION_MENU:
209             obj_set_unique_name(obj, "optionmenu");
210             obj_set_label(obj, catgets(Dtb_project_catd, 100, 254, "Options:"));
211             break;
212         case AB_CHOICE_EXCLUSIVE: 
213         default:
214             obj_set_unique_name(obj, "radiobox");
215             obj_set_label(obj, catgets(Dtb_project_catd, 100, 253, "Choice:"));
216             break;
217     }
218
219     obj_set_is_initially_visible(obj, True);
220     obj_set_is_initially_active(obj, True);
221
222     if (choice_type == AB_CHOICE_EXCLUSIVE)
223         obj_set_orientation(obj, AB_ORIENT_HORIZONTAL);
224     else
225         obj_set_orientation(obj, AB_ORIENT_VERTICAL);
226
227     obj_set_num_columns(obj, 1);
228
229     /* Add initial items to Choice */
230     items[0] = catgets(Dtb_project_catd, 6, 70, "itemA");
231     items[1] = catgets(Dtb_project_catd, 6, 71, "itemB");
232     for (i=0; i < XtNumber(items); i++)
233     {
234         iobj = obj_create(AB_TYPE_ITEM, NULL);
235         obj_append_child(obj, iobj);
236         obj_set_subtype(iobj, AB_ITEM_FOR_CHOICE);
237         iobj->label_type = AB_LABEL_STRING;
238
239         if (i == 0)
240             obj_set_is_initially_selected(iobj, True);
241         else
242             obj_set_is_initially_selected(iobj, False); 
243
244         obj_set_is_initially_active(iobj, True);
245         abobj_set_item_name(iobj, obj_get_module(obj), obj_get_name(obj), items[i]);
246         obj_set_label(iobj, items[i]);
247     }
248
249     obj_set_attachment(obj, AB_CP_NORTH, AB_ATTACH_POINT, NULL, obj->y);
250     obj_set_attachment(obj, AB_CP_WEST,  AB_ATTACH_POINT, NULL, obj->x);
251
252     return OK;
253
254 }
255
256 static Widget
257 choice_prop_init(
258     Widget    parent,
259     AB_PROP_TYPE type
260 )
261 {
262     DtbChoicePropDialogInfoRec  rev_choice_prop_dialog; /* Revolving Props */
263     DtbChoicePropDialogInfo     cgen; /* Codegen structure */
264     DtbRevolvPropDialogInfo     rpd = &(dtb_revolv_prop_dialog);
265     PropChoiceSettingsRec       *pcs = &(prop_choice_settings_rec[type]);
266     Widget                      item[6];
267     int                         item_val[6];
268     Widget                      item2[6];
269     int                         item2_val[6];
270     int                         n, j;
271     int                         i;
272
273     if (type == AB_PROP_REVOLVING)
274     {
275         /* Cloning Trick:
276          * Only the Attributes ControlPanel needs to be created within
277          * the existing Revolving Prop dialog, so fill out all other
278          * fields with the Revolving Prop dialog equivelents, so the
279          * dtb initialize proc will skip those non-NULL fields...
280          */
281         dtbChoicePropDialogInfo_clear(&rev_choice_prop_dialog);
282
283         cgen = &(rev_choice_prop_dialog);
284         cgen->prop_dialog = rpd->prop_dialog;
285         cgen->prop_dialog_shellform = rpd->prop_dialog_shellform; 
286         cgen->prop_dialog_panedwin = rpd->prop_dialog_panedwin;
287         cgen->prop_dialog_form = rpd->prop_dialog_form;
288         cgen->objlist_panel = rpd->objlist_panel;
289         cgen->objlist_label = rpd->objlist_label2;
290         cgen->objlist_scrolledwin = rpd->objlist_scrolledwin;
291         cgen->objlist = rpd->objlist;
292         cgen->attrs_ctrlpanel_frame = rpd->attrs_ctrlpanel_frame;
293         cgen->activate_panel = rpd->activate_panel;
294         cgen->apply_button = rpd->apply_button; 
295         cgen->ok_button = rpd->ok_button;
296         cgen->cancel_button = rpd->cancel_button;
297         cgen->reset_button = rpd->reset_button; 
298         cgen->help_button = rpd->help_button; 
299
300         /*
301          * Get notification of object destruction!
302          */  
303         prop_choice_install_obj_destroy_CB();
304
305     }
306     else /* AB_PROP_FIXED */
307         cgen = &dtb_choice_prop_dialog; 
308
309     if (dtb_choice_prop_dialog_initialize(cgen, parent) == 0)
310     {
311         pcs->prop_sheet = cgen->attrs_ctrlpanel;
312         pcs->current_obj = NULL;
313
314         if (type == AB_PROP_REVOLVING)
315                 XtVaSetValues(parent,
316                         XmNuserData, pcs->current_obj,
317                         NULL);
318
319         /* Dialog/Object List */
320         if (type == AB_PROP_FIXED)
321         {
322             prop_fixed_dialog_init(ab_choice_palitem,
323                         cgen->prop_dialog_shellform, cgen->objlist);
324             prop_activate_panel_init(type, ab_choice_palitem, 
325                         cgen->ok_button, cgen->apply_button, 
326                         cgen->reset_button, cgen->cancel_button,
327                         cgen->help_button);
328         }
329         /* Alternate Editor Buttons */
330         prop_editors_panel_init(type, ab_choice_palitem,
331             cgen->attach_button, cgen->conn_button, cgen->helptxt_button);
332
333         /*
334           * Prop Sheet Settings....
335          */
336
337         /* Name */
338         prop_field_init(&(pcs->name), cgen->name_field_label,
339                 cgen->name_field, cgen->name_cb);
340
341         /* Label, Type, Position */
342         n = 0;
343         item[n] = cgen->labeltype_rbox_items.String_item;
344         item_val[n] = AB_LABEL_STRING; n++;
345         item[n] = cgen->labeltype_rbox_items.Graphic_item;
346         item_val[n] = AB_LABEL_GLYPH; n++;
347         prop_options_init(&(pcs->label_type), cgen->labeltype_rbox_label,
348                 cgen->labeltype_rbox, cgen->labeltype_rbox_menu,
349                 n, item, (XtPointer*)item_val, cgen->labeltype_cb);
350
351         prop_field_init(&(pcs->label), cgen->label_field_label, 
352                 cgen->label_field, cgen->label_cb);
353
354         prop_label_field_init(&(pcs->label), cgen->graphic_hint, item, n);
355
356         n = 0;
357         item[n] = cgen->labelpos_rbox_items.Above_item;
358         item_val[n] = AB_CP_NORTH; n++;
359         item[n] = cgen->labelpos_rbox_items.Left_item;
360         item_val[n] = AB_CP_WEST; n++;
361         prop_options_init(&(pcs->label_pos), cgen->labelpos_rbox_label,
362                 cgen->labelpos_rbox, cgen->labelpos_rbox_menu,
363                 n, item, (XtPointer*)item_val, cgen->labeltype_cb);
364
365
366         /* Choice Type */
367         n = 0;
368         item[n] = cgen->choicetype_rbox_items.Radio_Box_item;
369         item_val[n] = AB_CHOICE_EXCLUSIVE; n++;
370         item[n] = cgen->choicetype_rbox_items.Check_Box_item;
371         item_val[n] = AB_CHOICE_NONEXCLUSIVE; n++;
372         item[n] = cgen->choicetype_rbox_items.Option_Menu_item;
373         item_val[n] = AB_CHOICE_OPTION_MENU; n++;
374         prop_options_init(&(pcs->choice_type), cgen->choicetype_rbox_label,
375                         cgen->choicetype_rbox, cgen->choicetype_rbox_menu,
376                         n, item, (XtPointer*)item_val,
377                         cgen->choicetype_cb);
378
379         for (i=0; i < n; i++)
380             XtAddCallback(item[i], XmNactivateCallback, typeCB, (XtPointer)type);
381
382         /* Rows/Columns */
383         n = 0;
384         item[n] = cgen->layout_rbox_items.Columns_item;
385         item_val[n] = AB_ORIENT_VERTICAL; n++;
386         item[n] = cgen->layout_rbox_items.Rows_item;
387         item_val[n] = AB_ORIENT_HORIZONTAL; n++;
388         prop_radiobox_init(&(pcs->row_col), cgen->layout_rbox_label,
389                 cgen->layout_rbox,
390                 n, item, (XtPointer*)item_val,
391                 cgen->layout_cb);
392
393         prop_field_init(&(pcs->row_col_count), NULL,
394                 cgen->layout_field, cgen->layout_cb);
395
396         /* Position */
397         prop_geomfield_init(&(pcs->pos), cgen->pos_label,
398                 cgen->x_field_label, cgen->x_field,
399                 cgen->y_field_label, cgen->y_field,
400                 NULL, NULL, NULL, NULL,
401                 cgen->pos_cb);
402
403         /* Initial State */
404         n = 0;
405         item[n] = cgen->istate_ckbox_items.Visible_item;
406         item_val[n] = AB_STATE_VISIBLE; n++;
407         item[n] = cgen->istate_ckbox_items.Active_item;
408         item_val[n] = AB_STATE_ACTIVE; n++;
409         prop_checkbox_init(&(pcs->init_state), cgen->istate_ckbox_label,
410                 cgen->istate_ckbox, n, item, item_val,
411                 cgen->istate_cb);
412
413         /* Color */
414         prop_colorfield_init(&(pcs->bg_color), cgen->bg_mbutton, 
415                 cgen->bg_mbutton_bg_mbutton_menu_items.None_item,
416                 cgen->bg_mbutton_bg_mbutton_menu_items.Color_Chooser_item,
417                 cgen->bg_swatch, cgen->bg_field, cgen->bg_cb);
418
419         prop_colorfield_init(&(pcs->fg_color), cgen->fg_mbutton,
420                 cgen->fg_mbutton_fg_mbutton_menu_items.None_item,  
421                 cgen->fg_mbutton_fg_mbutton_menu_items.Color_Chooser_item, 
422                 cgen->fg_swatch, cgen->fg_field, cgen->fg_cb); 
423
424         /* Item Editor....*/
425
426         /* Item Label Type */
427         n = 0;
428         item[n] = cgen->itemlabel_opmenu_items.String_item;
429         item_val[n] = AB_LABEL_STRING; n++;
430         item[n] = cgen->itemlabel_opmenu_items.Graphic_item;
431         item_val[n] = AB_LABEL_GLYPH; n++;
432         prop_options_init(&(pcs->item_label_type), cgen->itemlabel_type_label,
433                 cgen->itemlabel_opmenu, cgen->itemlabel_opmenu_menu,
434                 n, item, (XtPointer*)item_val, cgen->itemlist_cb);
435
436         for(i=0; i < n; i++)
437             XtAddCallback(item[i], XmNactivateCallback,
438                   (XtCallbackProc)prop_item_labeltypeCB, (XtPointer)&(pcs->items));
439
440         /* Item Label */
441         prop_field_init(&(pcs->item_label), cgen->itemlabel_label,
442                 cgen->itemlabel_field, cgen->itemlist_cb);
443
444         /* Item State */
445         n = 0;
446         item[n] = cgen->itemstate_ckbox_items.Active_item;
447         item_val[n] = AB_STATE_ACTIVE; n++;
448         item[n] = cgen->itemstate_ckbox_items.Selected_item;
449         item_val[n] = AB_STATE_SELECTED; n++;
450         prop_checkbox_init(&(pcs->item_state), cgen->itemstate_label,
451                 cgen->itemstate_ckbox, n, item, item_val,
452                 cgen->itemlist_cb);
453
454         /* Store Items->Add menu items in array */
455         n = 0;
456         item[n] = cgen->item_edit_mbutton_editmenu_items.Add_Before_item;
457         item_val[n] = INSERT_BEFORE; n++;
458         item[n] = cgen->item_edit_mbutton_editmenu_items.Add_After_item;
459         item_val[n] = INSERT_AFTER; n++;
460
461         /* Store Items->Edit menu items in array */
462         j = 0;
463         item2[j] = cgen->item_edit_mbutton_editmenu_items.Cut_item;
464         item2_val[j] = AB_EDIT_CUT; j++;
465         item2[j] = cgen->item_edit_mbutton_editmenu_items.Copy_item; 
466         item2_val[j] = AB_EDIT_COPY; j++; 
467         item2[j] = cgen->item_edit_mbutton_editmenu_items.Paste_item; 
468         item2_val[j] = AB_EDIT_PASTE; j++; 
469         item2[j] = cgen->item_edit_mbutton_editmenu_items.Delete_item;  
470         item2_val[j] = AB_EDIT_DELETE; j++;  
471         item2[j] = cgen->item_edit_mbutton_editmenu_items.Change_item;
472         item2_val[j] = EDIT_CHANGE; j++;
473
474         /* Hook up Item Editing mechanism to Item List */
475         prop_item_editor_init(&(pcs->items), AB_ITEM_FOR_CHOICE,
476                 cgen->itemlist, cgen->itemlist_cb, 
477                 cgen->item_add_button,
478                 n, item, item_val, /* Insert */
479                 j, item2, item2_val,/* Edit */
480                 &(pcs->item_label), &(pcs->item_label_type), 
481                 cgen->graphic_hint3,
482                 NULL, NULL, NULL, &(pcs->item_state), NULL,
483                 &(pcs->current_obj));
484
485         prop_changebars_cleared(pcs->prop_sheet);
486
487         return (cgen->prop_dialog_shellform);
488     }
489     else
490         return NULL;
491
492 }
493 static int
494 choice_prop_activate(
495     AB_PROP_TYPE type,
496     BOOL         active
497 )
498 {
499     ui_set_active(prop_choice_settings_rec[type].prop_sheet, active);
500
501     return OK;
502 }
503
504 static int
505 choice_prop_clear(
506     AB_PROP_TYPE type
507 )
508 {
509     PropChoiceSettingsRec       *pcs = &(prop_choice_settings_rec[type]);
510
511     if (pcs->current_obj == NULL)
512         return OK;
513
514     /* Clear Name */
515     prop_field_set_value(&(pcs->name), "", False);
516
517     /* Clear Label Type/Position */
518     prop_options_set_value(&(pcs->label_type), (XtPointer)AB_LABEL_STRING, False);
519     prop_options_set_value(&(pcs->label_pos), (XtPointer)AB_CP_WEST, False);
520
521     /* Clear Label */
522     ui_set_label_string(pcs->label.label, "Label:");
523     prop_field_set_value(&(pcs->label), "", False);
524
525     /* Clear Choice Type*/ 
526     prop_options_set_value(&(pcs->choice_type), (XtPointer)AB_CHOICE_EXCLUSIVE, False); 
527
528     /* Clear Row/Columns */
529     prop_radiobox_set_value(&(pcs->row_col), (XtPointer)AB_ORIENT_HORIZONTAL, False); 
530     prop_field_set_value(&(pcs->row_col_count), "", False);
531
532     /* Clear Position */
533     prop_geomfield_clear(&(pcs->pos), GEOM_X);
534     prop_geomfield_clear(&(pcs->pos), GEOM_Y);
535
536     /* Clear Initial State */
537     prop_checkbox_set_value(&(pcs->init_state), AB_STATE_VISIBLE, True, False);
538     prop_checkbox_set_value(&(pcs->init_state), AB_STATE_ACTIVE, True, False);
539
540     /* Clear Color */
541     prop_colorfield_set_value(&(pcs->bg_color), "", False);
542     prop_colorfield_set_value(&(pcs->fg_color), "", False);
543
544     /* Clear Items */
545     prop_item_editor_clear(&(pcs->items));
546
547     pcs->current_obj = NULL;
548
549     turnoff_changebars(type);
550
551     return OK;
552 }
553
554
555 static int
556 choice_prop_load(
557     ABObjPtr     obj,
558     AB_PROP_TYPE type,
559     unsigned long loadkey
560 )
561 {
562     PropChoiceSettingsRec       *pcs = &(prop_choice_settings_rec[type]);
563     AB_CHOICE_TYPE              ctype;
564     BOOL                        load_all = (loadkey & LoadAll);
565  
566     if (obj == NULL)
567     {
568         if (pcs->current_obj != NULL)
569             obj = pcs->current_obj;
570         else
571             return ERROR;
572     }
573     else if (!obj_is_choice(obj))
574         return ERROR;
575     else
576         pcs->current_obj = obj;
577
578     /* Load Name */
579     if (load_all || loadkey & LoadName)
580         prop_field_set_value(&(pcs->name), obj_get_name(obj), False);
581
582     if (load_all)
583     {
584         /* Load Label Type/Position */
585         prop_options_set_value(&(pcs->label_type), (XtPointer)obj->label_type, False);
586         prop_options_set_value(&(pcs->label_pos), (XtPointer)obj_get_label_position(obj), False);
587
588         /* Load Label */
589         prop_setup_label_field(&(pcs->label), NULL,
590                                 obj->label_type, obj_get_label(obj), AB_LINE_UNDEF);
591         /* Load Choice Type */
592         ctype = obj_get_choice_type(obj);
593         prop_options_set_value(&(pcs->choice_type), (XtPointer)ctype, False);
594         setup_type_settings(type, ctype);
595
596         /* Load Row/Column*/
597         prop_radiobox_set_value(&(pcs->row_col), (XtPointer)obj_get_orientation(obj), False);
598         prop_field_set_numeric_value(&(pcs->row_col_count), obj_get_num_columns(obj), False);
599
600         /* Load Initial State */
601         prop_checkbox_set_value(&(pcs->init_state), AB_STATE_VISIBLE,
602                                 obj_is_initially_visible(obj), False);
603         prop_checkbox_set_value(&(pcs->init_state), AB_STATE_ACTIVE,
604                                 obj_is_initially_active(obj), False);
605
606         /* Load Color */
607         prop_colorfield_set_value(&(pcs->bg_color), obj_get_bg_color(obj), False);
608         prop_colorfield_set_value(&(pcs->fg_color), obj_get_fg_color(obj), False);
609
610         /* Load Choice Items */
611         prop_item_editor_load(&(pcs->items), obj);
612
613         turnoff_changebars(type);
614     }
615
616     /* Load Position */
617     if (load_all || loadkey & LoadPosition)
618         prop_load_obj_position(obj, &(pcs->pos)); 
619
620     return OK;
621
622 }
623
624 static int
625 choice_prop_apply(
626     AB_PROP_TYPE   type
627 )
628 {
629     PropChoiceSettingsRec *pcs = &(prop_choice_settings_rec[type]);
630     STRING              value;
631     BOOL                size_chg = False;
632     BOOL                reset_bg = False;
633     BOOL                reset_fg = False;
634
635     if (!verify_props(type))
636         return ERROR;
637
638     if (prop_changed(pcs->name.changebar))
639     {
640         value = prop_field_get_value(&(pcs->name)); 
641         abobj_set_name(pcs->current_obj, value);
642         util_free(value);
643     }
644     if (prop_changed(pcs->label.changebar) || 
645         prop_changed(pcs->label_type.changebar))
646     {
647         value = prop_field_get_value(&(pcs->label));
648
649         abobj_set_label(pcs->current_obj,
650             (AB_LABEL_TYPE)prop_options_get_value(&(pcs->label_type)),
651                         value);
652         util_free(value);
653
654         abobj_set_label_position(pcs->current_obj,
655                 (AB_COMPASS_POINT)prop_options_get_value(&(pcs->label_pos)));
656
657         size_chg = True;
658     }
659 /*
660     if (prop_changed(pcs->choice_type.changebar))
661     {
662         abobj_set_choice_type(pcs->current_obj,
663             (AB_CHOICE_TYPE)prop_options_get_value(&(pcs->choice_type)));
664         size_chg = True;
665     }   
666 */
667     if (prop_changed(pcs->row_col.changebar))
668     {
669         int cols;
670         abobj_set_orientation(pcs->current_obj,
671             (AB_ORIENTATION)prop_radiobox_get_value(&(pcs->row_col)));
672         cols = prop_field_get_numeric_value(&(pcs->row_col_count));
673         abobj_set_num_columns(pcs->current_obj, cols);
674         size_chg = True;
675     }
676     if (prop_changed(pcs->pos.changebar))
677     {
678         if (abobj_is_movable(pcs->current_obj))
679             abobj_set_xy(pcs->current_obj,
680                 prop_geomfield_get_value(&(pcs->pos), GEOM_X),
681                 prop_geomfield_get_value(&(pcs->pos), GEOM_Y));
682     }
683     if (prop_changed(pcs->init_state.changebar))
684     {
685         abobj_set_visible(pcs->current_obj, 
686                 prop_checkbox_get_value(&(pcs->init_state), AB_STATE_VISIBLE));
687         abobj_set_active(pcs->current_obj,
688                 prop_checkbox_get_value(&(pcs->init_state), AB_STATE_ACTIVE));
689     }
690     if (prop_changed(pcs->fg_color.changebar))
691     {
692         value = prop_colorfield_get_value(&(pcs->fg_color));  
693         abobj_set_foreground_color(pcs->current_obj, value);
694         if (util_strempty(value))
695             reset_fg = True;
696         util_free(value);
697         prop_colorfield_set_value(&(pcs->fg_color), 
698                 obj_get_fg_color(pcs->current_obj), False);
699     }
700     if (prop_changed(pcs->bg_color.changebar))
701     {
702         value = prop_colorfield_get_value(&(pcs->bg_color));   
703         abobj_set_background_color(pcs->current_obj, value);
704         if (util_strempty(value))
705             reset_bg = True;
706         util_free(value);
707         prop_colorfield_set_value(&(pcs->bg_color), 
708                 obj_get_bg_color(pcs->current_obj), False);
709     }
710     if (prop_changed(pcs->items.changebar))
711     {
712         /* Ensure edits to current item are saved before apply */
713         prop_item_change(&(pcs->items), False);
714         prop_item_editor_apply(&(pcs->items));
715         size_chg = True;
716     }
717     if (prop_changed(pcs->choice_type.changebar))
718     {
719         abobj_set_choice_type(pcs->current_obj,
720             (AB_CHOICE_TYPE)prop_options_get_value(&(pcs->choice_type)));
721         size_chg = True;
722     }
723
724     abobj_tree_instantiate_changes(pcs->current_obj);
725
726     if (reset_bg || reset_fg) /* Set back to No Color */ 
727     {
728         ABObj        item;
729         AB_TRAVERSAL trav;
730
731         abobj_reset_colors(pcs->current_obj, reset_bg, reset_fg); 
732
733         /* Need to also reset the Item's colors also */
734         for (trav_open(&trav, pcs->current_obj, AB_TRAV_ITEMS);
735             (item = trav_next(&trav)) != NULL; )
736         {
737             abobj_reset_colors(item, reset_bg, reset_fg);
738         }
739         trav_close(&trav);
740     }
741     if (size_chg)
742         abobj_force_dang_form_resize(pcs->current_obj);
743  
744     turnoff_changebars(type);
745
746     return OK;
747 }
748
749 static BOOL
750 choice_prop_pending(
751     AB_PROP_TYPE type
752 )
753 {
754     return(prop_changebars_pending(prop_choice_settings_rec[type].prop_sheet));
755 }
756
757 static BOOL
758 verify_props(
759     AB_PROP_TYPE type
760 )
761 {
762     PropChoiceSettingsRec *pcs = &(prop_choice_settings_rec[type]);
763
764     if (prop_changed(pcs->name.changebar) && 
765                 !prop_name_ok(pcs->current_obj, pcs->name.field))
766         return False;
767  
768     if ((prop_changed(pcs->label_type.changebar) || prop_changed(pcs->label.changebar)) &&
769         (AB_BUILTIN_ACTION)prop_options_get_value(&(pcs->label_type)) == AB_LABEL_GLYPH &&
770         !prop_graphic_filename_ok(pcs->label.field, False))
771         return False;
772
773     if (prop_changed(pcs->row_col.changebar) && 
774         !prop_number_ok(pcs->row_col_count.field, "Row/Column Field", 1, 99))
775         return False;
776
777     if (prop_changed(pcs->pos.changebar) &&
778         (!prop_number_ok(pcs->pos.x_field, (STRING)XFieldStr, -SHRT_MAX, SHRT_MAX) ||
779          !prop_number_ok(pcs->pos.y_field, (STRING)YFieldStr, -SHRT_MAX, SHRT_MAX)))
780         return False;
781
782     if (prop_changed(pcs->fg_color.changebar) && !prop_color_ok(pcs->fg_color.field))
783         return False;
784  
785     if (prop_changed(pcs->bg_color.changebar) && !prop_color_ok(pcs->bg_color.field))
786         return False;
787
788     return True;
789 }
790
791 static void
792 turnoff_changebars(
793     AB_PROP_TYPE type
794 )
795 {
796     PropChoiceSettingsRec *pcs = &(prop_choice_settings_rec[type]);
797
798     prop_set_changebar(pcs->name.changebar,             PROP_CB_OFF);
799     prop_set_changebar(pcs->choice_type.changebar,      PROP_CB_OFF);
800     prop_set_changebar(pcs->pos.changebar,              PROP_CB_OFF);
801     prop_set_changebar(pcs->label_type.changebar,       PROP_CB_OFF);
802     prop_set_changebar(pcs->label.changebar,            PROP_CB_OFF);
803     prop_set_changebar(pcs->row_col.changebar,          PROP_CB_OFF);
804     prop_set_changebar(pcs->init_state.changebar,       PROP_CB_OFF);
805     prop_set_changebar(pcs->bg_color.changebar,         PROP_CB_OFF);
806     prop_set_changebar(pcs->fg_color.changebar,         PROP_CB_OFF);
807     prop_set_changebar(pcs->items.changebar,            PROP_CB_OFF);
808
809     prop_changebars_cleared(pcs->prop_sheet);
810
811 }
812
813 static void
814 setup_type_settings(
815     AB_PROP_TYPE        type,
816     AB_CHOICE_TYPE      choice_type
817 )
818 {
819     PropChoiceSettingsRec *pcs = &(prop_choice_settings_rec[type]);
820     BOOL                  active = True;
821
822     active = (!(choice_type == AB_CHOICE_OPTION_MENU));
823     ui_set_active(pcs->row_col.label, active);
824     ui_set_active(pcs->row_col.radiobox, active);
825     ui_set_active(pcs->row_col_count.field, active);
826 }
827
828 static void
829 typeCB(
830     Widget    item,
831     XtPointer clientdata,
832     XtPointer call_data
833 )
834 {
835     AB_PROP_TYPE        type = (AB_PROP_TYPE)clientdata;
836     AB_CHOICE_TYPE      choice_type = AB_CHOICE_UNDEF;
837
838     XtVaGetValues(item, XmNuserData, &choice_type, NULL);
839     setup_type_settings(type, choice_type);
840 }
841
842 /*
843  * Object destroy callback
844  */
845 static int
846 prop_choice_install_obj_destroy_CB()
847 {
848     static BOOL callback_installed = False;
849
850     if (callback_installed)
851     {
852         return 0;
853     }
854     obj_add_destroy_callback(prop_choice_obj_destroy_CB, "Choice Props");
855     return 0;
856 }
857
858 static int
859 prop_choice_obj_destroy_CB(ObjEvDestroyInfo destroyInfo)
860 {
861     int                 i;
862     ABObj               doomedObj = destroyInfo->obj;
863     PropChoiceSettings  pcs;
864
865     if (!obj_is_choice_item(doomedObj))
866     {
867         return 0;
868     }
869
870     for (i = 0; i < AB_PROP_TYPE_NUM_VALUES; ++i)
871     {
872         pcs = &(prop_choice_settings_rec[i]);
873
874         if (pcs->current_obj == doomedObj)
875             pcs->current_obj = NULL;
876         if (pcs->items.current_item == doomedObj)
877             pcs->items.current_item = NULL;
878         if (pcs->items.clipboard_item == doomedObj)
879             pcs->items.clipboard_item = NULL;
880     }
881     return 0;
882 }