Fix typo in license headers
[oweals/cde.git] / cde / programs / dtappbuilder / src / ab / pal_menubar.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 libraries 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_menubar.c /main/4 1996/08/07 19:49:33 mustafa $
26  *
27  * @(#)pal_menubar.c    1.36 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_menubar.c - Implements Palette Menubar 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 "menubar_ui.h"
59
60
61 typedef struct  PROP_MENUBAR_SETTINGS
62 {
63     Widget                      prop_sheet;
64     PropFieldSettingRec         name;
65     PropCheckboxSettingRec      init_state;
66     PropColorSettingRec         bg_color;
67     PropColorSettingRec         fg_color;
68     PropFieldSettingRec         item_label;
69     PropOptionsSettingRec       item_label_type;
70     PropFieldSettingRec         item_mnemonic;
71     PropCheckboxSettingRec      item_state;
72     PropMenunameSettingRec      item_menuname;
73     PropItemsSettingRec         items;
74     ABObj                       current_obj;
75 } PropMenubarSettingsRec, *PropMenubarSettings;
76
77 /*************************************************************************
78 **                                                                      **
79 **       Private Function Declarations                                  **
80 **                                                                      **
81 **************************************************************************/
82 /*
83  * Methods
84  */
85 static int      menubar_initialize(
86                     ABObj   obj
87                 );
88 static Widget   menubar_prop_init(
89                     Widget  parent,
90                     AB_PROP_TYPE type
91                 );
92 static int      menubar_prop_activate(
93                     AB_PROP_TYPE type,
94                     BOOL         active
95                 );
96 static int      menubar_prop_load(
97                     ABObj        obj,
98                     AB_PROP_TYPE type,
99                     unsigned long loadkey
100                 );
101 static int      menubar_prop_clear(
102                     AB_PROP_TYPE type
103                 );
104 static int      menubar_prop_apply(
105                     AB_PROP_TYPE type
106                 );
107 static BOOL     menubar_prop_pending(
108                     AB_PROP_TYPE type
109                 );
110
111 static BOOL     verify_props(
112                     AB_PROP_TYPE type
113                 );
114 static void     turnoff_changebars(
115                     AB_PROP_TYPE type
116                 );
117
118 /*
119  * ABObj callbacks
120  */
121 static int      prop_menubar_obj_destroy_CB(
122                     ObjEvDestroyInfo destroyInfo
123                 );
124 static int      prop_menubar_install_obj_destroy_CB(void);
125
126
127 /*
128  * Xt Callbacks
129  */
130
131 /*************************************************************************
132 **                                                                      **
133 **       Data                                                            **
134 **                                                                      **
135 **************************************************************************/
136 PalItemInfo menubar_palitem_rec = {
137
138     /* type             */  AB_TYPE_CONTAINER,
139     /* name             */  "Menubar",
140     /* animation pixmaps*/  NULL,
141     /* number of pixmaps*/  0,
142     /* rev_prop_frame   */  NULL,
143     /* fix_prop_dialog  */  NULL,
144     /* initialize       */  menubar_initialize,
145     /* is_a_test        */  obj_is_menubar,
146     /* prop_initialize  */  menubar_prop_init,
147     /* prop_activate    */  menubar_prop_activate,
148     /* prop_clear       */  menubar_prop_clear,
149     /* prop_load        */  menubar_prop_load,
150     /* prop_apply       */  menubar_prop_apply,
151     /* prop_pending     */  menubar_prop_pending
152
153 };
154
155 PalItemInfo *ab_menubar_palitem = &menubar_palitem_rec;
156 PropMenubarSettingsRec prop_menubar_settings_rec[AB_PROP_TYPE_NUM_VALUES];
157
158
159 /*************************************************************************
160 **                                                                      **
161 **       Function Definitions                                           **
162 **                                                                      **
163 **************************************************************************/
164 static int
165 menubar_initialize(
166     ABObj    obj
167 )
168 {
169     ABObj       iobj;
170     ABObj       module = obj_get_module(obj);
171     String  cascades[3];
172     int         i;
173
174     obj_set_unique_name(obj, "menubar");
175
176     obj->x = 0;
177     obj->y = 0;
178     obj_set_is_initially_visible(obj, True);
179     obj_set_is_initially_active(obj, True);
180
181     /* Add initial cascades to Choice */
182     cascades[0] = catgets(Dtb_project_catd, 6, 20, "File");
183     cascades[1] = catgets(Dtb_project_catd, 6, 21, "Edit");
184     cascades[2] = catgets(Dtb_project_catd, 6, 25, "Help");
185     for (i=0; i < XtNumber(cascades); i++)
186     {
187         iobj = obj_create(AB_TYPE_ITEM, NULL);
188         obj_set_subtype(iobj, AB_ITEM_FOR_MENUBAR);
189         obj_append_child(obj, iobj);
190         iobj->label_type = AB_LABEL_STRING;
191         obj_set_is_initially_active(iobj, True);
192         obj_set_is_initially_visible(iobj, True);
193         abobj_set_item_name(iobj, obj_get_module(obj), obj_get_name(obj), cascades[i]);
194         obj_set_label(iobj, cascades[i]);
195         if (i == 2)
196             obj_set_is_help_item(iobj, True);
197
198     }
199     return OK;
200
201 }
202
203 static Widget
204 menubar_prop_init(
205     Widget    parent,
206     AB_PROP_TYPE type
207 )
208 {
209     DtbMenubarPropDialogInfoRec rev_menubar_prop_dialog; /* Revolving Props */
210     DtbMenubarPropDialogInfo    cgen = &dtb_menubar_prop_dialog; /* Codegen structure */
211     DtbRevolvPropDialogInfo     rpd = &(dtb_revolv_prop_dialog);
212     PropMenubarSettingsRec      *pms = &(prop_menubar_settings_rec[type]);
213     Widget                      item[6];
214     int                         item_val[6];
215     Widget                      item2[6];
216     int                         item2_val[6];
217     int                         i, n, j;
218
219     if (type == AB_PROP_REVOLVING)
220     {
221         /* Cloning Trick:
222          * Only the Attributes ControlPanel needs to be created within
223          * the existing Revolving Prop dialog, so fill out all other
224          * fields with the Revolving Prop dialog equivelents, so the
225          * dtb initialize proc will skip those non-NULL fields...
226          */
227         dtbMenubarPropDialogInfo_clear(&rev_menubar_prop_dialog);
228
229         cgen = &(rev_menubar_prop_dialog);
230         cgen->prop_dialog = rpd->prop_dialog;
231         cgen->prop_dialog_shellform = rpd->prop_dialog_shellform; 
232         cgen->prop_dialog_panedwin = rpd->prop_dialog_panedwin;
233         cgen->prop_dialog_form = rpd->prop_dialog_form;
234         cgen->objlist_panel = rpd->objlist_panel;
235         cgen->objlist_label = rpd->objlist_label2;
236         cgen->objlist_scrolledwin = rpd->objlist_scrolledwin;
237         cgen->objlist = rpd->objlist;
238         cgen->attrs_ctrlpanel_frame = rpd->attrs_ctrlpanel_frame;
239         cgen->activate_panel = rpd->activate_panel;
240         cgen->apply_button = rpd->apply_button; 
241         cgen->ok_button = rpd->ok_button;
242         cgen->cancel_button = rpd->cancel_button;
243         cgen->reset_button = rpd->reset_button; 
244         cgen->help_button = rpd->help_button; 
245
246         /*
247          * Get notification of object destruction!
248          */  
249         prop_menubar_install_obj_destroy_CB();
250
251     }
252     else /* AB_PROP_FIXED */
253         cgen = &dtb_menubar_prop_dialog; 
254
255     if (dtb_menubar_prop_dialog_initialize(cgen, parent) == 0)
256     {
257         pms->prop_sheet = cgen->attrs_ctrlpanel;
258         pms->current_obj = NULL;
259
260         if (type == AB_PROP_REVOLVING)
261                 XtVaSetValues(parent,
262                         XmNuserData, pms->current_obj,
263                         NULL);
264
265         /* Dialog/Object List */
266         if (type == AB_PROP_FIXED)
267         {
268             prop_fixed_dialog_init(ab_menubar_palitem,
269                         cgen->prop_dialog_shellform, cgen->objlist);
270             prop_activate_panel_init(type, ab_menubar_palitem, 
271                         cgen->ok_button, cgen->apply_button, 
272                         cgen->reset_button, cgen->cancel_button,
273                         cgen->help_button);
274         }
275
276         /* Alternate Editor Buttons */
277         prop_editors_panel_init(type, ab_menubar_palitem,
278             NULL, cgen->conn_button, cgen->helptxt_button);
279
280         /*
281           * Prop Sheet Settings....
282          */
283
284         /* Name */
285         prop_field_init(&(pms->name), cgen->name_field_label,
286                 cgen->name_field, cgen->name_cb);
287
288         /* Initial State */
289         n = 0;
290         item[n] = cgen->istate_ckbox_items.Active_item;
291         item_val[n] = AB_STATE_ACTIVE; n++;
292         prop_checkbox_init(&(pms->init_state), cgen->istate_ckbox_label,
293                 cgen->istate_ckbox, n, item, item_val,
294                 cgen->istate_cb);
295
296         /* Background */
297         prop_colorfield_init(&(pms->bg_color), cgen->bg_mbutton, 
298                 cgen->bg_mbutton_bg_mbutton_menu_items.None_item,
299                 cgen->bg_mbutton_bg_mbutton_menu_items.Color_Chooser_item,
300                 cgen->bg_swatch, cgen->bg_field, cgen->bg_cb);
301
302         /* Foreground */
303         prop_colorfield_init(&(pms->fg_color), cgen->fg_mbutton,
304                 cgen->fg_mbutton_fg_mbutton_menu_items.None_item,  
305                 cgen->fg_mbutton_fg_mbutton_menu_items.Color_Chooser_item, 
306                 cgen->fg_swatch, cgen->fg_field, cgen->fg_cb); 
307
308         /* Item Editor....*/
309
310         /* Item Label */
311         prop_field_init(&(pms->item_label), cgen->item_label_label,
312                 cgen->itemlabel_field, cgen->itemlist_cb);
313         n = 0;
314         item[n] = cgen->itemlabel_opmenu_items.String_item;
315         item_val[n] = AB_LABEL_STRING; n++;
316         item[n] = cgen->itemlabel_opmenu_items.Graphic_item;
317         item_val[n] = AB_LABEL_GLYPH; n++;
318         prop_options_init(&(pms->item_label_type), cgen->item_labeltype_label,
319                 cgen->itemlabel_opmenu, cgen->itemlabel_opmenu_menu,
320                 n, item, (XtPointer*)item_val, cgen->itemlist_cb);
321
322         for(i=0; i < n; i++)
323             XtAddCallback(item[i], XmNactivateCallback,
324                   (XtCallbackProc)prop_item_labeltypeCB, (XtPointer)&(pms->items));
325
326         /* Item Mnemonic */
327         prop_field_init(&(pms->item_mnemonic), cgen->mnemonic_label,
328                 cgen->mnemonic_field, cgen->itemlist_cb);
329
330         /* Item State */
331         n = 0;
332         item[n] = cgen->itemstate_ckbox_items.Active_item;
333         item_val[n] = AB_STATE_ACTIVE; n++;
334         item[n] = cgen->itemstate_ckbox_items.Is_Help_Item_item;
335         item_val[n] = HELP_ITEM_KEY; n++;
336         prop_checkbox_init(&(pms->item_state), cgen->itemstate_label,
337                 cgen->itemstate_ckbox, n, item, item_val,
338                 cgen->itemlist_cb);
339
340         /* Item Menu Name */
341         prop_menuname_init(&(pms->item_menuname), type, cgen->menu_label,
342                         cgen->item_menu_mbutton, 
343                         cgen->item_menu_field,
344                         cgen->itemlabel_field, cgen->itemlist_cb, NULL/*title*/,
345                         &(pms->current_obj), True);
346
347         /* Store Items->Insert menu items in array */
348         n = 0;
349         item[n] = cgen->item_edit_mbutton_editmenu_items.Add_Before_item;
350         item_val[n] = INSERT_BEFORE; n++;
351         item[n] = cgen->item_edit_mbutton_editmenu_items.Add_After_item;
352         item_val[n] = INSERT_AFTER; n++;
353
354         /* Store Items->Edit menu items in array */
355         j = 0;
356         item2[j] = cgen->item_edit_mbutton_editmenu_items.Cut_item;
357         item2_val[j] = AB_EDIT_CUT; j++;
358         item2[j] = cgen->item_edit_mbutton_editmenu_items.Copy_item; 
359         item2_val[j] = AB_EDIT_COPY; j++; 
360         item2[j] = cgen->item_edit_mbutton_editmenu_items.Paste_item; 
361         item2_val[j] = AB_EDIT_PASTE; j++; 
362         item2[j] = cgen->item_edit_mbutton_editmenu_items.Delete_item;  
363         item2_val[j] = AB_EDIT_DELETE; j++;  
364         item2[j] = cgen->item_edit_mbutton_editmenu_items.Change_item;
365         item2_val[j] = EDIT_CHANGE; j++;
366
367         /* Hook up Item Editing mechanism to Item List */
368         prop_item_editor_init(&(pms->items), AB_ITEM_FOR_MENUBAR,
369                 cgen->itemlist, cgen->itemlist_cb, 
370                 cgen->item_add_button,
371                 n, item, item_val, /* Insert */
372                 j, item2, item2_val,/* Edit */
373                 &(pms->item_label), &(pms->item_label_type), cgen->graphic_hint,
374                 &(pms->item_mnemonic), NULL/*accel*/, NULL/*line_style*/,
375                 &(pms->item_state), &(pms->item_menuname),
376                 &(pms->current_obj));
377
378         prop_changebars_cleared(pms->prop_sheet);
379
380         return (cgen->prop_dialog_shellform);
381     }
382     else
383         return NULL;
384
385 }
386
387 static int
388 menubar_prop_activate(
389     AB_PROP_TYPE type,
390     BOOL         active
391 )
392 {
393     ui_set_active(prop_menubar_settings_rec[type].prop_sheet, active);
394
395     return OK;
396 }
397
398
399 static int
400 menubar_prop_clear(
401     AB_PROP_TYPE type
402 )
403 {
404     PropMenubarSettingsRec      *pms = &(prop_menubar_settings_rec[type]);
405
406     if (pms->current_obj == NULL)
407         return OK;
408
409     /* Clear Name */
410     prop_field_set_value(&(pms->name), "", False);
411
412     /* Clear Initial State */
413     prop_checkbox_set_value(&(pms->init_state), AB_STATE_ACTIVE, True, False);
414
415     /* Clear Background Color */
416     prop_colorfield_set_value(&(pms->bg_color), "", False);
417
418     /* Clear Foreground Color */
419     prop_colorfield_set_value(&(pms->fg_color), "", False);
420
421     /* Clear Items */
422     prop_item_editor_clear(&(pms->items));
423
424     pms->current_obj = NULL;
425
426     turnoff_changebars(type);
427
428     return OK;
429 }
430
431
432 static int
433 menubar_prop_load(
434     ABObjPtr     obj,
435     AB_PROP_TYPE type,
436     unsigned long loadkey
437 )
438 {
439     PropMenubarSettingsRec      *pms = &(prop_menubar_settings_rec[type]);
440     BOOL                        load_all = (loadkey & LoadAll);
441  
442     if (obj == NULL)
443     {
444         if (pms->current_obj != NULL)
445             obj = pms->current_obj;
446         else
447             return ERROR;
448     }
449     else if (!obj_is_menubar(obj))
450         return ERROR;
451     else
452         pms->current_obj = obj;
453
454     /* Load Name */
455     if (load_all || loadkey & LoadName)
456         prop_field_set_value(&(pms->name), obj_get_name(obj), False);
457
458     if (load_all)
459     {
460         /* Load Initial State */
461         prop_checkbox_set_value(&(pms->init_state), AB_STATE_ACTIVE,
462                 obj_is_initially_active(obj), False);
463
464         /* Load Color */
465         prop_colorfield_set_value(&(pms->bg_color), obj_get_bg_color(obj), False); 
466         prop_colorfield_set_value(&(pms->fg_color), obj_get_fg_color(obj), False);
467
468         /* Load Items */
469         prop_item_editor_load(&(pms->items), obj);
470  
471         turnoff_changebars(type);
472     }
473         
474     return OK;
475 }
476
477 static int
478 menubar_prop_apply(
479     AB_PROP_TYPE   type
480 )
481 {
482     PropMenubarSettingsRec      *pms = &(prop_menubar_settings_rec[type]);
483     STRING                      value;
484     ABObj                       mb_obj;
485     ABObj                       help_item;
486     BOOL                        reset_bg = False;
487     BOOL                        reset_fg = False;
488
489     if (!verify_props(type))
490         return ERROR;
491
492     if (prop_changed(pms->name.changebar))
493     {
494         value = prop_field_get_value(&(pms->name));     
495         abobj_set_name(pms->current_obj, value);
496         util_free(value);
497     }
498     if (prop_changed(pms->init_state.changebar))
499     {
500         abobj_set_active(pms->current_obj,
501                 prop_checkbox_get_value(&(pms->init_state), AB_STATE_ACTIVE));
502     }
503     if (prop_changed(pms->fg_color.changebar))
504     {
505         value = prop_colorfield_get_value(&(pms->fg_color));     
506         abobj_set_foreground_color(pms->current_obj, value);
507         if (util_strempty(value))
508             reset_fg = True;
509         util_free(value);
510         prop_colorfield_set_value(&(pms->fg_color), 
511                 obj_get_fg_color(pms->current_obj), False);
512     }
513     if (prop_changed(pms->bg_color.changebar))
514     {
515         value = prop_colorfield_get_value(&(pms->bg_color));     
516         abobj_set_background_color(pms->current_obj, value);
517         if (util_strempty(value))
518             reset_bg = True;
519         util_free(value);
520         prop_colorfield_set_value(&(pms->bg_color), 
521                 obj_get_bg_color(pms->current_obj), False);
522     }
523     if (prop_changed(pms->items.changebar))
524     {
525         /* Ensure edits to current item are saved before apply */
526         prop_item_change(&(pms->items), False);
527         prop_item_editor_apply(&(pms->items));
528     }
529
530     abobj_tree_instantiate_changes(pms->current_obj);
531
532     if (reset_bg || reset_fg) /* Set back to No Color */ 
533         abobj_reset_colors(pms->current_obj, reset_bg, reset_fg); 
534
535     /* We must set the Help Cascade AFTER changes have been
536      * instantiated because we require the live Widget-ID of
537      * Help-cascade and this is the only order which guarantees it.
538      */  
539     help_item = obj_get_menubar_help_item(pms->current_obj);
540     mb_obj = objxm_comp_get_subobj(pms->current_obj, AB_CFG_OBJECT_OBJ);
541
542     XtVaSetValues(objxm_get_widget(mb_obj),
543                 XmNmenuHelpWidget, help_item? objxm_get_widget(help_item): NULL,
544                 NULL);
545
546     turnoff_changebars(type);
547
548     return OK;
549 }
550
551 static BOOL
552 menubar_prop_pending(
553     AB_PROP_TYPE type
554 )
555 {
556     return(prop_changebars_pending(prop_menubar_settings_rec[type].prop_sheet));
557 }
558
559 static BOOL
560 verify_props(
561     AB_PROP_TYPE type
562 )
563 {
564     PropMenubarSettingsRec *pms = &(prop_menubar_settings_rec[type]);
565
566     if (prop_changed(pms->name.changebar) &&
567         !prop_name_ok(pms->current_obj, pms->name.field))
568         return False;
569
570     if (prop_changed(pms->fg_color.changebar) && !prop_color_ok(pms->fg_color.field))
571         return False;
572  
573     if (prop_changed(pms->bg_color.changebar) && !prop_color_ok(pms->bg_color.field))
574         return False;
575
576     return True;
577 }
578
579 static void
580 turnoff_changebars(
581     AB_PROP_TYPE type
582 )
583 {
584     PropMenubarSettingsRec *pms = &(prop_menubar_settings_rec[type]);
585
586     prop_set_changebar(pms->name.changebar,     PROP_CB_OFF);
587     prop_set_changebar(pms->init_state.changebar,PROP_CB_OFF);
588     prop_set_changebar(pms->bg_color.changebar,  PROP_CB_OFF);
589     prop_set_changebar(pms->fg_color.changebar,  PROP_CB_OFF);
590     prop_set_changebar(pms->items.changebar,     PROP_CB_OFF);
591
592     prop_changebars_cleared(pms->prop_sheet);
593
594 }
595
596 /*
597  * Object destroy callback
598  */
599 static int
600 prop_menubar_install_obj_destroy_CB()
601 {
602     static BOOL callback_installed = False;
603
604     if (callback_installed)
605     {
606         return 0;
607     }
608     obj_add_destroy_callback(prop_menubar_obj_destroy_CB, "Menubar Props");
609     return 0;
610 }
611
612 static int
613 prop_menubar_obj_destroy_CB(ObjEvDestroyInfo destroyInfo)
614 {
615     int                 i;
616     ABObj               doomedObj = destroyInfo->obj;
617     PropMenubarSettingsRec *pms;
618
619
620     if (!   (obj_is_item(doomedObj) && 
621             (obj_get_item_type(doomedObj) == AB_ITEM_FOR_MENUBAR)) )
622     {
623         return 0;
624     }
625
626     for (i = 0; i < AB_PROP_TYPE_NUM_VALUES; ++i)
627     {
628         pms = &(prop_menubar_settings_rec[i]);
629
630         if (pms->current_obj == doomedObj)
631             pms->current_obj = NULL;
632         if (pms->items.current_item == doomedObj)
633             pms->items.current_item = NULL;
634         if (pms->items.clipboard_item == doomedObj)
635             pms->items.clipboard_item = NULL;
636     }
637
638     return 0;
639 }