+// XTI for wxMenu(Bar)
+// ----------------------------------------------------------------------------
+
+wxDEFINE_FLAGS( wxMenuStyle )
+wxBEGIN_FLAGS( wxMenuStyle )
+wxFLAGS_MEMBER(wxMENU_TEAROFF)
+wxEND_FLAGS( wxMenuStyle )
+
+wxIMPLEMENT_DYNAMIC_CLASS_XTI(wxMenu, wxEvtHandler, "wx/menu.h")
+wxCOLLECTION_TYPE_INFO( wxMenuItem *, wxMenuItemList ) ;
+
+#if wxUSE_EXTENDED_RTTI
+template<> void wxCollectionToVariantArray( wxMenuItemList const &theList,
+ wxAnyList &value)
+{
+ wxListCollectionToAnyList<wxMenuItemList::compatibility_iterator>( theList, value ) ;
+}
+#endif
+
+wxBEGIN_PROPERTIES_TABLE(wxMenu)
+wxEVENT_PROPERTY( Select, wxEVT_COMMAND_MENU_SELECTED, wxCommandEvent)
+
+wxPROPERTY( Title, wxString, SetTitle, GetTitle, wxString(), \
+ 0 /*flags*/, wxT("Helpstring"), wxT("group") )
+
+wxREADONLY_PROPERTY_FLAGS( MenuStyle, wxMenuStyle, long, GetStyle, \
+ wxEMPTY_PARAMETER_VALUE, 0 /*flags*/, wxT("Helpstring"), \
+ wxT("group")) // style
+
+wxPROPERTY_COLLECTION( MenuItems, wxMenuItemList, wxMenuItem*, Append, \
+ GetMenuItems, 0 /*flags*/, wxT("Helpstring"), wxT("group"))
+wxEND_PROPERTIES_TABLE()
+
+wxEMPTY_HANDLERS_TABLE(wxMenu)
+
+wxDIRECT_CONSTRUCTOR_2( wxMenu, wxString, Title, long, MenuStyle )
+
+wxDEFINE_FLAGS( wxMenuBarStyle )
+
+wxBEGIN_FLAGS( wxMenuBarStyle )
+wxFLAGS_MEMBER(wxMB_DOCKABLE)
+wxEND_FLAGS( wxMenuBarStyle )
+
+#if wxUSE_EXTENDED_RTTI
+// the negative id would lead the window (its superclass !) to
+// vetoe streaming out otherwise
+bool wxMenuBarStreamingCallback( const wxObject *WXUNUSED(object), wxObjectWriter *,
+ wxObjectWriterCallback *, const wxStringToAnyHashMap & )
+{
+ return true;
+}
+#endif
+
+wxIMPLEMENT_DYNAMIC_CLASS_XTI_CALLBACK(wxMenuBar, wxWindow, "wx/menu.h", \
+ wxMenuBarStreamingCallback)
+
+
+#if wxUSE_EXTENDED_RTTI
+WX_DEFINE_LIST( wxMenuInfoHelperList )
+
+wxIMPLEMENT_DYNAMIC_CLASS_XTI(wxMenuInfoHelper, wxObject, "wx/menu.h")
+
+wxBEGIN_PROPERTIES_TABLE(wxMenuInfoHelper)
+wxREADONLY_PROPERTY( Menu, wxMenu*, GetMenu, wxEMPTY_PARAMETER_VALUE, \
+ 0 /*flags*/, wxT("Helpstring"), wxT("group"))
+
+wxREADONLY_PROPERTY( Title, wxString, GetTitle, wxString(), \
+ 0 /*flags*/, wxT("Helpstring"), wxT("group"))
+wxEND_PROPERTIES_TABLE()
+
+wxEMPTY_HANDLERS_TABLE(wxMenuInfoHelper)
+
+wxCONSTRUCTOR_2( wxMenuInfoHelper, wxMenu*, Menu, wxString, Title )
+
+wxCOLLECTION_TYPE_INFO( wxMenuInfoHelper *, wxMenuInfoHelperList ) ;
+
+template<> void wxCollectionToVariantArray( wxMenuInfoHelperList const &theList,
+ wxAnyList &value)
+{
+ wxListCollectionToAnyList<wxMenuInfoHelperList::compatibility_iterator>( theList, value ) ;
+}
+
+#endif
+
+wxBEGIN_PROPERTIES_TABLE(wxMenuBar)
+wxPROPERTY_COLLECTION( MenuInfos, wxMenuInfoHelperList, wxMenuInfoHelper*, AppendMenuInfo, \
+ GetMenuInfos, 0 /*flags*/, wxT("Helpstring"), wxT("group"))
+wxEND_PROPERTIES_TABLE()
+
+wxEMPTY_HANDLERS_TABLE(wxMenuBar)
+
+wxCONSTRUCTOR_DUMMY( wxMenuBar )
+
+#if wxUSE_EXTENDED_RTTI
+
+const wxMenuInfoHelperList& wxMenuBarBase::GetMenuInfos() const
+{
+ wxMenuInfoHelperList* list = const_cast< wxMenuInfoHelperList* > (& m_menuInfos);
+ WX_CLEAR_LIST( wxMenuInfoHelperList, *list);
+ for (size_t i = 0 ; i < GetMenuCount(); ++i)
+ {
+ wxMenuInfoHelper* info = new wxMenuInfoHelper();
+ info->Create( GetMenu(i), GetMenuLabel(i));
+ list->Append(info);
+ }
+ return m_menuInfos;
+}
+
+#endif
+
+// ----------------------------------------------------------------------------
+// XTI for wxMenuItem
+// ----------------------------------------------------------------------------
+
+#if wxUSE_EXTENDED_RTTI
+
+bool wxMenuItemStreamingCallback( const wxObject *object, wxObjectWriter *,
+ wxObjectWriterCallback *, const wxStringToAnyHashMap & )
+{
+ const wxMenuItem * mitem = wx_dynamic_cast(const wxMenuItem*, object);
+ if ( mitem->GetMenu() && !mitem->GetMenu()->GetTitle().empty() )
+ {
+ // we don't stream out the first two items for menus with a title,
+ // they will be reconstructed
+ if ( mitem->GetMenu()->FindItemByPosition(0) == mitem ||
+ mitem->GetMenu()->FindItemByPosition(1) == mitem )
+ return false;
+ }
+ return true;
+}
+
+#endif
+
+wxBEGIN_ENUM( wxItemKind )
+wxENUM_MEMBER( wxITEM_SEPARATOR )
+wxENUM_MEMBER( wxITEM_NORMAL )
+wxENUM_MEMBER( wxITEM_CHECK )
+wxENUM_MEMBER( wxITEM_RADIO )
+wxEND_ENUM( wxItemKind )
+
+wxIMPLEMENT_DYNAMIC_CLASS_XTI_CALLBACK(wxMenuItem, wxObject, "wx/menuitem.h", \
+ wxMenuItemStreamingCallback)
+
+wxBEGIN_PROPERTIES_TABLE(wxMenuItem)
+wxPROPERTY( Parent, wxMenu*, SetMenu, GetMenu, wxEMPTY_PARAMETER_VALUE, \
+ 0 /*flags*/, wxT("Helpstring"), wxT("group") )
+wxPROPERTY( Id, int, SetId, GetId, wxEMPTY_PARAMETER_VALUE, \
+ 0 /*flags*/, wxT("Helpstring"), wxT("group") )
+wxPROPERTY( ItemLabel, wxString, SetItemLabel, GetItemLabel, wxString(), \
+ 0 /*flags*/, wxT("Helpstring"), wxT("group") )
+wxPROPERTY( Help, wxString, SetHelp, GetHelp, wxString(), \
+ 0 /*flags*/, wxT("Helpstring"), wxT("group") )
+wxREADONLY_PROPERTY( Kind, wxItemKind, GetKind, wxEMPTY_PARAMETER_VALUE, \
+ 0 /*flags*/, wxT("Helpstring"), wxT("group") )
+wxPROPERTY( SubMenu, wxMenu*, SetSubMenu, GetSubMenu, wxEMPTY_PARAMETER_VALUE, \
+ 0 /*flags*/, wxT("Helpstring"), wxT("group") )
+wxPROPERTY( Enabled, bool, Enable, IsEnabled, wxAny((bool)true), \
+ 0 /*flags*/, wxT("Helpstring"), wxT("group") )
+wxPROPERTY( Checked, bool, Check, IsChecked, wxAny((bool)false), \
+ 0 /*flags*/, wxT("Helpstring"), wxT("group") )
+wxPROPERTY( Checkable, bool, SetCheckable, IsCheckable, wxAny((bool)false), \
+ 0 /*flags*/, wxT("Helpstring"), wxT("group") )
+wxEND_PROPERTIES_TABLE()
+
+wxEMPTY_HANDLERS_TABLE(wxMenuItem)
+
+wxDIRECT_CONSTRUCTOR_6( wxMenuItem, wxMenu*, Parent, int, Id, wxString, \
+ Text, wxString, Help, wxItemKind, Kind, wxMenu*, SubMenu )
+
+// ----------------------------------------------------------------------------
+// wxMenuItemBase
+// ----------------------------------------------------------------------------
+
+wxMenuItemBase::wxMenuItemBase(wxMenu *parentMenu,
+ int id,
+ const wxString& text,
+ const wxString& help,
+ wxItemKind kind,
+ wxMenu *subMenu)
+{
+ switch ( id )
+ {
+ case wxID_ANY:
+ m_id = wxWindow::NewControlId();
+ break;
+
+ case wxID_SEPARATOR:
+ m_id = wxID_SEPARATOR;
+
+ // there is a lot of existing code just doing Append(wxID_SEPARATOR)
+ // and it makes sense to omit the following optional parameters,
+ // including the kind one which doesn't default to wxITEM_SEPARATOR,
+ // of course, so override it here
+ kind = wxITEM_SEPARATOR;
+ break;
+
+ case wxID_NONE:
+ // (popup) menu titles in wxMSW use this ID to indicate that
+ // it's not a real menu item, so we don't want the check below to
+ // apply to it
+ m_id = id;
+ break;
+
+ default:
+ // ids are limited to 16 bits under MSW so portable code shouldn't
+ // use ids outside of this range (negative ids generated by wx are
+ // fine though)
+ wxASSERT_MSG( (id >= 0 && id < SHRT_MAX) ||
+ (id >= wxID_AUTO_LOWEST && id <= wxID_AUTO_HIGHEST),
+ wxS("invalid id value") );
+ m_id = id;
+ }
+
+ // notice that parentMenu can be NULL: the item can be attached to the menu
+ // later with SetMenu()
+
+ m_parentMenu = parentMenu;
+ m_subMenu = subMenu;
+ m_isEnabled = true;
+ m_isChecked = false;
+ m_kind = kind;
+
+ SetItemLabel(text);
+ SetHelp(help);
+}
+
+wxMenuItemBase::~wxMenuItemBase()
+{
+ delete m_subMenu;
+}
+
+#if wxUSE_ACCEL
+
+wxAcceleratorEntry *wxMenuItemBase::GetAccel() const
+{
+ return wxAcceleratorEntry::Create(GetItemLabel());
+}
+
+void wxMenuItemBase::SetAccel(wxAcceleratorEntry *accel)
+{
+ wxString text = m_text.BeforeFirst(wxT('\t'));
+ if ( accel )
+ {
+ text += wxT('\t');
+ text += accel->ToString();
+ }
+
+ SetItemLabel(text);
+}
+
+#endif // wxUSE_ACCEL
+
+void wxMenuItemBase::SetItemLabel(const wxString& str)
+{
+ m_text = str;
+
+ if ( m_text.empty() && !IsSeparator() )
+ {
+ wxASSERT_MSG( wxIsStockID(GetId()),
+ wxT("A non-stock menu item with an empty label?") );
+ m_text = wxGetStockLabel(GetId(), wxSTOCK_WITH_ACCELERATOR |
+ wxSTOCK_WITH_MNEMONIC);
+ }
+}
+
+void wxMenuItemBase::SetHelp(const wxString& str)
+{
+ m_help = str;
+
+ if ( m_help.empty() && !IsSeparator() && wxIsStockID(GetId()) )
+ {
+ // get a stock help string
+ m_help = wxGetStockHelpString(GetId());
+ }
+}
+
+#ifndef __WXPM__
+wxString wxMenuItemBase::GetLabelText(const wxString& text)
+{
+ return wxStripMenuCodes(text);
+}
+#endif
+
+#if WXWIN_COMPATIBILITY_2_8
+wxString wxMenuItemBase::GetLabelFromText(const wxString& text)
+{
+ return GetLabelText(text);
+}
+#endif
+
+bool wxMenuBase::ms_locked = true;
+
+// ----------------------------------------------------------------------------
+// wxMenu ctor and dtor
+// ----------------------------------------------------------------------------
+
+void wxMenuBase::Init(long style)
+{
+ m_menuBar = NULL;
+ m_menuParent = NULL;
+
+ m_invokingWindow = NULL;
+ m_style = style;
+ m_clientData = NULL;
+ m_eventHandler = this;
+}
+
+wxMenuBase::~wxMenuBase()
+{
+ WX_CLEAR_LIST(wxMenuItemList, m_items);
+}
+
+// ----------------------------------------------------------------------------
+// wxMenu item adding/removing
+// ----------------------------------------------------------------------------
+
+void wxMenuBase::AddSubMenu(wxMenu *submenu)
+{
+ wxCHECK_RET( submenu, wxT("can't add a NULL submenu") );
+
+ submenu->SetParent((wxMenu *)this);
+}
+
+wxMenuItem* wxMenuBase::DoAppend(wxMenuItem *item)
+{
+ wxCHECK_MSG( item, NULL, wxT("invalid item in wxMenu::Append()") );
+
+ m_items.Append(item);
+ item->SetMenu((wxMenu*)this);
+ if ( item->IsSubMenu() )
+ {
+ AddSubMenu(item->GetSubMenu());
+ }
+
+ return item;
+}
+
+wxMenuItem* wxMenuBase::Insert(size_t pos, wxMenuItem *item)
+{
+ wxCHECK_MSG( item, NULL, wxT("invalid item in wxMenu::Insert") );
+
+ if ( pos == GetMenuItemCount() )
+ {
+ return DoAppend(item);
+ }
+ else
+ {
+ wxCHECK_MSG( pos < GetMenuItemCount(), NULL,
+ wxT("invalid index in wxMenu::Insert") );
+
+ return DoInsert(pos, item);
+ }
+}
+
+wxMenuItem* wxMenuBase::DoInsert(size_t pos, wxMenuItem *item)
+{
+ wxCHECK_MSG( item, NULL, wxT("invalid item in wxMenu::Insert()") );
+
+ wxMenuItemList::compatibility_iterator node = m_items.Item(pos);
+ wxCHECK_MSG( node, NULL, wxT("invalid index in wxMenu::Insert()") );
+
+ m_items.Insert(node, item);
+ item->SetMenu((wxMenu*)this);
+ if ( item->IsSubMenu() )
+ {
+ AddSubMenu(item->GetSubMenu());
+ }
+
+ return item;
+}
+
+wxMenuItem *wxMenuBase::Remove(wxMenuItem *item)
+{
+ wxCHECK_MSG( item, NULL, wxT("invalid item in wxMenu::Remove") );
+
+ return DoRemove(item);
+}
+
+wxMenuItem *wxMenuBase::DoRemove(wxMenuItem *item)
+{
+ wxMenuItemList::compatibility_iterator node = m_items.Find(item);
+
+ // if we get here, the item is valid or one of Remove() functions is broken
+ wxCHECK_MSG( node, NULL, wxT("bug in wxMenu::Remove logic") );
+
+ // we detach the item, but we do delete the list node (i.e. don't call
+ // DetachNode() here!)
+ m_items.Erase(node);
+
+ // item isn't attached to anything any more
+ item->SetMenu(NULL);
+ wxMenu *submenu = item->GetSubMenu();
+ if ( submenu )
+ {
+ submenu->SetParent(NULL);
+ if ( submenu->IsAttached() )
+ submenu->Detach();
+ }
+
+ return item;
+}
+
+bool wxMenuBase::Delete(wxMenuItem *item)
+{
+ wxCHECK_MSG( item, false, wxT("invalid item in wxMenu::Delete") );
+
+ return DoDelete(item);
+}
+
+bool wxMenuBase::DoDelete(wxMenuItem *item)
+{
+ wxMenuItem *item2 = DoRemove(item);
+ wxCHECK_MSG( item2, false, wxT("failed to delete menu item") );
+
+ // don't delete the submenu
+ item2->SetSubMenu(NULL);
+
+ delete item2;
+
+ return true;
+}
+
+bool wxMenuBase::Destroy(wxMenuItem *item)
+{
+ wxCHECK_MSG( item, false, wxT("invalid item in wxMenu::Destroy") );
+
+ return DoDestroy(item);
+}
+
+bool wxMenuBase::DoDestroy(wxMenuItem *item)
+{
+ wxMenuItem *item2 = DoRemove(item);
+ wxCHECK_MSG( item2, false, wxT("failed to delete menu item") );
+
+ delete item2;
+
+ return true;
+}
+
+// ----------------------------------------------------------------------------
+// wxMenu searching for items
+// ----------------------------------------------------------------------------
+
+// Finds the item id matching the given string, wxNOT_FOUND if not found.
+int wxMenuBase::FindItem(const wxString& text) const
+{
+ wxString label = wxMenuItem::GetLabelText(text);
+ for ( wxMenuItemList::compatibility_iterator node = m_items.GetFirst();
+ node;
+ node = node->GetNext() )
+ {
+ wxMenuItem *item = node->GetData();
+ if ( item->IsSubMenu() )
+ {
+ int rc = item->GetSubMenu()->FindItem(label);
+ if ( rc != wxNOT_FOUND )
+ return rc;
+ }
+
+ // we execute this code for submenus as well to alllow finding them by
+ // name just like the ordinary items
+ if ( !item->IsSeparator() )
+ {
+ if ( item->GetItemLabelText() == label )
+ return item->GetId();
+ }
+ }
+
+ return wxNOT_FOUND;
+}
+
+// recursive search for item by id
+wxMenuItem *wxMenuBase::FindItem(int itemId, wxMenu **itemMenu) const
+{
+ if ( itemMenu )
+ *itemMenu = NULL;
+
+ wxMenuItem *item = NULL;
+ for ( wxMenuItemList::compatibility_iterator node = m_items.GetFirst();
+ node && !item;
+ node = node->GetNext() )
+ {
+ item = node->GetData();
+
+ if ( item->GetId() == itemId )
+ {
+ if ( itemMenu )
+ *itemMenu = (wxMenu *)this;
+ }
+ else if ( item->IsSubMenu() )
+ {
+ item = item->GetSubMenu()->FindItem(itemId, itemMenu);
+ }
+ else
+ {
+ // don't exit the loop
+ item = NULL;
+ }
+ }
+
+ return item;
+}
+
+// non recursive search
+wxMenuItem *wxMenuBase::FindChildItem(int id, size_t *ppos) const
+{
+ wxMenuItem *item = NULL;
+ wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst();
+
+ size_t pos;
+ for ( pos = 0; node; pos++ )
+ {
+ if ( node->GetData()->GetId() == id )
+ {
+ item = node->GetData();
+
+ break;
+ }
+
+ node = node->GetNext();
+ }
+
+ if ( ppos )
+ {
+ *ppos = item ? pos : (size_t)wxNOT_FOUND;
+ }
+
+ return item;
+}
+
+// find by position
+wxMenuItem* wxMenuBase::FindItemByPosition(size_t position) const
+{
+ wxCHECK_MSG( position < m_items.GetCount(), NULL,
+ wxT("wxMenu::FindItemByPosition(): invalid menu index") );
+
+ return m_items.Item( position )->GetData();
+}
+
+// ----------------------------------------------------------------------------
+// wxMenu helpers used by derived classes
+// ----------------------------------------------------------------------------
+
+// Update a menu and all submenus recursively. source is the object that has
+// the update event handlers defined for it. If NULL, the menu or associated
+// window will be used.
+void wxMenuBase::UpdateUI(wxEvtHandler* source)
+{
+ if (GetInvokingWindow())
+ {
+ // Don't update menus if the parent
+ // frame is about to get deleted
+ wxWindow *tlw = wxGetTopLevelParent( GetInvokingWindow() );
+ if (tlw && wxPendingDelete.Member(tlw))
+ return;
+ }
+
+ if ( !source && GetInvokingWindow() )
+ source = GetInvokingWindow()->GetEventHandler();
+ if ( !source )
+ source = GetEventHandler();
+ if ( !source )
+ source = this;
+
+ wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst();
+ while ( node )
+ {
+ wxMenuItem* item = node->GetData();
+ if ( !item->IsSeparator() )
+ {
+ wxWindowID id = item->GetId();
+ wxUpdateUIEvent event(id);
+ event.SetEventObject( source );
+
+ if ( source->ProcessEvent(event) )
+ {
+ // if anything changed, update the changed attribute
+ if (event.GetSetText())
+ SetLabel(id, event.GetText());
+ if (event.GetSetChecked())
+ Check(id, event.GetChecked());
+ if (event.GetSetEnabled())
+ Enable(id, event.GetEnabled());
+ }
+
+ // recurse to the submenus
+ if ( item->GetSubMenu() )
+ item->GetSubMenu()->UpdateUI(source);
+ }
+ //else: item is a separator (which doesn't process update UI events)
+
+ node = node->GetNext();
+ }
+}
+
+bool wxMenuBase::SendEvent(int id, int checked)
+{
+ wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, id);
+ event.SetEventObject(this);
+ event.SetInt(checked);
+
+ bool processed = false;
+
+ // Try the menu's event handler first
+ wxEvtHandler *handler = GetEventHandler();
+ if ( handler )
+ processed = handler->SafelyProcessEvent(event);
+
+ // Try the window the menu was popped up from or its menu bar belongs to
+ if ( !processed )
+ {
+ wxWindow * const win = GetWindow();
+ if ( win )
+ processed = win->HandleWindowEvent(event);
+ }
+
+ return processed;
+}
+
+// ----------------------------------------------------------------------------
+// wxMenu attaching/detaching to/from menu bar
+// ----------------------------------------------------------------------------
+
+wxMenuBar* wxMenuBase::GetMenuBar() const
+{
+ if(GetParent())
+ return GetParent()->GetMenuBar();
+ return m_menuBar;
+}
+
+void wxMenuBase::Attach(wxMenuBarBase *menubar)
+{
+ // use Detach() instead!
+ wxASSERT_MSG( menubar, wxT("menu can't be attached to NULL menubar") );
+
+ // use IsAttached() to prevent this from happening
+ wxASSERT_MSG( !m_menuBar, wxT("attaching menu twice?") );
+
+ m_menuBar = (wxMenuBar *)menubar;
+}
+
+void wxMenuBase::Detach()
+{
+ // use IsAttached() to prevent this from happening
+ wxASSERT_MSG( m_menuBar, wxT("detaching unattached menu?") );
+
+ m_menuBar = NULL;
+}
+
+// ----------------------------------------------------------------------------
+// wxMenu invoking window handling
+// ----------------------------------------------------------------------------
+
+void wxMenuBase::SetInvokingWindow(wxWindow *win)
+{
+ wxASSERT_MSG( !GetParent(),
+ "should only be called for top level popup menus" );
+ wxASSERT_MSG( !IsAttached(),
+ "menus attached to menu bar can't have invoking window" );
+
+ m_invokingWindow = win;
+}
+
+wxWindow *wxMenuBase::GetWindow() const
+{
+ // only the top level menus have non-NULL invoking window or a pointer to
+ // the menu bar so recurse upwards until we find it
+ const wxMenuBase *menu = this;
+ while ( menu->GetParent() )
+ {
+ menu = menu->GetParent();
+ }
+
+ return menu->GetMenuBar() ? menu->GetMenuBar()->GetFrame()
+ : menu->GetInvokingWindow();
+}
+
+// ----------------------------------------------------------------------------
+// wxMenu functions forwarded to wxMenuItem
+// ----------------------------------------------------------------------------
+
+void wxMenuBase::Enable( int id, bool enable )
+{
+ wxMenuItem *item = FindItem(id);
+
+ wxCHECK_RET( item, wxT("wxMenu::Enable: no such item") );
+
+ item->Enable(enable);
+}
+
+bool wxMenuBase::IsEnabled( int id ) const
+{
+ wxMenuItem *item = FindItem(id);
+
+ wxCHECK_MSG( item, false, wxT("wxMenu::IsEnabled: no such item") );
+
+ return item->IsEnabled();
+}
+
+void wxMenuBase::Check( int id, bool enable )
+{
+ wxMenuItem *item = FindItem(id);
+
+ wxCHECK_RET( item, wxT("wxMenu::Check: no such item") );
+
+ item->Check(enable);
+}
+
+bool wxMenuBase::IsChecked( int id ) const
+{
+ wxMenuItem *item = FindItem(id);
+
+ wxCHECK_MSG( item, false, wxT("wxMenu::IsChecked: no such item") );
+
+ return item->IsChecked();
+}
+
+void wxMenuBase::SetLabel( int id, const wxString &label )
+{
+ wxMenuItem *item = FindItem(id);
+
+ wxCHECK_RET( item, wxT("wxMenu::SetLabel: no such item") );
+
+ item->SetItemLabel(label);
+}
+
+wxString wxMenuBase::GetLabel( int id ) const
+{
+ wxMenuItem *item = FindItem(id);
+
+ wxCHECK_MSG( item, wxEmptyString, wxT("wxMenu::GetLabel: no such item") );
+
+ return item->GetItemLabel();
+}
+
+void wxMenuBase::SetHelpString( int id, const wxString& helpString )
+{
+ wxMenuItem *item = FindItem(id);
+
+ wxCHECK_RET( item, wxT("wxMenu::SetHelpString: no such item") );
+
+ item->SetHelp( helpString );
+}
+
+wxString wxMenuBase::GetHelpString( int id ) const
+{
+ wxMenuItem *item = FindItem(id);
+
+ wxCHECK_MSG( item, wxEmptyString, wxT("wxMenu::GetHelpString: no such item") );
+
+ return item->GetHelp();
+}
+
+// ----------------------------------------------------------------------------
+// wxMenuBarBase ctor and dtor