avoid setting initial position if it was not specified, broken in r70734
[wxWidgets.git] / src / osx / carbon / menu.cpp
index 5db7b7bc502731ec93f21999be7ef7faa477c14b..06a703dfd4c86a64042cb385f4be0ccd9ed82050 100644 (file)
@@ -4,7 +4,6 @@
 // Author:      Stefan Csomor
 // Modified by:
 // Created:     1998-01-01
 // Author:      Stefan Csomor
 // Modified by:
 // Created:     1998-01-01
-// RCS-ID:      $Id$
 // Copyright:   (c) Stefan Csomor
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 // Copyright:   (c) Stefan Csomor
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 // under carbon there's no such thing as a MenuItemRef, everything is done
 // on the 'parent' menu via index APIs (first line having index 1 !)
 
 // under carbon there's no such thing as a MenuItemRef, everything is done
 // on the 'parent' menu via index APIs (first line having index 1 !)
-// so to make things still work, we store the wxMenuItemImpl instance as a 
+// so to make things still work, we store the wxMenuItemImpl instance as a
 // RefCon at the respective menu line
 
 // RefCon at the respective menu line
 
-class wxMenuItemCarbonImpl : public wxMenuItemImpl 
+class wxMenuItemCarbonImpl : public wxMenuItemImpl
 {
 public :
     wxMenuItemCarbonImpl( wxMenuItem* peer ) : wxMenuItemImpl(peer)
 {
 public :
     wxMenuItemCarbonImpl( wxMenuItem* peer ) : wxMenuItemImpl(peer)
@@ -48,15 +47,15 @@ public :
         // the parent menu ref is only set, once the item has been attached
         m_parentMenuRef = NULL;
     }
         // the parent menu ref is only set, once the item has been attached
         m_parentMenuRef = NULL;
     }
-    
+
     ~wxMenuItemCarbonImpl();
     ~wxMenuItemCarbonImpl();
-        
+
     void SetBitmap( const wxBitmap& bitmap )
     {
         MenuItemIndex i = FindMenuItemIndex() ;
         if ( i > 0 )
         {
     void SetBitmap( const wxBitmap& bitmap )
     {
         MenuItemIndex i = FindMenuItemIndex() ;
         if ( i > 0 )
         {
-            if ( bitmap.Ok() )
+            if ( bitmap.IsOk() )
             {
 #if wxUSE_BMPBUTTON
                 ControlButtonContentInfo info ;
             {
 #if wxUSE_BMPBUTTON
                 ControlButtonContentInfo info ;
@@ -74,21 +73,21 @@ public :
 #endif
             }
         }
 #endif
             }
         }
-    }   
-    
-    void Enable( bool enable ) 
+    }
+
+    void Enable( bool enable )
     {
         MenuItemIndex i = FindMenuItemIndex() ;
         if ( i > 0 )
         {
     {
         MenuItemIndex i = FindMenuItemIndex() ;
         if ( i > 0 )
         {
-        
+
             if ( GetWXPeer()->GetId() == wxApp::s_macPreferencesMenuItemId)
             {
                 if ( enable )
                     EnableMenuCommand( NULL , kHICommandPreferences ) ;
                 else
                     DisableMenuCommand( NULL , kHICommandPreferences ) ;
             if ( GetWXPeer()->GetId() == wxApp::s_macPreferencesMenuItemId)
             {
                 if ( enable )
                     EnableMenuCommand( NULL , kHICommandPreferences ) ;
                 else
                     DisableMenuCommand( NULL , kHICommandPreferences ) ;
-            } 
+            }
             else if ( GetWXPeer()->GetId() == wxApp::s_macExitMenuItemId)
             {
                 if ( enable )
             else if ( GetWXPeer()->GetId() == wxApp::s_macExitMenuItemId)
             {
                 if ( enable )
@@ -96,20 +95,20 @@ public :
                 else
                     DisableMenuCommand( NULL , kHICommandQuit ) ;
             }
                 else
                     DisableMenuCommand( NULL , kHICommandQuit ) ;
             }
-        
+
             if ( enable )
                 EnableMenuItem(m_parentMenuRef , i);
             else
                 DisableMenuItem(m_parentMenuRef , i);
             if ( enable )
                 EnableMenuItem(m_parentMenuRef , i);
             else
                 DisableMenuItem(m_parentMenuRef , i);
-                
+
             if ( GetWXPeer()->IsSubMenu() )
             {
                 UMAEnableMenuItem( GetWXPeer()->GetSubMenu()->GetHMenu() , 0 , enable ) ;
             }
         }
             if ( GetWXPeer()->IsSubMenu() )
             {
                 UMAEnableMenuItem( GetWXPeer()->GetSubMenu()->GetHMenu() , 0 , enable ) ;
             }
         }
-    }   
-    
-    void Check( bool check ) 
+    }
+
+    void Check( bool check )
     {
         MenuItemIndex i = FindMenuItemIndex() ;
         if ( i > 0 )
     {
         MenuItemIndex i = FindMenuItemIndex() ;
         if ( i > 0 )
@@ -119,9 +118,9 @@ public :
             else
                 ::SetItemMark( m_parentMenuRef, i, 0 ) ; // no mark
         }
             else
                 ::SetItemMark( m_parentMenuRef, i, 0 ) ; // no mark
         }
-    }   
+    }
 
 
-    void Hide( bool hide ) 
+    void Hide( bool hide )
     {
         MenuItemIndex i = FindMenuItemIndex() ;
         if ( i > 0 )
     {
         MenuItemIndex i = FindMenuItemIndex() ;
         if ( i > 0 )
@@ -131,9 +130,9 @@ public :
             else
                 ChangeMenuItemAttributes( m_parentMenuRef, i, 0 , kMenuItemAttrHidden );
         }
             else
                 ChangeMenuItemAttributes( m_parentMenuRef, i, 0 , kMenuItemAttrHidden );
         }
-    }   
-    
-    void SetLabel( const wxString& text, wxAcceleratorEntry *entry ) 
+    }
+
+    void SetLabel( const wxString& text, wxAcceleratorEntry *entry )
     {
         MenuItemIndex i = FindMenuItemIndex() ;
         if ( i > 0 )
     {
         MenuItemIndex i = FindMenuItemIndex() ;
         if ( i > 0 )
@@ -142,16 +141,16 @@ public :
             UMASetMenuItemShortcut( m_parentMenuRef, i , entry ) ;
          }
     }
             UMASetMenuItemShortcut( m_parentMenuRef, i , entry ) ;
          }
     }
-        
+
     void * GetHMenuItem() { return NULL; }
     void * GetHMenuItem() { return NULL; }
-    
+
     // Carbon Only
     // Carbon Only
-    
-    void AttachToParent( MenuRef parentMenuRef, MenuItemIndex index ) 
+
+    void AttachToParent( MenuRef parentMenuRef, MenuItemIndex index )
     {
         m_parentMenuRef = parentMenuRef;
         if ( m_parentMenuRef && index > 0 )
     {
         m_parentMenuRef = parentMenuRef;
         if ( m_parentMenuRef && index > 0 )
-            SetMenuItemRefCon( m_parentMenuRef, index, (URefCon) this );
+            SetMenuItemRefCon( m_parentMenuRef, index, (URefCon) m_peer );
     }
 
     MenuItemIndex FindMenuItemIndex()
     }
 
     MenuItemIndex FindMenuItemIndex()
@@ -163,7 +162,7 @@ public :
             {
                 URefCon storedRef = 0;
                 GetMenuItemRefCon(m_parentMenuRef, i, &storedRef );
             {
                 URefCon storedRef = 0;
                 GetMenuItemRefCon(m_parentMenuRef, i, &storedRef );
-                if ( storedRef == (URefCon) this )
+                if ( storedRef == (URefCon) m_peer )
                 {
                     hit = i;
                     break;
                 {
                     hit = i;
                     break;
@@ -180,16 +179,17 @@ protected :
 // wxMenuImpl
 //
 
 // wxMenuImpl
 //
 
-class wxMenuCarbonImpl : public wxMenuImpl 
+class wxMenuCarbonImpl : public wxMenuImpl
 {
 public :
 {
 public :
-    wxMenuCarbonImpl( wxMenu* peer , MenuRef menu) : wxMenuImpl(peer), m_osxMenu(menu)
+    wxMenuCarbonImpl( wxMenu* peer , MenuRef menu , MenuRef oldMenu , SInt16 menuId)
+        : wxMenuImpl(peer), m_osxMenu(menu), m_oldMenuRef(oldMenu), m_menuId(menuId)
     {
     }
 
     virtual ~wxMenuCarbonImpl();
     {
     }
 
     virtual ~wxMenuCarbonImpl();
-        
-    virtual void InsertOrAppend(wxMenuItem *pItem, size_t pos) 
+
+    virtual void InsertOrAppend(wxMenuItem *pItem, size_t pos)
     {
         // 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
     {
         // 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
@@ -198,14 +198,14 @@ public :
         MenuItemIndex index = pos;
         if ( pos == (size_t) -1 )
             index = CountMenuItems(m_osxMenu);
         MenuItemIndex index = pos;
         if ( pos == (size_t) -1 )
             index = CountMenuItems(m_osxMenu);
-            
+
         if ( pItem->IsSeparator() )
         {
             InsertMenuItemTextWithCFString( m_osxMenu, CFSTR(""), index, kMenuItemAttrSeparator, 0);
             // now switch to the Carbon 1 based counting
             index += 1 ;
         }
         if ( pItem->IsSeparator() )
         {
             InsertMenuItemTextWithCFString( m_osxMenu, CFSTR(""), index, kMenuItemAttrSeparator, 0);
             // now switch to the Carbon 1 based counting
             index += 1 ;
         }
-        else 
+        else
         {
             InsertMenuItemTextWithCFString( m_osxMenu, CFSTR("placeholder"), index, 0, 0 );
 
         {
             InsertMenuItemTextWithCFString( m_osxMenu, CFSTR("placeholder"), index, 0, 0 );
 
@@ -223,7 +223,7 @@ public :
                 SetMenuItemCommandID( m_osxMenu, index , wxIdToMacCommand(pItem->GetId()) ) ;
             }
         }
                 SetMenuItemCommandID( m_osxMenu, index , wxIdToMacCommand(pItem->GetId()) ) ;
             }
         }
-        
+
         wxMenuItemCarbonImpl* impl = (wxMenuItemCarbonImpl*) pItem->GetPeer();
         impl->AttachToParent( m_osxMenu, index );
         // only now can all settings be updated correctly
         wxMenuItemCarbonImpl* impl = (wxMenuItemCarbonImpl*) pItem->GetPeer();
         impl->AttachToParent( m_osxMenu, index );
         // only now can all settings be updated correctly
@@ -231,8 +231,8 @@ public :
         pItem->UpdateItemStatus();
         pItem->UpdateItemBitmap();
     }
         pItem->UpdateItemStatus();
         pItem->UpdateItemBitmap();
     }
-        
-    virtual void Remove( wxMenuItem *pItem ) 
+
+    virtual void Remove( wxMenuItem *pItem )
     {
         wxMenuItemCarbonImpl* impl = (wxMenuItemCarbonImpl*) pItem->GetPeer();
         if ( impl )
     {
         wxMenuItemCarbonImpl* impl = (wxMenuItemCarbonImpl*) pItem->GetPeer();
         if ( impl )
@@ -245,7 +245,7 @@ public :
             }
         }
     }
             }
         }
     }
-    
+
     virtual void MakeRoot()
     {
         SetRootMenu( m_osxMenu );
     virtual void MakeRoot()
     {
         SetRootMenu( m_osxMenu );
@@ -280,6 +280,8 @@ public :
     static wxMenuImpl* CreateRootMenu( wxMenu* peer );
 protected :
     wxCFRef<MenuRef> m_osxMenu;
     static wxMenuImpl* CreateRootMenu( wxMenu* peer );
 protected :
     wxCFRef<MenuRef> m_osxMenu;
+    MenuRef m_oldMenuRef;
+    SInt16 m_menuId;
 } ;
 
 // static const short kwxMacAppleMenuId = 1 ;
 } ;
 
 // static const short kwxMacAppleMenuId = 1 ;
@@ -325,21 +327,35 @@ void wxRemoveMacMenuAssociation(wxMenu *menu)
 wxMenuCarbonImpl::~wxMenuCarbonImpl()
 {
     wxRemoveMacMenuAssociation( GetWXPeer() );
 wxMenuCarbonImpl::~wxMenuCarbonImpl()
 {
     wxRemoveMacMenuAssociation( GetWXPeer() );
+    // restore previous menu
+    m_osxMenu.reset();
+    if ( m_menuId > 0 )
+        MacDeleteMenu(m_menuId);
+    if ( m_oldMenuRef )
+        MacInsertMenu(m_oldMenuRef, -1);
 }
 
 wxMenuImpl* wxMenuImpl::Create( wxMenu* peer, const wxString& title )
 {
     // create the menu
     static SInt16 s_macNextMenuId = 3;
 }
 
 wxMenuImpl* wxMenuImpl::Create( wxMenu* peer, const wxString& title )
 {
     // create the menu
     static SInt16 s_macNextMenuId = 3;
+    SInt16 menuId = s_macNextMenuId++;
+    // save existing menu in case we're embedding into an application
+    // or sharing outside UI elements.
+    WXHMENU oldMenu = GetMenuHandle(menuId);
+    if ( oldMenu )
+        MacDeleteMenu(menuId);
     WXHMENU menu = NULL;
     WXHMENU menu = NULL;
-    CreateNewMenu( s_macNextMenuId++ , 0 , &menu ) ;
+    CreateNewMenu( menuId , 0 , &menu ) ;
     if ( !menu )
     {
         wxLogLastError(wxT("CreateNewMenu failed"));
     if ( !menu )
     {
         wxLogLastError(wxT("CreateNewMenu failed"));
+        if ( oldMenu )
+            MacInsertMenu(oldMenu, -1);
         return NULL;
     }
 
         return NULL;
     }
 
-    wxMenuImpl* c = new wxMenuCarbonImpl( peer, menu );
+    wxMenuImpl* c = new wxMenuCarbonImpl( peer, menu, oldMenu, menuId );
     c->SetTitle(title);
     wxAssociateMenuWithMacMenu( menu , peer ) ;
     return c;
     c->SetTitle(title);
     wxAssociateMenuWithMacMenu( menu , peer ) ;
     return c;
@@ -354,7 +370,7 @@ wxMenuItemCarbonImpl::~wxMenuItemCarbonImpl()
 }
 
 
 }
 
 
-wxMenuItemImpl* wxMenuItemImpl::Create( wxMenuItem* peer, 
+wxMenuItemImpl* wxMenuItemImpl::Create( wxMenuItem* peer,
                         wxMenu * WXUNUSED(pParentMenu),
                        int WXUNUSED(id),
                        const wxString& WXUNUSED(text),
                         wxMenu * WXUNUSED(pParentMenu),
                        int WXUNUSED(id),
                        const wxString& WXUNUSED(text),