]> git.saurik.com Git - wxWidgets.git/blame - src/common/menucmn.cpp
ANSI+Unicode compatibility fixes to wxArrayString
[wxWidgets.git] / src / common / menucmn.cpp
CommitLineData
3dfac970 1///////////////////////////////////////////////////////////////////////////////
0ad966ee 2// Name: src/common/menucmn.cpp
3dfac970
VZ
3// Purpose: wxMenu and wxMenuBar methods common to all ports
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 26.10.99
7// RCS-ID: $Id$
77ffb593 8// Copyright: (c) wxWidgets team
65571936 9// Licence: wxWindows licence
3dfac970
VZ
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
3dfac970
VZ
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
1e6feb95
VZ
27#if wxUSE_MENUS
28
3dfac970 29#ifndef WX_PRECOMP
1e6feb95
VZ
30 #include "wx/intl.h"
31 #include "wx/log.h"
3dfac970
VZ
32 #include "wx/menu.h"
33#endif
34
345319d6
VZ
35#include "wx/stockitem.h"
36
3dfac970
VZ
37// ----------------------------------------------------------------------------
38// template lists
39// ----------------------------------------------------------------------------
40
41#include "wx/listimpl.cpp"
717a57c2 42
259c43f6
VZ
43WX_DEFINE_LIST(wxMenuList)
44WX_DEFINE_LIST(wxMenuItemList)
3dfac970
VZ
45
46// ============================================================================
47// implementation
48// ============================================================================
49
50// ----------------------------------------------------------------------------
c36d4774 51// wxMenuItemBase
ee0a94cf
RR
52// ----------------------------------------------------------------------------
53
54wxMenuItemBase::wxMenuItemBase(wxMenu *parentMenu,
55 int id,
56 const wxString& text,
57 const wxString& help,
58 wxItemKind kind,
59 wxMenu *subMenu)
ee0a94cf
RR
60{
61 wxASSERT_MSG( parentMenu != NULL, wxT("menuitem should have a menu") );
62
63 m_parentMenu = parentMenu;
64 m_subMenu = subMenu;
65 m_isEnabled = true;
66 m_isChecked = false;
67 m_id = id;
68 m_kind = kind;
69 if (m_id == wxID_ANY)
f24b783a 70 m_id = wxNewId();
ee0a94cf
RR
71 if (m_id == wxID_SEPARATOR)
72 m_kind = wxITEM_SEPARATOR;
345319d6
VZ
73
74 SetText(text);
75 SetHelp(help);
ee0a94cf
RR
76}
77
78wxMenuItemBase::~wxMenuItemBase()
79{
80 delete m_subMenu;
81}
82
83#if wxUSE_ACCEL
84
1e6feb95
VZ
85wxAcceleratorEntry *wxMenuItemBase::GetAccel() const
86{
90527a50 87 return wxAcceleratorEntry::Create(GetText());
1e6feb95
VZ
88}
89
717a57c2
VZ
90void wxMenuItemBase::SetAccel(wxAcceleratorEntry *accel)
91{
92 wxString text = m_text.BeforeFirst(wxT('\t'));
93 if ( accel )
94 {
95 text += wxT('\t');
ee0a94cf 96 text += accel->ToString();
717a57c2
VZ
97 }
98
99 SetText(text);
100}
101
102#endif // wxUSE_ACCEL
103
345319d6
VZ
104void wxMenuItemBase::SetText(const wxString& str)
105{
106 m_text = str;
107
108 if ( m_text.empty() && !IsSeparator() )
109 {
110 wxASSERT_MSG( wxIsStockID(GetId()),
111 wxT("A non-stock menu item with an empty label?") );
112 m_text = wxGetStockLabel(GetId(), wxSTOCK_WITH_ACCELERATOR |
113 wxSTOCK_WITH_MNEMONIC);
114 }
115}
116
117void wxMenuItemBase::SetHelp(const wxString& str)
118{
119 m_help = str;
120
121 if ( m_help.empty() && !IsSeparator() && wxIsStockID(GetId()) )
122 {
123 // get a stock help string
124 m_help = wxGetStockHelpString(GetId());
125 }
126}
127
6d971354
RR
128bool wxMenuBase::ms_locked = true;
129
717a57c2
VZ
130// ----------------------------------------------------------------------------
131// wxMenu ctor and dtor
132// ----------------------------------------------------------------------------
133
134void wxMenuBase::Init(long style)
135{
717a57c2
VZ
136 m_menuBar = (wxMenuBar *)NULL;
137 m_menuParent = (wxMenu *)NULL;
138
139 m_invokingWindow = (wxWindow *)NULL;
140 m_style = style;
141 m_clientData = (void *)NULL;
142 m_eventHandler = this;
143}
144
145wxMenuBase::~wxMenuBase()
146{
222ed1d6 147 WX_CLEAR_LIST(wxMenuItemList, m_items);
41efa9a7 148
1e6feb95 149 // Actually, in GTK, the submenus have to get deleted first.
717a57c2
VZ
150}
151
152// ----------------------------------------------------------------------------
153// wxMenu item adding/removing
154// ----------------------------------------------------------------------------
155
1e6feb95
VZ
156void wxMenuBase::AddSubMenu(wxMenu *submenu)
157{
158 wxCHECK_RET( submenu, _T("can't add a NULL submenu") );
159
1e6feb95
VZ
160 submenu->SetParent((wxMenu *)this);
161}
162
9add9367 163wxMenuItem* wxMenuBase::DoAppend(wxMenuItem *item)
717a57c2 164{
9add9367 165 wxCHECK_MSG( item, NULL, wxT("invalid item in wxMenu::Append()") );
717a57c2
VZ
166
167 m_items.Append(item);
1e93ca17 168 item->SetMenu((wxMenu*)this);
1e6feb95
VZ
169 if ( item->IsSubMenu() )
170 {
171 AddSubMenu(item->GetSubMenu());
172 }
717a57c2 173
9add9367 174 return item;
717a57c2
VZ
175}
176
9add9367 177wxMenuItem* wxMenuBase::Insert(size_t pos, wxMenuItem *item)
717a57c2 178{
9add9367 179 wxCHECK_MSG( item, NULL, wxT("invalid item in wxMenu::Insert") );
717a57c2 180
32db328c
VZ
181 if ( pos == GetMenuItemCount() )
182 {
183 return DoAppend(item);
184 }
185 else
186 {
4e32eea1 187 wxCHECK_MSG( pos < GetMenuItemCount(), NULL,
32db328c
VZ
188 wxT("invalid index in wxMenu::Insert") );
189
190 return DoInsert(pos, item);
191 }
717a57c2
VZ
192}
193
9add9367 194wxMenuItem* wxMenuBase::DoInsert(size_t pos, wxMenuItem *item)
717a57c2 195{
9add9367 196 wxCHECK_MSG( item, NULL, wxT("invalid item in wxMenu::Insert()") );
717a57c2 197
222ed1d6 198 wxMenuItemList::compatibility_iterator node = m_items.Item(pos);
4e32eea1 199 wxCHECK_MSG( node, NULL, wxT("invalid index in wxMenu::Insert()") );
717a57c2
VZ
200
201 m_items.Insert(node, item);
1e93ca17 202 item->SetMenu((wxMenu*)this);
1e6feb95
VZ
203 if ( item->IsSubMenu() )
204 {
205 AddSubMenu(item->GetSubMenu());
206 }
717a57c2 207
9add9367 208 return item;
717a57c2
VZ
209}
210
211wxMenuItem *wxMenuBase::Remove(wxMenuItem *item)
212{
213 wxCHECK_MSG( item, NULL, wxT("invalid item in wxMenu::Remove") );
214
215 return DoRemove(item);
216}
217
218wxMenuItem *wxMenuBase::DoRemove(wxMenuItem *item)
219{
222ed1d6 220 wxMenuItemList::compatibility_iterator node = m_items.Find(item);
717a57c2
VZ
221
222 // if we get here, the item is valid or one of Remove() functions is broken
223 wxCHECK_MSG( node, NULL, wxT("bug in wxMenu::Remove logic") );
224
225 // we detach the item, but we do delete the list node (i.e. don't call
226 // DetachNode() here!)
222ed1d6 227 m_items.Erase(node);
717a57c2
VZ
228
229 // item isn't attached to anything any more
1e93ca17 230 item->SetMenu((wxMenu *)NULL);
717a57c2
VZ
231 wxMenu *submenu = item->GetSubMenu();
232 if ( submenu )
233 {
234 submenu->SetParent((wxMenu *)NULL);
082006f3
VZ
235 if ( submenu->IsAttached() )
236 submenu->Detach();
717a57c2
VZ
237 }
238
239 return item;
240}
241
242bool wxMenuBase::Delete(wxMenuItem *item)
243{
4e32eea1 244 wxCHECK_MSG( item, false, wxT("invalid item in wxMenu::Delete") );
717a57c2
VZ
245
246 return DoDelete(item);
247}
248
249bool wxMenuBase::DoDelete(wxMenuItem *item)
250{
251 wxMenuItem *item2 = DoRemove(item);
4e32eea1 252 wxCHECK_MSG( item2, false, wxT("failed to delete menu item") );
717a57c2
VZ
253
254 // don't delete the submenu
255 item2->SetSubMenu((wxMenu *)NULL);
256
257 delete item2;
258
4e32eea1 259 return true;
717a57c2
VZ
260}
261
262bool wxMenuBase::Destroy(wxMenuItem *item)
263{
4e32eea1 264 wxCHECK_MSG( item, false, wxT("invalid item in wxMenu::Destroy") );
717a57c2
VZ
265
266 return DoDestroy(item);
267}
268
269bool wxMenuBase::DoDestroy(wxMenuItem *item)
270{
271 wxMenuItem *item2 = DoRemove(item);
4e32eea1 272 wxCHECK_MSG( item2, false, wxT("failed to delete menu item") );
717a57c2
VZ
273
274 delete item2;
275
4e32eea1 276 return true;
717a57c2
VZ
277}
278
279// ----------------------------------------------------------------------------
280// wxMenu searching for items
281// ----------------------------------------------------------------------------
282
4e32eea1 283// Finds the item id matching the given string, wxNOT_FOUND if not found.
717a57c2
VZ
284int wxMenuBase::FindItem(const wxString& text) const
285{
3b59cdbf 286 wxString label = wxMenuItem::GetLabelFromText(text);
222ed1d6 287 for ( wxMenuItemList::compatibility_iterator node = m_items.GetFirst();
717a57c2
VZ
288 node;
289 node = node->GetNext() )
290 {
291 wxMenuItem *item = node->GetData();
292 if ( item->IsSubMenu() )
293 {
294 int rc = item->GetSubMenu()->FindItem(label);
295 if ( rc != wxNOT_FOUND )
296 return rc;
297 }
adb21613
VZ
298
299 // we execute this code for submenus as well to alllow finding them by
300 // name just like the ordinary items
301 if ( !item->IsSeparator() )
717a57c2
VZ
302 {
303 if ( item->GetLabel() == label )
304 return item->GetId();
305 }
306 }
307
308 return wxNOT_FOUND;
309}
310
311// recursive search for item by id
312wxMenuItem *wxMenuBase::FindItem(int itemId, wxMenu **itemMenu) const
313{
314 if ( itemMenu )
315 *itemMenu = NULL;
316
317 wxMenuItem *item = NULL;
222ed1d6 318 for ( wxMenuItemList::compatibility_iterator node = m_items.GetFirst();
717a57c2
VZ
319 node && !item;
320 node = node->GetNext() )
321 {
322 item = node->GetData();
323
324 if ( item->GetId() == itemId )
325 {
326 if ( itemMenu )
327 *itemMenu = (wxMenu *)this;
328 }
329 else if ( item->IsSubMenu() )
330 {
331 item = item->GetSubMenu()->FindItem(itemId, itemMenu);
332 }
333 else
334 {
335 // don't exit the loop
336 item = NULL;
337 }
338 }
339
340 return item;
341}
342
343// non recursive search
344wxMenuItem *wxMenuBase::FindChildItem(int id, size_t *ppos) const
345{
346 wxMenuItem *item = (wxMenuItem *)NULL;
222ed1d6 347 wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst();
717a57c2
VZ
348
349 size_t pos;
350 for ( pos = 0; node; pos++ )
351 {
1dddf838
VZ
352 if ( node->GetData()->GetId() == id )
353 {
354 item = node->GetData();
355
717a57c2 356 break;
1dddf838 357 }
717a57c2
VZ
358
359 node = node->GetNext();
360 }
361
362 if ( ppos )
363 {
1987af7e 364 *ppos = item ? pos : (size_t)wxNOT_FOUND;
717a57c2
VZ
365 }
366
367 return item;
368}
369
01ebf752
JS
370// find by position
371wxMenuItem* wxMenuBase::FindItemByPosition(size_t position) const
372{
20aed026
VZ
373 wxCHECK_MSG( position < m_items.GetCount(), NULL,
374 _T("wxMenu::FindItemByPosition(): invalid menu index") );
375
376 return m_items.Item( position )->GetData();
01ebf752
JS
377}
378
717a57c2 379// ----------------------------------------------------------------------------
1e6feb95 380// wxMenu helpers used by derived classes
717a57c2
VZ
381// ----------------------------------------------------------------------------
382
383// Update a menu and all submenus recursively. source is the object that has
384// the update event handlers defined for it. If NULL, the menu or associated
385// window will be used.
386void wxMenuBase::UpdateUI(wxEvtHandler* source)
387{
5ce61d9f
RR
388 if (GetInvokingWindow())
389 {
390 // Don't update menus if the parent
391 // frame is about to get deleted
392 wxWindow *tlw = wxGetTopLevelParent( GetInvokingWindow() );
393 if (tlw && wxPendingDelete.Member(tlw))
394 return;
395 }
396
717a57c2
VZ
397 if ( !source && GetInvokingWindow() )
398 source = GetInvokingWindow()->GetEventHandler();
399 if ( !source )
400 source = GetEventHandler();
401 if ( !source )
402 source = this;
403
222ed1d6 404 wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst();
717a57c2
VZ
405 while ( node )
406 {
407 wxMenuItem* item = node->GetData();
408 if ( !item->IsSeparator() )
409 {
410 wxWindowID id = item->GetId();
411 wxUpdateUIEvent event(id);
412 event.SetEventObject( source );
413
414 if ( source->ProcessEvent(event) )
415 {
18afa2ac 416 // if anything changed, update the changed attribute
717a57c2
VZ
417 if (event.GetSetText())
418 SetLabel(id, event.GetText());
419 if (event.GetSetChecked())
420 Check(id, event.GetChecked());
421 if (event.GetSetEnabled())
422 Enable(id, event.GetEnabled());
423 }
424
425 // recurse to the submenus
426 if ( item->GetSubMenu() )
427 item->GetSubMenu()->UpdateUI(source);
428 }
18afa2ac 429 //else: item is a separator (which doesn't process update UI events)
717a57c2
VZ
430
431 node = node->GetNext();
432 }
433}
434
1e6feb95
VZ
435bool wxMenuBase::SendEvent(int id, int checked)
436{
437 wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, id);
438 event.SetEventObject(this);
439 event.SetInt(checked);
440
4e32eea1 441 bool processed = false;
1e6feb95 442
1e6feb95 443 // Try the menu's event handler
902725ee 444 // if ( !processed )
1e6feb95
VZ
445 {
446 wxEvtHandler *handler = GetEventHandler();
447 if ( handler )
448 processed = handler->ProcessEvent(event);
449 }
450
451 // Try the window the menu was popped up from (and up through the
452 // hierarchy)
453 if ( !processed )
454 {
455 const wxMenuBase *menu = this;
456 while ( menu )
457 {
458 wxWindow *win = menu->GetInvokingWindow();
459 if ( win )
460 {
461 processed = win->GetEventHandler()->ProcessEvent(event);
462 break;
463 }
464
465 menu = menu->GetParent();
466 }
467 }
468
469 return processed;
470}
471
472// ----------------------------------------------------------------------------
473// wxMenu attaching/detaching to/from menu bar
474// ----------------------------------------------------------------------------
475
dbdf9a17
DE
476wxMenuBar* wxMenuBase::GetMenuBar() const
477{
478 if(GetParent())
479 return GetParent()->GetMenuBar();
480 return m_menuBar;
481}
482
1e6feb95
VZ
483void wxMenuBase::Attach(wxMenuBarBase *menubar)
484{
485 // use Detach() instead!
486 wxASSERT_MSG( menubar, _T("menu can't be attached to NULL menubar") );
487
488 // use IsAttached() to prevent this from happening
489 wxASSERT_MSG( !m_menuBar, _T("attaching menu twice?") );
490
491 m_menuBar = (wxMenuBar *)menubar;
492}
493
494void wxMenuBase::Detach()
495{
496 // use IsAttached() to prevent this from happening
497 wxASSERT_MSG( m_menuBar, _T("detaching unattached menu?") );
498
499 m_menuBar = NULL;
500}
501
717a57c2
VZ
502// ----------------------------------------------------------------------------
503// wxMenu functions forwarded to wxMenuItem
504// ----------------------------------------------------------------------------
505
506void wxMenuBase::Enable( int id, bool enable )
507{
508 wxMenuItem *item = FindItem(id);
509
510 wxCHECK_RET( item, wxT("wxMenu::Enable: no such item") );
511
512 item->Enable(enable);
513}
514
515bool wxMenuBase::IsEnabled( int id ) const
516{
517 wxMenuItem *item = FindItem(id);
518
4e32eea1 519 wxCHECK_MSG( item, false, wxT("wxMenu::IsEnabled: no such item") );
717a57c2
VZ
520
521 return item->IsEnabled();
522}
523
524void wxMenuBase::Check( int id, bool enable )
525{
526 wxMenuItem *item = FindItem(id);
527
528 wxCHECK_RET( item, wxT("wxMenu::Check: no such item") );
529
530 item->Check(enable);
531}
532
533bool wxMenuBase::IsChecked( int id ) const
534{
535 wxMenuItem *item = FindItem(id);
536
4e32eea1 537 wxCHECK_MSG( item, false, wxT("wxMenu::IsChecked: no such item") );
717a57c2
VZ
538
539 return item->IsChecked();
540}
541
542void wxMenuBase::SetLabel( int id, const wxString &label )
543{
544 wxMenuItem *item = FindItem(id);
545
546 wxCHECK_RET( item, wxT("wxMenu::SetLabel: no such item") );
547
548 item->SetText(label);
549}
550
551wxString wxMenuBase::GetLabel( int id ) const
552{
553 wxMenuItem *item = FindItem(id);
554
525d8583 555 wxCHECK_MSG( item, wxEmptyString, wxT("wxMenu::GetLabel: no such item") );
717a57c2
VZ
556
557 return item->GetText();
558}
559
560void wxMenuBase::SetHelpString( int id, const wxString& helpString )
561{
562 wxMenuItem *item = FindItem(id);
563
564 wxCHECK_RET( item, wxT("wxMenu::SetHelpString: no such item") );
565
566 item->SetHelp( helpString );
567}
568
569wxString wxMenuBase::GetHelpString( int id ) const
570{
571 wxMenuItem *item = FindItem(id);
572
525d8583 573 wxCHECK_MSG( item, wxEmptyString, wxT("wxMenu::GetHelpString: no such item") );
717a57c2
VZ
574
575 return item->GetHelp();
576}
577
578// ----------------------------------------------------------------------------
579// wxMenuBarBase ctor and dtor
3dfac970
VZ
580// ----------------------------------------------------------------------------
581
582wxMenuBarBase::wxMenuBarBase()
583{
1e6feb95
VZ
584 // not attached yet
585 m_menuBarFrame = NULL;
3dfac970
VZ
586}
587
588wxMenuBarBase::~wxMenuBarBase()
589{
222ed1d6 590 WX_CLEAR_LIST(wxMenuList, m_menus);
3dfac970
VZ
591}
592
593// ----------------------------------------------------------------------------
594// wxMenuBar item access: the base class versions manage m_menus list, the
595// derived class should reflect the changes in the real menubar
596// ----------------------------------------------------------------------------
597
598wxMenu *wxMenuBarBase::GetMenu(size_t pos) const
599{
222ed1d6 600 wxMenuList::compatibility_iterator node = m_menus.Item(pos);
3dfac970
VZ
601 wxCHECK_MSG( node, NULL, wxT("bad index in wxMenuBar::GetMenu()") );
602
603 return node->GetData();
604}
605
606bool wxMenuBarBase::Append(wxMenu *menu, const wxString& WXUNUSED(title))
607{
4e32eea1 608 wxCHECK_MSG( menu, false, wxT("can't append NULL menu") );
3dfac970
VZ
609
610 m_menus.Append(menu);
1e6feb95 611 menu->Attach(this);
3dfac970 612
4e32eea1 613 return true;
3dfac970
VZ
614}
615
616bool wxMenuBarBase::Insert(size_t pos, wxMenu *menu,
32db328c 617 const wxString& title)
3dfac970 618{
32db328c
VZ
619 if ( pos == m_menus.GetCount() )
620 {
186baeb2 621 return wxMenuBarBase::Append(menu, title);
32db328c 622 }
1e6feb95 623 else // not at the end
32db328c 624 {
4e32eea1 625 wxCHECK_MSG( menu, false, wxT("can't insert NULL menu") );
3dfac970 626
222ed1d6 627 wxMenuList::compatibility_iterator node = m_menus.Item(pos);
4e32eea1 628 wxCHECK_MSG( node, false, wxT("bad index in wxMenuBar::Insert()") );
3dfac970 629
32db328c 630 m_menus.Insert(node, menu);
1e6feb95 631 menu->Attach(this);
3dfac970 632
4e32eea1 633 return true;
32db328c 634 }
3dfac970
VZ
635}
636
637wxMenu *wxMenuBarBase::Replace(size_t pos, wxMenu *menu,
638 const wxString& WXUNUSED(title))
639{
640 wxCHECK_MSG( menu, NULL, wxT("can't insert NULL menu") );
641
222ed1d6 642 wxMenuList::compatibility_iterator node = m_menus.Item(pos);
3dfac970
VZ
643 wxCHECK_MSG( node, NULL, wxT("bad index in wxMenuBar::Replace()") );
644
645 wxMenu *menuOld = node->GetData();
646 node->SetData(menu);
647
1e6feb95
VZ
648 menu->Attach(this);
649 menuOld->Detach();
650
3dfac970
VZ
651 return menuOld;
652}
653
654wxMenu *wxMenuBarBase::Remove(size_t pos)
655{
222ed1d6 656 wxMenuList::compatibility_iterator node = m_menus.Item(pos);
3dfac970
VZ
657 wxCHECK_MSG( node, NULL, wxT("bad index in wxMenuBar::Remove()") );
658
3dfac970 659 wxMenu *menu = node->GetData();
222ed1d6 660 m_menus.Erase(node);
1e6feb95 661 menu->Detach();
3dfac970 662
3dfac970
VZ
663 return menu;
664}
665
270e8b6a 666int wxMenuBarBase::FindMenu(const wxString& title) const
52130557
VZ
667{
668 wxString label = wxMenuItem::GetLabelFromText(title);
669
670 size_t count = GetMenuCount();
671 for ( size_t i = 0; i < count; i++ )
672 {
673 wxString title2 = GetLabelTop(i);
674 if ( (title2 == title) ||
675 (wxMenuItem::GetLabelFromText(title2) == label) )
676 {
677 // found
2b5f62a0 678 return (int)i;
52130557
VZ
679 }
680 }
681
682 return wxNOT_FOUND;
683
684}
685
1e6feb95
VZ
686// ----------------------------------------------------------------------------
687// wxMenuBar attaching/detaching to/from the frame
688// ----------------------------------------------------------------------------
689
690void wxMenuBarBase::Attach(wxFrame *frame)
691{
692 wxASSERT_MSG( !IsAttached(), wxT("menubar already attached!") );
693
694 m_menuBarFrame = frame;
695}
696
697void wxMenuBarBase::Detach()
698{
699 wxASSERT_MSG( IsAttached(), wxT("detaching unattached menubar") );
700
701 m_menuBarFrame = NULL;
702}
703
704// ----------------------------------------------------------------------------
705// wxMenuBar searching for items
706// ----------------------------------------------------------------------------
707
708wxMenuItem *wxMenuBarBase::FindItem(int id, wxMenu **menu) const
709{
710 if ( menu )
711 *menu = NULL;
712
713 wxMenuItem *item = NULL;
222ed1d6
MB
714 size_t count = GetMenuCount(), i;
715 wxMenuList::const_iterator it;
716 for ( i = 0, it = m_menus.begin(); !item && (i < count); i++, it++ )
1e6feb95 717 {
222ed1d6 718 item = (*it)->FindItem(id, menu);
1e6feb95
VZ
719 }
720
721 return item;
722}
723
724int wxMenuBarBase::FindMenuItem(const wxString& menu, const wxString& item) const
725{
726 wxString label = wxMenuItem::GetLabelFromText(menu);
727
728 int i = 0;
222ed1d6 729 wxMenuList::compatibility_iterator node;
1e6feb95
VZ
730 for ( node = m_menus.GetFirst(); node; node = node->GetNext(), i++ )
731 {
732 if ( label == wxMenuItem::GetLabelFromText(GetLabelTop(i)) )
733 return node->GetData()->FindItem(item);
734 }
735
736 return wxNOT_FOUND;
737}
738
3dfac970
VZ
739// ---------------------------------------------------------------------------
740// wxMenuBar functions forwarded to wxMenuItem
741// ---------------------------------------------------------------------------
742
743void wxMenuBarBase::Enable(int id, bool enable)
744{
745 wxMenuItem *item = FindItem(id);
746
747 wxCHECK_RET( item, wxT("attempt to enable an item which doesn't exist") );
748
749 item->Enable(enable);
750}
751
752void wxMenuBarBase::Check(int id, bool check)
753{
754 wxMenuItem *item = FindItem(id);
755
756 wxCHECK_RET( item, wxT("attempt to check an item which doesn't exist") );
757 wxCHECK_RET( item->IsCheckable(), wxT("attempt to check an uncheckable item") );
758
759 item->Check(check);
760}
761
762bool wxMenuBarBase::IsChecked(int id) const
763{
764 wxMenuItem *item = FindItem(id);
765
4e32eea1 766 wxCHECK_MSG( item, false, wxT("wxMenuBar::IsChecked(): no such item") );
3dfac970
VZ
767
768 return item->IsChecked();
769}
770
771bool wxMenuBarBase::IsEnabled(int id) const
772{
773 wxMenuItem *item = FindItem(id);
774
4e32eea1 775 wxCHECK_MSG( item, false, wxT("wxMenuBar::IsEnabled(): no such item") );
3dfac970
VZ
776
777 return item->IsEnabled();
778}
779
780void wxMenuBarBase::SetLabel(int id, const wxString& label)
781{
782 wxMenuItem *item = FindItem(id);
783
784 wxCHECK_RET( item, wxT("wxMenuBar::SetLabel(): no such item") );
785
786 item->SetText(label);
787}
788
789wxString wxMenuBarBase::GetLabel(int id) const
790{
791 wxMenuItem *item = FindItem(id);
792
793 wxCHECK_MSG( item, wxEmptyString,
794 wxT("wxMenuBar::GetLabel(): no such item") );
795
796 return item->GetText();
797}
798
799void wxMenuBarBase::SetHelpString(int id, const wxString& helpString)
800{
801 wxMenuItem *item = FindItem(id);
802
803 wxCHECK_RET( item, wxT("wxMenuBar::SetHelpString(): no such item") );
804
805 item->SetHelp(helpString);
806}
807
808wxString wxMenuBarBase::GetHelpString(int id) const
809{
810 wxMenuItem *item = FindItem(id);
811
812 wxCHECK_MSG( item, wxEmptyString,
813 wxT("wxMenuBar::GetHelpString(): no such item") );
814
815 return item->GetHelp();
816}
817
4d538595
DS
818void wxMenuBarBase::UpdateMenus( void )
819{
820 wxEvtHandler* source;
821 wxMenu* menu;
822 int nCount = GetMenuCount();
823 for (int n = 0; n < nCount; n++)
824 {
825 menu = GetMenu( n );
826 if (menu != NULL)
827 {
828 source = menu->GetEventHandler();
829 if (source != NULL)
830 menu->UpdateUI( source );
831 }
832 }
833}
834
1e6feb95 835#endif // wxUSE_MENUS