X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c4e43bea7b24f7b7f58e3f87786490cd81abf0a7..6f26925422c2de7938509657eb981d6f752a6249:/src/common/menucmn.cpp diff --git a/src/common/menucmn.cpp b/src/common/menucmn.cpp index edceb72cc5..4c7abae78d 100644 --- a/src/common/menucmn.cpp +++ b/src/common/menucmn.cpp @@ -30,6 +30,7 @@ #include "wx/intl.h" #include "wx/log.h" #include "wx/menu.h" + #include "wx/frame.h" #endif #include "wx/stockitem.h" @@ -58,18 +59,47 @@ wxMenuItemBase::wxMenuItemBase(wxMenu *parentMenu, wxItemKind kind, wxMenu *subMenu) { - wxASSERT_MSG( parentMenu != NULL, wxT("menuitem should have a menu") ); + 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_id = id; m_kind = kind; - if (m_id == wxID_ANY) - m_id = wxNewId(); - if (m_id == wxID_SEPARATOR) - m_kind = wxITEM_SEPARATOR; SetItemLabel(text); SetHelp(help); @@ -125,6 +155,13 @@ void wxMenuItemBase::SetHelp(const wxString& str) } } +#ifndef __WXPM__ +wxString wxMenuItemBase::GetLabelText(const wxString& text) +{ + return wxStripMenuCodes(text); +} +#endif + #if WXWIN_COMPATIBILITY_2_8 wxString wxMenuItemBase::GetLabelFromText(const wxString& text) { @@ -140,20 +177,18 @@ bool wxMenuBase::ms_locked = true; void wxMenuBase::Init(long style) { - m_menuBar = (wxMenuBar *)NULL; - m_menuParent = (wxMenu *)NULL; + m_menuBar = NULL; + m_menuParent = NULL; - m_invokingWindow = (wxWindow *)NULL; + m_invokingWindow = NULL; m_style = style; - m_clientData = (void *)NULL; + m_clientData = NULL; m_eventHandler = this; } wxMenuBase::~wxMenuBase() { WX_CLEAR_LIST(wxMenuItemList, m_items); - - // Actually, in GTK, the submenus have to get deleted first. } // ---------------------------------------------------------------------------- @@ -162,7 +197,7 @@ wxMenuBase::~wxMenuBase() void wxMenuBase::AddSubMenu(wxMenu *submenu) { - wxCHECK_RET( submenu, _T("can't add a NULL submenu") ); + wxCHECK_RET( submenu, wxT("can't add a NULL submenu") ); submenu->SetParent((wxMenu *)this); } @@ -234,11 +269,11 @@ wxMenuItem *wxMenuBase::DoRemove(wxMenuItem *item) m_items.Erase(node); // item isn't attached to anything any more - item->SetMenu((wxMenu *)NULL); + item->SetMenu(NULL); wxMenu *submenu = item->GetSubMenu(); if ( submenu ) { - submenu->SetParent((wxMenu *)NULL); + submenu->SetParent(NULL); if ( submenu->IsAttached() ) submenu->Detach(); } @@ -259,7 +294,7 @@ bool wxMenuBase::DoDelete(wxMenuItem *item) wxCHECK_MSG( item2, false, wxT("failed to delete menu item") ); // don't delete the submenu - item2->SetSubMenu((wxMenu *)NULL); + item2->SetSubMenu(NULL); delete item2; @@ -350,7 +385,7 @@ wxMenuItem *wxMenuBase::FindItem(int itemId, wxMenu **itemMenu) const // non recursive search wxMenuItem *wxMenuBase::FindChildItem(int id, size_t *ppos) const { - wxMenuItem *item = (wxMenuItem *)NULL; + wxMenuItem *item = NULL; wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst(); size_t pos; @@ -378,7 +413,7 @@ wxMenuItem *wxMenuBase::FindChildItem(int id, size_t *ppos) const wxMenuItem* wxMenuBase::FindItemByPosition(size_t position) const { wxCHECK_MSG( position < m_items.GetCount(), NULL, - _T("wxMenu::FindItemByPosition(): invalid menu index") ); + wxT("wxMenu::FindItemByPosition(): invalid menu index") ); return m_items.Item( position )->GetData(); } @@ -447,30 +482,17 @@ bool wxMenuBase::SendEvent(int id, int checked) bool processed = false; - // Try the menu's event handler - // if ( !processed ) - { - wxEvtHandler *handler = GetEventHandler(); - if ( handler ) - processed = handler->ProcessEvent(event); - } + // 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 (and up through the - // hierarchy) + // Try the window the menu was popped up from or its menu bar belongs to if ( !processed ) { - const wxMenuBase *menu = this; - while ( menu ) - { - wxWindow *win = menu->GetInvokingWindow(); - if ( win ) - { - processed = win->GetEventHandler()->ProcessEvent(event); - break; - } - - menu = menu->GetParent(); - } + wxWindow * const win = GetWindow(); + if ( win ) + processed = win->HandleWindowEvent(event); } return processed; @@ -490,10 +512,10 @@ wxMenuBar* wxMenuBase::GetMenuBar() const void wxMenuBase::Attach(wxMenuBarBase *menubar) { // use Detach() instead! - wxASSERT_MSG( menubar, _T("menu can't be attached to NULL menubar") ); + wxASSERT_MSG( menubar, wxT("menu can't be attached to NULL menubar") ); // use IsAttached() to prevent this from happening - wxASSERT_MSG( !m_menuBar, _T("attaching menu twice?") ); + wxASSERT_MSG( !m_menuBar, wxT("attaching menu twice?") ); m_menuBar = (wxMenuBar *)menubar; } @@ -501,11 +523,39 @@ void wxMenuBase::Attach(wxMenuBarBase *menubar) void wxMenuBase::Detach() { // use IsAttached() to prevent this from happening - wxASSERT_MSG( m_menuBar, _T("detaching unattached menu?") ); + 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 // ---------------------------------------------------------------------------- @@ -610,9 +660,10 @@ wxMenu *wxMenuBarBase::GetMenu(size_t pos) const return node->GetData(); } -bool wxMenuBarBase::Append(wxMenu *menu, const wxString& WXUNUSED(title)) +bool wxMenuBarBase::Append(wxMenu *menu, const wxString& title) { wxCHECK_MSG( menu, false, wxT("can't append NULL menu") ); + wxCHECK_MSG( !title.empty(), false, wxT("can't append menu with empty title") ); m_menus.Append(menu); menu->Attach(this); @@ -822,7 +873,7 @@ wxString wxMenuBarBase::GetHelpString(int id) const return item->GetHelp(); } -void wxMenuBarBase::UpdateMenus( void ) +void wxMenuBarBase::UpdateMenus() { wxEvtHandler* source; wxMenu* menu; @@ -852,5 +903,4 @@ wxString wxMenuBarBase::GetLabelTop(size_t pos) const } #endif - #endif // wxUSE_MENUS