1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/cocoa/filedlg.mm
3 // Purpose: wxFileDialog for wxCocoa
7 // RCS-ID: $Id: filedlg.mm 40007 2006-07-05 13:10:46Z SC $
8 // Copyright: (c) Ryan Norton
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
25 #include "wx/filedlg.h"
28 #include "wx/msgdlg.h"
32 #include "wx/filename.h"
33 #include "wx/tokenzr.h"
35 #include "wx/osx/private.h"
37 // ============================================================================
39 // ============================================================================
42 // - support for old style MacOS creator / type combos
43 // - parameter support for descending into packages as directories (setTreatsFilePackagesAsDirectories)
45 IMPLEMENT_CLASS(wxFileDialog, wxFileDialogBase)
47 wxFileDialog::wxFileDialog(
48 wxWindow *parent, const wxString& message,
49 const wxString& defaultDir, const wxString& defaultFileName, const wxString& wildCard,
50 long style, const wxPoint& pos, const wxSize& sz, const wxString& name)
51 : wxFileDialogBase(parent, message, defaultDir, defaultFileName, wildCard, style, pos, sz, name)
55 NSArray* GetTypesFromFilter( const wxString filter )
57 NSMutableArray* types = nil;
58 if ( !filter.empty() )
61 wxArrayString extensions;
63 wxString filter2(filter) ;
68 for ( unsigned int i = 0; i < filter2.length() ; i++ )
70 if ( filter2.GetChar(i) == wxT('|') )
74 names.Add( current ) ;
78 extensions.Add( current ) ;
83 current = wxEmptyString ;
87 current += filter2.GetChar(i) ;
90 // we allow for compatibility reason to have a single filter expression (like *.*) without
91 // an explanatory text, in that case the first part is name and extension at the same time
93 wxASSERT_MSG( filterIndex == 0 || !isName , wxT("incorrect format of format string") ) ;
94 if ( current.empty() )
95 extensions.Add( names[filterIndex] ) ;
97 extensions.Add( current ) ;
98 if ( filterIndex == 0 || isName )
99 names.Add( current ) ;
103 const size_t extCount = extensions.GetCount();
104 for ( size_t i = 0 ; i < extCount; i++ )
106 wxString extensiongroup = extensions[i];
107 wxStringTokenizer tokenizer( extensiongroup , wxT(";") ) ;
108 while ( tokenizer.HasMoreTokens() )
110 wxString extension = tokenizer.GetNextToken() ;
111 // Remove leading '*'
112 if (extension.length() && (extension.GetChar(0) == '*'))
113 extension = extension.Mid( 1 );
115 // Remove leading '.'
116 if (extension.length() && (extension.GetChar(0) == '.'))
117 extension = extension.Mid( 1 );
119 if ( extension.IsEmpty() )
127 types = [[NSMutableArray alloc] init];
129 wxCFStringRef cfext(extension);
130 [types addObject: (NSString*)cfext.AsNSString() ];
132 // add support for classic fileType / creator here
133 wxUint32 fileType, creator;
134 // extension -> mactypes
143 int wxFileDialog::ShowModal()
145 int result = wxID_CANCEL;
147 NSSavePanel *panel = nil;
149 wxCFStringRef cf( m_message );
151 wxCFStringRef dir( m_dir );
152 wxCFStringRef file( m_fileName );
154 m_path = wxEmptyString;
157 wxNonOwnedWindow* parentWindow = NULL;
162 parentWindow = dynamic_cast<wxNonOwnedWindow*>(wxGetTopLevelParent(GetParent()));
165 if (HasFlag(wxFD_SAVE))
167 NSSavePanel* sPanel = [NSSavePanel savePanel];
168 // makes things more convenient:
169 [sPanel setCanCreateDirectories:YES];
170 [sPanel setMessage:cf.AsNSString()];
171 // if we should be able to descend into pacakges we must somehow
172 // be able to pass this in
173 [sPanel setTreatsFilePackagesAsDirectories:NO];
174 [sPanel setCanSelectHiddenExtension:YES];
176 if ( HasFlag(wxFD_OVERWRITE_PROMPT) )
183 NSWindow* nativeParent = parentWindow->GetWXWindow();
184 ModalDialogDelegate* sheetDelegate = [[ModalDialogDelegate alloc] init];
185 [sPanel beginSheetForDirectory:dir.AsNSString() file:file.AsNSString()
186 modalForWindow: nativeParent modalDelegate: sheetDelegate
187 didEndSelector: @selector(sheetDidEnd:returnCode:contextInfo:)
189 [sheetDelegate waitForSheetToFinish];
190 returnCode = [sheetDelegate code];
191 [sheetDelegate release];
196 returnCode = [sPanel runModalForDirectory:dir.AsNSString() file:file.AsNSString() ];
199 if (returnCode == NSOKButton )
204 wxCFStringRef filename( [[sPanel filename] retain] );
206 m_path = filename.AsString();
207 m_fileName = wxFileNameFromPath(m_path);
208 m_dir = wxPathOnly( m_path );
213 NSArray* types = GetTypesFromFilter( m_wildCard ) ;
214 NSOpenPanel* oPanel = [NSOpenPanel openPanel];
215 [oPanel setTreatsFilePackagesAsDirectories:NO];
216 [oPanel setCanChooseDirectories:NO];
217 [oPanel setResolvesAliases:YES];
218 [oPanel setCanChooseFiles:YES];
219 [oPanel setMessage:cf.AsNSString()];
224 NSWindow* nativeParent = parentWindow->GetWXWindow();
225 ModalDialogDelegate* sheetDelegate = [[ModalDialogDelegate alloc] init];
226 [oPanel beginSheetForDirectory:dir.AsNSString() file:file.AsNSString()
227 types: types modalForWindow: nativeParent
228 modalDelegate: sheetDelegate
229 didEndSelector: @selector(sheetDidEnd:returnCode:contextInfo:)
231 [sheetDelegate waitForSheetToFinish];
232 returnCode = [sheetDelegate code];
233 [sheetDelegate release];
238 returnCode = [oPanel runModalForDirectory:dir.AsNSString()
239 file:file.AsNSString() types:types];
241 if (returnCode == NSOKButton )
245 NSArray* filenames = [oPanel filenames];
246 for ( size_t i = 0 ; i < [filenames count] ; ++ i )
248 wxCFStringRef filename( [(NSString*) [filenames objectAtIndex:i] retain] );
249 wxString fnstr = filename.AsString();
250 m_paths.Add( fnstr );
251 m_fileNames.Add( wxFileNameFromPath(fnstr) );
255 m_fileName = wxFileNameFromPath(fnstr);
256 m_dir = wxPathOnly( fnstr );
267 #endif // wxUSE_FILEDLG