// Author: Stefan Csomor
// Modified by:
// Created: 1998-01-01
-// RCS-ID: $Id: menu.cpp 54129 2008-06-11 19:30:52Z SC $
// Copyright: (c) Stefan Csomor
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#include "wx/wxprec.h"
+#if wxUSE_MENUS
+
#include "wx/menu.h"
#ifndef WX_PRECOMP
#include "wx/app.h"
#include "wx/utils.h"
#include "wx/frame.h"
+ #include "wx/dialog.h"
#include "wx/menuitem.h"
#endif
{
}
-IMPLEMENT_DYNAMIC_CLASS(wxMenu, wxEvtHandler)
-IMPLEMENT_DYNAMIC_CLASS(wxMenuBar, wxEvtHandler)
-
-// the (popup) menu title has this special id
+// the (popup) menu title has this special menuid
static const int idMenuTitle = -3;
// ============================================================================
// implementation
// ============================================================================
-static void wxMenubarUnsetInvokingWindow( wxMenu *menu ) ;
-static void wxMenubarSetInvokingWindow( wxMenu *menu, wxWindow *win );
// Menus
// Construct a menu with optional title (then use append)
-static
-wxMenu *
-_wxMenuAt(const wxMenuList &menuList, size_t pos)
-{
- wxMenuList::compatibility_iterator menuIter = menuList.GetFirst();
-
- while (pos-- > 0)
- menuIter = menuIter->GetNext();
-
- return menuIter->GetData() ;
-}
-
void wxMenu::Init()
{
m_doBreak = false;
- m_startRadioGroup = -1;
m_allowRearrange = true;
m_noEventsMode = false;
-
+
m_peer = wxMenuImpl::Create( this, wxStripMenuCodes(m_title) );
// not available on the mac platform
}
-void wxMenu::Attach(wxMenuBarBase *menubar)
-{
- wxMenuBase::Attach(menubar);
-
- EndRadioGroup();
-}
-
void wxMenu::SetAllowRearrange( bool allow )
{
m_allowRearrange = allow;
// function appends a new item or submenu to the menu
// append a new item or submenu to the menu
-bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos)
+bool wxMenu::DoInsertOrAppend(wxMenuItem *item, size_t pos)
{
- wxASSERT_MSG( pItem != NULL, wxT("can't append NULL item to the menu") );
- m_peer->InsertOrAppend( pItem, pos );
+ wxASSERT_MSG( item != NULL, wxT("can't append NULL item to the menu") );
+ GetPeer()->InsertOrAppend( item, pos );
+
+ bool check = false;
- if ( pItem->IsSeparator() )
+ if ( item->IsSeparator() )
{
// nothing to do here
}
else
{
- wxMenu *pSubMenu = pItem->GetSubMenu() ;
+ wxMenu *pSubMenu = item->GetSubMenu() ;
if ( pSubMenu != NULL )
{
wxASSERT_MSG( pSubMenu->GetHMenu() != NULL , wxT("invalid submenu added"));
pSubMenu->DoRearrange();
}
- else
- {
- if ( pItem->GetId() == idMenuTitle )
- pItem->GetMenu()->Enable( idMenuTitle, false );
- }
- }
-
- // if we're already attached to the menubar, we must update it
- if ( IsAttached() && GetMenuBar()->IsAttached() )
- GetMenuBar()->Refresh();
+ else if ( item->IsRadio() )
+ {
+ // If a previous or next item is a radio button, add this radio
+ // button to the existing radio group. Otherwise start a new one
+ // for it.
+ wxMenuItemList& items = GetMenuItems();
- return true ;
-}
+ size_t const
+ posItem = pos == (size_t)-1 ? items.GetCount() - 1 : pos;
-void wxMenu::EndRadioGroup()
-{
- // we're not inside a radio group any longer
- m_startRadioGroup = -1;
-}
+ wxMenuItemList::compatibility_iterator node = items.Item(posItem);
+ wxCHECK_MSG( node, false, wxS("New item must have been inserted") );
-wxMenuItem* wxMenu::DoAppend(wxMenuItem *item)
-{
- wxCHECK_MSG( item, NULL, _T("NULL item in wxMenu::DoAppend") );
+ bool foundGroup = false;
+ if ( node->GetPrevious() )
+ {
+ wxMenuItem* const prev = node->GetPrevious()->GetData();
- bool check = false;
+ if ( prev->IsRadio() )
+ {
+ // This item is in the same group as the preceding one so
+ // we should use the same starting item, but getting it is
+ // a bit difficult as we can't query the start radio group
+ // item for it.
+ const int groupStart = prev->IsRadioGroupStart()
+ ? posItem - 1
+ : prev->GetRadioGroupStart();
+ item->SetRadioGroupStart(groupStart);
+
+ // We must also account for the new item by incrementing
+ // the index of the last item in this group.
+ wxMenuItem* const first = items.Item(groupStart)->GetData();
+ first->SetRadioGroupEnd(first->GetRadioGroupEnd() + 1);
+
+ foundGroup = true;
+ }
+ }
- if ( item->GetKind() == wxITEM_RADIO )
- {
- int count = GetMenuItemCount();
+ if ( !foundGroup && node->GetNext() )
+ {
+ wxMenuItem* const next = node->GetNext()->GetData();
- if ( m_startRadioGroup == -1 )
- {
- // start a new radio group
- m_startRadioGroup = count;
+ if ( next->IsRadio() )
+ {
+ // This item is the new starting item of this group as the
+ // previous item is not a radio item.
+ wxASSERT_MSG( next->IsRadioGroupStart(),
+ wxS("Where is the start of this group?") );
- // for now it has just one element
- item->SetAsRadioGroupStart();
- item->SetRadioGroupEnd(m_startRadioGroup);
+ // The index of the last item of the radio group must be
+ // incremented to account for the new item.
+ item->SetAsRadioGroupStart();
+ item->SetRadioGroupEnd(next->GetRadioGroupEnd() + 1);
- // ensure that we have a checked item in the radio group
- check = true;
- }
- else // extend the current radio group
- {
- // we need to update its end item
- item->SetRadioGroupStart(m_startRadioGroup);
- wxMenuItemList::compatibility_iterator node = GetMenuItems().Item(m_startRadioGroup);
+ // And the previous start item is not one any longer.
+ next->SetAsRadioGroupStart(false);
- if ( node )
- {
- node->GetData()->SetRadioGroupEnd(count);
+ foundGroup = true;
+ }
}
- else
+
+ if ( !foundGroup )
{
- wxFAIL_MSG( _T("where is the radio group start item?") );
+ // start a new radio group
+ item->SetAsRadioGroupStart();
+ item->SetRadioGroupEnd(posItem);
+
+ // ensure that we have a checked item in the radio group
+ check = true;
}
}
+ else
+ {
+ if ( item->GetId() == idMenuTitle )
+ item->GetMenu()->Enable( idMenuTitle, false );
+ }
}
- else // not a radio item
+
+ // We also need to update the indices of radio group start and end we store
+ // in any existing radio items after this item.
+ if ( pos < GetMenuItemCount() - 1 ) // takes into account pos == -1 case
{
- EndRadioGroup();
+ for ( wxMenuItemList::compatibility_iterator
+ node = GetMenuItems().Item(pos + 1);
+ node;
+ node = node->GetNext() )
+ {
+ wxMenuItem* const item = node->GetData();
+ if ( item->IsRadio() )
+ {
+ if ( item->IsRadioGroupStart() )
+ {
+ // If the starting item is after the just inserted one,
+ // then the end one must be after it too and needs to be
+ // updated.
+ item->SetRadioGroupEnd(item->GetRadioGroupEnd() + 1);
+ }
+ else // Not the first radio group item.
+ {
+ // We need to update the start item index only if it is
+ // after the just inserted item.
+ const int groupStart = item->GetRadioGroupStart();
+ if ( (size_t)groupStart > pos )
+ item->SetRadioGroupStart(groupStart + 1);
+ }
+ }
+ }
}
- if ( !wxMenuBase::DoAppend(item) || !DoInsertOrAppend(item) )
- return NULL;
+ // if we're already attached to the menubar, we must update it
+ if ( IsAttached() && GetMenuBar()->IsAttached() )
+ GetMenuBar()->Refresh();
if ( check )
- // check the item initially
item->Check(true);
- return item;
+ return true ;
+}
+
+wxMenuItem* wxMenu::DoAppend(wxMenuItem *item)
+{
+ if (wxMenuBase::DoAppend(item) && DoInsertOrAppend(item) )
+ return item;
+
+ return NULL;
}
wxMenuItem* wxMenu::DoInsert(size_t pos, wxMenuItem *item)
wxMenuItem *wxMenu::DoRemove(wxMenuItem *item)
{
+ if ( item->IsRadio() )
+ {
+ // Check if we're removing the item starting the radio group
+ if ( item->IsRadioGroupStart() )
+ {
+ // Yes, we do, update the next radio group item, if any, to be the
+ // start one now.
+ const int endGroup = item->GetRadioGroupEnd();
+
+ wxMenuItemList::compatibility_iterator
+ node = GetMenuItems().Item(endGroup);
+ wxASSERT_MSG( node, wxS("Should have valid radio group end") );
+
+ while ( node->GetData() != item )
+ {
+ const wxMenuItemList::compatibility_iterator
+ prevNode = node->GetPrevious();
+ wxMenuItem* const prevItem = prevNode->GetData();
+ if ( prevItem == item )
+ {
+ prevItem->SetAsRadioGroupStart();
+ prevItem->SetRadioGroupEnd(endGroup);
+ break;
+ }
+
+ node = prevNode;
+ }
+ }
+ }
+
/*
// we need to find the items position in the child list
size_t pos;
wxOSXMenuRemoveItem(m_hMenu , pos );
*/
- m_peer->Remove( item );
+ GetPeer()->Remove( item );
// and from internal data structures
return wxMenuBase::DoRemove(item);
}
void wxMenu::SetTitle(const wxString& label)
{
m_title = label ;
- m_peer->SetTitle( wxStripMenuCodes( label ) );
+ GetPeer()->SetTitle( wxStripMenuCodes( label ) );
}
bool wxMenu::ProcessCommand(wxCommandEvent & event)
// Try the window the menu was popped up from
// (and up through the hierarchy)
- wxWindow *win = GetInvokingWindow();
+ wxWindow *win = GetWindow();
if ( !processed && win )
processed = win->HandleWindowEvent(event);
// other
// ---------------------------------------------------------------------------
-wxWindow *wxMenu::GetWindow() const
-{
- if ( m_invokingWindow != NULL )
- return m_invokingWindow;
- else if ( GetMenuBar() != NULL)
- return (wxWindow *) GetMenuBar()->GetFrame();
-
- return NULL;
-}
-
// MacOS needs to know about submenus somewhere within this menu
// before it can be displayed, also hide special menu items
// like preferences that are handled by the OS
{
if ( !AllowRearrange() )
return;
-
+
wxMenuItem* previousItem = NULL ;
size_t pos ;
wxMenuItemList::compatibility_iterator node;
{
// next (i.e. second as we must be first) item is
// the separator to hide
- wxASSERT_MSG( pos == 0, _T("should be the menu start") );
+ wxASSERT_MSG( pos == 0, wxT("should be the menu start") );
sepToHide = next;
}
else if ( GetMenuItems().GetCount() == pos + 1 &&
bool wxMenu::HandleCommandUpdateStatus( wxMenuItem* item, wxWindow* senderWindow )
{
- int id = item ? item->GetId() : 0;
- wxUpdateUIEvent event(id);
+ int menuid = item ? item->GetId() : 0;
+ wxUpdateUIEvent event(menuid);
event.SetEventObject( this );
bool processed = false;
// (and up through the hierarchy)
if ( !processed )
{
- const wxMenuBase *menu = this;
- while ( menu )
- {
- wxWindow *win = menu->GetInvokingWindow();
- if ( win )
- {
- processed = win->HandleWindowEvent(event);
- break;
- }
-
- menu = menu->GetParent();
- }
+ wxWindow *win = GetWindow();
+ if ( win )
+ processed = win->HandleWindowEvent(event);
}
if ( !processed && senderWindow != NULL)
{
// if anything changed, update the changed attribute
if (event.GetSetText())
- SetLabel(id, event.GetText());
+ SetLabel(menuid, event.GetText());
if (event.GetSetChecked())
- Check(id, event.GetChecked());
+ Check(menuid, event.GetChecked());
if (event.GetSetEnabled())
- Enable(id, event.GetEnabled());
+ Enable(menuid, event.GetEnabled());
}
+ else
+ {
+#if wxOSX_USE_CARBON
+ // these two items are also managed by the Carbon Menu Manager, therefore we must
+ // always reset them ourselves
+ UInt32 cmd = 0;
+
+ if ( menuid == wxApp::s_macExitMenuItemId )
+ {
+ cmd = kHICommandQuit;
+ }
+ else if (menuid == wxApp::s_macPreferencesMenuItemId )
+ {
+ cmd = kHICommandPreferences;
+ }
+
+ if ( cmd != 0 )
+ {
+ if ( !item->IsEnabled() || wxDialog::OSXHasModalDialogsOpen() )
+ DisableMenuCommand( NULL , cmd ) ;
+ else
+ EnableMenuCommand( NULL , cmd ) ;
+
+ }
+#endif
+ }
+
return processed;
}
bool wxMenu::HandleCommandProcess( wxMenuItem* item, wxWindow* senderWindow )
{
- int id = item ? item->GetId() : 0;
+ int menuid = item ? item->GetId() : 0;
bool processed = false;
if (item->IsCheckable())
item->Check( !item->IsChecked() ) ;
- if ( SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) )
+ if ( SendEvent( menuid , item->IsCheckable() ? item->IsChecked() : -1 ) )
processed = true ;
else
{
if ( senderWindow != NULL )
{
- wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED , id);
- event.SetEventObject(senderWindow);
+ wxCommandEvent event(wxEVT_MENU , menuid);
+ event.SetEventObject(this);
event.SetInt(item->IsCheckable() ? item->IsChecked() : -1);
if ( senderWindow->HandleWindowEvent(event) )
processed = true ;
}
}
+
+ if(!processed && item)
+ {
+ processed = item->GetPeer()->DoDefault();
+ }
+
return processed;
}
void wxMenu::HandleMenuItemHighlighted( wxMenuItem* item )
{
- int id = item ? item->GetId() : 0;
- wxMenuEvent wxevent(wxEVT_MENU_HIGHLIGHT, id, this);
+ int menuid = item ? item->GetId() : 0;
+ wxMenuEvent wxevent(wxEVT_MENU_HIGHLIGHT, menuid, this);
DoHandleMenuEvent( wxevent );
}
-void wxMenu::HandleMenuOpened()
+void wxMenu::DoHandleMenuOpenedOrClosed(wxEventType evtType)
{
- wxMenuEvent wxevent(wxEVT_MENU_OPEN, 0, this);
+ // Popup menu being currently shown or NULL, defined in wincmn.cpp.
+ extern wxMenu *wxCurrentPopupMenu;
+
+ // Set the id to allow wxMenuEvent::IsPopup() to work correctly.
+ int menuid = this == wxCurrentPopupMenu ? wxID_ANY : 0;
+ wxMenuEvent wxevent(evtType, menuid, this);
DoHandleMenuEvent( wxevent );
}
+void wxMenu::HandleMenuOpened()
+{
+ DoHandleMenuOpenedOrClosed(wxEVT_MENU_OPEN);
+}
+
void wxMenu::HandleMenuClosed()
{
- wxMenuEvent wxevent(wxEVT_MENU_CLOSE, 0, this);
- DoHandleMenuEvent( wxevent );
+ DoHandleMenuOpenedOrClosed(wxEVT_MENU_CLOSE);
}
bool wxMenu::DoHandleMenuEvent(wxEvent& wxevent)
}
else
{
- wxWindow *win = GetInvokingWindow();
+ wxWindow *win = GetWindow();
if (win)
{
if ( win->HandleWindowEvent(wxevent) )
bool wxMenuBar::s_macAutoWindowMenu = true ;
WXHMENU wxMenuBar::s_macWindowMenuHandle = NULL ;
+
+wxMenu* emptyMenuBar = NULL;
+
+const int firstMenuPos = 1; // to account for the 0th application menu on mac
+
void wxMenuBar::Init()
{
+ if ( emptyMenuBar == NULL )
+ {
+ emptyMenuBar = new wxMenu();
+
+ wxMenu* appleMenu = new wxMenu();
+ appleMenu->SetAllowRearrange(false);
+#if !wxOSX_USE_CARBON
+ // standard menu items, handled in wxMenu::HandleCommandProcess(), see above:
+ wxString hideLabel;
+ hideLabel = wxString::Format(_("Hide %s"), wxTheApp ? wxTheApp->GetAppDisplayName() : _("Application"));
+ appleMenu->Append( wxID_OSX_HIDE, hideLabel + "\tCtrl+H" );
+ appleMenu->Append( wxID_OSX_HIDEOTHERS, _("Hide Others")+"\tAlt+Ctrl+H" );
+ appleMenu->Append( wxID_OSX_SHOWALL, _("Show All") );
+ appleMenu->AppendSeparator();
+
+ // Do always add "Quit" item unconditionally however, it can't be disabled.
+ wxString quitLabel;
+ quitLabel = wxString::Format(_("Quit %s"), wxTheApp ? wxTheApp->GetAppDisplayName() : _("Application"));
+ appleMenu->Append( wxApp::s_macExitMenuItemId, quitLabel + "\tCtrl+Q" );
+#endif // !wxOSX_USE_CARBON
+
+ emptyMenuBar->AppendSubMenu(appleMenu, "\x14") ;
+ }
+
m_eventHandler = this;
m_menuBarFrame = NULL;
- m_invokingWindow = (wxWindow*) NULL;
m_rootMenu = new wxMenu();
- wxMenu* applemenu = new wxMenu();
- applemenu->SetAllowRearrange(false);
- applemenu->Append( wxApp::s_macAboutMenuItemId, "About..." );
- applemenu->AppendSeparator();
- applemenu->Append( wxApp::s_macPreferencesMenuItemId, "Preferences..." );
- applemenu->AppendSeparator();
+ m_rootMenu->Attach(this);
+
+ m_appleMenu = new wxMenu();
+ m_appleMenu->SetAllowRearrange(false);
+
+ // Create standard items unless the application explicitly disabled this by
+ // setting the corresponding ids to wxID_NONE: although this is not
+ // recommended, sometimes these items really don't make sense.
+ if ( wxApp::s_macAboutMenuItemId != wxID_NONE )
+ {
+ wxString aboutLabel(_("About"));
+ if ( wxTheApp )
+ aboutLabel << ' ' << wxTheApp->GetAppDisplayName();
+ else
+ aboutLabel << "...";
+ m_appleMenu->Append( wxApp::s_macAboutMenuItemId, aboutLabel);
+ m_appleMenu->AppendSeparator();
+ }
+
+#if !wxOSX_USE_CARBON
+ if ( wxApp::s_macPreferencesMenuItemId != wxID_NONE )
+ {
+ m_appleMenu->Append( wxApp::s_macPreferencesMenuItemId,
+ _("Preferences...") + "\tCtrl+," );
+ m_appleMenu->AppendSeparator();
+ }
+
+ // standard menu items, handled in wxMenu::HandleCommandProcess(), see above:
+ wxString hideLabel;
+ hideLabel = wxString::Format(_("Hide %s"), wxTheApp ? wxTheApp->GetAppDisplayName() : _("Application"));
+ m_appleMenu->Append( wxID_OSX_HIDE, hideLabel + "\tCtrl+H" );
+ m_appleMenu->Append( wxID_OSX_HIDEOTHERS, _("Hide Others")+"\tAlt+Ctrl+H" );
+ m_appleMenu->Append( wxID_OSX_SHOWALL, _("Show All") );
+ m_appleMenu->AppendSeparator();
-#if ! wxOSX_USE_CARBON
- applemenu->Append( wxApp::s_macExitMenuItemId, "Quit\tCtrl+Q" );
-#endif
+ // Do always add "Quit" item unconditionally however, it can't be disabled.
+ wxString quitLabel;
+ quitLabel = wxString::Format(_("Quit %s"), wxTheApp ? wxTheApp->GetAppDisplayName() : _("Application"));
+ m_appleMenu->Append( wxApp::s_macExitMenuItemId, quitLabel + "\tCtrl+Q" );
+#endif // !wxOSX_USE_CARBON
- m_rootMenu->AppendSubMenu(applemenu, "\x14") ;
+ m_rootMenu->AppendSubMenu(m_appleMenu, "\x14") ;
}
wxMenuBar::wxMenuBar()
{
Init();
- m_titles.Alloc(count);
-
for ( size_t i = 0; i < count; i++ )
{
m_menus.Append(menus[i]);
- m_titles.Add(titles[i]);
menus[i]->Attach(this);
Append( menus[i], titles[i] );
if (s_macInstalledMenuBar == this)
{
+ emptyMenuBar->GetPeer()->MakeRoot();
s_macInstalledMenuBar = NULL;
}
+ wxDELETE( m_rootMenu );
+ // apple menu is a submenu, therefore we don't have to delete it
+ m_appleMenu = NULL;
+
+ // deleting the root menu also removes all its wxMenu* submenus, therefore
+ // we must avoid double deleting them in the superclass destructor
+ m_menus.clear();
}
void wxMenuBar::Refresh(bool WXUNUSED(eraseBackground), const wxRect *WXUNUSED(rect))
{
if ( s_macInstalledMenuBar == this )
return ;
-
- m_rootMenu->GetPeer()->MakeRoot();
-#if 0
- MenuBarHandle menubar = NULL ;
-
- menubar = NewHandleClear( 6 /* sizeof( MenuBarHeader ) */ ) ;
-
- ::SetMenuBar( menubar ) ;
- DisposeMenuBar( menubar ) ;
- MenuHandle appleMenu = NULL ;
-
- verify_noerr( CreateNewMenu( kwxMacAppleMenuId , 0 , &appleMenu ) ) ;
- verify_noerr( SetMenuTitleWithCFString( appleMenu , CFSTR( "\x14" ) ) );
+ m_rootMenu->GetPeer()->MakeRoot();
+
+ // hide items in the apple menu that don't exist in the wx menubar
+
+ wxMenuItem* appleItem = NULL;
+ wxMenuItem* wxItem = NULL;
- // Add About/Preferences separator only on OS X
- // KH/RN: Separator is always present on 10.3 but not on 10.2
- // However, the change from 10.2 to 10.3 suggests it is preferred
- InsertMenuItemTextWithCFString( appleMenu,
- CFSTR(""), 0, kMenuItemAttrSeparator, 0);
- InsertMenuItemTextWithCFString( appleMenu,
- CFSTR("About..."), 0, 0, 0);
- MacInsertMenu( appleMenu , 0 ) ;
+ int menuid = wxApp::s_macAboutMenuItemId;
+ appleItem = m_appleMenu->FindItem(menuid);
+ wxItem = FindItem(menuid);
+ if ( appleItem != NULL )
+ {
+ if ( wxItem == NULL )
+ appleItem->GetPeer()->Hide();
+ else
+ appleItem->SetItemLabel(wxItem->GetItemLabel());
+ }
+
+ menuid = wxApp::s_macPreferencesMenuItemId;
+ appleItem = m_appleMenu->FindItem(menuid);
+ wxItem = FindItem(menuid);
+ if ( appleItem != NULL )
+ {
+ if ( wxItem == NULL )
+ appleItem->GetPeer()->Hide();
+ else
+ appleItem->SetItemLabel(wxItem->GetItemLabel());
+ }
+
+
+#if 0
// if we have a mac help menu, clean it up before adding new items
MenuHandle helpMenuHandle ;
subMenu = item->GetSubMenu() ;
if (subMenu)
{
- // we don't support hierarchical menus in the help menu yet
+ UMAAppendMenuItem(mh, wxStripMenuCodes(item->GetText()) , wxFont::GetDefaultEncoding() );
+ MenuItemIndex position = CountMenuItems(mh);
+ ::SetMenuItemHierarchicalMenu(mh, position, MAC_WXHMENU(subMenu->GetHMenu()));
}
else
{
UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , m_titles[i], GetFont().GetEncoding() ) ;
menu->MacBeforeDisplay(false) ;
- ::InsertMenu(MAC_WXHMENU(_wxMenuAt(m_menus, i)->GetHMenu()), 0);
+ ::InsertMenu(MAC_WXHMENU(GetMenu(i)->GetHMenu()), 0);
}
}
void wxMenuBar::EnableTop(size_t pos, bool enable)
{
wxCHECK_RET( IsAttached(), wxT("doesn't work with unattached menubars") );
-
- m_rootMenu->FindItemByPosition( pos )->Enable(enable);
+
+ m_rootMenu->FindItemByPosition(pos+firstMenuPos)->Enable(enable);
Refresh();
}
+bool wxMenuBar::IsEnabledTop(size_t pos) const
+{
+ wxCHECK_MSG( IsAttached(), true,
+ wxT("doesn't work with unattached menubars") );
+
+ wxMenuItem* const item = m_rootMenu->FindItemByPosition(pos+firstMenuPos);
+ wxCHECK_MSG( item, false, wxT("invalid menu index") );
+
+ return item->IsEnabled();
+}
+
bool wxMenuBar::Enable(bool enable)
{
wxCHECK_MSG( IsAttached(), false, wxT("doesn't work with unattached menubars") );
{
wxCHECK_RET( pos < GetMenuCount(), wxT("invalid menu index") );
- m_titles[pos] = label;
-
- if ( !IsAttached() )
- return;
-
- _wxMenuAt(m_menus, pos)->SetTitle( label ) ;
+ GetMenu(pos)->SetTitle( label ) ;
}
wxString wxMenuBar::GetMenuLabel(size_t pos) const
wxCHECK_MSG( pos < GetMenuCount(), wxEmptyString,
wxT("invalid menu index in wxMenuBar::GetMenuLabel") );
- return m_titles[pos];
-}
-
-int wxMenuBar::FindMenu(const wxString& title)
-{
- wxString menuTitle = wxStripMenuCodes(title);
-
- size_t count = GetMenuCount();
- for ( size_t i = 0; i < count; i++ )
- {
- wxString title = wxStripMenuCodes(m_titles[i]);
- if ( menuTitle == title )
- return i;
- }
-
- return wxNOT_FOUND;
+ return GetMenu(pos)->GetTitle();
}
// ---------------------------------------------------------------------------
// wxMenuBar construction
// ---------------------------------------------------------------------------
-const int firstMenuPos = 1; // to account for the 0th application menu on mac
-
wxMenu *wxMenuBar::Replace(size_t pos, wxMenu *menu, const wxString& title)
{
wxMenu *menuOld = wxMenuBarBase::Replace(pos, menu, title);
if ( !menuOld )
return NULL;
- m_titles[pos] = title;
-
wxMenuItem* item = m_rootMenu->FindItemByPosition(pos+firstMenuPos);
m_rootMenu->Remove(item);
m_rootMenu->Insert( pos+firstMenuPos, wxMenuItem::New( m_rootMenu, wxID_ANY, title, "", wxITEM_NORMAL, menu ) );
- if (m_invokingWindow)
- wxMenubarSetInvokingWindow( menu, m_invokingWindow );
-
return menuOld;
}
if ( !wxMenuBarBase::Insert(pos, menu, title) )
return false;
- m_titles.Insert(title, pos);
-
m_rootMenu->Insert( pos+firstMenuPos, wxMenuItem::New( m_rootMenu, wxID_ANY, title, "", wxITEM_NORMAL, menu ) );
-
- if (m_invokingWindow)
- wxMenubarSetInvokingWindow( menu, m_invokingWindow );
+ menu->SetTitle(title);
return true;
}
wxMenuItem* item = m_rootMenu->FindItemByPosition(pos+firstMenuPos);
m_rootMenu->Remove(item);
- m_titles.RemoveAt(pos);
-
return menu;
}
if ( !wxMenuBarBase::Append(menu, title) )
return false;
- m_titles.Add(title);
-
m_rootMenu->AppendSubMenu(menu, title);
-
- // m_invokingWindow is set after wxFrame::SetMenuBar(). This call enables
- // adding menu later on.
- if (m_invokingWindow)
- wxMenubarSetInvokingWindow( menu, m_invokingWindow );
+ menu->SetTitle(title);
return true;
}
-static void wxMenubarUnsetInvokingWindow( wxMenu *menu )
-{
- menu->SetInvokingWindow( (wxWindow*) NULL );
- wxMenuItemList::compatibility_iterator node = menu->GetMenuItems().GetFirst();
-
- while (node)
- {
- wxMenuItem *menuitem = node->GetData();
- if (menuitem->IsSubMenu())
- wxMenubarUnsetInvokingWindow( menuitem->GetSubMenu() );
-
- node = node->GetNext();
- }
-}
-
-static void wxMenubarSetInvokingWindow( wxMenu *menu, wxWindow *win )
-{
- menu->SetInvokingWindow( win );
- wxMenuItem *menuitem;
- wxMenuItemList::compatibility_iterator node = menu->GetMenuItems().GetFirst();
-
- while (node)
- {
- menuitem = node->GetData();
- if (menuitem->IsSubMenu())
- wxMenubarSetInvokingWindow( menuitem->GetSubMenu() , win );
-
- node = node->GetNext();
- }
-}
-
-void wxMenuBar::UnsetInvokingWindow()
-{
- m_invokingWindow = (wxWindow*) NULL;
- wxMenu *menu;
- wxMenuList::compatibility_iterator node = m_menus.GetFirst();
-
- while (node)
- {
- menu = node->GetData();
- wxMenubarUnsetInvokingWindow( menu );
-
- node = node->GetNext();
- }
-}
-
-void wxMenuBar::SetInvokingWindow(wxFrame *frame)
-{
- m_invokingWindow = frame;
- wxMenu *menu;
- wxMenuList::compatibility_iterator node = m_menus.GetFirst();
-
- while (node)
- {
- menu = node->GetData();
- wxMenubarSetInvokingWindow( menu, frame );
-
- node = node->GetNext();
- }
-}
-
void wxMenuBar::Detach()
{
wxMenuBarBase::Detach() ;
wxMenuBarBase::Attach( frame ) ;
}
-// ---------------------------------------------------------------------------
-// wxMenuBar searching for menu items
-// ---------------------------------------------------------------------------
-
-// Find the itemString in menuString, and return the item id or wxNOT_FOUND
-int wxMenuBar::FindMenuItem(const wxString& menuString,
- const wxString& itemString) const
-{
- wxString menuLabel = wxStripMenuCodes(menuString);
- size_t count = GetMenuCount();
- for ( size_t i = 0; i < count; i++ )
- {
- wxString title = wxStripMenuCodes(m_titles[i]);
- if ( menuLabel == title )
- return _wxMenuAt(m_menus, i)->FindItem(itemString);
- }
-
- return wxNOT_FOUND;
-}
-
-wxMenuItem *wxMenuBar::FindItem(int id, wxMenu **itemMenu) const
-{
- if ( itemMenu )
- *itemMenu = NULL;
-
- wxMenuItem *item = NULL;
- size_t count = GetMenuCount();
- for ( size_t i = 0; !item && (i < count); i++ )
- item = _wxMenuAt(m_menus, i)->FindItem(id, itemMenu);
-
- return item;
-}
+#endif // wxUSE_MENUS