1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxMenu, wxMenuBar, wxMenuItem
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "menu.h"
14 #pragma implementation "menuitem.h"
17 // ============================================================================
18 // headers & declarations
19 // ============================================================================
26 #include "wx/menuitem.h"
27 #include "wx/window.h"
32 #include "wx/mac/uma.h"
34 // other standard headers
35 // ----------------------
38 #if !USE_SHARED_LIBRARY
39 IMPLEMENT_DYNAMIC_CLASS(wxMenu
, wxEvtHandler
)
40 IMPLEMENT_DYNAMIC_CLASS(wxMenuBar
, wxEvtHandler
)
43 // the (popup) menu title has this special id
44 static const int idMenuTitle
= -3;
45 static MenuItemIndex firstUserHelpMenuItem
= 0 ;
47 const short kwxMacMenuBarResource
= 1 ;
48 const short kwxMacAppleMenuId
= 1 ;
51 // Find an item given the Macintosh Menu Reference
53 #if KEY_wxList_DEPRECATED
54 wxList
wxWinMacMenuList(wxKEY_INTEGER
);
55 wxMenu
*wxFindMenuFromMacMenu(MenuRef inMenuRef
)
57 wxNode
*node
= wxWinMacMenuList
.Find((long)inMenuRef
);
60 return (wxMenu
*)node
->GetData();
63 void wxAssociateMenuWithMacMenu(MenuRef inMenuRef
, wxMenu
*menu
) ;
64 void wxAssociateMenuWithMacMenu(MenuRef inMenuRef
, wxMenu
*menu
)
66 // adding NULL MenuRef is (first) surely a result of an error and
67 // (secondly) breaks menu command processing
68 wxCHECK_RET( inMenuRef
!= (MenuRef
) NULL
, wxT("attempt to add a NULL MenuRef to menu list") );
70 if ( !wxWinMacMenuList
.Find((long)inMenuRef
) )
71 wxWinMacMenuList
.Append((long)inMenuRef
, menu
);
74 void wxRemoveMacMenuAssociation(wxMenu
*menu
) ;
75 void wxRemoveMacMenuAssociation(wxMenu
*menu
)
77 wxWinMacMenuList
.DeleteObject(menu
);
81 WX_DECLARE_HASH_MAP(MenuRef
, wxMenu
*, wxPointerHash
, wxPointerEqual
, MacMenuMap
);
83 static MacMenuMap wxWinMacMenuList
;
85 wxMenu
*wxFindMenuFromMacMenu(MenuRef inMenuRef
)
87 MacMenuMap::iterator node
= wxWinMacMenuList
.find(inMenuRef
);
89 return (node
== wxWinMacMenuList
.end()) ? NULL
: node
->second
;
92 void wxAssociateMenuWithMacMenu(MenuRef inMenuRef
, wxMenu
*menu
) ;
93 void wxAssociateMenuWithMacMenu(MenuRef inMenuRef
, wxMenu
*menu
)
95 // adding NULL MenuRef is (first) surely a result of an error and
96 // (secondly) breaks menu command processing
97 wxCHECK_RET( inMenuRef
!= (MenuRef
) NULL
, wxT("attempt to add a NULL MenuRef to menu list") );
99 wxWinMacMenuList
[inMenuRef
] = menu
;
102 void wxRemoveMacMenuAssociation(wxMenu
*menu
) ;
103 void wxRemoveMacMenuAssociation(wxMenu
*menu
)
105 // iterate over all the elements in the class
106 MacMenuMap::iterator it
;
107 for ( it
= wxWinMacMenuList
.begin(); it
!= wxWinMacMenuList
.end(); ++it
)
109 if ( it
->second
== menu
)
111 wxWinMacMenuList
.erase(it
);
116 #endif // deprecated wxList
118 // ============================================================================
120 // ============================================================================
121 static void wxMenubarUnsetInvokingWindow( wxMenu
*menu
) ;
122 static void wxMenubarSetInvokingWindow( wxMenu
*menu
, wxWindow
*win
);
126 // Construct a menu with optional title (then use append)
129 short wxMenu::s_macNextMenuId
= 3 ;
131 short wxMenu::s_macNextMenuId
= 2 ;
136 _wxMenuAt(const wxMenuList
&menuList
, size_t pos
)
138 wxMenuList::compatibility_iterator menuIter
= menuList
.GetFirst();
140 while (pos
-- > 0) menuIter
= menuIter
->GetNext();
142 return menuIter
->GetData() ;
148 m_startRadioGroup
= -1;
151 m_macMenuId
= s_macNextMenuId
++;
152 m_hMenu
= UMANewMenu(m_macMenuId
, m_title
, wxFont::GetDefaultEncoding() );
156 wxLogLastError(wxT("UMANewMenu failed"));
159 wxAssociateMenuWithMacMenu( (MenuRef
)m_hMenu
, this ) ;
161 // if we have a title, insert it in the beginning of the menu
164 Append(idMenuTitle
, m_title
) ;
171 wxRemoveMacMenuAssociation( this ) ;
172 if (MAC_WXHMENU(m_hMenu
))
173 ::DisposeMenu(MAC_WXHMENU(m_hMenu
));
178 // not available on the mac platform
181 void wxMenu::Attach(wxMenuBarBase
*menubar
)
183 wxMenuBase::Attach(menubar
);
188 // function appends a new item or submenu to the menu
189 // append a new item or submenu to the menu
190 bool wxMenu::DoInsertOrAppend(wxMenuItem
*pItem
, size_t pos
)
192 wxASSERT_MSG( pItem
!= NULL
, wxT("can't append NULL item to the menu") );
194 if ( pItem
->IsSeparator() )
196 if ( pos
== (size_t)-1 )
197 MacAppendMenu(MAC_WXHMENU(m_hMenu
), "\p-");
199 MacInsertMenuItem(MAC_WXHMENU(m_hMenu
), "\p-" , pos
);
203 wxMenu
*pSubMenu
= pItem
->GetSubMenu() ;
204 if ( pSubMenu
!= NULL
)
206 wxASSERT_MSG( pSubMenu
->m_hMenu
!= NULL
, wxT("invalid submenu added"));
207 pSubMenu
->m_menuParent
= this ;
209 if (wxMenuBar::MacGetInstalledMenuBar() == GetMenuBar())
211 pSubMenu
->MacBeforeDisplay( true ) ;
214 if ( pos
== (size_t)-1 )
215 UMAAppendSubMenuItem(MAC_WXHMENU(m_hMenu
), pItem
->GetText(), wxFont::GetDefaultEncoding() , pSubMenu
->m_macMenuId
);
217 UMAInsertSubMenuItem(MAC_WXHMENU(m_hMenu
), pItem
->GetText(), wxFont::GetDefaultEncoding() , pos
, pSubMenu
->m_macMenuId
);
218 pItem
->UpdateItemBitmap() ;
219 pItem
->UpdateItemStatus() ;
223 if ( pos
== (size_t)-1 )
225 UMAAppendMenuItem(MAC_WXHMENU(m_hMenu
), wxT("a") , wxFont::GetDefaultEncoding() );
226 pos
= CountMenuItems(MAC_WXHMENU(m_hMenu
)) ;
230 // MacOS counts menu items from 1 and inserts after, therefore having the
231 // same effect as wx 0 based and inserting before, we must correct pos
232 // after however for updates to be correct
233 UMAInsertMenuItem(MAC_WXHMENU(m_hMenu
), wxT("a"), wxFont::GetDefaultEncoding(), pos
);
237 SetMenuItemCommandID( MAC_WXHMENU(m_hMenu
) , pos
, pItem
->GetId() ) ;
238 SetMenuItemRefCon( MAC_WXHMENU(m_hMenu
) , pos
, (UInt32
) pItem
) ;
239 pItem
->UpdateItemText() ;
240 pItem
->UpdateItemBitmap() ;
241 pItem
->UpdateItemStatus() ;
243 if ( pItem
->GetId() == idMenuTitle
)
245 UMAEnableMenuItem(MAC_WXHMENU(m_hMenu
) , pos
, false ) ;
249 // if we're already attached to the menubar, we must update it
252 GetMenuBar()->Refresh();
257 void wxMenu::EndRadioGroup()
259 // we're not inside a radio group any longer
260 m_startRadioGroup
= -1;
263 wxMenuItem
* wxMenu::DoAppend(wxMenuItem
*item
)
265 wxCHECK_MSG( item
, NULL
, _T("NULL item in wxMenu::DoAppend") );
269 if ( item
->GetKind() == wxITEM_RADIO
)
271 int count
= GetMenuItemCount();
273 if ( m_startRadioGroup
== -1 )
275 // start a new radio group
276 m_startRadioGroup
= count
;
278 // for now it has just one element
279 item
->SetAsRadioGroupStart();
280 item
->SetRadioGroupEnd(m_startRadioGroup
);
282 // ensure that we have a checked item in the radio group
285 else // extend the current radio group
287 // we need to update its end item
288 item
->SetRadioGroupStart(m_startRadioGroup
);
289 wxMenuItemList::compatibility_iterator node
= GetMenuItems().Item(m_startRadioGroup
);
293 node
->GetData()->SetRadioGroupEnd(count
);
297 wxFAIL_MSG( _T("where is the radio group start item?") );
301 else // not a radio item
306 if ( !wxMenuBase::DoAppend(item
) || !DoInsertOrAppend(item
) )
313 // check the item initially
320 wxMenuItem
* wxMenu::DoInsert(size_t pos
, wxMenuItem
*item
)
322 if (wxMenuBase::DoInsert(pos
, item
) && DoInsertOrAppend(item
, pos
))
328 wxMenuItem
*wxMenu::DoRemove(wxMenuItem
*item
)
330 // we need to find the items position in the child list
332 wxMenuItemList::compatibility_iterator node
= GetMenuItems().GetFirst();
333 for ( pos
= 0; node
; pos
++ )
335 if ( node
->GetData() == item
)
338 node
= node
->GetNext();
341 // DoRemove() (unlike Remove) can only be called for existing item!
342 wxCHECK_MSG( node
, NULL
, wxT("bug in wxMenu::Remove logic") );
344 ::DeleteMenuItem(MAC_WXHMENU(m_hMenu
) , pos
+ 1);
348 // otherwise, the change won't be visible
349 GetMenuBar()->Refresh();
352 // and from internal data structures
353 return wxMenuBase::DoRemove(item
);
356 void wxMenu::SetTitle(const wxString
& label
)
359 UMASetMenuTitle(MAC_WXHMENU(m_hMenu
) , label
, wxFont::GetDefaultEncoding() ) ;
361 bool wxMenu::ProcessCommand(wxCommandEvent
& event
)
363 bool processed
= FALSE
;
365 // Try the menu's event handler
366 if ( !processed
&& GetEventHandler())
368 processed
= GetEventHandler()->ProcessEvent(event
);
371 // Try the window the menu was popped up from (and up through the
373 wxWindow
*win
= GetInvokingWindow();
374 if ( !processed
&& win
)
375 processed
= win
->GetEventHandler()->ProcessEvent(event
);
381 // ---------------------------------------------------------------------------
383 // ---------------------------------------------------------------------------
385 wxWindow
*wxMenu::GetWindow() const
387 if ( m_invokingWindow
!= NULL
)
388 return m_invokingWindow
;
389 else if ( GetMenuBar() != NULL
)
390 return (wxWindow
*) GetMenuBar()->GetFrame();
395 // helper functions returning the mac menu position for a certain item, note that this is
396 // mac-wise 1 - based, i.e. the first item has index 1 whereas on MSWin it has pos 0
398 int wxMenu::MacGetIndexFromId( int id
)
401 wxMenuItemList::compatibility_iterator node
= GetMenuItems().GetFirst();
402 for ( pos
= 0; node
; pos
++ )
404 if ( node
->GetData()->GetId() == id
)
407 node
= node
->GetNext();
416 int wxMenu::MacGetIndexFromItem( wxMenuItem
*pItem
)
419 wxMenuItemList::compatibility_iterator node
= GetMenuItems().GetFirst();
420 for ( pos
= 0; node
; pos
++ )
422 if ( node
->GetData() == pItem
)
425 node
= node
->GetNext();
434 void wxMenu::MacEnableMenu( bool bDoEnable
)
436 UMAEnableMenuItem(MAC_WXHMENU(m_hMenu
) , 0 , bDoEnable
) ;
441 // MacOS needs to know about submenus somewhere within this menu
442 // before it can be displayed , also hide special menu items like preferences
443 // that are handled by the OS
444 void wxMenu::MacBeforeDisplay( bool isSubMenu
)
446 wxMenuItem
* previousItem
= NULL
;
448 wxMenuItemList::compatibility_iterator node
;
450 for (pos
= 0, node
= GetMenuItems().GetFirst(); node
; node
= node
->GetNext(), pos
++)
452 item
= (wxMenuItem
*)node
->GetData();
453 wxMenu
* subMenu
= item
->GetSubMenu() ;
456 subMenu
->MacBeforeDisplay( true ) ;
461 if ( UMAGetSystemVersion() >= 0x1000 )
463 // what we do here is to hide the special items which are
464 // shown in the application menu anyhow -- it doesn't make
465 // sense to show them in their normal place as well
466 if ( item
->GetId() == wxApp::s_macPreferencesMenuItemId
||
467 item
->GetId() == wxApp::s_macExitMenuItemId
)
469 ChangeMenuItemAttributes( MAC_WXHMENU( GetHMenu() ),
470 pos
+ 1, kMenuItemAttrHidden
, 0 );
472 // also check for a separator which was used just to
473 // separate this item from the others, so don't leave
474 // separator at the menu start or end nor 2 consecutive
476 wxMenuItemList::compatibility_iterator nextNode
= node
->GetNext();
477 wxMenuItem
*next
= nextNode
? nextNode
->GetData() : NULL
;
480 if ( !previousItem
&& next
&& next
->IsSeparator() )
482 // next (i.e. second as we must be first) item is
483 // the separator to hide
484 wxASSERT_MSG( pos
== 0, _T("should be the menu start") );
487 else if ( GetMenuItems().GetCount() == pos
+ 1 &&
488 previousItem
!= NULL
&&
489 previousItem
->IsSeparator() )
491 // prev item is a trailing separator we want to hide
494 else if ( previousItem
&& previousItem
->IsSeparator() &&
495 next
&& next
->IsSeparator() )
497 // two consecutive separators, this is one too many
500 else // no separators to hide
507 // hide the separator as well
508 ChangeMenuItemAttributes( MAC_WXHMENU( GetHMenu() ),
515 #endif // TARGET_CARBON
517 previousItem
= item
;
521 ::InsertMenu(MAC_WXHMENU( GetHMenu()), -1);
524 // undo all changes from the MacBeforeDisplay call
525 void wxMenu::MacAfterDisplay( bool isSubMenu
)
528 ::DeleteMenu(MacGetMenuId());
530 wxMenuItem
* previousItem
= NULL
;
532 wxMenuItemList::compatibility_iterator node
;
534 for (pos
= 0, node
= GetMenuItems().GetFirst(); node
; node
= node
->GetNext(), pos
++)
536 item
= (wxMenuItem
*)node
->GetData();
537 wxMenu
* subMenu
= item
->GetSubMenu() ;
540 subMenu
->MacAfterDisplay( true ) ;
544 // no need to undo hidings
546 previousItem
= item
;
554 Mac Implementation note :
556 The Mac has only one global menubar, so we attempt to install the currently
557 active menubar from a frame, we currently don't take into account mdi-frames
558 which would ask for menu-merging
560 Secondly there is no mac api for changing a menubar that is not the current
561 menubar, so we have to wait for preparing the actual menubar until the
562 wxMenubar is to be used
564 We can in subsequent versions use MacInstallMenuBar to provide some sort of
565 auto-merge for MDI in case this will be necessary
569 wxMenuBar
* wxMenuBar::s_macInstalledMenuBar
= NULL
;
570 wxMenuBar
* wxMenuBar::s_macCommonMenuBar
= NULL
;
572 void wxMenuBar::Init()
574 m_eventHandler
= this;
575 m_menuBarFrame
= NULL
;
576 m_invokingWindow
= (wxWindow
*) NULL
;
579 wxMenuBar::wxMenuBar()
584 wxMenuBar::wxMenuBar( long WXUNUSED(style
) )
590 wxMenuBar::wxMenuBar(int count
, wxMenu
*menus
[], const wxString titles
[])
594 m_titles
.Alloc(count
);
596 for ( int i
= 0; i
< count
; i
++ )
598 m_menus
.Append(menus
[i
]);
599 m_titles
.Add(titles
[i
]);
601 menus
[i
]->Attach(this);
605 wxMenuBar::~wxMenuBar()
607 if (s_macCommonMenuBar
== this)
608 s_macCommonMenuBar
= NULL
;
609 if (s_macInstalledMenuBar
== this)
612 s_macInstalledMenuBar
= NULL
;
617 void wxMenuBar::Refresh(bool WXUNUSED(eraseBackground
), const wxRect
*WXUNUSED(rect
))
619 wxCHECK_RET( IsAttached(), wxT("can't refresh unatteched menubar") );
624 void wxMenuBar::MacInstallMenuBar()
626 if ( s_macInstalledMenuBar
== this )
629 MenuBarHandle menubar
= NULL
;
630 #if TARGET_API_MAC_OSX
631 menubar
= NewHandleClear( 6 /* sizeof( MenuBarHeader ) */ ) ;
633 menubar
= NewHandleClear( 12 ) ;
634 (*menubar
)[3] = 0x0a ;
636 ::SetMenuBar( menubar
) ;
637 DisposeMenuBar( menubar
) ;
638 MenuHandle appleMenu
= NULL
;
639 char appleMenuTitle
[3] = { 01 , kMenuAppleLogoFilledGlyph
, 0 } ;
641 verify_noerr( CreateNewMenu( kwxMacAppleMenuId
, 0 , &appleMenu
) ) ;
642 verify_noerr( SetMenuTitle( appleMenu
, (ConstStr255Param
) appleMenuTitle
) );
644 // Add About/Preferences separator only on OS X
645 // KH/RN: Separator is always present on 10.3 but not on 10.2
646 // However, the change from 10.2 to 10.3 suggests it is preferred
647 #if TARGET_API_MAC_OSX
648 MacInsertMenuItem( appleMenu
, "\p-" , 0 ) ;
651 MacInsertMenuItem( appleMenu
, "\pAbout..." , 0 ) ;
652 MacInsertMenu( appleMenu
, 0 ) ;
654 // clean-up the help menu before adding new items
655 MenuHandle mh
= NULL
;
656 if ( UMAGetHelpMenu( &mh
, &firstUserHelpMenuItem
) == noErr
)
658 for ( int i
= CountMenuItems( mh
) ; i
>= firstUserHelpMenuItem
; --i
)
660 DeleteMenuItem( mh
, i
) ;
668 if ( UMAGetSystemVersion() >= 0x1000 && wxApp::s_macPreferencesMenuItemId
)
670 wxMenuItem
*item
= FindItem( wxApp::s_macPreferencesMenuItemId
, NULL
) ;
671 if ( item
== NULL
|| !(item
->IsEnabled()) )
672 DisableMenuCommand( NULL
, kHICommandPreferences
) ;
674 EnableMenuCommand( NULL
, kHICommandPreferences
) ;
677 wxMenuList::compatibility_iterator menuIter
= m_menus
.GetFirst();
679 for (size_t i
= 0; i
< m_menus
.GetCount(); i
++, menuIter
= menuIter
->GetNext())
681 wxMenuItemList::compatibility_iterator node
;
684 wxMenu
* menu
= menuIter
->GetData() , *subMenu
= NULL
;
686 if( m_titles
[i
] == wxT("?") || m_titles
[i
] == wxT("&?") || m_titles
[i
] == wxApp::s_macHelpMenuTitleName
)
693 for (pos
= 0 , node
= menu
->GetMenuItems().GetFirst(); node
; node
= node
->GetNext(), pos
++)
695 item
= (wxMenuItem
*)node
->GetData();
696 subMenu
= item
->GetSubMenu() ;
699 // we don't support hierarchical menus in the help menu yet
703 if ( item
->IsSeparator() )
706 MacAppendMenu(mh
, "\p-" );
710 wxAcceleratorEntry
* entry
= wxGetAccelFromString( item
->GetText() ) ;
712 if ( item
->GetId() == wxApp::s_macAboutMenuItemId
)
714 UMASetMenuItemText( GetMenuHandle( kwxMacAppleMenuId
) , 1 , item
->GetText() , wxFont::GetDefaultEncoding() );
715 UMAEnableMenuItem( GetMenuHandle( kwxMacAppleMenuId
) , 1 , true );
716 SetMenuItemCommandID( GetMenuHandle( kwxMacAppleMenuId
) , 1 , item
->GetId() ) ;
717 SetMenuItemRefCon(GetMenuHandle( kwxMacAppleMenuId
) , 1 , (UInt32
)item
) ;
718 UMASetMenuItemShortcut( GetMenuHandle( kwxMacAppleMenuId
) , 1 , entry
) ;
724 UMAAppendMenuItem(mh
, item
->GetText() , wxFont::GetDefaultEncoding(), entry
);
725 SetMenuItemCommandID( mh
, CountMenuItems(mh
) , item
->GetId() ) ;
726 SetMenuItemRefCon( mh
, CountMenuItems(mh
) , (UInt32
)item
) ;
737 UMASetMenuTitle( MAC_WXHMENU(menu
->GetHMenu()) , m_titles
[i
], m_font
.GetEncoding() ) ;
738 menu
->MacBeforeDisplay(false) ;
739 ::InsertMenu(MAC_WXHMENU(_wxMenuAt(m_menus
, i
)->GetHMenu()), 0);
743 s_macInstalledMenuBar
= this;
746 void wxMenuBar::EnableTop(size_t pos
, bool enable
)
748 wxCHECK_RET( IsAttached(), wxT("doesn't work with unattached menubars") );
749 _wxMenuAt(m_menus
, pos
)->MacEnableMenu( enable
) ;
753 bool wxMenuBar::Enable( bool enable
)
755 wxCHECK_MSG( IsAttached(), false, wxT("doesn't work with unattached menubars") );
757 for (i
= 0; i
< GetMenuCount(); i
++)
759 EnableTop(i
, enable
);
764 void wxMenuBar::SetLabelTop(size_t pos
, const wxString
& label
)
766 wxCHECK_RET( pos
< GetMenuCount(), wxT("invalid menu index") );
768 m_titles
[pos
] = label
;
775 _wxMenuAt(m_menus
, pos
)->SetTitle( label
) ;
777 if (wxMenuBar::s_macInstalledMenuBar
== this) // are we currently installed ?
779 ::SetMenuBar( GetMenuBar() ) ;
784 wxString
wxMenuBar::GetLabelTop(size_t pos
) const
786 wxCHECK_MSG( pos
< GetMenuCount(), wxEmptyString
,
787 wxT("invalid menu index in wxMenuBar::GetLabelTop") );
789 return m_titles
[pos
];
792 int wxMenuBar::FindMenu(const wxString
& title
)
794 wxString menuTitle
= wxStripMenuCodes(title
);
796 size_t count
= GetMenuCount();
797 for ( size_t i
= 0; i
< count
; i
++ )
799 wxString title
= wxStripMenuCodes(m_titles
[i
]);
800 if ( menuTitle
== title
)
809 // ---------------------------------------------------------------------------
810 // wxMenuBar construction
811 // ---------------------------------------------------------------------------
813 // ---------------------------------------------------------------------------
814 // wxMenuBar construction
815 // ---------------------------------------------------------------------------
817 wxMenu
*wxMenuBar::Replace(size_t pos
, wxMenu
*menu
, const wxString
& title
)
819 wxMenu
*menuOld
= wxMenuBarBase::Replace(pos
, menu
, title
);
822 m_titles
[pos
] = title
;
826 if (s_macInstalledMenuBar
== this)
828 menuOld
->MacAfterDisplay( false ) ;
829 ::DeleteMenu( menuOld
->MacGetMenuId() /* m_menus[pos]->MacGetMenuId() */ ) ;
831 menu
->MacBeforeDisplay( false ) ;
832 UMASetMenuTitle( MAC_WXHMENU(menu
->GetHMenu()) , title
, m_font
.GetEncoding() ) ;
833 if ( pos
== m_menus
.GetCount() - 1)
835 ::InsertMenu( MAC_WXHMENU(menu
->GetHMenu()) , 0 ) ;
839 ::InsertMenu( MAC_WXHMENU(menu
->GetHMenu()) , _wxMenuAt(m_menus
, pos
+1)->MacGetMenuId() ) ;
846 if (m_invokingWindow
)
847 wxMenubarSetInvokingWindow( menu
, m_invokingWindow
);
852 bool wxMenuBar::Insert(size_t pos
, wxMenu
*menu
, const wxString
& title
)
854 if ( !wxMenuBarBase::Insert(pos
, menu
, title
) )
857 m_titles
.Insert(title
, pos
);
859 UMASetMenuTitle( MAC_WXHMENU(menu
->GetHMenu()) , title
, m_font
.GetEncoding() ) ;
861 if ( IsAttached() && s_macInstalledMenuBar
== this )
863 if (s_macInstalledMenuBar
== this)
865 menu
->MacBeforeDisplay( false ) ;
866 if ( pos
== (size_t) -1 || pos
+ 1 == m_menus
.GetCount() )
868 ::InsertMenu( MAC_WXHMENU(menu
->GetHMenu()) , 0 ) ;
872 ::InsertMenu( MAC_WXHMENU(menu
->GetHMenu()) , _wxMenuAt(m_menus
, pos
+1)->MacGetMenuId() ) ;
877 if (m_invokingWindow
)
878 wxMenubarSetInvokingWindow( menu
, m_invokingWindow
);
883 wxMenu
*wxMenuBar::Remove(size_t pos
)
885 wxMenu
*menu
= wxMenuBarBase::Remove(pos
);
891 if (s_macInstalledMenuBar
== this)
893 ::DeleteMenu( menu
->MacGetMenuId() /* m_menus[pos]->MacGetMenuId() */ ) ;
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 UMASetMenuTitle( MAC_WXHMENU(menu
->GetHMenu()) , title
, m_font
.GetEncoding() ) ;
918 if (s_macInstalledMenuBar
== this)
920 ::InsertMenu( MAC_WXHMENU(menu
->GetHMenu()) , 0 ) ;
926 // m_invokingWindow is set after wxFrame::SetMenuBar(). This call enables
927 // adding menu later on.
928 if (m_invokingWindow
)
929 wxMenubarSetInvokingWindow( menu
, m_invokingWindow
);
934 static void wxMenubarUnsetInvokingWindow( wxMenu
*menu
)
936 menu
->SetInvokingWindow( (wxWindow
*) NULL
);
938 wxMenuItemList::compatibility_iterator node
= menu
->GetMenuItems().GetFirst();
941 wxMenuItem
*menuitem
= node
->GetData();
942 if (menuitem
->IsSubMenu())
943 wxMenubarUnsetInvokingWindow( menuitem
->GetSubMenu() );
944 node
= node
->GetNext();
948 static void wxMenubarSetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
950 menu
->SetInvokingWindow( win
);
952 wxMenuItemList::compatibility_iterator node
= menu
->GetMenuItems().GetFirst();
955 wxMenuItem
*menuitem
= node
->GetData();
956 if (menuitem
->IsSubMenu())
957 wxMenubarSetInvokingWindow( menuitem
->GetSubMenu() , win
);
958 node
= node
->GetNext();
962 void wxMenuBar::UnsetInvokingWindow()
964 m_invokingWindow
= (wxWindow
*) NULL
;
965 wxMenuList::compatibility_iterator node
= m_menus
.GetFirst();
968 wxMenu
*menu
= node
->GetData();
969 wxMenubarUnsetInvokingWindow( menu
);
970 node
= node
->GetNext();
974 void wxMenuBar::SetInvokingWindow(wxFrame
*frame
)
976 m_invokingWindow
= frame
;
977 wxMenuList::compatibility_iterator node
= m_menus
.GetFirst();
980 wxMenu
*menu
= node
->GetData();
981 wxMenubarSetInvokingWindow( menu
, frame
);
982 node
= node
->GetNext();
986 void wxMenuBar::Detach()
988 wxMenuBarBase::Detach() ;
991 void wxMenuBar::Attach(wxFrame
*frame
)
993 wxMenuBarBase::Attach( frame
) ;
995 // ---------------------------------------------------------------------------
996 // wxMenuBar searching for menu items
997 // ---------------------------------------------------------------------------
999 // Find the itemString in menuString, and return the item id or wxNOT_FOUND
1000 int wxMenuBar::FindMenuItem(const wxString
& menuString
,
1001 const wxString
& itemString
) const
1003 wxString menuLabel
= wxStripMenuCodes(menuString
);
1004 size_t count
= GetMenuCount();
1005 for ( size_t i
= 0; i
< count
; i
++ )
1007 wxString title
= wxStripMenuCodes(m_titles
[i
]);
1008 if ( menuLabel
== title
)
1009 return _wxMenuAt(m_menus
, i
)->FindItem(itemString
);
1015 wxMenuItem
*wxMenuBar::FindItem(int id
, wxMenu
**itemMenu
) const
1020 wxMenuItem
*item
= NULL
;
1021 size_t count
= GetMenuCount();
1022 for ( size_t i
= 0; !item
&& (i
< count
); i
++ )
1024 item
= _wxMenuAt(m_menus
, i
)->FindItem(id
, itemMenu
);