]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/menu.cpp
don't call SelectObject() twice in SetBrush() nor SetFont() neither
[wxWidgets.git] / src / mac / menu.cpp
index 9d308de12071467827fcf58f1a6f4211c1e90186..9a04c36935ab6fddef1d2a1d6924ef36bb698944 100644 (file)
@@ -1,14 +1,18 @@
 /////////////////////////////////////////////////////////////////////////////
 // Name:        menu.cpp
 // Purpose:     wxMenu, wxMenuBar, wxMenuItem
 /////////////////////////////////////////////////////////////////////////////
 // Name:        menu.cpp
 // 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
 /////////////////////////////////////////////////////////////////////////////
 
 /////////////////////////////////////////////////////////////////////////////
 
+#ifdef __GNUG__
+#pragma implementation "menu.h"
+#pragma implementation "menuitem.h"
+#endif
 
 // ============================================================================
 // headers & declarations
 
 // ============================================================================
 // headers & declarations
 // wxWindows headers
 // -----------------
 
 // wxWindows headers
 // -----------------
 
-#ifdef __GNUG__
-#pragma implementation "menu.h"
-#pragma implementation "menuitem.h"
-#endif
-
 #include "wx/app.h"
 #include "wx/menu.h"
 #include "wx/menuitem.h"
 #include "wx/window.h"
 #include "wx/log.h"
 #include "wx/utils.h"
 #include "wx/app.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"
 
 #include "wx/mac/uma.h"
 
 
 #include "wx/mac/uma.h"
 
@@ -42,7 +42,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxMenuBar, wxEvtHandler)
 
 // the (popup) menu title has this special id
 static const int idMenuTitle = -2;
 
 // the (popup) menu title has this special id
 static const int idMenuTitle = -2;
-static int formerHelpMenuItems = 0 ;
+static MenuItemIndex firstUserHelpMenuItem = 0 ;
 
 const short kwxMacMenuBarResource = 1 ;
 const short kwxMacAppleMenuId = 1 ;
 
 const short kwxMacMenuBarResource = 1 ;
 const short kwxMacAppleMenuId = 1 ;
@@ -50,28 +50,31 @@ const short kwxMacAppleMenuId = 1 ;
 // ============================================================================
 // implementation
 // ============================================================================
 // ============================================================================
 // 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
 
 void wxMenu::Init()
 {
     m_doBreak = FALSE;
 
 void wxMenu::Init()
 {
     m_doBreak = FALSE;
+    m_startRadioGroup = -1;
 
     // create the menu
 
     // create the menu
-       Str255  label;
-       wxMenuItem::MacBuildMenuString( label, NULL , NULL , m_title , false );
-       m_macMenuId = s_macNextMenuId++; 
-    wxCHECK_RET( s_macNextMenuId < 236 , "menu ids > 235 cannot be used for submenus on mac" );
-       m_hMenu = UMANewMenu(m_macMenuId, label);
+    m_macMenuId = s_macNextMenuId++;
+    m_hMenu = UMANewMenu(m_macMenuId, m_title, wxFont::GetDefaultEncoding() );
 
     if ( !m_hMenu )
     {
 
     if ( !m_hMenu )
     {
-        wxLogLastError("CreatePopupMenu");
+        wxLogLastError(wxT("UMANewMenu failed"));
     }
 
     // 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
@@ -84,162 +87,159 @@ void wxMenu::Init()
 
 wxMenu::~wxMenu()
 {
 
 wxMenu::~wxMenu()
 {
-       if (m_hMenu)
-               UMADisposeMenu(m_hMenu);
-
-#if wxUSE_ACCEL
-    // delete accels
-    WX_CLEAR_ARRAY(m_accels);
-#endif // wxUSE_ACCEL
+    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
 }
 
 }
 
-#if wxUSE_ACCEL
-
-int wxMenu::FindAccel(int id) const
+void wxMenu::Attach(wxMenuBarBase *menubar)
 {
 {
-    size_t n, count = m_accels.GetCount();
-    for ( n = 0; n < count; n++ )
-    {
-        if ( m_accels[n]->m_command == id )
-            return n;
-    }
+    wxMenuBase::Attach(menubar);
 
 
-    return wxNOT_FOUND;
+    EndRadioGroup();
 }
 
 }
 
-void wxMenu::UpdateAccel(wxMenuItem *item)
+// 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)
 {
 {
-    // find the (new) accel for this item
-    wxAcceleratorEntry *accel = wxGetAccelFromString(item->GetText());
-    if ( accel )
-        accel->m_command = item->GetId();
-
-    // find the old one
-    int n = FindAccel(item->GetId());
-    if ( n == wxNOT_FOUND )
+    wxASSERT_MSG( pItem != NULL, wxT("can't append NULL item to the menu") );
+
+    if ( pItem->IsSeparator() )
     {
     {
-        // no old, add new if any
-        if ( accel )
-            m_accels.Add(accel);
+        if ( pos == (size_t)-1 )
+            MacAppendMenu(MAC_WXHMENU(m_hMenu), "\p-");
         else
         else
-            return;     // skipping RebuildAccelTable() below
+            MacInsertMenuItem(MAC_WXHMENU(m_hMenu), "\p-" , pos);
     }
     else
     {
     }
     else
     {
-        // replace old with new or just remove the old one if no new
-        delete m_accels[n];
-        if ( accel )
-            m_accels[n] = accel;
+        wxMenu *pSubMenu = pItem->GetSubMenu() ;
+        if ( pSubMenu != NULL )
+        {
+               wxASSERT_MSG( pSubMenu->m_hMenu != NULL , wxT("invalid submenu added"));
+            pSubMenu->m_menuParent = this ;
+
+            if (wxMenuBar::MacGetInstalledMenuBar() == m_menuBar)
+            {
+                pSubMenu->MacBeforeDisplay( true ) ;
+             }
+
+            if ( pos == (size_t)-1 )
+                UMAAppendSubMenuItem(MAC_WXHMENU(m_hMenu), pItem->GetText(), wxFont::GetDefaultEncoding() , pSubMenu->m_macMenuId);
+            else
+                UMAInsertSubMenuItem(MAC_WXHMENU(m_hMenu), pItem->GetText(), wxFont::GetDefaultEncoding()  , pos, pSubMenu->m_macMenuId);
+            pItem->UpdateItemBitmap() ;
+            pItem->UpdateItemStatus() ;
+        }
         else
         else
-            m_accels.Remove(n);
+        {
+            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 , 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() )
     {
     if ( IsAttached() )
     {
-        m_menuBar->RebuildAccelTable();
+        m_menuBar->Refresh();
     }
     }
+    return TRUE ;
 }
 
 }
 
-#endif // wxUSE_ACCEL
+void wxMenu::EndRadioGroup()
+{
+    // we're not inside a radio group any longer
+    m_startRadioGroup = -1;
+}
 
 
-// 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)
+wxMenuItem* wxMenu::DoAppend(wxMenuItem *item)
 {
 {
-    wxASSERT_MSG( pItem != NULL, "can't append NULL item to the menu" );
-#if wxUSE_ACCEL
-    UpdateAccel(pItem);
-#endif // wxUSE_ACCEL
-
-       if ( pItem->IsSeparator() )
-       {
-               if ( pos == (size_t)-1 )
-               {
-                       MacAppendMenu(m_hMenu, "\p-");
-               }
-               else
-               {
-                       MacInsertMenuItem(m_hMenu, "\p-" , pos);
-               }
-       }
-       else 
-       {
-               wxMenu *pSubMenu = pItem->GetSubMenu() ;
-               if ( pSubMenu != NULL )
-               {
-                       Str255 label;
-                       wxASSERT_MSG( pSubMenu->m_hMenu != NULL , "invalid submenu added");
-                   pSubMenu->m_menuParent = this ;
-                       wxMenuItem::MacBuildMenuString( label , NULL , NULL , pItem->GetText() ,false);
-               
-                       if (wxMenuBar::MacGetInstalledMenuBar() == m_menuBar) 
-                       {
-                               UMAInsertMenu( pSubMenu->m_hMenu , -1 ) ;
-                       }
-                       
-                       if ( pos == (size_t)-1 )
-                       {
-                               UMAAppendSubMenuItem(m_hMenu, label, pSubMenu->m_macMenuId);
-                       }
-                       else
-                       {
-                               UMAInsertSubMenuItem(m_hMenu, label , pos, pSubMenu->m_macMenuId);
-                       }
-               }
-               else
-               {
-                       Str255 label ;
-                       UInt8 modifiers ;
-                       SInt16 key ;
-                       wxMenuItem::MacBuildMenuString( label, &key  , &modifiers , pItem->GetText(), pItem->GetId() == wxApp::s_macAboutMenuItemId);
-                       if ( label[0] == 0 )
-                       {
-                               // we cannot add empty menus on mac
-                               label[0] = 1 ;
-                               label[1] = ' ' ;
-                       }
-                       if ( pos == (size_t)-1 )
-                       {
-                               UMAAppendMenuItem(m_hMenu, label,key,modifiers);
-                       }
-                       else
-                       {
-                               UMAInsertMenuItem(m_hMenu, label , pos,key,modifiers);
-                       }
-                       if ( pItem->GetId() == idMenuTitle ) 
-                       {
-                               if ( pos == (size_t)-1 )
-                               {
-                                       UMADisableMenuItem( m_hMenu , CountMenuItems( m_hMenu ) ) ;
-                               }
-                               else
-                               {
-                                       UMADisableMenuItem( m_hMenu , pos + 1 ) ;
-                               }
-                       }
-               }
-       }
-    // if we're already attached to the menubar, we must update it
-    if ( IsAttached() )
+    wxCHECK_MSG( item, NULL, _T("NULL item in wxMenu::DoAppend") );
+
+    bool check = FALSE;
+
+    if ( item->GetKind() == wxITEM_RADIO )
     {
     {
-        m_menuBar->Refresh();
+        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::Node *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();
     }
     }
-       return TRUE ;
-}
 
 
-bool wxMenu::DoAppend(wxMenuItem *item)
-{
-    return wxMenuBase::DoAppend(item) && DoInsertOrAppend(item);
+    if ( !wxMenuBase::DoAppend(item) || !DoInsertOrAppend(item) )
+    {
+        return NULL;
+    }
+
+    if ( check )
+    {
+        // check the item initially
+        item->Check(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;
+    else
+        return NULL;
 }
 
 wxMenuItem *wxMenu::DoRemove(wxMenuItem *item)
 }
 
 wxMenuItem *wxMenu::DoRemove(wxMenuItem *item)
@@ -258,23 +258,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") );
 
-#if wxUSE_ACCEL
-    // remove the corresponding accel from the accel table
-    int n = FindAccel(item->GetId());
-    if ( n != wxNOT_FOUND )
-    {
-        delete m_accels[n];
-
-        m_accels.Remove(n);
-    }
-    //else: this item doesn't have an accel, nothing to do
-#endif // wxUSE_ACCEL
-
-       ::DeleteMenuItem( m_hMenu , pos + 1);
+    ::DeleteMenuItem(MAC_WXHMENU(m_hMenu) , pos + 1);
 
     if ( IsAttached() )
     {
 
     if ( IsAttached() )
     {
-        // otherwise, the chane won't be visible
+        // otherwise, the change won't be visible
         m_menuBar->Refresh();
     }
 
         m_menuBar->Refresh();
     }
 
@@ -282,47 +270,15 @@ wxMenuItem *wxMenu::DoRemove(wxMenuItem *item)
     return wxMenuBase::DoRemove(item);
 }
 
     return wxMenuBase::DoRemove(item);
 }
 
-// ---------------------------------------------------------------------------
-// accelerator helpers
-// ---------------------------------------------------------------------------
-
-#if wxUSE_ACCEL
-
-// create the wxAcceleratorEntries for our accels and put them into provided
-// array - return the number of accels we have
-size_t wxMenu::CopyAccels(wxAcceleratorEntry *accels) const
-{
-    size_t count = GetAccelCount();
-    for ( size_t n = 0; n < count; n++ )
-    {
-        *accels++ = *m_accels[n];
-    }
-
-    return count;
-}
-
-#endif // wxUSE_ACCEL
-
 void wxMenu::SetTitle(const wxString& label)
 {
 void wxMenu::SetTitle(const wxString& label)
 {
-       Str255 title ;
-    m_title = label ;
-       wxMenuItem::MacBuildMenuString( title, NULL , NULL , label , false );
-       UMASetMenuTitle( m_hMenu , title ) ;
+       m_title = label ;
+    UMASetMenuTitle(MAC_WXHMENU(m_hMenu) , label , wxFont::GetDefaultEncoding() ) ;
 }
 bool wxMenu::ProcessCommand(wxCommandEvent & event)
 {
     bool processed = FALSE;
 
 }
 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
-
     // Try the menu's event handler
     if ( !processed && GetEventHandler())
     {
     // Try the menu's event handler
     if ( !processed && GetEventHandler())
     {
@@ -343,22 +299,6 @@ bool wxMenu::ProcessCommand(wxCommandEvent & event)
 // other
 // ---------------------------------------------------------------------------
 
 // other
 // ---------------------------------------------------------------------------
 
-void wxMenu::Attach(wxMenuBar *menubar)
-{
-    // menu can be in at most one menubar because otherwise they would both
-    // delete the menu pointer
-    wxASSERT_MSG( !m_menuBar, wxT("menu belongs to 2 menubars, expect a crash") );
-
-    m_menuBar = menubar;
-}
-
-void wxMenu::Detach()
-{
-    wxASSERT_MSG( m_menuBar, wxT("can't detach menu if it's not attached") );
-
-    m_menuBar = NULL;
-}
-
 wxWindow *wxMenu::GetWindow() const
 {
     if ( m_invokingWindow != NULL )
 wxWindow *wxMenu::GetWindow() const
 {
     if ( m_invokingWindow != NULL )
@@ -369,10 +309,10 @@ wxWindow *wxMenu::GetWindow() const
     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;
     wxMenuItemList::Node *node = GetMenuItems().GetFirst();
 {
     size_t pos;
     wxMenuItemList::Node *node = GetMenuItems().GetFirst();
@@ -383,14 +323,14 @@ 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;
     wxMenuItemList::Node *node = GetMenuItems().GetFirst();
 {
     size_t pos;
     wxMenuItemList::Node *node = GetMenuItems().GetFirst();
@@ -403,134 +343,89 @@ int wxMenu::MacGetIndexFromItem( wxMenuItem *pItem )
     }
 
     if (!node)
     }
 
     if (!node)
-               return 0;
-               
-       return pos + 1 ;
+        return 0;
+
+    return pos + 1 ;
 }
 
 }
 
-void wxMenu::MacEnableMenu( bool bDoEnable ) 
+void wxMenu::MacEnableMenu( bool bDoEnable )
 {
 {
-       if ( bDoEnable )
-               UMAEnableMenuItem( m_hMenu , 0 ) ;
-       else
-               UMADisableMenuItem( m_hMenu , 0 ) ;
-               
-       ::DrawMenuBar() ;
+    UMAEnableMenuItem(MAC_WXHMENU(m_hMenu) , 0 , bDoEnable ) ;
+
+    ::DrawMenuBar() ;
 }
 
 }
 
-bool wxMenu::MacMenuSelect( wxEvtHandler* handler, long when , int macMenuId, int macMenuItemNum )
+// 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 )
 {
 {
-  int pos;
-  wxNode *node;
-
-       if ( m_macMenuId == macMenuId )
-       {
-               node = GetMenuItems().Nth(macMenuItemNum-1);
-               if (node) 
-               {
-                       wxMenuItem *pItem = (wxMenuItem*)node->Data();
-
-                       if (pItem->IsCheckable())
-                               pItem->Check(! pItem->IsChecked());
-
-                       wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, pItem->GetId());
-                       event.m_timeStamp = when;
-                       event.SetEventObject(handler);
-               event.SetInt( pItem->GetId() );
-                       {
-                               bool processed = false ;
-
-#if WXWIN_COMPATIBILITY
-                           // Try a callback
-                           if (m_callback)
-                           {
-                                   (void) (*(m_callback)) (*this, event);
-                                   processed = TRUE;
-                           }
-#endif                 
-                           // 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 ;
-               }
-       }
-#ifndef __WXMAC_X__
-       else if ( macMenuId == kHMHelpMenuID )
-       {
-               int menuItem = formerHelpMenuItems ;
-         for (pos = 0, node = GetMenuItems().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 ;
-#if WXWIN_COMPATIBILITY
-                                           // Try a callback
-                                           if (m_callback)
-                                           {
-                                                   (void) (*(m_callback)) (*this, event);
-                                                   processed = TRUE;
-                                           }
-#endif                                 
-                                           // 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 ;
-                               }
-                       }
-         }
-       }
-#endif // __WXMAC_X__
-
-  for (pos = 0, node = GetMenuItems().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 ;
+    wxMenuItem* previousItem = NULL ;
+    size_t pos ;
+    wxMenuItemList::Node *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
+        {
+            #if TARGET_CARBON
+            if ( UMAGetSystemVersion() >= 0x1000 )
+            {
+                if ( item->GetId() == wxApp::s_macPreferencesMenuItemId || item->GetId() == wxApp::s_macExitMenuItemId)
+                {
+                    ChangeMenuItemAttributes( MAC_WXHMENU( GetHMenu() ) , pos + 1, kMenuItemAttrHidden, 0 );
+                    if ( GetMenuItems().GetCount() == pos + 1 &&
+                            previousItem != NULL &&
+                                previousItem->IsSeparator() )
+                    {
+                        ChangeMenuItemAttributes( MAC_WXHMENU( GetHMenu() ) , pos , kMenuItemAttrHidden, 0 );
+                    }
+                }
+            }
+            #endif
+        }
+        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());
+
+    wxMenuItem* previousItem = NULL ;
+    int pos ;
+    wxMenuItemList::Node *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->MacAfterDisplay( true ) ;
+        }
+        else
+        {
+            // no need to undo hidings
+        }
+        previousItem = item ;
+    }
 }
 
 // Menu Bar
 
 }
 
 // Menu Bar
 
-/* 
+/*
 
 Mac Implementation note :
 
 
 Mac Implementation note :
 
@@ -538,21 +433,23 @@ 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 ;
 
 void wxMenuBar::Init()
 {
     m_eventHandler = this;
     m_menuBarFrame = NULL;
 
 void wxMenuBar::Init()
 {
     m_eventHandler = this;
     m_menuBarFrame = NULL;
+    m_invokingWindow = (wxWindow*) NULL;
 }
 
 wxMenuBar::wxMenuBar()
 }
 
 wxMenuBar::wxMenuBar()
@@ -583,182 +480,140 @@ 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()
+void wxMenuBar::Refresh(bool WXUNUSED(eraseBackground), const wxRect *WXUNUSED(rect))
 {
     wxCHECK_RET( IsAttached(), wxT("can't refresh unatteched menubar") );
 
     DrawMenuBar();
 }
 
 {
     wxCHECK_RET( IsAttached(), wxT("can't refresh unatteched menubar") );
 
     DrawMenuBar();
 }
 
-#if wxUSE_ACCEL
-
-void wxMenuBar::RebuildAccelTable()
+void wxMenuBar::MacInstallMenuBar()
 {
 {
-    // merge the accelerators of all menus into one accel table
-    size_t nAccelCount = 0;
-    size_t i, count = GetMenuCount();
-    for ( i = 0; i < count; i++ )
+    if ( s_macInstalledMenuBar == this )
+        return ;
+
+    wxStAppResource resload ;
+
+    Handle menubar = ::GetNewMBar( kwxMacMenuBarResource ) ;
+    wxString message ;
+    wxCHECK_RET( menubar != NULL, wxT("can't read MBAR resource") );
+    ::SetMenuBar( menubar ) ;
+#if TARGET_API_MAC_CARBON
+    ::DisposeMenuBar( menubar ) ;
+#else
+    ::DisposeHandle( menubar ) ;
+#endif
+
+#if TARGET_API_MAC_OS8
+    MenuHandle menu = ::GetMenuHandle( kwxMacAppleMenuId ) ;
+    if ( CountMenuItems( menu ) == 2 )
     {
     {
-        nAccelCount += m_menus[i]->GetAccelCount();
+        ::AppendResMenu(menu, 'DRVR');
     }
     }
+#endif
 
 
-    if ( nAccelCount )
+    // clean-up the help menu before adding new items
+    MenuHandle mh = NULL ;
+    if ( UMAGetHelpMenu( &mh , &firstUserHelpMenuItem) == noErr )
     {
     {
-        wxAcceleratorEntry *accelEntries = new wxAcceleratorEntry[nAccelCount];
-
-        nAccelCount = 0;
-        for ( i = 0; i < count; i++ )
+        for ( int i = CountMenuItems( mh ) ; i >= firstUserHelpMenuItem ; --i )
         {
         {
-            nAccelCount += m_menus[i]->CopyAccels(&accelEntries[nAccelCount]);
+            DeleteMenuItem( mh , i ) ;
         }
         }
-
-        m_accelTable = wxAcceleratorTable(nAccelCount, accelEntries);
-
-        delete [] accelEntries;
     }
     }
-}
-
-#endif // wxUSE_ACCEL
-
-
-void wxMenuBar::MacInstallMenuBar() 
-{
-       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_menus.GetCount(); i++)
-       {
-                       Str255  label;
-       wxNode *node;
-       wxMenuItem *item;
-       int pos ;
-                       wxMenu* menu = m_menus[i] , *subMenu = NULL ;
-               
-#if !TARGET_CARBON
-                       /* the help menu does not exist in CARBON anymore */                    
-                       if( m_titles[i] == "?" || 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->GetMenuItems().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            
-                                       {
-                                               if ( item->IsSeparator() )
-                                               {
-                                                       if ( mh )
-                                                               UMAAppendMenuItem(mh, "\p-" );
-                                               }
-                                               else
-                                               {
-                                                       Str255 label ;
-                                                       UInt8 modifiers ;
-                                                       SInt16 key ;
-                                                       wxMenuItem::MacBuildMenuString( label, &key , &modifiers  , item->GetText(), 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 )
-                                                       { 
-                                                                       UMASetMenuItemText( GetMenuHandle( kwxMacAppleMenuId ) , 1 , label );
-                                                                       UMAEnableMenuItem( GetMenuHandle( kwxMacAppleMenuId ) , 1 );
-                                                       }
-                                                       else
-                                                       {
-                                                               if ( mh )
-                                                                       UMAAppendMenuItem(mh, label , key , modifiers );
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-#else
-                       if( m_titles[i] == "?" || m_titles[i] == "&?"  || m_titles[i] == wxApp::s_macHelpMenuTitleName )
-                       {
-                               wxMenuItem::MacBuildMenuString( label, NULL , NULL , m_titles[i] , false );
-                               UMASetMenuTitle( menu->GetHMenu() , label ) ;
-                                       
-                               for (pos = 0 , node = menu->GetMenuItems().First(); node; node = node->Next(), pos++) 
-                               {
-                                       item = (wxMenuItem *)node->Data();
-                                       subMenu = item->GetSubMenu() ;
-                                       if (subMenu)                    
-                                       {
-                                               UMAInsertMenu( subMenu->GetHMenu() , -1 ) ;
-                                       }
-                                       else
-                                       {
-                                               if ( item->GetId() == wxApp::s_macAboutMenuItemId )
-                                               { 
-                                                       Str255 label ;
-                                                       UInt8 modifiers ;
-                                                       SInt16 key ;
-                                                       wxMenuItem::MacBuildMenuString( label, &key , &modifiers  , item->GetText(), item->GetId() != wxApp::s_macAboutMenuItemId); // no shortcut in about menu
-                                                       UMASetMenuItemText( GetMenuHandle( kwxMacAppleMenuId ) , 1 , label );
-                                                       UMAEnableMenuItem( GetMenuHandle( kwxMacAppleMenuId ) , 1 );
-                                               }
-                                       }
-                               }
-                               UMAInsertMenu(m_menus[i]->GetHMenu(), 0);
-                       }
+    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
 #endif
-                       else
-                       {
-                               wxMenuItem::MacBuildMenuString( label, NULL , NULL , m_titles[i] , false );
-                               UMASetMenuTitle( menu->GetHMenu() , label ) ;
-                               for (pos = 0, node = menu->GetMenuItems().First(); node; node = node->Next(), pos++) 
-                               {
-                                       item = (wxMenuItem *)node->Data();
-                                       subMenu = item->GetSubMenu() ;
-                                       if (subMenu)                    
-                                       {
-                                               UMAInsertMenu( subMenu->GetHMenu() , -1 ) ;
-                                       }
-                               }
-                               UMAInsertMenu(m_menus[i]->GetHMenu(), 0);
-                       }
-               }
-               UMADrawMenuBar() ;
-
-       s_macInstalledMenuBar = this;
+       for (size_t i = 0; i < m_menus.GetCount(); i++)
+      {
+        wxMenuItemList::Node *node;
+        wxMenuItem *item;
+        int pos ;
+        wxMenu* menu = m_menus[i] , *subMenu = NULL ;
+
+        if( m_titles[i] == wxT("?") || m_titles[i] == wxT("&?")  || 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() , wxFont::GetDefaultEncoding() );
+                                UMAEnableMenuItem( GetMenuHandle( kwxMacAppleMenuId ) , 1 , true );
+                                SetMenuItemCommandID( GetMenuHandle( kwxMacAppleMenuId ) , 1 , item->GetId() ) ;
+                                UMASetMenuItemShortcut( GetMenuHandle( kwxMacAppleMenuId ) , 1 , entry ) ;
+                         }
+                        else
+                        {
+                            if ( mh )
+                            {
+                                UMAAppendMenuItem(mh, item->GetText()  , wxFont::GetDefaultEncoding(), entry);
+                                SetMenuItemCommandID( mh , CountMenuItems(mh) , item->GetId() ) ;
+                            }
+                        }
+
+                        delete entry ;
+                    }
+                }
+            }
+        }
+        else
+        {
+            UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , m_titles[i], m_font.GetEncoding()  ) ;
+            m_menus[i]->MacBeforeDisplay(false) ;
+            ::InsertMenu(MAC_WXHMENU(m_menus[i]->GetHMenu()), 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 ) ;
+    m_menus[pos]->MacEnableMenu( enable ) ;
     Refresh();
 }
 
     Refresh();
 }
 
@@ -774,11 +629,11 @@ void wxMenuBar::SetLabelTop(size_t pos, const wxString& label)
     }
 
     m_menus[pos]->SetTitle( label ) ;
     }
 
     m_menus[pos]->SetTitle( label ) ;
-       if (wxMenuBar::s_macInstalledMenuBar == this) // are we currently installed ?
-       {
-               ::SetMenuBar( GetMenuBar() ) ;
-               ::InvalMenuBar() ;
-       }
+    if (wxMenuBar::s_macInstalledMenuBar == this) // are we currently installed ?
+    {
+        ::SetMenuBar( GetMenuBar() ) ;
+        ::InvalMenuBar() ;
+    }
 }
 
 wxString wxMenuBar::GetLabelTop(size_t pos) const
 }
 
 wxString wxMenuBar::GetLabelTop(size_t pos) const
@@ -798,7 +653,7 @@ 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;
@@ -823,32 +678,23 @@ wxMenu *wxMenuBar::Replace(size_t pos, wxMenu *menu, const wxString& title)
 
     if ( IsAttached() )
     {
 
     if ( IsAttached() )
     {
-               if (s_macInstalledMenuBar == this)
-               {
-                       UMADeleteMenu( menuOld->MacGetMenuId() /* m_menus[pos]->MacGetMenuId() */ ) ;
-                       {
-                               Str255  label;
-                               wxMenuItem::MacBuildMenuString( label, NULL , NULL , title , false );
-                               UMASetMenuTitle( menu->GetHMenu() , label ) ;
-                               if ( pos == m_menus.GetCount() - 1)
-                               {
-                                       UMAInsertMenu( menu->GetHMenu() , 0 ) ;
-                               }
-                               else
-                               {
-                                       UMAInsertMenu( menu->GetHMenu() , m_menus[pos+1]->MacGetMenuId() ) ;
-                               }
-                       }
-               }
-
-
-#if wxUSE_ACCEL
-        if ( menuOld->HasAccels() || menu->HasAccels() )
+        if (s_macInstalledMenuBar == this)
         {
         {
-            // need to rebuild accell table
-            RebuildAccelTable();
+            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()) , m_menus[pos+1]->MacGetMenuId() ) ;
+                }
+            }
         }
         }
-#endif // wxUSE_ACCEL
 
         Refresh();
     }
 
         Refresh();
     }
@@ -863,76 +709,28 @@ bool wxMenuBar::Insert(size_t pos, wxMenu *menu, const wxString& title)
 
     m_titles.Insert(title, pos);
 
 
     m_titles.Insert(title, pos);
 
-    menu->Attach(this);
+    UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , title , m_font.GetEncoding() ) ;
 
 
-    if ( IsAttached() )
+    if ( IsAttached() && s_macInstalledMenuBar == this )
     {
     {
-       if ( pos == (size_t) -1 )
-               {
-                       ::InsertMenu( menu->GetHMenu() , 0 ) ;
-               }
-               else
-               {
-                       ::InsertMenu( menu->GetHMenu() , m_menus[pos+1]->MacGetMenuId() ) ;
-               }
-
-#if wxUSE_ACCEL
-        if ( menu->HasAccels() )
+        if (s_macInstalledMenuBar == this)
         {
         {
-            // need to rebuild accell table
-            RebuildAccelTable();
+            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()) , m_menus[pos+1]->MacGetMenuId() ) ;
+            }
         }
         }
-#endif // wxUSE_ACCEL
-
         Refresh();
     }
 
     return TRUE;
 }
 
         Refresh();
     }
 
     return TRUE;
 }
 
-void wxMenuBar::MacMenuSelect(wxEvtHandler* handler, long when , int macMenuId, int macMenuItemNum)
-{
-       // 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_menus.GetCount() ; i++)
-         {
-               if ( m_menus[i]->MacGetMenuId() == macMenuId
-#ifndef __WXMAC_X__
-                    || 
-                       ( macMenuId == kHMHelpMenuID && ( m_titles[i] == "?" || m_titles[i] == "&?"  || m_titles[i] == wxApp::s_macHelpMenuTitleName ) )
-#endif
-                       )
-               {
-                       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_menus.GetCount(); i++)
-         {
-               if ( m_menus[i]->MacMenuSelect( handler , when , macMenuId , macMenuItemNum ) )
-               {
-                       break ;
-               }
-         }
-       }
-}
-
 wxMenu *wxMenuBar::Remove(size_t pos)
 {
     wxMenu *menu = wxMenuBarBase::Remove(pos);
 wxMenu *wxMenuBar::Remove(size_t pos)
 {
     wxMenu *menu = wxMenuBarBase::Remove(pos);
@@ -941,25 +739,15 @@ wxMenu *wxMenuBar::Remove(size_t pos)
 
     if ( IsAttached() )
     {
 
     if ( IsAttached() )
     {
-               if (s_macInstalledMenuBar == this)
-               {
-                       ::DeleteMenu( menu->MacGetMenuId() /* m_menus[pos]->MacGetMenuId() */ ) ;
-               }
-
-        menu->Detach();
-
-#if wxUSE_ACCEL
-        if ( menu->HasAccels() )
+        if (s_macInstalledMenuBar == this)
         {
         {
-            // need to rebuild accell table
-            RebuildAccelTable();
+            ::DeleteMenu( menu->MacGetMenuId() /* m_menus[pos]->MacGetMenuId() */ ) ;
         }
         }
-#endif // wxUSE_ACCEL
 
         Refresh();
     }
 
 
         Refresh();
     }
 
-    m_titles.Remove(pos);
+    m_titles.RemoveAt(pos);
 
     return menu;
 }
 
     return menu;
 }
@@ -972,40 +760,88 @@ bool wxMenuBar::Append(wxMenu *menu, const wxString& title)
     if ( !wxMenuBarBase::Append(menu, title) )
         return FALSE;
 
     if ( !wxMenuBarBase::Append(menu, title) )
         return FALSE;
 
-    menu->Attach(this);
-
     m_titles.Add(title);
 
     m_titles.Add(title);
 
+    UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , title , m_font.GetEncoding() ) ;
+
     if ( IsAttached() )
     {
     if ( IsAttached() )
     {
-               if (s_macInstalledMenuBar == this)
-               {
-                       ::InsertMenu( menu->GetHMenu() , 0 ) ;
-               }
-
-#if wxUSE_ACCEL
-        if ( menu->HasAccels() )
+        if (s_macInstalledMenuBar == this)
         {
         {
-            // need to rebuild accell table
-            RebuildAccelTable();
+            ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , 0 ) ;
         }
         }
-#endif // wxUSE_ACCEL
 
         Refresh();
     }
 
 
         Refresh();
     }
 
+   // m_invokingWindow is set after wxFrame::SetMenuBar(). This call enables
+    // adding menu later on.
+    if (m_invokingWindow)
+        wxMenubarSetInvokingWindow( menu, m_invokingWindow );
+
     return TRUE;
 }
 
     return TRUE;
 }
 
-void wxMenuBar::Attach(wxFrame *frame)
+static void wxMenubarUnsetInvokingWindow( wxMenu *menu )
 {
 {
-//    wxASSERT_MSG( !IsAttached(), wxT("menubar already attached!") );
+    menu->SetInvokingWindow( (wxWindow*) NULL );
 
 
-    m_menuBarFrame = frame;
+    wxMenuItemList::Node *node = menu->GetMenuItems().GetFirst();
+    while (node)
+    {
+        wxMenuItem *menuitem = node->GetData();
+        if (menuitem->IsSubMenu())
+            wxMenubarUnsetInvokingWindow( menuitem->GetSubMenu() );
+        node = node->GetNext();
+    }
+}
+
+static void wxMenubarSetInvokingWindow( wxMenu *menu, wxWindow *win )
+{
+    menu->SetInvokingWindow( win );
 
 
-#if wxUSE_ACCEL
-    RebuildAccelTable();
-#endif // wxUSE_ACCEL
+    wxMenuItemList::Node *node = menu->GetMenuItems().GetFirst();
+    while (node)
+    {
+        wxMenuItem *menuitem = node->GetData();
+        if (menuitem->IsSubMenu())
+            wxMenubarSetInvokingWindow( menuitem->GetSubMenu() , win );
+        node = node->GetNext();
+    }
+}
+
+void wxMenuBar::UnsetInvokingWindow()
+{
+    m_invokingWindow = (wxWindow*) NULL;
+    wxMenuList::Node *node = m_menus.GetFirst();
+    while (node)
+    {
+        wxMenu *menu = node->GetData();
+        wxMenubarUnsetInvokingWindow( menu );
+        node = node->GetNext();
+    }
+}
+
+void wxMenuBar::SetInvokingWindow(wxFrame *frame)
+{
+    m_invokingWindow = frame;
+    wxMenuList::Node *node = m_menus.GetFirst();
+    while (node)
+    {
+        wxMenu *menu = node->GetData();
+        wxMenubarSetInvokingWindow( menu, frame );
+        node = node->GetNext();
+    }
+}
+
+void wxMenuBar::Detach()
+{
+    wxMenuBarBase::Detach() ;
+}
+
+void wxMenuBar::Attach(wxFrame *frame)
+{
+    wxMenuBarBase::Attach( frame ) ;
 }
 // ---------------------------------------------------------------------------
 // wxMenuBar searching for menu items
 }
 // ---------------------------------------------------------------------------
 // wxMenuBar searching for menu items