1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/menu_osx.cpp
3 // Purpose: wxMenu, wxMenuBar, wxMenuItem
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
13 // headers & declarations
14 // ============================================================================
19 #include "wx/wxprec.h"
30 #include "wx/dialog.h"
31 #include "wx/menuitem.h"
34 #include "wx/osx/private.h"
36 // other standard headers
37 // ----------------------
40 IMPLEMENT_ABSTRACT_CLASS( wxMenuImpl
, wxObject
)
42 wxMenuImpl::~wxMenuImpl()
46 // the (popup) menu title has this special menuid
47 static const int idMenuTitle
= -3;
49 // ============================================================================
51 // ============================================================================
55 // Construct a menu with optional title (then use append)
60 m_startRadioGroup
= -1;
61 m_allowRearrange
= true;
62 m_noEventsMode
= false;
64 m_peer
= wxMenuImpl::Create( this, wxStripMenuCodes(m_title
) );
67 // if we have a title, insert it in the beginning of the menu
68 if ( !m_title
.empty() )
70 Append(idMenuTitle
, m_title
) ;
80 WXHMENU
wxMenu::GetHMenu() const
83 return m_peer
->GetHMenu();
89 // not available on the mac platform
92 void wxMenu::Attach(wxMenuBarBase
*menubar
)
94 wxMenuBase::Attach(menubar
);
99 void wxMenu::SetAllowRearrange( bool allow
)
101 m_allowRearrange
= allow
;
104 void wxMenu::SetNoEventsMode( bool noEvents
)
106 m_noEventsMode
= noEvents
;
109 // function appends a new item or submenu to the menu
110 // append a new item or submenu to the menu
111 bool wxMenu::DoInsertOrAppend(wxMenuItem
*pItem
, size_t pos
)
113 wxASSERT_MSG( pItem
!= NULL
, wxT("can't append NULL item to the menu") );
114 GetPeer()->InsertOrAppend( pItem
, pos
);
116 if ( pItem
->IsSeparator() )
118 // nothing to do here
122 wxMenu
*pSubMenu
= pItem
->GetSubMenu() ;
123 if ( pSubMenu
!= NULL
)
125 wxASSERT_MSG( pSubMenu
->GetHMenu() != NULL
, wxT("invalid submenu added"));
126 pSubMenu
->m_menuParent
= this ;
128 pSubMenu
->DoRearrange();
132 if ( pItem
->GetId() == idMenuTitle
)
133 pItem
->GetMenu()->Enable( idMenuTitle
, false );
137 // if we're already attached to the menubar, we must update it
138 if ( IsAttached() && GetMenuBar()->IsAttached() )
139 GetMenuBar()->Refresh();
144 void wxMenu::EndRadioGroup()
146 // we're not inside a radio group any longer
147 m_startRadioGroup
= -1;
150 wxMenuItem
* wxMenu::DoAppend(wxMenuItem
*item
)
152 wxCHECK_MSG( item
, NULL
, wxT("NULL item in wxMenu::DoAppend") );
156 if ( item
->GetKind() == wxITEM_RADIO
)
158 int count
= GetMenuItemCount();
160 if ( m_startRadioGroup
== -1 )
162 // start a new radio group
163 m_startRadioGroup
= count
;
165 // for now it has just one element
166 item
->SetAsRadioGroupStart();
167 item
->SetRadioGroupEnd(m_startRadioGroup
);
169 // ensure that we have a checked item in the radio group
172 else // extend the current radio group
174 // we need to update its end item
175 item
->SetRadioGroupStart(m_startRadioGroup
);
176 wxMenuItemList::compatibility_iterator node
= GetMenuItems().Item(m_startRadioGroup
);
180 node
->GetData()->SetRadioGroupEnd(count
);
184 wxFAIL_MSG( wxT("where is the radio group start item?") );
188 else // not a radio item
193 if ( !wxMenuBase::DoAppend(item
) || !DoInsertOrAppend(item
) )
197 // check the item initially
203 wxMenuItem
* wxMenu::DoInsert(size_t pos
, wxMenuItem
*item
)
205 if (wxMenuBase::DoInsert(pos
, item
) && DoInsertOrAppend(item
, pos
))
211 wxMenuItem
*wxMenu::DoRemove(wxMenuItem
*item
)
213 if ( m_startRadioGroup
!= -1 )
215 // Check if we're removing the item starting the radio group
216 if ( GetMenuItems().Item(m_startRadioGroup
)->GetData() == item
)
218 // Yes, we do, so reset its index as the next item added shouldn't
219 // count as part of the same radio group anyhow.
220 m_startRadioGroup
= -1;
225 // we need to find the items position in the child list
227 wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst();
229 for ( pos = 0; node; pos++ )
231 if ( node->GetData() == item )
234 node = node->GetNext();
237 // DoRemove() (unlike Remove) can only be called for existing item!
238 wxCHECK_MSG( node, NULL, wxT("bug in wxMenu::Remove logic") );
240 wxOSXMenuRemoveItem(m_hMenu , pos );
242 GetPeer()->Remove( item
);
243 // and from internal data structures
244 return wxMenuBase::DoRemove(item
);
247 void wxMenu::SetTitle(const wxString
& label
)
250 GetPeer()->SetTitle( wxStripMenuCodes( label
) );
253 bool wxMenu::ProcessCommand(wxCommandEvent
& event
)
255 bool processed
= false;
257 // Try the menu's event handler
258 if ( /* !processed && */ GetEventHandler())
259 processed
= GetEventHandler()->SafelyProcessEvent(event
);
261 // Try the window the menu was popped up from
262 // (and up through the hierarchy)
263 wxWindow
*win
= GetWindow();
264 if ( !processed
&& win
)
265 processed
= win
->HandleWindowEvent(event
);
270 // ---------------------------------------------------------------------------
272 // ---------------------------------------------------------------------------
274 // MacOS needs to know about submenus somewhere within this menu
275 // before it can be displayed, also hide special menu items
276 // like preferences that are handled by the OS
277 void wxMenu::DoRearrange()
279 if ( !AllowRearrange() )
282 wxMenuItem
* previousItem
= NULL
;
284 wxMenuItemList::compatibility_iterator node
;
287 for (pos
= 0, node
= GetMenuItems().GetFirst(); node
; node
= node
->GetNext(), pos
++)
289 item
= (wxMenuItem
*)node
->GetData();
290 wxMenu
* subMenu
= item
->GetSubMenu() ;
297 // what we do here is to hide the special items which are
298 // shown in the application menu anyhow -- it doesn't make
299 // sense to show them in their normal place as well
300 if ( item
->GetId() == wxApp::s_macAboutMenuItemId
||
301 item
->GetId() == wxApp::s_macPreferencesMenuItemId
||
302 item
->GetId() == wxApp::s_macExitMenuItemId
)
305 item
->GetPeer()->Hide( true );
307 // also check for a separator which was used just to
308 // separate this item from the others, so don't leave
309 // separator at the menu start or end nor 2 consecutive
311 wxMenuItemList::compatibility_iterator nextNode
= node
->GetNext();
312 wxMenuItem
*next
= nextNode
? nextNode
->GetData() : NULL
;
314 wxMenuItem
*sepToHide
= 0;
315 if ( !previousItem
&& next
&& next
->IsSeparator() )
317 // next (i.e. second as we must be first) item is
318 // the separator to hide
319 wxASSERT_MSG( pos
== 0, wxT("should be the menu start") );
322 else if ( GetMenuItems().GetCount() == pos
+ 1 &&
323 previousItem
!= NULL
&&
324 previousItem
->IsSeparator() )
326 // prev item is a trailing separator we want to hide
327 sepToHide
= previousItem
;
329 else if ( previousItem
&& previousItem
->IsSeparator() &&
330 next
&& next
->IsSeparator() )
332 // two consecutive separators, this is one too many
338 // hide the separator as well
339 sepToHide
->GetPeer()->Hide( true );
344 previousItem
= item
;
349 bool wxMenu::HandleCommandUpdateStatus( wxMenuItem
* item
, wxWindow
* senderWindow
)
351 int menuid
= item
? item
->GetId() : 0;
352 wxUpdateUIEvent
event(menuid
);
353 event
.SetEventObject( this );
355 bool processed
= false;
357 // Try the menu's event handler
359 wxEvtHandler
*handler
= GetEventHandler();
361 processed
= handler
->ProcessEvent(event
);
364 // Try the window the menu was popped up from
365 // (and up through the hierarchy)
368 wxWindow
*win
= GetWindow();
370 processed
= win
->HandleWindowEvent(event
);
373 if ( !processed
&& senderWindow
!= NULL
)
375 processed
= senderWindow
->HandleWindowEvent(event
);
380 // if anything changed, update the changed attribute
381 if (event
.GetSetText())
382 SetLabel(menuid
, event
.GetText());
383 if (event
.GetSetChecked())
384 Check(menuid
, event
.GetChecked());
385 if (event
.GetSetEnabled())
386 Enable(menuid
, event
.GetEnabled());
391 // these two items are also managed by the Carbon Menu Manager, therefore we must
392 // always reset them ourselves
395 if ( menuid
== wxApp::s_macExitMenuItemId
)
397 cmd
= kHICommandQuit
;
399 else if (menuid
== wxApp::s_macPreferencesMenuItemId
)
401 cmd
= kHICommandPreferences
;
406 if ( !item
->IsEnabled() || wxDialog::OSXHasModalDialogsOpen() )
407 DisableMenuCommand( NULL
, cmd
) ;
409 EnableMenuCommand( NULL
, cmd
) ;
418 bool wxMenu::HandleCommandProcess( wxMenuItem
* item
, wxWindow
* senderWindow
)
420 int menuid
= item
? item
->GetId() : 0;
421 bool processed
= false;
422 if (item
->IsCheckable())
423 item
->Check( !item
->IsChecked() ) ;
425 if ( SendEvent( menuid
, item
->IsCheckable() ? item
->IsChecked() : -1 ) )
429 if ( senderWindow
!= NULL
)
431 wxCommandEvent
event(wxEVT_MENU
, menuid
);
432 event
.SetEventObject(this);
433 event
.SetInt(item
->IsCheckable() ? item
->IsChecked() : -1);
435 if ( senderWindow
->HandleWindowEvent(event
) )
440 if(!processed
&& item
)
442 processed
= item
->GetPeer()->DoDefault();
448 void wxMenu::HandleMenuItemHighlighted( wxMenuItem
* item
)
450 int menuid
= item
? item
->GetId() : 0;
451 wxMenuEvent
wxevent(wxEVT_MENU_HIGHLIGHT
, menuid
, this);
452 DoHandleMenuEvent( wxevent
);
455 void wxMenu::DoHandleMenuOpenedOrClosed(wxEventType evtType
)
457 // Popup menu being currently shown or NULL, defined in wincmn.cpp.
458 extern wxMenu
*wxCurrentPopupMenu
;
460 // Set the id to allow wxMenuEvent::IsPopup() to work correctly.
461 int menuid
= this == wxCurrentPopupMenu
? wxID_ANY
: 0;
462 wxMenuEvent
wxevent(evtType
, menuid
, this);
463 DoHandleMenuEvent( wxevent
);
466 void wxMenu::HandleMenuOpened()
468 DoHandleMenuOpenedOrClosed(wxEVT_MENU_OPEN
);
471 void wxMenu::HandleMenuClosed()
473 DoHandleMenuOpenedOrClosed(wxEVT_MENU_CLOSE
);
476 bool wxMenu::DoHandleMenuEvent(wxEvent
& wxevent
)
478 wxevent
.SetEventObject(this);
479 wxEvtHandler
* handler
= GetEventHandler();
480 if (handler
&& handler
->ProcessEvent(wxevent
))
486 wxWindow
*win
= GetWindow();
489 if ( win
->HandleWindowEvent(wxevent
) )
500 Mac Implementation note :
502 The Mac has only one global menubar, so we attempt to install the currently
503 active menubar from a frame, we currently don't take into account mdi-frames
504 which would ask for menu-merging
506 Secondly there is no mac api for changing a menubar that is not the current
507 menubar, so we have to wait for preparing the actual menubar until the
508 wxMenubar is to be used
510 We can in subsequent versions use MacInstallMenuBar to provide some sort of
511 auto-merge for MDI in case this will be necessary
515 wxMenuBar
* wxMenuBar::s_macInstalledMenuBar
= NULL
;
516 wxMenuBar
* wxMenuBar::s_macCommonMenuBar
= NULL
;
517 bool wxMenuBar::s_macAutoWindowMenu
= true ;
518 WXHMENU
wxMenuBar::s_macWindowMenuHandle
= NULL
;
521 wxMenu
* emptyMenuBar
= NULL
;
523 const int firstMenuPos
= 1; // to account for the 0th application menu on mac
525 void wxMenuBar::Init()
527 if ( emptyMenuBar
== NULL
)
529 emptyMenuBar
= new wxMenu();
531 wxMenu
* appleMenu
= new wxMenu();
532 appleMenu
->SetAllowRearrange(false);
533 #if !wxOSX_USE_CARBON
534 // standard menu items, handled in wxMenu::HandleCommandProcess(), see above:
536 hideLabel
= wxString::Format(_("Hide %s"), wxTheApp
? wxTheApp
->GetAppDisplayName() : _("Application"));
537 appleMenu
->Append( wxID_OSX_HIDE
, hideLabel
+ "\tCtrl+H" );
538 appleMenu
->Append( wxID_OSX_HIDEOTHERS
, _("Hide Others")+"\tAlt+Ctrl+H" );
539 appleMenu
->Append( wxID_OSX_SHOWALL
, _("Show All") );
540 appleMenu
->AppendSeparator();
542 // Do always add "Quit" item unconditionally however, it can't be disabled.
544 quitLabel
= wxString::Format(_("Quit %s"), wxTheApp
? wxTheApp
->GetAppDisplayName() : _("Application"));
545 appleMenu
->Append( wxApp::s_macExitMenuItemId
, quitLabel
+ "\tCtrl+Q" );
546 #endif // !wxOSX_USE_CARBON
548 emptyMenuBar
->AppendSubMenu(appleMenu
, "\x14") ;
551 m_eventHandler
= this;
552 m_menuBarFrame
= NULL
;
553 m_rootMenu
= new wxMenu();
554 m_rootMenu
->Attach(this);
556 m_appleMenu
= new wxMenu();
557 m_appleMenu
->SetAllowRearrange(false);
559 // Create standard items unless the application explicitly disabled this by
560 // setting the corresponding ids to wxID_NONE: although this is not
561 // recommended, sometimes these items really don't make sense.
562 if ( wxApp::s_macAboutMenuItemId
!= wxID_NONE
)
564 wxString
aboutLabel(_("About"));
566 aboutLabel
<< ' ' << wxTheApp
->GetAppDisplayName();
569 m_appleMenu
->Append( wxApp::s_macAboutMenuItemId
, aboutLabel
);
570 m_appleMenu
->AppendSeparator();
573 #if !wxOSX_USE_CARBON
574 if ( wxApp::s_macPreferencesMenuItemId
!= wxID_NONE
)
576 m_appleMenu
->Append( wxApp::s_macPreferencesMenuItemId
,
577 _("Preferences...") + "\tCtrl+," );
578 m_appleMenu
->AppendSeparator();
581 // standard menu items, handled in wxMenu::HandleCommandProcess(), see above:
583 hideLabel
= wxString::Format(_("Hide %s"), wxTheApp
? wxTheApp
->GetAppDisplayName() : _("Application"));
584 m_appleMenu
->Append( wxID_OSX_HIDE
, hideLabel
+ "\tCtrl+H" );
585 m_appleMenu
->Append( wxID_OSX_HIDEOTHERS
, _("Hide Others")+"\tAlt+Ctrl+H" );
586 m_appleMenu
->Append( wxID_OSX_SHOWALL
, _("Show All") );
587 m_appleMenu
->AppendSeparator();
589 // Do always add "Quit" item unconditionally however, it can't be disabled.
591 quitLabel
= wxString::Format(_("Quit %s"), wxTheApp
? wxTheApp
->GetAppDisplayName() : _("Application"));
592 m_appleMenu
->Append( wxApp::s_macExitMenuItemId
, quitLabel
+ "\tCtrl+Q" );
593 #endif // !wxOSX_USE_CARBON
595 m_rootMenu
->AppendSubMenu(m_appleMenu
, "\x14") ;
598 wxMenuBar::wxMenuBar()
603 wxMenuBar::wxMenuBar( long WXUNUSED(style
) )
608 wxMenuBar::wxMenuBar(size_t count
, wxMenu
*menus
[], const wxString titles
[], long WXUNUSED(style
))
612 for ( size_t i
= 0; i
< count
; i
++ )
614 m_menus
.Append(menus
[i
]);
616 menus
[i
]->Attach(this);
617 Append( menus
[i
], titles
[i
] );
621 wxMenuBar::~wxMenuBar()
623 if (s_macCommonMenuBar
== this)
624 s_macCommonMenuBar
= NULL
;
626 if (s_macInstalledMenuBar
== this)
628 emptyMenuBar
->GetPeer()->MakeRoot();
629 s_macInstalledMenuBar
= NULL
;
631 wxDELETE( m_rootMenu
);
632 // apple menu is a submenu, therefore we don't have to delete it
635 // deleting the root menu also removes all its wxMenu* submenus, therefore
636 // we must avoid double deleting them in the superclass destructor
640 void wxMenuBar::Refresh(bool WXUNUSED(eraseBackground
), const wxRect
*WXUNUSED(rect
))
642 wxCHECK_RET( IsAttached(), wxT("can't refresh unatteched menubar") );
645 void wxMenuBar::MacInstallMenuBar()
647 if ( s_macInstalledMenuBar
== this )
650 m_rootMenu
->GetPeer()->MakeRoot();
652 // hide items in the apple menu that don't exist in the wx menubar
654 wxMenuItem
* appleItem
= NULL
;
655 wxMenuItem
* wxItem
= NULL
;
657 int menuid
= wxApp::s_macAboutMenuItemId
;
658 appleItem
= m_appleMenu
->FindItem(menuid
);
659 wxItem
= FindItem(menuid
);
660 if ( appleItem
!= NULL
)
662 if ( wxItem
== NULL
)
663 appleItem
->GetPeer()->Hide();
665 appleItem
->SetItemLabel(wxItem
->GetItemLabel());
668 menuid
= wxApp::s_macPreferencesMenuItemId
;
669 appleItem
= m_appleMenu
->FindItem(menuid
);
670 wxItem
= FindItem(menuid
);
671 if ( appleItem
!= NULL
)
673 if ( wxItem
== NULL
)
674 appleItem
->GetPeer()->Hide();
676 appleItem
->SetItemLabel(wxItem
->GetItemLabel());
682 // if we have a mac help menu, clean it up before adding new items
683 MenuHandle helpMenuHandle
;
684 MenuItemIndex firstUserHelpMenuItem
;
686 if ( UMAGetHelpMenuDontCreate( &helpMenuHandle
, &firstUserHelpMenuItem
) == noErr
)
688 for ( int i
= CountMenuItems( helpMenuHandle
) ; i
>= firstUserHelpMenuItem
; --i
)
689 DeleteMenuItem( helpMenuHandle
, i
) ;
693 helpMenuHandle
= NULL
;
696 if ( wxApp::s_macPreferencesMenuItemId
)
698 wxMenuItem
*item
= FindItem( wxApp::s_macPreferencesMenuItemId
, NULL
) ;
699 if ( item
== NULL
|| !(item
->IsEnabled()) )
700 DisableMenuCommand( NULL
, kHICommandPreferences
) ;
702 EnableMenuCommand( NULL
, kHICommandPreferences
) ;
705 // Unlike preferences which may or may not exist, the Quit item should be always
706 // enabled unless it is added by the application and then disabled, otherwise
707 // a program would be required to add an item with wxID_EXIT in order to get the
708 // Quit menu item to be enabled, which seems a bit burdensome.
709 if ( wxApp::s_macExitMenuItemId
)
711 wxMenuItem
*item
= FindItem( wxApp::s_macExitMenuItemId
, NULL
) ;
712 if ( item
!= NULL
&& !(item
->IsEnabled()) )
713 DisableMenuCommand( NULL
, kHICommandQuit
) ;
715 EnableMenuCommand( NULL
, kHICommandQuit
) ;
718 wxString strippedHelpMenuTitle
= wxStripMenuCodes( wxApp::s_macHelpMenuTitleName
) ;
719 wxString strippedTranslatedHelpMenuTitle
= wxStripMenuCodes( wxString( _("&Help") ) ) ;
720 wxMenuList::compatibility_iterator menuIter
= m_menus
.GetFirst();
721 for (size_t i
= 0; i
< m_menus
.GetCount(); i
++, menuIter
= menuIter
->GetNext())
723 wxMenuItemList::compatibility_iterator node
;
725 wxMenu
* menu
= menuIter
->GetData() , *subMenu
= NULL
;
726 wxString strippedMenuTitle
= wxStripMenuCodes(m_titles
[i
]);
728 if ( strippedMenuTitle
== wxT("?") || strippedMenuTitle
== strippedHelpMenuTitle
|| strippedMenuTitle
== strippedTranslatedHelpMenuTitle
)
730 for (node
= menu
->GetMenuItems().GetFirst(); node
; node
= node
->GetNext())
732 item
= (wxMenuItem
*)node
->GetData();
733 subMenu
= item
->GetSubMenu() ;
736 UMAAppendMenuItem(mh
, wxStripMenuCodes(item
->GetText()) , wxFont::GetDefaultEncoding() );
737 MenuItemIndex position
= CountMenuItems(mh
);
738 ::SetMenuItemHierarchicalMenu(mh
, position
, MAC_WXHMENU(subMenu
->GetHMenu()));
742 if ( item
->GetId() != wxApp::s_macAboutMenuItemId
)
744 // we have found a user help menu and an item other than the about item,
745 // so we can create the mac help menu now, if we haven't created it yet
746 if ( helpMenuHandle
== NULL
)
748 if ( UMAGetHelpMenu( &helpMenuHandle
, &firstUserHelpMenuItem
) != noErr
)
750 helpMenuHandle
= NULL
;
756 if ( item
->IsSeparator() )
758 if ( helpMenuHandle
)
759 AppendMenuItemTextWithCFString( helpMenuHandle
,
760 CFSTR(""), kMenuItemAttrSeparator
, 0,NULL
);
765 entry
= wxAcceleratorEntry::Create( item
->GetItemLabel() ) ;
767 if ( item
->GetId() == wxApp::s_macAboutMenuItemId
)
769 // this will be taken care of below
773 if ( helpMenuHandle
)
775 UMAAppendMenuItem(helpMenuHandle
, wxStripMenuCodes(item
->GetItemLabel()) , wxFont::GetDefaultEncoding(), entry
);
776 SetMenuItemCommandID( helpMenuHandle
, CountMenuItems(helpMenuHandle
) , wxIdToMacCommand ( item
->GetId() ) ) ;
777 SetMenuItemRefCon( helpMenuHandle
, CountMenuItems(helpMenuHandle
) , (URefCon
) item
) ;
787 else if ( ( m_titles
[i
] == wxT("Window") || m_titles
[i
] == wxT("&Window") )
788 && GetAutoWindowMenu() )
790 if ( MacGetWindowMenuHMenu() == NULL
)
792 CreateStandardWindowMenu( 0 , (MenuHandle
*) &s_macWindowMenuHandle
) ;
795 MenuRef wm
= (MenuRef
)MacGetWindowMenuHMenu();
799 // get the insertion point in the standard menu
800 MenuItemIndex winListStart
;
801 GetIndMenuItemWithCommandID(wm
,
802 kHICommandWindowListSeparator
, 1, NULL
, &winListStart
);
804 // add a separator so that the standard items and the custom items
805 // aren't mixed together, but only if this is the first run
806 OSStatus err
= GetIndMenuItemWithCommandID(wm
,
807 'WXWM', 1, NULL
, NULL
);
809 if ( err
== menuItemNotFoundErr
)
811 InsertMenuItemTextWithCFString( wm
,
812 CFSTR(""), winListStart
-1, kMenuItemAttrSeparator
, 'WXWM');
815 wxInsertMenuItemsInMenu(menu
, wm
, winListStart
);
819 UMASetMenuTitle( MAC_WXHMENU(menu
->GetHMenu()) , m_titles
[i
], GetFont().GetEncoding() ) ;
820 menu
->MacBeforeDisplay(false) ;
822 ::InsertMenu(MAC_WXHMENU(GetMenu(i
)->GetHMenu()), 0);
826 // take care of the about menu item wherever it is
829 wxMenuItem
*aboutMenuItem
= FindItem(wxApp::s_macAboutMenuItemId
, &aboutMenu
) ;
833 entry
= wxAcceleratorEntry::Create( aboutMenuItem
->GetItemLabel() ) ;
834 UMASetMenuItemText( GetMenuHandle( kwxMacAppleMenuId
) , 1 , wxStripMenuCodes ( aboutMenuItem
->GetItemLabel() ) , wxFont::GetDefaultEncoding() );
835 UMAEnableMenuItem( GetMenuHandle( kwxMacAppleMenuId
) , 1 , true );
836 SetMenuItemCommandID( GetMenuHandle( kwxMacAppleMenuId
) , 1 , kHICommandAbout
) ;
837 SetMenuItemRefCon(GetMenuHandle( kwxMacAppleMenuId
) , 1 , (URefCon
)aboutMenuItem
) ;
838 UMASetMenuItemShortcut( GetMenuHandle( kwxMacAppleMenuId
) , 1 , entry
) ;
843 if ( GetAutoWindowMenu() )
845 if ( MacGetWindowMenuHMenu() == NULL
)
846 CreateStandardWindowMenu( 0 , (MenuHandle
*) &s_macWindowMenuHandle
) ;
848 InsertMenu( (MenuHandle
) MacGetWindowMenuHMenu() , 0 ) ;
854 s_macInstalledMenuBar
= this;
857 void wxMenuBar::EnableTop(size_t pos
, bool enable
)
859 wxCHECK_RET( IsAttached(), wxT("doesn't work with unattached menubars") );
861 m_rootMenu
->FindItemByPosition(pos
+firstMenuPos
)->Enable(enable
);
866 bool wxMenuBar::IsEnabledTop(size_t pos
) const
868 wxCHECK_MSG( IsAttached(), true,
869 wxT("doesn't work with unattached menubars") );
871 wxMenuItem
* const item
= m_rootMenu
->FindItemByPosition(pos
+firstMenuPos
);
872 wxCHECK_MSG( item
, false, wxT("invalid menu index") );
874 return item
->IsEnabled();
877 bool wxMenuBar::Enable(bool enable
)
879 wxCHECK_MSG( IsAttached(), false, wxT("doesn't work with unattached menubars") );
882 for (i
= 0; i
< GetMenuCount(); i
++)
883 EnableTop(i
, enable
);
888 void wxMenuBar::SetMenuLabel(size_t pos
, const wxString
& label
)
890 wxCHECK_RET( pos
< GetMenuCount(), wxT("invalid menu index") );
892 GetMenu(pos
)->SetTitle( label
) ;
895 wxString
wxMenuBar::GetMenuLabel(size_t pos
) const
897 wxCHECK_MSG( pos
< GetMenuCount(), wxEmptyString
,
898 wxT("invalid menu index in wxMenuBar::GetMenuLabel") );
900 return GetMenu(pos
)->GetTitle();
903 // ---------------------------------------------------------------------------
904 // wxMenuBar construction
905 // ---------------------------------------------------------------------------
907 wxMenu
*wxMenuBar::Replace(size_t pos
, wxMenu
*menu
, const wxString
& title
)
909 wxMenu
*menuOld
= wxMenuBarBase::Replace(pos
, menu
, title
);
913 wxMenuItem
* item
= m_rootMenu
->FindItemByPosition(pos
+firstMenuPos
);
914 m_rootMenu
->Remove(item
);
915 m_rootMenu
->Insert( pos
+firstMenuPos
, wxMenuItem::New( m_rootMenu
, wxID_ANY
, title
, "", wxITEM_NORMAL
, menu
) );
920 bool wxMenuBar::Insert(size_t pos
, wxMenu
*menu
, const wxString
& title
)
922 if ( !wxMenuBarBase::Insert(pos
, menu
, title
) )
925 m_rootMenu
->Insert( pos
+firstMenuPos
, wxMenuItem::New( m_rootMenu
, wxID_ANY
, title
, "", wxITEM_NORMAL
, menu
) );
926 menu
->SetTitle(title
);
931 wxMenu
*wxMenuBar::Remove(size_t pos
)
933 wxMenu
*menu
= wxMenuBarBase::Remove(pos
);
937 wxMenuItem
* item
= m_rootMenu
->FindItemByPosition(pos
+firstMenuPos
);
938 m_rootMenu
->Remove(item
);
943 bool wxMenuBar::Append(wxMenu
*menu
, const wxString
& title
)
945 WXHMENU submenu
= menu
? menu
->GetHMenu() : 0;
946 wxCHECK_MSG( submenu
, false, wxT("can't append invalid menu to menubar") );
948 if ( !wxMenuBarBase::Append(menu
, title
) )
951 m_rootMenu
->AppendSubMenu(menu
, title
);
952 menu
->SetTitle(title
);
957 void wxMenuBar::Detach()
959 wxMenuBarBase::Detach() ;
962 void wxMenuBar::Attach(wxFrame
*frame
)
964 wxMenuBarBase::Attach( frame
) ;
967 #endif // wxUSE_MENUS