]> git.saurik.com Git - wxWidgets.git/blobdiff - src/osx/cocoa/menuitem.mm
updated setup.h for OpenVMS
[wxWidgets.git] / src / osx / cocoa / menuitem.mm
index 8a81661f541f7a09c3b6059c10b9773ed6a617f6..0c6c930e32d91c516851e6c8ad00452e127c3b3d 100644 (file)
@@ -4,7 +4,7 @@
 // Author:      Stefan Csomor
 // Modified by:
 // Created:     1998-01-01
-// RCS-ID:      $Id: menuitem.cpp 54129 2008-06-11 19:30:52Z SC $
+// RCS-ID:      $Id$
 // Copyright:   (c) Stefan Csomor
 // Licence:     wxWindows licence
 ///////////////////////////////////////////////////////////////////////////////
 
 #ifndef WX_PRECOMP
     #include "wx/app.h"
+    #include "wx/log.h"
     #include "wx/menu.h"
 #endif // WX_PRECOMP
 
 #include "wx/osx/private.h"
 
+// a mapping from wx ids to standard osx actions in order to support the native menu item handling
+// if a new mapping is added, make sure the wxNonOwnedWindowController has a handler for this action as well
+
+struct Mapping
+{
+    int menuid;
+    SEL action;
+};
+
+Mapping sActionToWXMapping[] =
+{
+// as we don't have NSUndoManager support we must not use the native actions
+#if 0
+    { wxID_UNDO, @selector(undo:) },
+    { wxID_REDO, @selector(redo:) },
+#endif
+    { wxID_CUT, @selector(cut:) },
+    { wxID_COPY, @selector(copy:) },
+    { wxID_PASTE, @selector(paste:) },
+    { wxID_CLEAR, @selector(delete:) },
+    { wxID_SELECTALL, @selector(selectAll:) },
+    { 0, NULL }
+};
+
+int wxOSXGetIdFromSelector(SEL action )
+{
+    int i = 0 ;
+    while ( sActionToWXMapping[i].action != nil )
+    {
+        if ( sActionToWXMapping[i].action == action )
+            return sActionToWXMapping[i].menuid;
+        ++i;
+    }
+    
+    return 0;
+}
+
+SEL wxOSXGetSelectorFromID(int menuId )
+{
+    int i = 0 ;
+    while ( sActionToWXMapping[i].action != nil )
+    {
+        if ( sActionToWXMapping[i].menuid == menuId )
+            return sActionToWXMapping[i].action;
+        ++i;
+    }
+    
+    return nil;
+}
+
+
 @implementation wxNSMenuItem
 
-- (id) init
+- (id) initWithTitle:(NSString *)aString action:(SEL)aSelector keyEquivalent:(NSString *)charCode
 {
-    [super init];
-     return self;
+    self = [super initWithTitle:aString action:aSelector keyEquivalent:charCode];
+    return self;
 }
 
 - (void) clickedAction: (id) sender
 {
+    wxUnusedVar(sender);
     if ( impl )
     {
-        impl->GetWXPeer()->GetMenu()->HandleCommandProcess(impl->GetWXPeer());
+        wxMenuItem* menuitem = impl->GetWXPeer();
+        if ( menuitem->GetMenu()->HandleCommandProcess(menuitem) == false )
+        {
+        }
      }
 }
 
+- (void) setEnabled:(BOOL) flag
+{
+    [super setEnabled:flag];
+}
+
 - (BOOL)validateMenuItem:(NSMenuItem *) menuItem
 {
+    wxUnusedVar(menuItem);
     if( impl )
     {
-        impl->GetWXPeer()->GetMenu()->HandleCommandUpdateStatus(impl->GetWXPeer());
-        return impl->GetWXPeer()->IsEnabled();
+        wxMenuItem* wxmenuitem = impl->GetWXPeer();
+        if ( wxmenuitem )
+        {
+            wxmenuitem->GetMenu()->HandleCommandUpdateStatus(wxmenuitem);
+            return wxmenuitem->IsEnabled();
+        }
     }
     return YES ;
 }
 
 void wxMacCocoaMenuItemSetAccelerator( NSMenuItem* menuItem, wxAcceleratorEntry* entry )
 {
+    if ( entry == NULL )
+    {
+        [menuItem setKeyEquivalent:@""];
+        return;
+    }
+         
     unsigned int modifiers = 0 ;
     int key = entry->GetKeyCode() ;
     if ( key )
     {
-        if (entry->GetFlags() & wxACCEL_CTRL);
+        if (entry->GetFlags() & wxACCEL_CTRL)
             modifiers |= NSCommandKeyMask;
 
+        if (entry->GetFlags() & wxACCEL_RAW_CTRL)
+            modifiers |= NSControlKeyMask;
+        
         if (entry->GetFlags() & wxACCEL_ALT)
             modifiers |= NSAlternateKeyMask ;
 
@@ -86,71 +161,59 @@ void wxMacCocoaMenuItemSetAccelerator( NSMenuItem* menuItem, wxAcceleratorEntry*
         {
             switch ( key )
             {
-/*
-                // standard function keys from here
-                case WXK_TAB :
-                    modifiers |= NSFunctionKeyMask ;
-                    shortcut = NSTabCharacter ;
-                    break ;
-
-                case kEnterCharCode :
-                    modifiers |= NSFunctionKeyMask ;
-                    cocoaKey = NSTabCharacter ;
-                    break ;
-
-                case WXK_RETURN :
-                    modifiers |= NSFunctionKeyMask ;
-                    cocoaKey = NSTabCharacter ;
-                    break ;
-
-                case WXK_ESCAPE :
-                    modifiers |= NSFunctionKeyMask ;
-                    cocoaKey = kEscapeCharCode ;
-                    break ;
-
-                case WXK_SPACE :
-                    shortcut = ' ' ;
-                    break ;
-
-
                 case WXK_CLEAR :
-                    cocoaKey = kClearCharCode ;
+                    modifiers |= NSFunctionKeyMask;
+                    shortcut = NSDeleteCharacter ;
                     break ;
 
                 case WXK_PAGEUP :
-                    cocoaKey = kPageUpCharCode ;
+                    modifiers |= NSFunctionKeyMask;
+                    shortcut = NSPageUpFunctionKey ;
                     break ;
 
                 case WXK_PAGEDOWN :
-                    cocoaKey = kPageDownCharCode ;
+                    modifiers |= NSFunctionKeyMask;
+                    shortcut = NSPageDownFunctionKey ;
                     break ;
 
                 case WXK_LEFT :
-                    cocoaKey = kLeftArrowCharCode ;
+                    modifiers |= NSNumericPadKeyMask | NSFunctionKeyMask;
+                    shortcut = NSLeftArrowFunctionKey ;
                     break ;
 
                 case WXK_UP :
-                    cocoaKey = kUpArrowCharCode ;
+                    modifiers |= NSNumericPadKeyMask | NSFunctionKeyMask;
+                    shortcut = NSUpArrowFunctionKey ;
                     break ;
 
                 case WXK_RIGHT :
-                    cocoaKey = kRightArrowCharCode ;
+                    modifiers |= NSNumericPadKeyMask | NSFunctionKeyMask;
+                    shortcut = NSRightArrowFunctionKey ;
                     break ;
 
                 case WXK_DOWN :
-                    cocoaKey = kDownArrowCharCode ;
+                    modifiers |= NSNumericPadKeyMask | NSFunctionKeyMask;
+                    shortcut = NSDownArrowFunctionKey ;
                     break ;
 
                 case WXK_HOME :
-                    cocoaKey = kHomeCharCode ;
+                    modifiers |= NSFunctionKeyMask;
+                    shortcut = NSHomeFunctionKey ;
                     break ;
 
                 case WXK_END :
-                    cocoaKey = kEndCharCode ;
+                    modifiers |= NSFunctionKeyMask;
+                    shortcut = NSEndFunctionKey ;
                     break ;
-*/
-                // TODO Test all above with their function key equiv.
-                // from NSEvent.h
+
+                case WXK_NUMPAD_ENTER :
+                    shortcut = NSEnterCharacter;
+                    break;
+                    
+                case WXK_BACK :
+                case WXK_RETURN :
+                case WXK_TAB :
+                case WXK_ESCAPE :
                 default :
                     if(entry->GetFlags() & wxACCEL_SHIFT)
                         shortcut = toupper(key);
@@ -165,7 +228,11 @@ void wxMacCocoaMenuItemSetAccelerator( NSMenuItem* menuItem, wxAcceleratorEntry*
     }
 }
 
-class wxMenuItemCocoaImpl : public wxMenuItemImpl 
+@interface NSMenuItem(PossibleMethods)
+- (void)setHidden:(BOOL)hidden;
+@end
+
+class wxMenuItemCocoaImpl : public wxMenuItemImpl
 {
 public :
     wxMenuItemCocoaImpl( wxMenuItem* peer, NSMenuItem* item ) : wxMenuItemImpl(peer), m_osxMenuItem(item)
@@ -173,39 +240,43 @@ public :
         if ( ![m_osxMenuItem isSeparatorItem] )
             [(wxNSMenuItem*)m_osxMenuItem setImplementation:this];
     }
-    
+
     ~wxMenuItemCocoaImpl();
-        
-    void SetBitmap( const wxBitmap& bitmap ) 
+
+    void SetBitmap( const wxBitmap& bitmap )
     {
         [m_osxMenuItem setImage:bitmap.GetNSImage()];
     }
-    
-    void Enable( bool enable ) 
+
+    void Enable( bool enable )
     {
         [m_osxMenuItem setEnabled:enable];
     }
-    
-    void Check( bool check ) 
+
+    void Check( bool check )
     {
         [m_osxMenuItem setState:( check ?  NSOnState :  NSOffState) ];
     }
-    
+
     void Hide( bool hide )
     {
-        [m_osxMenuItem setHidden:hide ];
+        // NB: setHidden is new as of 10.5 so we should not call it below there
+        if ([m_osxMenuItem respondsToSelector:@selector(setHidden:)])
+            [m_osxMenuItem setHidden:hide ];
+        else
+            wxLogDebug("wxMenuItemCocoaImpl::Hide not yet supported under OS X < 10.5");
     }
-    
-    void SetLabel( const wxString& text, wxAcceleratorEntry *entry ) 
+
+    void SetLabel( const wxString& text, wxAcceleratorEntry *entry )
     {
         wxCFStringRef cfText(text);
         [m_osxMenuItem setTitle:cfText.AsNSString()];
-        
-        if ( entry )
-            wxMacCocoaMenuItemSetAccelerator( m_osxMenuItem, entry );
 
+        wxMacCocoaMenuItemSetAccelerator( m_osxMenuItem, entry );
     }
     
+    bool DoDefault();
+
     void * GetHMenuItem() { return m_osxMenuItem; }
 
 protected :
@@ -216,20 +287,44 @@ wxMenuItemCocoaImpl::~wxMenuItemCocoaImpl()
 {
     if ( ![m_osxMenuItem isSeparatorItem] )
         [(wxNSMenuItem*)m_osxMenuItem setImplementation:nil];
+    [m_osxMenuItem release];
 }
 
+bool wxMenuItemCocoaImpl::DoDefault()
+{
+    bool handled=false;
+    int menuid = m_peer->GetId();
+    
+    NSApplication *theNSApplication = [NSApplication sharedApplication];
+    if (menuid == wxID_OSX_HIDE)
+    {
+        [theNSApplication hide:nil];
+        handled=true;
+    }
+    else if (menuid == wxID_OSX_HIDEOTHERS)
+    {
+        [theNSApplication hideOtherApplications:nil];
+        handled=true;
+    }
+    else if (menuid == wxID_OSX_SHOWALL)
+    {
+        [theNSApplication unhideAllApplications:nil];
+        handled=true;
+    }
+    return handled;
+}
 
 wxMenuItemImpl* wxMenuItemImpl::Create( wxMenuItem* peer, wxMenu *pParentMenu,
-                       int id,
+                       int menuid,
                        const wxString& text,
                        wxAcceleratorEntry *entry,
-                       const wxString& strHelp,
+                       const wxString& WXUNUSED(strHelp),
                        wxItemKind kind,
                        wxMenu *pSubMenu )
 {
     wxMenuItemImpl* c = NULL;
     NSMenuItem* item = nil;
-    
+
     if ( kind == wxITEM_SEPARATOR )
     {
         item = [[NSMenuItem separatorItem] retain];
@@ -237,24 +332,33 @@ wxMenuItemImpl* wxMenuItemImpl::Create( wxMenuItem* peer, wxMenu *pParentMenu,
     else
     {
         wxCFStringRef cfText(text);
-        wxNSMenuItem* temp = [ [ wxNSMenuItem alloc ] init ];
-        if ( ! pParentMenu->GetNoEventsMode() )
+        SEL selector = nil;
+        bool targetSelf = false;
+        if ( (pParentMenu == NULL || !pParentMenu->GetNoEventsMode()) && pSubMenu == NULL )
         {
-            [temp setTarget: temp];
-            [temp setAction: @selector(clickedAction:)];
+            selector = wxOSXGetSelectorFromID(menuid);
+            
+            if ( selector == nil )
+            {
+                selector = @selector(clickedAction:);
+                targetSelf = true;
+            }
         }
-        [temp setTitle:cfText.AsNSString()];
+        
+        wxNSMenuItem* menuitem = [ [ wxNSMenuItem alloc ] initWithTitle:cfText.AsNSString() action:selector keyEquivalent:@""];
+        if ( targetSelf )
+            [menuitem setTarget:menuitem];
+        
         if ( pSubMenu )
         {
             pSubMenu->GetPeer()->SetTitle( text );
-            [temp setSubmenu:pSubMenu->GetHMenu()];
+            [menuitem setSubmenu:pSubMenu->GetHMenu()];
         }
         else
         {
-            if ( entry )
-                wxMacCocoaMenuItemSetAccelerator( temp, entry );
+            wxMacCocoaMenuItemSetAccelerator( menuitem, entry );
         }
-        item = temp;
+        item = menuitem;
     }
     c = new wxMenuItemCocoaImpl( peer, item );
     return c;