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