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 IMPLEMENT_DYNAMIC_CLASS(wxMenu
, wxEvtHandler
)
47 IMPLEMENT_DYNAMIC_CLASS(wxMenuBar
, wxEvtHandler
)
49 // the (popup) menu title has this special id
50 static const int idMenuTitle
= -3;
52 // ============================================================================
54 // ============================================================================
58 // Construct a menu with optional title (then use append)
63 m_startRadioGroup
= -1;
64 m_allowRearrange
= true;
65 m_noEventsMode
= false;
67 m_peer
= wxMenuImpl
::Create( this, wxStripMenuCodes(m_title
) );
70 // if we have a title, insert it in the beginning of the menu
71 if ( !m_title
.empty() )
73 Append(idMenuTitle
, m_title
) ;
83 WXHMENU wxMenu
::GetHMenu() const
86 return m_peer
->GetHMenu();
92 // not available on the mac platform
95 void wxMenu
::Attach(wxMenuBarBase
*menubar
)
97 wxMenuBase
::Attach(menubar
);
102 void wxMenu
::SetAllowRearrange( bool allow
)
104 m_allowRearrange
= allow
;
107 void wxMenu
::SetNoEventsMode( bool noEvents
)
109 m_noEventsMode
= noEvents
;
112 // function appends a new item or submenu to the menu
113 // append a new item or submenu to the menu
114 bool wxMenu
::DoInsertOrAppend(wxMenuItem
*pItem
, size_t pos
)
116 wxASSERT_MSG( pItem
!= NULL
, wxT("can't append NULL item to the menu") );
117 m_peer
->InsertOrAppend( pItem
, pos
);
119 if ( pItem
->IsSeparator() )
121 // nothing to do here
125 wxMenu
*pSubMenu
= pItem
->GetSubMenu() ;
126 if ( pSubMenu
!= NULL
)
128 wxASSERT_MSG( pSubMenu
->GetHMenu() != NULL
, wxT("invalid submenu added"));
129 pSubMenu
->m_menuParent
= this ;
131 pSubMenu
->DoRearrange();
135 if ( pItem
->GetId() == idMenuTitle
)
136 pItem
->GetMenu()->Enable( idMenuTitle
, false );
140 // if we're already attached to the menubar, we must update it
141 if ( IsAttached() && GetMenuBar()->IsAttached() )
142 GetMenuBar()->Refresh();
147 void wxMenu
::EndRadioGroup()
149 // we're not inside a radio group any longer
150 m_startRadioGroup
= -1;
153 wxMenuItem
* wxMenu
::DoAppend(wxMenuItem
*item
)
155 wxCHECK_MSG( item
, NULL
, wxT("NULL item in wxMenu::DoAppend") );
159 if ( item
->GetKind() == wxITEM_RADIO
)
161 int count
= GetMenuItemCount();
163 if ( m_startRadioGroup
== -1 )
165 // start a new radio group
166 m_startRadioGroup
= count
;
168 // for now it has just one element
169 item
->SetAsRadioGroupStart();
170 item
->SetRadioGroupEnd(m_startRadioGroup
);
172 // ensure that we have a checked item in the radio group
175 else // extend the current radio group
177 // we need to update its end item
178 item
->SetRadioGroupStart(m_startRadioGroup
);
179 wxMenuItemList
::compatibility_iterator node
= GetMenuItems().Item(m_startRadioGroup
);
183 node
->GetData()->SetRadioGroupEnd(count
);
187 wxFAIL_MSG( wxT("where is the radio group start item?") );
191 else // not a radio item
196 if ( !wxMenuBase
::DoAppend(item
) || !DoInsertOrAppend(item
) )
200 // check the item initially
206 wxMenuItem
* wxMenu
::DoInsert(size_t pos
, wxMenuItem
*item
)
208 if (wxMenuBase
::DoInsert(pos
, item
) && DoInsertOrAppend(item
, pos
))
214 wxMenuItem
*wxMenu
::DoRemove(wxMenuItem
*item
)
217 // we need to find the items position in the child list
219 wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst();
221 for ( pos = 0; node; pos++ )
223 if ( node->GetData() == item )
226 node = node->GetNext();
229 // DoRemove() (unlike Remove) can only be called for existing item!
230 wxCHECK_MSG( node, NULL, wxT("bug in wxMenu::Remove logic") );
232 wxOSXMenuRemoveItem(m_hMenu , pos );
234 m_peer
->Remove( item
);
235 // and from internal data structures
236 return wxMenuBase
::DoRemove(item
);
239 void wxMenu
::SetTitle(const wxString
& label
)
242 m_peer
->SetTitle( wxStripMenuCodes( label
) );
245 bool wxMenu
::ProcessCommand(wxCommandEvent
& event
)
247 bool processed
= false;
249 // Try the menu's event handler
250 if ( /* !processed && */ GetEventHandler())
251 processed
= GetEventHandler()->SafelyProcessEvent(event
);
253 // Try the window the menu was popped up from
254 // (and up through the hierarchy)
255 wxWindow
*win
= GetWindow();
256 if ( !processed
&& win
)
257 processed
= win
->HandleWindowEvent(event
);
262 // ---------------------------------------------------------------------------
264 // ---------------------------------------------------------------------------
266 // MacOS needs to know about submenus somewhere within this menu
267 // before it can be displayed, also hide special menu items
268 // like preferences that are handled by the OS
269 void wxMenu
::DoRearrange()
271 if ( !AllowRearrange() )
274 wxMenuItem
* previousItem
= NULL
;
276 wxMenuItemList
::compatibility_iterator node
;
279 for (pos
= 0, node
= GetMenuItems().GetFirst(); node
; node
= node
->GetNext(), pos
++)
281 item
= (wxMenuItem
*)node
->GetData();
282 wxMenu
* subMenu
= item
->GetSubMenu() ;
289 // what we do here is to hide the special items which are
290 // shown in the application menu anyhow -- it doesn't make
291 // sense to show them in their normal place as well
292 if ( item
->GetId() == wxApp
::s_macAboutMenuItemId
||
293 item
->GetId() == wxApp
::s_macPreferencesMenuItemId
||
294 item
->GetId() == wxApp
::s_macExitMenuItemId
)
297 item
->GetPeer()->Hide( true );
299 // also check for a separator which was used just to
300 // separate this item from the others, so don't leave
301 // separator at the menu start or end nor 2 consecutive
303 wxMenuItemList
::compatibility_iterator nextNode
= node
->GetNext();
304 wxMenuItem
*next
= nextNode ? nextNode
->GetData() : NULL
;
306 wxMenuItem
*sepToHide
= 0;
307 if ( !previousItem
&& next
&& next
->IsSeparator() )
309 // next (i.e. second as we must be first) item is
310 // the separator to hide
311 wxASSERT_MSG( pos
== 0, wxT("should be the menu start") );
314 else if ( GetMenuItems().GetCount() == pos
+ 1 &&
315 previousItem
!= NULL
&&
316 previousItem
->IsSeparator() )
318 // prev item is a trailing separator we want to hide
319 sepToHide
= previousItem
;
321 else if ( previousItem
&& previousItem
->IsSeparator() &&
322 next
&& next
->IsSeparator() )
324 // two consecutive separators, this is one too many
330 // hide the separator as well
331 sepToHide
->GetPeer()->Hide( true );
336 previousItem
= item
;
341 bool wxMenu
::HandleCommandUpdateStatus( wxMenuItem
* item
, wxWindow
* senderWindow
)
343 int id
= item ? item
->GetId() : 0;
344 wxUpdateUIEvent
event(id
);
345 event
.SetEventObject( this );
347 bool processed
= false;
349 // Try the menu's event handler
351 wxEvtHandler
*handler
= GetEventHandler();
353 processed
= handler
->ProcessEvent(event
);
356 // Try the window the menu was popped up from
357 // (and up through the hierarchy)
360 wxWindow
*win
= GetWindow();
362 processed
= win
->HandleWindowEvent(event
);
365 if ( !processed
&& senderWindow
!= NULL
)
367 processed
= senderWindow
->HandleWindowEvent(event
);
372 // if anything changed, update the changed attribute
373 if (event
.GetSetText())
374 SetLabel(id
, event
.GetText());
375 if (event
.GetSetChecked())
376 Check(id
, event
.GetChecked());
377 if (event
.GetSetEnabled())
378 Enable(id
, event
.GetEnabled());
383 // these two items are also managed by the Carbon Menu Manager, therefore we must
384 // always reset them ourselves
387 if ( id
== wxApp
::s_macExitMenuItemId
)
389 cmd
= kHICommandQuit
;
391 else if (id
== wxApp
::s_macPreferencesMenuItemId
)
393 cmd
= kHICommandPreferences
;
398 if ( !item
->IsEnabled() || wxDialog
::OSXHasModalDialogsOpen() )
399 DisableMenuCommand( NULL
, cmd
) ;
401 EnableMenuCommand( NULL
, cmd
) ;
410 bool wxMenu
::HandleCommandProcess( wxMenuItem
* item
, wxWindow
* senderWindow
)
412 int id
= item ? item
->GetId() : 0;
413 bool processed
= false;
414 if (item
->IsCheckable())
415 item
->Check( !item
->IsChecked() ) ;
417 if ( SendEvent( id
, item
->IsCheckable() ? item
->IsChecked() : -1 ) )
421 if ( senderWindow
!= NULL
)
423 wxCommandEvent
event(wxEVT_COMMAND_MENU_SELECTED
, id
);
424 event
.SetEventObject(senderWindow
);
425 event
.SetInt(item
->IsCheckable() ? item
->IsChecked() : -1);
427 if ( senderWindow
->HandleWindowEvent(event
) )
432 if(!processed
&& item
)
434 processed
= item
->GetPeer()->DoDefault();
440 void wxMenu
::HandleMenuItemHighlighted( wxMenuItem
* item
)
442 int id
= item ? item
->GetId() : 0;
443 wxMenuEvent
wxevent(wxEVT_MENU_HIGHLIGHT
, id
, this);
444 DoHandleMenuEvent( wxevent
);
447 void wxMenu
::HandleMenuOpened()
449 wxMenuEvent
wxevent(wxEVT_MENU_OPEN
, 0, this);
450 DoHandleMenuEvent( wxevent
);
453 void wxMenu
::HandleMenuClosed()
455 wxMenuEvent
wxevent(wxEVT_MENU_CLOSE
, 0, this);
456 DoHandleMenuEvent( wxevent
);
459 bool wxMenu
::DoHandleMenuEvent(wxEvent
& wxevent
)
461 wxevent
.SetEventObject(this);
462 wxEvtHandler
* handler
= GetEventHandler();
463 if (handler
&& handler
->ProcessEvent(wxevent
))
469 wxWindow
*win
= GetWindow();
472 if ( win
->HandleWindowEvent(wxevent
) )
483 Mac Implementation note :
485 The Mac has only one global menubar, so we attempt to install the currently
486 active menubar from a frame, we currently don't take into account mdi-frames
487 which would ask for menu-merging
489 Secondly there is no mac api for changing a menubar that is not the current
490 menubar, so we have to wait for preparing the actual menubar until the
491 wxMenubar is to be used
493 We can in subsequent versions use MacInstallMenuBar to provide some sort of
494 auto-merge for MDI in case this will be necessary
498 wxMenuBar
* wxMenuBar
::s_macInstalledMenuBar
= NULL
;
499 wxMenuBar
* wxMenuBar
::s_macCommonMenuBar
= NULL
;
500 bool wxMenuBar
::s_macAutoWindowMenu
= true ;
501 WXHMENU wxMenuBar
::s_macWindowMenuHandle
= NULL
;
503 void wxMenuBar
::Init()
505 m_eventHandler
= this;
506 m_menuBarFrame
= NULL
;
507 m_rootMenu
= new wxMenu();
508 m_rootMenu
->Attach(this);
510 m_appleMenu
= new wxMenu();
511 m_appleMenu
->SetAllowRearrange(false);
513 // Create standard items unless the application explicitly disabled this by
514 // setting the corresponding ids to wxID_NONE: although this is not
515 // recommended, sometimes these items really don't make sense.
516 if ( wxApp
::s_macAboutMenuItemId
!= wxID_NONE
)
518 wxString
aboutLabel(_("About"));
520 aboutLabel
<< ' ' << wxTheApp
->GetAppDisplayName();
523 m_appleMenu
->Append( wxApp
::s_macAboutMenuItemId
, aboutLabel
);
524 m_appleMenu
->AppendSeparator();
527 #if !wxOSX_USE_CARBON
528 if ( wxApp
::s_macPreferencesMenuItemId
!= wxID_NONE
)
530 m_appleMenu
->Append( wxApp
::s_macPreferencesMenuItemId
,
531 _("Preferences...") + "\tCtrl+," );
532 m_appleMenu
->AppendSeparator();
535 // standard menu items, handled in wxMenu::HandleCommandProcess(), see above:
536 wxString
hideLabel(_("Hide"));
538 hideLabel
<< ' ' << wxTheApp
->GetAppDisplayName();
539 hideLabel
<< "\tCtrl+H";
540 m_appleMenu
->Append( wxID_OSX_HIDE
, hideLabel
);
541 m_appleMenu
->Append( wxID_OSX_HIDEOTHERS
, _("Hide Others")+"\tAlt+Ctrl+H" );
542 m_appleMenu
->Append( wxID_OSX_SHOWALL
, _("Show All") );
543 m_appleMenu
->AppendSeparator();
545 // Do always add "Quit" item unconditionally however, it can't be disabled.
546 wxString
quitLabel(_("Quit"));
548 quitLabel
<< ' ' << wxTheApp
->GetAppDisplayName();
549 quitLabel
<< "\tCtrl+Q";
550 m_appleMenu
->Append( wxApp
::s_macExitMenuItemId
, quitLabel
);
551 #endif // !wxOSX_USE_CARBON
553 m_rootMenu
->AppendSubMenu(m_appleMenu
, "\x14") ;
556 wxMenuBar
::wxMenuBar()
561 wxMenuBar
::wxMenuBar( long WXUNUSED(style
) )
566 wxMenuBar
::wxMenuBar(size_t count
, wxMenu
*menus
[], const wxString titles
[], long WXUNUSED(style
))
570 m_titles
.Alloc(count
);
572 for ( size_t i
= 0; i
< count
; i
++ )
574 m_menus
.Append(menus
[i
]);
575 m_titles
.Add(titles
[i
]);
577 menus
[i
]->Attach(this);
578 Append( menus
[i
], titles
[i
] );
582 wxMenuBar
::~wxMenuBar()
584 if (s_macCommonMenuBar
== this)
585 s_macCommonMenuBar
= NULL
;
587 if (s_macInstalledMenuBar
== this)
589 s_macInstalledMenuBar
= NULL
;
593 void wxMenuBar
::Refresh(bool WXUNUSED(eraseBackground
), const wxRect
*WXUNUSED(rect
))
595 wxCHECK_RET( IsAttached(), wxT("can't refresh unatteched menubar") );
598 void wxMenuBar
::MacInstallMenuBar()
600 if ( s_macInstalledMenuBar
== this )
603 m_rootMenu
->GetPeer()->MakeRoot();
607 MenuBarHandle menubar
= NULL
;
609 menubar
= NewHandleClear( 6 /* sizeof( MenuBarHeader ) */ ) ;
611 ::SetMenuBar( menubar
) ;
612 DisposeMenuBar( menubar
) ;
613 MenuHandle appleMenu
= NULL
;
615 verify_noerr( CreateNewMenu( kwxMacAppleMenuId
, 0 , &appleMenu
) ) ;
616 verify_noerr( SetMenuTitleWithCFString( appleMenu
, CFSTR( "\x14" ) ) );
618 // Add About/Preferences separator only on OS X
619 // KH/RN: Separator is always present on 10.3 but not on 10.2
620 // However, the change from 10.2 to 10.3 suggests it is preferred
621 InsertMenuItemTextWithCFString( appleMenu
,
622 CFSTR(""), 0, kMenuItemAttrSeparator
, 0);
623 InsertMenuItemTextWithCFString( appleMenu
,
624 CFSTR("About..."), 0, 0, 0);
625 MacInsertMenu( appleMenu
, 0 ) ;
627 // if we have a mac help menu, clean it up before adding new items
628 MenuHandle helpMenuHandle
;
629 MenuItemIndex firstUserHelpMenuItem
;
631 if ( UMAGetHelpMenuDontCreate( &helpMenuHandle
, &firstUserHelpMenuItem
) == noErr
)
633 for ( int i
= CountMenuItems( helpMenuHandle
) ; i
>= firstUserHelpMenuItem
; --i
)
634 DeleteMenuItem( helpMenuHandle
, i
) ;
638 helpMenuHandle
= NULL
;
641 if ( wxApp
::s_macPreferencesMenuItemId
)
643 wxMenuItem
*item
= FindItem( wxApp
::s_macPreferencesMenuItemId
, NULL
) ;
644 if ( item
== NULL
|| !(item
->IsEnabled()) )
645 DisableMenuCommand( NULL
, kHICommandPreferences
) ;
647 EnableMenuCommand( NULL
, kHICommandPreferences
) ;
650 // Unlike preferences which may or may not exist, the Quit item should be always
651 // enabled unless it is added by the application and then disabled, otherwise
652 // a program would be required to add an item with wxID_EXIT in order to get the
653 // Quit menu item to be enabled, which seems a bit burdensome.
654 if ( wxApp
::s_macExitMenuItemId
)
656 wxMenuItem
*item
= FindItem( wxApp
::s_macExitMenuItemId
, NULL
) ;
657 if ( item
!= NULL
&& !(item
->IsEnabled()) )
658 DisableMenuCommand( NULL
, kHICommandQuit
) ;
660 EnableMenuCommand( NULL
, kHICommandQuit
) ;
663 wxString strippedHelpMenuTitle
= wxStripMenuCodes( wxApp
::s_macHelpMenuTitleName
) ;
664 wxString strippedTranslatedHelpMenuTitle
= wxStripMenuCodes( wxString( _("&Help") ) ) ;
665 wxMenuList
::compatibility_iterator menuIter
= m_menus
.GetFirst();
666 for (size_t i
= 0; i
< m_menus
.GetCount(); i
++, menuIter
= menuIter
->GetNext())
668 wxMenuItemList
::compatibility_iterator node
;
670 wxMenu
* menu
= menuIter
->GetData() , *subMenu
= NULL
;
671 wxString strippedMenuTitle
= wxStripMenuCodes(m_titles
[i
]);
673 if ( strippedMenuTitle
== wxT("?") || strippedMenuTitle
== strippedHelpMenuTitle
|| strippedMenuTitle
== strippedTranslatedHelpMenuTitle
)
675 for (node
= menu
->GetMenuItems().GetFirst(); node
; node
= node
->GetNext())
677 item
= (wxMenuItem
*)node
->GetData();
678 subMenu
= item
->GetSubMenu() ;
681 UMAAppendMenuItem(mh
, wxStripMenuCodes(item
->GetText()) , wxFont
::GetDefaultEncoding() );
682 MenuItemIndex position
= CountMenuItems(mh
);
683 ::SetMenuItemHierarchicalMenu(mh
, position
, MAC_WXHMENU(subMenu
->GetHMenu()));
687 if ( item
->GetId() != wxApp
::s_macAboutMenuItemId
)
689 // we have found a user help menu and an item other than the about item,
690 // so we can create the mac help menu now, if we haven't created it yet
691 if ( helpMenuHandle
== NULL
)
693 if ( UMAGetHelpMenu( &helpMenuHandle
, &firstUserHelpMenuItem
) != noErr
)
695 helpMenuHandle
= NULL
;
701 if ( item
->IsSeparator() )
703 if ( helpMenuHandle
)
704 AppendMenuItemTextWithCFString( helpMenuHandle
,
705 CFSTR(""), kMenuItemAttrSeparator
, 0,NULL
);
710 entry
= wxAcceleratorEntry
::Create( item
->GetItemLabel() ) ;
712 if ( item
->GetId() == wxApp
::s_macAboutMenuItemId
)
714 // this will be taken care of below
718 if ( helpMenuHandle
)
720 UMAAppendMenuItem(helpMenuHandle
, wxStripMenuCodes(item
->GetItemLabel()) , wxFont
::GetDefaultEncoding(), entry
);
721 SetMenuItemCommandID( helpMenuHandle
, CountMenuItems(helpMenuHandle
) , wxIdToMacCommand ( item
->GetId() ) ) ;
722 SetMenuItemRefCon( helpMenuHandle
, CountMenuItems(helpMenuHandle
) , (URefCon
) item
) ;
732 else if ( ( m_titles
[i
] == wxT("Window") || m_titles
[i
] == wxT("&Window") )
733 && GetAutoWindowMenu() )
735 if ( MacGetWindowMenuHMenu() == NULL
)
737 CreateStandardWindowMenu( 0 , (MenuHandle
*) &s_macWindowMenuHandle
) ;
740 MenuRef wm
= (MenuRef
)MacGetWindowMenuHMenu();
744 // get the insertion point in the standard menu
745 MenuItemIndex winListStart
;
746 GetIndMenuItemWithCommandID(wm
,
747 kHICommandWindowListSeparator
, 1, NULL
, &winListStart
);
749 // add a separator so that the standard items and the custom items
750 // aren't mixed together, but only if this is the first run
751 OSStatus err
= GetIndMenuItemWithCommandID(wm
,
752 'WXWM', 1, NULL
, NULL
);
754 if ( err
== menuItemNotFoundErr
)
756 InsertMenuItemTextWithCFString( wm
,
757 CFSTR(""), winListStart
-1, kMenuItemAttrSeparator
, 'WXWM');
760 wxInsertMenuItemsInMenu(menu
, wm
, winListStart
);
764 UMASetMenuTitle( MAC_WXHMENU(menu
->GetHMenu()) , m_titles
[i
], GetFont().GetEncoding() ) ;
765 menu
->MacBeforeDisplay(false) ;
767 ::InsertMenu(MAC_WXHMENU(GetMenu(i
)->GetHMenu()), 0);
771 // take care of the about menu item wherever it is
774 wxMenuItem
*aboutMenuItem
= FindItem(wxApp
::s_macAboutMenuItemId
, &aboutMenu
) ;
778 entry
= wxAcceleratorEntry
::Create( aboutMenuItem
->GetItemLabel() ) ;
779 UMASetMenuItemText( GetMenuHandle( kwxMacAppleMenuId
) , 1 , wxStripMenuCodes ( aboutMenuItem
->GetItemLabel() ) , wxFont
::GetDefaultEncoding() );
780 UMAEnableMenuItem( GetMenuHandle( kwxMacAppleMenuId
) , 1 , true );
781 SetMenuItemCommandID( GetMenuHandle( kwxMacAppleMenuId
) , 1 , kHICommandAbout
) ;
782 SetMenuItemRefCon(GetMenuHandle( kwxMacAppleMenuId
) , 1 , (URefCon
)aboutMenuItem
) ;
783 UMASetMenuItemShortcut( GetMenuHandle( kwxMacAppleMenuId
) , 1 , entry
) ;
788 if ( GetAutoWindowMenu() )
790 if ( MacGetWindowMenuHMenu() == NULL
)
791 CreateStandardWindowMenu( 0 , (MenuHandle
*) &s_macWindowMenuHandle
) ;
793 InsertMenu( (MenuHandle
) MacGetWindowMenuHMenu() , 0 ) ;
799 s_macInstalledMenuBar
= this;
802 void wxMenuBar
::EnableTop(size_t pos
, bool enable
)
804 wxCHECK_RET( IsAttached(), wxT("doesn't work with unattached menubars") );
806 m_rootMenu
->FindItemByPosition( pos
)->Enable(enable
);
811 bool wxMenuBar
::Enable(bool enable
)
813 wxCHECK_MSG( IsAttached(), false, wxT("doesn't work with unattached menubars") );
816 for (i
= 0; i
< GetMenuCount(); i
++)
817 EnableTop(i
, enable
);
822 void wxMenuBar
::SetMenuLabel(size_t pos
, const wxString
& label
)
824 wxCHECK_RET( pos
< GetMenuCount(), wxT("invalid menu index") );
826 m_titles
[pos
] = label
;
831 GetMenu(pos
)->SetTitle( label
) ;
834 wxString wxMenuBar
::GetMenuLabel(size_t pos
) const
836 wxCHECK_MSG( pos
< GetMenuCount(), wxEmptyString
,
837 wxT("invalid menu index in wxMenuBar::GetMenuLabel") );
839 return m_titles
[pos
];
842 int wxMenuBar
::FindMenu(const wxString
& title
)
844 wxString menuTitle
= wxStripMenuCodes(title
);
846 size_t count
= GetMenuCount();
847 for ( size_t i
= 0; i
< count
; i
++ )
849 wxString title
= wxStripMenuCodes(m_titles
[i
]);
850 if ( menuTitle
== title
)
857 // ---------------------------------------------------------------------------
858 // wxMenuBar construction
859 // ---------------------------------------------------------------------------
861 const int firstMenuPos
= 1; // to account for the 0th application menu on mac
863 wxMenu
*wxMenuBar
::Replace(size_t pos
, wxMenu
*menu
, const wxString
& title
)
865 wxMenu
*menuOld
= wxMenuBarBase
::Replace(pos
, menu
, title
);
869 m_titles
[pos
] = title
;
871 wxMenuItem
* item
= m_rootMenu
->FindItemByPosition(pos
+firstMenuPos
);
872 m_rootMenu
->Remove(item
);
873 m_rootMenu
->Insert( pos
+firstMenuPos
, wxMenuItem
::New( m_rootMenu
, wxID_ANY
, title
, "", wxITEM_NORMAL
, menu
) );
878 bool wxMenuBar
::Insert(size_t pos
, wxMenu
*menu
, const wxString
& title
)
880 if ( !wxMenuBarBase
::Insert(pos
, menu
, title
) )
883 m_titles
.Insert(title
, pos
);
885 m_rootMenu
->Insert( pos
+firstMenuPos
, wxMenuItem
::New( m_rootMenu
, wxID_ANY
, title
, "", wxITEM_NORMAL
, menu
) );
890 wxMenu
*wxMenuBar
::Remove(size_t pos
)
892 wxMenu
*menu
= wxMenuBarBase
::Remove(pos
);
896 wxMenuItem
* item
= m_rootMenu
->FindItemByPosition(pos
+firstMenuPos
);
897 m_rootMenu
->Remove(item
);
899 m_titles
.RemoveAt(pos
);
904 bool wxMenuBar
::Append(wxMenu
*menu
, const wxString
& title
)
906 WXHMENU submenu
= menu ? menu
->GetHMenu() : 0;
907 wxCHECK_MSG( submenu
, false, wxT("can't append invalid menu to menubar") );
909 if ( !wxMenuBarBase
::Append(menu
, title
) )
914 m_rootMenu
->AppendSubMenu(menu
, title
);
919 void wxMenuBar
::Detach()
921 wxMenuBarBase
::Detach() ;
924 void wxMenuBar
::Attach(wxFrame
*frame
)
926 wxMenuBarBase
::Attach( frame
) ;
929 // ---------------------------------------------------------------------------
930 // wxMenuBar searching for menu items
931 // ---------------------------------------------------------------------------
933 // Find the itemString in menuString, and return the item id or wxNOT_FOUND
934 int wxMenuBar
::FindMenuItem(const wxString
& menuString
,
935 const wxString
& itemString
) const
937 wxString menuLabel
= wxStripMenuCodes(menuString
);
938 size_t count
= GetMenuCount();
939 for ( size_t i
= 0; i
< count
; i
++ )
941 wxString title
= wxStripMenuCodes(m_titles
[i
]);
942 if ( menuLabel
== title
)
943 return GetMenu(i
)->FindItem(itemString
);
949 wxMenuItem
*wxMenuBar
::FindItem(int id
, wxMenu
**itemMenu
) const
954 wxMenuItem
*item
= NULL
;
955 size_t count
= GetMenuCount();
956 for ( size_t i
= 0; !item
&& (i
< count
); i
++ )
957 item
= GetMenu(i
)->FindItem(id
, itemMenu
);