]> git.saurik.com Git - wxWidgets.git/blob - src/osx/cocoa/filedlg.mm
moving OnInit back
[wxWidgets.git] / src / osx / cocoa / filedlg.mm
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/cocoa/filedlg.mm
3 // Purpose: wxFileDialog for wxCocoa
4 // Author: Ryan Norton
5 // Modified by:
6 // Created: 2004-10-02
7 // RCS-ID: $Id: filedlg.mm 40007 2006-07-05 13:10:46Z SC $
8 // Copyright: (c) Ryan Norton
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22
23 #if wxUSE_FILEDLG
24
25 #include "wx/filedlg.h"
26
27 #ifndef WX_PRECOMP
28 #include "wx/msgdlg.h"
29 #include "wx/app.h"
30 #endif
31
32 #include "wx/filename.h"
33 #include "wx/tokenzr.h"
34
35 #include "wx/osx/private.h"
36
37 // ============================================================================
38 // implementation
39 // ============================================================================
40
41 // Open Items:
42 // - support for old style MacOS creator / type combos
43 // - parameter support for descending into packages as directories (setTreatsFilePackagesAsDirectories)
44
45 IMPLEMENT_CLASS(wxFileDialog, wxFileDialogBase)
46
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)
52 {
53 }
54
55 NSArray* GetTypesFromFilter( const wxString filter )
56 {
57 NSMutableArray* types = nil;
58 if ( !filter.empty() )
59 {
60 wxArrayString names ;
61 wxArrayString extensions;
62
63 wxString filter2(filter) ;
64 int filterIndex = 0;
65 bool isName = true ;
66 wxString current ;
67
68 for ( unsigned int i = 0; i < filter2.length() ; i++ )
69 {
70 if ( filter2.GetChar(i) == wxT('|') )
71 {
72 if ( isName )
73 {
74 names.Add( current ) ;
75 }
76 else
77 {
78 extensions.Add( current ) ;
79 ++filterIndex ;
80 }
81
82 isName = !isName ;
83 current = wxEmptyString ;
84 }
85 else
86 {
87 current += filter2.GetChar(i) ;
88 }
89 }
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
92
93 wxASSERT_MSG( filterIndex == 0 || !isName , wxT("incorrect format of format string") ) ;
94 if ( current.empty() )
95 extensions.Add( names[filterIndex] ) ;
96 else
97 extensions.Add( current ) ;
98 if ( filterIndex == 0 || isName )
99 names.Add( current ) ;
100
101 ++filterIndex ;
102
103 const size_t extCount = extensions.GetCount();
104 for ( size_t i = 0 ; i < extCount; i++ )
105 {
106 wxString extensiongroup = extensions[i];
107 wxStringTokenizer tokenizer( extensiongroup , wxT(";") ) ;
108 while ( tokenizer.HasMoreTokens() )
109 {
110 wxString extension = tokenizer.GetNextToken() ;
111 // Remove leading '*'
112 if (extension.length() && (extension.GetChar(0) == '*'))
113 extension = extension.Mid( 1 );
114
115 // Remove leading '.'
116 if (extension.length() && (extension.GetChar(0) == '.'))
117 extension = extension.Mid( 1 );
118
119 // Remove leading '*', this is for handling *.*
120 if (extension.length() && (extension.GetChar(0) == '*'))
121 extension = extension.Mid( 1 );
122
123 if ( extension.IsEmpty() )
124 {
125 if ( types != nil )
126 [types release];
127 return nil;
128 }
129
130 if ( types == nil )
131 types = [[NSMutableArray alloc] init];
132
133 wxCFStringRef cfext(extension);
134 [types addObject: (NSString*)cfext.AsNSString() ];
135 #if 0
136 // add support for classic fileType / creator here
137 wxUint32 fileType, creator;
138 // extension -> mactypes
139 #endif
140 }
141
142 }
143 }
144 return types;
145 }
146
147 void wxFileDialog::ShowWindowModal()
148 {
149 wxCFStringRef cf( m_message );
150 wxCFStringRef dir( m_dir );
151 wxCFStringRef file( m_fileName );
152
153 wxNonOwnedWindow* parentWindow = NULL;
154
155 m_modality = wxDIALOG_MODALITY_WINDOW_MODAL;
156
157 if (GetParent())
158 parentWindow = dynamic_cast<wxNonOwnedWindow*>(wxGetTopLevelParent(GetParent()));
159
160 wxASSERT_MSG(parentWindow, "Window modal display requires parent.");
161
162 if (HasFlag(wxFD_SAVE))
163 {
164 NSSavePanel* sPanel = [NSSavePanel savePanel];
165 // makes things more convenient:
166 [sPanel setCanCreateDirectories:YES];
167 [sPanel setMessage:cf.AsNSString()];
168 // if we should be able to descend into pacakges we must somehow
169 // be able to pass this in
170 [sPanel setTreatsFilePackagesAsDirectories:NO];
171 [sPanel setCanSelectHiddenExtension:YES];
172
173 NSWindow* nativeParent = parentWindow->GetWXWindow();
174 ModalDialogDelegate* sheetDelegate = [[ModalDialogDelegate alloc] init];
175 [sheetDelegate setImplementation: this];
176 [sPanel beginSheetForDirectory:dir.AsNSString() file:file.AsNSString()
177 modalForWindow: nativeParent modalDelegate: sheetDelegate
178 didEndSelector: @selector(sheetDidEnd:returnCode:contextInfo:)
179 contextInfo: nil];
180 }
181 else
182 {
183 NSArray* types = GetTypesFromFilter( m_wildCard ) ;
184 NSOpenPanel* oPanel = [NSOpenPanel openPanel];
185 [oPanel setTreatsFilePackagesAsDirectories:NO];
186 [oPanel setCanChooseDirectories:NO];
187 [oPanel setResolvesAliases:YES];
188 [oPanel setCanChooseFiles:YES];
189 [oPanel setMessage:cf.AsNSString()];
190
191 NSWindow* nativeParent = parentWindow->GetWXWindow();
192 ModalDialogDelegate* sheetDelegate = [[ModalDialogDelegate alloc] init];
193 [sheetDelegate setImplementation: this];
194 [oPanel beginSheetForDirectory:dir.AsNSString() file:file.AsNSString()
195 types: types modalForWindow: nativeParent
196 modalDelegate: sheetDelegate
197 didEndSelector: @selector(sheetDidEnd:returnCode:contextInfo:)
198 contextInfo: nil];
199 }
200 }
201
202 int wxFileDialog::ShowModal()
203 {
204 NSSavePanel *panel = nil;
205
206 wxCFStringRef cf( m_message );
207
208 wxCFStringRef dir( m_dir );
209 wxCFStringRef file( m_fileName );
210
211 m_path = wxEmptyString;
212 m_fileNames.Clear();
213 m_paths.Clear();
214 // since we don't support retrieving the matching filter
215 m_filterIndex = -1;
216
217 wxNonOwnedWindow* parentWindow = NULL;
218 int returnCode = -1;
219
220 if (GetParent())
221 {
222 parentWindow = dynamic_cast<wxNonOwnedWindow*>(wxGetTopLevelParent(GetParent()));
223 }
224
225 if (HasFlag(wxFD_SAVE))
226 {
227 NSSavePanel* sPanel = [NSSavePanel savePanel];
228 // makes things more convenient:
229 [sPanel setCanCreateDirectories:YES];
230 [sPanel setMessage:cf.AsNSString()];
231 // if we should be able to descend into pacakges we must somehow
232 // be able to pass this in
233 [sPanel setTreatsFilePackagesAsDirectories:NO];
234 [sPanel setCanSelectHiddenExtension:YES];
235
236 if ( HasFlag(wxFD_OVERWRITE_PROMPT) )
237 {
238 }
239
240 returnCode = [sPanel runModalForDirectory:dir.AsNSString() file:file.AsNSString() ];
241 ModalFinishedCallback(sPanel, returnCode);
242 }
243 else
244 {
245 NSArray* types = GetTypesFromFilter( m_wildCard ) ;
246 NSOpenPanel* oPanel = [NSOpenPanel openPanel];
247 [oPanel setTreatsFilePackagesAsDirectories:NO];
248 [oPanel setCanChooseDirectories:NO];
249 [oPanel setResolvesAliases:YES];
250 [oPanel setCanChooseFiles:YES];
251 [oPanel setMessage:cf.AsNSString()];
252
253 returnCode = [oPanel runModalForDirectory:dir.AsNSString()
254 file:file.AsNSString() types:types];
255
256 ModalFinishedCallback(oPanel, returnCode);
257
258 if ( types != nil )
259 [types release];
260 }
261
262 return GetReturnCode();
263 }
264
265 void wxFileDialog::ModalFinishedCallback(void* panel, int returnCode)
266 {
267 int result = wxID_CANCEL;
268 if (HasFlag(wxFD_SAVE))
269 {
270 if (returnCode == NSOKButton )
271 {
272 NSSavePanel* sPanel = (NSSavePanel*)panel;
273 result = wxID_OK;
274
275 m_path = wxCFStringRef::AsString([sPanel filename]);
276 m_fileName = wxFileNameFromPath(m_path);
277 m_dir = wxPathOnly( m_path );
278 }
279 }
280 else
281 {
282 NSOpenPanel* oPanel = (NSOpenPanel*)panel;
283 if (returnCode == NSOKButton )
284 {
285 panel = oPanel;
286 result = wxID_OK;
287 NSArray* filenames = [oPanel filenames];
288 for ( size_t i = 0 ; i < [filenames count] ; ++ i )
289 {
290 wxString fnstr = wxCFStringRef::AsString([filenames objectAtIndex:i]);
291 m_paths.Add( fnstr );
292 m_fileNames.Add( wxFileNameFromPath(fnstr) );
293 if ( i == 0 )
294 {
295 m_path = fnstr;
296 m_fileName = wxFileNameFromPath(fnstr);
297 m_dir = wxPathOnly( fnstr );
298 }
299 }
300 }
301 }
302 SetReturnCode(result);
303
304 if (GetModality() == wxDIALOG_MODALITY_WINDOW_MODAL)
305 SendWindowModalDialogEvent ( wxEVT_WINDOW_MODAL_DIALOG_CLOSED );
306 }
307
308 #endif // wxUSE_FILEDLG