]> git.saurik.com Git - wxWidgets.git/blobdiff - src/osx/cocoa/filedlg.mm
safe degradation
[wxWidgets.git] / src / osx / cocoa / filedlg.mm
index 462ee154e477e7d604f7fcb7e385642a0cf11f63..b4decc5dcd16a48ec2d467141ec57f5c90067b73 100644 (file)
@@ -30,6 +30,7 @@
 #endif
 
 #include "wx/filename.h"
+#include "wx/tokenzr.h"
 
 #include "wx/osx/private.h"
 
@@ -51,7 +52,6 @@ wxFileDialog::wxFileDialog(
 {
 }
 
-
 NSArray* GetTypesFromFilter( const wxString filter )
 {
     NSMutableArray* types = nil;
@@ -103,43 +103,100 @@ NSArray* GetTypesFromFilter( const wxString filter )
         const size_t extCount = extensions.GetCount();
         for ( size_t i = 0 ; i < extCount; i++ )
         {
-            wxString extension = extensions[i];
-
-            // Remove leading '*'
-            if (extension.length() && (extension.GetChar(0) == '*'))
-                extension = extension.Mid( 1 );
-
-            // Remove leading '.'
-            if (extension.length() && (extension.GetChar(0) == '.'))
-                extension = extension.Mid( 1 );
-
-            if ( extension.IsEmpty() )
+            wxString extensiongroup = extensions[i];
+            wxStringTokenizer tokenizer( extensiongroup , wxT(";") ) ;
+            while ( tokenizer.HasMoreTokens() )
             {
-                if ( types != nil )
-                    [types release];
-                return nil;
-            }
+                wxString extension = tokenizer.GetNextToken() ;
+                // Remove leading '*'
+                if (extension.length() && (extension.GetChar(0) == '*'))
+                    extension = extension.Mid( 1 );
 
+                // Remove leading '.'
+                if (extension.length() && (extension.GetChar(0) == '.'))
+                    extension = extension.Mid( 1 );
 
-            if ( types == nil )
-                types = [[NSMutableArray alloc] init];
+                if ( extension.IsEmpty() )
+                {
+                    if ( types != nil )
+                        [types release];
+                    return nil;
+                }
+
+                if ( types == nil )
+                    types = [[NSMutableArray alloc] init];
 
-            wxCFStringRef cfext(extension);
-            [types addObject: (NSString*)cfext.AsNSString()  ];
+                wxCFStringRef cfext(extension);
+                [types addObject: (NSString*)cfext.AsNSString()  ];
 #if 0
-            // add support for classic fileType / creator here
-            wxUint32 fileType, creator;
-            // extension -> mactypes
+                // add support for classic fileType / creator here
+                wxUint32 fileType, creator;
+                // extension -> mactypes
 #endif
+            }
+
         }
     }
     return types;
 }
 
-int wxFileDialog::ShowModal()
+void wxFileDialog::ShowWindowModal()
 {
-    int result = wxID_CANCEL;
+    wxCFStringRef cf( m_message );
+    wxCFStringRef dir( m_dir );
+    wxCFStringRef file( m_fileName );
 
+    wxNonOwnedWindow* parentWindow = NULL;
+    
+    m_modality = wxDIALOG_MODALITY_WINDOW_MODAL;
+
+    if (GetParent())
+        parentWindow = dynamic_cast<wxNonOwnedWindow*>(wxGetTopLevelParent(GetParent()));
+
+    wxASSERT_MSG(parentWindow, "Window modal display requires parent.");
+    
+    if (HasFlag(wxFD_SAVE))
+    {
+        NSSavePanel* sPanel = [NSSavePanel savePanel];
+        // makes things more convenient:
+        [sPanel setCanCreateDirectories:YES];
+        [sPanel setMessage:cf.AsNSString()];
+        // if we should be able to descend into pacakges we must somehow
+        // be able to pass this in
+        [sPanel setTreatsFilePackagesAsDirectories:NO];
+        [sPanel setCanSelectHiddenExtension:YES];
+        
+        NSWindow* nativeParent = parentWindow->GetWXWindow();
+        ModalDialogDelegate* sheetDelegate = [[ModalDialogDelegate alloc] init];
+        [sheetDelegate setImplementation: this];
+        [sPanel beginSheetForDirectory:dir.AsNSString() file:file.AsNSString()
+            modalForWindow: nativeParent modalDelegate: sheetDelegate
+            didEndSelector: @selector(sheetDidEnd:returnCode:contextInfo:)
+            contextInfo: nil];
+    }
+    else 
+    {
+        NSArray* types = GetTypesFromFilter( m_wildCard ) ;
+        NSOpenPanel* oPanel = [NSOpenPanel openPanel];
+        [oPanel setTreatsFilePackagesAsDirectories:NO];
+        [oPanel setCanChooseDirectories:NO];
+        [oPanel setResolvesAliases:YES];
+        [oPanel setCanChooseFiles:YES];
+        [oPanel setMessage:cf.AsNSString()];
+    
+        NSWindow* nativeParent = parentWindow->GetWXWindow();
+        ModalDialogDelegate* sheetDelegate = [[ModalDialogDelegate alloc] init];
+        [sheetDelegate setImplementation: this];
+        [oPanel beginSheetForDirectory:dir.AsNSString() file:file.AsNSString()
+            types: types modalForWindow: nativeParent
+            modalDelegate: sheetDelegate
+            didEndSelector: @selector(sheetDidEnd:returnCode:contextInfo:)
+            contextInfo: nil];
+    }
+}
+
+int wxFileDialog::ShowModal()
+{
     NSSavePanel *panel = nil;
 
     wxCFStringRef cf( m_message );
@@ -149,6 +206,17 @@ int wxFileDialog::ShowModal()
 
     m_path = wxEmptyString;
     m_fileNames.Clear();
+    m_paths.Clear();
+    // since we don't support retrieving the matching filter
+    m_filterIndex = -1;
+
+    wxNonOwnedWindow* parentWindow = NULL;
+    int returnCode = -1;
+
+    if (GetParent())
+    {
+        parentWindow = dynamic_cast<wxNonOwnedWindow*>(wxGetTopLevelParent(GetParent()));
+    }
 
     if (HasFlag(wxFD_SAVE))
     {
@@ -165,17 +233,8 @@ int wxFileDialog::ShowModal()
         {
         }
 
-        if ( [sPanel runModalForDirectory:dir.AsNSString() file:file.AsNSString() ] == NSOKButton )
-        {
-            panel = sPanel;
-            result = wxID_OK;
-
-            wxCFStringRef filename( [[sPanel filename] retain] );
-
-            m_path = filename.AsString();
-            m_fileName = wxFileNameFromPath(m_path);
-            m_dir = wxPathOnly( m_path );
-        }
+        returnCode = [sPanel runModalForDirectory:dir.AsNSString() file:file.AsNSString() ];
+        ModalFinishedCallback(sPanel, returnCode);
     }
     else
     {
@@ -187,15 +246,44 @@ int wxFileDialog::ShowModal()
         [oPanel setCanChooseFiles:YES];
         [oPanel setMessage:cf.AsNSString()];
 
-        if ( [oPanel runModalForDirectory:dir.AsNSString() file:file.AsNSString() types:types] == NSOKButton )
+        returnCode = [oPanel runModalForDirectory:dir.AsNSString()
+                        file:file.AsNSString() types:types];
+
+        ModalFinishedCallback(oPanel, returnCode);
+        
+        if ( types != nil )
+            [types release];
+    }
+
+    return GetReturnCode();
+}
+
+void wxFileDialog::ModalFinishedCallback(void* panel, int returnCode)
+{
+    int result = wxID_CANCEL;
+    if (HasFlag(wxFD_SAVE))
+    {
+        if (returnCode == NSOKButton )
+        {
+            NSSavePanel* sPanel = (NSSavePanel*)panel;
+            result = wxID_OK;
+
+            m_path = wxCFStringRef::AsString([sPanel filename]);
+            m_fileName = wxFileNameFromPath(m_path);
+            m_dir = wxPathOnly( m_path );
+        }
+    }
+    else
+    {
+        NSOpenPanel* oPanel = (NSOpenPanel*)panel;
+        if (returnCode == NSOKButton )
         {
             panel = oPanel;
             result = wxID_OK;
             NSArray* filenames = [oPanel filenames];
             for ( size_t i = 0 ; i < [filenames count] ; ++ i )
             {
-                wxCFStringRef filename( [(NSString*) [filenames objectAtIndex:i] retain] );
-                wxString fnstr = filename.AsString();
+                wxString fnstr = wxCFStringRef::AsString([filenames objectAtIndex:i]);
                 m_paths.Add( fnstr );
                 m_fileNames.Add( wxFileNameFromPath(fnstr) );
                 if ( i == 0 )
@@ -206,11 +294,11 @@ int wxFileDialog::ShowModal()
                 }
             }
         }
-        if ( types != nil )
-            [types release];
     }
-
-    return result;
+    SetReturnCode(result);
+    
+    if (GetModality() == wxDIALOG_MODALITY_WINDOW_MODAL)
+        SendWindowModalDialogEvent ( wxEVT_WINDOW_MODAL_DIALOG_CLOSED  );
 }
 
 #endif // wxUSE_FILEDLG