2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
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
23 /* $TOG: MenuBar.C /main/6 1997/06/03 16:12:28 mgreess $ */
27 * RESTRICTED CONFIDENTIAL INFORMATION:
29 * The information in this document is subject to special
30 * restrictions in a confidential disclosure agreement bertween
31 * HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
32 * document outside HP, IBM, Sun, USL, SCO, or Univel wihtout
33 * Sun's specific written approval. This documment and all copies
34 * and derivative works thereof must be returned or destroyed at
37 * Copyright 1993, 1994, 1995 Sun Microsystems, Inc. All rights reserved.
41 ///////////////////////////////////////////////////////////////////////////////
42 //////////////////////////////////////////////////////////////////////////////
43 // This example code is from the book:
45 // Object-Oriented Programming with C++ and OSF/Motif
48 // Prentice Hall, 1992
51 // Copyright 1991 by Prentice Hall
52 // All Rights Reserved
54 // Permission to use, copy, modify, and distribute this software for
55 // any purpose except publication and without fee is hereby granted, provided
56 // that the above copyright notice appear in all copies of the software.
57 ///////////////////////////////////////////////////////////////////////////////
58 //////////////////////////////////////////////////////////////////////////////
61 //////////////////////////////////////////////////////////
62 // MenuBar.C: A menu bar whose panes support items
64 //////////////////////////////////////////////////////////
66 ////////////////////////////////////////////////////////////
67 // MODIFIED TO SUPPORT SUBMENUS - not described in Book
68 ///////////////////////////////////////////////////////////
71 #include "Application.h"
75 #include "ToggleButtonInterface.h"
76 #include "ButtonInterface.h"
78 #include <Xm/RowColumn.h>
79 #include <Xm/CascadeB.h>
80 #include <Xm/Separator.h>
86 extern XtPointer _XmStringUngenerate (
90 XmTextType output_type);
93 MenuBar::MenuBar ( Widget parent, char *name, unsigned char type )
94 : UIComponent ( name )
96 // Base widget is a Motif menu bar widget
101 if( type == XmMENU_POPUP) {
105 XtSetArg(args[i], XmNwhichButton, theApplication->bMenuButton()); i++;
106 _w = XmCreatePopupMenu( parent, _name, args, i );
107 // XtVaSetValues(_w, XmNwhichButton, theApplication->bMenuButton(), NULL);
109 type = XmMENU_BAR; // Force it to menu bar
110 _w = XmCreateMenuBar ( parent, _name, NULL, 0 );
113 printHelpId("_w", _w);
114 /* install callback */
115 // XtAddCallback(_w, XmNhelpCallback, HelpCB, helpId);
117 installDestroyHandler();
119 Widget MenuBar::addCommands ( Widget *menuBarCascade, CmdList *list, Boolean help, unsigned char type )
121 return( createPulldown ( _w, list, menuBarCascade, help, type ) );
124 Widget MenuBar::addCommands ( CmdList *list, Boolean help, unsigned char type )
126 return( createPulldown ( _w, list, help, type ) );
130 MenuBar::createPulldown (
143 if(type != XmMENU_POPUP)
146 // Create a pulldown menu pane for this list of commands
148 if( type == XmMENU_BAR) {
149 pulldown = XmCreatePulldownMenu( parent,
150 (char *) list->name(), NULL, 0 );
151 label_str = XmStringCreateLocalized(list->getLabel());
152 XtVaSetValues(pulldown,
153 XmNlabelString, label_str,
155 printHelpId("pulldown", pulldown);
156 /* install callback */
157 // XtAddCallback(pulldown, XmNhelpCallback, HelpCB, helpId);
160 // Each entry in the menu bar must have a cascade button
161 // from which the user can pull down the pane
163 if (cascade != NULL && *cascade != NULL)
164 XtVaSetValues (*cascade, XmNsubMenuId, pulldown,
165 XmNlabelString, label_str,
169 XtSetArg(args2[0], XmNsubMenuId, pulldown);
170 *cascade = XtCreateWidget ( list->name(),
171 xmCascadeButtonWidgetClass,
174 XtVaSetValues(*cascade,
175 XmNlabelString, label_str,
178 XtSetArg (args2[0], XmNmenuHelpWidget, *cascade);
179 XtSetValues (parent, args2, 1);
182 XtManageChild ( *cascade );
183 printHelpId("cascade", *cascade);
184 /* install callback */
187 // Install callbacks for each of the
188 // pulldown menus so we can get
189 // On Item help for them.
191 helpId = XtName(*cascade);
192 if (helpId == "Mailbox") {
193 XtAddCallback(*cascade, XmNhelpCallback,
194 HelpCB, (void *)DTMAILCONTAINERMENUID);
195 } else if (helpId == "Edit") {
196 XtAddCallback(*cascade, XmNhelpCallback,
197 HelpCB, (void *)DTMAILEDITMENUID);
198 } else if (helpId == "Message") {
199 XtAddCallback(*cascade, XmNhelpCallback,
200 HelpCB, (void *)DTMAILMESSAGEMENUID);
201 } else if (helpId == "Attachments") {
202 XtAddCallback(*cascade, XmNhelpCallback,
203 HelpCB, (void *)DTMAILATTACHMENUID);
204 } else if (helpId == "View") {
205 XtAddCallback(*cascade, XmNhelpCallback,
206 HelpCB, (void *)DTMAILVIEWMENUID);
207 } else if (helpId == "Compose") {
208 XtAddCallback(*cascade, XmNhelpCallback,
209 HelpCB, (void *)DTMAILCOMPOSEMENUID);
217 // Loop through the cmdList, creating a menu
218 // entry for each command.
219 Widget *head_wl, *wl;
221 head_wl = wl = new Widget[ list->size() ];
223 for ( i = 0; i < list->size(); i++)
226 if(!strcmp((*list)[i]->className(), "CmdList")) {
227 Widget pane = createPulldown(pulldown,
228 (CmdList*) (*list)[i], FALSE, XmMENU_BAR);
229 ((CmdList *)(*list)[i])->setPaneWidget(pane);
230 label_str = XmStringCreateLocalized(((CmdList *)(*list)[i])->getLabel());
232 XmNlabelString, label_str,
235 if ( !strcmp((*list)[i]->className(),"SeparatorCmd")) {
236 *(wl++) = XtCreateWidget ( (*list)[i]->name(),
237 xmSeparatorWidgetClass,
240 } else if (!strcmp((*list)[i]->className(),"ToggleButtonCmd")) {
242 ci = new ToggleButtonInterface(pulldown, (*list)[i] );
243 *(wl++) = ci->baseWidget();
244 } else if(!strcmp((*list)[i]->className(),"LabelCmd")) {
245 label_str = XmStringCreateLocalized((*list)[i]->getLabel());
247 *(wl++) = XtVaCreateWidget ( (*list)[i]->name(),
250 XmNlabelString, label_str,
254 ci = new ButtonInterface ( pulldown, (*list)[i] );
255 *(wl++) = ci->baseWidget();
262 XtManageChildren ( head_wl, num_wl );
269 MenuBar::createPulldown (
276 Widget pulldown, cascade;
281 if(type != XmMENU_POPUP)
284 // Create a pulldown menu pane for this list of commands
286 if( type == XmMENU_BAR) {
287 pulldown = XmCreatePulldownMenu( parent,
288 (char *) list->name(), NULL, 0 );
289 label_str = XmStringCreateLocalized(list->getLabel());
290 XtVaSetValues(pulldown,
291 XmNlabelString, label_str,
293 printHelpId("pulldown", pulldown);
294 /* install callback */
295 // XtAddCallback(pulldown, XmNhelpCallback, HelpCB, helpId);
298 // Each entry in the menu bar must have a cascade button
299 // from which the user can pull down the pane
301 XtSetArg(args2[0], XmNsubMenuId, pulldown);
302 cascade = XtCreateWidget ( list->name(),
303 xmCascadeButtonWidgetClass,
306 XtVaSetValues(cascade,
307 XmNlabelString, label_str,
310 XtSetArg (args2[0], XmNmenuHelpWidget, cascade);
311 XtSetValues (parent, args2, 1);
314 XtManageChild ( cascade );
315 printHelpId("cascade", cascade);
316 /* install callback */
319 // Install callbacks for each of the
320 // pulldown menus so we can get
321 // On Item help for them.
323 helpId = XtName(cascade);
324 if (helpId == "Mailbox") {
325 XtAddCallback(cascade, XmNhelpCallback,
326 HelpCB, (void *)DTMAILCONTAINERMENUID);
327 } else if (helpId == "Edit") {
328 XtAddCallback(cascade, XmNhelpCallback,
329 HelpCB, (void *)DTMAILEDITMENUID);
330 } else if (helpId == "Message") {
331 XtAddCallback(cascade, XmNhelpCallback,
332 HelpCB, (void *)DTMAILMESSAGEMENUID);
333 } else if (helpId == "Attachments") {
334 XtAddCallback(cascade, XmNhelpCallback,
335 HelpCB, (void *)DTMAILATTACHMENUID);
336 } else if (helpId == "View") {
337 XtAddCallback(cascade, XmNhelpCallback,
338 HelpCB, (void *)DTMAILVIEWMENUID);
339 } else if (helpId == "Compose") {
340 XtAddCallback(cascade, XmNhelpCallback,
341 HelpCB, (void *)DTMAILCOMPOSEMENUID);
348 // Loop through the cmdList, creating a menu
349 // entry for each command.
351 for ( i = 0; i < list->size(); i++)
354 if(!strcmp((*list)[i]->className(), "CmdList")) {
355 Widget pane = createPulldown(pulldown,
356 (CmdList*) (*list)[i], FALSE, XmMENU_BAR);
357 ((CmdList *)(*list)[i])->setPaneWidget(pane);
358 label_str = XmStringCreateLocalized((*list)[i]->getLabel());
360 XmNlabelString, label_str,
363 if ( !strcmp((*list)[i]->className(),"SeparatorCmd")) {
364 XtCreateManagedWidget ( (*list)[i]->name(),
365 xmSeparatorWidgetClass,
368 } else if (!strcmp((*list)[i]->className(),"ToggleButtonCmd")) {
370 ci = new ToggleButtonInterface(pulldown, (*list)[i]);
372 } else if(!strcmp((*list)[i]->className(),"LabelCmd")) {
377 _i18n = XtCreateManagedWidget(
384 xms = XmStringCreateLocalized((char*) (*list)[i]->getLabel());
385 XtSetArg( _args[0], XmNlabelString, xms );
386 XtSetValues( _i18n, _args, 1 );
390 ci = new ButtonInterface ( pulldown, (*list)[i] );
398 // SR - Added to handle dynamic menus
401 MenuBar::addCommands(
406 // if(isValidMenuPane(pulldown) == FALSE)
410 XtArgVal num_children;
412 Boolean haveNoSeparator;
413 int newItemIndex, numPBUnmanaged, tmpPBUnmanaged;
415 XtVaGetValues(pulldown,
416 XmNnumChildren, &num_children,
419 children = (WidgetList)XtMalloc(sizeof(Widget) * num_children);
421 XtVaGetValues(pulldown,
422 XmNchildren, &children,
425 // Handle the creation or management of the Separator.
427 haveNoSeparator = TRUE;
430 for (i=0; (i < num_children); i++) {
431 Widget wid = (Widget) children[i];
432 if (XtIsSubclass(wid, xmSeparatorWidgetClass)) {
434 haveNoSeparator = FALSE;
436 else if (XtIsSubclass(wid, xmPushButtonWidgetClass)) {
437 if (!XtIsManaged(wid)) { // If widget is unmanaged
442 if (haveNoSeparator) {
443 XtCreateManagedWidget ("Separator",
444 xmSeparatorWidgetClass,
447 haveNoSeparator = FALSE;
450 // Now handle the pushButton case
455 // Loop through the cmdList, creating a menu
456 // entry for each command.
458 for (newItemIndex = 0; newItemIndex < new_list->size(); newItemIndex++) {
460 tmpPBUnmanaged = numPBUnmanaged;
462 if (numPBUnmanaged > 0) { // If there exists unmanaged PBs
464 (i < num_children) &&
465 (tmpPBUnmanaged == numPBUnmanaged);
468 Widget wid = (Widget) children[i];
470 if (XtIsSubclass(wid, xmPushButtonWidgetClass)) {
471 if (!XtIsManaged(wid)) {
472 // If widget is unmanaged
473 // Set its label to be the newItemIndex widget's.
475 // Bump up newItemIndex
477 XmNlabelString, XmStringCreateLocalized(
478 (char *) (*new_list)[newItemIndex]->getLabel()),
486 else { // No unmanaged push buttons available
488 ci = new ButtonInterface (
489 pulldown, (*new_list)[newItemIndex]
499 MenuBar::removeOnlyCommands(
501 CmdList *redundant_list
504 // if(isValidMenuPane(pulldown) == FALSE)
508 XtArgVal num_children;
511 XtVaGetValues(pulldown,
512 XmNnumChildren, &num_children,
515 children = (WidgetList)XtMalloc(sizeof(Widget) * num_children);
517 XtVaGetValues(pulldown,
518 XmNchildren, &children,
521 // Loop through widget list. Destroy those widgets that map to those
522 // in the redundant list.
524 for (i=0; i<num_children; i++) {
526 Widget wid = (Widget) children[i];
528 if (XtIsSubclass(wid, xmPushButtonWidgetClass)) {
530 for (j=0; j<redundant_list->size(); j++) {
532 ButtonInterface::mapName((*redundant_list)[j]->name(), name);
533 if (strcmp(XtName(wid), name) == 0) {
534 // The redundant item has been found.
535 XtUnmanageChild(wid);
542 MenuBar::removeCommands(
544 CmdList *redundant_list
547 // if(isValidMenuPane(pulldown) == FALSE)
551 XtArgVal num_children;
554 XtVaGetValues(pulldown,
555 XmNnumChildren, &num_children,
558 children = (WidgetList)XtMalloc(sizeof(Widget) * num_children);
560 XtVaGetValues(pulldown,
561 XmNchildren, &children,
564 // Loop through widget list. Destroy those widgets that map to those
565 // in the redundant list.
567 for (i=0; i<num_children; i++) {
569 Widget wid = (Widget) children[i];
571 if (XtIsSubclass(wid, xmSeparatorWidgetClass)) {
572 XtUnmanageChild(wid);
574 else if (XtIsSubclass(wid, xmPushButtonWidgetClass)) {
576 for (j=0; j<redundant_list->size(); j++) {
579 XtVaGetValues(wid, XmNlabelString, &str, NULL);
580 if (str == NULL) continue;
582 label = (char *) _XmStringUngenerate(
584 XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
586 if (label == NULL) continue;
587 if (strcmp(label, (*redundant_list)[j]->getLabel()) == 0) {
588 // The redundant item has been found.
589 XtUnmanageChild(wid);
603 // if(isValidMenuPane(pulldown) == FALSE)
607 ci = new ButtonInterface ( pulldown, cmd);
612 MenuBar::changeLabel(
618 // if(isValidMenuPane(pulldown) == FALSE)
621 int managed_widgets, i;
622 XtArgVal num_children;
627 XtVaGetValues(pulldown,
628 XmNnumChildren, &num_children,
631 children = (WidgetList)XtMalloc(sizeof(Widget) * num_children);
633 XtVaGetValues(pulldown,
634 XmNchildren, &children,
637 // Some widgets may be unmanaged, so find the real index
638 for (managed_widgets=0, i=0;
639 managed_widgets <= index && i < num_children; i++) {
640 wid = (Widget) children[i];
641 if (XtIsManaged(wid)) managed_widgets++;
643 if (--i >= num_children) return;
645 wid = (Widget) children[i];
647 label = XmStringCreateLocalized(name);
650 XmNlabelString, label,
656 MenuBar::changeLabel(Widget pulldown,
657 const char * button_name,
660 // if(isValidMenuPane(pulldown) == FALSE)
663 // Locate the appropriate widget in the list.
665 XtArgVal num_children;
667 XmString label_string = XmStringCreateLocalized((char *)label);
669 ButtonInterface::mapName(button_name, wid_name);
671 XtVaGetValues(pulldown,
672 XmNnumChildren, &num_children,
675 Widget * children = new Widget[num_children];
676 XtVaGetValues(pulldown,
677 XmNchildren, &children,
680 for (int wid = 0; wid < num_children; wid++) {
681 if (strcmp(XtName(children[wid]), wid_name) == 0) {
682 if (XtIsManaged(children[wid]))
683 XtVaSetValues(children[wid],
684 XmNlabelString, label_string,
689 XmStringFree(label_string);
693 MenuBar::rotateLabels(
699 // if(isValidMenuPane(pulldown) == FALSE)
702 int num_managed_wids=0, i, j, num_to_change;
703 XtArgVal num_children;
705 XmString label, endlabel;
708 if (startindex < 0 || endindex < 0)
711 XtVaGetValues(pulldown,
712 XmNnumChildren, &num_children,
715 if (startindex >= num_children || endindex >= num_children)
718 num_to_change = endindex - startindex;
719 if (num_children < num_to_change || num_to_change == 0)
722 children = (WidgetList)XtMalloc(sizeof(Widget) * num_children);
724 XtVaGetValues(pulldown,
725 XmNchildren, &children,
728 // Some of the widgets may be unmanaged: find the first managed widget
729 for (i = startindex; i < num_children; i++) {
730 if (XtIsManaged(children[i]))
735 if (startindex == num_children)
738 // Find the real endindex
739 endindex = startindex+1;
740 while (endindex < num_children) {
741 if (XtIsManaged(children[endindex]))
743 if (num_managed_wids == num_to_change)
744 // We have found the endindex at this point
749 if (endindex == num_children)
752 wid = (Widget) children[endindex];
754 XmNlabelString, &label,
756 endlabel = XmStringCopy(label);
759 while (i > startindex) {
762 if (--j < startindex) break;
763 prevwid = (Widget) children[j];
764 } while (!XtIsManaged(prevwid));
766 XtVaGetValues(prevwid,
767 XmNlabelString, &label,
771 XmNlabelString, label,
776 wid = (Widget) children[i];
779 wid = (Widget) children[startindex];
781 XmNlabelString, endlabel,
784 XmStringFree(endlabel);
789 MenuBar::isValidMenuPane(Widget w)
791 Boolean retval = FALSE;
794 while(parent && parent != _w)
795 parent = XtParent(parent);
802 #endif /* DEAD_WOOD */
805 MenuBar::removeCommand(
810 //if(isValidMenuPane(pulldown) == FALSE)
813 int managed_widgets, i;
814 XtArgVal num_children;
817 XtVaGetValues(pulldown,
818 XmNnumChildren, &num_children,
821 children = (WidgetList)XtMalloc(sizeof(Widget) * num_children);
823 XtVaGetValues(pulldown,
824 XmNchildren, &children,
827 // Some widgets may be unmanaged, so find the real index
828 for (managed_widgets=0, i=0;
829 managed_widgets <= index && i < num_children; i++) {
830 Widget wid = (Widget) children[i];
831 if (XtIsManaged(wid)) managed_widgets++;
834 if (--i < num_children)
835 XtUnmanageChild(children[i]);