]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/menu.cpp
moved win_gtk.h header to wx/gtk/private, it's for internal use only
[wxWidgets.git] / src / mac / carbon / menu.cpp
index b22001b870b32f575de8fcda9122758d5177a9f4..23e288ea882c407fef1575cf6a0798b730ecf068 100644 (file)
@@ -1,31 +1,32 @@
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
-// Name:        menu.cpp
+// Name:        src/mac/carbon/menu.cpp
 // Purpose:     wxMenu, wxMenuBar, wxMenuItem
 // Purpose:     wxMenu, wxMenuBar, wxMenuItem
-// Author:      AUTHOR
+// Author:      Stefan Csomor
 // Modified by:
 // Modified by:
-// Created:     ??/??/98
+// Created:     1998-01-01
 // RCS-ID:      $Id$
 // RCS-ID:      $Id$
-// Copyright:   (c) AUTHOR
-// Licence:    wxWindows licence
+// Copyright:   (c) Stefan Csomor
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 /////////////////////////////////////////////////////////////////////////////
 
-
 // ============================================================================
 // headers & declarations
 // ============================================================================
 
 // ============================================================================
 // headers & declarations
 // ============================================================================
 
-// wxWindows headers
+// wxWidgets headers
 // -----------------
 
 // -----------------
 
-#ifdef __GNUG__
-#pragma implementation "menu.h"
-#pragma implementation "menuitem.h"
-#endif
+#include "wx/wxprec.h"
 
 #include "wx/menu.h"
 
 #include "wx/menu.h"
-#include "wx/menuitem.h"
-#include "wx/log.h"
-#include "wx/utils.h"
+
+#ifndef WX_PRECOMP
+    #include "wx/log.h"
+    #include "wx/app.h"
+    #include "wx/utils.h"
+    #include "wx/frame.h"
+    #include "wx/menuitem.h"
+#endif
 
 #include "wx/mac/uma.h"
 
 
 #include "wx/mac/uma.h"
 
 // ----------------------
 #include <string.h>
 
 // ----------------------
 #include <string.h>
 
-#if !USE_SHARED_LIBRARY
 IMPLEMENT_DYNAMIC_CLASS(wxMenu, wxEvtHandler)
 IMPLEMENT_DYNAMIC_CLASS(wxMenuBar, wxEvtHandler)
 IMPLEMENT_DYNAMIC_CLASS(wxMenu, wxEvtHandler)
 IMPLEMENT_DYNAMIC_CLASS(wxMenuBar, wxEvtHandler)
-#endif
 
 // the (popup) menu title has this special id
 
 // the (popup) menu title has this special id
-static const int idMenuTitle = -2;
-static int formerHelpMenuItems = 0 ;
+static const int idMenuTitle = -3;
 
 
-const short kwxMacMenuBarResource = 1 ;
-const short kwxMacAppleMenuId = 1 ;
+static const short kwxMacAppleMenuId = 1 ;
 
 
-// ============================================================================
-// implementation
-// ============================================================================
 
 
-//
-// Helper Functions to get Mac Menus the way they should be ;-)
-//
+// Find an item given the Macintosh Menu Reference
+
+WX_DECLARE_HASH_MAP(MenuRef, wxMenu*, wxPointerHash, wxPointerEqual, MacMenuMap);
+
+static MacMenuMap wxWinMacMenuList;
 
 
-void wxMacCtoPString(const char* theCString, Str255 thePString);
+wxMenu *wxFindMenuFromMacMenu(MenuRef inMenuRef)
+{
+    MacMenuMap::iterator node = wxWinMacMenuList.find(inMenuRef);
 
 
-// remove inappropriate characters, if useShortcuts is false, the ampersand will not auto-generate a mac menu-shortcut
+    return (node == wxWinMacMenuList.end()) ? NULL : node->second;
+}
 
 
-static void wxMacBuildMenuString(StringPtr outMacItemText, char *outMacShortcutChar , short *outMacModifiers , const char *inItemName , bool useShortcuts )
+void wxAssociateMenuWithMacMenu(MenuRef inMenuRef, wxMenu *menu) ;
+void wxAssociateMenuWithMacMenu(MenuRef inMenuRef, wxMenu *menu)
 {
 {
-       char *p = (char *) &outMacItemText[1] ;
-       short macModifiers = 0 ;
-       char macShortCut = 0 ;
-       
-       if ( useShortcuts && !wxApp::s_macSupportPCMenuShortcuts )
-               useShortcuts = false ;
-       
-       // we have problems with a leading hypen - it will be taken as a separator
-       
-       while ( *inItemName == '-' )
-               inItemName++ ;
-               
-       while( *inItemName )
-       {
-               switch ( *inItemName )
-               {
-                       // special characters for macintosh menus -> use some replacement
-                       case ';' :
-                               *p++ = ',' ;
-                               break ;
-                       case '^' :
-                               *p++ = ' ' ;
-                               break ;
-                       case '!' :
-                               *p++ = ' ' ;
-                               break ;
-                       case '<' :
-                               *p++ = ' ' ;
-                               break ;
-                       case '/' :
-                               *p++ = '|' ;
-                               break ;
-                       case '(' :
-                               *p++ = '[' ;
-                               break ;
-                       case ')' :      
-                               *p++ = ']' ;
-                               break ;
-                       // shortcuts
-                       case '&' :
-                               {
-                                       ++inItemName ;
-                                       if ( *inItemName )
-                                       {
-                                               *p++ = *inItemName ;
-                                               if ( useShortcuts )
-                                                       macShortCut = *inItemName ;
-                                       }
-                                       else
-                                               --inItemName ;
-                               }
-                               break ;
-                       // win-like accelerators
-                       case '\t' :
-                               {
-                                       ++inItemName ;
-                                       while( *inItemName )
-                                       {
-                                               if (strncmp("Ctrl+", inItemName, 5) == 0) 
-                                               {
-                                                       inItemName = inItemName + 5;
-                                                       macShortCut = *inItemName;
-                                               }
-                                               else if (strncmp("Alt+", inItemName, 4) == 0) 
-                                               {
-                                                       inItemName = inItemName + 4;
-                                                       macModifiers |= kMenuOptionModifier ;
-                                                       macShortCut = *inItemName ;
-                                               }
-                                               else if (strncmp("Shift+", inItemName, 6) == 0) 
-                                               {
-                                                       inItemName = inItemName + 6;
-                                                       macModifiers |= kMenuShiftModifier ;
-                                                       macShortCut = *inItemName ;
-                                               }
-                                               else if (strncmp("F", inItemName, 1) == 0) 
-                                               {
-                                                       inItemName += strlen( inItemName ) ;
-                                                       // no function keys at the moment
-                                                       // macModifiers |= kMenuShiftModifier ;
-                                                       // macShortCut = *inItemName ;
-                                               }
-                                               else
-                                               {
-                                                       break ;
-                                               }
-                                       }
-
-                                       if ( *inItemName == 0 )
-                                               --inItemName ;
-                                               
-                               }
-                               break ;
-                       default :
-                               *p++ = *inItemName ;
-               }
-               ++inItemName ;
-       }
-
-       outMacItemText[0] = (p - (char *)outMacItemText) - 1;
-       if ( outMacShortcutChar )
-               *outMacShortcutChar = macShortCut ;
-       if ( outMacModifiers )
-               *outMacModifiers = macModifiers ;
-       if ( macShortCut )
-       {
-                       int pos = outMacItemText[0] ;
-                       outMacItemText[++pos] = '/';
-                       outMacItemText[++pos] = toupper( macShortCut );
-                       outMacItemText[0] = pos ;
-       }
+    // adding NULL MenuRef is (first) surely a result of an error and
+    // (secondly) breaks menu command processing
+    wxCHECK_RET( inMenuRef != (MenuRef) NULL, wxT("attempt to add a NULL MenuRef to menu list") );
+
+    wxWinMacMenuList[inMenuRef] = menu;
 }
 
 }
 
+void wxRemoveMacMenuAssociation(wxMenu *menu) ;
+void wxRemoveMacMenuAssociation(wxMenu *menu)
+{
+   // iterate over all the elements in the class
+    MacMenuMap::iterator it;
+    for ( it = wxWinMacMenuList.begin(); it != wxWinMacMenuList.end(); ++it )
+    {
+        if ( it->second == menu )
+        {
+            wxWinMacMenuList.erase(it);
+            break;
+        }
+    }
+}
+
+void wxInsertMenuItemsInMenu(wxMenu* menu, MenuRef wm, MenuItemIndex insertAfter)
+{
+    wxMenuItemList::compatibility_iterator node;
+    wxMenuItem *item;
+    wxMenu *subMenu = NULL ;
+    bool newItems = false;
+
+    for (node = menu->GetMenuItems().GetFirst(); node; node = node->GetNext())
+    {
+        item = (wxMenuItem *)node->GetData();
+        subMenu = item->GetSubMenu() ;
+        if (subMenu)
+        {
+            wxInsertMenuItemsInMenu(subMenu, (MenuRef)subMenu->GetHMenu(), 0);
+        }
+        if ( item->IsSeparator() )
+        {
+            if ( wm && newItems)
+                InsertMenuItemTextWithCFString( wm,
+                    CFSTR(""), insertAfter, kMenuItemAttrSeparator, 0);
+
+            newItems = false;
+        }
+        else
+        {
+            wxAcceleratorEntry*
+                entry = wxAcceleratorEntry::Create( item->GetItemLabel() ) ;
+
+            MenuItemIndex winListPos = (MenuItemIndex)-1;
+            OSStatus err = GetIndMenuItemWithCommandID(wm,
+                        wxIdToMacCommand ( item->GetId() ), 1, NULL, &winListPos);
+
+            if ( wm && err == menuItemNotFoundErr )
+            {
+                // NB: the only way to determine whether or not we should add
+                // a separator is to know if we've added menu items to the menu
+                // before the separator.
+                newItems = true;
+                UMAInsertMenuItem(wm, wxStripMenuCodes(item->GetItemLabel()) , wxFont::GetDefaultEncoding(), insertAfter, entry);
+                SetMenuItemCommandID( wm , insertAfter+1 , wxIdToMacCommand ( item->GetId() ) ) ;
+                SetMenuItemRefCon( wm , insertAfter+1 , (URefCon) item ) ;
+            }
+
+            delete entry ;
+        }
+    }
+}
+
+// ============================================================================
+// implementation
+// ============================================================================
+static void wxMenubarUnsetInvokingWindow( wxMenu *menu ) ;
+static void wxMenubarSetInvokingWindow( wxMenu *menu, wxWindow *win );
+
 // Menus
 
 // Construct a menu with optional title (then use append)
 
 // Menus
 
 // Construct a menu with optional title (then use append)
 
+#ifdef __DARWIN__
+short wxMenu::s_macNextMenuId = 3 ;
+#else
 short wxMenu::s_macNextMenuId = 2 ;
 short wxMenu::s_macNextMenuId = 2 ;
+#endif
 
 
-wxMenu::wxMenu(const wxString& title, const wxFunction func)
+static
+wxMenu *
+_wxMenuAt(const wxMenuList &menuList, size_t pos)
 {
 {
-    m_title = title;
-    m_parent = NULL;
-    m_eventHandler = this;
-    m_noItems = 0;
-    m_menuBar = NULL;
-    m_pInvokingWindow = NULL ;
-    m_clientData = (void*) NULL;
-    if (m_title != "")
-    {
-        Append(idMenuTitle, m_title) ;
-        AppendSeparator() ;
-    }
+    wxMenuList::compatibility_iterator menuIter = menuList.GetFirst();
 
 
-    Callback(func);
+    while (pos-- > 0)
+        menuIter = menuIter->GetNext();
 
 
-       Str255  label;
-       wxMacBuildMenuString( label, NULL , NULL , title , false );
-       m_macMenuId = s_macNextMenuId++; 
-    wxCHECK_RET( s_macNextMenuId < 236 , "menu ids > 235 cannot be used for submenus on mac" );
-       m_macMenuHandle = ::NewMenu(m_macMenuId, label);
-       m_macMenuEnabled = true ;
+    return menuIter->GetData() ;
 }
 
 }
 
-// The wxWindow destructor will take care of deleting the submenus.
-wxMenu::~wxMenu()
+void wxMenu::Init()
 {
 {
-    wxNode *node = m_menuItems.First();
-    while (node)
+    m_doBreak = false;
+    m_startRadioGroup = -1;
+
+    // create the menu
+    m_macMenuId = s_macNextMenuId++;
+    m_hMenu = UMANewMenu(m_macMenuId, m_title, wxFont::GetDefaultEncoding() );
+
+    if ( !m_hMenu )
     {
     {
-        wxMenuItem *item = (wxMenuItem *)node->Data();
-
-        // Delete child menus.
-        // Beware: they must not be appended to children list!!!
-        // (because order of delete is significant)
-        if (item->GetSubMenu())
-            item->DeleteSubMenu();
-
-        wxNode *next = node->Next();
-        delete item;
-        delete node;
-        node = next;
+        wxLogLastError(wxT("UMANewMenu failed"));
+    }
+
+    wxAssociateMenuWithMacMenu( (MenuRef)m_hMenu , this ) ;
+
+    // if we have a title, insert it in the beginning of the menu
+    if ( !m_title.empty() )
+    {
+        Append(idMenuTitle, m_title) ;
+        AppendSeparator() ;
     }
     }
-       if (m_macMenuHandle)
-               ::DisposeMenu(m_macMenuHandle);
 }
 
 }
 
-void wxMenu::Break()
+wxMenu::~wxMenu()
 {
 {
-       // not available on the mac platform
+    wxRemoveMacMenuAssociation( this ) ;
+    if (MAC_WXHMENU(m_hMenu))
+        ::DisposeMenu(MAC_WXHMENU(m_hMenu));
 }
 
 }
 
-// function appends a new item or submenu to the menu
-void wxMenu::Append(wxMenuItem *pItem)
+void wxMenu::Break()
 {
 {
-    wxCHECK_RET( pItem != NULL, "can't append NULL item to the menu" );
-
-    m_menuItems.Append(pItem);
-
-       if ( pItem->IsSeparator() )
-       {
-               MacAppendMenu(m_macMenuHandle, "\p-");
-       }
-       else 
-       {
-               wxMenu *pSubMenu = pItem->GetSubMenu() ;
-               if ( pSubMenu != NULL )
-               {
-                       Str255 label;
-                       wxCHECK_RET( pSubMenu->m_macMenuHandle != NULL , "invalid submenu added");
-                   pSubMenu->m_parent = this ;
-                       wxMacBuildMenuString( label , NULL , NULL , pItem->GetName() ,false);
-               
-                       // hardcoded adding of the submenu combination for mac
-               
-                       int theEnd = label[0] + 1; 
-                       if (theEnd > 251) 
-                               theEnd = 251; // mac allows only 255 characters
-                       label[theEnd++] = '/';
-                       label[theEnd++] = hMenuCmd; 
-                       label[theEnd++] = '!';
-                       label[theEnd++] = pSubMenu->m_macMenuId; 
-                       label[theEnd] = 0x00;
-                       label[0] = theEnd;
-
-                       if (wxMenuBar::s_macInstalledMenuBar == m_menuBar) 
-                       {
-                               ::InsertMenu( pSubMenu->m_macMenuHandle , -1 ) ;
-                       }
-                       
-                       ::AppendMenu(m_macMenuHandle, label);
-               }
-               else
-               {
-                       Str255 label ;
-                       wxMacBuildMenuString( label , NULL , NULL , pItem->GetName(), pItem->GetId() == wxApp::s_macAboutMenuItemId);
-                       if ( label[0] == 0 )
-                       {
-                               // we cannot add empty menus on mac
-                               label[0] = 1 ;
-                               label[1] = ' ' ;
-                       }
-                       ::AppendMenu(m_macMenuHandle, label );
-                       if ( pItem->GetId() == idMenuTitle ) 
-                       {
-                                       UMADisableMenuItem( m_macMenuHandle , CountMItems( m_macMenuHandle ) ) ;
-                       }
-               }
-       }
-
-    m_noItems++;
+    // not available on the mac platform
 }
 
 }
 
-void wxMenu::AppendSeparator()
+void wxMenu::Attach(wxMenuBarBase *menubar)
 {
 {
-    Append(new wxMenuItem(this, ID_SEPARATOR));
+    wxMenuBase::Attach(menubar);
+
+    EndRadioGroup();
 }
 
 }
 
-// Pullright item
-void wxMenu::Append(int Id, const wxString& label, wxMenu *SubMenu, 
-                    const wxString& helpString)
+// 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)
 {
 {
-    Append(new wxMenuItem(this, Id, label, helpString, FALSE, SubMenu));
+    wxASSERT_MSG( pItem != NULL, wxT("can't append NULL item to the menu") );
+
+    if ( pItem->IsSeparator() )
+    {
+        if ( pos == (size_t)-1 )
+            AppendMenuItemTextWithCFString( MAC_WXHMENU(m_hMenu),
+                CFSTR(""), kMenuItemAttrSeparator, 0,NULL);
+        else
+            InsertMenuItemTextWithCFString( MAC_WXHMENU(m_hMenu),
+                CFSTR(""), pos, kMenuItemAttrSeparator, 0);
+    }
+    else
+    {
+        wxMenu *pSubMenu = pItem->GetSubMenu() ;
+        if ( pSubMenu != NULL )
+        {
+            wxASSERT_MSG( pSubMenu->m_hMenu != NULL , wxT("invalid submenu added"));
+            pSubMenu->m_menuParent = this ;
+
+            if (wxMenuBar::MacGetInstalledMenuBar() == GetMenuBar())
+                pSubMenu->MacBeforeDisplay( true ) ;
+
+            if ( pos == (size_t)-1 )
+                UMAAppendSubMenuItem(MAC_WXHMENU(m_hMenu), wxStripMenuCodes(pItem->GetItemLabel()), wxFont::GetDefaultEncoding(), pSubMenu->m_macMenuId);
+            else
+                UMAInsertSubMenuItem(MAC_WXHMENU(m_hMenu), wxStripMenuCodes(pItem->GetItemLabel()), wxFont::GetDefaultEncoding(), pos, pSubMenu->m_macMenuId);
+
+            pItem->UpdateItemBitmap() ;
+            pItem->UpdateItemStatus() ;
+        }
+        else
+        {
+            if ( pos == (size_t)-1 )
+            {
+                UMAAppendMenuItem(MAC_WXHMENU(m_hMenu), wxT("a") , wxFont::GetDefaultEncoding() );
+                pos = CountMenuItems(MAC_WXHMENU(m_hMenu)) ;
+            }
+            else
+            {
+                // MacOS counts menu items from 1 and inserts after, therefore having the
+                // same effect as wx 0 based and inserting before, we must correct pos
+                // after however for updates to be correct
+                UMAInsertMenuItem(MAC_WXHMENU(m_hMenu), wxT("a"), wxFont::GetDefaultEncoding(), pos);
+                pos += 1 ;
+            }
+
+            SetMenuItemCommandID( MAC_WXHMENU(m_hMenu) , pos , wxIdToMacCommand ( pItem->GetId() ) ) ;
+            SetMenuItemRefCon( MAC_WXHMENU(m_hMenu) , pos , (URefCon) pItem ) ;
+            pItem->UpdateItemText() ;
+            pItem->UpdateItemBitmap() ;
+            pItem->UpdateItemStatus() ;
+
+            if ( pItem->GetId() == idMenuTitle )
+                UMAEnableMenuItem(MAC_WXHMENU(m_hMenu) , pos , false ) ;
+        }
+    }
+
+    // if we're already attached to the menubar, we must update it
+    if ( IsAttached() && GetMenuBar()->IsAttached() )
+        GetMenuBar()->Refresh();
+
+    return true ;
 }
 
 }
 
-// Ordinary menu item
-void wxMenu::Append(int Id, const wxString& label, 
-                    const wxString& helpString, bool checkable)
+void wxMenu::EndRadioGroup()
 {
 {
-  // 'checkable' parameter is useless for Windows.
-    Append(new wxMenuItem(this, Id, label, helpString, checkable));
+    // we're not inside a radio group any longer
+    m_startRadioGroup = -1;
 }
 
 }
 
-void wxMenu::Delete(int id)
+wxMenuItem* wxMenu::DoAppend(wxMenuItem *item)
 {
 {
-    wxNode *node;
-    wxMenuItem *item;
-    int pos;
+    wxCHECK_MSG( item, NULL, _T("NULL item in wxMenu::DoAppend") );
+
+    bool check = false;
 
 
-    for (pos = 0, node = m_menuItems.First(); node; node = node->Next(), pos++) {
-        item = (wxMenuItem *)node->Data();
-        if (item->GetId() == id)
-               break;
+    if ( item->GetKind() == wxITEM_RADIO )
+    {
+        int count = GetMenuItemCount();
+
+        if ( m_startRadioGroup == -1 )
+        {
+            // start a new radio group
+            m_startRadioGroup = count;
+
+            // for now it has just one element
+            item->SetAsRadioGroupStart();
+            item->SetRadioGroupEnd(m_startRadioGroup);
+
+            // 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);
+
+            if ( node )
+            {
+                node->GetData()->SetRadioGroupEnd(count);
+            }
+            else
+            {
+                wxFAIL_MSG( _T("where is the radio group start item?") );
+            }
+        }
+    }
+    else // not a radio item
+    {
+        EndRadioGroup();
     }
 
     }
 
-    if (!node)
-               return;
-
-    int index = pos + 1 ;
-
-    if (index < 1)
-               return;
-
-       wxMenu *pSubMenu = item->GetSubMenu();
-       if ( pSubMenu != NULL ) 
-       {
-               ::DeleteMenuItem( m_macMenuHandle , index);
-               pSubMenu->m_parent = NULL;
-               // TODO: Why isn't subMenu deleted here???
-               // Will put this in for now. Assuming this is supposed
-               // to delete the menu, not just remove it.
-               item->DeleteSubMenu();
-       }
-       else 
-       {
-               ::DeleteMenuItem( m_macMenuHandle , index);
-       }
-
-    m_menuItems.DeleteNode(node);
-       // TODO shouldn't we do this ? \8e_m_noItems--; 
-    delete item;
-}
+    if ( !wxMenuBase::DoAppend(item) || !DoInsertOrAppend(item) )
+        return NULL;
 
 
-void wxMenu::Enable(int Id, bool Flag)
-{
-    wxMenuItem *item = FindItemForId(Id);
-    wxCHECK_RET( item != NULL, "can't enable non-existing menu item" );
+    if ( check )
+        // check the item initially
+        item->Check(true);
 
 
-    item->Enable(Flag);
+    return item;
 }
 
 }
 
-bool wxMenu::Enabled(int Id) const
+wxMenuItem* wxMenu::DoInsert(size_t pos, wxMenuItem *item)
 {
 {
-    wxMenuItem *item = FindItemForId(Id);
-    wxCHECK( item != NULL, FALSE );
+    if (wxMenuBase::DoInsert(pos, item) && DoInsertOrAppend(item, pos))
+        return item;
 
 
-    return item->IsEnabled();
+    return NULL;
 }
 
 }
 
-void wxMenu::Check(int Id, bool Flag)
+wxMenuItem *wxMenu::DoRemove(wxMenuItem *item)
 {
 {
-    wxMenuItem *item = FindItemForId(Id);
-    wxCHECK_RET( item != NULL, "can't get status of non-existing menu item" );
+    // we need to find the items position in the child list
+    size_t pos;
+    wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst();
 
 
-    item->Check(Flag);
-}
+    for ( pos = 0; node; pos++ )
+    {
+        if ( node->GetData() == item )
+            break;
 
 
-bool wxMenu::Checked(int Id) const
-{
-    wxMenuItem *item = FindItemForId(Id);
-    wxCHECK( item != NULL, FALSE );
+        node = node->GetNext();
+    }
+
+    // DoRemove() (unlike Remove) can only be called for existing item!
+    wxCHECK_MSG( node, NULL, wxT("bug in wxMenu::Remove logic") );
 
 
-    return item->IsChecked();
+    ::DeleteMenuItem(MAC_WXHMENU(m_hMenu) , pos + 1);
+
+    if ( IsAttached() && GetMenuBar()->IsAttached() )
+        // otherwise, the change won't be visible
+        GetMenuBar()->Refresh();
+
+    // and from internal data structures
+    return wxMenuBase::DoRemove(item);
 }
 
 void wxMenu::SetTitle(const wxString& label)
 {
 }
 
 void wxMenu::SetTitle(const wxString& label)
 {
-       Str255 title ;
     m_title = label ;
     m_title = label ;
-       wxMacBuildMenuString( title, NULL , NULL , label , false );
-       UMASetMenuTitle( m_macMenuHandle , title ) ;
-       if (wxMenuBar::s_macInstalledMenuBar == m_menuBar) // are we currently installed ?
-       {
-               ::SetMenuBar( GetMenuBar() ) ;
-               ::InvalMenuBar() ;
-       }
-       // TODO:for submenus -> their parent item text must be corrected
+    UMASetMenuTitle(MAC_WXHMENU(m_hMenu) , label , wxFont::GetDefaultEncoding() ) ;
 }
 
 }
 
-const wxString wxMenu::GetTitle() const
+bool wxMenu::ProcessCommand(wxCommandEvent & event)
 {
 {
-    return m_title;
-}
+    bool processed = false;
 
 
-void wxMenu::SetLabel(int id, const wxString& label)
-{
-    Str255 maclabel ;
-   int index ;
-    wxMenuItem *item = FindItemForId(id) ;
-    if (item==NULL)
-        return;
+    // Try the menu's event handler
+    if ( /* !processed && */ GetEventHandler())
+        processed = GetEventHandler()->SafelyProcessEvent(event);
 
 
-    index = MacGetIndexFromItem( item ) ;
-    if (index < 1)
-               return;
+    // Try the window the menu was popped up from
+    // (and up through the hierarchy)
+    wxWindow *win = GetInvokingWindow();
+    if ( !processed && win )
+        processed = win->HandleWindowEvent(event);
 
 
-    if (item->GetSubMenu()==NULL)
-    {
-               wxMacBuildMenuString( maclabel , NULL , NULL , label , false );
-               ::SetMenuItemText( m_macMenuHandle , index , maclabel ) ;
-    }
-    else
-    {
-               wxMacBuildMenuString( maclabel , NULL , NULL , label , false );
-               ::SetMenuItemText( m_macMenuHandle , index , maclabel ) ;
-    }
-    item->SetName(label);
+    return processed;
 }
 
 }
 
-wxString wxMenu::GetLabel(int Id) const
+// ---------------------------------------------------------------------------
+// other
+// ---------------------------------------------------------------------------
+
+wxWindow *wxMenu::GetWindow() const
 {
 {
-    wxMenuItem *pItem = FindItemForId(Id) ;
-    return pItem->GetName() ;
+    if ( m_invokingWindow != NULL )
+        return m_invokingWindow;
+    else if ( GetMenuBar() != NULL)
+        return (wxWindow *) GetMenuBar()->GetFrame();
+
+    return NULL;
 }
 
 }
 
-// Finds the item id matching the given string, -1 if not found.
-int wxMenu::FindItem (const wxString& itemString) const
-{
-    char buf1[200];
-    char buf2[200];
-    wxStripMenuCodes ((char *)(const char *)itemString, buf1);
+// helper functions returning the mac menu position for a certain item, note that this is
+// mac-wise 1 - based, i.e. the first item has index 1 whereas on MSWin it has pos 0
 
 
-    for (wxNode * node = m_menuItems.First (); node; node = node->Next ())
+int wxMenu::MacGetIndexFromId( int id )
+{
+    size_t pos;
+    wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst();
+    for ( pos = 0; node; pos++ )
     {
     {
-      wxMenuItem *item = (wxMenuItem *) node->Data ();
-      if (item->GetSubMenu())
-      {
-        int ans = item->GetSubMenu()->FindItem(itemString);
-        if (ans > -1)
-          return ans;
-      }
-      if ( !item->IsSeparator() )
-      {
-        wxStripMenuCodes((char *)item->GetName().c_str(), buf2);
-        if (strcmp(buf1, buf2) == 0)
-          return item->GetId();
-      }
+        if ( node->GetData()->GetId() == id )
+            break;
+
+        node = node->GetNext();
     }
 
     }
 
-    return -1;
+    if (!node)
+        return 0;
+
+    return pos + 1 ;
 }
 
 }
 
-wxMenuItem *wxMenu::FindItemForId(int itemId, wxMenu ** itemMenu) const
+int wxMenu::MacGetIndexFromItem( wxMenuItem *pItem )
 {
 {
-    if (itemMenu)
-        *itemMenu = NULL;
-    for (wxNode * node = m_menuItems.First (); node; node = node->Next ())
+    size_t pos;
+    wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst();
+    for ( pos = 0; node; pos++ )
     {
     {
-        wxMenuItem *item = (wxMenuItem *) node->Data ();
-
-        if (item->GetId() == itemId)
-        {
-            if (itemMenu)
-                *itemMenu = (wxMenu *) this;
-            return item;
-        }
+        if ( node->GetData() == pItem )
+            break;
 
 
-        if (item->GetSubMenu())
-        {
-            wxMenuItem *ans = item->GetSubMenu()->FindItemForId (itemId, itemMenu);
-            if (ans)
-                return ans;
-        }
+        node = node->GetNext();
     }
 
     }
 
-    if (itemMenu)
-        *itemMenu = NULL;
-    return NULL;
-}
+    if (!node)
+        return 0;
 
 
-void wxMenu::SetHelpString(int itemId, const wxString& helpString)
-{
-    wxMenuItem *item = FindItemForId (itemId);
-    if (item)
-        item->SetHelp(helpString);
+    return pos + 1 ;
 }
 
 }
 
-wxString wxMenu::GetHelpString (int itemId) const
+void wxMenu::MacEnableMenu( bool bDoEnable )
 {
 {
-    wxMenuItem *item = FindItemForId (itemId);
-    wxString str("");
-    return (item == NULL) ? str : item->GetHelp();
+    UMAEnableMenuItem(MAC_WXHMENU(m_hMenu) , 0 , bDoEnable ) ;
+
+    ::DrawMenuBar() ;
 }
 
 }
 
-void wxMenu::ProcessCommand(wxCommandEvent & event)
+// 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
+void wxMenu::MacBeforeDisplay( bool isSubMenu )
 {
 {
-    bool processed = FALSE;
+    wxMenuItem* previousItem = NULL ;
+    size_t pos ;
+    wxMenuItemList::compatibility_iterator node;
+    wxMenuItem *item;
 
 
-    // Try a callback
-    if (m_callback)
+    for (pos = 0, node = GetMenuItems().GetFirst(); node; node = node->GetNext(), pos++)
     {
     {
-            (void) (*(m_callback)) (*this, event);
-            processed = TRUE;
-    }
+        item = (wxMenuItem *)node->GetData();
+        wxMenu* subMenu = item->GetSubMenu() ;
+        if (subMenu)
+        {
+            subMenu->MacBeforeDisplay( true ) ;
+        }
+        else // normal item
+        {
+            // what we do here is to hide the special items which are
+            // shown in the application menu anyhow -- it doesn't make
+            // sense to show them in their normal place as well
+            if ( item->GetId() == wxApp::s_macAboutMenuItemId ||
+                    item->GetId() == wxApp::s_macPreferencesMenuItemId ||
+                    item->GetId() == wxApp::s_macExitMenuItemId )
+
+            {
+                ChangeMenuItemAttributes( MAC_WXHMENU( GetHMenu() ),
+                                          pos + 1, kMenuItemAttrHidden, 0 );
+
+                // also check for a separator which was used just to
+                // separate this item from the others, so don't leave
+                // separator at the menu start or end nor 2 consecutive
+                // separators
+                wxMenuItemList::compatibility_iterator nextNode = node->GetNext();
+                wxMenuItem *next = nextNode ? nextNode->GetData() : NULL;
+
+                size_t posSeptoHide;
+                if ( !previousItem && next && next->IsSeparator() )
+                {
+                    // 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") );
+                    posSeptoHide = 2;
+                }
+                else if ( GetMenuItems().GetCount() == pos + 1 &&
+                            previousItem != NULL &&
+                                previousItem->IsSeparator() )
+                {
+                    // prev item is a trailing separator we want to hide
+                    posSeptoHide = pos;
+                }
+                else if ( previousItem && previousItem->IsSeparator() &&
+                            next && next->IsSeparator() )
+                {
+                    // two consecutive separators, this is one too many
+                    posSeptoHide = pos;
+                }
+                else // no separators to hide
+                {
+                    posSeptoHide = 0;
+                }
+
+                if ( posSeptoHide )
+                {
+                    // hide the separator as well
+                    ChangeMenuItemAttributes( MAC_WXHMENU( GetHMenu() ),
+                                              posSeptoHide,
+                                              kMenuItemAttrHidden,
+                                              0 );
+                }
+            }
+        }
 
 
-    // Try the menu's event handler
-    if ( !processed && GetEventHandler())
-    {
-            processed = GetEventHandler()->ProcessEvent(event);
+        previousItem = item ;
     }
 
     }
 
-  // Try the window the menu was popped up from (and up
-  // through the hierarchy)
-  if ( !processed && GetInvokingWindow())
-    processed = GetInvokingWindow()->GetEventHandler()->ProcessEvent(event);
+    if ( isSubMenu )
+        ::InsertMenu(MAC_WXHMENU( GetHMenu()), -1);
 }
 
 }
 
-bool wxWindow::PopupMenu(wxMenu *menu, int x, int y)
+// undo all changes from the MacBeforeDisplay call
+void wxMenu::MacAfterDisplay( bool isSubMenu )
 {
 {
-       menu->SetInvokingWindow(this);
-       ClientToScreen( &x , &y ) ;
+    if ( isSubMenu )
+        ::DeleteMenu(MacGetMenuId());
 
 
-       ::InsertMenu( menu->m_macMenuHandle , -1 ) ;
-  long menuResult = ::PopUpMenuSelect(menu->m_macMenuHandle ,y,x, 0) ;
-  menu->MacMenuSelect( this , TickCount() , HiWord(menuResult) , LoWord(menuResult) ) ;
-       ::DeleteMenu( menu->m_macMenuId ) ;
-  menu->SetInvokingWindow(NULL);
+    wxMenuItemList::compatibility_iterator node;
+    wxMenuItem *item;
 
 
-  return TRUE;
+    for (node = GetMenuItems().GetFirst(); node; node = node->GetNext())
+    {
+        item = (wxMenuItem *)node->GetData();
+        wxMenu* subMenu = item->GetSubMenu() ;
+        if (subMenu)
+        {
+            subMenu->MacAfterDisplay( true ) ;
+        }
+        else
+        {
+            // no need to undo hidings
+        }
+    }
 }
 
 }
 
-// helper functions returning the mac menu position for a certain item, note that this is 
-// mac-wise 1 - based, i.e. the first item has index 1 whereas on MSWin it has pos 0
-
-int wxMenu::MacGetIndexFromId( int id ) 
+wxInt32 wxMenu::MacHandleCommandProcess( wxMenuItem* item, int id, wxWindow* targetWindow )
 {
 {
-    wxNode *node;
-    wxMenuItem *item;
-    int pos;
-       
-    for (pos = 0, node = m_menuItems.First(); node; node = node->Next(), pos++) 
+    OSStatus result = eventNotHandledErr ;
+    if (item->IsCheckable())
+        item->Check( !item->IsChecked() ) ;
+
+    if ( SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) )
+        result = noErr ;
+    else
     {
     {
-               item = (wxMenuItem *)node->Data();
-               if (item->GetId() == id)
-                       break;
-    }
+        if ( targetWindow != NULL )
+        {
+            wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED , id);
+            event.SetEventObject(targetWindow);
+            event.SetInt(item->IsCheckable() ? item->IsChecked() : -1);
 
 
-    if (!node)
-               return 0;
-               
-       return pos + 1 ;
+            if ( targetWindow->HandleWindowEvent(event) )
+                result = noErr ;
+        }
+    }
+    return result;
 }
 
 }
 
-int wxMenu::MacGetIndexFromItem( wxMenuItem *pItem ) 
+wxInt32 wxMenu::MacHandleCommandUpdateStatus(wxMenuItem* WXUNUSED(item),
+                                             int id,
+                                             wxWindow* targetWindow)
 {
 {
-    wxNode *node;
-    int pos;
+    OSStatus result = eventNotHandledErr ;
+    wxUpdateUIEvent event(id);
+    event.SetEventObject( this );
+
+    bool processed = false;
 
 
-    for (pos = 0, node = m_menuItems.First(); node; node = node->Next(), pos++) 
+    // Try the menu's event handler
     {
     {
-               if ((wxMenuItem *)node->Data() == pItem)
-                       break;
+        wxEvtHandler *handler = GetEventHandler();
+        if ( handler )
+            processed = handler->ProcessEvent(event);
     }
 
     }
 
-    if (!node)
-               return 0;
-               
-       return pos + 1 ;
-}
+    // Try the window the menu was popped up from
+    // (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();
+        }
+    }
 
 
-void wxMenu::MacEnableMenu( bool bDoEnable ) 
-{
-       m_macMenuEnabled = bDoEnable ;
-       if ( bDoEnable )
-               UMAEnableMenuItem( m_macMenuHandle , 0 ) ;
-       else
-               UMADisableMenuItem( m_macMenuHandle , 0 ) ;
-               
-       ::DrawMenuBar() ;
-}
+    if ( !processed && targetWindow != NULL)
+    {
+        processed = targetWindow->HandleWindowEvent(event);
+    }
 
 
-bool wxMenu::MacMenuSelect( wxEvtHandler* handler, long when , int macMenuId, int macMenuItemNum )
-{
-  int pos;
-  wxNode *node;
-
-       if ( m_macMenuId == macMenuId )
-       {
-               node = m_menuItems.Nth(macMenuItemNum-1);
-               if (node) 
-               {
-                       wxMenuItem *pItem = (wxMenuItem*)node->Data();
-       
-                       wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, pItem->GetId());
-                       event.m_timeStamp = when;
-                       event.SetEventObject(handler);
-      event.SetInt( pItem->GetId() );
-
-                       {
-                               bool processed = false ;
-
-                   // Try a callback
-                   if (m_callback)
-                   {
-                           (void) (*(m_callback)) (*this, event);
-                           processed = TRUE;
-                   }
-               
-                   // Try the menu's event handler
-                   if ( !processed && handler)
-                   {
-                           processed = handler->ProcessEvent(event);
-                   }
-               
-                       // Try the window the menu was popped up from (and up
-                       // through the hierarchy)
-                       if ( !processed && GetInvokingWindow())
-                       processed = GetInvokingWindow()->GetEventHandler()->ProcessEvent(event);
-                 }
-                       return true ;
-               }
-       }
-       else if ( macMenuId == kHMHelpMenuID )
-       {
-               int menuItem = formerHelpMenuItems ;
-         for (pos = 0, node = m_menuItems.First(); node; node = node->Next(), pos++) 
-         {     
-               wxMenuItem * pItem = (wxMenuItem *)  node->Data() ;
-               
-               wxMenu *pSubMenu = pItem->GetSubMenu() ;
-                       if ( pSubMenu != NULL )
-                       {
-                       }
-                       else
-                       {
-                               if ( pItem->GetId() != wxApp::s_macAboutMenuItemId )
-                                       ++menuItem ;
-                                       
-                               if ( menuItem == macMenuItemNum )
-                               {
-                                       wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, pItem->GetId());
-                                       event.m_timeStamp = when;
-                                       event.SetEventObject(handler);
-                       event.SetInt( pItem->GetId() );
-                                       
-                                       {
-                                               bool processed = false ;
-                                   // Try a callback
-                                   if (m_callback)
-                                   {
-                                           (void) (*(m_callback)) (*this, event);
-                                           processed = TRUE;
-                                   }
-                               
-                                   // Try the menu's event handler
-                                   if ( !processed && handler)
-                                   {
-                                           processed = handler->ProcessEvent(event);
-                                   }
-                               
-                                       // Try the window the menu was popped up from (and up
-                                       // through the hierarchy)
-                                       if ( !processed && GetInvokingWindow())
-                                       processed = GetInvokingWindow()->GetEventHandler()->ProcessEvent(event);
-                                 }
-                                 
-                                       return true ;
-                               }
-                       }
-         }
-       }
-
-  for (pos = 0, node = m_menuItems.First(); node; node = node->Next(), pos++) 
-  {    
-       wxMenuItem * pItem = (wxMenuItem *)  node->Data() ;
-       
-       wxMenu *pSubMenu = pItem->GetSubMenu() ;
-               if ( pSubMenu != NULL )
-               {
-                       if ( pSubMenu->MacMenuSelect( handler , when , macMenuId , macMenuItemNum ) )
-                               return true ;
-               }
-  }
-
-       return false ;
+    if ( processed )
+    {
+        // 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());
+
+        result = noErr ;
+    }
+    return result;
 }
 
 // Menu Bar
 
 }
 
 // Menu Bar
 
-/* 
+/*
 
 Mac Implementation note :
 
 
 Mac Implementation note :
 
@@ -706,438 +639,542 @@ The Mac has only one global menubar, so we attempt to install the currently
 active menubar from a frame, we currently don't take into account mdi-frames
 which would ask for menu-merging
 
 active menubar from a frame, we currently don't take into account mdi-frames
 which would ask for menu-merging
 
-Secondly there is no mac api for changing a menubar that is not the current 
+Secondly there is no mac api for changing a menubar that is not the current
 menubar, so we have to wait for preparing the actual menubar until the
 wxMenubar is to be used
 
 menubar, so we have to wait for preparing the actual menubar until the
 wxMenubar is to be used
 
-We can in subsequent versions use MacInstallMenuBar to provide some sort of 
+We can in subsequent versions use MacInstallMenuBar to provide some sort of
 auto-merge for MDI in case this will be necessary
 
 */
 
 wxMenuBar* wxMenuBar::s_macInstalledMenuBar = NULL ;
 auto-merge for MDI in case this will be necessary
 
 */
 
 wxMenuBar* wxMenuBar::s_macInstalledMenuBar = NULL ;
+wxMenuBar* wxMenuBar::s_macCommonMenuBar = NULL ;
+bool     wxMenuBar::s_macAutoWindowMenu = true ;
+WXHMENU  wxMenuBar::s_macWindowMenuHandle = NULL ;
 
 
-wxMenuBar::wxMenuBar()
+void wxMenuBar::Init()
 {
     m_eventHandler = this;
 {
     m_eventHandler = this;
-    m_menuCount = 0;
-    m_menus = NULL;
-    m_titles = NULL;
     m_menuBarFrame = NULL;
     m_menuBarFrame = NULL;
+    m_invokingWindow = (wxWindow*) NULL;
 }
 
 }
 
-wxMenuBar::wxMenuBar(int n, wxMenu *menus[], const wxString titles[])
+wxMenuBar::wxMenuBar()
 {
 {
-    m_eventHandler = this;
-    m_menuCount = n;
-    m_menus = menus;
-    m_titles = new wxString[n];
-    int i;
-    for ( i = 0; i < n; i++ )
-                       m_titles[i] = titles[i];
-    m_menuBarFrame = NULL;
+    Init();
 }
 
 }
 
-wxMenuBar::~wxMenuBar()
+wxMenuBar::wxMenuBar( long WXUNUSED(style) )
 {
 {
-       if (s_macInstalledMenuBar == this)
-       {
-               ::ClearMenuBar();
-               s_macInstalledMenuBar = NULL;
-       }
-
-    int i;
-    for (i = 0; i < m_menuCount; i++)
-    {
-        delete m_menus[i];
-    }
-    delete[] m_menus;
-    delete[] m_titles;
-
+    Init();
 }
 
 }
 
-void wxMenuBar::MacInstallMenuBar() 
+wxMenuBar::wxMenuBar(size_t count, wxMenu *menus[], const wxString titles[], long WXUNUSED(style))
 {
 {
-       Handle menubar = ::GetNewMBar( kwxMacMenuBarResource ) ;
-       wxString message ;
-       wxCHECK_RET( menubar != NULL, "can't read MBAR resource" );
-       ::SetMenuBar( menubar ) ;
-       ::DisposeHandle( menubar ) ;
-
-               MenuHandle menu = ::GetMenuHandle( kwxMacAppleMenuId ) ;
-               ::AppendResMenu(menu, 'DRVR');
-       for (int i = 0; i < m_menuCount; i++)
-       {
-                       Str255  label;
-       wxNode *node;
-       wxMenuItem *item;
-       int pos ;
-                       wxMenu* menu = m_menus[i] , *subMenu = NULL ;
-               
-                       
-                       if( m_titles[i] == "?" || m_titles[i] == wxApp::s_macHelpMenuTitleName )
-                       {
-                               MenuHandle mh = NULL ;
-                               if ( HMGetHelpMenuHandle( &mh ) != noErr )
-                               {
-                                       continue ;
-                               }
-                               if ( formerHelpMenuItems == 0 )
-                               {
-                                       if( mh )
-                                               formerHelpMenuItems = CountMenuItems( mh ) ;
-                               }
-                                       
-                       for (pos = 0 , node = menu->m_menuItems.First(); node; node = node->Next(), pos++) 
-                       {
-                                       item = (wxMenuItem *)node->Data();
-                                       subMenu = item->GetSubMenu() ;
-                                       if (subMenu)                    
-                                       {
-                                               // we don't support hierarchical menus in the help menu yet
-                                       }
-                                       else            
-                                       {
-                                               Str255 label ;
-                                               wxMacBuildMenuString( label , NULL , NULL , item->GetName(), item->GetId() != wxApp::s_macAboutMenuItemId); // no shortcut in about menu
-                                               if ( label[0] == 0 )
-                                               {
-                                                       // we cannot add empty menus on mac
-                                                       label[0] = 1 ;
-                                                       label[1] = ' ' ;
-                                               }
-                                               if ( item->GetId() == wxApp::s_macAboutMenuItemId )
-                                               { 
-                                                               ::SetMenuItemText( GetMenuHandle( kwxMacAppleMenuId ) , 1 , label );
-               //                                      ::EnableMenuItem( GetMenuHandle( kwxMacAppleMenuId ) , 1 );
-                                                               ::EnableItem( GetMenuHandle( kwxMacAppleMenuId ) , 1 );
-                                               }
-                                               else
-                                               {
-                                                       if ( mh )
-                                                               ::AppendMenu(mh, label );
-                                               }
-                                       }
-                               }
-                       }
-                       else
-                       {
-                               wxMacBuildMenuString( label, NULL , NULL , m_titles[i] , false );
-                               UMASetMenuTitle( menu->m_macMenuHandle , label ) ;
-                       for (pos = 0, node = menu->m_menuItems.First(); node; node = node->Next(), pos++) 
-                       {
-                                       item = (wxMenuItem *)node->Data();
-                                       subMenu = item->GetSubMenu() ;
-                                       if (subMenu)                    
-                                       {
-                                               ::InsertMenu( subMenu->m_macMenuHandle , -1 ) ;
-                                       }
-                               }
-                               ::InsertMenu(m_menus[i]->m_macMenuHandle, 0);
-                       }
-               }
-               ::DrawMenuBar() ;
-
-       s_macInstalledMenuBar = this;
-}
+    Init();
 
 
+    m_titles.Alloc(count);
 
 
-// Must only be used AFTER menu has been attached to frame,
-// otherwise use individual menus to enable/disable items
-void wxMenuBar::Enable(int id, bool flag)
-{
-    wxMenu *itemMenu = NULL;
-    wxMenuItem *item = FindItemForId(id, &itemMenu) ;
-    if (!item)
-        return;
+    for ( size_t i = 0; i < count; i++ )
+    {
+        m_menus.Append(menus[i]);
+        m_titles.Add(titles[i]);
 
 
-       item->Enable( flag ) ;
+        menus[i]->Attach(this);
+    }
 }
 
 }
 
-void wxMenuBar::EnableTop(int pos, bool flag)
+wxMenuBar::~wxMenuBar()
 {
 {
-       m_menus[pos]->MacEnableMenu( flag ) ;
+    if (s_macCommonMenuBar == this)
+        s_macCommonMenuBar = NULL;
+
+    if (s_macInstalledMenuBar == this)
+    {
+        ::ClearMenuBar();
+        s_macInstalledMenuBar = NULL;
+    }
 }
 
 }
 
-// Must only be used AFTER menu has been attached to frame,
-// otherwise use individual menus
-void wxMenuBar::Check(int id, bool flag)
+void wxMenuBar::Refresh(bool WXUNUSED(eraseBackground), const wxRect *WXUNUSED(rect))
 {
 {
-    wxMenu *itemMenu = NULL;
-    wxMenuItem *item = FindItemForId(id, &itemMenu) ;
-    if (!item)
-        return;
+    wxCHECK_RET( IsAttached(), wxT("can't refresh unatteched menubar") );
 
 
-    if (!item->IsCheckable())
-        return ;
-
-       item->Check( flag ) ;
+    DrawMenuBar();
 }
 
 }
 
-bool wxMenuBar::Checked(int id) const
+void wxMenuBar::MacInstallMenuBar()
 {
 {
-    wxMenu *itemMenu = NULL;
-    wxMenuItem *item = FindItemForId(id, &itemMenu) ;
-    if (!item)
-        return FALSE;
+    if ( s_macInstalledMenuBar == this )
+        return ;
+
+    MenuBarHandle menubar = NULL ;
 
 
-    if (!item->IsCheckable())
-        return FALSE ;
+    menubar = NewHandleClear( 6 /* sizeof( MenuBarHeader ) */ ) ;
 
 
-    return item->IsChecked() ;
+    ::SetMenuBar( menubar ) ;
+    DisposeMenuBar( menubar ) ;
+    MenuHandle appleMenu = NULL ;
+
+    verify_noerr( CreateNewMenu( kwxMacAppleMenuId , 0 , &appleMenu ) ) ;
+    verify_noerr( SetMenuTitleWithCFString( appleMenu , CFSTR( "\x14" ) ) );
+
+    // 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 ) ;
+
+    // if we have a mac help menu, clean it up before adding new items
+    MenuHandle helpMenuHandle ;
+    MenuItemIndex firstUserHelpMenuItem ;
+
+    if ( UMAGetHelpMenuDontCreate( &helpMenuHandle , &firstUserHelpMenuItem) == noErr )
+    {
+        for ( int i = CountMenuItems( helpMenuHandle ) ; i >= firstUserHelpMenuItem ; --i )
+            DeleteMenuItem( helpMenuHandle , i ) ;
+    }
+    else
+    {
+        helpMenuHandle = NULL ;
+    }
+
+    if ( wxApp::s_macPreferencesMenuItemId)
+    {
+        wxMenuItem *item = FindItem( wxApp::s_macPreferencesMenuItemId , NULL ) ;
+        if ( item == NULL || !(item->IsEnabled()) )
+            DisableMenuCommand( NULL , kHICommandPreferences ) ;
+        else
+            EnableMenuCommand( NULL , kHICommandPreferences ) ;
+    }
+
+    // Unlike preferences which may or may not exist, the Quit item should be always
+    // enabled unless it is added by the application and then disabled, otherwise
+    // a program would be required to add an item with wxID_EXIT in order to get the
+    // Quit menu item to be enabled, which seems a bit burdensome.
+    if ( wxApp::s_macExitMenuItemId)
+    {
+        wxMenuItem *item = FindItem( wxApp::s_macExitMenuItemId , NULL ) ;
+        if ( item != NULL && !(item->IsEnabled()) )
+            DisableMenuCommand( NULL , kHICommandQuit ) ;
+        else
+            EnableMenuCommand( NULL , kHICommandQuit ) ;
+    }
+
+    wxString strippedHelpMenuTitle = wxStripMenuCodes( wxApp::s_macHelpMenuTitleName ) ;
+    wxString strippedTranslatedHelpMenuTitle = wxStripMenuCodes( wxString( _("&Help") ) ) ;
+    wxMenuList::compatibility_iterator menuIter = m_menus.GetFirst();
+    for (size_t i = 0; i < m_menus.GetCount(); i++, menuIter = menuIter->GetNext())
+    {
+        wxMenuItemList::compatibility_iterator node;
+        wxMenuItem *item;
+        wxMenu* menu = menuIter->GetData() , *subMenu = NULL ;
+        wxString strippedMenuTitle = wxStripMenuCodes(m_titles[i]);
+
+        if ( strippedMenuTitle == wxT("?") || strippedMenuTitle == strippedHelpMenuTitle || strippedMenuTitle == strippedTranslatedHelpMenuTitle )
+        {
+            for (node = menu->GetMenuItems().GetFirst(); node; node = node->GetNext())
+            {
+                item = (wxMenuItem *)node->GetData();
+                subMenu = item->GetSubMenu() ;
+                if (subMenu)
+                {
+                    // we don't support hierarchical menus in the help menu yet
+                }
+                else
+                {
+                    if ( item->GetId() != wxApp::s_macAboutMenuItemId )
+                    {
+                        // we have found a user help menu and an item other than the about item,
+                        // so we can create the mac help menu now, if we haven't created it yet
+                        if ( helpMenuHandle == NULL )
+                        {
+                            if ( UMAGetHelpMenu( &helpMenuHandle , &firstUserHelpMenuItem) != noErr )
+                            {
+                                helpMenuHandle = NULL ;
+                                break ;
+                            }
+                        }
+                    }
+
+                    if ( item->IsSeparator() )
+                    {
+                        if ( helpMenuHandle )
+                            AppendMenuItemTextWithCFString( helpMenuHandle,
+                                CFSTR(""), kMenuItemAttrSeparator, 0,NULL);
+                    }
+                    else
+                    {
+                        wxAcceleratorEntry*
+                            entry = wxAcceleratorEntry::Create( item->GetItemLabel() ) ;
+
+                        if ( item->GetId() == wxApp::s_macAboutMenuItemId )
+                        {
+                            // this will be taken care of below
+                        }
+                        else
+                        {
+                            if ( helpMenuHandle )
+                            {
+                                UMAAppendMenuItem(helpMenuHandle, wxStripMenuCodes(item->GetItemLabel()) , wxFont::GetDefaultEncoding(), entry);
+                                SetMenuItemCommandID( helpMenuHandle , CountMenuItems(helpMenuHandle) , wxIdToMacCommand ( item->GetId() ) ) ;
+                                SetMenuItemRefCon( helpMenuHandle , CountMenuItems(helpMenuHandle) , (URefCon) item ) ;
+                            }
+                        }
+
+                        delete entry ;
+                    }
+                }
+            }
+        }
+
+        else if ( ( m_titles[i] == wxT("Window") || m_titles[i] == wxT("&Window") )
+                && GetAutoWindowMenu() )
+        {
+            if ( MacGetWindowMenuHMenu() == NULL )
+            {
+                CreateStandardWindowMenu( 0 , (MenuHandle*) &s_macWindowMenuHandle ) ;
+            }
+
+            MenuRef wm = (MenuRef)MacGetWindowMenuHMenu();
+            if ( wm == NULL )
+                break;
+
+            // get the insertion point in the standard menu
+            MenuItemIndex winListStart;
+            GetIndMenuItemWithCommandID(wm,
+                        kHICommandWindowListSeparator, 1, NULL, &winListStart);
+
+            // add a separator so that the standard items and the custom items
+            // aren't mixed together, but only if this is the first run
+            OSStatus err = GetIndMenuItemWithCommandID(wm,
+                        'WXWM', 1, NULL, NULL);
+
+            if ( err == menuItemNotFoundErr )
+            {
+                InsertMenuItemTextWithCFString( wm,
+                        CFSTR(""), winListStart-1, kMenuItemAttrSeparator, 'WXWM');
+            }
+
+            wxInsertMenuItemsInMenu(menu, wm, winListStart);
+        }
+        else
+        {
+            UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , m_titles[i], m_font.GetEncoding()  ) ;
+            menu->MacBeforeDisplay(false) ;
+
+            ::InsertMenu(MAC_WXHMENU(_wxMenuAt(m_menus, i)->GetHMenu()), 0);
+        }
+    }
+
+    // take care of the about menu item wherever it is
+    {
+        wxMenu* aboutMenu ;
+        wxMenuItem *aboutMenuItem = FindItem(wxApp::s_macAboutMenuItemId , &aboutMenu) ;
+        if ( aboutMenuItem )
+        {
+            wxAcceleratorEntry*
+                entry = wxAcceleratorEntry::Create( aboutMenuItem->GetItemLabel() ) ;
+            UMASetMenuItemText( GetMenuHandle( kwxMacAppleMenuId ) , 1 , wxStripMenuCodes ( aboutMenuItem->GetItemLabel() ) , wxFont::GetDefaultEncoding() );
+            UMAEnableMenuItem( GetMenuHandle( kwxMacAppleMenuId ) , 1 , true );
+            SetMenuItemCommandID( GetMenuHandle( kwxMacAppleMenuId ) , 1 , kHICommandAbout ) ;
+            SetMenuItemRefCon(GetMenuHandle( kwxMacAppleMenuId ) , 1 , (URefCon)aboutMenuItem ) ;
+            UMASetMenuItemShortcut( GetMenuHandle( kwxMacAppleMenuId ) , 1 , entry ) ;
+        }
+    }
+
+    if ( GetAutoWindowMenu() )
+    {
+        if ( MacGetWindowMenuHMenu() == NULL )
+            CreateStandardWindowMenu( 0 , (MenuHandle*) &s_macWindowMenuHandle ) ;
+
+        InsertMenu( (MenuHandle) MacGetWindowMenuHMenu() , 0 ) ;
+    }
+
+    ::DrawMenuBar() ;
+    s_macInstalledMenuBar = this;
 }
 
 }
 
-bool wxMenuBar::Enabled(int id) const
+void wxMenuBar::EnableTop(size_t pos, bool enable)
 {
 {
-    wxMenu *itemMenu = NULL;
-    wxMenuItem *item = FindItemForId(id, &itemMenu) ;
-    if (!item)
-        return FALSE;
-
-       if ( !item->IsEnabled() )
-               return FALSE ;
-       
-       if ( itemMenu->m_macMenuEnabled == false )
-               return FALSE ;
-               
-       while( itemMenu->m_parent )
-       {
-               itemMenu = (wxMenu*) itemMenu->m_parent ;
-               if ( itemMenu->IsKindOf( CLASSINFO( wxMenu ) ) )
-               {
-                       if ( itemMenu->m_macMenuEnabled == false )
-                               return FALSE ;
-               }
-       }
-       
-    return TRUE ;
-}
+    wxCHECK_RET( IsAttached(), wxT("doesn't work with unattached menubars") );
 
 
+    _wxMenuAt(m_menus, pos)->MacEnableMenu( enable ) ;
+    Refresh();
+}
 
 
-void wxMenuBar::SetLabel(int id, const wxString& label)
+bool wxMenuBar::Enable(bool enable)
 {
 {
-    wxMenu *itemMenu = NULL;
-    wxMenuItem *item = FindItemForId(id, &itemMenu) ;
+    wxCHECK_MSG( IsAttached(), false, wxT("doesn't work with unattached menubars") );
 
 
-    if (!item)
-        return;
+    size_t i;
+    for (i = 0; i < GetMenuCount(); i++)
+        EnableTop(i, enable);
 
 
-    itemMenu->SetLabel( id , label ) ;
+    return true;
 }
 
 }
 
-wxString wxMenuBar::GetLabel(int id) const
+void wxMenuBar::SetMenuLabel(size_t pos, const wxString& label)
 {
 {
-    wxMenu *itemMenu = NULL;
-    wxMenuItem *item = FindItemForId(id, &itemMenu) ;
+    wxCHECK_RET( pos < GetMenuCount(), wxT("invalid menu index") );
+
+    m_titles[pos] = label;
+
+    if ( !IsAttached() )
+        return;
 
 
-    if (!item)
-        return wxString("");
+    _wxMenuAt(m_menus, pos)->SetTitle( label ) ;
 
 
-    return itemMenu->GetLabel( id ) ;
+    if (wxMenuBar::s_macInstalledMenuBar == this) // are we currently installed ?
+    {
+        ::SetMenuBar( GetMenuBar() ) ;
+        ::InvalMenuBar() ;
+    }
 }
 
 }
 
-void wxMenuBar::SetLabelTop(int pos, const wxString& label)
+wxString wxMenuBar::GetMenuLabel(size_t pos) const
 {
 {
-    m_menus[pos]->SetTitle( label ) ;
+    wxCHECK_MSG( pos < GetMenuCount(), wxEmptyString,
+                 wxT("invalid menu index in wxMenuBar::GetMenuLabel") );
+
+    return m_titles[pos];
 }
 
 }
 
-wxString wxMenuBar::GetLabelTop(int pos) const
+int wxMenuBar::FindMenu(const wxString& title)
 {
 {
-   return m_menus[pos]->GetTitle() ;
+    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;
 }
 
 }
 
-bool wxMenuBar::OnDelete(wxMenu *a_menu, int pos)
+// ---------------------------------------------------------------------------
+// wxMenuBar construction
+// ---------------------------------------------------------------------------
+
+wxMenu *wxMenuBar::Replace(size_t pos, wxMenu *menu, const wxString& title)
 {
 {
-       if (s_macInstalledMenuBar == this)
-       {
-               ::DeleteMenu( a_menu->m_macMenuId /* m_menus[pos]->m_macMenuId */ ) ;
-               ::InvalMenuBar() ;
-               return TRUE ;
-       }
-       else
-       {
-               return TRUE ;
-       }
+    wxMenu *menuOld = wxMenuBarBase::Replace(pos, menu, title);
+    if ( !menuOld )
+        return NULL;
+
+    m_titles[pos] = title;
+
+    if ( IsAttached() )
+    {
+        if (s_macInstalledMenuBar == this)
+        {
+            menuOld->MacAfterDisplay( false ) ;
+            ::DeleteMenu( menuOld->MacGetMenuId() /* m_menus[pos]->MacGetMenuId() */ ) ;
+
+            menu->MacBeforeDisplay( false ) ;
+            UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , title , m_font.GetEncoding() ) ;
+            if ( pos == m_menus.GetCount() - 1)
+                ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , 0 ) ;
+            else
+                ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , _wxMenuAt(m_menus, pos + 1)->MacGetMenuId() ) ;
+        }
+
+        Refresh();
+    }
+
+    if (m_invokingWindow)
+        wxMenubarSetInvokingWindow( menu, m_invokingWindow );
+
+    return menuOld;
 }
 
 }
 
-bool wxMenuBar::OnAppend(wxMenu *a_menu, const char *title)
+bool wxMenuBar::Insert(size_t pos, wxMenu *menu, const wxString& title)
 {
 {
-       if (!a_menu->m_macMenuHandle)
-               return FALSE;
-
-       if (s_macInstalledMenuBar == this)
-       {
-               Str255  label;
-               wxMacBuildMenuString( label, NULL , NULL , title , false );
-               UMASetMenuTitle( a_menu->m_macMenuHandle , label ) ;
-               ::InsertMenu( a_menu->m_macMenuHandle , 0 ) ;
-               ::InvalMenuBar() ;
-               return TRUE ;
-       }
-       else
-       {
-               return TRUE ;
-       }
+    if ( !wxMenuBarBase::Insert(pos, menu, title) )
+        return false;
+
+    m_titles.Insert(title, pos);
+
+    UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , title , m_font.GetEncoding() ) ;
+
+    if ( IsAttached() && s_macInstalledMenuBar == this )
+    {
+        if (s_macInstalledMenuBar == this)
+        {
+            menu->MacBeforeDisplay( false ) ;
+
+            if ( pos == (size_t) -1  || pos + 1 == m_menus.GetCount() )
+                ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , 0 ) ;
+            else
+                ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , _wxMenuAt(m_menus, pos+1)->MacGetMenuId() ) ;
+        }
+
+        Refresh();
+    }
+
+    if (m_invokingWindow)
+        wxMenubarSetInvokingWindow( menu, m_invokingWindow );
+
+    return true;
 }
 
 }
 
-void wxMenuBar::Append (wxMenu * menu, const wxString& title)
+wxMenu *wxMenuBar::Remove(size_t pos)
 {
 {
-    if (!OnAppend(menu, title))
-        return;
+    wxMenu *menu = wxMenuBarBase::Remove(pos);
+    if ( !menu )
+        return NULL;
 
 
-    m_menuCount ++;
-    wxMenu **new_menus = new wxMenu *[m_menuCount];
-    wxString *new_titles = new wxString[m_menuCount];
-    int i;
-
-    for (i = 0; i < m_menuCount - 1; i++)
-       {
-        new_menus[i] = m_menus[i];
-        m_menus[i] = NULL;
-        new_titles[i] = m_titles[i];
-        m_titles[i] = "";
-    }
-    if (m_menus)
+    if ( IsAttached() )
     {
     {
-        delete[]m_menus;
-        delete[]m_titles;
+        if (s_macInstalledMenuBar == this)
+            ::DeleteMenu( menu->MacGetMenuId() /* m_menus[pos]->MacGetMenuId() */ ) ;
+
+        Refresh();
     }
     }
-    m_menus = new_menus;
-    m_titles = new_titles;
 
 
-    m_menus[m_menuCount - 1] = (wxMenu *)menu;
-    m_titles[m_menuCount - 1] = title;
+    m_titles.RemoveAt(pos);
 
 
-  ((wxMenu *)menu)->m_menuBar = (wxMenuBar *) this;
-  ((wxMenu *)menu)->SetParent(this);
+    return menu;
 }
 
 }
 
-void wxMenuBar::Delete(wxMenu * menu, int i)
+bool wxMenuBar::Append(wxMenu *menu, const wxString& title)
 {
 {
-    int j;
-    int ii = (int) i;
+    WXHMENU submenu = menu ? menu->GetHMenu() : 0;
+        wxCHECK_MSG( submenu, false, wxT("can't append invalid menu to menubar") );
+
+    if ( !wxMenuBarBase::Append(menu, title) )
+        return false;
+
+    m_titles.Add(title);
+
+    UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , title , m_font.GetEncoding() ) ;
 
 
-    if (menu != 0)
+    if ( IsAttached() )
     {
     {
-           for (ii = 0; ii < m_menuCount; ii++)
+        if (s_macInstalledMenuBar == this)
         {
         {
-            if (m_menus[ii] == menu)
-            break;
-           }
-        if (ii >= m_menuCount)
-            return;
-    } else
-    {
-        if (ii < 0 || ii >= m_menuCount)
-            return;
-        menu = m_menus[ii];
+            menu->MacBeforeDisplay( false ) ;
+            ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , 0 ) ;
+        }
+
+        Refresh();
     }
 
     }
 
-    if (!OnDelete(menu, ii))
-        return;
+    // m_invokingWindow is set after wxFrame::SetMenuBar(). This call enables
+    // adding menu later on.
+    if (m_invokingWindow)
+        wxMenubarSetInvokingWindow( menu, m_invokingWindow );
 
 
-    menu->SetParent(NULL);
+    return true;
+}
+
+static void wxMenubarUnsetInvokingWindow( wxMenu *menu )
+{
+    menu->SetInvokingWindow( (wxWindow*) NULL );
+    wxMenuItemList::compatibility_iterator node = menu->GetMenuItems().GetFirst();
 
 
-    -- m_menuCount;
-    for (j = ii; j < m_menuCount; j++)
+    while (node)
     {
     {
-        m_menus[j] = m_menus[j + 1];
-        m_titles[j] = m_titles[j + 1];
+        wxMenuItem *menuitem = node->GetData();
+        if (menuitem->IsSubMenu())
+            wxMenubarUnsetInvokingWindow( menuitem->GetSubMenu() );
+
+        node = node->GetNext();
     }
 }
 
     }
 }
 
-// Find the menu menuString, item itemString, and return the item id.
-// Returns -1 if none found.
-int wxMenuBar::FindMenuItem (const wxString& menuString, const wxString& itemString) const
+static void wxMenubarSetInvokingWindow( wxMenu *menu, wxWindow *win )
 {
 {
-    char buf1[200];
-    char buf2[200];
-    wxStripMenuCodes ((char *)(const char *)menuString, buf1);
-    int i;
-    for (i = 0; i < m_menuCount; i++)
+    menu->SetInvokingWindow( win );
+    wxMenuItem *menuitem;
+    wxMenuItemList::compatibility_iterator node = menu->GetMenuItems().GetFirst();
+
+    while (node)
     {
     {
-        wxStripMenuCodes ((char *)(const char *)m_titles[i], buf2);
-        if (strcmp (buf1, buf2) == 0)
-            return m_menus[i]->FindItem (itemString);
+        menuitem = node->GetData();
+        if (menuitem->IsSubMenu())
+            wxMenubarSetInvokingWindow( menuitem->GetSubMenu() , win );
+
+        node = node->GetNext();
     }
     }
-    return -1;
 }
 
 }
 
-wxMenuItem *wxMenuBar::FindItemForId (int Id, wxMenu ** itemMenu) const
+void wxMenuBar::UnsetInvokingWindow()
 {
 {
-    if (itemMenu)
-        *itemMenu = NULL;
+    m_invokingWindow = (wxWindow*) NULL;
+    wxMenu *menu;
+    wxMenuList::compatibility_iterator node = m_menus.GetFirst();
 
 
-    wxMenuItem *item = NULL;
-    int i;
-    for (i = 0; i < m_menuCount; i++)
-        if ((item = m_menus[i]->FindItemForId (Id, itemMenu)))
-            return item;
-    return NULL;
+    while (node)
+    {
+        menu = node->GetData();
+        wxMenubarUnsetInvokingWindow( menu );
+
+        node = node->GetNext();
+    }
 }
 
 }
 
-void wxMenuBar::SetHelpString (int Id, const wxString& helpString)
+void wxMenuBar::SetInvokingWindow(wxFrame *frame)
 {
 {
-    int i;
-    for (i = 0; i < m_menuCount; i++)
+    m_invokingWindow = frame;
+    wxMenu *menu;
+    wxMenuList::compatibility_iterator node = m_menus.GetFirst();
+
+    while (node)
     {
     {
-        if (m_menus[i]->FindItemForId (Id))
-        {
-            m_menus[i]->SetHelpString (Id, helpString);
-            return;
-        }
+        menu = node->GetData();
+        wxMenubarSetInvokingWindow( menu, frame );
+
+        node = node->GetNext();
     }
 }
 
     }
 }
 
-wxString wxMenuBar::GetHelpString (int Id) const
+void wxMenuBar::Detach()
 {
 {
-    int i;
-    for (i = 0; i < m_menuCount; i++)
+    wxMenuBarBase::Detach() ;
+}
+
+void wxMenuBar::Attach(wxFrame *frame)
+{
+    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++ )
     {
     {
-        if (m_menus[i]->FindItemForId (Id))
-            return wxString(m_menus[i]->GetHelpString (Id));
+        wxString title = wxStripMenuCodes(m_titles[i]);
+        if ( menuLabel == title )
+            return _wxMenuAt(m_menus, i)->FindItem(itemString);
     }
     }
-    return wxString("");
+
+    return wxNOT_FOUND;
 }
 
 }
 
-void wxMenuBar::MacMenuSelect(wxEvtHandler* handler, long when , int macMenuId, int macMenuItemNum)
+wxMenuItem *wxMenuBar::FindItem(int id, wxMenu **itemMenu) const
 {
 {
-       // first scan fast for direct commands, i.e. menus which have these commands directly in their own list
-
-       if ( macMenuId == kwxMacAppleMenuId && macMenuItemNum == 1 )
-       {
-                       wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, wxApp::s_macAboutMenuItemId );
-                       event.m_timeStamp = when;
-                       event.SetEventObject(handler);
-       event.SetInt( wxApp::s_macAboutMenuItemId );
-                       handler->ProcessEvent(event);
-       }
-       else
-       {               
-         for (int i = 0; i < m_menuCount; i++)
-         {
-               if ( m_menus[i]->m_macMenuId == macMenuId || 
-                       ( macMenuId == kHMHelpMenuID && ( m_titles[i] == "?" || m_titles[i] == wxApp::s_macHelpMenuTitleName ) )
-                       )
-               {
-                       if ( m_menus[i]->MacMenuSelect( handler , when , macMenuId , macMenuItemNum ) )
-                               return ;
-                       else
-                       {
-                               //TODO flag this as an error since it must contain the item
-                               return ;
-                       }
-               }
-               }
-       
-         for (int i = 0; i < m_menuCount; i++)
-         {
-               if ( m_menus[i]->MacMenuSelect( handler , when , macMenuId , macMenuItemNum ) )
-               {
-                       break ;
-               }
-               }
-       }
-}
+    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;
+}