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