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