]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/menu.cpp
add wxUSE_DATAVIEWCTRL check to fix a hundred compilation errors
[wxWidgets.git] / src / mac / carbon / menu.cpp
CommitLineData
e9576ca5 1/////////////////////////////////////////////////////////////////////////////
e4db172a 2// Name: src/mac/carbon/menu.cpp
e9576ca5 3// Purpose: wxMenu, wxMenuBar, wxMenuItem
a31a5f85 4// Author: Stefan Csomor
e9576ca5 5// Modified by:
a31a5f85 6// Created: 1998-01-01
e9576ca5 7// RCS-ID: $Id$
a31a5f85 8// Copyright: (c) Stefan Csomor
e4db172a 9// Licence: wxWindows licence
e9576ca5
SC
10/////////////////////////////////////////////////////////////////////////////
11
e9576ca5
SC
12// ============================================================================
13// headers & declarations
14// ============================================================================
15
77ffb593 16// wxWidgets headers
e9576ca5
SC
17// -----------------
18
3d1a4878
SC
19#include "wx/wxprec.h"
20
e9576ca5 21#include "wx/menu.h"
e4db172a
WS
22
23#ifndef WX_PRECOMP
24 #include "wx/log.h"
670f9935 25 #include "wx/app.h"
de6185e2 26 #include "wx/utils.h"
76b49cf4 27 #include "wx/frame.h"
25466131 28 #include "wx/menuitem.h"
e4db172a
WS
29#endif
30
519cb848
SC
31#include "wx/mac/uma.h"
32
e9576ca5
SC
33// other standard headers
34// ----------------------
35#include <string.h>
36
e9576ca5
SC
37IMPLEMENT_DYNAMIC_CLASS(wxMenu, wxEvtHandler)
38IMPLEMENT_DYNAMIC_CLASS(wxMenuBar, wxEvtHandler)
e9576ca5 39
519cb848 40// the (popup) menu title has this special id
de5914a1 41static const int idMenuTitle = -3;
519cb848 42
716d0327 43static const short kwxMacAppleMenuId = 1 ;
519cb848 44
de5914a1
SC
45
46// Find an item given the Macintosh Menu Reference
47
71f2fb52
RN
48WX_DECLARE_HASH_MAP(MenuRef, wxMenu*, wxPointerHash, wxPointerEqual, MacMenuMap);
49
50static MacMenuMap wxWinMacMenuList;
51
52wxMenu *wxFindMenuFromMacMenu(MenuRef inMenuRef)
53{
54 MacMenuMap::iterator node = wxWinMacMenuList.find(inMenuRef);
55
56 return (node == wxWinMacMenuList.end()) ? NULL : node->second;
57}
58
59void wxAssociateMenuWithMacMenu(MenuRef inMenuRef, wxMenu *menu) ;
60void wxAssociateMenuWithMacMenu(MenuRef inMenuRef, wxMenu *menu)
61{
62 // adding NULL MenuRef is (first) surely a result of an error and
63 // (secondly) breaks menu command processing
64 wxCHECK_RET( inMenuRef != (MenuRef) NULL, wxT("attempt to add a NULL MenuRef to menu list") );
de5914a1 65
71f2fb52
RN
66 wxWinMacMenuList[inMenuRef] = menu;
67}
68
69void wxRemoveMacMenuAssociation(wxMenu *menu) ;
70void wxRemoveMacMenuAssociation(wxMenu *menu)
71{
72 // iterate over all the elements in the class
73 MacMenuMap::iterator it;
74 for ( it = wxWinMacMenuList.begin(); it != wxWinMacMenuList.end(); ++it )
75 {
76 if ( it->second == menu )
77 {
78 wxWinMacMenuList.erase(it);
79 break;
80 }
81 }
82}
de5914a1 83
e608ff58
KO
84void wxInsertMenuItemsInMenu(wxMenu* menu, MenuRef wm, MenuItemIndex insertAfter)
85{
86 wxMenuItemList::compatibility_iterator node;
87 wxMenuItem *item;
88 wxMenu *subMenu = NULL ;
89 bool newItems = false;
90
91 for (node = menu->GetMenuItems().GetFirst(); node; node = node->GetNext())
92 {
93 item = (wxMenuItem *)node->GetData();
94 subMenu = item->GetSubMenu() ;
95 if (subMenu)
96 {
90f58090 97 wxInsertMenuItemsInMenu(subMenu, (MenuRef)subMenu->GetHMenu(), 0);
e608ff58
KO
98 }
99 if ( item->IsSeparator() )
100 {
101 if ( wm && newItems)
102 InsertMenuItemTextWithCFString( wm,
90f58090
VZ
103 CFSTR(""), insertAfter, kMenuItemAttrSeparator, 0);
104
e608ff58
KO
105 newItems = false;
106 }
107 else
108 {
109 wxAcceleratorEntry*
9a9c35d3 110 entry = wxAcceleratorEntry::Create( item->GetItemLabel() ) ;
e608ff58 111
90f58090
VZ
112 MenuItemIndex winListPos = (MenuItemIndex)-1;
113 OSStatus err = GetIndMenuItemWithCommandID(wm,
e608ff58 114 wxIdToMacCommand ( item->GetId() ), 1, NULL, &winListPos);
90f58090 115
e608ff58
KO
116 if ( wm && err == menuItemNotFoundErr )
117 {
118 // NB: the only way to determine whether or not we should add
119 // a separator is to know if we've added menu items to the menu
120 // before the separator.
121 newItems = true;
9a9c35d3 122 UMAInsertMenuItem(wm, wxStripMenuCodes(item->GetItemLabel()) , wxFont::GetDefaultEncoding(), insertAfter, entry);
e608ff58
KO
123 SetMenuItemCommandID( wm , insertAfter+1 , wxIdToMacCommand ( item->GetId() ) ) ;
124 SetMenuItemRefCon( wm , insertAfter+1 , (URefCon) item ) ;
125 }
126
127 delete entry ;
128 }
90f58090 129 }
e608ff58
KO
130}
131
e9576ca5
SC
132// ============================================================================
133// implementation
134// ============================================================================
7c15086c
SC
135static void wxMenubarUnsetInvokingWindow( wxMenu *menu ) ;
136static void wxMenubarSetInvokingWindow( wxMenu *menu, wxWindow *win );
519cb848 137
e9576ca5
SC
138// Menus
139
140// Construct a menu with optional title (then use append)
519cb848 141
f5c6eb5c 142#ifdef __DARWIN__
82ca6dbc
GD
143short wxMenu::s_macNextMenuId = 3 ;
144#else
519cb848 145short wxMenu::s_macNextMenuId = 2 ;
82ca6dbc 146#endif
519cb848 147
71f2fb52
RN
148static
149wxMenu *
150_wxMenuAt(const wxMenuList &menuList, size_t pos)
151{
152 wxMenuList::compatibility_iterator menuIter = menuList.GetFirst();
902725ee 153
5977edb9
DS
154 while (pos-- > 0)
155 menuIter = menuIter->GetNext();
902725ee 156
71f2fb52
RN
157 return menuIter->GetData() ;
158}
159
e7549107 160void wxMenu::Init()
e9576ca5 161{
902725ee 162 m_doBreak = false;
7c15086c 163 m_startRadioGroup = -1;
e7549107
SC
164
165 // create the menu
58751a86 166 m_macMenuId = s_macNextMenuId++;
a9412f8f 167 m_hMenu = UMANewMenu(m_macMenuId, m_title, wxFont::GetDefaultEncoding() );
e7549107
SC
168
169 if ( !m_hMenu )
170 {
22026088 171 wxLogLastError(wxT("UMANewMenu failed"));
e7549107
SC
172 }
173
de5914a1
SC
174 wxAssociateMenuWithMacMenu( (MenuRef)m_hMenu , this ) ;
175
e7549107 176 // if we have a title, insert it in the beginning of the menu
902725ee 177 if ( !m_title.empty() )
e9576ca5 178 {
519cb848 179 Append(idMenuTitle, m_title) ;
e9576ca5
SC
180 AppendSeparator() ;
181 }
e7549107 182}
e9576ca5 183
e7549107
SC
184wxMenu::~wxMenu()
185{
de5914a1 186 wxRemoveMacMenuAssociation( this ) ;
e40298d5
JS
187 if (MAC_WXHMENU(m_hMenu))
188 ::DisposeMenu(MAC_WXHMENU(m_hMenu));
e9576ca5
SC
189}
190
e7549107 191void wxMenu::Break()
e9576ca5 192{
e40298d5 193 // not available on the mac platform
e7549107 194}
e9576ca5 195
7c15086c 196void wxMenu::Attach(wxMenuBarBase *menubar)
e7549107 197{
7c15086c 198 wxMenuBase::Attach(menubar);
e7549107 199
7c15086c 200 EndRadioGroup();
e9576ca5
SC
201}
202
e9576ca5 203// function appends a new item or submenu to the menu
e7549107
SC
204// append a new item or submenu to the menu
205bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos)
e9576ca5 206{
427ff662 207 wxASSERT_MSG( pItem != NULL, wxT("can't append NULL item to the menu") );
e9576ca5 208
e40298d5
JS
209 if ( pItem->IsSeparator() )
210 {
211 if ( pos == (size_t)-1 )
4f74e0d1 212 AppendMenuItemTextWithCFString( MAC_WXHMENU(m_hMenu),
90f58090 213 CFSTR(""), kMenuItemAttrSeparator, 0,NULL);
e40298d5 214 else
4f74e0d1 215 InsertMenuItemTextWithCFString( MAC_WXHMENU(m_hMenu),
90f58090 216 CFSTR(""), pos, kMenuItemAttrSeparator, 0);
e40298d5 217 }
58751a86 218 else
e40298d5
JS
219 {
220 wxMenu *pSubMenu = pItem->GetSubMenu() ;
221 if ( pSubMenu != NULL )
222 {
5977edb9 223 wxASSERT_MSG( pSubMenu->m_hMenu != NULL , wxT("invalid submenu added"));
e40298d5 224 pSubMenu->m_menuParent = this ;
58751a86 225
4224f059 226 if (wxMenuBar::MacGetInstalledMenuBar() == GetMenuBar())
d46342af 227 pSubMenu->MacBeforeDisplay( true ) ;
58751a86 228
e40298d5 229 if ( pos == (size_t)-1 )
9a9c35d3 230 UMAAppendSubMenuItem(MAC_WXHMENU(m_hMenu), wxStripMenuCodes(pItem->GetItemLabel()), wxFont::GetDefaultEncoding(), pSubMenu->m_macMenuId);
e40298d5 231 else
9a9c35d3 232 UMAInsertSubMenuItem(MAC_WXHMENU(m_hMenu), wxStripMenuCodes(pItem->GetItemLabel()), wxFont::GetDefaultEncoding(), pos, pSubMenu->m_macMenuId);
5977edb9 233
e40298d5
JS
234 pItem->UpdateItemBitmap() ;
235 pItem->UpdateItemStatus() ;
236 }
237 else
238 {
239 if ( pos == (size_t)-1 )
240 {
a9412f8f 241 UMAAppendMenuItem(MAC_WXHMENU(m_hMenu), wxT("a") , wxFont::GetDefaultEncoding() );
e40298d5
JS
242 pos = CountMenuItems(MAC_WXHMENU(m_hMenu)) ;
243 }
244 else
245 {
4ab107d7
SC
246 // MacOS counts menu items from 1 and inserts after, therefore having the
247 // same effect as wx 0 based and inserting before, we must correct pos
248 // after however for updates to be correct
a9412f8f 249 UMAInsertMenuItem(MAC_WXHMENU(m_hMenu), wxT("a"), wxFont::GetDefaultEncoding(), pos);
4ab107d7 250 pos += 1 ;
e40298d5 251 }
e4db172a 252
ca71e3ae 253 SetMenuItemCommandID( MAC_WXHMENU(m_hMenu) , pos , wxIdToMacCommand ( pItem->GetId() ) ) ;
4f74e0d1 254 SetMenuItemRefCon( MAC_WXHMENU(m_hMenu) , pos , (URefCon) pItem ) ;
e40298d5
JS
255 pItem->UpdateItemText() ;
256 pItem->UpdateItemBitmap() ;
257 pItem->UpdateItemStatus() ;
258
5977edb9 259 if ( pItem->GetId() == idMenuTitle )
e40298d5 260 UMAEnableMenuItem(MAC_WXHMENU(m_hMenu) , pos , false ) ;
e40298d5
JS
261 }
262 }
5977edb9 263
e7549107 264 // if we're already attached to the menubar, we must update it
b6d4a1af 265 if ( IsAttached() && GetMenuBar()->IsAttached() )
4224f059 266 GetMenuBar()->Refresh();
5977edb9 267
902725ee 268 return true ;
e9576ca5
SC
269}
270
7c15086c
SC
271void wxMenu::EndRadioGroup()
272{
273 // we're not inside a radio group any longer
274 m_startRadioGroup = -1;
275}
276
9add9367 277wxMenuItem* wxMenu::DoAppend(wxMenuItem *item)
e9576ca5 278{
9add9367 279 wxCHECK_MSG( item, NULL, _T("NULL item in wxMenu::DoAppend") );
7c15086c 280
902725ee 281 bool check = false;
7c15086c
SC
282
283 if ( item->GetKind() == wxITEM_RADIO )
284 {
285 int count = GetMenuItemCount();
286
287 if ( m_startRadioGroup == -1 )
288 {
289 // start a new radio group
290 m_startRadioGroup = count;
291
292 // for now it has just one element
293 item->SetAsRadioGroupStart();
294 item->SetRadioGroupEnd(m_startRadioGroup);
295
296 // ensure that we have a checked item in the radio group
902725ee 297 check = true;
7c15086c
SC
298 }
299 else // extend the current radio group
300 {
301 // we need to update its end item
302 item->SetRadioGroupStart(m_startRadioGroup);
71f2fb52 303 wxMenuItemList::compatibility_iterator node = GetMenuItems().Item(m_startRadioGroup);
7c15086c
SC
304
305 if ( node )
306 {
307 node->GetData()->SetRadioGroupEnd(count);
308 }
309 else
310 {
311 wxFAIL_MSG( _T("where is the radio group start item?") );
312 }
313 }
314 }
315 else // not a radio item
316 {
317 EndRadioGroup();
318 }
319
320 if ( !wxMenuBase::DoAppend(item) || !DoInsertOrAppend(item) )
9add9367 321 return NULL;
7c15086c
SC
322
323 if ( check )
7c15086c 324 // check the item initially
902725ee 325 item->Check(true);
7c15086c 326
9add9367 327 return item;
e9576ca5
SC
328}
329
9add9367 330wxMenuItem* wxMenu::DoInsert(size_t pos, wxMenuItem *item)
e9576ca5 331{
9add9367
RD
332 if (wxMenuBase::DoInsert(pos, item) && DoInsertOrAppend(item, pos))
333 return item;
5977edb9
DS
334
335 return NULL;
e9576ca5
SC
336}
337
e7549107 338wxMenuItem *wxMenu::DoRemove(wxMenuItem *item)
e9576ca5 339{
e7549107
SC
340 // we need to find the items position in the child list
341 size_t pos;
71f2fb52 342 wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst();
5977edb9 343
e7549107
SC
344 for ( pos = 0; node; pos++ )
345 {
346 if ( node->GetData() == item )
347 break;
e9576ca5 348
e7549107 349 node = node->GetNext();
e9576ca5
SC
350 }
351
e7549107
SC
352 // DoRemove() (unlike Remove) can only be called for existing item!
353 wxCHECK_MSG( node, NULL, wxT("bug in wxMenu::Remove logic") );
519cb848 354
e40298d5 355 ::DeleteMenuItem(MAC_WXHMENU(m_hMenu) , pos + 1);
e9576ca5 356
b6d4a1af 357 if ( IsAttached() && GetMenuBar()->IsAttached() )
7c15086c 358 // otherwise, the change won't be visible
4224f059 359 GetMenuBar()->Refresh();
e9576ca5 360
e7549107
SC
361 // and from internal data structures
362 return wxMenuBase::DoRemove(item);
e9576ca5
SC
363}
364
e9576ca5
SC
365void wxMenu::SetTitle(const wxString& label)
366{
902725ee 367 m_title = label ;
a9412f8f 368 UMASetMenuTitle(MAC_WXHMENU(m_hMenu) , label , wxFont::GetDefaultEncoding() ) ;
e9576ca5 369}
902725ee 370
e7549107 371bool wxMenu::ProcessCommand(wxCommandEvent & event)
e9576ca5 372{
902725ee 373 bool processed = false;
e9576ca5 374
e9576ca5 375 // Try the menu's event handler
902725ee 376 if ( /* !processed && */ GetEventHandler())
e7549107 377 processed = GetEventHandler()->ProcessEvent(event);
519cb848 378
5977edb9
DS
379 // Try the window the menu was popped up from
380 // (and up through the hierarchy)
e7549107
SC
381 wxWindow *win = GetInvokingWindow();
382 if ( !processed && win )
383 processed = win->GetEventHandler()->ProcessEvent(event);
384
385 return processed;
386}
387
e7549107
SC
388// ---------------------------------------------------------------------------
389// other
390// ---------------------------------------------------------------------------
391
e7549107
SC
392wxWindow *wxMenu::GetWindow() const
393{
394 if ( m_invokingWindow != NULL )
395 return m_invokingWindow;
4224f059
DE
396 else if ( GetMenuBar() != NULL)
397 return (wxWindow *) GetMenuBar()->GetFrame();
e7549107
SC
398
399 return NULL;
400}
519cb848 401
58751a86 402// helper functions returning the mac menu position for a certain item, note that this is
519cb848
SC
403// mac-wise 1 - based, i.e. the first item has index 1 whereas on MSWin it has pos 0
404
58751a86 405int wxMenu::MacGetIndexFromId( int id )
519cb848 406{
e7549107 407 size_t pos;
71f2fb52 408 wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst();
e7549107 409 for ( pos = 0; node; pos++ )
519cb848 410 {
e7549107
SC
411 if ( node->GetData()->GetId() == id )
412 break;
519cb848 413
e7549107
SC
414 node = node->GetNext();
415 }
58751a86 416
519cb848 417 if (!node)
e40298d5 418 return 0;
58751a86 419
e40298d5 420 return pos + 1 ;
519cb848
SC
421}
422
58751a86 423int wxMenu::MacGetIndexFromItem( wxMenuItem *pItem )
519cb848 424{
e7549107 425 size_t pos;
71f2fb52 426 wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst();
e7549107 427 for ( pos = 0; node; pos++ )
519cb848 428 {
e7549107
SC
429 if ( node->GetData() == pItem )
430 break;
431
432 node = node->GetNext();
519cb848
SC
433 }
434
435 if (!node)
e40298d5 436 return 0;
58751a86 437
e40298d5 438 return pos + 1 ;
519cb848
SC
439}
440
58751a86 441void wxMenu::MacEnableMenu( bool bDoEnable )
519cb848 442{
e40298d5 443 UMAEnableMenuItem(MAC_WXHMENU(m_hMenu) , 0 , bDoEnable ) ;
58751a86 444
e40298d5 445 ::DrawMenuBar() ;
519cb848
SC
446}
447
d46342af 448// MacOS needs to know about submenus somewhere within this menu
5977edb9
DS
449// before it can be displayed, also hide special menu items
450// like preferences that are handled by the OS
58751a86 451void wxMenu::MacBeforeDisplay( bool isSubMenu )
d46342af
SC
452{
453 wxMenuItem* previousItem = NULL ;
5be55d56 454 size_t pos ;
71f2fb52 455 wxMenuItemList::compatibility_iterator node;
d46342af 456 wxMenuItem *item;
5977edb9 457
58751a86 458 for (pos = 0, node = GetMenuItems().GetFirst(); node; node = node->GetNext(), pos++)
d46342af
SC
459 {
460 item = (wxMenuItem *)node->GetData();
461 wxMenu* subMenu = item->GetSubMenu() ;
58751a86 462 if (subMenu)
d46342af
SC
463 {
464 subMenu->MacBeforeDisplay( true ) ;
465 }
fa4a6942 466 else // normal item
d46342af 467 {
6524e8f0
SC
468 // what we do here is to hide the special items which are
469 // shown in the application menu anyhow -- it doesn't make
470 // sense to show them in their normal place as well
471 if ( item->GetId() == wxApp::s_macAboutMenuItemId ||
6524e8f0 472 item->GetId() == wxApp::s_macPreferencesMenuItemId ||
03561a3c 473 item->GetId() == wxApp::s_macExitMenuItemId )
902725ee 474
d46342af 475 {
6524e8f0
SC
476 ChangeMenuItemAttributes( MAC_WXHMENU( GetHMenu() ),
477 pos + 1, kMenuItemAttrHidden, 0 );
478
479 // also check for a separator which was used just to
480 // separate this item from the others, so don't leave
481 // separator at the menu start or end nor 2 consecutive
482 // separators
483 wxMenuItemList::compatibility_iterator nextNode = node->GetNext();
484 wxMenuItem *next = nextNode ? nextNode->GetData() : NULL;
485
486 size_t posSeptoHide;
487 if ( !previousItem && next && next->IsSeparator() )
d46342af 488 {
6524e8f0
SC
489 // next (i.e. second as we must be first) item is
490 // the separator to hide
491 wxASSERT_MSG( pos == 0, _T("should be the menu start") );
492 posSeptoHide = 2;
493 }
494 else if ( GetMenuItems().GetCount() == pos + 1 &&
495 previousItem != NULL &&
496 previousItem->IsSeparator() )
497 {
498 // prev item is a trailing separator we want to hide
499 posSeptoHide = pos;
500 }
501 else if ( previousItem && previousItem->IsSeparator() &&
502 next && next->IsSeparator() )
503 {
504 // two consecutive separators, this is one too many
505 posSeptoHide = pos;
506 }
507 else // no separators to hide
508 {
509 posSeptoHide = 0;
510 }
fa4a6942 511
6524e8f0
SC
512 if ( posSeptoHide )
513 {
514 // hide the separator as well
515 ChangeMenuItemAttributes( MAC_WXHMENU( GetHMenu() ),
516 posSeptoHide,
517 kMenuItemAttrHidden,
518 0 );
d46342af
SC
519 }
520 }
d46342af 521 }
5977edb9 522
d46342af
SC
523 previousItem = item ;
524 }
525
526 if ( isSubMenu )
527 ::InsertMenu(MAC_WXHMENU( GetHMenu()), -1);
d46342af 528}
5977edb9 529
d46342af 530// undo all changes from the MacBeforeDisplay call
58751a86 531void wxMenu::MacAfterDisplay( bool isSubMenu )
d46342af
SC
532{
533 if ( isSubMenu )
534 ::DeleteMenu(MacGetMenuId());
535
71f2fb52 536 wxMenuItemList::compatibility_iterator node;
d46342af 537 wxMenuItem *item;
5977edb9 538
716d0327 539 for (node = GetMenuItems().GetFirst(); node; node = node->GetNext())
d46342af
SC
540 {
541 item = (wxMenuItem *)node->GetData();
542 wxMenu* subMenu = item->GetSubMenu() ;
58751a86 543 if (subMenu)
d46342af
SC
544 {
545 subMenu->MacAfterDisplay( true ) ;
546 }
547 else
548 {
549 // no need to undo hidings
550 }
d46342af
SC
551 }
552}
553
6239ee05
SC
554wxInt32 wxMenu::MacHandleCommandProcess( wxMenuItem* item, int id, wxWindow* targetWindow )
555{
556 OSStatus result = eventNotHandledErr ;
557 if (item->IsCheckable())
558 item->Check( !item->IsChecked() ) ;
559
560 if ( SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) )
561 result = noErr ;
562 else
563 {
564 if ( targetWindow != NULL )
565 {
566 wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED , id);
567 event.SetEventObject(targetWindow);
568 event.SetInt(item->IsCheckable() ? item->IsChecked() : -1);
569
570 if ( targetWindow->GetEventHandler()->ProcessEvent(event) )
571 result = noErr ;
572 }
573 }
574 return result;
575}
576
577wxInt32 wxMenu::MacHandleCommandUpdateStatus( wxMenuItem* item, int id, wxWindow* targetWindow )
578{
579 OSStatus result = eventNotHandledErr ;
580 wxUpdateUIEvent event(id);
581 event.SetEventObject( this );
582
583 bool processed = false;
584
585 // Try the menu's event handler
586 {
587 wxEvtHandler *handler = GetEventHandler();
588 if ( handler )
589 processed = handler->ProcessEvent(event);
590 }
591
592 // Try the window the menu was popped up from
593 // (and up through the hierarchy)
594 if ( !processed )
595 {
596 const wxMenuBase *menu = this;
597 while ( menu )
598 {
599 wxWindow *win = menu->GetInvokingWindow();
600 if ( win )
601 {
602 processed = win->GetEventHandler()->ProcessEvent(event);
603 break;
604 }
605
606 menu = menu->GetParent();
607 }
608 }
609
610 if ( !processed && targetWindow != NULL)
611 {
612 processed = targetWindow->GetEventHandler()->ProcessEvent(event);
613 }
614
615 if ( processed )
616 {
617 // if anything changed, update the changed attribute
618 if (event.GetSetText())
619 SetLabel(id, event.GetText());
620 if (event.GetSetChecked())
621 Check(id, event.GetChecked());
622 if (event.GetSetEnabled())
623 Enable(id, event.GetEnabled());
624
625 result = noErr ;
626 }
627 return result;
628}
629
e9576ca5 630// Menu Bar
519cb848 631
58751a86 632/*
519cb848
SC
633
634Mac Implementation note :
635
636The Mac has only one global menubar, so we attempt to install the currently
637active menubar from a frame, we currently don't take into account mdi-frames
638which would ask for menu-merging
639
58751a86 640Secondly there is no mac api for changing a menubar that is not the current
519cb848
SC
641menubar, so we have to wait for preparing the actual menubar until the
642wxMenubar is to be used
643
58751a86 644We can in subsequent versions use MacInstallMenuBar to provide some sort of
519cb848
SC
645auto-merge for MDI in case this will be necessary
646
647*/
648
649wxMenuBar* wxMenuBar::s_macInstalledMenuBar = NULL ;
1b1d2207 650wxMenuBar* wxMenuBar::s_macCommonMenuBar = NULL ;
22e3c5bd
SC
651bool wxMenuBar::s_macAutoWindowMenu = true ;
652WXHMENU wxMenuBar::s_macWindowMenuHandle = NULL ;
519cb848 653
e7549107 654void wxMenuBar::Init()
e9576ca5
SC
655{
656 m_eventHandler = this;
e9576ca5 657 m_menuBarFrame = NULL;
7c15086c 658 m_invokingWindow = (wxWindow*) NULL;
e9576ca5
SC
659}
660
51abe921
SC
661wxMenuBar::wxMenuBar()
662{
663 Init();
664}
665
666wxMenuBar::wxMenuBar( long WXUNUSED(style) )
667{
668 Init();
669}
670
294ea16d 671wxMenuBar::wxMenuBar(size_t count, wxMenu *menus[], const wxString titles[], long WXUNUSED(style))
e9576ca5 672{
e7549107
SC
673 Init();
674
675 m_titles.Alloc(count);
676
d2103c8c 677 for ( size_t i = 0; i < count; i++ )
e7549107
SC
678 {
679 m_menus.Append(menus[i]);
680 m_titles.Add(titles[i]);
681
682 menus[i]->Attach(this);
683 }
e9576ca5
SC
684}
685
686wxMenuBar::~wxMenuBar()
687{
1b1d2207
DE
688 if (s_macCommonMenuBar == this)
689 s_macCommonMenuBar = NULL;
5977edb9 690
e40298d5
JS
691 if (s_macInstalledMenuBar == this)
692 {
693 ::ClearMenuBar();
694 s_macInstalledMenuBar = NULL;
695 }
e7549107
SC
696}
697
6d6da89c 698void wxMenuBar::Refresh(bool WXUNUSED(eraseBackground), const wxRect *WXUNUSED(rect))
e7549107
SC
699{
700 wxCHECK_RET( IsAttached(), wxT("can't refresh unatteched menubar") );
e9576ca5 701
e7549107 702 DrawMenuBar();
e9576ca5
SC
703}
704
58751a86 705void wxMenuBar::MacInstallMenuBar()
519cb848 706{
2b8a6962
GD
707 if ( s_macInstalledMenuBar == this )
708 return ;
58751a86 709
53d92341 710 MenuBarHandle menubar = NULL ;
5977edb9 711
53d92341
SC
712#if TARGET_API_MAC_OSX
713 menubar = NewHandleClear( 6 /* sizeof( MenuBarHeader ) */ ) ;
714#else
715 menubar = NewHandleClear( 12 ) ;
716 (*menubar)[3] = 0x0a ;
717#endif
5977edb9 718
2b8a6962 719 ::SetMenuBar( menubar ) ;
dd05f811 720 DisposeMenuBar( menubar ) ;
cda73c27 721 MenuHandle appleMenu = NULL ;
cda73c27
SC
722
723 verify_noerr( CreateNewMenu( kwxMacAppleMenuId , 0 , &appleMenu ) ) ;
4f74e0d1 724 verify_noerr( SetMenuTitleWithCFString( appleMenu , CFSTR( "\x14" ) ) );
23c6ddc8 725
262ce38a
KH
726 // Add About/Preferences separator only on OS X
727 // KH/RN: Separator is always present on 10.3 but not on 10.2
728 // However, the change from 10.2 to 10.3 suggests it is preferred
729#if TARGET_API_MAC_OSX
4f74e0d1 730 InsertMenuItemTextWithCFString( appleMenu,
90f58090 731 CFSTR(""), 0, kMenuItemAttrSeparator, 0);
262ce38a 732#endif
4f74e0d1 733 InsertMenuItemTextWithCFString( appleMenu,
90f58090 734 CFSTR("About..."), 0, 0, 0);
cda73c27
SC
735 MacInsertMenu( appleMenu , 0 ) ;
736
4dd25308
VZ
737 // if we have a mac help menu, clean it up before adding new items
738 MenuHandle helpMenuHandle ;
739 MenuItemIndex firstUserHelpMenuItem ;
902725ee 740
4dd25308 741 if ( UMAGetHelpMenuDontCreate( &helpMenuHandle , &firstUserHelpMenuItem) == noErr )
e40298d5 742 {
4dd25308
VZ
743 for ( int i = CountMenuItems( helpMenuHandle ) ; i >= firstUserHelpMenuItem ; --i )
744 DeleteMenuItem( helpMenuHandle , i ) ;
745 }
746 else
747 {
748 helpMenuHandle = NULL ;
e40298d5 749 }
5977edb9 750
03561a3c 751 if ( wxApp::s_macPreferencesMenuItemId)
e40298d5
JS
752 {
753 wxMenuItem *item = FindItem( wxApp::s_macPreferencesMenuItemId , NULL ) ;
754 if ( item == NULL || !(item->IsEnabled()) )
755 DisableMenuCommand( NULL , kHICommandPreferences ) ;
756 else
757 EnableMenuCommand( NULL , kHICommandPreferences ) ;
758 }
5977edb9 759
3e275c2d
KH
760 // Unlike preferences which may or may not exist, the Quit item should be always
761 // enabled unless it is added by the application and then disabled, otherwise
762 // a program would be required to add an item with wxID_EXIT in order to get the
763 // Quit menu item to be enabled, which seems a bit burdensome.
03561a3c 764 if ( wxApp::s_macExitMenuItemId)
e9626c1b
KH
765 {
766 wxMenuItem *item = FindItem( wxApp::s_macExitMenuItemId , NULL ) ;
3e275c2d 767 if ( item != NULL && !(item->IsEnabled()) )
e9626c1b
KH
768 DisableMenuCommand( NULL , kHICommandQuit ) ;
769 else
770 EnableMenuCommand( NULL , kHICommandQuit ) ;
771 }
5977edb9 772
4dd25308
VZ
773 wxString strippedHelpMenuTitle = wxStripMenuCodes( wxApp::s_macHelpMenuTitleName ) ;
774 wxString strippedTranslatedHelpMenuTitle = wxStripMenuCodes( wxString( _("&Help") ) ) ;
6524e8f0 775 wxMenuList::compatibility_iterator menuIter = m_menus.GetFirst();
6524e8f0
SC
776 for (size_t i = 0; i < m_menus.GetCount(); i++, menuIter = menuIter->GetNext())
777 {
71f2fb52 778 wxMenuItemList::compatibility_iterator node;
2b5f62a0 779 wxMenuItem *item;
71f2fb52 780 wxMenu* menu = menuIter->GetData() , *subMenu = NULL ;
4dd25308 781 wxString strippedMenuTitle = wxStripMenuCodes(m_titles[i]);
e40298d5 782
4dd25308 783 if ( strippedMenuTitle == wxT("?") || strippedMenuTitle == strippedHelpMenuTitle || strippedMenuTitle == strippedTranslatedHelpMenuTitle )
e40298d5 784 {
716d0327 785 for (node = menu->GetMenuItems().GetFirst(); node; node = node->GetNext())
e40298d5 786 {
6524e8f0
SC
787 item = (wxMenuItem *)node->GetData();
788 subMenu = item->GetSubMenu() ;
58751a86 789 if (subMenu)
e40298d5
JS
790 {
791 // we don't support hierarchical menus in the help menu yet
792 }
58751a86 793 else
e40298d5 794 {
6524e8f0
SC
795 if ( item->GetId() != wxApp::s_macAboutMenuItemId )
796 {
4dd25308
VZ
797 // we have found a user help menu and an item other than the about item,
798 // so we can create the mac help menu now, if we haven't created it yet
799 if ( helpMenuHandle == NULL )
6524e8f0 800 {
4dd25308 801 if ( UMAGetHelpMenu( &helpMenuHandle , &firstUserHelpMenuItem) != noErr )
6524e8f0 802 {
4dd25308 803 helpMenuHandle = NULL ;
6524e8f0 804 break ;
902725ee 805 }
6524e8f0
SC
806 }
807 }
5977edb9 808
e40298d5
JS
809 if ( item->IsSeparator() )
810 {
4dd25308
VZ
811 if ( helpMenuHandle )
812 AppendMenuItemTextWithCFString( helpMenuHandle,
90f58090 813 CFSTR(""), kMenuItemAttrSeparator, 0,NULL);
e40298d5
JS
814 }
815 else
816 {
90527a50 817 wxAcceleratorEntry*
9a9c35d3 818 entry = wxAcceleratorEntry::Create( item->GetItemLabel() ) ;
e40298d5
JS
819
820 if ( item->GetId() == wxApp::s_macAboutMenuItemId )
58751a86 821 {
6524e8f0
SC
822 // this will be taken care of below
823 }
e40298d5
JS
824 else
825 {
4dd25308 826 if ( helpMenuHandle )
e40298d5 827 {
9a9c35d3 828 UMAAppendMenuItem(helpMenuHandle, wxStripMenuCodes(item->GetItemLabel()) , wxFont::GetDefaultEncoding(), entry);
4dd25308
VZ
829 SetMenuItemCommandID( helpMenuHandle , CountMenuItems(helpMenuHandle) , wxIdToMacCommand ( item->GetId() ) ) ;
830 SetMenuItemRefCon( helpMenuHandle , CountMenuItems(helpMenuHandle) , (URefCon) item ) ;
e40298d5
JS
831 }
832 }
58751a86 833
e40298d5
JS
834 delete entry ;
835 }
836 }
837 }
838 }
90f58090
VZ
839
840 else if ( ( m_titles[i] == wxT("Window") || m_titles[i] == wxT("&Window") )
e608ff58 841 && GetAutoWindowMenu() )
90f58090 842 {
e608ff58
KO
843 if ( MacGetWindowMenuHMenu() == NULL )
844 {
845 CreateStandardWindowMenu( 0 , (MenuHandle*) &s_macWindowMenuHandle ) ;
846 }
90f58090 847
e608ff58
KO
848 MenuRef wm = (MenuRef)MacGetWindowMenuHMenu();
849 if ( wm == NULL )
850 break;
90f58090 851
e608ff58
KO
852 // get the insertion point in the standard menu
853 MenuItemIndex winListStart;
90f58090 854 GetIndMenuItemWithCommandID(wm,
e608ff58 855 kHICommandWindowListSeparator, 1, NULL, &winListStart);
90f58090 856
e608ff58
KO
857 // add a separator so that the standard items and the custom items
858 // aren't mixed together, but only if this is the first run
90f58090 859 OSStatus err = GetIndMenuItemWithCommandID(wm,
e608ff58 860 'WXWM', 1, NULL, NULL);
90f58090 861
e608ff58
KO
862 if ( err == menuItemNotFoundErr )
863 {
864 InsertMenuItemTextWithCFString( wm,
865 CFSTR(""), winListStart-1, kMenuItemAttrSeparator, 'WXWM');
866 }
90f58090
VZ
867
868 wxInsertMenuItemsInMenu(menu, wm, winListStart);
e608ff58 869 }
e40298d5
JS
870 else
871 {
a9412f8f 872 UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , m_titles[i], m_font.GetEncoding() ) ;
71f2fb52 873 menu->MacBeforeDisplay(false) ;
90f58090 874
71f2fb52 875 ::InsertMenu(MAC_WXHMENU(_wxMenuAt(m_menus, i)->GetHMenu()), 0);
e40298d5
JS
876 }
877 }
5977edb9 878
6524e8f0
SC
879 // take care of the about menu item wherever it is
880 {
881 wxMenu* aboutMenu ;
882 wxMenuItem *aboutMenuItem = FindItem(wxApp::s_macAboutMenuItemId , &aboutMenu) ;
883 if ( aboutMenuItem )
884 {
90527a50 885 wxAcceleratorEntry*
9a9c35d3
JS
886 entry = wxAcceleratorEntry::Create( aboutMenuItem->GetItemLabel() ) ;
887 UMASetMenuItemText( GetMenuHandle( kwxMacAppleMenuId ) , 1 , wxStripMenuCodes ( aboutMenuItem->GetItemLabel() ) , wxFont::GetDefaultEncoding() );
6524e8f0 888 UMAEnableMenuItem( GetMenuHandle( kwxMacAppleMenuId ) , 1 , true );
ca71e3ae 889 SetMenuItemCommandID( GetMenuHandle( kwxMacAppleMenuId ) , 1 , kHICommandAbout ) ;
4f74e0d1 890 SetMenuItemRefCon(GetMenuHandle( kwxMacAppleMenuId ) , 1 , (URefCon)aboutMenuItem ) ;
6524e8f0
SC
891 UMASetMenuItemShortcut( GetMenuHandle( kwxMacAppleMenuId ) , 1 , entry ) ;
892 }
893 }
5977edb9 894
22e3c5bd
SC
895 if ( GetAutoWindowMenu() )
896 {
897 if ( MacGetWindowMenuHMenu() == NULL )
22e3c5bd 898 CreateStandardWindowMenu( 0 , (MenuHandle*) &s_macWindowMenuHandle ) ;
5977edb9 899
22e3c5bd
SC
900 InsertMenu( (MenuHandle) MacGetWindowMenuHMenu() , 0 ) ;
901 }
5977edb9 902
e40298d5
JS
903 ::DrawMenuBar() ;
904 s_macInstalledMenuBar = this;
519cb848
SC
905}
906
e7549107 907void wxMenuBar::EnableTop(size_t pos, bool enable)
e9576ca5 908{
e7549107 909 wxCHECK_RET( IsAttached(), wxT("doesn't work with unattached menubars") );
5977edb9 910
71f2fb52 911 _wxMenuAt(m_menus, pos)->MacEnableMenu( enable ) ;
e7549107 912 Refresh();
e9576ca5
SC
913}
914
5977edb9 915bool wxMenuBar::Enable(bool enable)
c393c740 916{
5059f192 917 wxCHECK_MSG( IsAttached(), false, wxT("doesn't work with unattached menubars") );
5977edb9 918
c393c740
JS
919 size_t i;
920 for (i = 0; i < GetMenuCount(); i++)
c393c740 921 EnableTop(i, enable);
5977edb9 922
c393c740
JS
923 return true;
924}
925
52af3158 926void wxMenuBar::SetMenuLabel(size_t pos, const wxString& label)
e9576ca5 927{
e7549107 928 wxCHECK_RET( pos < GetMenuCount(), wxT("invalid menu index") );
e9576ca5 929
e7549107 930 m_titles[pos] = label;
e9576ca5 931
e7549107 932 if ( !IsAttached() )
e9576ca5
SC
933 return;
934
71f2fb52
RN
935 _wxMenuAt(m_menus, pos)->SetTitle( label ) ;
936
e40298d5
JS
937 if (wxMenuBar::s_macInstalledMenuBar == this) // are we currently installed ?
938 {
939 ::SetMenuBar( GetMenuBar() ) ;
940 ::InvalMenuBar() ;
941 }
e9576ca5
SC
942}
943
52af3158 944wxString wxMenuBar::GetMenuLabel(size_t pos) const
e9576ca5 945{
e7549107 946 wxCHECK_MSG( pos < GetMenuCount(), wxEmptyString,
52af3158 947 wxT("invalid menu index in wxMenuBar::GetMenuLabel") );
519cb848 948
e7549107 949 return m_titles[pos];
e9576ca5
SC
950}
951
e7549107 952int wxMenuBar::FindMenu(const wxString& title)
e9576ca5 953{
e7549107 954 wxString menuTitle = wxStripMenuCodes(title);
e9576ca5 955
e7549107
SC
956 size_t count = GetMenuCount();
957 for ( size_t i = 0; i < count; i++ )
e9576ca5 958 {
e7549107
SC
959 wxString title = wxStripMenuCodes(m_titles[i]);
960 if ( menuTitle == title )
58751a86 961 return i;
e9576ca5 962 }
e9576ca5 963
e7549107 964 return wxNOT_FOUND;
e9576ca5
SC
965}
966
e7549107
SC
967// ---------------------------------------------------------------------------
968// wxMenuBar construction
969// ---------------------------------------------------------------------------
970
971wxMenu *wxMenuBar::Replace(size_t pos, wxMenu *menu, const wxString& title)
e9576ca5 972{
e7549107
SC
973 wxMenu *menuOld = wxMenuBarBase::Replace(pos, menu, title);
974 if ( !menuOld )
a8fb9ede 975 return NULL;
5977edb9 976
e7549107 977 m_titles[pos] = title;
e9576ca5 978
e7549107 979 if ( IsAttached() )
e9576ca5 980 {
e40298d5
JS
981 if (s_macInstalledMenuBar == this)
982 {
d46342af 983 menuOld->MacAfterDisplay( false ) ;
e40298d5 984 ::DeleteMenu( menuOld->MacGetMenuId() /* m_menus[pos]->MacGetMenuId() */ ) ;
5977edb9
DS
985
986 menu->MacBeforeDisplay( false ) ;
987 UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , title , m_font.GetEncoding() ) ;
988 if ( pos == m_menus.GetCount() - 1)
989 ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , 0 ) ;
990 else
991 ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , _wxMenuAt(m_menus, pos + 1)->MacGetMenuId() ) ;
e40298d5 992 }
e9576ca5 993
e7549107 994 Refresh();
e9576ca5 995 }
5977edb9 996
0f4c4140
SC
997 if (m_invokingWindow)
998 wxMenubarSetInvokingWindow( menu, m_invokingWindow );
e9576ca5 999
e7549107 1000 return menuOld;
e9576ca5
SC
1001}
1002
e7549107 1003bool wxMenuBar::Insert(size_t pos, wxMenu *menu, const wxString& title)
e9576ca5 1004{
e7549107 1005 if ( !wxMenuBarBase::Insert(pos, menu, title) )
902725ee 1006 return false;
e9576ca5 1007
e7549107 1008 m_titles.Insert(title, pos);
e9576ca5 1009
a9412f8f 1010 UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , title , m_font.GetEncoding() ) ;
e7549107 1011
d46342af 1012 if ( IsAttached() && s_macInstalledMenuBar == this )
e9576ca5 1013 {
d46342af 1014 if (s_macInstalledMenuBar == this)
e40298d5 1015 {
d46342af 1016 menu->MacBeforeDisplay( false ) ;
5977edb9 1017
d46342af 1018 if ( pos == (size_t) -1 || pos + 1 == m_menus.GetCount() )
d46342af 1019 ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , 0 ) ;
d46342af 1020 else
71f2fb52 1021 ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , _wxMenuAt(m_menus, pos+1)->MacGetMenuId() ) ;
e40298d5 1022 }
5977edb9 1023
e7549107 1024 Refresh();
e9576ca5 1025 }
5977edb9 1026
0f4c4140
SC
1027 if (m_invokingWindow)
1028 wxMenubarSetInvokingWindow( menu, m_invokingWindow );
e7549107 1029
902725ee 1030 return true;
e9576ca5
SC
1031}
1032
51abe921
SC
1033wxMenu *wxMenuBar::Remove(size_t pos)
1034{
1035 wxMenu *menu = wxMenuBarBase::Remove(pos);
1036 if ( !menu )
1037 return NULL;
1038
1039 if ( IsAttached() )
1040 {
e40298d5 1041 if (s_macInstalledMenuBar == this)
e40298d5 1042 ::DeleteMenu( menu->MacGetMenuId() /* m_menus[pos]->MacGetMenuId() */ ) ;
51abe921 1043
51abe921
SC
1044 Refresh();
1045 }
1046
5fe38474 1047 m_titles.RemoveAt(pos);
51abe921
SC
1048
1049 return menu;
1050}
1051
1052bool wxMenuBar::Append(wxMenu *menu, const wxString& title)
1053{
1054 WXHMENU submenu = menu ? menu->GetHMenu() : 0;
5977edb9 1055 wxCHECK_MSG( submenu, false, wxT("can't append invalid menu to menubar") );
51abe921
SC
1056
1057 if ( !wxMenuBarBase::Append(menu, title) )
902725ee 1058 return false;
51abe921 1059
51abe921 1060 m_titles.Add(title);
58751a86 1061
a9412f8f 1062 UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , title , m_font.GetEncoding() ) ;
51abe921
SC
1063
1064 if ( IsAttached() )
1065 {
e40298d5
JS
1066 if (s_macInstalledMenuBar == this)
1067 {
94c80d52 1068 menu->MacBeforeDisplay( false ) ;
e40298d5
JS
1069 ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , 0 ) ;
1070 }
51abe921
SC
1071
1072 Refresh();
1073 }
1074
0f4c4140 1075 // m_invokingWindow is set after wxFrame::SetMenuBar(). This call enables
7c15086c
SC
1076 // adding menu later on.
1077 if (m_invokingWindow)
1078 wxMenubarSetInvokingWindow( menu, m_invokingWindow );
1079
902725ee 1080 return true;
51abe921
SC
1081}
1082
2b5f62a0
VZ
1083static void wxMenubarUnsetInvokingWindow( wxMenu *menu )
1084{
1085 menu->SetInvokingWindow( (wxWindow*) NULL );
71f2fb52 1086 wxMenuItemList::compatibility_iterator node = menu->GetMenuItems().GetFirst();
5977edb9 1087
2b5f62a0
VZ
1088 while (node)
1089 {
1090 wxMenuItem *menuitem = node->GetData();
1091 if (menuitem->IsSubMenu())
1092 wxMenubarUnsetInvokingWindow( menuitem->GetSubMenu() );
5977edb9 1093
2b5f62a0
VZ
1094 node = node->GetNext();
1095 }
1096}
1097
1098static void wxMenubarSetInvokingWindow( wxMenu *menu, wxWindow *win )
1099{
1100 menu->SetInvokingWindow( win );
5977edb9 1101 wxMenuItem *menuitem;
71f2fb52 1102 wxMenuItemList::compatibility_iterator node = menu->GetMenuItems().GetFirst();
5977edb9 1103
2b5f62a0
VZ
1104 while (node)
1105 {
5977edb9 1106 menuitem = node->GetData();
2b5f62a0
VZ
1107 if (menuitem->IsSubMenu())
1108 wxMenubarSetInvokingWindow( menuitem->GetSubMenu() , win );
5977edb9 1109
2b5f62a0
VZ
1110 node = node->GetNext();
1111 }
1112}
1113
1114void wxMenuBar::UnsetInvokingWindow()
1115{
7c15086c 1116 m_invokingWindow = (wxWindow*) NULL;
5977edb9 1117 wxMenu *menu;
71f2fb52 1118 wxMenuList::compatibility_iterator node = m_menus.GetFirst();
5977edb9 1119
2b5f62a0
VZ
1120 while (node)
1121 {
5977edb9 1122 menu = node->GetData();
2b5f62a0 1123 wxMenubarUnsetInvokingWindow( menu );
5977edb9 1124
2b5f62a0
VZ
1125 node = node->GetNext();
1126 }
1127}
1128
1129void wxMenuBar::SetInvokingWindow(wxFrame *frame)
1130{
7c15086c 1131 m_invokingWindow = frame;
5977edb9 1132 wxMenu *menu;
71f2fb52 1133 wxMenuList::compatibility_iterator node = m_menus.GetFirst();
5977edb9 1134
2b5f62a0
VZ
1135 while (node)
1136 {
5977edb9 1137 menu = node->GetData();
2b5f62a0 1138 wxMenubarSetInvokingWindow( menu, frame );
5977edb9 1139
2b5f62a0
VZ
1140 node = node->GetNext();
1141 }
1142}
1143
90b959ae 1144void wxMenuBar::Detach()
2f1ae414 1145{
90b959ae
SC
1146 wxMenuBarBase::Detach() ;
1147}
2f1ae414 1148
90b959ae
SC
1149void wxMenuBar::Attach(wxFrame *frame)
1150{
1151 wxMenuBarBase::Attach( frame ) ;
2f1ae414 1152}
5977edb9 1153
51abe921
SC
1154// ---------------------------------------------------------------------------
1155// wxMenuBar searching for menu items
1156// ---------------------------------------------------------------------------
1157
1158// Find the itemString in menuString, and return the item id or wxNOT_FOUND
1159int wxMenuBar::FindMenuItem(const wxString& menuString,
1160 const wxString& itemString) const
1161{
1162 wxString menuLabel = wxStripMenuCodes(menuString);
1163 size_t count = GetMenuCount();
1164 for ( size_t i = 0; i < count; i++ )
1165 {
1166 wxString title = wxStripMenuCodes(m_titles[i]);
ef089805 1167 if ( menuLabel == title )
71f2fb52 1168 return _wxMenuAt(m_menus, i)->FindItem(itemString);
51abe921
SC
1169 }
1170
1171 return wxNOT_FOUND;
1172}
1173
1174wxMenuItem *wxMenuBar::FindItem(int id, wxMenu **itemMenu) const
1175{
1176 if ( itemMenu )
1177 *itemMenu = NULL;
1178
1179 wxMenuItem *item = NULL;
1180 size_t count = GetMenuCount();
1181 for ( size_t i = 0; !item && (i < count); i++ )
71f2fb52 1182 item = _wxMenuAt(m_menus, i)->FindItem(id, itemMenu);
51abe921
SC
1183
1184 return item;
1185}