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 IMPLEMENT_DYNAMIC_CLASS(wxMenu
, wxEvtHandler
)
41 IMPLEMENT_DYNAMIC_CLASS(wxMenuBar
, wxEvtHandler
)
43 // the (popup) menu title has this special id
44 static const int idMenuTitle
= -3;
46 const short kwxMacMenuBarResource
= 1 ;
47 const short kwxMacAppleMenuId
= 1 ;
50 // Find an item given the Macintosh Menu Reference
52 WX_DECLARE_HASH_MAP(MenuRef
, wxMenu
*, wxPointerHash
, wxPointerEqual
, MacMenuMap
);
54 static MacMenuMap wxWinMacMenuList
;
56 wxMenu
*wxFindMenuFromMacMenu(MenuRef inMenuRef
)
58 MacMenuMap::iterator node
= wxWinMacMenuList
.find(inMenuRef
);
60 return (node
== wxWinMacMenuList
.end()) ? NULL
: node
->second
;
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 wxWinMacMenuList
[inMenuRef
] = menu
;
73 void wxRemoveMacMenuAssociation(wxMenu
*menu
) ;
74 void wxRemoveMacMenuAssociation(wxMenu
*menu
)
76 // iterate over all the elements in the class
77 MacMenuMap::iterator it
;
78 for ( it
= wxWinMacMenuList
.begin(); it
!= wxWinMacMenuList
.end(); ++it
)
80 if ( it
->second
== menu
)
82 wxWinMacMenuList
.erase(it
);
88 // ============================================================================
90 // ============================================================================
91 static void wxMenubarUnsetInvokingWindow( wxMenu
*menu
) ;
92 static void wxMenubarSetInvokingWindow( wxMenu
*menu
, wxWindow
*win
);
96 // Construct a menu with optional title (then use append)
99 short wxMenu::s_macNextMenuId
= 3 ;
101 short wxMenu::s_macNextMenuId
= 2 ;
106 _wxMenuAt(const wxMenuList
&menuList
, size_t pos
)
108 wxMenuList::compatibility_iterator menuIter
= menuList
.GetFirst();
110 while (pos
-- > 0) menuIter
= menuIter
->GetNext();
112 return menuIter
->GetData() ;
118 m_startRadioGroup
= -1;
121 m_macMenuId
= s_macNextMenuId
++;
122 m_hMenu
= UMANewMenu(m_macMenuId
, m_title
, wxFont::GetDefaultEncoding() );
126 wxLogLastError(wxT("UMANewMenu failed"));
129 wxAssociateMenuWithMacMenu( (MenuRef
)m_hMenu
, this ) ;
131 // if we have a title, insert it in the beginning of the menu
132 if ( !m_title
.empty() )
134 Append(idMenuTitle
, m_title
) ;
141 wxRemoveMacMenuAssociation( this ) ;
142 if (MAC_WXHMENU(m_hMenu
))
143 ::DisposeMenu(MAC_WXHMENU(m_hMenu
));
148 // not available on the mac platform
151 void wxMenu::Attach(wxMenuBarBase
*menubar
)
153 wxMenuBase::Attach(menubar
);
158 // function appends a new item or submenu to the menu
159 // append a new item or submenu to the menu
160 bool wxMenu::DoInsertOrAppend(wxMenuItem
*pItem
, size_t pos
)
162 wxASSERT_MSG( pItem
!= NULL
, wxT("can't append NULL item to the menu") );
164 if ( pItem
->IsSeparator() )
166 if ( pos
== (size_t)-1 )
167 MacAppendMenu(MAC_WXHMENU(m_hMenu
), "\p-");
169 MacInsertMenuItem(MAC_WXHMENU(m_hMenu
), "\p-" , pos
);
173 wxMenu
*pSubMenu
= pItem
->GetSubMenu() ;
174 if ( pSubMenu
!= NULL
)
176 wxASSERT_MSG( pSubMenu
->m_hMenu
!= NULL
, wxT("invalid submenu added"));
177 pSubMenu
->m_menuParent
= this ;
179 if (wxMenuBar::MacGetInstalledMenuBar() == GetMenuBar())
181 pSubMenu
->MacBeforeDisplay( true ) ;
184 if ( pos
== (size_t)-1 )
185 UMAAppendSubMenuItem(MAC_WXHMENU(m_hMenu
), pItem
->GetText(), wxFont::GetDefaultEncoding() , pSubMenu
->m_macMenuId
);
187 UMAInsertSubMenuItem(MAC_WXHMENU(m_hMenu
), pItem
->GetText(), wxFont::GetDefaultEncoding() , pos
, pSubMenu
->m_macMenuId
);
188 pItem
->UpdateItemBitmap() ;
189 pItem
->UpdateItemStatus() ;
193 if ( pos
== (size_t)-1 )
195 UMAAppendMenuItem(MAC_WXHMENU(m_hMenu
), wxT("a") , wxFont::GetDefaultEncoding() );
196 pos
= CountMenuItems(MAC_WXHMENU(m_hMenu
)) ;
200 // MacOS counts menu items from 1 and inserts after, therefore having the
201 // same effect as wx 0 based and inserting before, we must correct pos
202 // after however for updates to be correct
203 UMAInsertMenuItem(MAC_WXHMENU(m_hMenu
), wxT("a"), wxFont::GetDefaultEncoding(), pos
);
207 SetMenuItemCommandID( MAC_WXHMENU(m_hMenu
) , pos
, pItem
->GetId() ) ;
208 SetMenuItemRefCon( MAC_WXHMENU(m_hMenu
) , pos
, (UInt32
) pItem
) ;
209 pItem
->UpdateItemText() ;
210 pItem
->UpdateItemBitmap() ;
211 pItem
->UpdateItemStatus() ;
213 if ( pItem
->GetId() == idMenuTitle
)
215 UMAEnableMenuItem(MAC_WXHMENU(m_hMenu
) , pos
, false ) ;
219 // if we're already attached to the menubar, we must update it
220 if ( IsAttached() && GetMenuBar()->IsAttached() )
222 GetMenuBar()->Refresh();
227 void wxMenu::EndRadioGroup()
229 // we're not inside a radio group any longer
230 m_startRadioGroup
= -1;
233 wxMenuItem
* wxMenu::DoAppend(wxMenuItem
*item
)
235 wxCHECK_MSG( item
, NULL
, _T("NULL item in wxMenu::DoAppend") );
239 if ( item
->GetKind() == wxITEM_RADIO
)
241 int count
= GetMenuItemCount();
243 if ( m_startRadioGroup
== -1 )
245 // start a new radio group
246 m_startRadioGroup
= count
;
248 // for now it has just one element
249 item
->SetAsRadioGroupStart();
250 item
->SetRadioGroupEnd(m_startRadioGroup
);
252 // ensure that we have a checked item in the radio group
255 else // extend the current radio group
257 // we need to update its end item
258 item
->SetRadioGroupStart(m_startRadioGroup
);
259 wxMenuItemList::compatibility_iterator node
= GetMenuItems().Item(m_startRadioGroup
);
263 node
->GetData()->SetRadioGroupEnd(count
);
267 wxFAIL_MSG( _T("where is the radio group start item?") );
271 else // not a radio item
276 if ( !wxMenuBase::DoAppend(item
) || !DoInsertOrAppend(item
) )
283 // check the item initially
290 wxMenuItem
* wxMenu::DoInsert(size_t pos
, wxMenuItem
*item
)
292 if (wxMenuBase::DoInsert(pos
, item
) && DoInsertOrAppend(item
, pos
))
298 wxMenuItem
*wxMenu::DoRemove(wxMenuItem
*item
)
300 // we need to find the items position in the child list
302 wxMenuItemList::compatibility_iterator node
= GetMenuItems().GetFirst();
303 for ( pos
= 0; node
; pos
++ )
305 if ( node
->GetData() == item
)
308 node
= node
->GetNext();
311 // DoRemove() (unlike Remove) can only be called for existing item!
312 wxCHECK_MSG( node
, NULL
, wxT("bug in wxMenu::Remove logic") );
314 ::DeleteMenuItem(MAC_WXHMENU(m_hMenu
) , pos
+ 1);
316 if ( IsAttached() && GetMenuBar()->IsAttached() )
318 // otherwise, the change won't be visible
319 GetMenuBar()->Refresh();
322 // and from internal data structures
323 return wxMenuBase::DoRemove(item
);
326 void wxMenu::SetTitle(const wxString
& label
)
329 UMASetMenuTitle(MAC_WXHMENU(m_hMenu
) , label
, wxFont::GetDefaultEncoding() ) ;
332 bool wxMenu::ProcessCommand(wxCommandEvent
& event
)
334 bool processed
= false;
336 // Try the menu's event handler
337 if ( /* !processed && */ GetEventHandler())
339 processed
= GetEventHandler()->ProcessEvent(event
);
342 // Try the window the menu was popped up from (and up through the
344 wxWindow
*win
= GetInvokingWindow();
345 if ( !processed
&& win
)
346 processed
= win
->GetEventHandler()->ProcessEvent(event
);
352 // ---------------------------------------------------------------------------
354 // ---------------------------------------------------------------------------
356 wxWindow
*wxMenu::GetWindow() const
358 if ( m_invokingWindow
!= NULL
)
359 return m_invokingWindow
;
360 else if ( GetMenuBar() != NULL
)
361 return (wxWindow
*) GetMenuBar()->GetFrame();
366 // helper functions returning the mac menu position for a certain item, note that this is
367 // mac-wise 1 - based, i.e. the first item has index 1 whereas on MSWin it has pos 0
369 int wxMenu::MacGetIndexFromId( int id
)
372 wxMenuItemList::compatibility_iterator node
= GetMenuItems().GetFirst();
373 for ( pos
= 0; node
; pos
++ )
375 if ( node
->GetData()->GetId() == id
)
378 node
= node
->GetNext();
387 int wxMenu::MacGetIndexFromItem( wxMenuItem
*pItem
)
390 wxMenuItemList::compatibility_iterator node
= GetMenuItems().GetFirst();
391 for ( pos
= 0; node
; pos
++ )
393 if ( node
->GetData() == pItem
)
396 node
= node
->GetNext();
405 void wxMenu::MacEnableMenu( bool bDoEnable
)
407 UMAEnableMenuItem(MAC_WXHMENU(m_hMenu
) , 0 , bDoEnable
) ;
412 // MacOS needs to know about submenus somewhere within this menu
413 // before it can be displayed , also hide special menu items like preferences
414 // that are handled by the OS
415 void wxMenu::MacBeforeDisplay( bool isSubMenu
)
417 wxMenuItem
* previousItem
= NULL
;
419 wxMenuItemList::compatibility_iterator node
;
421 for (pos
= 0, node
= GetMenuItems().GetFirst(); node
; node
= node
->GetNext(), pos
++)
423 item
= (wxMenuItem
*)node
->GetData();
424 wxMenu
* subMenu
= item
->GetSubMenu() ;
427 subMenu
->MacBeforeDisplay( true ) ;
432 // what we do here is to hide the special items which are
433 // shown in the application menu anyhow -- it doesn't make
434 // sense to show them in their normal place as well
435 if ( item
->GetId() == wxApp::s_macAboutMenuItemId
||
436 ( UMAGetSystemVersion() >= 0x1000 && (
437 item
->GetId() == wxApp::s_macPreferencesMenuItemId
||
438 item
->GetId() == wxApp::s_macExitMenuItemId
) ) )
441 ChangeMenuItemAttributes( MAC_WXHMENU( GetHMenu() ),
442 pos
+ 1, kMenuItemAttrHidden
, 0 );
444 // also check for a separator which was used just to
445 // separate this item from the others, so don't leave
446 // separator at the menu start or end nor 2 consecutive
448 wxMenuItemList::compatibility_iterator nextNode
= node
->GetNext();
449 wxMenuItem
*next
= nextNode
? nextNode
->GetData() : NULL
;
452 if ( !previousItem
&& next
&& next
->IsSeparator() )
454 // next (i.e. second as we must be first) item is
455 // the separator to hide
456 wxASSERT_MSG( pos
== 0, _T("should be the menu start") );
459 else if ( GetMenuItems().GetCount() == pos
+ 1 &&
460 previousItem
!= NULL
&&
461 previousItem
->IsSeparator() )
463 // prev item is a trailing separator we want to hide
466 else if ( previousItem
&& previousItem
->IsSeparator() &&
467 next
&& next
->IsSeparator() )
469 // two consecutive separators, this is one too many
472 else // no separators to hide
479 // hide the separator as well
480 ChangeMenuItemAttributes( MAC_WXHMENU( GetHMenu() ),
486 #endif // TARGET_CARBON
488 previousItem
= item
;
492 ::InsertMenu(MAC_WXHMENU( GetHMenu()), -1);
495 // undo all changes from the MacBeforeDisplay call
496 void wxMenu::MacAfterDisplay( bool isSubMenu
)
499 ::DeleteMenu(MacGetMenuId());
501 wxMenuItem
* previousItem
= NULL
;
503 wxMenuItemList::compatibility_iterator node
;
505 for (pos
= 0, node
= GetMenuItems().GetFirst(); node
; node
= node
->GetNext(), pos
++)
507 item
= (wxMenuItem
*)node
->GetData();
508 wxMenu
* subMenu
= item
->GetSubMenu() ;
511 subMenu
->MacAfterDisplay( true ) ;
515 // no need to undo hidings
517 previousItem
= item
;
525 Mac Implementation note :
527 The Mac has only one global menubar, so we attempt to install the currently
528 active menubar from a frame, we currently don't take into account mdi-frames
529 which would ask for menu-merging
531 Secondly there is no mac api for changing a menubar that is not the current
532 menubar, so we have to wait for preparing the actual menubar until the
533 wxMenubar is to be used
535 We can in subsequent versions use MacInstallMenuBar to provide some sort of
536 auto-merge for MDI in case this will be necessary
540 wxMenuBar
* wxMenuBar::s_macInstalledMenuBar
= NULL
;
541 wxMenuBar
* wxMenuBar::s_macCommonMenuBar
= NULL
;
542 bool wxMenuBar::s_macAutoWindowMenu
= true ;
543 WXHMENU
wxMenuBar::s_macWindowMenuHandle
= NULL
;
545 void wxMenuBar::Init()
547 m_eventHandler
= this;
548 m_menuBarFrame
= NULL
;
549 m_invokingWindow
= (wxWindow
*) NULL
;
552 wxMenuBar::wxMenuBar()
557 wxMenuBar::wxMenuBar( long WXUNUSED(style
) )
563 wxMenuBar::wxMenuBar(size_t count
, wxMenu
*menus
[], const wxString titles
[], long WXUNUSED(style
))
567 m_titles
.Alloc(count
);
569 for ( size_t i
= 0; i
< count
; i
++ )
571 m_menus
.Append(menus
[i
]);
572 m_titles
.Add(titles
[i
]);
574 menus
[i
]->Attach(this);
578 wxMenuBar::~wxMenuBar()
580 if (s_macCommonMenuBar
== this)
581 s_macCommonMenuBar
= NULL
;
582 if (s_macInstalledMenuBar
== this)
585 s_macInstalledMenuBar
= NULL
;
590 void wxMenuBar::Refresh(bool WXUNUSED(eraseBackground
), const wxRect
*WXUNUSED(rect
))
592 wxCHECK_RET( IsAttached(), wxT("can't refresh unatteched menubar") );
597 void wxMenuBar::MacInstallMenuBar()
599 if ( s_macInstalledMenuBar
== this )
602 MenuBarHandle menubar
= NULL
;
603 #if TARGET_API_MAC_OSX
604 menubar
= NewHandleClear( 6 /* sizeof( MenuBarHeader ) */ ) ;
606 menubar
= NewHandleClear( 12 ) ;
607 (*menubar
)[3] = 0x0a ;
609 ::SetMenuBar( menubar
) ;
610 DisposeMenuBar( menubar
) ;
611 MenuHandle appleMenu
= NULL
;
612 char appleMenuTitle
[3] = { 01 , kMenuAppleLogoFilledGlyph
, 0 } ;
614 verify_noerr( CreateNewMenu( kwxMacAppleMenuId
, 0 , &appleMenu
) ) ;
615 verify_noerr( SetMenuTitle( appleMenu
, (ConstStr255Param
) appleMenuTitle
) );
617 // Add About/Preferences separator only on OS X
618 // KH/RN: Separator is always present on 10.3 but not on 10.2
619 // However, the change from 10.2 to 10.3 suggests it is preferred
620 #if TARGET_API_MAC_OSX
621 MacInsertMenuItem( appleMenu
, "\p-" , 0 ) ;
624 MacInsertMenuItem( appleMenu
, "\pAbout..." , 0 ) ;
625 MacInsertMenu( appleMenu
, 0 ) ;
627 // clean-up the help menu before adding new items
628 static MenuHandle mh
= NULL
;
632 MenuItemIndex firstUserHelpMenuItem
;
633 if ( UMAGetHelpMenu( &mh
, &firstUserHelpMenuItem
) == noErr
)
635 for ( int i
= CountMenuItems( mh
) ; i
>= firstUserHelpMenuItem
; --i
)
637 DeleteMenuItem( mh
, i
) ;
646 if ( UMAGetSystemVersion() >= 0x1000 && wxApp::s_macPreferencesMenuItemId
)
648 wxMenuItem
*item
= FindItem( wxApp::s_macPreferencesMenuItemId
, NULL
) ;
649 if ( item
== NULL
|| !(item
->IsEnabled()) )
650 DisableMenuCommand( NULL
, kHICommandPreferences
) ;
652 EnableMenuCommand( NULL
, kHICommandPreferences
) ;
654 // Unlike preferences which may or may not exist, the Quit item should be always
655 // enabled unless it is added by the application and then disabled, otherwise
656 // a program would be required to add an item with wxID_EXIT in order to get the
657 // Quit menu item to be enabled, which seems a bit burdensome.
658 if ( UMAGetSystemVersion() >= 0x1000 && wxApp::s_macExitMenuItemId
)
660 wxMenuItem
*item
= FindItem( wxApp::s_macExitMenuItemId
, NULL
) ;
661 if ( item
!= NULL
&& !(item
->IsEnabled()) )
662 DisableMenuCommand( NULL
, kHICommandQuit
) ;
664 EnableMenuCommand( NULL
, kHICommandQuit
) ;
667 wxMenuList::compatibility_iterator menuIter
= m_menus
.GetFirst();
669 for (size_t i
= 0; i
< m_menus
.GetCount(); i
++, menuIter
= menuIter
->GetNext())
671 wxMenuItemList::compatibility_iterator node
;
674 wxMenu
* menu
= menuIter
->GetData() , *subMenu
= NULL
;
676 if( m_titles
[i
] == wxT("?") || m_titles
[i
] == wxT("&?") || m_titles
[i
] == wxApp::s_macHelpMenuTitleName
)
678 for (pos
= 0 , node
= menu
->GetMenuItems().GetFirst(); node
; node
= node
->GetNext(), pos
++)
680 item
= (wxMenuItem
*)node
->GetData();
681 subMenu
= item
->GetSubMenu() ;
684 // we don't support hierarchical menus in the help menu yet
688 if ( item
->GetId() != wxApp::s_macAboutMenuItemId
)
692 MenuItemIndex firstUserHelpMenuItem
;
693 if ( UMAGetHelpMenu( &mh
, &firstUserHelpMenuItem
) == noErr
)
703 if ( item
->IsSeparator() )
706 MacAppendMenu(mh
, "\p-" );
710 wxAcceleratorEntry
* entry
= wxGetAccelFromString( item
->GetText() ) ;
712 if ( item
->GetId() == wxApp::s_macAboutMenuItemId
)
714 // this will be taken care of below
720 UMAAppendMenuItem(mh
, item
->GetText() , wxFont::GetDefaultEncoding(), entry
);
721 SetMenuItemCommandID( mh
, CountMenuItems(mh
) , item
->GetId() ) ;
722 SetMenuItemRefCon( mh
, CountMenuItems(mh
) , (UInt32
)item
) ;
733 UMASetMenuTitle( MAC_WXHMENU(menu
->GetHMenu()) , m_titles
[i
], m_font
.GetEncoding() ) ;
734 menu
->MacBeforeDisplay(false) ;
735 ::InsertMenu(MAC_WXHMENU(_wxMenuAt(m_menus
, i
)->GetHMenu()), 0);
738 // take care of the about menu item wherever it is
741 wxMenuItem
*aboutMenuItem
= FindItem(wxApp::s_macAboutMenuItemId
, &aboutMenu
) ;
744 wxAcceleratorEntry
* entry
= wxGetAccelFromString( aboutMenuItem
->GetText() ) ;
745 UMASetMenuItemText( GetMenuHandle( kwxMacAppleMenuId
) , 1 , aboutMenuItem
->GetText() , wxFont::GetDefaultEncoding() );
746 UMAEnableMenuItem( GetMenuHandle( kwxMacAppleMenuId
) , 1 , true );
747 SetMenuItemCommandID( GetMenuHandle( kwxMacAppleMenuId
) , 1 , aboutMenuItem
->GetId() ) ;
748 SetMenuItemRefCon(GetMenuHandle( kwxMacAppleMenuId
) , 1 , (UInt32
)aboutMenuItem
) ;
749 UMASetMenuItemShortcut( GetMenuHandle( kwxMacAppleMenuId
) , 1 , entry
) ;
752 if ( GetAutoWindowMenu() )
754 if ( MacGetWindowMenuHMenu() == NULL
)
756 CreateStandardWindowMenu( 0 , (MenuHandle
*) &s_macWindowMenuHandle
) ;
758 InsertMenu( (MenuHandle
) MacGetWindowMenuHMenu() , 0 ) ;
761 s_macInstalledMenuBar
= this;
764 void wxMenuBar::EnableTop(size_t pos
, bool enable
)
766 wxCHECK_RET( IsAttached(), wxT("doesn't work with unattached menubars") );
767 _wxMenuAt(m_menus
, pos
)->MacEnableMenu( enable
) ;
771 bool wxMenuBar::Enable( bool enable
)
773 wxCHECK_MSG( IsAttached(), false, wxT("doesn't work with unattached menubars") );
775 for (i
= 0; i
< GetMenuCount(); i
++)
777 EnableTop(i
, enable
);
782 void wxMenuBar::SetLabelTop(size_t pos
, const wxString
& label
)
784 wxCHECK_RET( pos
< GetMenuCount(), wxT("invalid menu index") );
786 m_titles
[pos
] = label
;
793 _wxMenuAt(m_menus
, pos
)->SetTitle( label
) ;
795 if (wxMenuBar::s_macInstalledMenuBar
== this) // are we currently installed ?
797 ::SetMenuBar( GetMenuBar() ) ;
802 wxString
wxMenuBar::GetLabelTop(size_t pos
) const
804 wxCHECK_MSG( pos
< GetMenuCount(), wxEmptyString
,
805 wxT("invalid menu index in wxMenuBar::GetLabelTop") );
807 return m_titles
[pos
];
810 int wxMenuBar::FindMenu(const wxString
& title
)
812 wxString menuTitle
= wxStripMenuCodes(title
);
814 size_t count
= GetMenuCount();
815 for ( size_t i
= 0; i
< count
; i
++ )
817 wxString title
= wxStripMenuCodes(m_titles
[i
]);
818 if ( menuTitle
== title
)
827 // ---------------------------------------------------------------------------
828 // wxMenuBar construction
829 // ---------------------------------------------------------------------------
831 wxMenu
*wxMenuBar::Replace(size_t pos
, wxMenu
*menu
, const wxString
& title
)
833 wxMenu
*menuOld
= wxMenuBarBase::Replace(pos
, menu
, title
);
836 m_titles
[pos
] = title
;
840 if (s_macInstalledMenuBar
== this)
842 menuOld
->MacAfterDisplay( false ) ;
843 ::DeleteMenu( menuOld
->MacGetMenuId() /* m_menus[pos]->MacGetMenuId() */ ) ;
845 menu
->MacBeforeDisplay( false ) ;
846 UMASetMenuTitle( MAC_WXHMENU(menu
->GetHMenu()) , title
, m_font
.GetEncoding() ) ;
847 if ( pos
== m_menus
.GetCount() - 1)
849 ::InsertMenu( MAC_WXHMENU(menu
->GetHMenu()) , 0 ) ;
853 ::InsertMenu( MAC_WXHMENU(menu
->GetHMenu()) , _wxMenuAt(m_menus
, pos
+1)->MacGetMenuId() ) ;
860 if (m_invokingWindow
)
861 wxMenubarSetInvokingWindow( menu
, m_invokingWindow
);
866 bool wxMenuBar::Insert(size_t pos
, wxMenu
*menu
, const wxString
& title
)
868 if ( !wxMenuBarBase::Insert(pos
, menu
, title
) )
871 m_titles
.Insert(title
, pos
);
873 UMASetMenuTitle( MAC_WXHMENU(menu
->GetHMenu()) , title
, m_font
.GetEncoding() ) ;
875 if ( IsAttached() && s_macInstalledMenuBar
== this )
877 if (s_macInstalledMenuBar
== this)
879 menu
->MacBeforeDisplay( false ) ;
880 if ( pos
== (size_t) -1 || pos
+ 1 == m_menus
.GetCount() )
882 ::InsertMenu( MAC_WXHMENU(menu
->GetHMenu()) , 0 ) ;
886 ::InsertMenu( MAC_WXHMENU(menu
->GetHMenu()) , _wxMenuAt(m_menus
, pos
+1)->MacGetMenuId() ) ;
891 if (m_invokingWindow
)
892 wxMenubarSetInvokingWindow( menu
, m_invokingWindow
);
897 wxMenu
*wxMenuBar::Remove(size_t pos
)
899 wxMenu
*menu
= wxMenuBarBase::Remove(pos
);
905 if (s_macInstalledMenuBar
== this)
907 ::DeleteMenu( menu
->MacGetMenuId() /* m_menus[pos]->MacGetMenuId() */ ) ;
913 m_titles
.RemoveAt(pos
);
918 bool wxMenuBar::Append(wxMenu
*menu
, const wxString
& title
)
920 WXHMENU submenu
= menu
? menu
->GetHMenu() : 0;
921 wxCHECK_MSG( submenu
, false, wxT("can't append invalid menu to menubar") );
923 if ( !wxMenuBarBase::Append(menu
, title
) )
928 UMASetMenuTitle( MAC_WXHMENU(menu
->GetHMenu()) , title
, m_font
.GetEncoding() ) ;
932 if (s_macInstalledMenuBar
== this)
934 menu
->MacBeforeDisplay( false ) ;
935 ::InsertMenu( MAC_WXHMENU(menu
->GetHMenu()) , 0 ) ;
941 // m_invokingWindow is set after wxFrame::SetMenuBar(). This call enables
942 // adding menu later on.
943 if (m_invokingWindow
)
944 wxMenubarSetInvokingWindow( menu
, m_invokingWindow
);
949 static void wxMenubarUnsetInvokingWindow( wxMenu
*menu
)
951 menu
->SetInvokingWindow( (wxWindow
*) NULL
);
953 wxMenuItemList::compatibility_iterator node
= menu
->GetMenuItems().GetFirst();
956 wxMenuItem
*menuitem
= node
->GetData();
957 if (menuitem
->IsSubMenu())
958 wxMenubarUnsetInvokingWindow( menuitem
->GetSubMenu() );
959 node
= node
->GetNext();
963 static void wxMenubarSetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
965 menu
->SetInvokingWindow( win
);
967 wxMenuItemList::compatibility_iterator node
= menu
->GetMenuItems().GetFirst();
970 wxMenuItem
*menuitem
= node
->GetData();
971 if (menuitem
->IsSubMenu())
972 wxMenubarSetInvokingWindow( menuitem
->GetSubMenu() , win
);
973 node
= node
->GetNext();
977 void wxMenuBar::UnsetInvokingWindow()
979 m_invokingWindow
= (wxWindow
*) NULL
;
980 wxMenuList::compatibility_iterator node
= m_menus
.GetFirst();
983 wxMenu
*menu
= node
->GetData();
984 wxMenubarUnsetInvokingWindow( menu
);
985 node
= node
->GetNext();
989 void wxMenuBar::SetInvokingWindow(wxFrame
*frame
)
991 m_invokingWindow
= frame
;
992 wxMenuList::compatibility_iterator node
= m_menus
.GetFirst();
995 wxMenu
*menu
= node
->GetData();
996 wxMenubarSetInvokingWindow( menu
, frame
);
997 node
= node
->GetNext();
1001 void wxMenuBar::Detach()
1003 wxMenuBarBase::Detach() ;
1006 void wxMenuBar::Attach(wxFrame
*frame
)
1008 wxMenuBarBase::Attach( frame
) ;
1010 // ---------------------------------------------------------------------------
1011 // wxMenuBar searching for menu items
1012 // ---------------------------------------------------------------------------
1014 // Find the itemString in menuString, and return the item id or wxNOT_FOUND
1015 int wxMenuBar::FindMenuItem(const wxString
& menuString
,
1016 const wxString
& itemString
) const
1018 wxString menuLabel
= wxStripMenuCodes(menuString
);
1019 size_t count
= GetMenuCount();
1020 for ( size_t i
= 0; i
< count
; i
++ )
1022 wxString title
= wxStripMenuCodes(m_titles
[i
]);
1023 if ( menuLabel
== title
)
1024 return _wxMenuAt(m_menus
, i
)->FindItem(itemString
);
1030 wxMenuItem
*wxMenuBar::FindItem(int id
, wxMenu
**itemMenu
) const
1035 wxMenuItem
*item
= NULL
;
1036 size_t count
= GetMenuCount();
1037 for ( size_t i
= 0; !item
&& (i
< count
); i
++ )
1039 item
= _wxMenuAt(m_menus
, i
)->FindItem(id
, itemMenu
);