X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/8208e181cb576ec6cda37624923f95a59af43072..bf31fa26c74df94d13f0b5ffc9842fe9bc3004be:/src/mac/carbon/menu.cpp

diff --git a/src/mac/carbon/menu.cpp b/src/mac/carbon/menu.cpp
index 427db90852..1159391d37 100644
--- a/src/mac/carbon/menu.cpp
+++ b/src/mac/carbon/menu.cpp
@@ -22,8 +22,10 @@
 #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"
 
@@ -33,12 +35,14 @@
 // ----------------------
 #include <string.h>
 
+#if !USE_SHARED_LIBRARY
 IMPLEMENT_DYNAMIC_CLASS(wxMenu, wxEvtHandler)
 IMPLEMENT_DYNAMIC_CLASS(wxMenuBar, wxEvtHandler)
+#endif
 
 // 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 ;
@@ -47,151 +51,16 @@ const short kwxMacAppleMenuId = 1 ;
 // implementation
 // ============================================================================
 
-//
-// Helper Functions to get Mac Menus the way they should be ;-)
-//
-
-void wxMacCtoPString(const char* theCString, Str255 thePString);
-
-// remove inappropriate characters, if useShortcuts is false, the ampersand will not auto-generate a mac menu-shortcut
-
-void wxMacBuildMenuString(StringPtr outMacItemText, char *outMacShortcutChar , short *outMacModifiers , const char *inItemText , bool useShortcuts )
-{
-	char *p = (char *) &outMacItemText[1] ;
-	short macModifiers = 0 ;
-	char macShortCut = 0 ;
-	const char *inItemName ;
-	wxString inItemTextMac ;
-	
-	if (wxApp::s_macDefaultEncodingIsPC)
-	{
-		inItemTextMac =  wxMacMakeMacStringFromPC( inItemText ) ;
-		inItemName = inItemTextMac ;
-	}
-	else
-	{
-		inItemName = inItemText ;
-	}
-	
-	if ( useShortcuts && !wxApp::s_macSupportPCMenuShortcuts )
-		useShortcuts = false ;
-	
-	// we have problems with a leading hypen - it will be taken as a separator
-	
-	while ( *inItemName == '-' )
-		inItemName++ ;
-		
-	while( *inItemName )
-	{
-		switch ( *inItemName )
-		{
-			// special characters for macintosh menus -> use some replacement
-			case ';' :
-				*p++ = ',' ;
-				break ;
-			case '^' :
-				*p++ = ' ' ;
-				break ;
-			case '!' :
-				*p++ = ' ' ;
-				break ;
-			case '<' :
-				*p++ = ' ' ;
-				break ;
-			case '/' :
-				*p++ = '|' ;
-				break ;
-			case '(' :
-				*p++ = '[' ;
-				break ;
-			case ')' :	
-				*p++ = ']' ;
-				break ;
-			// shortcuts
-			case '&' :
-				{
-					++inItemName ;
-					if ( *inItemName )
-					{
-						*p++ = *inItemName ;
-						if ( useShortcuts )
-							macShortCut = *inItemName ;
-					}
-					else
-						--inItemName ;
-				}
-				break ;
-			// win-like accelerators
-			case '\t' :
-				{
-					++inItemName ;
-					while( *inItemName )
-					{
-						if (strncmp("Ctrl", inItemName, 4) == 0) 
-						{
-							inItemName = inItemName + 5;
-							macShortCut = *inItemName;
-						}
-						else if  (strncmp("Cntrl", inItemName, 5) == 0) 
-						{
-							inItemName = inItemName + 6;
-							macShortCut = *inItemName;
-						}
-						else if (strncmp("Alt", inItemName, 3) == 0) 
-						{
-							inItemName = inItemName + 4;
-							macModifiers |= kMenuOptionModifier ;
-							macShortCut = *inItemName ;
-						}
-						else if (strncmp("Shift", inItemName, 5) == 0) 
-						{
-							inItemName = inItemName + 6;
-							macModifiers |= kMenuShiftModifier ;
-							macShortCut = *inItemName ;
-						}
-						else if (strncmp("F", inItemName, 1) == 0) 
-						{
-							inItemName += strlen( inItemName ) ;
-							// no function keys at the moment
-							// macModifiers |= kMenuShiftModifier ;
-							// macShortCut = *inItemName ;
-						}
-						else
-						{
-							break ;
-						}
-					}
-
-					if ( *inItemName == 0 )
-						--inItemName ;
-						
-				}
-				break ;
-			default :
-				*p++ = *inItemName ;
-		}
-		++inItemName ;
-	}
-
-	outMacItemText[0] = (p - (char *)outMacItemText) - 1;
-	if ( outMacShortcutChar )
-		*outMacShortcutChar = macShortCut ;
-	if ( outMacModifiers )
-		*outMacModifiers = macModifiers ;
-	if ( macShortCut )
-	{
-			int pos = outMacItemText[0] ;
-			outMacItemText[++pos] = '/';
-			outMacItemText[++pos] = toupper( macShortCut );
-			outMacItemText[0] = pos ;
-	}
-}
 
 // Menus
 
 // Construct a menu with optional title (then use append)
 
+#ifdef __DARWIN__
+short wxMenu::s_macNextMenuId = 3 ;
+#else
 short wxMenu::s_macNextMenuId = 2 ;
+#endif
 
 void wxMenu::Init()
 {
@@ -199,7 +68,7 @@ void wxMenu::Init()
 
     // create the menu
 	Str255 	label;
-	wxMacBuildMenuString( label, NULL , NULL , m_title , false );
+	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 = ::NewMenu(m_macMenuId, label);
@@ -219,8 +88,8 @@ void wxMenu::Init()
 
 wxMenu::~wxMenu()
 {
-	if (m_hMenu)
-		::DisposeMenu(m_hMenu);
+	if (MAC_WXHMENU(m_hMenu))
+		::DisposeMenu(MAC_WXHMENU(m_hMenu));
 
 #if wxUSE_ACCEL
     // delete accels
@@ -271,7 +140,7 @@ void wxMenu::UpdateAccel(wxMenuItem *item)
         if ( accel )
             m_accels[n] = accel;
         else
-            m_accels.Remove(n);
+            m_accels.RemoveAt(n);
     }
 
     if ( IsAttached() )
@@ -295,11 +164,11 @@ bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos)
 	{
 		if ( pos == (size_t)-1 )
 		{
-			MacAppendMenu(m_hMenu, "\p-");
+			MacAppendMenu(MAC_WXHMENU(m_hMenu), "\p-");
 		}
 		else
 		{
-			MacInsertMenuItem(m_hMenu, "\p-" , pos);
+			MacInsertMenuItem(MAC_WXHMENU(m_hMenu), "\p-" , pos);
 		}
 	}
 	else 
@@ -310,38 +179,28 @@ bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos)
  			Str255 label;
    			wxASSERT_MSG( pSubMenu->m_hMenu != NULL , "invalid submenu added");
 		    pSubMenu->m_menuParent = this ;
-			wxMacBuildMenuString( label , NULL , NULL , pItem->GetText() ,false);
-		
-			// hardcoded adding of the submenu combination for mac
+			wxMenuItem::MacBuildMenuString( label , NULL , NULL , pItem->GetText() ,false);
 		
-			int theEnd = label[0] + 1; 
-			if (theEnd > 251) 
-				theEnd = 251; // mac allows only 255 characters
-			label[theEnd++] = '/';
-			label[theEnd++] = hMenuCmd; 
-			label[theEnd++] = '!';
-			label[theEnd++] = pSubMenu->m_macMenuId; 
-			label[theEnd] = 0x00;
-			label[0] = theEnd;
-
 			if (wxMenuBar::MacGetInstalledMenuBar() == m_menuBar) 
 			{
-				::InsertMenu( pSubMenu->m_hMenu , -1 ) ;
+				::InsertMenu( MAC_WXHMENU( pSubMenu->m_hMenu ) , -1 ) ;
 			}
 			
 			if ( pos == (size_t)-1 )
 			{
-				MacAppendMenu(m_hMenu, label);
+				UMAAppendSubMenuItem(MAC_WXHMENU(m_hMenu), label, pSubMenu->m_macMenuId);
 			}
 			else
 			{
-				MacInsertMenuItem(m_hMenu, label , pos);
+				UMAInsertSubMenuItem(MAC_WXHMENU(m_hMenu), label , pos, pSubMenu->m_macMenuId);
 			}
 		}
 		else
 		{
 			Str255 label ;
-			wxMacBuildMenuString( label , NULL , NULL , pItem->GetText(), pItem->GetId() == wxApp::s_macAboutMenuItemId);
+			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
@@ -350,21 +209,21 @@ bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos)
 			}
 			if ( pos == (size_t)-1 )
 			{
-				MacAppendMenu(m_hMenu, label);
+				UMAAppendMenuItem(MAC_WXHMENU(m_hMenu), label,key,modifiers);
 			}
 			else
 			{
-				MacInsertMenuItem(m_hMenu, label , pos);
+				UMAInsertMenuItem(MAC_WXHMENU(m_hMenu), label , pos,key,modifiers);
 			}
   			if ( pItem->GetId() == idMenuTitle ) 
   			{
   				if ( pos == (size_t)-1 )
 				{
-					UMADisableMenuItem( m_hMenu , CountMItems( m_hMenu ) ) ;
+					UMADisableMenuItem(MAC_WXHMENU(m_hMenu) , CountMenuItems(MAC_WXHMENU(m_hMenu) ) ) ;
 				}
 				else
 				{
-					UMADisableMenuItem( m_hMenu , pos + 1 ) ;
+					UMADisableMenuItem(MAC_WXHMENU(m_hMenu) , pos + 1 ) ;
 				}
   			}
 		}
@@ -410,12 +269,12 @@ wxMenuItem *wxMenu::DoRemove(wxMenuItem *item)
     {
         delete m_accels[n];
 
-        m_accels.Remove(n);
+        m_accels.RemoveAt(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() )
     {
@@ -452,113 +311,9 @@ void wxMenu::SetTitle(const wxString& label)
 {
 	Str255 title ;
     m_title = label ;
-	wxMacBuildMenuString( title, NULL , NULL , label , false );
-	UMASetMenuTitle( m_hMenu , title ) ;
-}
-
-/*
-
-void wxMenu::SetLabel(int id, const wxString& label)
-{
-    Str255 maclabel ;
-   int index ;
-    wxMenuItem *item = FindItemForId(id) ;
-    if (item==NULL)
-        return;
-
-    index = MacGetIndexFromItem( item ) ;
-    if (index < 1)
-		return;
-
-    if (item->GetSubMenu()==NULL)
-    {
-		wxMacBuildMenuString( maclabel , NULL , NULL , label , false );
-		::SetMenuItemText( m_hMenu , index , maclabel ) ;
-    }
-    else
-    {
-		wxMacBuildMenuString( maclabel , NULL , NULL , label , false );
-		::SetMenuItemText( m_hMenu , index , maclabel ) ;
-    }
-    item->SetName(label);
-}
-
-wxString wxMenu::GetLabel(int Id) const
-{
-    wxMenuItem *pItem = FindItemForId(Id) ;
-    return pItem->GetName() ;
-}
-
-// Finds the item id matching the given string, -1 if not found.
-int wxMenu::FindItem (const wxString& itemString) const
-{
-    char buf1[200];
-    char buf2[200];
-    wxStripMenuCodes ((char *)(const char *)itemString, buf1);
-
-    for (wxNode * node = m_menuItems.First (); node; node = node->Next ())
-    {
-      wxMenuItem *item = (wxMenuItem *) node->Data ();
-      if (item->GetSubMenu())
-      {
-        int ans = item->GetSubMenu()->FindItem(itemString);
-        if (ans > -1)
-          return ans;
-      }
-      if ( !item->IsSeparator() )
-      {
-        wxStripMenuCodes((char *)item->GetName().c_str(), buf2);
-        if (strcmp(buf1, buf2) == 0)
-          return item->GetId();
-      }
-    }
-
-    return -1;
-}
-
-wxMenuItem *wxMenu::FindItemForId(int itemId, wxMenu ** itemMenu) const
-{
-    if (itemMenu)
-        *itemMenu = NULL;
-    for (wxNode * node = m_menuItems.First (); node; node = node->Next ())
-    {
-        wxMenuItem *item = (wxMenuItem *) node->Data ();
-
-        if (item->GetId() == itemId)
-        {
-            if (itemMenu)
-                *itemMenu = (wxMenu *) this;
-            return item;
-        }
-
-        if (item->GetSubMenu())
-        {
-            wxMenuItem *ans = item->GetSubMenu()->FindItemForId (itemId, itemMenu);
-            if (ans)
-                return ans;
-        }
-    }
-
-    if (itemMenu)
-        *itemMenu = NULL;
-    return NULL;
-}
-
-void wxMenu::SetHelpString(int itemId, const wxString& helpString)
-{
-    wxMenuItem *item = FindItemForId (itemId);
-    if (item)
-        item->SetHelp(helpString);
-}
-
-wxString wxMenu::GetHelpString (int itemId) const
-{
-    wxMenuItem *item = FindItemForId (itemId);
-    wxString str("");
-    return (item == NULL) ? str : item->GetHelp();
+	wxMenuItem::MacBuildMenuString( title, NULL , NULL , label , false );
+	UMASetMenuTitle(MAC_WXHMENU(m_hMenu) , title ) ;
 }
-*/
-
 bool wxMenu::ProcessCommand(wxCommandEvent & event)
 {
     bool processed = FALSE;
@@ -592,28 +347,12 @@ bool wxMenu::ProcessCommand(wxCommandEvent & event)
 // 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 )
         return m_invokingWindow;
     else if ( m_menuBar != NULL)
-        return m_menuBar->GetFrame();
+        return (wxWindow *) m_menuBar->GetFrame();
 
     return NULL;
 }
@@ -660,116 +399,119 @@ int wxMenu::MacGetIndexFromItem( wxMenuItem *pItem )
 void wxMenu::MacEnableMenu( bool bDoEnable ) 
 {
 	if ( bDoEnable )
-		UMAEnableMenuItem( m_hMenu , 0 ) ;
+		UMAEnableMenuItem(MAC_WXHMENU(m_hMenu) , 0 ) ;
 	else
-		UMADisableMenuItem( m_hMenu , 0 ) ;
+		UMADisableMenuItem(MAC_WXHMENU(m_hMenu) , 0 ) ;
 		
 	::DrawMenuBar() ;
 }
 
 bool wxMenu::MacMenuSelect( wxEvtHandler* handler, long when , int macMenuId, int macMenuItemNum )
 {
-  int pos;
-  wxNode *node;
-
-	if ( m_macMenuId == macMenuId )
-	{
-		node = GetMenuItems().Nth(macMenuItemNum-1);
-		if (node) 
-		{
-			wxMenuItem *pItem = (wxMenuItem*)node->Data();
-	
-			wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, pItem->GetId());
-			event.m_timeStamp = when;
-			event.SetEventObject(handler);
-     		event.SetInt( pItem->GetId() );
-			{
-				bool processed = false ;
+    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;
-			    }
+                // 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 ;
-		}
-	}
-	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 ;
+                // Try the menu's event handler
+                if ( !processed && handler)
+                {
+                    processed = handler->ProcessEvent(event);
+                }
+                
+                // Try the window the menu was popped up from (and up
+                // through the hierarchy)
+                if ( !processed && GetInvokingWindow())
+                    processed = GetInvokingWindow()->GetEventHandler()->ProcessEvent(event);
+            }
+            return true ;
+        }
+    }
+    else if ( macMenuId == kHMHelpMenuID )
+    {
+        int menuItem = firstUserHelpMenuItem-1 ;
+        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;
-					    }
+                        // 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 ;
-				}
-			}
-	  }
-	}
-
-  for (pos = 0, node = GetMenuItems().First(); node; node = node->Next(), pos++) 
-  {	
-  		wxMenuItem * pItem = (wxMenuItem *)  node->Data() ;
+                        // Try the menu's event handler
+                        if ( !processed && handler)
+                        {
+                            processed = handler->ProcessEvent(event);
+                        }
+                        
+                        // Try the window the menu was popped up from (and up
+                        // through the hierarchy)
+                        if ( !processed && GetInvokingWindow())
+                            processed = GetInvokingWindow()->GetEventHandler()->ProcessEvent(event);
+                    }
+                    return true ;
+                }
+            }
+        }
+    }
+    
+    for (pos = 0, node = 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 ;
+        wxMenu *pSubMenu = pItem->GetSubMenu() ;
+        if ( pSubMenu != NULL )
+        {
+            if ( pSubMenu->MacMenuSelect( handler , when , macMenuId , macMenuItemNum ) )
+                return true ;
+        }
+    }
+    
+    return false ;
 }
 
 // Menu Bar
@@ -871,18 +613,33 @@ void wxMenuBar::RebuildAccelTable()
 }
 
 #endif // wxUSE_ACCEL
-
-
+#ifdef WXMAKINGDLL
+extern short gCurrentResource ;
+#endif
 void wxMenuBar::MacInstallMenuBar() 
 {
+	if ( s_macInstalledMenuBar == this )
+		return ;
+		
+    wxStAppResource resload ;
+		
   	Handle menubar = ::GetNewMBar( kwxMacMenuBarResource ) ;
   	wxString message ;
   	wxCHECK_RET( menubar != NULL, "can't read MBAR resource" );
   	::SetMenuBar( menubar ) ;
+#if TARGET_API_MAC_CARBON
+    ::DisposeMenuBar( menubar ) ;
+#else
   	::DisposeHandle( menubar ) ;
+#endif
 
 		MenuHandle menu = ::GetMenuHandle( kwxMacAppleMenuId ) ;
-		::AppendResMenu(menu, 'DRVR');
+#if TARGET_API_MAC_OS8
+    if ( CountMenuItems( menu ) == 2 )
+    {
+		  ::AppendResMenu(menu, 'DRVR');
+		}
+#endif
  
    	for (int i = 0; i < m_menus.GetCount(); i++)
   	{
@@ -892,22 +649,21 @@ void wxMenuBar::MacInstallMenuBar()
     	int pos ;
 			wxMenu* menu = m_menus[i] , *subMenu = NULL ;
 		
-			
 			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 ) ;
-				}
+			  if ( UMAGetHelpMenu( &mh , &firstUserHelpMenuItem) != noErr )
+			  {
+			    continue ;
+			  }
+
+		    for ( int i = CountMenuItems( mh ) ; i >= firstUserHelpMenuItem ; --i )
+		    {
+		      DeleteMenuItem( mh , i ) ;
+		    }
 					
-		  	for (pos = 0 , node = menu->GetMenuItems().First(); node; node = node->Next(), pos++) 
-	  		{
+			  	for (pos = 0 , node = menu->GetMenuItems().First(); node; node = node->Next(), pos++) 
+		  		{
 		 			item = (wxMenuItem *)node->Data();
 		 			subMenu = item->GetSubMenu() ;
 					if (subMenu)	 		
@@ -919,12 +675,14 @@ void wxMenuBar::MacInstallMenuBar()
 						if ( item->IsSeparator() )
 						{
 							if ( mh )
-								::AppendMenu(mh, "\p-" );
+								MacAppendMenu(mh, "\p-" );
 						}
 						else
 						{
 							Str255 label ;
-							wxMacBuildMenuString( label , NULL , NULL , item->GetText(), item->GetId() != wxApp::s_macAboutMenuItemId); // no shortcut in about menu
+							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
@@ -934,13 +692,12 @@ void wxMenuBar::MacInstallMenuBar()
 							if ( item->GetId() == wxApp::s_macAboutMenuItemId )
 							{ 
 									::SetMenuItemText( GetMenuHandle( kwxMacAppleMenuId ) , 1 , label );
-			//					::EnableMenuItem( GetMenuHandle( kwxMacAppleMenuId ) , 1 );
-									::EnableItem( GetMenuHandle( kwxMacAppleMenuId ) , 1 );
+									UMAEnableMenuItem( GetMenuHandle( kwxMacAppleMenuId ) , 1 );
 	 						}
 							else
 							{
 								if ( mh )
-									::AppendMenu(mh, label );
+									UMAAppendMenuItem(mh, label , key , modifiers );
 							}
 						}
 					}
@@ -948,22 +705,40 @@ void wxMenuBar::MacInstallMenuBar()
 			}
 			else
 			{
-				wxMacBuildMenuString( label, NULL , NULL , m_titles[i] , false );
-				UMASetMenuTitle( menu->GetHMenu() , label ) ;
-		  	for (pos = 0, node = menu->GetMenuItems().First(); node; node = node->Next(), pos++) 
-	  		{
+				wxMenuItem::MacBuildMenuString( label, NULL , NULL , m_titles[i] , false );
+				UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , label ) ;
+					wxArrayPtrVoid submenus ;
+					
+		  		for (pos = 0, node = menu->GetMenuItems().First(); node; node = node->Next(), pos++) 
+	  			{
 		 			item = (wxMenuItem *)node->Data();
 		 			subMenu = item->GetSubMenu() ;
 					if (subMenu)	 		
 					{
-						::InsertMenu( subMenu->GetHMenu() , -1 ) ;
+  					  submenus.Add(subMenu) ;
 					}
 				}
-				::InsertMenu(m_menus[i]->GetHMenu(), 0);
+				::InsertMenu(MAC_WXHMENU(m_menus[i]->GetHMenu()), 0);
+				for ( int i = 0 ; i < submenus.GetCount() ; ++i )
+				{
+				  wxMenu* submenu = (wxMenu*) submenus[i] ;
+        	wxNode *subnode;
+        	wxMenuItem *subitem;
+        	int subpos ;
+          for ( subpos = 0 , subnode = submenu->GetMenuItems().First(); subnode; subnode = subnode->Next(), subpos++) 
+		  		{
+  		 			subitem = (wxMenuItem *)subnode->Data();
+  		 			wxMenu* itsSubMenu = subitem->GetSubMenu() ;
+  					if (itsSubMenu)	 		
+  					{
+  						submenus.Add(itsSubMenu) ;
+  					}  				
+  				}
+					::InsertMenu( MAC_WXHMENU(submenu->GetHMenu()) , -1 ) ;
+  			}
 			}
 		}
 		::DrawMenuBar() ;
-
 	s_macInstalledMenuBar = this;
 }
 
@@ -1040,15 +815,15 @@ wxMenu *wxMenuBar::Replace(size_t pos, wxMenu *menu, const wxString& title)
 			::DeleteMenu( menuOld->MacGetMenuId() /* m_menus[pos]->MacGetMenuId() */ ) ;
 			{
 				Str255 	label;
-				wxMacBuildMenuString( label, NULL , NULL , title , false );
-				UMASetMenuTitle( menu->GetHMenu() , label ) ;
+				wxMenuItem::MacBuildMenuString( label, NULL , NULL , title , false );
+				UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , label ) ;
 				if ( pos == m_menus.GetCount() - 1)
 				{
-					::InsertMenu( menu->GetHMenu() , 0 ) ;
+					::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , 0 ) ;
 				}
 				else
 				{
-					::InsertMenu( menu->GetHMenu() , m_menus[pos+1]->MacGetMenuId() ) ;
+					::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , m_menus[pos+1]->MacGetMenuId() ) ;
 				}
 			}
 		}
@@ -1075,17 +850,19 @@ bool wxMenuBar::Insert(size_t pos, wxMenu *menu, const wxString& title)
 
     m_titles.Insert(title, pos);
 
-    menu->Attach(this);
+    Str255 label ;
+		wxMenuItem::MacBuildMenuString( label, NULL , NULL , title , false );
+		UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , label ) ;
 
     if ( IsAttached() )
     {
-    	if ( pos == (size_t) -1 )
+    	if ( pos == (size_t) -1  || pos + 1 == m_menus.GetCount() )
 		{
-			::InsertMenu( menu->GetHMenu() , 0 ) ;
+			::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , 0 ) ;
 		}
 		else
 		{
-			::InsertMenu( menu->GetHMenu() , m_menus[pos+1]->MacGetMenuId() ) ;
+			::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , m_menus[pos+1]->MacGetMenuId() ) ;
 		}
 
 #if wxUSE_ACCEL
@@ -1104,33 +881,31 @@ bool wxMenuBar::Insert(size_t pos, wxMenu *menu, const wxString& title)
 
 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 || 
-	  		( macMenuId == kHMHelpMenuID && ( m_titles[i] == "?" || m_titles[i] == "&?"  || m_titles[i] == wxApp::s_macHelpMenuTitleName ) )
-	  		)
-	  	{
-	  		if ( m_menus[i]->MacMenuSelect( handler , when , macMenuId , macMenuItemNum ) )
-	  			return ;
-	  		else
-	  		{
-	  			//TODO flag this as an error since it must contain the item
-	  			return ;
-	  		}
-	  	}
-		}
+    // 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 || ( macMenuId == kHMHelpMenuID && ( m_titles[i] == "?" || m_titles[i] == "&?"  || m_titles[i] == wxApp::s_macHelpMenuTitleName ) ) )
+            {
+                if ( m_menus[i]->MacMenuSelect( handler , when , macMenuId , macMenuItemNum ) )
+                    return ;
+                else
+                {
+                    //TODO flag this as an error since it must contain the item
+                    return ;
+                }
+            }
+        }
 	
 	  for (int i = 0; i < m_menus.GetCount(); i++)
 	  {
@@ -1181,16 +956,18 @@ bool wxMenuBar::Append(wxMenu *menu, const wxString& title)
     if ( !wxMenuBarBase::Append(menu, title) )
         return FALSE;
 
-    menu->Attach(this);
-
     m_titles.Add(title);
+    
+    Str255 label ;
+		wxMenuItem::MacBuildMenuString( label, NULL , NULL , title , false );
+		UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , label ) ;
 
     if ( IsAttached() )
     {
-		if (s_macInstalledMenuBar == this)
-		{
-			::InsertMenu( menu->GetHMenu() , 0 ) ;
-		}
+    		if (s_macInstalledMenuBar == this)
+    		{
+    			::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , 0 ) ;
+    		}
 
 #if wxUSE_ACCEL
         if ( menu->HasAccels() )
@@ -1206,6 +983,19 @@ bool wxMenuBar::Append(wxMenu *menu, const wxString& title)
     return TRUE;
 }
 
+void wxMenuBar::Detach()
+{
+    wxMenuBarBase::Detach() ;
+}
+
+void wxMenuBar::Attach(wxFrame *frame)
+{
+    wxMenuBarBase::Attach( frame ) ;
+
+#if wxUSE_ACCEL
+    RebuildAccelTable();
+#endif // wxUSE_ACCEL
+}
 // ---------------------------------------------------------------------------
 // wxMenuBar searching for menu items
 // ---------------------------------------------------------------------------