1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxMenu, wxMenuBar, wxMenuItem
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13 #pragma implementation "menu.h"
14 #pragma implementation "menuitem.h"
17 // ============================================================================
18 // headers & declarations
19 // ============================================================================
24 #include "wx/wxprec.h"
28 #include "wx/menuitem.h"
29 #include "wx/window.h"
34 #include "wx/mac/uma.h"
36 // other standard headers
37 // ----------------------
40 #if !USE_SHARED_LIBRARY
41 IMPLEMENT_DYNAMIC_CLASS(wxMenu
, wxEvtHandler
)
42 IMPLEMENT_DYNAMIC_CLASS(wxMenuBar
, wxEvtHandler
)
45 // the (popup) menu title has this special id
46 static const int idMenuTitle
= -3;
47 static MenuItemIndex firstUserHelpMenuItem
= 0 ;
49 const short kwxMacMenuBarResource
= 1 ;
50 const short kwxMacAppleMenuId
= 1 ;
53 // Find an item given the Macintosh Menu Reference
55 #if KEY_wxList_DEPRECATED
56 wxList
wxWinMacMenuList(wxKEY_INTEGER
);
57 wxMenu
*wxFindMenuFromMacMenu(MenuRef inMenuRef
)
59 wxNode
*node
= wxWinMacMenuList
.Find((long)inMenuRef
);
62 return (wxMenu
*)node
->GetData();
65 void wxAssociateMenuWithMacMenu(MenuRef inMenuRef
, wxMenu
*menu
) ;
66 void wxAssociateMenuWithMacMenu(MenuRef inMenuRef
, wxMenu
*menu
)
68 // adding NULL MenuRef is (first) surely a result of an error and
69 // (secondly) breaks menu command processing
70 wxCHECK_RET( inMenuRef
!= (MenuRef
) NULL
, wxT("attempt to add a NULL MenuRef to menu list") );
72 if ( !wxWinMacMenuList
.Find((long)inMenuRef
) )
73 wxWinMacMenuList
.Append((long)inMenuRef
, menu
);
76 void wxRemoveMacMenuAssociation(wxMenu
*menu
) ;
77 void wxRemoveMacMenuAssociation(wxMenu
*menu
)
79 wxWinMacMenuList
.DeleteObject(menu
);
83 WX_DECLARE_HASH_MAP(MenuRef
, wxMenu
*, wxPointerHash
, wxPointerEqual
, MacMenuMap
);
85 static MacMenuMap wxWinMacMenuList
;
87 wxMenu
*wxFindMenuFromMacMenu(MenuRef inMenuRef
)
89 MacMenuMap::iterator node
= wxWinMacMenuList
.find(inMenuRef
);
91 return (node
== wxWinMacMenuList
.end()) ? NULL
: node
->second
;
94 void wxAssociateMenuWithMacMenu(MenuRef inMenuRef
, wxMenu
*menu
) ;
95 void wxAssociateMenuWithMacMenu(MenuRef inMenuRef
, wxMenu
*menu
)
97 // adding NULL MenuRef is (first) surely a result of an error and
98 // (secondly) breaks menu command processing
99 wxCHECK_RET( inMenuRef
!= (MenuRef
) NULL
, wxT("attempt to add a NULL MenuRef to menu list") );
101 wxWinMacMenuList
[inMenuRef
] = menu
;
104 void wxRemoveMacMenuAssociation(wxMenu
*menu
) ;
105 void wxRemoveMacMenuAssociation(wxMenu
*menu
)
107 // iterate over all the elements in the class
108 MacMenuMap::iterator it
;
109 for ( it
= wxWinMacMenuList
.begin(); it
!= wxWinMacMenuList
.end(); ++it
)
111 if ( it
->second
== menu
)
113 wxWinMacMenuList
.erase(it
);
118 #endif // deprecated wxList
120 // ============================================================================
122 // ============================================================================
123 static void wxMenubarUnsetInvokingWindow( wxMenu
*menu
) ;
124 static void wxMenubarSetInvokingWindow( wxMenu
*menu
, wxWindow
*win
);
128 // Construct a menu with optional title (then use append)
131 short wxMenu::s_macNextMenuId
= 3 ;
133 short wxMenu::s_macNextMenuId
= 2 ;
138 _wxMenuAt(const wxMenuList
&menuList
, size_t pos
)
140 wxMenuList::compatibility_iterator menuIter
= menuList
.GetFirst();
142 while (pos
-- > 0) menuIter
= menuIter
->GetNext();
144 return menuIter
->GetData() ;
150 m_startRadioGroup
= -1;
153 m_macMenuId
= s_macNextMenuId
++;
154 m_hMenu
= UMANewMenu(m_macMenuId
, m_title
, wxFont::GetDefaultEncoding() );
158 wxLogLastError(wxT("UMANewMenu failed"));
161 wxAssociateMenuWithMacMenu( (MenuRef
)m_hMenu
, this ) ;
163 // if we have a title, insert it in the beginning of the menu
166 Append(idMenuTitle
, m_title
) ;
173 wxRemoveMacMenuAssociation( this ) ;
174 if (MAC_WXHMENU(m_hMenu
))
175 ::DisposeMenu(MAC_WXHMENU(m_hMenu
));
180 // not available on the mac platform
183 void wxMenu::Attach(wxMenuBarBase
*menubar
)
185 wxMenuBase::Attach(menubar
);
190 // function appends a new item or submenu to the menu
191 // append a new item or submenu to the menu
192 bool wxMenu::DoInsertOrAppend(wxMenuItem
*pItem
, size_t pos
)
194 wxASSERT_MSG( pItem
!= NULL
, wxT("can't append NULL item to the menu") );
196 if ( pItem
->IsSeparator() )
198 if ( pos
== (size_t)-1 )
199 MacAppendMenu(MAC_WXHMENU(m_hMenu
), "\p-");
201 MacInsertMenuItem(MAC_WXHMENU(m_hMenu
), "\p-" , pos
);
205 wxMenu
*pSubMenu
= pItem
->GetSubMenu() ;
206 if ( pSubMenu
!= NULL
)
208 wxASSERT_MSG( pSubMenu
->m_hMenu
!= NULL
, wxT("invalid submenu added"));
209 pSubMenu
->m_menuParent
= this ;
211 if (wxMenuBar::MacGetInstalledMenuBar() == GetMenuBar())
213 pSubMenu
->MacBeforeDisplay( true ) ;
216 if ( pos
== (size_t)-1 )
217 UMAAppendSubMenuItem(MAC_WXHMENU(m_hMenu
), pItem
->GetText(), wxFont::GetDefaultEncoding() , pSubMenu
->m_macMenuId
);
219 UMAInsertSubMenuItem(MAC_WXHMENU(m_hMenu
), pItem
->GetText(), wxFont::GetDefaultEncoding() , pos
, pSubMenu
->m_macMenuId
);
220 pItem
->UpdateItemBitmap() ;
221 pItem
->UpdateItemStatus() ;
225 if ( pos
== (size_t)-1 )
227 UMAAppendMenuItem(MAC_WXHMENU(m_hMenu
), wxT("a") , wxFont::GetDefaultEncoding() );
228 pos
= CountMenuItems(MAC_WXHMENU(m_hMenu
)) ;
232 // MacOS counts menu items from 1 and inserts after, therefore having the
233 // same effect as wx 0 based and inserting before, we must correct pos
234 // after however for updates to be correct
235 UMAInsertMenuItem(MAC_WXHMENU(m_hMenu
), wxT("a"), wxFont::GetDefaultEncoding(), pos
);
239 SetMenuItemCommandID( MAC_WXHMENU(m_hMenu
) , pos
, pItem
->GetId() ) ;
240 SetMenuItemRefCon( MAC_WXHMENU(m_hMenu
) , pos
, (UInt32
) pItem
) ;
241 pItem
->UpdateItemText() ;
242 pItem
->UpdateItemBitmap() ;
243 pItem
->UpdateItemStatus() ;
245 if ( pItem
->GetId() == idMenuTitle
)
247 UMAEnableMenuItem(MAC_WXHMENU(m_hMenu
) , pos
, false ) ;
251 // if we're already attached to the menubar, we must update it
254 GetMenuBar()->Refresh();
259 void wxMenu::EndRadioGroup()
261 // we're not inside a radio group any longer
262 m_startRadioGroup
= -1;
265 wxMenuItem
* wxMenu::DoAppend(wxMenuItem
*item
)
267 wxCHECK_MSG( item
, NULL
, _T("NULL item in wxMenu::DoAppend") );
271 if ( item
->GetKind() == wxITEM_RADIO
)
273 int count
= GetMenuItemCount();
275 if ( m_startRadioGroup
== -1 )
277 // start a new radio group
278 m_startRadioGroup
= count
;
280 // for now it has just one element
281 item
->SetAsRadioGroupStart();
282 item
->SetRadioGroupEnd(m_startRadioGroup
);
284 // ensure that we have a checked item in the radio group
287 else // extend the current radio group
289 // we need to update its end item
290 item
->SetRadioGroupStart(m_startRadioGroup
);
291 wxMenuItemList::compatibility_iterator node
= GetMenuItems().Item(m_startRadioGroup
);
295 node
->GetData()->SetRadioGroupEnd(count
);
299 wxFAIL_MSG( _T("where is the radio group start item?") );
303 else // not a radio item
308 if ( !wxMenuBase::DoAppend(item
) || !DoInsertOrAppend(item
) )
315 // check the item initially
322 wxMenuItem
* wxMenu::DoInsert(size_t pos
, wxMenuItem
*item
)
324 if (wxMenuBase::DoInsert(pos
, item
) && DoInsertOrAppend(item
, pos
))
330 wxMenuItem
*wxMenu::DoRemove(wxMenuItem
*item
)
332 // we need to find the items position in the child list
334 wxMenuItemList::compatibility_iterator node
= GetMenuItems().GetFirst();
335 for ( pos
= 0; node
; pos
++ )
337 if ( node
->GetData() == item
)
340 node
= node
->GetNext();
343 // DoRemove() (unlike Remove) can only be called for existing item!
344 wxCHECK_MSG( node
, NULL
, wxT("bug in wxMenu::Remove logic") );
346 ::DeleteMenuItem(MAC_WXHMENU(m_hMenu
) , pos
+ 1);
350 // otherwise, the change won't be visible
351 GetMenuBar()->Refresh();
354 // and from internal data structures
355 return wxMenuBase::DoRemove(item
);
358 void wxMenu::SetTitle(const wxString
& label
)
361 UMASetMenuTitle(MAC_WXHMENU(m_hMenu
) , label
, wxFont::GetDefaultEncoding() ) ;
363 bool wxMenu::ProcessCommand(wxCommandEvent
& event
)
365 bool processed
= FALSE
;
367 // Try the menu's event handler
368 if ( !processed
&& GetEventHandler())
370 processed
= GetEventHandler()->ProcessEvent(event
);
373 // Try the window the menu was popped up from (and up through the
375 wxWindow
*win
= GetInvokingWindow();
376 if ( !processed
&& win
)
377 processed
= win
->GetEventHandler()->ProcessEvent(event
);
383 // ---------------------------------------------------------------------------
385 // ---------------------------------------------------------------------------
387 wxWindow
*wxMenu::GetWindow() const
389 if ( m_invokingWindow
!= NULL
)
390 return m_invokingWindow
;
391 else if ( GetMenuBar() != NULL
)
392 return (wxWindow
*) GetMenuBar()->GetFrame();
397 // helper functions returning the mac menu position for a certain item, note that this is
398 // mac-wise 1 - based, i.e. the first item has index 1 whereas on MSWin it has pos 0
400 int wxMenu::MacGetIndexFromId( int id
)
403 wxMenuItemList::compatibility_iterator node
= GetMenuItems().GetFirst();
404 for ( pos
= 0; node
; pos
++ )
406 if ( node
->GetData()->GetId() == id
)
409 node
= node
->GetNext();
418 int wxMenu::MacGetIndexFromItem( wxMenuItem
*pItem
)
421 wxMenuItemList::compatibility_iterator node
= GetMenuItems().GetFirst();
422 for ( pos
= 0; node
; pos
++ )
424 if ( node
->GetData() == pItem
)
427 node
= node
->GetNext();
436 void wxMenu::MacEnableMenu( bool bDoEnable
)
438 UMAEnableMenuItem(MAC_WXHMENU(m_hMenu
) , 0 , bDoEnable
) ;
443 // MacOS needs to know about submenus somewhere within this menu
444 // before it can be displayed , also hide special menu items like preferences
445 // that are handled by the OS
446 void wxMenu::MacBeforeDisplay( bool isSubMenu
)
448 wxMenuItem
* previousItem
= NULL
;
450 wxMenuItemList::compatibility_iterator node
;
452 for (pos
= 0, node
= GetMenuItems().GetFirst(); node
; node
= node
->GetNext(), pos
++)
454 item
= (wxMenuItem
*)node
->GetData();
455 wxMenu
* subMenu
= item
->GetSubMenu() ;
458 subMenu
->MacBeforeDisplay( true ) ;
463 if ( UMAGetSystemVersion() >= 0x1000 )
465 // what we do here is to hide the special items which are
466 // shown in the application menu anyhow -- it doesn't make
467 // sense to show them in their normal place as well
468 if ( item
->GetId() == wxApp::s_macPreferencesMenuItemId
||
469 item
->GetId() == wxApp::s_macExitMenuItemId
)
471 ChangeMenuItemAttributes( MAC_WXHMENU( GetHMenu() ),
472 pos
+ 1, kMenuItemAttrHidden
, 0 );
474 // also check for a separator which was used just to
475 // separate this item from the others, so don't leave
476 // separator at the menu start or end nor 2 consecutive
478 wxMenuItemList::compatibility_iterator nextNode
= node
->GetNext();
479 wxMenuItem
*next
= nextNode
? nextNode
->GetData() : NULL
;
482 if ( !previousItem
&& next
&& next
->IsSeparator() )
484 // next (i.e. second as we must be first) item is
485 // the separator to hide
486 wxASSERT_MSG( pos
== 0, _T("should be the menu start") );
489 else if ( GetMenuItems().GetCount() == pos
+ 1 &&
490 previousItem
!= NULL
&&
491 previousItem
->IsSeparator() )
493 // prev item is a trailing separator we want to hide
496 else if ( previousItem
&& previousItem
->IsSeparator() &&
497 next
&& next
->IsSeparator() )
499 // two consecutive separators, this is one too many
502 else // no separators to hide
509 // hide the separator as well
510 ChangeMenuItemAttributes( MAC_WXHMENU( GetHMenu() ),
517 #endif // TARGET_CARBON
519 previousItem
= item
;
523 ::InsertMenu(MAC_WXHMENU( GetHMenu()), -1);
526 // undo all changes from the MacBeforeDisplay call
527 void wxMenu::MacAfterDisplay( bool isSubMenu
)
530 ::DeleteMenu(MacGetMenuId());
532 wxMenuItem
* previousItem
= NULL
;
534 wxMenuItemList::compatibility_iterator node
;
536 for (pos
= 0, node
= GetMenuItems().GetFirst(); node
; node
= node
->GetNext(), pos
++)
538 item
= (wxMenuItem
*)node
->GetData();
539 wxMenu
* subMenu
= item
->GetSubMenu() ;
542 subMenu
->MacAfterDisplay( true ) ;
546 // no need to undo hidings
548 previousItem
= item
;
556 Mac Implementation note :
558 The Mac has only one global menubar, so we attempt to install the currently
559 active menubar from a frame, we currently don't take into account mdi-frames
560 which would ask for menu-merging
562 Secondly there is no mac api for changing a menubar that is not the current
563 menubar, so we have to wait for preparing the actual menubar until the
564 wxMenubar is to be used
566 We can in subsequent versions use MacInstallMenuBar to provide some sort of
567 auto-merge for MDI in case this will be necessary
571 wxMenuBar
* wxMenuBar::s_macInstalledMenuBar
= NULL
;
572 wxMenuBar
* wxMenuBar::s_macCommonMenuBar
= NULL
;
574 void wxMenuBar::Init()
576 m_eventHandler
= this;
577 m_menuBarFrame
= NULL
;
578 m_invokingWindow
= (wxWindow
*) NULL
;
581 wxMenuBar::wxMenuBar()
586 wxMenuBar::wxMenuBar( long WXUNUSED(style
) )
592 wxMenuBar::wxMenuBar(int count
, wxMenu
*menus
[], const wxString titles
[])
596 m_titles
.Alloc(count
);
598 for ( int i
= 0; i
< count
; i
++ )
600 m_menus
.Append(menus
[i
]);
601 m_titles
.Add(titles
[i
]);
603 menus
[i
]->Attach(this);
607 wxMenuBar::~wxMenuBar()
609 if (s_macCommonMenuBar
== this)
610 s_macCommonMenuBar
= NULL
;
611 if (s_macInstalledMenuBar
== this)
614 s_macInstalledMenuBar
= NULL
;
619 void wxMenuBar::Refresh(bool WXUNUSED(eraseBackground
), const wxRect
*WXUNUSED(rect
))
621 wxCHECK_RET( IsAttached(), wxT("can't refresh unatteched menubar") );
626 void wxMenuBar::MacInstallMenuBar()
628 if ( s_macInstalledMenuBar
== this )
631 MenuBarHandle menubar
= NULL
;
632 #if TARGET_API_MAC_OSX
633 menubar
= NewHandleClear( 6 /* sizeof( MenuBarHeader ) */ ) ;
635 menubar
= NewHandleClear( 12 ) ;
636 (*menubar
)[3] = 0x0a ;
638 ::SetMenuBar( menubar
) ;
639 DisposeMenuBar( menubar
) ;
640 MenuHandle appleMenu
= NULL
;
641 char appleMenuTitle
[3] = { 01 , kMenuAppleLogoFilledGlyph
, 0 } ;
643 verify_noerr( CreateNewMenu( kwxMacAppleMenuId
, 0 , &appleMenu
) ) ;
644 verify_noerr( SetMenuTitle( appleMenu
, (ConstStr255Param
) appleMenuTitle
) );
646 // Add About/Preferences separator only on OS X
647 // KH/RN: Separator is always present on 10.3 but not on 10.2
648 // However, the change from 10.2 to 10.3 suggests it is preferred
649 #if TARGET_API_MAC_OSX
650 MacInsertMenuItem( appleMenu
, "\p-" , 0 ) ;
653 MacInsertMenuItem( appleMenu
, "\pAbout..." , 0 ) ;
654 MacInsertMenu( appleMenu
, 0 ) ;
656 // clean-up the help menu before adding new items
657 MenuHandle mh
= NULL
;
658 if ( UMAGetHelpMenu( &mh
, &firstUserHelpMenuItem
) == noErr
)
660 for ( int i
= CountMenuItems( mh
) ; i
>= firstUserHelpMenuItem
; --i
)
662 DeleteMenuItem( mh
, i
) ;
670 if ( UMAGetSystemVersion() >= 0x1000 && wxApp::s_macPreferencesMenuItemId
)
672 wxMenuItem
*item
= FindItem( wxApp::s_macPreferencesMenuItemId
, NULL
) ;
673 if ( item
== NULL
|| !(item
->IsEnabled()) )
674 DisableMenuCommand( NULL
, kHICommandPreferences
) ;
676 EnableMenuCommand( NULL
, kHICommandPreferences
) ;
679 wxMenuList::compatibility_iterator menuIter
= m_menus
.GetFirst();
681 for (size_t i
= 0; i
< m_menus
.GetCount(); i
++, menuIter
= menuIter
->GetNext())
683 wxMenuItemList::compatibility_iterator node
;
686 wxMenu
* menu
= menuIter
->GetData() , *subMenu
= NULL
;
688 if( m_titles
[i
] == wxT("?") || m_titles
[i
] == wxT("&?") || m_titles
[i
] == wxApp::s_macHelpMenuTitleName
)
695 for (pos
= 0 , node
= menu
->GetMenuItems().GetFirst(); node
; node
= node
->GetNext(), pos
++)
697 item
= (wxMenuItem
*)node
->GetData();
698 subMenu
= item
->GetSubMenu() ;
701 // we don't support hierarchical menus in the help menu yet
705 if ( item
->IsSeparator() )
708 MacAppendMenu(mh
, "\p-" );
712 wxAcceleratorEntry
* entry
= wxGetAccelFromString( item
->GetText() ) ;
714 if ( item
->GetId() == wxApp::s_macAboutMenuItemId
)
716 UMASetMenuItemText( GetMenuHandle( kwxMacAppleMenuId
) , 1 , item
->GetText() , wxFont::GetDefaultEncoding() );
717 UMAEnableMenuItem( GetMenuHandle( kwxMacAppleMenuId
) , 1 , true );
718 SetMenuItemCommandID( GetMenuHandle( kwxMacAppleMenuId
) , 1 , item
->GetId() ) ;
719 SetMenuItemRefCon(GetMenuHandle( kwxMacAppleMenuId
) , 1 , (UInt32
)item
) ;
720 UMASetMenuItemShortcut( GetMenuHandle( kwxMacAppleMenuId
) , 1 , entry
) ;
726 UMAAppendMenuItem(mh
, item
->GetText() , wxFont::GetDefaultEncoding(), entry
);
727 SetMenuItemCommandID( mh
, CountMenuItems(mh
) , item
->GetId() ) ;
728 SetMenuItemRefCon( mh
, CountMenuItems(mh
) , (UInt32
)item
) ;
739 UMASetMenuTitle( MAC_WXHMENU(menu
->GetHMenu()) , m_titles
[i
], m_font
.GetEncoding() ) ;
740 menu
->MacBeforeDisplay(false) ;
741 ::InsertMenu(MAC_WXHMENU(_wxMenuAt(m_menus
, i
)->GetHMenu()), 0);
745 s_macInstalledMenuBar
= this;
748 void wxMenuBar::EnableTop(size_t pos
, bool enable
)
750 wxCHECK_RET( IsAttached(), wxT("doesn't work with unattached menubars") );
751 _wxMenuAt(m_menus
, pos
)->MacEnableMenu( enable
) ;
755 bool wxMenuBar::Enable( bool enable
)
757 wxCHECK_MSG( IsAttached(), false, wxT("doesn't work with unattached menubars") );
759 for (i
= 0; i
< GetMenuCount(); i
++)
761 EnableTop(i
, enable
);
766 void wxMenuBar::SetLabelTop(size_t pos
, const wxString
& label
)
768 wxCHECK_RET( pos
< GetMenuCount(), wxT("invalid menu index") );
770 m_titles
[pos
] = label
;
777 _wxMenuAt(m_menus
, pos
)->SetTitle( label
) ;
779 if (wxMenuBar::s_macInstalledMenuBar
== this) // are we currently installed ?
781 ::SetMenuBar( GetMenuBar() ) ;
786 wxString
wxMenuBar::GetLabelTop(size_t pos
) const
788 wxCHECK_MSG( pos
< GetMenuCount(), wxEmptyString
,
789 wxT("invalid menu index in wxMenuBar::GetLabelTop") );
791 return m_titles
[pos
];
794 int wxMenuBar::FindMenu(const wxString
& title
)
796 wxString menuTitle
= wxStripMenuCodes(title
);
798 size_t count
= GetMenuCount();
799 for ( size_t i
= 0; i
< count
; i
++ )
801 wxString title
= wxStripMenuCodes(m_titles
[i
]);
802 if ( menuTitle
== title
)
811 // ---------------------------------------------------------------------------
812 // wxMenuBar construction
813 // ---------------------------------------------------------------------------
815 // ---------------------------------------------------------------------------
816 // wxMenuBar construction
817 // ---------------------------------------------------------------------------
819 wxMenu
*wxMenuBar::Replace(size_t pos
, wxMenu
*menu
, const wxString
& title
)
821 wxMenu
*menuOld
= wxMenuBarBase::Replace(pos
, menu
, title
);
824 m_titles
[pos
] = title
;
828 if (s_macInstalledMenuBar
== this)
830 menuOld
->MacAfterDisplay( false ) ;
831 ::DeleteMenu( menuOld
->MacGetMenuId() /* m_menus[pos]->MacGetMenuId() */ ) ;
833 menu
->MacBeforeDisplay( false ) ;
834 UMASetMenuTitle( MAC_WXHMENU(menu
->GetHMenu()) , title
, m_font
.GetEncoding() ) ;
835 if ( pos
== m_menus
.GetCount() - 1)
837 ::InsertMenu( MAC_WXHMENU(menu
->GetHMenu()) , 0 ) ;
841 ::InsertMenu( MAC_WXHMENU(menu
->GetHMenu()) , _wxMenuAt(m_menus
, pos
+1)->MacGetMenuId() ) ;
848 if (m_invokingWindow
)
849 wxMenubarSetInvokingWindow( menu
, m_invokingWindow
);
854 bool wxMenuBar::Insert(size_t pos
, wxMenu
*menu
, const wxString
& title
)
856 if ( !wxMenuBarBase::Insert(pos
, menu
, title
) )
859 m_titles
.Insert(title
, pos
);
861 UMASetMenuTitle( MAC_WXHMENU(menu
->GetHMenu()) , title
, m_font
.GetEncoding() ) ;
863 if ( IsAttached() && s_macInstalledMenuBar
== this )
865 if (s_macInstalledMenuBar
== this)
867 menu
->MacBeforeDisplay( false ) ;
868 if ( pos
== (size_t) -1 || pos
+ 1 == m_menus
.GetCount() )
870 ::InsertMenu( MAC_WXHMENU(menu
->GetHMenu()) , 0 ) ;
874 ::InsertMenu( MAC_WXHMENU(menu
->GetHMenu()) , _wxMenuAt(m_menus
, pos
+1)->MacGetMenuId() ) ;
879 if (m_invokingWindow
)
880 wxMenubarSetInvokingWindow( menu
, m_invokingWindow
);
885 wxMenu
*wxMenuBar::Remove(size_t pos
)
887 wxMenu
*menu
= wxMenuBarBase::Remove(pos
);
893 if (s_macInstalledMenuBar
== this)
895 ::DeleteMenu( menu
->MacGetMenuId() /* m_menus[pos]->MacGetMenuId() */ ) ;
901 m_titles
.RemoveAt(pos
);
906 bool wxMenuBar::Append(wxMenu
*menu
, const wxString
& title
)
908 WXHMENU submenu
= menu
? menu
->GetHMenu() : 0;
909 wxCHECK_MSG( submenu
, FALSE
, wxT("can't append invalid menu to menubar") );
911 if ( !wxMenuBarBase::Append(menu
, title
) )
916 UMASetMenuTitle( MAC_WXHMENU(menu
->GetHMenu()) , title
, m_font
.GetEncoding() ) ;
920 if (s_macInstalledMenuBar
== this)
922 ::InsertMenu( MAC_WXHMENU(menu
->GetHMenu()) , 0 ) ;
928 // m_invokingWindow is set after wxFrame::SetMenuBar(). This call enables
929 // adding menu later on.
930 if (m_invokingWindow
)
931 wxMenubarSetInvokingWindow( menu
, m_invokingWindow
);
936 static void wxMenubarUnsetInvokingWindow( wxMenu
*menu
)
938 menu
->SetInvokingWindow( (wxWindow
*) NULL
);
940 wxMenuItemList::compatibility_iterator node
= menu
->GetMenuItems().GetFirst();
943 wxMenuItem
*menuitem
= node
->GetData();
944 if (menuitem
->IsSubMenu())
945 wxMenubarUnsetInvokingWindow( menuitem
->GetSubMenu() );
946 node
= node
->GetNext();
950 static void wxMenubarSetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
952 menu
->SetInvokingWindow( win
);
954 wxMenuItemList::compatibility_iterator node
= menu
->GetMenuItems().GetFirst();
957 wxMenuItem
*menuitem
= node
->GetData();
958 if (menuitem
->IsSubMenu())
959 wxMenubarSetInvokingWindow( menuitem
->GetSubMenu() , win
);
960 node
= node
->GetNext();
964 void wxMenuBar::UnsetInvokingWindow()
966 m_invokingWindow
= (wxWindow
*) NULL
;
967 wxMenuList::compatibility_iterator node
= m_menus
.GetFirst();
970 wxMenu
*menu
= node
->GetData();
971 wxMenubarUnsetInvokingWindow( menu
);
972 node
= node
->GetNext();
976 void wxMenuBar::SetInvokingWindow(wxFrame
*frame
)
978 m_invokingWindow
= frame
;
979 wxMenuList::compatibility_iterator node
= m_menus
.GetFirst();
982 wxMenu
*menu
= node
->GetData();
983 wxMenubarSetInvokingWindow( menu
, frame
);
984 node
= node
->GetNext();
988 void wxMenuBar::Detach()
990 wxMenuBarBase::Detach() ;
993 void wxMenuBar::Attach(wxFrame
*frame
)
995 wxMenuBarBase::Attach( frame
) ;
997 // ---------------------------------------------------------------------------
998 // wxMenuBar searching for menu items
999 // ---------------------------------------------------------------------------
1001 // Find the itemString in menuString, and return the item id or wxNOT_FOUND
1002 int wxMenuBar::FindMenuItem(const wxString
& menuString
,
1003 const wxString
& itemString
) const
1005 wxString menuLabel
= wxStripMenuCodes(menuString
);
1006 size_t count
= GetMenuCount();
1007 for ( size_t i
= 0; i
< count
; i
++ )
1009 wxString title
= wxStripMenuCodes(m_titles
[i
]);
1010 if ( menuLabel
== title
)
1011 return _wxMenuAt(m_menus
, i
)->FindItem(itemString
);
1017 wxMenuItem
*wxMenuBar::FindItem(int id
, wxMenu
**itemMenu
) const
1022 wxMenuItem
*item
= NULL
;
1023 size_t count
= GetMenuCount();
1024 for ( size_t i
= 0; !item
&& (i
< count
); i
++ )
1026 item
= _wxMenuAt(m_menus
, i
)->FindItem(id
, itemMenu
);