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