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_allowRearrange
= true;
61 m_noEventsMode
= false;
63 m_peer
= wxMenuImpl::Create( this, wxStripMenuCodes(m_title
) );
66 // if we have a title, insert it in the beginning of the menu
67 if ( !m_title
.empty() )
69 Append(idMenuTitle
, m_title
) ;
79 WXHMENU
wxMenu::GetHMenu() const
82 return m_peer
->GetHMenu();
88 // not available on the mac platform
91 void wxMenu::SetAllowRearrange( bool allow
)
93 m_allowRearrange
= allow
;
96 void wxMenu::SetNoEventsMode( bool noEvents
)
98 m_noEventsMode
= noEvents
;
101 // function appends a new item or submenu to the menu
102 // append a new item or submenu to the menu
103 bool wxMenu::DoInsertOrAppend(wxMenuItem
*item
, size_t pos
)
105 wxASSERT_MSG( item
!= NULL
, wxT("can't append NULL item to the menu") );
106 GetPeer()->InsertOrAppend( item
, pos
);
108 if ( item
->IsSeparator() )
110 // nothing to do here
114 wxMenu
*pSubMenu
= item
->GetSubMenu() ;
115 if ( pSubMenu
!= NULL
)
117 wxASSERT_MSG( pSubMenu
->GetHMenu() != NULL
, wxT("invalid submenu added"));
118 pSubMenu
->m_menuParent
= this ;
120 pSubMenu
->DoRearrange();
124 if ( item
->GetId() == idMenuTitle
)
125 item
->GetMenu()->Enable( idMenuTitle
, false );
129 // if we're already attached to the menubar, we must update it
130 if ( IsAttached() && GetMenuBar()->IsAttached() )
131 GetMenuBar()->Refresh();
136 wxMenuItem
* wxMenu::DoAppend(wxMenuItem
*item
)
138 wxCHECK_MSG( item
, NULL
, wxT("NULL item in wxMenu::DoAppend") );
142 if ( item
->IsRadio() )
144 int count
= GetMenuItemCount();
146 if ( !count
|| !(*GetMenuItems().rbegin())->IsRadio() )
148 // start a new radio group
149 item
->SetAsRadioGroupStart();
150 item
->SetRadioGroupEnd(count
);
152 // ensure that we have a checked item in the radio group
155 else // extend the current radio group
157 // we need to update its end item
158 wxMenuItem
* const last
= *GetMenuItems().rbegin();
159 const int groupStart
= last
->IsRadioGroupStart()
161 : last
->GetRadioGroupStart();
163 item
->SetRadioGroupStart(groupStart
);
164 wxMenuItemList::compatibility_iterator node
= GetMenuItems().Item(groupStart
);
168 node
->GetData()->SetRadioGroupEnd(count
);
172 wxFAIL_MSG( wxT("where is the radio group start item?") );
177 if ( !wxMenuBase::DoAppend(item
) || !DoInsertOrAppend(item
) )
181 // check the item initially
187 wxMenuItem
* wxMenu::DoInsert(size_t pos
, wxMenuItem
*item
)
189 if (wxMenuBase::DoInsert(pos
, item
) && DoInsertOrAppend(item
, pos
))
195 wxMenuItem
*wxMenu::DoRemove(wxMenuItem
*item
)
197 if ( item
->IsRadio() )
199 // Check if we're removing the item starting the radio group
200 if ( item
->IsRadioGroupStart() )
202 // Yes, we do, update the next radio group item, if any, to be the
204 const int endGroup
= item
->GetRadioGroupEnd();
206 wxMenuItemList::compatibility_iterator
207 node
= GetMenuItems().Item(endGroup
);
208 wxASSERT_MSG( node
, wxS("Should have valid radio group end") );
210 while ( node
->GetData() != item
)
212 const wxMenuItemList::compatibility_iterator
213 prevNode
= node
->GetPrevious();
214 wxMenuItem
* const prevItem
= prevNode
->GetData();
215 if ( prevItem
== item
)
217 prevItem
->SetAsRadioGroupStart();
218 prevItem
->SetRadioGroupEnd(endGroup
);
228 // we need to find the items position in the child list
230 wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst();
232 for ( pos = 0; node; pos++ )
234 if ( node->GetData() == item )
237 node = node->GetNext();
240 // DoRemove() (unlike Remove) can only be called for existing item!
241 wxCHECK_MSG( node, NULL, wxT("bug in wxMenu::Remove logic") );
243 wxOSXMenuRemoveItem(m_hMenu , pos );
245 GetPeer()->Remove( item
);
246 // and from internal data structures
247 return wxMenuBase::DoRemove(item
);
250 void wxMenu::SetTitle(const wxString
& label
)
253 GetPeer()->SetTitle( wxStripMenuCodes( label
) );
256 bool wxMenu::ProcessCommand(wxCommandEvent
& event
)
258 bool processed
= false;
260 // Try the menu's event handler
261 if ( /* !processed && */ GetEventHandler())
262 processed
= GetEventHandler()->SafelyProcessEvent(event
);
264 // Try the window the menu was popped up from
265 // (and up through the hierarchy)
266 wxWindow
*win
= GetWindow();
267 if ( !processed
&& win
)
268 processed
= win
->HandleWindowEvent(event
);
273 // ---------------------------------------------------------------------------
275 // ---------------------------------------------------------------------------
277 // MacOS needs to know about submenus somewhere within this menu
278 // before it can be displayed, also hide special menu items
279 // like preferences that are handled by the OS
280 void wxMenu::DoRearrange()
282 if ( !AllowRearrange() )
285 wxMenuItem
* previousItem
= NULL
;
287 wxMenuItemList::compatibility_iterator node
;
290 for (pos
= 0, node
= GetMenuItems().GetFirst(); node
; node
= node
->GetNext(), pos
++)
292 item
= (wxMenuItem
*)node
->GetData();
293 wxMenu
* subMenu
= item
->GetSubMenu() ;
300 // what we do here is to hide the special items which are
301 // shown in the application menu anyhow -- it doesn't make
302 // sense to show them in their normal place as well
303 if ( item
->GetId() == wxApp::s_macAboutMenuItemId
||
304 item
->GetId() == wxApp::s_macPreferencesMenuItemId
||
305 item
->GetId() == wxApp::s_macExitMenuItemId
)
308 item
->GetPeer()->Hide( true );
310 // also check for a separator which was used just to
311 // separate this item from the others, so don't leave
312 // separator at the menu start or end nor 2 consecutive
314 wxMenuItemList::compatibility_iterator nextNode
= node
->GetNext();
315 wxMenuItem
*next
= nextNode
? nextNode
->GetData() : NULL
;
317 wxMenuItem
*sepToHide
= 0;
318 if ( !previousItem
&& next
&& next
->IsSeparator() )
320 // next (i.e. second as we must be first) item is
321 // the separator to hide
322 wxASSERT_MSG( pos
== 0, wxT("should be the menu start") );
325 else if ( GetMenuItems().GetCount() == pos
+ 1 &&
326 previousItem
!= NULL
&&
327 previousItem
->IsSeparator() )
329 // prev item is a trailing separator we want to hide
330 sepToHide
= previousItem
;
332 else if ( previousItem
&& previousItem
->IsSeparator() &&
333 next
&& next
->IsSeparator() )
335 // two consecutive separators, this is one too many
341 // hide the separator as well
342 sepToHide
->GetPeer()->Hide( true );
347 previousItem
= item
;
352 bool wxMenu::HandleCommandUpdateStatus( wxMenuItem
* item
, wxWindow
* senderWindow
)
354 int menuid
= item
? item
->GetId() : 0;
355 wxUpdateUIEvent
event(menuid
);
356 event
.SetEventObject( this );
358 bool processed
= false;
360 // Try the menu's event handler
362 wxEvtHandler
*handler
= GetEventHandler();
364 processed
= handler
->ProcessEvent(event
);
367 // Try the window the menu was popped up from
368 // (and up through the hierarchy)
371 wxWindow
*win
= GetWindow();
373 processed
= win
->HandleWindowEvent(event
);
376 if ( !processed
&& senderWindow
!= NULL
)
378 processed
= senderWindow
->HandleWindowEvent(event
);
383 // if anything changed, update the changed attribute
384 if (event
.GetSetText())
385 SetLabel(menuid
, event
.GetText());
386 if (event
.GetSetChecked())
387 Check(menuid
, event
.GetChecked());
388 if (event
.GetSetEnabled())
389 Enable(menuid
, event
.GetEnabled());
394 // these two items are also managed by the Carbon Menu Manager, therefore we must
395 // always reset them ourselves
398 if ( menuid
== wxApp::s_macExitMenuItemId
)
400 cmd
= kHICommandQuit
;
402 else if (menuid
== wxApp::s_macPreferencesMenuItemId
)
404 cmd
= kHICommandPreferences
;
409 if ( !item
->IsEnabled() || wxDialog::OSXHasModalDialogsOpen() )
410 DisableMenuCommand( NULL
, cmd
) ;
412 EnableMenuCommand( NULL
, cmd
) ;
421 bool wxMenu::HandleCommandProcess( wxMenuItem
* item
, wxWindow
* senderWindow
)
423 int menuid
= item
? item
->GetId() : 0;
424 bool processed
= false;
425 if (item
->IsCheckable())
426 item
->Check( !item
->IsChecked() ) ;
428 if ( SendEvent( menuid
, item
->IsCheckable() ? item
->IsChecked() : -1 ) )
432 if ( senderWindow
!= NULL
)
434 wxCommandEvent
event(wxEVT_MENU
, menuid
);
435 event
.SetEventObject(this);
436 event
.SetInt(item
->IsCheckable() ? item
->IsChecked() : -1);
438 if ( senderWindow
->HandleWindowEvent(event
) )
443 if(!processed
&& item
)
445 processed
= item
->GetPeer()->DoDefault();
451 void wxMenu::HandleMenuItemHighlighted( wxMenuItem
* item
)
453 int menuid
= item
? item
->GetId() : 0;
454 wxMenuEvent
wxevent(wxEVT_MENU_HIGHLIGHT
, menuid
, this);
455 DoHandleMenuEvent( wxevent
);
458 void wxMenu::DoHandleMenuOpenedOrClosed(wxEventType evtType
)
460 // Popup menu being currently shown or NULL, defined in wincmn.cpp.
461 extern wxMenu
*wxCurrentPopupMenu
;
463 // Set the id to allow wxMenuEvent::IsPopup() to work correctly.
464 int menuid
= this == wxCurrentPopupMenu
? wxID_ANY
: 0;
465 wxMenuEvent
wxevent(evtType
, menuid
, this);
466 DoHandleMenuEvent( wxevent
);
469 void wxMenu::HandleMenuOpened()
471 DoHandleMenuOpenedOrClosed(wxEVT_MENU_OPEN
);
474 void wxMenu::HandleMenuClosed()
476 DoHandleMenuOpenedOrClosed(wxEVT_MENU_CLOSE
);
479 bool wxMenu::DoHandleMenuEvent(wxEvent
& wxevent
)
481 wxevent
.SetEventObject(this);
482 wxEvtHandler
* handler
= GetEventHandler();
483 if (handler
&& handler
->ProcessEvent(wxevent
))
489 wxWindow
*win
= GetWindow();
492 if ( win
->HandleWindowEvent(wxevent
) )
503 Mac Implementation note :
505 The Mac has only one global menubar, so we attempt to install the currently
506 active menubar from a frame, we currently don't take into account mdi-frames
507 which would ask for menu-merging
509 Secondly there is no mac api for changing a menubar that is not the current
510 menubar, so we have to wait for preparing the actual menubar until the
511 wxMenubar is to be used
513 We can in subsequent versions use MacInstallMenuBar to provide some sort of
514 auto-merge for MDI in case this will be necessary
518 wxMenuBar
* wxMenuBar::s_macInstalledMenuBar
= NULL
;
519 wxMenuBar
* wxMenuBar::s_macCommonMenuBar
= NULL
;
520 bool wxMenuBar::s_macAutoWindowMenu
= true ;
521 WXHMENU
wxMenuBar::s_macWindowMenuHandle
= NULL
;
524 wxMenu
* emptyMenuBar
= NULL
;
526 const int firstMenuPos
= 1; // to account for the 0th application menu on mac
528 void wxMenuBar::Init()
530 if ( emptyMenuBar
== NULL
)
532 emptyMenuBar
= new wxMenu();
534 wxMenu
* appleMenu
= new wxMenu();
535 appleMenu
->SetAllowRearrange(false);
536 #if !wxOSX_USE_CARBON
537 // standard menu items, handled in wxMenu::HandleCommandProcess(), see above:
539 hideLabel
= wxString::Format(_("Hide %s"), wxTheApp
? wxTheApp
->GetAppDisplayName() : _("Application"));
540 appleMenu
->Append( wxID_OSX_HIDE
, hideLabel
+ "\tCtrl+H" );
541 appleMenu
->Append( wxID_OSX_HIDEOTHERS
, _("Hide Others")+"\tAlt+Ctrl+H" );
542 appleMenu
->Append( wxID_OSX_SHOWALL
, _("Show All") );
543 appleMenu
->AppendSeparator();
545 // Do always add "Quit" item unconditionally however, it can't be disabled.
547 quitLabel
= wxString::Format(_("Quit %s"), wxTheApp
? wxTheApp
->GetAppDisplayName() : _("Application"));
548 appleMenu
->Append( wxApp::s_macExitMenuItemId
, quitLabel
+ "\tCtrl+Q" );
549 #endif // !wxOSX_USE_CARBON
551 emptyMenuBar
->AppendSubMenu(appleMenu
, "\x14") ;
554 m_eventHandler
= this;
555 m_menuBarFrame
= NULL
;
556 m_rootMenu
= new wxMenu();
557 m_rootMenu
->Attach(this);
559 m_appleMenu
= new wxMenu();
560 m_appleMenu
->SetAllowRearrange(false);
562 // Create standard items unless the application explicitly disabled this by
563 // setting the corresponding ids to wxID_NONE: although this is not
564 // recommended, sometimes these items really don't make sense.
565 if ( wxApp::s_macAboutMenuItemId
!= wxID_NONE
)
567 wxString
aboutLabel(_("About"));
569 aboutLabel
<< ' ' << wxTheApp
->GetAppDisplayName();
572 m_appleMenu
->Append( wxApp::s_macAboutMenuItemId
, aboutLabel
);
573 m_appleMenu
->AppendSeparator();
576 #if !wxOSX_USE_CARBON
577 if ( wxApp::s_macPreferencesMenuItemId
!= wxID_NONE
)
579 m_appleMenu
->Append( wxApp::s_macPreferencesMenuItemId
,
580 _("Preferences...") + "\tCtrl+," );
581 m_appleMenu
->AppendSeparator();
584 // standard menu items, handled in wxMenu::HandleCommandProcess(), see above:
586 hideLabel
= wxString::Format(_("Hide %s"), wxTheApp
? wxTheApp
->GetAppDisplayName() : _("Application"));
587 m_appleMenu
->Append( wxID_OSX_HIDE
, hideLabel
+ "\tCtrl+H" );
588 m_appleMenu
->Append( wxID_OSX_HIDEOTHERS
, _("Hide Others")+"\tAlt+Ctrl+H" );
589 m_appleMenu
->Append( wxID_OSX_SHOWALL
, _("Show All") );
590 m_appleMenu
->AppendSeparator();
592 // Do always add "Quit" item unconditionally however, it can't be disabled.
594 quitLabel
= wxString::Format(_("Quit %s"), wxTheApp
? wxTheApp
->GetAppDisplayName() : _("Application"));
595 m_appleMenu
->Append( wxApp::s_macExitMenuItemId
, quitLabel
+ "\tCtrl+Q" );
596 #endif // !wxOSX_USE_CARBON
598 m_rootMenu
->AppendSubMenu(m_appleMenu
, "\x14") ;
601 wxMenuBar::wxMenuBar()
606 wxMenuBar::wxMenuBar( long WXUNUSED(style
) )
611 wxMenuBar::wxMenuBar(size_t count
, wxMenu
*menus
[], const wxString titles
[], long WXUNUSED(style
))
615 for ( size_t i
= 0; i
< count
; i
++ )
617 m_menus
.Append(menus
[i
]);
619 menus
[i
]->Attach(this);
620 Append( menus
[i
], titles
[i
] );
624 wxMenuBar::~wxMenuBar()
626 if (s_macCommonMenuBar
== this)
627 s_macCommonMenuBar
= NULL
;
629 if (s_macInstalledMenuBar
== this)
631 emptyMenuBar
->GetPeer()->MakeRoot();
632 s_macInstalledMenuBar
= NULL
;
634 wxDELETE( m_rootMenu
);
635 // apple menu is a submenu, therefore we don't have to delete it
638 // deleting the root menu also removes all its wxMenu* submenus, therefore
639 // we must avoid double deleting them in the superclass destructor
643 void wxMenuBar::Refresh(bool WXUNUSED(eraseBackground
), const wxRect
*WXUNUSED(rect
))
645 wxCHECK_RET( IsAttached(), wxT("can't refresh unatteched menubar") );
648 void wxMenuBar::MacInstallMenuBar()
650 if ( s_macInstalledMenuBar
== this )
653 m_rootMenu
->GetPeer()->MakeRoot();
655 // hide items in the apple menu that don't exist in the wx menubar
657 wxMenuItem
* appleItem
= NULL
;
658 wxMenuItem
* wxItem
= NULL
;
660 int menuid
= wxApp::s_macAboutMenuItemId
;
661 appleItem
= m_appleMenu
->FindItem(menuid
);
662 wxItem
= FindItem(menuid
);
663 if ( appleItem
!= NULL
)
665 if ( wxItem
== NULL
)
666 appleItem
->GetPeer()->Hide();
668 appleItem
->SetItemLabel(wxItem
->GetItemLabel());
671 menuid
= wxApp::s_macPreferencesMenuItemId
;
672 appleItem
= m_appleMenu
->FindItem(menuid
);
673 wxItem
= FindItem(menuid
);
674 if ( appleItem
!= NULL
)
676 if ( wxItem
== NULL
)
677 appleItem
->GetPeer()->Hide();
679 appleItem
->SetItemLabel(wxItem
->GetItemLabel());
685 // if we have a mac help menu, clean it up before adding new items
686 MenuHandle helpMenuHandle
;
687 MenuItemIndex firstUserHelpMenuItem
;
689 if ( UMAGetHelpMenuDontCreate( &helpMenuHandle
, &firstUserHelpMenuItem
) == noErr
)
691 for ( int i
= CountMenuItems( helpMenuHandle
) ; i
>= firstUserHelpMenuItem
; --i
)
692 DeleteMenuItem( helpMenuHandle
, i
) ;
696 helpMenuHandle
= NULL
;
699 if ( wxApp::s_macPreferencesMenuItemId
)
701 wxMenuItem
*item
= FindItem( wxApp::s_macPreferencesMenuItemId
, NULL
) ;
702 if ( item
== NULL
|| !(item
->IsEnabled()) )
703 DisableMenuCommand( NULL
, kHICommandPreferences
) ;
705 EnableMenuCommand( NULL
, kHICommandPreferences
) ;
708 // Unlike preferences which may or may not exist, the Quit item should be always
709 // enabled unless it is added by the application and then disabled, otherwise
710 // a program would be required to add an item with wxID_EXIT in order to get the
711 // Quit menu item to be enabled, which seems a bit burdensome.
712 if ( wxApp::s_macExitMenuItemId
)
714 wxMenuItem
*item
= FindItem( wxApp::s_macExitMenuItemId
, NULL
) ;
715 if ( item
!= NULL
&& !(item
->IsEnabled()) )
716 DisableMenuCommand( NULL
, kHICommandQuit
) ;
718 EnableMenuCommand( NULL
, kHICommandQuit
) ;
721 wxString strippedHelpMenuTitle
= wxStripMenuCodes( wxApp::s_macHelpMenuTitleName
) ;
722 wxString strippedTranslatedHelpMenuTitle
= wxStripMenuCodes( wxString( _("&Help") ) ) ;
723 wxMenuList::compatibility_iterator menuIter
= m_menus
.GetFirst();
724 for (size_t i
= 0; i
< m_menus
.GetCount(); i
++, menuIter
= menuIter
->GetNext())
726 wxMenuItemList::compatibility_iterator node
;
728 wxMenu
* menu
= menuIter
->GetData() , *subMenu
= NULL
;
729 wxString strippedMenuTitle
= wxStripMenuCodes(m_titles
[i
]);
731 if ( strippedMenuTitle
== wxT("?") || strippedMenuTitle
== strippedHelpMenuTitle
|| strippedMenuTitle
== strippedTranslatedHelpMenuTitle
)
733 for (node
= menu
->GetMenuItems().GetFirst(); node
; node
= node
->GetNext())
735 item
= (wxMenuItem
*)node
->GetData();
736 subMenu
= item
->GetSubMenu() ;
739 UMAAppendMenuItem(mh
, wxStripMenuCodes(item
->GetText()) , wxFont::GetDefaultEncoding() );
740 MenuItemIndex position
= CountMenuItems(mh
);
741 ::SetMenuItemHierarchicalMenu(mh
, position
, MAC_WXHMENU(subMenu
->GetHMenu()));
745 if ( item
->GetId() != wxApp::s_macAboutMenuItemId
)
747 // we have found a user help menu and an item other than the about item,
748 // so we can create the mac help menu now, if we haven't created it yet
749 if ( helpMenuHandle
== NULL
)
751 if ( UMAGetHelpMenu( &helpMenuHandle
, &firstUserHelpMenuItem
) != noErr
)
753 helpMenuHandle
= NULL
;
759 if ( item
->IsSeparator() )
761 if ( helpMenuHandle
)
762 AppendMenuItemTextWithCFString( helpMenuHandle
,
763 CFSTR(""), kMenuItemAttrSeparator
, 0,NULL
);
768 entry
= wxAcceleratorEntry::Create( item
->GetItemLabel() ) ;
770 if ( item
->GetId() == wxApp::s_macAboutMenuItemId
)
772 // this will be taken care of below
776 if ( helpMenuHandle
)
778 UMAAppendMenuItem(helpMenuHandle
, wxStripMenuCodes(item
->GetItemLabel()) , wxFont::GetDefaultEncoding(), entry
);
779 SetMenuItemCommandID( helpMenuHandle
, CountMenuItems(helpMenuHandle
) , wxIdToMacCommand ( item
->GetId() ) ) ;
780 SetMenuItemRefCon( helpMenuHandle
, CountMenuItems(helpMenuHandle
) , (URefCon
) item
) ;
790 else if ( ( m_titles
[i
] == wxT("Window") || m_titles
[i
] == wxT("&Window") )
791 && GetAutoWindowMenu() )
793 if ( MacGetWindowMenuHMenu() == NULL
)
795 CreateStandardWindowMenu( 0 , (MenuHandle
*) &s_macWindowMenuHandle
) ;
798 MenuRef wm
= (MenuRef
)MacGetWindowMenuHMenu();
802 // get the insertion point in the standard menu
803 MenuItemIndex winListStart
;
804 GetIndMenuItemWithCommandID(wm
,
805 kHICommandWindowListSeparator
, 1, NULL
, &winListStart
);
807 // add a separator so that the standard items and the custom items
808 // aren't mixed together, but only if this is the first run
809 OSStatus err
= GetIndMenuItemWithCommandID(wm
,
810 'WXWM', 1, NULL
, NULL
);
812 if ( err
== menuItemNotFoundErr
)
814 InsertMenuItemTextWithCFString( wm
,
815 CFSTR(""), winListStart
-1, kMenuItemAttrSeparator
, 'WXWM');
818 wxInsertMenuItemsInMenu(menu
, wm
, winListStart
);
822 UMASetMenuTitle( MAC_WXHMENU(menu
->GetHMenu()) , m_titles
[i
], GetFont().GetEncoding() ) ;
823 menu
->MacBeforeDisplay(false) ;
825 ::InsertMenu(MAC_WXHMENU(GetMenu(i
)->GetHMenu()), 0);
829 // take care of the about menu item wherever it is
832 wxMenuItem
*aboutMenuItem
= FindItem(wxApp::s_macAboutMenuItemId
, &aboutMenu
) ;
836 entry
= wxAcceleratorEntry::Create( aboutMenuItem
->GetItemLabel() ) ;
837 UMASetMenuItemText( GetMenuHandle( kwxMacAppleMenuId
) , 1 , wxStripMenuCodes ( aboutMenuItem
->GetItemLabel() ) , wxFont::GetDefaultEncoding() );
838 UMAEnableMenuItem( GetMenuHandle( kwxMacAppleMenuId
) , 1 , true );
839 SetMenuItemCommandID( GetMenuHandle( kwxMacAppleMenuId
) , 1 , kHICommandAbout
) ;
840 SetMenuItemRefCon(GetMenuHandle( kwxMacAppleMenuId
) , 1 , (URefCon
)aboutMenuItem
) ;
841 UMASetMenuItemShortcut( GetMenuHandle( kwxMacAppleMenuId
) , 1 , entry
) ;
846 if ( GetAutoWindowMenu() )
848 if ( MacGetWindowMenuHMenu() == NULL
)
849 CreateStandardWindowMenu( 0 , (MenuHandle
*) &s_macWindowMenuHandle
) ;
851 InsertMenu( (MenuHandle
) MacGetWindowMenuHMenu() , 0 ) ;
857 s_macInstalledMenuBar
= this;
860 void wxMenuBar::EnableTop(size_t pos
, bool enable
)
862 wxCHECK_RET( IsAttached(), wxT("doesn't work with unattached menubars") );
864 m_rootMenu
->FindItemByPosition(pos
+firstMenuPos
)->Enable(enable
);
869 bool wxMenuBar::IsEnabledTop(size_t pos
) const
871 wxCHECK_MSG( IsAttached(), true,
872 wxT("doesn't work with unattached menubars") );
874 wxMenuItem
* const item
= m_rootMenu
->FindItemByPosition(pos
+firstMenuPos
);
875 wxCHECK_MSG( item
, false, wxT("invalid menu index") );
877 return item
->IsEnabled();
880 bool wxMenuBar::Enable(bool enable
)
882 wxCHECK_MSG( IsAttached(), false, wxT("doesn't work with unattached menubars") );
885 for (i
= 0; i
< GetMenuCount(); i
++)
886 EnableTop(i
, enable
);
891 void wxMenuBar::SetMenuLabel(size_t pos
, const wxString
& label
)
893 wxCHECK_RET( pos
< GetMenuCount(), wxT("invalid menu index") );
895 GetMenu(pos
)->SetTitle( label
) ;
898 wxString
wxMenuBar::GetMenuLabel(size_t pos
) const
900 wxCHECK_MSG( pos
< GetMenuCount(), wxEmptyString
,
901 wxT("invalid menu index in wxMenuBar::GetMenuLabel") );
903 return GetMenu(pos
)->GetTitle();
906 // ---------------------------------------------------------------------------
907 // wxMenuBar construction
908 // ---------------------------------------------------------------------------
910 wxMenu
*wxMenuBar::Replace(size_t pos
, wxMenu
*menu
, const wxString
& title
)
912 wxMenu
*menuOld
= wxMenuBarBase::Replace(pos
, menu
, title
);
916 wxMenuItem
* item
= m_rootMenu
->FindItemByPosition(pos
+firstMenuPos
);
917 m_rootMenu
->Remove(item
);
918 m_rootMenu
->Insert( pos
+firstMenuPos
, wxMenuItem::New( m_rootMenu
, wxID_ANY
, title
, "", wxITEM_NORMAL
, menu
) );
923 bool wxMenuBar::Insert(size_t pos
, wxMenu
*menu
, const wxString
& title
)
925 if ( !wxMenuBarBase::Insert(pos
, menu
, title
) )
928 m_rootMenu
->Insert( pos
+firstMenuPos
, wxMenuItem::New( m_rootMenu
, wxID_ANY
, title
, "", wxITEM_NORMAL
, menu
) );
929 menu
->SetTitle(title
);
934 wxMenu
*wxMenuBar::Remove(size_t pos
)
936 wxMenu
*menu
= wxMenuBarBase::Remove(pos
);
940 wxMenuItem
* item
= m_rootMenu
->FindItemByPosition(pos
+firstMenuPos
);
941 m_rootMenu
->Remove(item
);
946 bool wxMenuBar::Append(wxMenu
*menu
, const wxString
& title
)
948 WXHMENU submenu
= menu
? menu
->GetHMenu() : 0;
949 wxCHECK_MSG( submenu
, false, wxT("can't append invalid menu to menubar") );
951 if ( !wxMenuBarBase::Append(menu
, title
) )
954 m_rootMenu
->AppendSubMenu(menu
, title
);
955 menu
->SetTitle(title
);
960 void wxMenuBar::Detach()
962 wxMenuBarBase::Detach() ;
965 void wxMenuBar::Attach(wxFrame
*frame
)
967 wxMenuBarBase::Attach( frame
) ;
970 #endif // wxUSE_MENUS