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