Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtappbuilder / src / ab / pal_spinbox.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_spinbox.c /main/5 1996/08/08 18:03:54 mustafa $
26  *
27  *      @(#)pal_spinbox.c       1.4 22 Feb 1994
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_spinbox.c - Implements Palette SpinBox object functionality
46  */
47 #include <stdio.h>
48 #include <Xm/Xm.h>
49 #include <ab_private/obj_notify.h>
50 #include <ab_private/pal.h>
51 #include <ab_private/ab.h>
52 #include <ab_private/prop.h>
53 #include <ab_private/abobj.h>
54 #include <ab_private/abobj_set.h>
55 #include <ab_private/ui_util.h>
56 #include "spinbox_ui.h"
57
58 const    int    spinbox_init_width  = 100;
59
60 typedef struct  PROP_SPINBOX_SETTINGS
61 {
62     Widget                      prop_sheet;
63     PropFieldSettingRec         name;
64     PropRadioSettingRec         spinbox_type;
65     PropGeometrySettingRec      geometry;
66     PropOptionsSettingRec       label_type;
67     PropFieldSettingRec         label;
68     PropOptionsSettingRec       label_pos;
69     PropOptionsSettingRec       arrow_style;
70     Widget                      valrange_label;
71     PropFieldSettingRec         min;
72     PropFieldSettingRec         max;
73     PropFieldSettingRec         incr;
74     PropFieldSettingRec         decimal;
75     PropFieldSettingRec         ivalue;
76     PropCheckboxSettingRec      init_state;
77     PropColorSettingRec         bg_color;
78     PropColorSettingRec         fg_color;
79     PropFieldSettingRec         item_label;
80     PropCheckboxSettingRec      item_state;
81     Widget                      item_list_label;
82     PropItemsSettingRec         items;
83     Widget                      item_add_button;
84     Widget                      item_edit_button;
85     ABObj                       current_obj;
86 } PropSpinboxSettingsRec, *PropSpinboxSettings;
87
88 /*************************************************************************
89 **                                                                      **
90 **       Private Function Declarations                                  **
91 **                                                                      **
92 **************************************************************************/
93 /*
94  * Methods
95  */
96 static int      spinbox_initialize(
97                     ABObj   obj
98                 );
99 static Widget   spinbox_prop_init(
100                     Widget  parent,
101                     AB_PROP_TYPE type
102                 );
103 static int      spinbox_prop_activate(
104                     AB_PROP_TYPE type,
105                     BOOL         active
106                 );
107 static int      spinbox_prop_clear(
108                     AB_PROP_TYPE type
109                 );
110 static int      spinbox_prop_load(
111                     ABObj        obj,
112                     AB_PROP_TYPE type,
113                     unsigned long loadkey
114                 );
115 static int      spinbox_prop_apply(
116                     AB_PROP_TYPE type
117                 );
118 static BOOL     spinbox_prop_pending(
119                     AB_PROP_TYPE type
120                 );
121
122 static BOOL     verify_props(
123                     AB_PROP_TYPE type
124                 );
125 static void     turnoff_changebars(
126                     AB_PROP_TYPE type
127                 );
128 static void     setup_content_settings(
129                     AB_PROP_TYPE type,
130                     AB_TEXT_TYPE spinbox_type
131                 );
132 /*
133  * ABObj Callbacks
134  */
135 static int      spinbox_install_obj_destroy_CB(void);
136
137 static int      spinbox_obj_destroy_CB(
138                     ObjEvDestroyInfo destroyInfo
139                 );
140 /*
141  * Xt Callbacks
142  */
143 static void     spinbox_typeCB(
144                     Widget   widget,
145                     XtPointer clientdata,
146                     XmToggleButtonCallbackStruct *state
147                 );
148
149 /*************************************************************************
150 **                                                                      **
151 **       Data                                                            **
152 **                                                                      **
153 **************************************************************************/
154 PalItemInfo spinbox_palitem_rec = {
155
156     /* type             */  AB_TYPE_SPIN_BOX,
157     /* name             */  "Spin Box",
158     /* animation pixmaps*/  NULL,
159     /* number of pixmaps*/  0,
160     /* rev_prop_frame   */  NULL,
161     /* fix_prop_dialog  */  NULL,
162     /* initialize       */  spinbox_initialize,
163     /* is_a_test        */  obj_is_spin_box,
164     /* prop_initialize  */  spinbox_prop_init,
165     /* prop_activate    */  spinbox_prop_activate,
166     /* prop_clear       */  spinbox_prop_clear,
167     /* prop_load        */  spinbox_prop_load,
168     /* prop_apply       */  spinbox_prop_apply,
169     /* prop_pending     */  spinbox_prop_pending
170
171 };
172
173 PalItemInfo *ab_spinbox_palitem = &spinbox_palitem_rec;
174 PropSpinboxSettingsRec prop_spinbox_settings_rec[AB_PROP_TYPE_NUM_VALUES];
175
176
177 /*************************************************************************
178 **                                                                      **
179 **       Function Definitions                                           **
180 **                                                                      **
181 **************************************************************************/
182 static int
183 spinbox_initialize(
184     ABObj    obj
185 )
186 {
187     obj_set_unique_name(obj, "spinbox");
188
189     obj_set_label(obj, catgets(Dtb_project_catd, 100, 262, "SpinBox:"));
190     obj_set_label_position(obj, AB_CP_NORTH);
191     obj_set_width(obj, spinbox_init_width);
192     obj_set_text_type(obj, AB_TEXT_NUMERIC);
193     obj_set_min_value(obj, 0);
194     obj_set_max_value(obj, 100);
195     obj_set_increment(obj, 1);
196     obj_set_arrow_style(obj, AB_ARROW_END);
197     obj_set_is_initially_visible(obj, True);
198     obj_set_is_initially_active(obj, True);
199
200     obj_set_attachment(obj, AB_CP_NORTH, AB_ATTACH_POINT, NULL, obj->y);
201     obj_set_attachment(obj, AB_CP_WEST,  AB_ATTACH_POINT, NULL, obj->x);
202
203     return OK;
204 }
205
206 static Widget
207 spinbox_prop_init(
208     Widget parent,
209     AB_PROP_TYPE type
210 )
211 {
212     DtbSpinboxPropDialogInfoRec rev_spinbox_prop_dialog; /* Revolving Props */
213     DtbSpinboxPropDialogInfo    cgen = &dtb_spinbox_prop_dialog; /* Codegen structure */
214     DtbRevolvPropDialogInfo     rpd = &(dtb_revolv_prop_dialog);
215     PropSpinboxSettingsRec      *pss = &(prop_spinbox_settings_rec[type]);
216     Widget                      item[6];
217     int                         item_val[6];
218     Widget                      item2[6];
219     int                         item2_val[6];
220     int                         i, n, j;
221
222     if (type == AB_PROP_REVOLVING)
223     {
224         /* Cloning Trick:
225          * Only the Attributes ControlPanel needs to be created within
226          * the existing Revolving Prop dialog, so fill out all other
227          * fields with the Revolving Prop dialog equivelents, so the
228          * dtb initialize proc will skip those non-NULL fields...
229          */
230         dtbSpinboxPropDialogInfo_clear(&rev_spinbox_prop_dialog);
231
232         cgen = &(rev_spinbox_prop_dialog);
233         cgen->prop_dialog = rpd->prop_dialog;
234         cgen->prop_dialog_shellform = rpd->prop_dialog_shellform;
235         cgen->prop_dialog_panedwin = rpd->prop_dialog_panedwin;
236         cgen->prop_dialog_form = rpd->prop_dialog_form;
237         cgen->objlist_panel = rpd->objlist_panel;
238         cgen->objlist_label = rpd->objlist_label2;
239         cgen->objlist_scrolledwin = rpd->objlist_scrolledwin;
240         cgen->objlist = rpd->objlist;
241         cgen->attrs_ctrlpanel_frame = rpd->attrs_ctrlpanel_frame;
242         cgen->activate_panel = rpd->activate_panel;
243         cgen->apply_button = rpd->apply_button;
244         cgen->ok_button = rpd->ok_button;
245         cgen->cancel_button = rpd->cancel_button;
246         cgen->reset_button = rpd->reset_button;
247         cgen->help_button = rpd->help_button;
248
249         /*
250          * Get notification of object destruction!
251          */
252         spinbox_install_obj_destroy_CB();
253
254     }
255     else /* AB_PROP_FIXED */
256         cgen = &dtb_spinbox_prop_dialog;
257
258     if (dtb_spinbox_prop_dialog_initialize(cgen, parent) == 0)
259     {
260         pss->prop_sheet = cgen->attrs_ctrlpanel;
261         pss->current_obj = NULL;
262
263         if (type == AB_PROP_REVOLVING)
264                 XtVaSetValues(parent,
265                         XmNuserData, pss->current_obj,
266                         NULL);
267
268         /* Dialog/Object List */
269         if (type == AB_PROP_FIXED)
270         {
271             prop_fixed_dialog_init(ab_spinbox_palitem,
272                         cgen->prop_dialog_shellform, cgen->objlist);
273             prop_activate_panel_init(type, ab_spinbox_palitem,
274                         cgen->ok_button, cgen->apply_button,
275                         cgen->reset_button, cgen->cancel_button,
276                         cgen->help_button);
277         }
278
279         /* Alternate Editor Buttons */
280         prop_editors_panel_init(type, ab_spinbox_palitem,
281             cgen->attach_button, cgen->conn_button, cgen->helptxt_button);
282
283         /*
284           * Prop Sheet Settings....
285          */
286
287         /* Name */
288         prop_field_init(&(pss->name), cgen->name_field_label,
289                 cgen->name_field, cgen->name_cb);
290
291         /* Spinbox Type */
292         n = 0;
293         item[n] = cgen->spinboxtype_rbox_items.Numeric_item;
294         item_val[n] = AB_TEXT_NUMERIC; n++;
295         item[n] = cgen->spinboxtype_rbox_items.String_List_item;
296         item_val[n] = AB_TEXT_DEFINED_STRING; n++;
297         prop_radiobox_init(&(pss->spinbox_type), cgen->spinboxtype_rbox_label,
298                        cgen->spinboxtype_rbox, n, item, (XtPointer*)item_val,
299                        cgen->spinboxtype_cb);
300         for(i=0; i < n; i++)
301             XtAddCallback(item[i], XmNvalueChangedCallback,
302                         (XtCallbackProc)spinbox_typeCB, (XtPointer)type);
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(&(pss->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(&(pss->label), cgen->label_field_label,
316                 cgen->label_field, cgen->label_cb);
317
318         prop_label_field_init(&(pss->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(&(pss->label_pos), cgen->labeltype_rbox_label,
326                 cgen->labelpos_rbox, cgen->labelpos_rbox_menu,
327                 n, item, (XtPointer*)item_val,
328                 cgen->labeltype_cb);
329
330         /* Arrow Style */
331         n = 0;
332         item[n] = cgen->arrowstyle_opmenu_items.Flat_Beginning_item;
333         item_val[n] = AB_ARROW_FLAT_BEGIN; n++;
334         item[n] = cgen->arrowstyle_opmenu_items.Flat_End_item;
335         item_val[n] = AB_ARROW_FLAT_END; n++;
336         item[n] = cgen->arrowstyle_opmenu_items.Beginning_item;
337         item_val[n] = AB_ARROW_BEGIN; n++;
338         item[n] = cgen->arrowstyle_opmenu_items.End_item;
339         item_val[n] = AB_ARROW_END; n++;
340         item[n] = cgen->arrowstyle_opmenu_items.Split_item;
341         item_val[n] = AB_ARROW_SPLIT; n++;
342         prop_options_init(&(pss->arrow_style), cgen->arrowstyle_opmenu_label,
343                 cgen->arrowstyle_opmenu, cgen->arrowstyle_opmenu_menu,
344                 n, item, (XtPointer*)item_val,
345                 cgen->arrowstyle_cb);
346
347         /* Min & Max & Incr */
348         pss->valrange_label = cgen->valrange_label;
349         prop_field_init(&(pss->min), cgen->min_field_label,
350                 cgen->min_field, cgen->valrange_cb);
351         prop_field_init(&(pss->max), cgen->max_field_label,
352                 cgen->max_field, cgen->valrange_cb);
353         prop_field_init(&(pss->incr), cgen->incr_field_label,
354                 cgen->incr_field, cgen->valrange_cb);
355
356         /* Initial Value/Decimal Points */
357         prop_field_init(&(pss->ivalue), cgen->ivalue_label,
358                 cgen->ivalue_field, cgen->ivalue_cb);
359
360         prop_field_init(&(pss->decimal), cgen->decimal_field_label,
361                 cgen->decimal_field, cgen->ivalue_cb);
362
363         /* Geometry */
364         prop_geomfield_init(&(pss->geometry), cgen->geom_label,
365                 cgen->x_field_label, cgen->x_field,
366                 cgen->y_field_label, cgen->y_field,
367                 cgen->width_field_label, cgen->width_field,
368                 NULL, NULL,
369                 cgen->geom_cb);
370
371         /* Initial State */
372         n = 0;
373         item[n] = cgen->istate_ckbox_items.Visible_item;
374         item_val[n] = AB_STATE_VISIBLE; n++;
375         item[n] = cgen->istate_ckbox_items.Active_item;
376         item_val[n] = AB_STATE_ACTIVE; n++;
377         prop_checkbox_init(&(pss->init_state), cgen->istate_ckbox_label,
378                 cgen->istate_ckbox, n, item, item_val,
379                 cgen->istate_cb);
380
381         /* Color */
382         prop_colorfield_init(&(pss->bg_color), cgen->bg_mbutton,
383                 cgen->bg_mbutton_bg_mbutton_menu_items.None_item,
384                 cgen->bg_mbutton_bg_mbutton_menu_items.Color_Chooser_item,
385                 cgen->bg_swatch, cgen->bg_field, cgen->bg_cb);
386
387         prop_colorfield_init(&(pss->fg_color), cgen->fg_mbutton,
388                 cgen->fg_mbutton_fg_mbutton_menu_items.None_item,
389                 cgen->fg_mbutton_fg_mbutton_menu_items.Color_Chooser_item,
390                 cgen->fg_swatch, cgen->fg_field, cgen->fg_cb);
391
392         /* Item Editor....*/
393
394         /* Item Label */
395         prop_field_init(&(pss->item_label), cgen->itemlabel_label,
396                 cgen->itemlabel_field, cgen->itemlist_cb);
397
398         /* Item State */
399         n = 0;
400         item[n] = cgen->item_state_ckbox_items.Selected_item;
401         item_val[n] = AB_STATE_SELECTED; n++;
402         prop_checkbox_init(&(pss->item_state), NULL,
403                 cgen->item_state_ckbox, n, item, item_val,
404                 cgen->itemlist_cb);
405
406         /* Store Items->Add menu items in array */
407         n = 0;
408         item[n] = cgen->item_edit_mbutton_editmenu_items.Add_Before_item;
409         item_val[n] = INSERT_BEFORE; n++;
410         item[n] = cgen->item_edit_mbutton_editmenu_items.Add_After_item;
411         item_val[n] = INSERT_AFTER; n++;
412
413         /* Store Items->Edit menu items in array */
414         j = 0;
415         item2[j] = cgen->item_edit_mbutton_editmenu_items.Cut_item;
416         item2_val[j] = AB_EDIT_CUT; j++;
417         item2[j] = cgen->item_edit_mbutton_editmenu_items.Copy_item;
418         item2_val[j] = AB_EDIT_COPY; j++;
419         item2[j] = cgen->item_edit_mbutton_editmenu_items.Paste_item;
420         item2_val[j] = AB_EDIT_PASTE; j++;
421         item2[j] = cgen->item_edit_mbutton_editmenu_items.Delete_item;
422         item2_val[j] = AB_EDIT_DELETE; j++;
423         item2[j] = cgen->item_edit_mbutton_editmenu_items.Change_item;
424         item2_val[j] = EDIT_CHANGE; j++;
425
426         pss->item_list_label = cgen->itemlist_label;
427         pss->item_add_button = cgen->item_add_button;
428         pss->item_edit_button = cgen->item_edit_mbutton;
429         prop_item_editor_init(&(pss->items), AB_ITEM_FOR_SPIN_BOX,
430                 cgen->itemlist, cgen->itemlist_cb,
431                 cgen->item_add_button,
432                 n, item, item_val,
433                 j, item2, item2_val,
434                 &(pss->item_label), NULL/*label_type*/, NULL/*graphic_hint*/,
435                 NULL/*mnemonic*/, NULL/*accel*/, NULL/*line_style*/,
436                 &(pss->item_state), NULL/*submenu*/,
437                 &(pss->current_obj));
438
439         prop_changebars_cleared(pss->prop_sheet);
440
441         return (cgen->prop_dialog_shellform);
442     }
443     else
444         return NULL;
445
446 }
447
448 static int
449 spinbox_prop_activate(
450     AB_PROP_TYPE type,
451     BOOL         active
452 )
453 {
454     ui_set_active(prop_spinbox_settings_rec[type].prop_sheet, active);
455
456     return OK;
457 }
458
459
460 static int
461 spinbox_prop_clear(
462     AB_PROP_TYPE type
463 )
464 {
465     PropSpinboxSettingsRec      *pss = &(prop_spinbox_settings_rec[type]);
466
467     if (pss->current_obj == NULL)
468         return OK;
469
470     /* Clear Name */
471     prop_field_set_value(&(pss->name), "", False);
472
473     /* Clear Label Type/Position */
474     prop_options_set_value(&(pss->label_type), (XtPointer)AB_LABEL_STRING, False);
475     prop_options_set_value(&(pss->label_pos), (XtPointer)AB_CP_WEST, False);
476
477     /* Clear Label */
478     ui_set_label_string(pss->label.label, "Label:");
479     prop_field_set_value(&(pss->label), "", False);
480
481     /* Clear Spinbox Type */
482     prop_radiobox_set_value(&(pss->spinbox_type),
483                             (XtPointer)AB_TEXT_NUMERIC, False);
484
485     /* Clear Arrow Style*/
486     prop_options_set_value(&(pss->arrow_style), (XtPointer)AB_ARROW_END, False);
487
488     /* Clear Min/Max/Incr */
489     prop_field_set_value(&(pss->min), "", False);
490     prop_field_set_value(&(pss->max), "", False);
491     prop_field_set_value(&(pss->incr), "", False);
492
493     /* Clear Initial Value/Decimal Points */
494     prop_field_set_value(&(pss->decimal), "", False);
495     prop_field_set_value(&(pss->ivalue), "", False);
496
497     /* Clear Geometry */
498     prop_geomfield_clear(&(pss->geometry), GEOM_X);
499     prop_geomfield_clear(&(pss->geometry), GEOM_Y);
500     prop_geomfield_clear(&(pss->geometry), GEOM_WIDTH);
501
502     /* Clear Initial State */
503     prop_checkbox_set_value(&(pss->init_state), AB_STATE_VISIBLE, True, False);
504     prop_checkbox_set_value(&(pss->init_state), AB_STATE_ACTIVE, True, False);
505
506     /* Clear Color */
507     prop_colorfield_set_value(&(pss->bg_color), "", False);
508     prop_colorfield_set_value(&(pss->fg_color), "", False);
509
510     /* Clear Items */
511     prop_item_editor_clear(&(pss->items));
512
513     pss->current_obj = NULL;
514
515     turnoff_changebars(type);
516
517     return OK;
518 }
519
520 static int
521 spinbox_prop_load(
522     ABObjPtr     obj,
523     AB_PROP_TYPE type,
524     unsigned long loadkey
525 )
526 {
527     PropSpinboxSettingsRec      *pss = &(prop_spinbox_settings_rec[type]);
528     AB_TEXT_TYPE                spinbox_type;
529     BOOL                        load_all = (loadkey & LoadAll);
530
531     if (obj == NULL)
532     {
533         if (pss->current_obj != NULL)
534             obj = pss->current_obj;
535         else
536             return ERROR;
537     }
538     else if (!obj_is_spin_box(obj))
539         return ERROR;
540     else
541         pss->current_obj = obj;
542
543     /* Load Name */
544     if (load_all || loadkey & LoadName)
545         prop_field_set_value(&(pss->name), obj_get_name(obj), False);
546
547     if (load_all)
548     {
549         /* Load Label Type/Position */
550         prop_options_set_value(&(pss->label_type), (XtPointer)obj->label_type, False);
551         prop_options_set_value(&(pss->label_pos), (XtPointer)obj_get_label_position(obj), False);
552
553         /* Load Label */
554         prop_setup_label_field(&(pss->label), NULL,
555                                 obj->label_type, obj_get_label(obj), AB_LINE_UNDEF);
556
557         /* Load Spinbox Type */
558         spinbox_type = obj_get_text_type(obj);
559         prop_radiobox_set_value(&(pss->spinbox_type),
560                                 (XtPointer)spinbox_type, False);
561         setup_content_settings(type, spinbox_type);
562
563         /* Load Arrow Style */
564         prop_options_set_value(&(pss->arrow_style), (XtPointer)obj_get_arrow_style(obj), False);
565
566         /* Load Min/Max/Incr */
567         prop_field_set_numeric_value(&(pss->min), obj_get_min_value(obj), False);
568         prop_field_set_numeric_value(&(pss->max), obj_get_max_value(obj), False);
569         prop_field_set_numeric_value(&(pss->incr), obj_get_increment(obj), False);
570
571         /* Load Initial Value/Decimal Points  */
572         prop_field_set_numeric_value(&(pss->ivalue),
573                                 obj_get_initial_value_int(obj), False);
574         prop_field_set_numeric_value(&(pss->decimal),
575                 obj_get_decimal_points(obj), False);
576
577         /* Load Initial State */
578         prop_checkbox_set_value(&(pss->init_state), AB_STATE_VISIBLE,
579                 obj_is_initially_visible(obj), False);
580         prop_checkbox_set_value(&(pss->init_state), AB_STATE_ACTIVE,
581                 obj_is_initially_active(obj), False);
582
583         /* Load Color */
584         prop_colorfield_set_value(&(pss->bg_color), obj_get_bg_color(obj), False);
585         prop_colorfield_set_value(&(pss->fg_color), obj_get_fg_color(obj), False);
586
587         /* Load Items */
588         prop_item_editor_load(&(pss->items), obj);
589
590         turnoff_changebars(type);
591     }
592
593     /* Load Geometry */
594     if (load_all || loadkey & LoadPosition)
595         prop_load_obj_position(obj, &(pss->geometry));
596
597     if (load_all || loadkey & LoadSize)
598         prop_load_obj_size(obj, &(pss->geometry));
599
600     return OK;
601 }
602
603 int
604 spinbox_prop_apply(
605     AB_PROP_TYPE   type
606 )
607 {
608     PropSpinboxSettingsRec      *pss = &(prop_spinbox_settings_rec[type]);
609     AB_TEXT_TYPE                spinbox_type;
610     STRING                      value;
611     int                         new_w;
612     BOOL                        size_chg = False;
613     BOOL                        reset_bg = False;
614     BOOL                        reset_fg = False;
615
616     if (!verify_props(type))
617         return ERROR;
618
619     if (prop_changed(pss->name.changebar))
620     {
621         value = prop_field_get_value(&(pss->name));
622         abobj_set_name(pss->current_obj, value);
623         util_free(value);
624     }
625     if (prop_changed(pss->label.changebar) ||
626         prop_changed(pss->label_type.changebar))
627     {
628         value = prop_field_get_value(&(pss->label));
629         abobj_set_label(pss->current_obj,
630             (AB_LABEL_TYPE)prop_options_get_value(&(pss->label_type)),
631                         value);
632         util_free(value);
633
634         abobj_set_label_position(pss->current_obj,
635                 (AB_COMPASS_POINT)prop_options_get_value(&(pss->label_pos)));
636         size_chg = True;
637     }
638     if (prop_changed(pss->spinbox_type.changebar))
639     {
640         spinbox_type = (AB_TEXT_TYPE)prop_radiobox_get_value(&(pss->spinbox_type));
641
642         if (spinbox_type == AB_TEXT_NUMERIC &&
643             obj_get_text_type(pss->current_obj) == AB_TEXT_DEFINED_STRING)
644         {
645              int                num_items;
646              DTB_MODAL_ANSWER   answer = DTB_ANSWER_NONE;
647
648             XtVaGetValues(pss->items.item_list, XmNitemCount, &num_items, NULL);
649             if (num_items > 0)
650             {
651                 /* Popup Modal Message and wait for answer */
652                 dtb_spinbox_chg_type_msg_initialize(&
653                         dtb_spinbox_chg_type_msg);
654                 answer = dtb_show_modal_message(
655                                 pss->spinbox_type.radiobox,
656                                 &dtb_spinbox_chg_type_msg,
657                                 NULL, NULL, NULL);
658                 if (answer == DTB_ANSWER_CANCEL)
659                     return 0;
660                 else
661                 {
662                     /* Destroy any existing StringList items */
663                     prop_item_editor_clear(&(pss->items));
664                     prop_set_changebar(pss->items.changebar, PROP_CB_ON);
665                 }
666             }
667         }
668         abobj_set_text_type(pss->current_obj, spinbox_type);
669     }
670     if (prop_changed(pss->arrow_style.changebar))
671     {
672         abobj_set_arrow_style(pss->current_obj,
673                 (AB_ARROW_STYLE)prop_options_get_value(&(pss->arrow_style)));
674     }
675     if (prop_changed(pss->min.changebar))
676     {
677         abobj_set_min_max_values(pss->current_obj,
678                 prop_field_get_numeric_value(&(pss->min)),
679                 prop_field_get_numeric_value(&(pss->max)));
680         abobj_set_increment(pss->current_obj,
681                 prop_field_get_numeric_value(&(pss->incr)));
682
683     }
684     if (prop_changed(pss->ivalue.changebar))
685     {
686         abobj_set_initial_value(pss->current_obj, NULL,
687                 prop_field_get_numeric_value(&(pss->ivalue)));
688         abobj_set_decimal_points(pss->current_obj,
689                 prop_field_get_numeric_value(&(pss->decimal)));
690     }
691     if (prop_changed(pss->geometry.changebar))
692     {
693         if (abobj_width_resizable(pss->current_obj))
694         {
695             new_w = prop_geomfield_get_value(&(pss->geometry), GEOM_WIDTH);
696             abobj_set_pixel_width(pss->current_obj, new_w, 0);
697             size_chg = True;
698         }
699         if (abobj_is_movable(pss->current_obj))
700             abobj_set_xy(pss->current_obj,
701                 prop_geomfield_get_value(&(pss->geometry), GEOM_X),
702                 prop_geomfield_get_value(&(pss->geometry), GEOM_Y));
703
704     }
705     if (prop_changed(pss->init_state.changebar))
706     {
707         abobj_set_visible(pss->current_obj,
708                 prop_checkbox_get_value(&(pss->init_state), AB_STATE_VISIBLE));
709         abobj_set_active(pss->current_obj,
710                 prop_checkbox_get_value(&(pss->init_state), AB_STATE_ACTIVE));
711     }
712     if (prop_changed(pss->fg_color.changebar))
713     {
714         value = prop_colorfield_get_value(&(pss->fg_color));
715         abobj_set_foreground_color(pss->current_obj, value);
716         if (util_strempty(value))
717             reset_fg = True;
718         util_free(value);
719         prop_colorfield_set_value(&(pss->fg_color),
720                 obj_get_fg_color(pss->current_obj), False);
721     }
722     if (prop_changed(pss->bg_color.changebar))
723     {
724         value = prop_colorfield_get_value(&(pss->bg_color));
725         abobj_set_background_color(pss->current_obj, value);
726         if (util_strempty(value))
727             reset_bg = True;
728         util_free(value);
729         prop_colorfield_set_value(&(pss->bg_color),
730                 obj_get_bg_color(pss->current_obj), False);
731     }
732     if (prop_changed(pss->items.changebar))
733     {
734         prop_item_change(&(pss->items), False);
735         prop_item_editor_apply(&(pss->items));
736         size_chg = True;
737     }
738     abobj_tree_instantiate_changes(pss->current_obj);
739
740     if (reset_bg || reset_fg) /* Set back to No Color */
741         abobj_reset_colors(pss->current_obj, reset_bg, reset_fg);
742     if (size_chg)
743         abobj_force_dang_form_resize(pss->current_obj);
744
745     turnoff_changebars(type);
746
747     return OK;
748 }
749
750 static BOOL
751 spinbox_prop_pending(
752     AB_PROP_TYPE type
753 )
754 {
755     return(prop_changebars_pending(prop_spinbox_settings_rec[type].prop_sheet));
756 }
757
758 static BOOL
759 verify_props(
760     AB_PROP_TYPE type
761 )
762 {
763     PropSpinboxSettingsRec *pss = &(prop_spinbox_settings_rec[type]);
764     int                     min, max;
765
766     if (prop_changed(pss->name.changebar) &&
767         !prop_name_ok(pss->current_obj, pss->name.field))
768         return False;
769
770     if ((prop_changed(pss->label_type.changebar) || prop_changed(pss->label.changebar)) &&
771         prop_options_get_value(&(pss->label_type)) == (XtPointer)AB_LABEL_GLYPH &&
772         !prop_graphic_filename_ok(pss->label.field, False))
773         return False;
774
775     if (!prop_number_ok(pss->min.field, "Min Field", INT_MIN, INT_MAX))
776         return False;
777
778     min = prop_field_get_numeric_value(&(pss->min));
779     if (!prop_number_ok(pss->max.field, "Max Field", min+1, INT_MAX))
780         return False;
781
782     max = prop_field_get_numeric_value(&(pss->max));
783     if (!prop_number_ok(pss->incr.field, "Increment Field", 1, max - min))
784         return False;
785
786     if (!prop_number_ok(pss->ivalue.field, "Initial Value Field", min, max) ||
787         !prop_number_ok(pss->decimal.field, "Decimal Field", 0, 99))
788         return False;
789
790     if (prop_changed(pss->geometry.changebar) &&
791         (!prop_number_ok(pss->geometry.x_field, (STRING)XFieldStr, -SHRT_MAX, SHRT_MAX) ||
792          !prop_number_ok(pss->geometry.y_field, (STRING)YFieldStr, -SHRT_MAX, SHRT_MAX) ||
793          !prop_number_ok(pss->geometry.w_field, (STRING)WFieldStr, 1, SHRT_MAX)))
794         return False;
795
796     if (prop_changed(pss->fg_color.changebar) &&
797         !prop_color_ok(pss->fg_color.field))
798         return False;
799
800     if (prop_changed(pss->bg_color.changebar) &&
801         !prop_color_ok(pss->bg_color.field))
802         return False;
803
804     return True;
805 }
806
807 static void
808 turnoff_changebars(
809     AB_PROP_TYPE type
810 )
811 {
812     PropSpinboxSettingsRec *pss = &(prop_spinbox_settings_rec[type]);
813
814     prop_set_changebar(pss->name.changebar,             PROP_CB_OFF);
815     prop_set_changebar(pss->spinbox_type.changebar,     PROP_CB_OFF);
816     prop_set_changebar(pss->geometry.changebar,         PROP_CB_OFF);
817     prop_set_changebar(pss->label_type.changebar,       PROP_CB_OFF);
818     prop_set_changebar(pss->label.changebar,            PROP_CB_OFF);
819     prop_set_changebar(pss->arrow_style.changebar,      PROP_CB_OFF);
820     prop_set_changebar(pss->min.changebar,              PROP_CB_OFF);
821     prop_set_changebar(pss->ivalue.changebar,           PROP_CB_OFF);
822     prop_set_changebar(pss->init_state.changebar,       PROP_CB_OFF);
823     prop_set_changebar(pss->bg_color.changebar,         PROP_CB_OFF);
824     prop_set_changebar(pss->fg_color.changebar,         PROP_CB_OFF);
825     prop_set_changebar(pss->items.changebar,            PROP_CB_OFF);
826
827     prop_changebars_cleared(pss->prop_sheet);
828 }
829
830 static void
831 spinbox_typeCB(
832     Widget      item,
833     XtPointer   clientdata,
834     XmToggleButtonCallbackStruct *state
835 )
836 {
837     AB_PROP_TYPE           type = (AB_PROP_TYPE)clientdata;
838     PropSpinboxSettingsRec *pss = &(prop_spinbox_settings_rec[type]);
839     int                    value;
840     int                    num_items;
841
842     if (state->set)
843     {
844         XtVaGetValues(item, XmNuserData, &value, NULL);
845         setup_content_settings(type, (AB_TEXT_TYPE)value);
846
847         if (value == AB_TEXT_DEFINED_STRING)
848         {
849             /* If type is changed to StringList and there are no items,
850              * inactivate the item settings.
851              */
852             XtVaGetValues(pss->items.item_list, XmNitemCount, &num_items, NULL);
853             if (num_items < 1)
854             {
855                 ui_field_set_editable(pss->item_label.field, False);
856                 ui_set_active(pss->item_label.label, False);
857                 ui_set_active(pss->item_state.checkbox, False);
858             }
859         }
860     }
861 }
862
863 static void
864 setup_content_settings(
865     AB_PROP_TYPE        type,
866     AB_TEXT_TYPE        spinbox_type
867 )
868 {
869     PropSpinboxSettingsRec *pss = &(prop_spinbox_settings_rec[type]);
870
871     switch(spinbox_type)
872     {
873         case AB_TEXT_NUMERIC:
874             ui_set_active(pss->valrange_label, True);
875             ui_set_active(pss->min.field, True);
876             ui_set_active(pss->min.label, True);
877             ui_set_active(pss->max.field, True);
878             ui_set_active(pss->max.label, True);
879             ui_set_active(pss->incr.field, True);
880             ui_set_active(pss->incr.label, True);
881             ui_set_active(pss->decimal.field, True);
882             ui_set_active(pss->decimal.label, True);
883             ui_set_active(pss->ivalue.field, True);
884             ui_set_active(pss->ivalue.label, True);
885
886             ui_set_active(pss->item_list_label, False);
887             ui_set_active(pss->items.item_list, False);
888             ui_set_active(pss->item_add_button, False);
889             ui_set_active(pss->item_edit_button, False);
890             ui_field_set_editable(pss->item_label.field, False);
891             ui_set_active(pss->item_label.label, False);
892             ui_set_active(pss->item_state.checkbox, False);
893             break;
894         case AB_TEXT_DEFINED_STRING:
895             ui_set_active(pss->valrange_label, False);
896             ui_set_active(pss->min.field, False);
897             ui_set_active(pss->min.label, False);
898             ui_set_active(pss->max.field, False);
899             ui_set_active(pss->max.label, False);
900             ui_set_active(pss->incr.field, False);
901             ui_set_active(pss->incr.label, False);
902             ui_set_active(pss->decimal.field, False);
903             ui_set_active(pss->decimal.label, False);
904             ui_set_active(pss->ivalue.field, False);
905             ui_set_active(pss->ivalue.label, False);
906
907             ui_set_active(pss->item_list_label, True);
908             ui_set_active(pss->items.item_list, True);
909             ui_set_active(pss->item_add_button, True);
910             ui_set_active(pss->item_edit_button, True);
911             ui_field_set_editable(pss->item_label.field, True);
912             ui_set_active(pss->item_label.label, True);
913             ui_set_active(pss->item_state.checkbox, True);
914             break;
915     }
916 }
917
918 static int
919 spinbox_install_obj_destroy_CB()
920 {
921     static BOOL callback_installed = False;
922
923     if (callback_installed)
924         return 0;
925
926     obj_add_destroy_callback(spinbox_obj_destroy_CB, "SpinBox Props");
927     return 0;
928 }
929
930
931 static int
932 spinbox_obj_destroy_CB(ObjEvDestroyInfo destroyInfo)
933 {
934     int                 i;
935     ABObj               doomedObj = destroyInfo->obj;
936     PropSpinboxSettingsRec *pss;
937
938     if (!obj_is_spin_box_item(doomedObj))
939         return 0;
940
941     for (i = 0; i < AB_PROP_TYPE_NUM_VALUES; ++i)
942     {
943         pss = &(prop_spinbox_settings_rec[i]);
944
945         if (pss->current_obj == doomedObj)
946             pss->current_obj = NULL;
947         if (pss->items.current_item == doomedObj)
948             pss->items.current_item = NULL;
949         if (pss->items.clipboard_item == doomedObj)
950             pss->items.clipboard_item = NULL;
951     }
952     return 0;
953 }
954