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 #if KEY_wxList_DEPRECATED
53 wxList
wxWinMacMenuList(wxKEY_INTEGER
);
54 wxMenu
*wxFindMenuFromMacMenu(MenuRef inMenuRef
)
56 wxNode
*node
= wxWinMacMenuList
.Find((long)inMenuRef
);
59 return (wxMenu
*)node
->GetData();
62 void wxAssociateMenuWithMacMenu(MenuRef inMenuRef
, wxMenu
*menu
) ;
63 void wxAssociateMenuWithMacMenu(MenuRef inMenuRef
, wxMenu
*menu
)
65 // adding NULL MenuRef is (first) surely a result of an error and
66 // (secondly) breaks menu command processing
67 wxCHECK_RET( inMenuRef
!= (MenuRef
) NULL
, wxT("attempt to add a NULL MenuRef to menu list") );
69 if ( !wxWinMacMenuList
.Find((long)inMenuRef
) )
70 wxWinMacMenuList
.Append((long)inMenuRef
, menu
);
73 void wxRemoveMacMenuAssociation(wxMenu
*menu
) ;
74 void wxRemoveMacMenuAssociation(wxMenu
*menu
)
76 wxWinMacMenuList
.DeleteObject(menu
);
80 WX_DECLARE_HASH_MAP(MenuRef
, wxMenu
*, wxPointerHash
, wxPointerEqual
, MacMenuMap
);
82 static MacMenuMap wxWinMacMenuList
;
84 wxMenu
*wxFindMenuFromMacMenu(MenuRef inMenuRef
)
86 MacMenuMap::iterator node
= wxWinMacMenuList
.find(inMenuRef
);
88 return (node
== wxWinMacMenuList
.end()) ? NULL
: node
->second
;
91 void wxAssociateMenuWithMacMenu(MenuRef inMenuRef
, wxMenu
*menu
) ;
92 void wxAssociateMenuWithMacMenu(MenuRef inMenuRef
, wxMenu
*menu
)
94 // adding NULL MenuRef is (first) surely a result of an error and
95 // (secondly) breaks menu command processing
96 wxCHECK_RET( inMenuRef
!= (MenuRef
) NULL
, wxT("attempt to add a NULL MenuRef to menu list") );
98 wxWinMacMenuList
[inMenuRef
] = menu
;
101 void wxRemoveMacMenuAssociation(wxMenu
*menu
) ;
102 void wxRemoveMacMenuAssociation(wxMenu
*menu
)
104 // iterate over all the elements in the class
105 MacMenuMap::iterator it
;
106 for ( it
= wxWinMacMenuList
.begin(); it
!= wxWinMacMenuList
.end(); ++it
)
108 if ( it
->second
== menu
)
110 wxWinMacMenuList
.erase(it
);
115 #endif // deprecated wxList
117 // ============================================================================
119 // ============================================================================
120 static void wxMenubarUnsetInvokingWindow( wxMenu
*menu
) ;
121 static void wxMenubarSetInvokingWindow( wxMenu
*menu
, wxWindow
*win
);
125 // Construct a menu with optional title (then use append)
128 short wxMenu::s_macNextMenuId
= 3 ;
130 short wxMenu::s_macNextMenuId
= 2 ;
135 _wxMenuAt(const wxMenuList
&menuList
, size_t pos
)
137 wxMenuList::compatibility_iterator menuIter
= menuList
.GetFirst();
139 while (pos
-- > 0) menuIter
= menuIter
->GetNext();
141 return menuIter
->GetData() ;
147 m_startRadioGroup
= -1;
150 m_macMenuId
= s_macNextMenuId
++;
151 m_hMenu
= UMANewMenu(m_macMenuId
, m_title
, wxFont::GetDefaultEncoding() );
155 wxLogLastError(wxT("UMANewMenu failed"));
158 wxAssociateMenuWithMacMenu( (MenuRef
)m_hMenu
, this ) ;
160 // if we have a title, insert it in the beginning of the menu
163 Append(idMenuTitle
, m_title
) ;
170 wxRemoveMacMenuAssociation( this ) ;
171 if (MAC_WXHMENU(m_hMenu
))
172 ::DisposeMenu(MAC_WXHMENU(m_hMenu
));
177 // not available on the mac platform
180 void wxMenu::Attach(wxMenuBarBase
*menubar
)
182 wxMenuBase::Attach(menubar
);
187 // function appends a new item or submenu to the menu
188 // append a new item or submenu to the menu
189 bool wxMenu::DoInsertOrAppend(wxMenuItem
*pItem
, size_t pos
)
191 wxASSERT_MSG( pItem
!= NULL
, wxT("can't append NULL item to the menu") );
193 if ( pItem
->IsSeparator() )
195 if ( pos
== (size_t)-1 )
196 MacAppendMenu(MAC_WXHMENU(m_hMenu
), "\p-");
198 MacInsertMenuItem(MAC_WXHMENU(m_hMenu
), "\p-" , pos
);
202 wxMenu
*pSubMenu
= pItem
->GetSubMenu() ;
203 if ( pSubMenu
!= NULL
)
205 wxASSERT_MSG( pSubMenu
->m_hMenu
!= NULL
, wxT("invalid submenu added"));
206 pSubMenu
->m_menuParent
= this ;
208 if (wxMenuBar::MacGetInstalledMenuBar() == GetMenuBar())
210 pSubMenu
->MacBeforeDisplay( true ) ;
213 if ( pos
== (size_t)-1 )
214 UMAAppendSubMenuItem(MAC_WXHMENU(m_hMenu
), pItem
->GetText(), wxFont::GetDefaultEncoding() , pSubMenu
->m_macMenuId
);
216 UMAInsertSubMenuItem(MAC_WXHMENU(m_hMenu
), pItem
->GetText(), wxFont::GetDefaultEncoding() , pos
, pSubMenu
->m_macMenuId
);
217 pItem
->UpdateItemBitmap() ;
218 pItem
->UpdateItemStatus() ;
222 if ( pos
== (size_t)-1 )
224 UMAAppendMenuItem(MAC_WXHMENU(m_hMenu
), wxT("a") , wxFont::GetDefaultEncoding() );
225 pos
= CountMenuItems(MAC_WXHMENU(m_hMenu
)) ;
229 // MacOS counts menu items from 1 and inserts after, therefore having the
230 // same effect as wx 0 based and inserting before, we must correct pos
231 // after however for updates to be correct
232 UMAInsertMenuItem(MAC_WXHMENU(m_hMenu
), wxT("a"), wxFont::GetDefaultEncoding(), pos
);
236 SetMenuItemCommandID( MAC_WXHMENU(m_hMenu
) , pos
, pItem
->GetId() ) ;
237 SetMenuItemRefCon( MAC_WXHMENU(m_hMenu
) , pos
, (UInt32
) pItem
) ;
238 pItem
->UpdateItemText() ;
239 pItem
->UpdateItemBitmap() ;
240 pItem
->UpdateItemStatus() ;
242 if ( pItem
->GetId() == idMenuTitle
)
244 UMAEnableMenuItem(MAC_WXHMENU(m_hMenu
) , pos
, false ) ;
248 // if we're already attached to the menubar, we must update it
249 if ( IsAttached() && GetMenuBar()->IsAttached() )
251 GetMenuBar()->Refresh();
256 void wxMenu::EndRadioGroup()
258 // we're not inside a radio group any longer
259 m_startRadioGroup
= -1;
262 wxMenuItem
* wxMenu::DoAppend(wxMenuItem
*item
)
264 wxCHECK_MSG( item
, NULL
, _T("NULL item in wxMenu::DoAppend") );
268 if ( item
->GetKind() == wxITEM_RADIO
)
270 int count
= GetMenuItemCount();
272 if ( m_startRadioGroup
== -1 )
274 // start a new radio group
275 m_startRadioGroup
= count
;
277 // for now it has just one element
278 item
->SetAsRadioGroupStart();
279 item
->SetRadioGroupEnd(m_startRadioGroup
);
281 // ensure that we have a checked item in the radio group
284 else // extend the current radio group
286 // we need to update its end item
287 item
->SetRadioGroupStart(m_startRadioGroup
);
288 wxMenuItemList::compatibility_iterator node
= GetMenuItems().Item(m_startRadioGroup
);
292 node
->GetData()->SetRadioGroupEnd(count
);
296 wxFAIL_MSG( _T("where is the radio group start item?") );
300 else // not a radio item
305 if ( !wxMenuBase::DoAppend(item
) || !DoInsertOrAppend(item
) )
312 // check the item initially
319 wxMenuItem
* wxMenu::DoInsert(size_t pos
, wxMenuItem
*item
)
321 if (wxMenuBase::DoInsert(pos
, item
) && DoInsertOrAppend(item
, pos
))
327 wxMenuItem
*wxMenu::DoRemove(wxMenuItem
*item
)
329 // we need to find the items position in the child list
331 wxMenuItemList::compatibility_iterator node
= GetMenuItems().GetFirst();
332 for ( pos
= 0; node
; pos
++ )
334 if ( node
->GetData() == item
)
337 node
= node
->GetNext();
340 // DoRemove() (unlike Remove) can only be called for existing item!
341 wxCHECK_MSG( node
, NULL
, wxT("bug in wxMenu::Remove logic") );
343 ::DeleteMenuItem(MAC_WXHMENU(m_hMenu
) , pos
+ 1);
345 if ( IsAttached() && GetMenuBar()->IsAttached() )
347 // otherwise, the change won't be visible
348 GetMenuBar()->Refresh();
351 // and from internal data structures
352 return wxMenuBase::DoRemove(item
);
355 void wxMenu::SetTitle(const wxString
& label
)
358 UMASetMenuTitle(MAC_WXHMENU(m_hMenu
) , label
, wxFont::GetDefaultEncoding() ) ;
360 bool wxMenu::ProcessCommand(wxCommandEvent
& event
)
362 bool processed
= FALSE
;
364 // Try the menu's event handler
365 if ( !processed
&& GetEventHandler())
367 processed
= GetEventHandler()->ProcessEvent(event
);
370 // Try the window the menu was popped up from (and up through the
372 wxWindow
*win
= GetInvokingWindow();
373 if ( !processed
&& win
)
374 processed
= win
->GetEventHandler()->ProcessEvent(event
);
380 // ---------------------------------------------------------------------------
382 // ---------------------------------------------------------------------------
384 wxWindow
*wxMenu::GetWindow() const
386 if ( m_invokingWindow
!= NULL
)
387 return m_invokingWindow
;
388 else if ( GetMenuBar() != NULL
)
389 return (wxWindow
*) GetMenuBar()->GetFrame();
394 // helper functions returning the mac menu position for a certain item, note that this is
395 // mac-wise 1 - based, i.e. the first item has index 1 whereas on MSWin it has pos 0
397 int wxMenu::MacGetIndexFromId( int id
)
400 wxMenuItemList::compatibility_iterator node
= GetMenuItems().GetFirst();
401 for ( pos
= 0; node
; pos
++ )
403 if ( node
->GetData()->GetId() == id
)
406 node
= node
->GetNext();
415 int wxMenu::MacGetIndexFromItem( wxMenuItem
*pItem
)
418 wxMenuItemList::compatibility_iterator node
= GetMenuItems().GetFirst();
419 for ( pos
= 0; node
; pos
++ )
421 if ( node
->GetData() == pItem
)
424 node
= node
->GetNext();
433 void wxMenu::MacEnableMenu( bool bDoEnable
)
435 UMAEnableMenuItem(MAC_WXHMENU(m_hMenu
) , 0 , bDoEnable
) ;
440 // MacOS needs to know about submenus somewhere within this menu
441 // before it can be displayed , also hide special menu items like preferences
442 // that are handled by the OS
443 void wxMenu::MacBeforeDisplay( bool isSubMenu
)
445 wxMenuItem
* previousItem
= NULL
;
447 wxMenuItemList::compatibility_iterator node
;
449 for (pos
= 0, node
= GetMenuItems().GetFirst(); node
; node
= node
->GetNext(), pos
++)
451 item
= (wxMenuItem
*)node
->GetData();
452 wxMenu
* subMenu
= item
->GetSubMenu() ;
455 subMenu
->MacBeforeDisplay( true ) ;
460 // what we do here is to hide the special items which are
461 // shown in the application menu anyhow -- it doesn't make
462 // sense to show them in their normal place as well
463 if ( item
->GetId() == wxApp::s_macAboutMenuItemId
||
464 ( UMAGetSystemVersion() >= 0x1000 && (
465 item
->GetId() == wxApp::s_macPreferencesMenuItemId
||
466 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() ),
514 #endif // TARGET_CARBON
516 previousItem
= item
;
520 ::InsertMenu(MAC_WXHMENU( GetHMenu()), -1);
523 // undo all changes from the MacBeforeDisplay call
524 void wxMenu::MacAfterDisplay( bool isSubMenu
)
527 ::DeleteMenu(MacGetMenuId());
529 wxMenuItem
* previousItem
= NULL
;
531 wxMenuItemList::compatibility_iterator node
;
533 for (pos
= 0, node
= GetMenuItems().GetFirst(); node
; node
= node
->GetNext(), pos
++)
535 item
= (wxMenuItem
*)node
->GetData();
536 wxMenu
* subMenu
= item
->GetSubMenu() ;
539 subMenu
->MacAfterDisplay( true ) ;
543 // no need to undo hidings
545 previousItem
= item
;
553 Mac Implementation note :
555 The Mac has only one global menubar, so we attempt to install the currently
556 active menubar from a frame, we currently don't take into account mdi-frames
557 which would ask for menu-merging
559 Secondly there is no mac api for changing a menubar that is not the current
560 menubar, so we have to wait for preparing the actual menubar until the
561 wxMenubar is to be used
563 We can in subsequent versions use MacInstallMenuBar to provide some sort of
564 auto-merge for MDI in case this will be necessary
568 wxMenuBar
* wxMenuBar::s_macInstalledMenuBar
= NULL
;
569 wxMenuBar
* wxMenuBar::s_macCommonMenuBar
= NULL
;
570 bool wxMenuBar::s_macAutoWindowMenu
= true ;
571 WXHMENU
wxMenuBar::s_macWindowMenuHandle
= NULL
;
573 void wxMenuBar::Init()
575 m_eventHandler
= this;
576 m_menuBarFrame
= NULL
;
577 m_invokingWindow
= (wxWindow
*) NULL
;
580 wxMenuBar::wxMenuBar()
585 wxMenuBar::wxMenuBar( long WXUNUSED(style
) )
591 wxMenuBar::wxMenuBar(size_t count
, wxMenu
*menus
[], const wxString titles
[], long WXUNUSED(style
))
595 m_titles
.Alloc(count
);
597 for ( size_t i
= 0; i
< count
; i
++ )
599 m_menus
.Append(menus
[i
]);
600 m_titles
.Add(titles
[i
]);
602 menus
[i
]->Attach(this);
606 wxMenuBar::~wxMenuBar()
608 if (s_macCommonMenuBar
== this)
609 s_macCommonMenuBar
= NULL
;
610 if (s_macInstalledMenuBar
== this)
613 s_macInstalledMenuBar
= NULL
;
618 void wxMenuBar::Refresh(bool WXUNUSED(eraseBackground
), const wxRect
*WXUNUSED(rect
))
620 wxCHECK_RET( IsAttached(), wxT("can't refresh unatteched menubar") );
625 void wxMenuBar::MacInstallMenuBar()
627 if ( s_macInstalledMenuBar
== this )
630 MenuBarHandle menubar
= NULL
;
631 #if TARGET_API_MAC_OSX
632 menubar
= NewHandleClear( 6 /* sizeof( MenuBarHeader ) */ ) ;
634 menubar
= NewHandleClear( 12 ) ;
635 (*menubar
)[3] = 0x0a ;
637 ::SetMenuBar( menubar
) ;
638 DisposeMenuBar( menubar
) ;
639 MenuHandle appleMenu
= NULL
;
640 char appleMenuTitle
[3] = { 01 , kMenuAppleLogoFilledGlyph
, 0 } ;
642 verify_noerr( CreateNewMenu( kwxMacAppleMenuId
, 0 , &appleMenu
) ) ;
643 verify_noerr( SetMenuTitle( appleMenu
, (ConstStr255Param
) appleMenuTitle
) );
645 // Add About/Preferences separator only on OS X
646 // KH/RN: Separator is always present on 10.3 but not on 10.2
647 // However, the change from 10.2 to 10.3 suggests it is preferred
648 #if TARGET_API_MAC_OSX
649 MacInsertMenuItem( appleMenu
, "\p-" , 0 ) ;
652 MacInsertMenuItem( appleMenu
, "\pAbout..." , 0 ) ;
653 MacInsertMenu( appleMenu
, 0 ) ;
655 // clean-up the help menu before adding new items
656 static MenuHandle mh
= NULL
;
660 MenuItemIndex firstUserHelpMenuItem
;
661 if ( UMAGetHelpMenu( &mh
, &firstUserHelpMenuItem
) == noErr
)
663 for ( int i
= CountMenuItems( mh
) ; i
>= firstUserHelpMenuItem
; --i
)
665 DeleteMenuItem( mh
, i
) ;
674 if ( UMAGetSystemVersion() >= 0x1000 && wxApp::s_macPreferencesMenuItemId
)
676 wxMenuItem
*item
= FindItem( wxApp::s_macPreferencesMenuItemId
, NULL
) ;
677 if ( item
== NULL
|| !(item
->IsEnabled()) )
678 DisableMenuCommand( NULL
, kHICommandPreferences
) ;
680 EnableMenuCommand( NULL
, kHICommandPreferences
) ;
682 // Unlike preferences which may or may not exist, the Quit item should be always
683 // enabled unless it is added by the application and then disabled, otherwise
684 // a program would be required to add an item with wxID_EXIT in order to get the
685 // Quit menu item to be enabled, which seems a bit burdensome.
686 if ( UMAGetSystemVersion() >= 0x1000 && wxApp::s_macExitMenuItemId
)
688 wxMenuItem
*item
= FindItem( wxApp::s_macExitMenuItemId
, NULL
) ;
689 if ( item
!= NULL
&& !(item
->IsEnabled()) )
690 DisableMenuCommand( NULL
, kHICommandQuit
) ;
692 EnableMenuCommand( NULL
, kHICommandQuit
) ;
695 wxMenuList::compatibility_iterator menuIter
= m_menus
.GetFirst();
697 for (size_t i
= 0; i
< m_menus
.GetCount(); i
++, menuIter
= menuIter
->GetNext())
699 wxMenuItemList::compatibility_iterator node
;
702 wxMenu
* menu
= menuIter
->GetData() , *subMenu
= NULL
;
704 if( m_titles
[i
] == wxT("?") || m_titles
[i
] == wxT("&?") || m_titles
[i
] == wxApp::s_macHelpMenuTitleName
)
706 for (pos
= 0 , node
= menu
->GetMenuItems().GetFirst(); node
; node
= node
->GetNext(), pos
++)
708 item
= (wxMenuItem
*)node
->GetData();
709 subMenu
= item
->GetSubMenu() ;
712 // we don't support hierarchical menus in the help menu yet
716 if ( item
->GetId() != wxApp::s_macAboutMenuItemId
)
720 MenuItemIndex firstUserHelpMenuItem
;
721 if ( UMAGetHelpMenu( &mh
, &firstUserHelpMenuItem
) == noErr
)
731 if ( item
->IsSeparator() )
734 MacAppendMenu(mh
, "\p-" );
738 wxAcceleratorEntry
* entry
= wxGetAccelFromString( item
->GetText() ) ;
740 if ( item
->GetId() == wxApp::s_macAboutMenuItemId
)
742 // this will be taken care of below
748 UMAAppendMenuItem(mh
, item
->GetText() , wxFont::GetDefaultEncoding(), entry
);
749 SetMenuItemCommandID( mh
, CountMenuItems(mh
) , item
->GetId() ) ;
750 SetMenuItemRefCon( mh
, CountMenuItems(mh
) , (UInt32
)item
) ;
761 UMASetMenuTitle( MAC_WXHMENU(menu
->GetHMenu()) , m_titles
[i
], m_font
.GetEncoding() ) ;
762 menu
->MacBeforeDisplay(false) ;
763 ::InsertMenu(MAC_WXHMENU(_wxMenuAt(m_menus
, i
)->GetHMenu()), 0);
766 // take care of the about menu item wherever it is
769 wxMenuItem
*aboutMenuItem
= FindItem(wxApp::s_macAboutMenuItemId
, &aboutMenu
) ;
772 wxAcceleratorEntry
* entry
= wxGetAccelFromString( aboutMenuItem
->GetText() ) ;
773 UMASetMenuItemText( GetMenuHandle( kwxMacAppleMenuId
) , 1 , aboutMenuItem
->GetText() , wxFont::GetDefaultEncoding() );
774 UMAEnableMenuItem( GetMenuHandle( kwxMacAppleMenuId
) , 1 , true );
775 SetMenuItemCommandID( GetMenuHandle( kwxMacAppleMenuId
) , 1 , aboutMenuItem
->GetId() ) ;
776 SetMenuItemRefCon(GetMenuHandle( kwxMacAppleMenuId
) , 1 , (UInt32
)aboutMenuItem
) ;
777 UMASetMenuItemShortcut( GetMenuHandle( kwxMacAppleMenuId
) , 1 , entry
) ;
780 if ( GetAutoWindowMenu() )
782 if ( MacGetWindowMenuHMenu() == NULL
)
784 CreateStandardWindowMenu( 0 , (MenuHandle
*) &s_macWindowMenuHandle
) ;
786 InsertMenu( (MenuHandle
) MacGetWindowMenuHMenu() , 0 ) ;
789 s_macInstalledMenuBar
= this;
792 void wxMenuBar::EnableTop(size_t pos
, bool enable
)
794 wxCHECK_RET( IsAttached(), wxT("doesn't work with unattached menubars") );
795 _wxMenuAt(m_menus
, pos
)->MacEnableMenu( enable
) ;
799 bool wxMenuBar::Enable( bool enable
)
801 wxCHECK_MSG( IsAttached(), false, wxT("doesn't work with unattached menubars") );
803 for (i
= 0; i
< GetMenuCount(); i
++)
805 EnableTop(i
, enable
);
810 void wxMenuBar::SetLabelTop(size_t pos
, const wxString
& label
)
812 wxCHECK_RET( pos
< GetMenuCount(), wxT("invalid menu index") );
814 m_titles
[pos
] = label
;
821 _wxMenuAt(m_menus
, pos
)->SetTitle( label
) ;
823 if (wxMenuBar::s_macInstalledMenuBar
== this) // are we currently installed ?
825 ::SetMenuBar( GetMenuBar() ) ;
830 wxString
wxMenuBar::GetLabelTop(size_t pos
) const
832 wxCHECK_MSG( pos
< GetMenuCount(), wxEmptyString
,
833 wxT("invalid menu index in wxMenuBar::GetLabelTop") );
835 return m_titles
[pos
];
838 int wxMenuBar::FindMenu(const wxString
& title
)
840 wxString menuTitle
= wxStripMenuCodes(title
);
842 size_t count
= GetMenuCount();
843 for ( size_t i
= 0; i
< count
; i
++ )
845 wxString title
= wxStripMenuCodes(m_titles
[i
]);
846 if ( menuTitle
== title
)
855 // ---------------------------------------------------------------------------
856 // wxMenuBar construction
857 // ---------------------------------------------------------------------------
859 wxMenu
*wxMenuBar::Replace(size_t pos
, wxMenu
*menu
, const wxString
& title
)
861 wxMenu
*menuOld
= wxMenuBarBase::Replace(pos
, menu
, title
);
864 m_titles
[pos
] = title
;
868 if (s_macInstalledMenuBar
== this)
870 menuOld
->MacAfterDisplay( false ) ;
871 ::DeleteMenu( menuOld
->MacGetMenuId() /* m_menus[pos]->MacGetMenuId() */ ) ;
873 menu
->MacBeforeDisplay( false ) ;
874 UMASetMenuTitle( MAC_WXHMENU(menu
->GetHMenu()) , title
, m_font
.GetEncoding() ) ;
875 if ( pos
== m_menus
.GetCount() - 1)
877 ::InsertMenu( MAC_WXHMENU(menu
->GetHMenu()) , 0 ) ;
881 ::InsertMenu( MAC_WXHMENU(menu
->GetHMenu()) , _wxMenuAt(m_menus
, pos
+1)->MacGetMenuId() ) ;
888 if (m_invokingWindow
)
889 wxMenubarSetInvokingWindow( menu
, m_invokingWindow
);
894 bool wxMenuBar::Insert(size_t pos
, wxMenu
*menu
, const wxString
& title
)
896 if ( !wxMenuBarBase::Insert(pos
, menu
, title
) )
899 m_titles
.Insert(title
, pos
);
901 UMASetMenuTitle( MAC_WXHMENU(menu
->GetHMenu()) , title
, m_font
.GetEncoding() ) ;
903 if ( IsAttached() && s_macInstalledMenuBar
== this )
905 if (s_macInstalledMenuBar
== this)
907 menu
->MacBeforeDisplay( false ) ;
908 if ( pos
== (size_t) -1 || pos
+ 1 == m_menus
.GetCount() )
910 ::InsertMenu( MAC_WXHMENU(menu
->GetHMenu()) , 0 ) ;
914 ::InsertMenu( MAC_WXHMENU(menu
->GetHMenu()) , _wxMenuAt(m_menus
, pos
+1)->MacGetMenuId() ) ;
919 if (m_invokingWindow
)
920 wxMenubarSetInvokingWindow( menu
, m_invokingWindow
);
925 wxMenu
*wxMenuBar::Remove(size_t pos
)
927 wxMenu
*menu
= wxMenuBarBase::Remove(pos
);
933 if (s_macInstalledMenuBar
== this)
935 ::DeleteMenu( menu
->MacGetMenuId() /* m_menus[pos]->MacGetMenuId() */ ) ;
941 m_titles
.RemoveAt(pos
);
946 bool wxMenuBar::Append(wxMenu
*menu
, const wxString
& title
)
948 WXHMENU submenu
= menu
? menu
->GetHMenu() : 0;
949 wxCHECK_MSG( submenu
, FALSE
, wxT("can't append invalid menu to menubar") );
951 if ( !wxMenuBarBase::Append(menu
, title
) )
956 UMASetMenuTitle( MAC_WXHMENU(menu
->GetHMenu()) , title
, m_font
.GetEncoding() ) ;
960 if (s_macInstalledMenuBar
== this)
962 menu
->MacBeforeDisplay( false ) ;
963 ::InsertMenu( MAC_WXHMENU(menu
->GetHMenu()) , 0 ) ;
969 // m_invokingWindow is set after wxFrame::SetMenuBar(). This call enables
970 // adding menu later on.
971 if (m_invokingWindow
)
972 wxMenubarSetInvokingWindow( menu
, m_invokingWindow
);
977 static void wxMenubarUnsetInvokingWindow( wxMenu
*menu
)
979 menu
->SetInvokingWindow( (wxWindow
*) NULL
);
981 wxMenuItemList::compatibility_iterator node
= menu
->GetMenuItems().GetFirst();
984 wxMenuItem
*menuitem
= node
->GetData();
985 if (menuitem
->IsSubMenu())
986 wxMenubarUnsetInvokingWindow( menuitem
->GetSubMenu() );
987 node
= node
->GetNext();
991 static void wxMenubarSetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
993 menu
->SetInvokingWindow( win
);
995 wxMenuItemList::compatibility_iterator node
= menu
->GetMenuItems().GetFirst();
998 wxMenuItem
*menuitem
= node
->GetData();
999 if (menuitem
->IsSubMenu())
1000 wxMenubarSetInvokingWindow( menuitem
->GetSubMenu() , win
);
1001 node
= node
->GetNext();
1005 void wxMenuBar::UnsetInvokingWindow()
1007 m_invokingWindow
= (wxWindow
*) NULL
;
1008 wxMenuList::compatibility_iterator node
= m_menus
.GetFirst();
1011 wxMenu
*menu
= node
->GetData();
1012 wxMenubarUnsetInvokingWindow( menu
);
1013 node
= node
->GetNext();
1017 void wxMenuBar::SetInvokingWindow(wxFrame
*frame
)
1019 m_invokingWindow
= frame
;
1020 wxMenuList::compatibility_iterator node
= m_menus
.GetFirst();
1023 wxMenu
*menu
= node
->GetData();
1024 wxMenubarSetInvokingWindow( menu
, frame
);
1025 node
= node
->GetNext();
1029 void wxMenuBar::Detach()
1031 wxMenuBarBase::Detach() ;
1034 void wxMenuBar::Attach(wxFrame
*frame
)
1036 wxMenuBarBase::Attach( frame
) ;
1038 // ---------------------------------------------------------------------------
1039 // wxMenuBar searching for menu items
1040 // ---------------------------------------------------------------------------
1042 // Find the itemString in menuString, and return the item id or wxNOT_FOUND
1043 int wxMenuBar::FindMenuItem(const wxString
& menuString
,
1044 const wxString
& itemString
) const
1046 wxString menuLabel
= wxStripMenuCodes(menuString
);
1047 size_t count
= GetMenuCount();
1048 for ( size_t i
= 0; i
< count
; i
++ )
1050 wxString title
= wxStripMenuCodes(m_titles
[i
]);
1051 if ( menuLabel
== title
)
1052 return _wxMenuAt(m_menus
, i
)->FindItem(itemString
);
1058 wxMenuItem
*wxMenuBar::FindItem(int id
, wxMenu
**itemMenu
) const
1063 wxMenuItem
*item
= NULL
;
1064 size_t count
= GetMenuCount();
1065 for ( size_t i
= 0; !item
&& (i
< count
); i
++ )
1067 item
= _wxMenuAt(m_menus
, i
)->FindItem(id
, itemMenu
);