1
///////////////////////////////////////////////////////////////////////////////
2
// Name: src/common/menucmn.cpp
3
// Purpose: wxMenu and wxMenuBar methods common to all ports
4
// Author: Vadim Zeitlin
7
// Copyright: (c) wxWidgets team
8
// Licence: wxWindows licence
9
///////////////////////////////////////////////////////////////////////////////
11
// ============================================================================
13
// ============================================================================
15
// ----------------------------------------------------------------------------
17
// ----------------------------------------------------------------------------
19
// For compilers that support precompilation, includes "wx.h".
20
#include "wx/wxprec.h"
35
#include "wx/stockitem.h"
37
// ----------------------------------------------------------------------------
39
// ----------------------------------------------------------------------------
41
#include "wx/listimpl.cpp"
43
WX_DEFINE_LIST(wxMenuList)
44
WX_DEFINE_LIST(wxMenuItemList)
46
// ============================================================================
48
// ============================================================================
50
// ----------------------------------------------------------------------------
51
// XTI for wxMenu(Bar)
52
// ----------------------------------------------------------------------------
54
wxDEFINE_FLAGS( wxMenuStyle )
55
wxBEGIN_FLAGS( wxMenuStyle )
56
wxFLAGS_MEMBER(wxMENU_TEAROFF)
57
wxEND_FLAGS( wxMenuStyle )
59
wxIMPLEMENT_DYNAMIC_CLASS_XTI(wxMenu, wxEvtHandler, "wx/menu.h")
60
wxCOLLECTION_TYPE_INFO( wxMenuItem *, wxMenuItemList ) ;
62
#if wxUSE_EXTENDED_RTTI
63
template<> void wxCollectionToVariantArray( wxMenuItemList const &theList,
66
wxListCollectionToAnyList<wxMenuItemList::compatibility_iterator>( theList, value ) ;
70
wxBEGIN_PROPERTIES_TABLE(wxMenu)
71
wxEVENT_PROPERTY( Select, wxEVT_MENU, wxCommandEvent)
73
wxPROPERTY( Title, wxString, SetTitle, GetTitle, wxString(), \
74
0 /*flags*/, wxT("Helpstring"), wxT("group") )
76
wxREADONLY_PROPERTY_FLAGS( MenuStyle, wxMenuStyle, long, GetStyle, \
77
wxEMPTY_PARAMETER_VALUE, 0 /*flags*/, wxT("Helpstring"), \
78
wxT("group")) // style
80
wxPROPERTY_COLLECTION( MenuItems, wxMenuItemList, wxMenuItem*, Append, \
81
GetMenuItems, 0 /*flags*/, wxT("Helpstring"), wxT("group"))
82
wxEND_PROPERTIES_TABLE()
84
wxEMPTY_HANDLERS_TABLE(wxMenu)
86
wxDIRECT_CONSTRUCTOR_2( wxMenu, wxString, Title, long, MenuStyle )
88
wxDEFINE_FLAGS( wxMenuBarStyle )
90
wxBEGIN_FLAGS( wxMenuBarStyle )
91
wxFLAGS_MEMBER(wxMB_DOCKABLE)
92
wxEND_FLAGS( wxMenuBarStyle )
94
#if wxUSE_EXTENDED_RTTI
95
// the negative id would lead the window (its superclass !) to
96
// vetoe streaming out otherwise
97
bool wxMenuBarStreamingCallback( const wxObject *WXUNUSED(object), wxObjectWriter *,
98
wxObjectWriterCallback *, const wxStringToAnyHashMap & )
104
wxIMPLEMENT_DYNAMIC_CLASS_XTI_CALLBACK(wxMenuBar, wxWindow, "wx/menu.h", \
105
wxMenuBarStreamingCallback)
108
#if wxUSE_EXTENDED_RTTI
109
WX_DEFINE_LIST( wxMenuInfoHelperList )
111
wxIMPLEMENT_DYNAMIC_CLASS_XTI(wxMenuInfoHelper, wxObject, "wx/menu.h")
113
wxBEGIN_PROPERTIES_TABLE(wxMenuInfoHelper)
114
wxREADONLY_PROPERTY( Menu, wxMenu*, GetMenu, wxEMPTY_PARAMETER_VALUE, \
115
0 /*flags*/, wxT("Helpstring"), wxT("group"))
117
wxREADONLY_PROPERTY( Title, wxString, GetTitle, wxString(), \
118
0 /*flags*/, wxT("Helpstring"), wxT("group"))
119
wxEND_PROPERTIES_TABLE()
121
wxEMPTY_HANDLERS_TABLE(wxMenuInfoHelper)
123
wxCONSTRUCTOR_2( wxMenuInfoHelper, wxMenu*, Menu, wxString, Title )
125
wxCOLLECTION_TYPE_INFO( wxMenuInfoHelper *, wxMenuInfoHelperList ) ;
127
template<> void wxCollectionToVariantArray( wxMenuInfoHelperList const &theList,
130
wxListCollectionToAnyList<wxMenuInfoHelperList::compatibility_iterator>( theList, value ) ;
135
wxBEGIN_PROPERTIES_TABLE(wxMenuBar)
136
wxPROPERTY_COLLECTION( MenuInfos, wxMenuInfoHelperList, wxMenuInfoHelper*, AppendMenuInfo, \
137
GetMenuInfos, 0 /*flags*/, wxT("Helpstring"), wxT("group"))
138
wxEND_PROPERTIES_TABLE()
140
wxEMPTY_HANDLERS_TABLE(wxMenuBar)
142
wxCONSTRUCTOR_DUMMY( wxMenuBar )
144
#if wxUSE_EXTENDED_RTTI
146
const wxMenuInfoHelperList& wxMenuBarBase::GetMenuInfos() const
148
wxMenuInfoHelperList* list = const_cast< wxMenuInfoHelperList* > (& m_menuInfos);
149
WX_CLEAR_LIST( wxMenuInfoHelperList, *list);
150
for (size_t i = 0 ; i < GetMenuCount(); ++i)
152
wxMenuInfoHelper* info = new wxMenuInfoHelper();
153
info->Create( GetMenu(i), GetMenuLabel(i));
161
// ----------------------------------------------------------------------------
162
// XTI for wxMenuItem
163
// ----------------------------------------------------------------------------
165
#if wxUSE_EXTENDED_RTTI
167
bool wxMenuItemStreamingCallback( const wxObject *object, wxObjectWriter *,
168
wxObjectWriterCallback *, const wxStringToAnyHashMap & )
170
const wxMenuItem * mitem = wx_dynamic_cast(const wxMenuItem*, object);
171
if ( mitem->GetMenu() && !mitem->GetMenu()->GetTitle().empty() )
173
// we don't stream out the first two items for menus with a title,
174
// they will be reconstructed
175
if ( mitem->GetMenu()->FindItemByPosition(0) == mitem ||
176
mitem->GetMenu()->FindItemByPosition(1) == mitem )
184
wxBEGIN_ENUM( wxItemKind )
185
wxENUM_MEMBER( wxITEM_SEPARATOR )
186
wxENUM_MEMBER( wxITEM_NORMAL )
187
wxENUM_MEMBER( wxITEM_CHECK )
188
wxENUM_MEMBER( wxITEM_RADIO )
189
wxEND_ENUM( wxItemKind )
191
wxIMPLEMENT_DYNAMIC_CLASS_XTI_CALLBACK(wxMenuItem, wxObject, "wx/menuitem.h", \
192
wxMenuItemStreamingCallback)
194
wxBEGIN_PROPERTIES_TABLE(wxMenuItem)
195
wxPROPERTY( Parent, wxMenu*, SetMenu, GetMenu, wxEMPTY_PARAMETER_VALUE, \
196
0 /*flags*/, wxT("Helpstring"), wxT("group") )
197
wxPROPERTY( Id, int, SetId, GetId, wxEMPTY_PARAMETER_VALUE, \
198
0 /*flags*/, wxT("Helpstring"), wxT("group") )
199
wxPROPERTY( ItemLabel, wxString, SetItemLabel, GetItemLabel, wxString(), \
200
0 /*flags*/, wxT("Helpstring"), wxT("group") )
201
wxPROPERTY( Help, wxString, SetHelp, GetHelp, wxString(), \
202
0 /*flags*/, wxT("Helpstring"), wxT("group") )
203
wxREADONLY_PROPERTY( Kind, wxItemKind, GetKind, wxEMPTY_PARAMETER_VALUE, \
204
0 /*flags*/, wxT("Helpstring"), wxT("group") )
205
wxPROPERTY( SubMenu, wxMenu*, SetSubMenu, GetSubMenu, wxEMPTY_PARAMETER_VALUE, \
206
0 /*flags*/, wxT("Helpstring"), wxT("group") )
207
wxPROPERTY( Enabled, bool, Enable, IsEnabled, wxAny((bool)true), \
208
0 /*flags*/, wxT("Helpstring"), wxT("group") )
209
wxPROPERTY( Checked, bool, Check, IsChecked, wxAny((bool)false), \
210
0 /*flags*/, wxT("Helpstring"), wxT("group") )
211
wxPROPERTY( Checkable, bool, SetCheckable, IsCheckable, wxAny((bool)false), \
212
0 /*flags*/, wxT("Helpstring"), wxT("group") )
213
wxEND_PROPERTIES_TABLE()
215
wxEMPTY_HANDLERS_TABLE(wxMenuItem)
217
wxDIRECT_CONSTRUCTOR_6( wxMenuItem, wxMenu*, Parent, int, Id, wxString, \
218
Text, wxString, Help, wxItemKind, Kind, wxMenu*, SubMenu )
220
// ----------------------------------------------------------------------------
222
// ----------------------------------------------------------------------------
224
wxMenuItemBase::wxMenuItemBase(wxMenu *parentMenu,
226
const wxString& text,
227
const wxString& help,
234
m_id = wxWindow::NewControlId();
238
m_id = wxID_SEPARATOR;
240
// there is a lot of existing code just doing Append(wxID_SEPARATOR)
241
// and it makes sense to omit the following optional parameters,
242
// including the kind one which doesn't default to wxITEM_SEPARATOR,
243
// of course, so override it here
244
kind = wxITEM_SEPARATOR;
248
// (popup) menu titles in wxMSW use this ID to indicate that
249
// it's not a real menu item, so we don't want the check below to
255
// ids are limited to 16 bits under MSW so portable code shouldn't
256
// use ids outside of this range (negative ids generated by wx are
258
wxASSERT_MSG( (itemid >= 0 && itemid < SHRT_MAX) ||
259
(itemid >= wxID_AUTO_LOWEST && itemid <= wxID_AUTO_HIGHEST),
260
wxS("invalid itemid value") );
264
// notice that parentMenu can be NULL: the item can be attached to the menu
265
// later with SetMenu()
267
m_parentMenu = parentMenu;
277
wxMenuItemBase::~wxMenuItemBase()
284
wxAcceleratorEntry *wxMenuItemBase::GetAccel() const
286
return wxAcceleratorEntry::Create(GetItemLabel());
289
void wxMenuItemBase::SetAccel(wxAcceleratorEntry *accel)
291
wxString text = m_text.BeforeFirst(wxT('\t'));
295
text += accel->ToString();
301
#endif // wxUSE_ACCEL
303
void wxMenuItemBase::SetItemLabel(const wxString& str)
307
if ( m_text.empty() && !IsSeparator() )
309
wxASSERT_MSG( wxIsStockID(GetId()),
310
wxT("A non-stock menu item with an empty label?") );
311
m_text = wxGetStockLabel(GetId(), wxSTOCK_WITH_ACCELERATOR |
312
wxSTOCK_WITH_MNEMONIC);
316
void wxMenuItemBase::SetHelp(const wxString& str)
320
if ( m_help.empty() && !IsSeparator() && wxIsStockID(GetId()) )
322
// get a stock help string
323
m_help = wxGetStockHelpString(GetId());
328
wxString wxMenuItemBase::GetLabelText(const wxString& text)
330
return wxStripMenuCodes(text);
334
#if WXWIN_COMPATIBILITY_2_8
335
wxString wxMenuItemBase::GetLabelFromText(const wxString& text)
337
return GetLabelText(text);
341
bool wxMenuBase::ms_locked = true;
343
// ----------------------------------------------------------------------------
344
// wxMenu ctor and dtor
345
// ----------------------------------------------------------------------------
347
void wxMenuBase::Init(long style)
352
m_invokingWindow = NULL;
355
m_eventHandler = this;
358
wxMenuBase::~wxMenuBase()
360
WX_CLEAR_LIST(wxMenuItemList, m_items);
363
// ----------------------------------------------------------------------------
364
// wxMenu item adding/removing
365
// ----------------------------------------------------------------------------
367
void wxMenuBase::AddSubMenu(wxMenu *submenu)
369
wxCHECK_RET( submenu, wxT("can't add a NULL submenu") );
371
submenu->SetParent((wxMenu *)this);
374
wxMenuItem* wxMenuBase::DoAppend(wxMenuItem *item)
376
wxCHECK_MSG( item, NULL, wxT("invalid item in wxMenu::Append()") );
378
m_items.Append(item);
379
item->SetMenu((wxMenu*)this);
380
if ( item->IsSubMenu() )
382
AddSubMenu(item->GetSubMenu());
388
wxMenuItem* wxMenuBase::Insert(size_t pos, wxMenuItem *item)
390
wxCHECK_MSG( item, NULL, wxT("invalid item in wxMenu::Insert") );
392
if ( pos == GetMenuItemCount() )
394
return DoAppend(item);
398
wxCHECK_MSG( pos < GetMenuItemCount(), NULL,
399
wxT("invalid index in wxMenu::Insert") );
401
return DoInsert(pos, item);
405
wxMenuItem* wxMenuBase::DoInsert(size_t pos, wxMenuItem *item)
407
wxCHECK_MSG( item, NULL, wxT("invalid item in wxMenu::Insert()") );
409
wxMenuItemList::compatibility_iterator node = m_items.Item(pos);
410
wxCHECK_MSG( node, NULL, wxT("invalid index in wxMenu::Insert()") );
412
m_items.Insert(node, item);
413
item->SetMenu((wxMenu*)this);
414
if ( item->IsSubMenu() )
416
AddSubMenu(item->GetSubMenu());
422
wxMenuItem *wxMenuBase::Remove(wxMenuItem *item)
424
wxCHECK_MSG( item, NULL, wxT("invalid item in wxMenu::Remove") );
426
return DoRemove(item);
429
wxMenuItem *wxMenuBase::DoRemove(wxMenuItem *item)
431
wxMenuItemList::compatibility_iterator node = m_items.Find(item);
433
// if we get here, the item is valid or one of Remove() functions is broken
434
wxCHECK_MSG( node, NULL, wxT("bug in wxMenu::Remove logic") );
436
// we detach the item, but we do delete the list node (i.e. don't call
437
// DetachNode() here!)
440
// item isn't attached to anything any more
442
wxMenu *submenu = item->GetSubMenu();
445
submenu->SetParent(NULL);
446
if ( submenu->IsAttached() )
453
bool wxMenuBase::Delete(wxMenuItem *item)
455
wxCHECK_MSG( item, false, wxT("invalid item in wxMenu::Delete") );
457
return DoDelete(item);
460
bool wxMenuBase::DoDelete(wxMenuItem *item)
462
wxMenuItem *item2 = DoRemove(item);
463
wxCHECK_MSG( item2, false, wxT("failed to delete menu item") );
465
// don't delete the submenu
466
item2->SetSubMenu(NULL);
473
bool wxMenuBase::Destroy(wxMenuItem *item)
475
wxCHECK_MSG( item, false, wxT("invalid item in wxMenu::Destroy") );
477
return DoDestroy(item);
480
bool wxMenuBase::DoDestroy(wxMenuItem *item)
482
wxMenuItem *item2 = DoRemove(item);
483
wxCHECK_MSG( item2, false, wxT("failed to delete menu item") );
490
// ----------------------------------------------------------------------------
491
// wxMenu searching for items
492
// ----------------------------------------------------------------------------
494
// Finds the item id matching the given string, wxNOT_FOUND if not found.
495
int wxMenuBase::FindItem(const wxString& text) const
497
wxString label = wxMenuItem::GetLabelText(text);
498
for ( wxMenuItemList::compatibility_iterator node = m_items.GetFirst();
500
node = node->GetNext() )
502
wxMenuItem *item = node->GetData();
503
if ( item->IsSubMenu() )
505
int rc = item->GetSubMenu()->FindItem(label);
506
if ( rc != wxNOT_FOUND )
510
// we execute this code for submenus as well to alllow finding them by
511
// name just like the ordinary items
512
if ( !item->IsSeparator() )
514
if ( item->GetItemLabelText() == label )
515
return item->GetId();
522
// recursive search for item by id
523
wxMenuItem *wxMenuBase::FindItem(int itemId, wxMenu **itemMenu) const
528
wxMenuItem *item = NULL;
529
for ( wxMenuItemList::compatibility_iterator node = m_items.GetFirst();
531
node = node->GetNext() )
533
item = node->GetData();
535
if ( item->GetId() == itemId )
538
*itemMenu = (wxMenu *)this;
540
else if ( item->IsSubMenu() )
542
item = item->GetSubMenu()->FindItem(itemId, itemMenu);
546
// don't exit the loop
554
// non recursive search
555
wxMenuItem *wxMenuBase::FindChildItem(int itemid, size_t *ppos) const
557
wxMenuItem *item = NULL;
558
wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst();
561
for ( pos = 0; node; pos++ )
563
if ( node->GetData()->GetId() == itemid )
565
item = node->GetData();
570
node = node->GetNext();
575
*ppos = item ? pos : (size_t)wxNOT_FOUND;
582
wxMenuItem* wxMenuBase::FindItemByPosition(size_t position) const
584
wxCHECK_MSG( position < m_items.GetCount(), NULL,
585
wxT("wxMenu::FindItemByPosition(): invalid menu index") );
587
return m_items.Item( position )->GetData();
590
// ----------------------------------------------------------------------------
591
// wxMenu helpers used by derived classes
592
// ----------------------------------------------------------------------------
594
// Update a menu and all submenus recursively. source is the object that has
595
// the update event handlers defined for it. If NULL, the menu or associated
596
// window will be used.
597
void wxMenuBase::UpdateUI(wxEvtHandler* source)
599
wxWindow * const win = GetWindow();
601
if ( !source && win )
602
source = win->GetEventHandler();
604
source = GetEventHandler();
608
wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst();
611
wxMenuItem* item = node->GetData();
612
if ( !item->IsSeparator() )
614
wxWindowID itemid = item->GetId();
615
wxUpdateUIEvent event(itemid);
616
event.SetEventObject( this );
618
if ( source->ProcessEvent(event) )
620
// if anything changed, update the changed attribute
621
if (event.GetSetText())
622
SetLabel(itemid, event.GetText());
623
if (event.GetSetChecked())
624
Check(itemid, event.GetChecked());
625
if (event.GetSetEnabled())
626
Enable(itemid, event.GetEnabled());
629
// recurse to the submenus
630
if ( item->GetSubMenu() )
631
item->GetSubMenu()->UpdateUI(source);
633
//else: item is a separator (which doesn't process update UI events)
635
node = node->GetNext();
639
bool wxMenuBase::SendEvent(int itemid, int checked)
641
wxCommandEvent event(wxEVT_MENU, itemid);
642
event.SetEventObject(this);
643
event.SetInt(checked);
645
wxWindow* const win = GetWindow();
646
wxMenuBar* const mb = GetMenuBar();
648
// Try the menu's event handler first
649
wxEvtHandler *handler = GetEventHandler();
652
// Indicate to the event processing code that we're going to pass this
653
// event to another handler if it's not processed here to prevent it
654
// from passing the event to wxTheApp: this will be done below if we do
655
// have the associated window.
657
event.SetWillBeProcessedAgain();
659
if ( handler->SafelyProcessEvent(event) )
663
// If this menu is part of the menu bar, process the event there: this will
664
// also propagate it upwards to the window containing the menu bar.
666
return mb->HandleWindowEvent(event);
668
// Try the window the menu was popped up from.
670
return win->HandleWindowEvent(event);
676
// ----------------------------------------------------------------------------
677
// wxMenu attaching/detaching to/from menu bar
678
// ----------------------------------------------------------------------------
680
wxMenuBar* wxMenuBase::GetMenuBar() const
683
return GetParent()->GetMenuBar();
687
void wxMenuBase::Attach(wxMenuBarBase *menubar)
689
// use Detach() instead!
690
wxASSERT_MSG( menubar, wxT("menu can't be attached to NULL menubar") );
692
// use IsAttached() to prevent this from happening
693
wxASSERT_MSG( !m_menuBar, wxT("attaching menu twice?") );
695
m_menuBar = (wxMenuBar *)menubar;
698
void wxMenuBase::Detach()
700
// use IsAttached() to prevent this from happening
701
wxASSERT_MSG( m_menuBar, wxT("detaching unattached menu?") );
706
// ----------------------------------------------------------------------------
707
// wxMenu invoking window handling
708
// ----------------------------------------------------------------------------
710
void wxMenuBase::SetInvokingWindow(wxWindow *win)
712
wxASSERT_MSG( !GetParent(),
713
"should only be called for top level popup menus" );
714
wxASSERT_MSG( !IsAttached(),
715
"menus attached to menu bar can't have invoking window" );
717
m_invokingWindow = win;
720
wxWindow *wxMenuBase::GetWindow() const
722
// only the top level menus have non-NULL invoking window or a pointer to
723
// the menu bar so recurse upwards until we find it
724
const wxMenuBase *menu = this;
725
while ( menu->GetParent() )
727
menu = menu->GetParent();
730
return menu->GetMenuBar() ? menu->GetMenuBar()->GetFrame()
731
: menu->GetInvokingWindow();
734
// ----------------------------------------------------------------------------
735
// wxMenu functions forwarded to wxMenuItem
736
// ----------------------------------------------------------------------------
738
void wxMenuBase::Enable( int itemid, bool enable )
740
wxMenuItem *item = FindItem(itemid);
742
wxCHECK_RET( item, wxT("wxMenu::Enable: no such item") );
744
item->Enable(enable);
747
bool wxMenuBase::IsEnabled( int itemid ) const
749
wxMenuItem *item = FindItem(itemid);
751
wxCHECK_MSG( item, false, wxT("wxMenu::IsEnabled: no such item") );
753
return item->IsEnabled();
756
void wxMenuBase::Check( int itemid, bool enable )
758
wxMenuItem *item = FindItem(itemid);
760
wxCHECK_RET( item, wxT("wxMenu::Check: no such item") );
765
bool wxMenuBase::IsChecked( int itemid ) const
767
wxMenuItem *item = FindItem(itemid);
769
wxCHECK_MSG( item, false, wxT("wxMenu::IsChecked: no such item") );
771
return item->IsChecked();
774
void wxMenuBase::SetLabel( int itemid, const wxString &label )
776
wxMenuItem *item = FindItem(itemid);
778
wxCHECK_RET( item, wxT("wxMenu::SetLabel: no such item") );
780
item->SetItemLabel(label);
783
wxString wxMenuBase::GetLabel( int itemid ) const
785
wxMenuItem *item = FindItem(itemid);
787
wxCHECK_MSG( item, wxEmptyString, wxT("wxMenu::GetLabel: no such item") );
789
return item->GetItemLabel();
792
void wxMenuBase::SetHelpString( int itemid, const wxString& helpString )
794
wxMenuItem *item = FindItem(itemid);
796
wxCHECK_RET( item, wxT("wxMenu::SetHelpString: no such item") );
798
item->SetHelp( helpString );
801
wxString wxMenuBase::GetHelpString( int itemid ) const
803
wxMenuItem *item = FindItem(itemid);
805
wxCHECK_MSG( item, wxEmptyString, wxT("wxMenu::GetHelpString: no such item") );
807
return item->GetHelp();
810
// ----------------------------------------------------------------------------
811
// wxMenuBarBase ctor and dtor
812
// ----------------------------------------------------------------------------
814
wxMenuBarBase::wxMenuBarBase()
817
m_menuBarFrame = NULL;
820
wxMenuBarBase::~wxMenuBarBase()
822
WX_CLEAR_LIST(wxMenuList, m_menus);
825
// ----------------------------------------------------------------------------
826
// wxMenuBar item access: the base class versions manage m_menus list, the
827
// derived class should reflect the changes in the real menubar
828
// ----------------------------------------------------------------------------
830
wxMenu *wxMenuBarBase::GetMenu(size_t pos) const
832
wxMenuList::compatibility_iterator node = m_menus.Item(pos);
833
wxCHECK_MSG( node, NULL, wxT("bad index in wxMenuBar::GetMenu()") );
835
return node->GetData();
838
bool wxMenuBarBase::Append(wxMenu *menu, const wxString& title)
840
wxCHECK_MSG( menu, false, wxT("can't append NULL menu") );
841
wxCHECK_MSG( !title.empty(), false, wxT("can't append menu with empty title") );
843
m_menus.Append(menu);
849
bool wxMenuBarBase::Insert(size_t pos, wxMenu *menu,
850
const wxString& title)
852
if ( pos == m_menus.GetCount() )
854
return wxMenuBarBase::Append(menu, title);
856
else // not at the end
858
wxCHECK_MSG( menu, false, wxT("can't insert NULL menu") );
860
wxMenuList::compatibility_iterator node = m_menus.Item(pos);
861
wxCHECK_MSG( node, false, wxT("bad index in wxMenuBar::Insert()") );
863
m_menus.Insert(node, menu);
870
wxMenu *wxMenuBarBase::Replace(size_t pos, wxMenu *menu,
871
const wxString& WXUNUSED(title))
873
wxCHECK_MSG( menu, NULL, wxT("can't insert NULL menu") );
875
wxMenuList::compatibility_iterator node = m_menus.Item(pos);
876
wxCHECK_MSG( node, NULL, wxT("bad index in wxMenuBar::Replace()") );
878
wxMenu *menuOld = node->GetData();
887
wxMenu *wxMenuBarBase::Remove(size_t pos)
889
wxMenuList::compatibility_iterator node = m_menus.Item(pos);
890
wxCHECK_MSG( node, NULL, wxT("bad index in wxMenuBar::Remove()") );
892
wxMenu *menu = node->GetData();
899
int wxMenuBarBase::FindMenu(const wxString& title) const
901
wxString label = wxMenuItem::GetLabelText(title);
903
size_t count = GetMenuCount();
904
for ( size_t i = 0; i < count; i++ )
906
wxString title2 = GetMenuLabel(i);
907
if ( (title2 == title) ||
908
(wxMenuItem::GetLabelText(title2) == label) )
919
// ----------------------------------------------------------------------------
920
// wxMenuBar attaching/detaching to/from the frame
921
// ----------------------------------------------------------------------------
923
void wxMenuBarBase::Attach(wxFrame *frame)
925
wxASSERT_MSG( !IsAttached(), wxT("menubar already attached!") );
928
m_menuBarFrame = frame;
931
void wxMenuBarBase::Detach()
933
wxASSERT_MSG( IsAttached(), wxT("detaching unattached menubar") );
935
m_menuBarFrame = NULL;
939
// ----------------------------------------------------------------------------
940
// wxMenuBar searching for items
941
// ----------------------------------------------------------------------------
943
wxMenuItem *wxMenuBarBase::FindItem(int itemid, wxMenu **menu) const
948
wxMenuItem *item = NULL;
949
size_t count = GetMenuCount(), i;
950
wxMenuList::const_iterator it;
951
for ( i = 0, it = m_menus.begin(); !item && (i < count); i++, it++ )
953
item = (*it)->FindItem(itemid, menu);
959
int wxMenuBarBase::FindMenuItem(const wxString& menu, const wxString& item) const
961
wxString label = wxMenuItem::GetLabelText(menu);
964
wxMenuList::compatibility_iterator node;
965
for ( node = m_menus.GetFirst(); node; node = node->GetNext(), i++ )
967
if ( label == wxMenuItem::GetLabelText(GetMenuLabel(i)) )
968
return node->GetData()->FindItem(item);
974
// ---------------------------------------------------------------------------
975
// wxMenuBar functions forwarded to wxMenuItem
976
// ---------------------------------------------------------------------------
978
void wxMenuBarBase::Enable(int itemid, bool enable)
980
wxMenuItem *item = FindItem(itemid);
982
wxCHECK_RET( item, wxT("attempt to enable an item which doesn't exist") );
984
item->Enable(enable);
987
void wxMenuBarBase::Check(int itemid, bool check)
989
wxMenuItem *item = FindItem(itemid);
991
wxCHECK_RET( item, wxT("attempt to check an item which doesn't exist") );
992
wxCHECK_RET( item->IsCheckable(), wxT("attempt to check an uncheckable item") );
997
bool wxMenuBarBase::IsChecked(int itemid) const
999
wxMenuItem *item = FindItem(itemid);
1001
wxCHECK_MSG( item, false, wxT("wxMenuBar::IsChecked(): no such item") );
1003
return item->IsChecked();
1006
bool wxMenuBarBase::IsEnabled(int itemid) const
1008
wxMenuItem *item = FindItem(itemid);
1010
wxCHECK_MSG( item, false, wxT("wxMenuBar::IsEnabled(): no such item") );
1012
return item->IsEnabled();
1015
void wxMenuBarBase::SetLabel(int itemid, const wxString& label)
1017
wxMenuItem *item = FindItem(itemid);
1019
wxCHECK_RET( item, wxT("wxMenuBar::SetLabel(): no such item") );
1021
item->SetItemLabel(label);
1024
wxString wxMenuBarBase::GetLabel(int itemid) const
1026
wxMenuItem *item = FindItem(itemid);
1028
wxCHECK_MSG( item, wxEmptyString,
1029
wxT("wxMenuBar::GetLabel(): no such item") );
1031
return item->GetItemLabel();
1034
void wxMenuBarBase::SetHelpString(int itemid, const wxString& helpString)
1036
wxMenuItem *item = FindItem(itemid);
1038
wxCHECK_RET( item, wxT("wxMenuBar::SetHelpString(): no such item") );
1040
item->SetHelp(helpString);
1043
wxString wxMenuBarBase::GetHelpString(int itemid) const
1045
wxMenuItem *item = FindItem(itemid);
1047
wxCHECK_MSG( item, wxEmptyString,
1048
wxT("wxMenuBar::GetHelpString(): no such item") );
1050
return item->GetHelp();
1053
void wxMenuBarBase::UpdateMenus()
1056
int nCount = GetMenuCount();
1057
for (int n = 0; n < nCount; n++)
1059
menu = GetMenu( n );
1061
menu->UpdateUI( NULL );
1065
#if WXWIN_COMPATIBILITY_2_8
1066
// get or change the label of the menu at given position
1067
void wxMenuBarBase::SetLabelTop(size_t pos, const wxString& label)
1069
SetMenuLabel(pos, label);
1072
wxString wxMenuBarBase::GetLabelTop(size_t pos) const
1074
return GetMenuLabelText(pos);
1078
#endif // wxUSE_MENUS