]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/menu.cpp
check that the version of __sync_sub_and_fetch that returns a value is supported...
[wxWidgets.git] / src / mac / carbon / menu.cpp
index a5fe24d23bff812659057b834ba7b999293ad045..23e288ea882c407fef1575cf6a0798b730ecf068 100644 (file)
@@ -1,34 +1,32 @@
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
-// Name:        menu.cpp
+// Name:        src/mac/carbon/menu.cpp
 // Purpose:     wxMenu, wxMenuBar, wxMenuItem
 // Author:      Stefan Csomor
 // Modified by:
 // Created:     1998-01-01
 // RCS-ID:      $Id$
 // Copyright:   (c) Stefan Csomor
 // Purpose:     wxMenu, wxMenuBar, wxMenuItem
 // Author:      Stefan Csomor
 // Modified by:
 // Created:     1998-01-01
 // RCS-ID:      $Id$
 // Copyright:   (c) Stefan Csomor
-// Licence:    wxWindows licence
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 /////////////////////////////////////////////////////////////////////////////
 
-
-#ifdef __GNUG__
-#pragma implementation "menu.h"
-#pragma implementation "menuitem.h"
-#endif
-
 // ============================================================================
 // headers & declarations
 // ============================================================================
 
 // ============================================================================
 // headers & declarations
 // ============================================================================
 
-// wxWindows headers
+// wxWidgets headers
 // -----------------
 
 // -----------------
 
-#include "wx/app.h"
+#include "wx/wxprec.h"
+
 #include "wx/menu.h"
 #include "wx/menu.h"
-#include "wx/menuitem.h"
-#include "wx/window.h"
-#include "wx/log.h"
-#include "wx/utils.h"
-#include "wx/frame.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 MenuItemIndex firstUserHelpMenuItem = 0 ;
+static const int idMenuTitle = -3;
+
+static const short kwxMacAppleMenuId = 1 ;
+
+
+// Find an item given the Macintosh Menu Reference
+
+WX_DECLARE_HASH_MAP(MenuRef, wxMenu*, wxPointerHash, wxPointerEqual, MacMenuMap);
+
+static MacMenuMap wxWinMacMenuList;
+
+wxMenu *wxFindMenuFromMacMenu(MenuRef inMenuRef)
+{
+    MacMenuMap::iterator node = wxWinMacMenuList.find(inMenuRef);
+
+    return (node == wxWinMacMenuList.end()) ? NULL : node->second;
+}
+
+void wxAssociateMenuWithMacMenu(MenuRef inMenuRef, wxMenu *menu) ;
+void wxAssociateMenuWithMacMenu(MenuRef inMenuRef, wxMenu *menu)
+{
+    // 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 ) ;
+            }
 
 
-const short kwxMacMenuBarResource = 1 ;
-const short kwxMacAppleMenuId = 1 ;
+            delete entry ;
+        }
+    }
+}
 
 // ============================================================================
 // implementation
 
 // ============================================================================
 // implementation
@@ -64,22 +145,36 @@ short wxMenu::s_macNextMenuId = 3 ;
 short wxMenu::s_macNextMenuId = 2 ;
 #endif
 
 short wxMenu::s_macNextMenuId = 2 ;
 #endif
 
+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()
 {
 void wxMenu::Init()
 {
-    m_doBreak = FALSE;
+    m_doBreak = false;
     m_startRadioGroup = -1;
 
     // create the menu
     m_startRadioGroup = -1;
 
     // create the menu
-       m_macMenuId = s_macNextMenuId++; 
-       m_hMenu = UMANewMenu(m_macMenuId, m_title);
+    m_macMenuId = s_macNextMenuId++;
+    m_hMenu = UMANewMenu(m_macMenuId, m_title, wxFont::GetDefaultEncoding() );
 
     if ( !m_hMenu )
     {
 
     if ( !m_hMenu )
     {
-        wxLogLastError("UMANewMenu failed");
+        wxLogLastError(wxT("UMANewMenu failed"));
     }
 
     }
 
+    wxAssociateMenuWithMacMenu( (MenuRef)m_hMenu , this ) ;
+
     // if we have a title, insert it in the beginning of the menu
     // if we have a title, insert it in the beginning of the menu
-    if ( !!m_title )
+    if ( !m_title.empty() )
     {
         Append(idMenuTitle, m_title) ;
         AppendSeparator() ;
     {
         Append(idMenuTitle, m_title) ;
         AppendSeparator() ;
@@ -88,13 +183,14 @@ void wxMenu::Init()
 
 wxMenu::~wxMenu()
 {
 
 wxMenu::~wxMenu()
 {
-       if (MAC_WXHMENU(m_hMenu))
-               ::DisposeMenu(MAC_WXHMENU(m_hMenu));
+    wxRemoveMacMenuAssociation( this ) ;
+    if (MAC_WXHMENU(m_hMenu))
+        ::DisposeMenu(MAC_WXHMENU(m_hMenu));
 }
 
 void wxMenu::Break()
 {
 }
 
 void wxMenu::Break()
 {
-       // not available on the mac platform
+    // not available on the mac platform
 }
 
 void wxMenu::Attach(wxMenuBarBase *menubar)
 }
 
 void wxMenu::Attach(wxMenuBarBase *menubar)
@@ -108,62 +204,68 @@ void wxMenu::Attach(wxMenuBarBase *menubar)
 // append a new item or submenu to the menu
 bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos)
 {
 // append a new item or submenu to the menu
 bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos)
 {
-    wxASSERT_MSG( pItem != NULL, "can't append NULL item to the menu" );
-
-       if ( pItem->IsSeparator() )
-       {
-               if ( pos == (size_t)-1 )
-                       MacAppendMenu(MAC_WXHMENU(m_hMenu), "\p-");
-               else
-                       MacInsertMenuItem(MAC_WXHMENU(m_hMenu), "\p-" , pos);
-       }
-       else 
-       {
-               wxMenu *pSubMenu = pItem->GetSubMenu() ;
-               if ( pSubMenu != NULL )
-               {
-                       wxASSERT_MSG( pSubMenu->m_hMenu != NULL , "invalid submenu added");
-                   pSubMenu->m_menuParent = this ;
-               
-                       if (wxMenuBar::MacGetInstalledMenuBar() == m_menuBar) 
-                               ::InsertMenu( MAC_WXHMENU( pSubMenu->m_hMenu ) , -1 ) ;
-                       
-                       if ( pos == (size_t)-1 )
-                               UMAAppendSubMenuItem(MAC_WXHMENU(m_hMenu), pItem->GetText(), pSubMenu->m_macMenuId);
-                       else
-                               UMAInsertSubMenuItem(MAC_WXHMENU(m_hMenu), pItem->GetText() , pos, pSubMenu->m_macMenuId);
-                       pItem->UpdateItemBitmap() ;
-                       pItem->UpdateItemStatus() ;
-               }
-               else
-               {
-                       if ( pos == (size_t)-1 )
-                       {
-                               UMAAppendMenuItem(MAC_WXHMENU(m_hMenu), "a" );
-                               pos = CountMenuItems(MAC_WXHMENU(m_hMenu)) ;
-                       }
-                       else
-                       {
-                               UMAInsertMenuItem(MAC_WXHMENU(m_hMenu), "a" , pos);
-                       }
-
-                       SetMenuItemCommandID( MAC_WXHMENU(m_hMenu) , pos , pItem->GetId() ) ;
-                       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() )
+    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
     {
     {
-        m_menuBar->Refresh();
+        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 ) ;
+        }
     }
     }
-       return TRUE ;
+
+    // if we're already attached to the menubar, we must update it
+    if ( IsAttached() && GetMenuBar()->IsAttached() )
+        GetMenuBar()->Refresh();
+
+    return true ;
 }
 
 void wxMenu::EndRadioGroup()
 }
 
 void wxMenu::EndRadioGroup()
@@ -172,11 +274,11 @@ void wxMenu::EndRadioGroup()
     m_startRadioGroup = -1;
 }
 
     m_startRadioGroup = -1;
 }
 
-bool wxMenu::DoAppend(wxMenuItem *item)
+wxMenuItem* wxMenu::DoAppend(wxMenuItem *item)
 {
 {
-    wxCHECK_MSG( item, FALSE, _T("NULL item in wxMenu::DoAppend") );
+    wxCHECK_MSG( item, NULL, _T("NULL item in wxMenu::DoAppend") );
 
 
-    bool check = FALSE;
+    bool check = false;
 
     if ( item->GetKind() == wxITEM_RADIO )
     {
 
     if ( item->GetKind() == wxITEM_RADIO )
     {
@@ -192,13 +294,13 @@ bool wxMenu::DoAppend(wxMenuItem *item)
             item->SetRadioGroupEnd(m_startRadioGroup);
 
             // ensure that we have a checked item in the radio group
             item->SetRadioGroupEnd(m_startRadioGroup);
 
             // ensure that we have a checked item in the radio group
-            check = TRUE;
+            check = true;
         }
         else // extend the current radio group
         {
             // we need to update its end item
             item->SetRadioGroupStart(m_startRadioGroup);
         }
         else // extend the current radio group
         {
             // we need to update its end item
             item->SetRadioGroupStart(m_startRadioGroup);
-            wxMenuItemList::Node *node = GetMenuItems().Item(m_startRadioGroup);
+            wxMenuItemList::compatibility_iterator node = GetMenuItems().Item(m_startRadioGroup);
 
             if ( node )
             {
 
             if ( node )
             {
@@ -216,29 +318,29 @@ bool wxMenu::DoAppend(wxMenuItem *item)
     }
 
     if ( !wxMenuBase::DoAppend(item) || !DoInsertOrAppend(item) )
     }
 
     if ( !wxMenuBase::DoAppend(item) || !DoInsertOrAppend(item) )
-    {
-        return FALSE;
-    }
+        return NULL;
 
     if ( check )
 
     if ( check )
-    {
         // check the item initially
         // check the item initially
-        item->Check(TRUE);
-    }
+        item->Check(true);
 
 
-    return TRUE;
+    return item;
 }
 
 }
 
-bool wxMenu::DoInsert(size_t pos, wxMenuItem *item)
+wxMenuItem* wxMenu::DoInsert(size_t pos, wxMenuItem *item)
 {
 {
-    return wxMenuBase::DoInsert(pos, item) && DoInsertOrAppend(item, pos);
+    if (wxMenuBase::DoInsert(pos, item) && DoInsertOrAppend(item, pos))
+        return item;
+
+    return NULL;
 }
 
 wxMenuItem *wxMenu::DoRemove(wxMenuItem *item)
 {
     // we need to find the items position in the child list
     size_t pos;
 }
 
 wxMenuItem *wxMenu::DoRemove(wxMenuItem *item)
 {
     // we need to find the items position in the child list
     size_t pos;
-    wxMenuItemList::Node *node = GetMenuItems().GetFirst();
+    wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst();
+
     for ( pos = 0; node; pos++ )
     {
         if ( node->GetData() == item )
     for ( pos = 0; node; pos++ )
     {
         if ( node->GetData() == item )
@@ -250,13 +352,11 @@ wxMenuItem *wxMenu::DoRemove(wxMenuItem *item)
     // DoRemove() (unlike Remove) can only be called for existing item!
     wxCHECK_MSG( node, NULL, wxT("bug in wxMenu::Remove logic") );
 
     // DoRemove() (unlike Remove) can only be called for existing item!
     wxCHECK_MSG( node, NULL, wxT("bug in wxMenu::Remove logic") );
 
-       ::DeleteMenuItem(MAC_WXHMENU(m_hMenu) , pos + 1);
+    ::DeleteMenuItem(MAC_WXHMENU(m_hMenu) , pos + 1);
 
 
-    if ( IsAttached() )
-    {
+    if ( IsAttached() && GetMenuBar()->IsAttached() )
         // otherwise, the change won't be visible
         // otherwise, the change won't be visible
-        m_menuBar->Refresh();
-    }
+        GetMenuBar()->Refresh();
 
     // and from internal data structures
     return wxMenuBase::DoRemove(item);
 
     // and from internal data structures
     return wxMenuBase::DoRemove(item);
@@ -264,38 +364,27 @@ wxMenuItem *wxMenu::DoRemove(wxMenuItem *item)
 
 void wxMenu::SetTitle(const wxString& label)
 {
 
 void wxMenu::SetTitle(const wxString& label)
 {
-       m_title = label ;
-       UMASetMenuTitle(MAC_WXHMENU(m_hMenu) , label ) ;
+    m_title = label ;
+    UMASetMenuTitle(MAC_WXHMENU(m_hMenu) , label , wxFont::GetDefaultEncoding() ) ;
 }
 }
+
 bool wxMenu::ProcessCommand(wxCommandEvent & event)
 {
 bool wxMenu::ProcessCommand(wxCommandEvent & event)
 {
-    bool processed = FALSE;
-
-#if WXWIN_COMPATIBILITY
-    // Try a callback
-    if (m_callback)
-    {
-        (void)(*(m_callback))(*this, event);
-        processed = TRUE;
-    }
-#endif WXWIN_COMPATIBILITY
+    bool processed = false;
 
     // Try the menu's event handler
 
     // Try the menu's event handler
-    if ( !processed && GetEventHandler())
-    {
-        processed = GetEventHandler()->ProcessEvent(event);
-    }
+    if ( /* !processed && */ GetEventHandler())
+        processed = GetEventHandler()->SafelyProcessEvent(event);
 
 
-    // Try the window the menu was popped up from (and up through the
-    // hierarchy)
+    // Try the window the menu was popped up from
+    // (and up through the hierarchy)
     wxWindow *win = GetInvokingWindow();
     if ( !processed && win )
     wxWindow *win = GetInvokingWindow();
     if ( !processed && win )
-        processed = win->GetEventHandler()->ProcessEvent(event);
+        processed = win->HandleWindowEvent(event);
 
     return processed;
 }
 
 
     return processed;
 }
 
-
 // ---------------------------------------------------------------------------
 // other
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // other
 // ---------------------------------------------------------------------------
@@ -304,19 +393,19 @@ wxWindow *wxMenu::GetWindow() const
 {
     if ( m_invokingWindow != NULL )
         return m_invokingWindow;
 {
     if ( m_invokingWindow != NULL )
         return m_invokingWindow;
-    else if ( m_menuBar != NULL)
-        return (wxWindow *) m_menuBar->GetFrame();
+    else if ( GetMenuBar() != NULL)
+        return (wxWindow *) GetMenuBar()->GetFrame();
 
     return NULL;
 }
 
 
     return NULL;
 }
 
-// helper functions returning the mac menu position for a certain item, note that this is 
+// 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
 
 // mac-wise 1 - based, i.e. the first item has index 1 whereas on MSWin it has pos 0
 
-int wxMenu::MacGetIndexFromId( int id ) 
+int wxMenu::MacGetIndexFromId( int id )
 {
     size_t pos;
 {
     size_t pos;
-    wxMenuItemList::Node *node = GetMenuItems().GetFirst();
+    wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst();
     for ( pos = 0; node; pos++ )
     {
         if ( node->GetData()->GetId() == id )
     for ( pos = 0; node; pos++ )
     {
         if ( node->GetData()->GetId() == id )
@@ -324,17 +413,17 @@ int wxMenu::MacGetIndexFromId( int id )
 
         node = node->GetNext();
     }
 
         node = node->GetNext();
     }
-       
+
     if (!node)
     if (!node)
-               return 0;
-               
-       return pos + 1 ;
+        return 0;
+
+    return pos + 1 ;
 }
 
 }
 
-int wxMenu::MacGetIndexFromItem( wxMenuItem *pItem ) 
+int wxMenu::MacGetIndexFromItem( wxMenuItem *pItem )
 {
     size_t pos;
 {
     size_t pos;
-    wxMenuItemList::Node *node = GetMenuItems().GetFirst();
+    wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst();
     for ( pos = 0; node; pos++ )
     {
         if ( node->GetData() == pItem )
     for ( pos = 0; node; pos++ )
     {
         if ( node->GetData() == pItem )
@@ -344,21 +433,205 @@ int wxMenu::MacGetIndexFromItem( wxMenuItem *pItem )
     }
 
     if (!node)
     }
 
     if (!node)
-               return 0;
-               
-       return pos + 1 ;
+        return 0;
+
+    return pos + 1 ;
+}
+
+void wxMenu::MacEnableMenu( bool bDoEnable )
+{
+    UMAEnableMenuItem(MAC_WXHMENU(m_hMenu) , 0 , bDoEnable ) ;
+
+    ::DrawMenuBar() ;
+}
+
+// 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 )
+{
+    wxMenuItem* previousItem = NULL ;
+    size_t pos ;
+    wxMenuItemList::compatibility_iterator node;
+    wxMenuItem *item;
+
+    for (pos = 0, node = GetMenuItems().GetFirst(); node; node = node->GetNext(), pos++)
+    {
+        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 );
+                }
+            }
+        }
+
+        previousItem = item ;
+    }
+
+    if ( isSubMenu )
+        ::InsertMenu(MAC_WXHMENU( GetHMenu()), -1);
+}
+
+// undo all changes from the MacBeforeDisplay call
+void wxMenu::MacAfterDisplay( bool isSubMenu )
+{
+    if ( isSubMenu )
+        ::DeleteMenu(MacGetMenuId());
+
+    wxMenuItemList::compatibility_iterator node;
+    wxMenuItem *item;
+
+    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
+        }
+    }
+}
+
+wxInt32 wxMenu::MacHandleCommandProcess( wxMenuItem* item, int id, wxWindow* targetWindow )
+{
+    OSStatus result = eventNotHandledErr ;
+    if (item->IsCheckable())
+        item->Check( !item->IsChecked() ) ;
+
+    if ( SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) )
+        result = noErr ;
+    else
+    {
+        if ( targetWindow != NULL )
+        {
+            wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED , id);
+            event.SetEventObject(targetWindow);
+            event.SetInt(item->IsCheckable() ? item->IsChecked() : -1);
+
+            if ( targetWindow->HandleWindowEvent(event) )
+                result = noErr ;
+        }
+    }
+    return result;
 }
 
 }
 
-void wxMenu::MacEnableMenu( bool bDoEnable ) 
+wxInt32 wxMenu::MacHandleCommandUpdateStatus(wxMenuItem* WXUNUSED(item),
+                                             int id,
+                                             wxWindow* targetWindow)
 {
 {
-       UMAEnableMenuItem(MAC_WXHMENU(m_hMenu) , 0 , bDoEnable ) ;
-               
-       ::DrawMenuBar() ;
+    OSStatus result = eventNotHandledErr ;
+    wxUpdateUIEvent event(id);
+    event.SetEventObject( this );
+
+    bool processed = false;
+
+    // Try the menu's event handler
+    {
+        wxEvtHandler *handler = GetEventHandler();
+        if ( handler )
+            processed = handler->ProcessEvent(event);
+    }
+
+    // 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();
+        }
+    }
+
+    if ( !processed && targetWindow != NULL)
+    {
+        processed = targetWindow->HandleWindowEvent(event);
+    }
+
+    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 :
 
@@ -366,16 +639,19 @@ 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 ;
 
 void wxMenuBar::Init()
 {
 
 void wxMenuBar::Init()
 {
@@ -394,14 +670,13 @@ wxMenuBar::wxMenuBar( long WXUNUSED(style) )
     Init();
 }
 
     Init();
 }
 
-
-wxMenuBar::wxMenuBar(int count, wxMenu *menus[], const wxString titles[])
+wxMenuBar::wxMenuBar(size_t count, wxMenu *menus[], const wxString titles[], long WXUNUSED(style))
 {
     Init();
 
     m_titles.Alloc(count);
 
 {
     Init();
 
     m_titles.Alloc(count);
 
-    for ( int i = 0; i < count; i++ )
+    for ( size_t i = 0; i < count; i++ )
     {
         m_menus.Append(menus[i]);
         m_titles.Add(titles[i]);
     {
         m_menus.Append(menus[i]);
         m_titles.Add(titles[i]);
@@ -412,12 +687,14 @@ wxMenuBar::wxMenuBar(int count, wxMenu *menus[], const wxString titles[])
 
 wxMenuBar::~wxMenuBar()
 {
 
 wxMenuBar::~wxMenuBar()
 {
-       if (s_macInstalledMenuBar == this)
-       {
-               ::ClearMenuBar();
-               s_macInstalledMenuBar = NULL;
-       }
+    if (s_macCommonMenuBar == this)
+        s_macCommonMenuBar = NULL;
 
 
+    if (s_macInstalledMenuBar == this)
+    {
+        ::ClearMenuBar();
+        s_macInstalledMenuBar = NULL;
+    }
 }
 
 void wxMenuBar::Refresh(bool WXUNUSED(eraseBackground), const wxRect *WXUNUSED(rect))
 }
 
 void wxMenuBar::Refresh(bool WXUNUSED(eraseBackground), const wxRect *WXUNUSED(rect))
@@ -427,194 +704,242 @@ void wxMenuBar::Refresh(bool WXUNUSED(eraseBackground), const wxRect *WXUNUSED(r
     DrawMenuBar();
 }
 
     DrawMenuBar();
 }
 
-void wxMenuBar::MacInstallMenuBar() 
+void wxMenuBar::MacInstallMenuBar()
 {
     if ( s_macInstalledMenuBar == this )
         return ;
 {
     if ( s_macInstalledMenuBar == this )
         return ;
-               
-    wxStAppResource resload ;
-               
-    Handle menubar = ::GetNewMBar( kwxMacMenuBarResource ) ;
-    wxString message ;
-    wxCHECK_RET( menubar != NULL, "can't read MBAR resource" );
+
+    MenuBarHandle menubar = NULL ;
+
+    menubar = NewHandleClear( 6 /* sizeof( MenuBarHeader ) */ ) ;
+
     ::SetMenuBar( menubar ) ;
     ::SetMenuBar( menubar ) ;
-#if TARGET_API_MAC_CARBON
-    ::DisposeMenuBar( menubar ) ;
-#else
-    ::DisposeHandle( menubar ) ;
-#endif
+    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 TARGET_API_MAC_OS8
-    MenuHandle menu = ::GetMenuHandle( kwxMacAppleMenuId ) ;
-    if ( CountMenuItems( menu ) == 2 )
+    if ( wxApp::s_macPreferencesMenuItemId)
     {
     {
-        ::AppendResMenu(menu, 'DRVR');
+        wxMenuItem *item = FindItem( wxApp::s_macPreferencesMenuItemId , NULL ) ;
+        if ( item == NULL || !(item->IsEnabled()) )
+            DisableMenuCommand( NULL , kHICommandPreferences ) ;
+        else
+            EnableMenuCommand( NULL , kHICommandPreferences ) ;
     }
     }
-#endif
-    // clean-up the help menu before adding new items
-       MenuHandle mh = NULL ;
-       if ( UMAGetHelpMenu( &mh , &firstUserHelpMenuItem) == noErr )
-       {
-           for ( int i = CountMenuItems( mh ) ; i >= firstUserHelpMenuItem ; --i )
-           {
-               DeleteMenuItem( mh , i ) ;
-           }
-       }
-       else
-       {
-           mh = NULL ;
-       }
-#if TARGET_CARBON
-       if ( UMAGetSystemVersion() >= 0x1000 && wxApp::s_macPreferencesMenuItemId)
-       {
-               wxMenuItem *item = FindItem( wxApp::s_macPreferencesMenuItemId , NULL ) ;
-               if ( item == NULL || !(item->IsEnabled()) )
-                       DisableMenuCommand( NULL , kHICommandPreferences ) ;
-               else
-                       EnableMenuCommand( NULL , kHICommandPreferences ) ;
-       }
-#endif
-       for (size_t i = 0; i < m_menus.GetCount(); i++)
-       {
-        Str255         label;
-        wxMenuItemList::Node *node;
+
+    // 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;
         wxMenuItem *item;
-        int pos ;
-       wxMenu* menu = m_menus[i] , *subMenu = NULL ;
-
-       if( m_titles[i] == "?" || m_titles[i] == "&?"  || m_titles[i] == wxApp::s_macHelpMenuTitleName )
-       {
-                       if ( mh == NULL )
-                       {
-                           continue ;
-                       }
-                               
-                       for (pos = 0 , node = menu->GetMenuItems().GetFirst(); node; node = node->GetNext(), pos++) 
-                       {
-                               item = (wxMenuItem *)node->GetData();
-                               subMenu = item->GetSubMenu() ;
-                               if (subMenu)                    
-                               {
-                                       // we don't support hierarchical menus in the help menu yet
-                               }
-                               else            
-                               {
-                                       if ( item->IsSeparator() )
-                                       {
-                                               if ( mh )
-                                                       MacAppendMenu(mh, "\p-" );
-                                       }
-                                       else
-                                       {
-                                               wxAcceleratorEntry* entry = wxGetAccelFromString( item->GetText() ) ;
-
-                                               if ( item->GetId() == wxApp::s_macAboutMenuItemId )
-                                               { 
-                                                               UMASetMenuItemText( GetMenuHandle( kwxMacAppleMenuId ) , 1 , item->GetText()  );
-                                                               UMAEnableMenuItem( GetMenuHandle( kwxMacAppleMenuId ) , 1 , true );
-                                                               SetMenuItemCommandID( GetMenuHandle( kwxMacAppleMenuId ) , 1 , item->GetId() ) ;
-                                                               UMASetMenuItemShortcut( GetMenuHandle( kwxMacAppleMenuId ) , 1 , entry ) ;
-                                               }
-                                               else
-                                               {
-                                                       if ( mh )
-                                                       {
-                                                               UMAAppendMenuItem(mh, item->GetText()  , entry );
-                                                               SetMenuItemCommandID( mh , CountMenuItems(mh) , item->GetId() ) ;
-                                                       }
-                                               }
-                                               
-                                               delete entry ;
-                                       }
-                               }
-                       }
-               }
-               else
-               {
-                       UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , m_titles[i] ) ;
-                       wxArrayPtrVoid submenus ;
-                       wxMenuItem* previousItem = NULL ;
-                       for (pos = 0, node = menu->GetMenuItems().GetFirst(); node; node = node->GetNext(), pos++) 
-                       {
-                               item = (wxMenuItem *)node->GetData();
-                               subMenu = item->GetSubMenu() ;
-                               if (subMenu)                    
-                               {
-                                 submenus.Add(subMenu) ;
-                               }
-                               else
-                               {
-#if TARGET_CARBON
-                                       if ( UMAGetSystemVersion() >= 0x1000 )
-                                       {
-                                               if ( item->GetId() == wxApp::s_macPreferencesMenuItemId || item->GetId() == wxApp::s_macExitMenuItemId)
-                                               {
-                                                       ChangeMenuItemAttributes( MAC_WXHMENU( menu->GetHMenu() ) , pos + 1, kMenuItemAttrHidden, 0 );
-                                                       if ( menu->GetMenuItems().GetCount() == pos + 1 && previousItem != NULL && previousItem->IsSeparator() )
-                                                       {
-                                                               ChangeMenuItemAttributes( MAC_WXHMENU( menu->GetHMenu() ) , pos , kMenuItemAttrHidden, 0 );
-                                                       }
-                                               }
-                                       }
-#endif 
-                               }
-                               previousItem = item ;
-                       }
-                       ::InsertMenu(MAC_WXHMENU(m_menus[i]->GetHMenu()), 0);
-                       for ( size_t i = 0 ; i < submenus.GetCount() ; ++i )
-                       {
-                           wxMenu* submenu = (wxMenu*) submenus[i] ;
-               wxMenuItemList::Node *subnode;
-               wxMenuItem *subitem;
-               int subpos ;
-                for ( subpos = 0 , subnode = submenu->GetMenuItems().GetFirst(); subnode; subnode = subnode->GetNext(), subpos++) 
-                               {
-                                       subitem = (wxMenuItem *)subnode->GetData();
-                                       wxMenu* itsSubMenu = subitem->GetSubMenu() ;
-                                       if (itsSubMenu)                 
-                                       {
-                                               submenus.Add(itsSubMenu) ;
-                                       }                               
-                               }
-                               ::InsertMenu( MAC_WXHMENU(submenu->GetHMenu()) , -1 ) ;
-                   }
-               }
-       }
-       ::DrawMenuBar() ;
-       s_macInstalledMenuBar = this;
+        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;
 }
 
 void wxMenuBar::EnableTop(size_t pos, bool enable)
 {
     wxCHECK_RET( IsAttached(), wxT("doesn't work with unattached menubars") );
 }
 
 void wxMenuBar::EnableTop(size_t pos, bool enable)
 {
     wxCHECK_RET( IsAttached(), wxT("doesn't work with unattached menubars") );
-       m_menus[pos]->MacEnableMenu( enable ) ;
+
+    _wxMenuAt(m_menus, pos)->MacEnableMenu( enable ) ;
     Refresh();
 }
 
     Refresh();
 }
 
-void wxMenuBar::SetLabelTop(size_t pos, const wxString& label)
+bool wxMenuBar::Enable(bool enable)
+{
+    wxCHECK_MSG( IsAttached(), false, wxT("doesn't work with unattached menubars") );
+
+    size_t i;
+    for (i = 0; i < GetMenuCount(); i++)
+        EnableTop(i, enable);
+
+    return true;
+}
+
+void wxMenuBar::SetMenuLabel(size_t pos, const wxString& label)
 {
     wxCHECK_RET( pos < GetMenuCount(), wxT("invalid menu index") );
 
     m_titles[pos] = label;
 
     if ( !IsAttached() )
 {
     wxCHECK_RET( pos < GetMenuCount(), wxT("invalid menu index") );
 
     m_titles[pos] = label;
 
     if ( !IsAttached() )
-    {
         return;
         return;
-    }
 
 
-    m_menus[pos]->SetTitle( label ) ;
-       if (wxMenuBar::s_macInstalledMenuBar == this) // are we currently installed ?
-       {
-               ::SetMenuBar( GetMenuBar() ) ;
-               ::InvalMenuBar() ;
-       }
+    _wxMenuAt(m_menus, pos)->SetTitle( label ) ;
+
+    if (wxMenuBar::s_macInstalledMenuBar == this) // are we currently installed ?
+    {
+        ::SetMenuBar( GetMenuBar() ) ;
+        ::InvalMenuBar() ;
+    }
 }
 
 }
 
-wxString wxMenuBar::GetLabelTop(size_t pos) const
+wxString wxMenuBar::GetMenuLabel(size_t pos) const
 {
     wxCHECK_MSG( pos < GetMenuCount(), wxEmptyString,
 {
     wxCHECK_MSG( pos < GetMenuCount(), wxEmptyString,
-                 wxT("invalid menu index in wxMenuBar::GetLabelTop") );
+                 wxT("invalid menu index in wxMenuBar::GetMenuLabel") );
 
     return m_titles[pos];
 }
 
     return m_titles[pos];
 }
@@ -628,18 +953,12 @@ int wxMenuBar::FindMenu(const wxString& title)
     {
         wxString title = wxStripMenuCodes(m_titles[i]);
         if ( menuTitle == title )
     {
         wxString title = wxStripMenuCodes(m_titles[i]);
         if ( menuTitle == title )
-            return i; 
+            return i;
     }
 
     return wxNOT_FOUND;
     }
 
     return wxNOT_FOUND;
-
 }
 
 }
 
-
-// ---------------------------------------------------------------------------
-// wxMenuBar construction
-// ---------------------------------------------------------------------------
-
 // ---------------------------------------------------------------------------
 // wxMenuBar construction
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // wxMenuBar construction
 // ---------------------------------------------------------------------------
@@ -648,56 +967,62 @@ wxMenu *wxMenuBar::Replace(size_t pos, wxMenu *menu, const wxString& title)
 {
     wxMenu *menuOld = wxMenuBarBase::Replace(pos, menu, title);
     if ( !menuOld )
 {
     wxMenu *menuOld = wxMenuBarBase::Replace(pos, menu, title);
     if ( !menuOld )
-        return FALSE;
+        return NULL;
+
     m_titles[pos] = title;
 
     if ( IsAttached() )
     {
     m_titles[pos] = title;
 
     if ( IsAttached() )
     {
-               if (s_macInstalledMenuBar == this)
-               {
-                       ::DeleteMenu( menuOld->MacGetMenuId() /* m_menus[pos]->MacGetMenuId() */ ) ;
-                       {
-                               UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , title ) ;
-                               if ( pos == m_menus.GetCount() - 1)
-                               {
-                                       ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , 0 ) ;
-                               }
-                               else
-                               {
-                                       ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , m_menus[pos+1]->MacGetMenuId() ) ;
-                               }
-                       }
-               }
+        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();
     }
 
 
         Refresh();
     }
 
+    if (m_invokingWindow)
+        wxMenubarSetInvokingWindow( menu, m_invokingWindow );
+
     return menuOld;
 }
 
 bool wxMenuBar::Insert(size_t pos, wxMenu *menu, const wxString& title)
 {
     if ( !wxMenuBarBase::Insert(pos, menu, title) )
     return menuOld;
 }
 
 bool wxMenuBar::Insert(size_t pos, wxMenu *menu, const wxString& title)
 {
     if ( !wxMenuBarBase::Insert(pos, menu, title) )
-        return FALSE;
+        return false;
 
     m_titles.Insert(title, pos);
 
 
     m_titles.Insert(title, pos);
 
-       UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , title ) ;
+    UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , title , m_font.GetEncoding() ) ;
 
 
-    if ( IsAttached() )
+    if ( IsAttached() && s_macInstalledMenuBar == this )
     {
     {
-       if ( pos == (size_t) -1  || pos + 1 == m_menus.GetCount() )
-               {
-                       ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , 0 ) ;
-               }
-               else
-               {
-                       ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , m_menus[pos+1]->MacGetMenuId() ) ;
-               }
+        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();
     }
 
         Refresh();
     }
 
-    return TRUE;
+    if (m_invokingWindow)
+        wxMenubarSetInvokingWindow( menu, m_invokingWindow );
+
+    return true;
 }
 
 wxMenu *wxMenuBar::Remove(size_t pos)
 }
 
 wxMenu *wxMenuBar::Remove(size_t pos)
@@ -708,17 +1033,13 @@ wxMenu *wxMenuBar::Remove(size_t pos)
 
     if ( IsAttached() )
     {
 
     if ( IsAttached() )
     {
-               if (s_macInstalledMenuBar == this)
-               {
-                       ::DeleteMenu( menu->MacGetMenuId() /* m_menus[pos]->MacGetMenuId() */ ) ;
-               }
-
-        menu->Detach();
+        if (s_macInstalledMenuBar == this)
+            ::DeleteMenu( menu->MacGetMenuId() /* m_menus[pos]->MacGetMenuId() */ ) ;
 
         Refresh();
     }
 
 
         Refresh();
     }
 
-    m_titles.Remove(pos);
+    m_titles.RemoveAt(pos);
 
     return menu;
 }
 
     return menu;
 }
@@ -726,43 +1047,45 @@ wxMenu *wxMenuBar::Remove(size_t pos)
 bool wxMenuBar::Append(wxMenu *menu, const wxString& title)
 {
     WXHMENU submenu = menu ? menu->GetHMenu() : 0;
 bool wxMenuBar::Append(wxMenu *menu, const wxString& title)
 {
     WXHMENU submenu = menu ? menu->GetHMenu() : 0;
-    wxCHECK_MSG( submenu, FALSE, wxT("can't append invalid menu to menubar") );
+        wxCHECK_MSG( submenu, false, wxT("can't append invalid menu to menubar") );
 
     if ( !wxMenuBarBase::Append(menu, title) )
 
     if ( !wxMenuBarBase::Append(menu, title) )
-        return FALSE;
+        return false;
 
     m_titles.Add(title);
 
     m_titles.Add(title);
-    
-       UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , title ) ;
+
+    UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , title , m_font.GetEncoding() ) ;
 
     if ( IsAttached() )
     {
 
     if ( IsAttached() )
     {
-               if (s_macInstalledMenuBar == this)
-               {
-                       ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , 0 ) ;
-               }
+        if (s_macInstalledMenuBar == this)
+        {
+            menu->MacBeforeDisplay( false ) ;
+            ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , 0 ) ;
+        }
 
         Refresh();
     }
 
 
         Refresh();
     }
 
-   // m_invokingWindow is set after wxFrame::SetMenuBar(). This call enables
+    // m_invokingWindow is set after wxFrame::SetMenuBar(). This call enables
     // adding menu later on.
     if (m_invokingWindow)
         wxMenubarSetInvokingWindow( menu, m_invokingWindow );
 
     // adding menu later on.
     if (m_invokingWindow)
         wxMenubarSetInvokingWindow( menu, m_invokingWindow );
 
-    return TRUE;
+    return true;
 }
 
 static void wxMenubarUnsetInvokingWindow( wxMenu *menu )
 {
     menu->SetInvokingWindow( (wxWindow*) NULL );
 }
 
 static void wxMenubarUnsetInvokingWindow( wxMenu *menu )
 {
     menu->SetInvokingWindow( (wxWindow*) NULL );
+    wxMenuItemList::compatibility_iterator node = menu->GetMenuItems().GetFirst();
 
 
-    wxMenuItemList::Node *node = menu->GetMenuItems().GetFirst();
     while (node)
     {
         wxMenuItem *menuitem = node->GetData();
         if (menuitem->IsSubMenu())
             wxMenubarUnsetInvokingWindow( menuitem->GetSubMenu() );
     while (node)
     {
         wxMenuItem *menuitem = node->GetData();
         if (menuitem->IsSubMenu())
             wxMenubarUnsetInvokingWindow( menuitem->GetSubMenu() );
+
         node = node->GetNext();
     }
 }
         node = node->GetNext();
     }
 }
@@ -770,13 +1093,15 @@ static void wxMenubarUnsetInvokingWindow( wxMenu *menu )
 static void wxMenubarSetInvokingWindow( wxMenu *menu, wxWindow *win )
 {
     menu->SetInvokingWindow( win );
 static void wxMenubarSetInvokingWindow( wxMenu *menu, wxWindow *win )
 {
     menu->SetInvokingWindow( win );
+    wxMenuItem *menuitem;
+    wxMenuItemList::compatibility_iterator node = menu->GetMenuItems().GetFirst();
 
 
-    wxMenuItemList::Node *node = menu->GetMenuItems().GetFirst();
     while (node)
     {
     while (node)
     {
-        wxMenuItem *menuitem = node->GetData();
+        menuitem = node->GetData();
         if (menuitem->IsSubMenu())
             wxMenubarSetInvokingWindow( menuitem->GetSubMenu() , win );
         if (menuitem->IsSubMenu())
             wxMenubarSetInvokingWindow( menuitem->GetSubMenu() , win );
+
         node = node->GetNext();
     }
 }
         node = node->GetNext();
     }
 }
@@ -784,11 +1109,14 @@ static void wxMenubarSetInvokingWindow( wxMenu *menu, wxWindow *win )
 void wxMenuBar::UnsetInvokingWindow()
 {
     m_invokingWindow = (wxWindow*) NULL;
 void wxMenuBar::UnsetInvokingWindow()
 {
     m_invokingWindow = (wxWindow*) NULL;
-    wxMenuList::Node *node = m_menus.GetFirst();
+    wxMenu *menu;
+    wxMenuList::compatibility_iterator node = m_menus.GetFirst();
+
     while (node)
     {
     while (node)
     {
-        wxMenu *menu = node->GetData();
+        menu = node->GetData();
         wxMenubarUnsetInvokingWindow( menu );
         wxMenubarUnsetInvokingWindow( menu );
+
         node = node->GetNext();
     }
 }
         node = node->GetNext();
     }
 }
@@ -796,11 +1124,14 @@ void wxMenuBar::UnsetInvokingWindow()
 void wxMenuBar::SetInvokingWindow(wxFrame *frame)
 {
     m_invokingWindow = frame;
 void wxMenuBar::SetInvokingWindow(wxFrame *frame)
 {
     m_invokingWindow = frame;
-    wxMenuList::Node *node = m_menus.GetFirst();
+    wxMenu *menu;
+    wxMenuList::compatibility_iterator node = m_menus.GetFirst();
+
     while (node)
     {
     while (node)
     {
-        wxMenu *menu = node->GetData();
+        menu = node->GetData();
         wxMenubarSetInvokingWindow( menu, frame );
         wxMenubarSetInvokingWindow( menu, frame );
+
         node = node->GetNext();
     }
 }
         node = node->GetNext();
     }
 }
@@ -814,6 +1145,7 @@ void wxMenuBar::Attach(wxFrame *frame)
 {
     wxMenuBarBase::Attach( frame ) ;
 }
 {
     wxMenuBarBase::Attach( frame ) ;
 }
+
 // ---------------------------------------------------------------------------
 // wxMenuBar searching for menu items
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // wxMenuBar searching for menu items
 // ---------------------------------------------------------------------------
@@ -827,8 +1159,8 @@ int wxMenuBar::FindMenuItem(const wxString& menuString,
     for ( size_t i = 0; i < count; i++ )
     {
         wxString title = wxStripMenuCodes(m_titles[i]);
     for ( size_t i = 0; i < count; i++ )
     {
         wxString title = wxStripMenuCodes(m_titles[i]);
-        if ( menuString == title )
-            return m_menus[i]->FindItem(itemString);
+        if ( menuLabel == title )
+            return _wxMenuAt(m_menus, i)->FindItem(itemString);
     }
 
     return wxNOT_FOUND;
     }
 
     return wxNOT_FOUND;
@@ -842,11 +1174,7 @@ wxMenuItem *wxMenuBar::FindItem(int id, wxMenu **itemMenu) const
     wxMenuItem *item = NULL;
     size_t count = GetMenuCount();
     for ( size_t i = 0; !item && (i < count); i++ )
     wxMenuItem *item = NULL;
     size_t count = GetMenuCount();
     for ( size_t i = 0; !item && (i < count); i++ )
-    {
-        item = m_menus[i]->FindItem(id, itemMenu);
-    }
+        item = _wxMenuAt(m_menus, i)->FindItem(id, itemMenu);
 
     return item;
 }
 
     return item;
 }
-
-