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