]> git.saurik.com Git - wxWidgets.git/blame - src/osx/cocoa/filedlg.mm
fixing searchctrl on osx_cocoa, changing type for peer to wxSearchCtrl
[wxWidgets.git] / src / osx / cocoa / filedlg.mm
CommitLineData
0f9b48d1
SC
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"
b822bdc0 33#include "wx/tokenzr.h"
0f9b48d1
SC
34
35#include "wx/osx/private.h"
36
37// ============================================================================
38// implementation
39// ============================================================================
40
4dd9fdf8
SC
41// Open Items:
42// - support for old style MacOS creator / type combos
43// - parameter support for descending into packages as directories (setTreatsFilePackagesAsDirectories)
44
0f9b48d1
SC
45IMPLEMENT_CLASS(wxFileDialog, wxFileDialogBase)
46
47wxFileDialog::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
61ad44c7
SC
55bool wxFileDialog::SupportsExtraControl() const
56{
2f30930a 57 return true;
61ad44c7
SC
58}
59
0f9b48d1
SC
60NSArray* GetTypesFromFilter( const wxString filter )
61{
62 NSMutableArray* types = nil;
63 if ( !filter.empty() )
64 {
65 wxArrayString names ;
66 wxArrayString extensions;
bd365871 67
0f9b48d1
SC
68 wxString filter2(filter) ;
69 int filterIndex = 0;
70 bool isName = true ;
71 wxString current ;
72
73 for ( unsigned int i = 0; i < filter2.length() ; i++ )
74 {
75 if ( filter2.GetChar(i) == wxT('|') )
76 {
77 if ( isName )
78 {
79 names.Add( current ) ;
80 }
81 else
82 {
83 extensions.Add( current ) ;
84 ++filterIndex ;
85 }
86
87 isName = !isName ;
88 current = wxEmptyString ;
89 }
90 else
91 {
92 current += filter2.GetChar(i) ;
93 }
94 }
95 // we allow for compatibility reason to have a single filter expression (like *.*) without
96 // an explanatory text, in that case the first part is name and extension at the same time
97
98 wxASSERT_MSG( filterIndex == 0 || !isName , wxT("incorrect format of format string") ) ;
99 if ( current.empty() )
100 extensions.Add( names[filterIndex] ) ;
101 else
102 extensions.Add( current ) ;
103 if ( filterIndex == 0 || isName )
104 names.Add( current ) ;
105
106 ++filterIndex ;
107
108 const size_t extCount = extensions.GetCount();
109 for ( size_t i = 0 ; i < extCount; i++ )
110 {
b822bdc0
SC
111 wxString extensiongroup = extensions[i];
112 wxStringTokenizer tokenizer( extensiongroup , wxT(";") ) ;
113 while ( tokenizer.HasMoreTokens() )
0f9b48d1 114 {
b822bdc0
SC
115 wxString extension = tokenizer.GetNextToken() ;
116 // Remove leading '*'
117 if (extension.length() && (extension.GetChar(0) == '*'))
118 extension = extension.Mid( 1 );
bd365871 119
b822bdc0
SC
120 // Remove leading '.'
121 if (extension.length() && (extension.GetChar(0) == '.'))
122 extension = extension.Mid( 1 );
bd365871 123
05c218ee
KO
124 // Remove leading '*', this is for handling *.*
125 if (extension.length() && (extension.GetChar(0) == '*'))
126 extension = extension.Mid( 1 );
127
b822bdc0
SC
128 if ( extension.IsEmpty() )
129 {
130 if ( types != nil )
131 [types release];
132 return nil;
133 }
134
135 if ( types == nil )
136 types = [[NSMutableArray alloc] init];
bd365871 137
b822bdc0
SC
138 wxCFStringRef cfext(extension);
139 [types addObject: (NSString*)cfext.AsNSString() ];
bd365871 140#if 0
b822bdc0
SC
141 // add support for classic fileType / creator here
142 wxUint32 fileType, creator;
143 // extension -> mactypes
0f9b48d1 144#endif
b822bdc0
SC
145 }
146
0f9b48d1
SC
147 }
148 }
149 return types;
150}
151
bfa92264 152void wxFileDialog::ShowWindowModal()
0f9b48d1 153{
bfa92264
KO
154 wxCFStringRef cf( m_message );
155 wxCFStringRef dir( m_dir );
156 wxCFStringRef file( m_fileName );
157
158 wxNonOwnedWindow* parentWindow = NULL;
159
160 m_modality = wxDIALOG_MODALITY_WINDOW_MODAL;
161
162 if (GetParent())
163 parentWindow = dynamic_cast<wxNonOwnedWindow*>(wxGetTopLevelParent(GetParent()));
164
165 wxASSERT_MSG(parentWindow, "Window modal display requires parent.");
166
167 if (HasFlag(wxFD_SAVE))
168 {
169 NSSavePanel* sPanel = [NSSavePanel savePanel];
2f30930a
SC
170
171 SetupExtraControls(sPanel);
172
bfa92264
KO
173 // makes things more convenient:
174 [sPanel setCanCreateDirectories:YES];
175 [sPanel setMessage:cf.AsNSString()];
176 // if we should be able to descend into pacakges we must somehow
177 // be able to pass this in
178 [sPanel setTreatsFilePackagesAsDirectories:NO];
179 [sPanel setCanSelectHiddenExtension:YES];
180
181 NSWindow* nativeParent = parentWindow->GetWXWindow();
182 ModalDialogDelegate* sheetDelegate = [[ModalDialogDelegate alloc] init];
183 [sheetDelegate setImplementation: this];
184 [sPanel beginSheetForDirectory:dir.AsNSString() file:file.AsNSString()
185 modalForWindow: nativeParent modalDelegate: sheetDelegate
186 didEndSelector: @selector(sheetDidEnd:returnCode:contextInfo:)
187 contextInfo: nil];
188 }
189 else
190 {
191 NSArray* types = GetTypesFromFilter( m_wildCard ) ;
192 NSOpenPanel* oPanel = [NSOpenPanel openPanel];
2f30930a
SC
193
194 SetupExtraControls(oPanel);
195
bfa92264
KO
196 [oPanel setTreatsFilePackagesAsDirectories:NO];
197 [oPanel setCanChooseDirectories:NO];
198 [oPanel setResolvesAliases:YES];
199 [oPanel setCanChooseFiles:YES];
200 [oPanel setMessage:cf.AsNSString()];
201
202 NSWindow* nativeParent = parentWindow->GetWXWindow();
203 ModalDialogDelegate* sheetDelegate = [[ModalDialogDelegate alloc] init];
204 [sheetDelegate setImplementation: this];
205 [oPanel beginSheetForDirectory:dir.AsNSString() file:file.AsNSString()
206 types: types modalForWindow: nativeParent
207 modalDelegate: sheetDelegate
208 didEndSelector: @selector(sheetDidEnd:returnCode:contextInfo:)
209 contextInfo: nil];
210 }
211}
bd365871 212
2f30930a 213void wxFileDialog::SetupExtraControls(WXWindow nativeWindow)
bfa92264 214{
2f30930a
SC
215 NSSavePanel* panel = (NSSavePanel*) nativeWindow;
216
217 wxNonOwnedWindow::Create( GetParent(), nativeWindow );
218
219 if (HasExtraControlCreator())
220 {
221 CreateExtraControl();
222 wxWindow* control = GetExtraControl();
223 if ( control )
224 {
225 NSView* accView = control->GetHandle();
226 [accView removeFromSuperview];
227 [panel setAccessoryView:accView];
228 }
229 else
230 {
231 [panel setAccessoryView:nil];
232 }
233 }
234}
bd365871 235
2f30930a
SC
236int wxFileDialog::ShowModal()
237{
0f9b48d1 238 wxCFStringRef cf( m_message );
bd365871 239
1b447793 240 wxCFStringRef dir( m_dir );
0f9b48d1 241 wxCFStringRef file( m_fileName );
bd365871 242
0f9b48d1
SC
243 m_path = wxEmptyString;
244 m_fileNames.Clear();
8b558f12 245 m_paths.Clear();
2efd54a4
SC
246 // since we don't support retrieving the matching filter
247 m_filterIndex = -1;
03647350 248
724999ee
KO
249 wxNonOwnedWindow* parentWindow = NULL;
250 int returnCode = -1;
03647350
VZ
251
252 if (GetParent())
724999ee
KO
253 {
254 parentWindow = dynamic_cast<wxNonOwnedWindow*>(wxGetTopLevelParent(GetParent()));
255 }
bd365871 256
0f9b48d1
SC
257 if (HasFlag(wxFD_SAVE))
258 {
259 NSSavePanel* sPanel = [NSSavePanel savePanel];
2f30930a
SC
260
261 SetupExtraControls(sPanel);
262
0f9b48d1
SC
263 // makes things more convenient:
264 [sPanel setCanCreateDirectories:YES];
265 [sPanel setMessage:cf.AsNSString()];
4dd9fdf8
SC
266 // if we should be able to descend into pacakges we must somehow
267 // be able to pass this in
0f9b48d1 268 [sPanel setTreatsFilePackagesAsDirectories:NO];
4dd9fdf8 269 [sPanel setCanSelectHiddenExtension:YES];
bd365871 270
0f9b48d1
SC
271 if ( HasFlag(wxFD_OVERWRITE_PROMPT) )
272 {
273 }
440e5cb2 274
bfa92264
KO
275 returnCode = [sPanel runModalForDirectory:dir.AsNSString() file:file.AsNSString() ];
276 ModalFinishedCallback(sPanel, returnCode);
2f30930a 277
d623e8b1 278 UnsubclassWin();
2f30930a 279 [sPanel setAccessoryView:nil];
0f9b48d1
SC
280 }
281 else
282 {
283 NSArray* types = GetTypesFromFilter( m_wildCard ) ;
284 NSOpenPanel* oPanel = [NSOpenPanel openPanel];
2f30930a
SC
285
286 SetupExtraControls(oPanel);
287
0f9b48d1
SC
288 [oPanel setTreatsFilePackagesAsDirectories:NO];
289 [oPanel setCanChooseDirectories:NO];
290 [oPanel setResolvesAliases:YES];
291 [oPanel setCanChooseFiles:YES];
292 [oPanel setMessage:cf.AsNSString()];
bd365871 293
bfa92264 294 returnCode = [oPanel runModalForDirectory:dir.AsNSString()
724999ee 295 file:file.AsNSString() types:types];
bfa92264
KO
296
297 ModalFinishedCallback(oPanel, returnCode);
298
d623e8b1 299 UnsubclassWin();
2f30930a
SC
300 [oPanel setAccessoryView:nil];
301
bfa92264
KO
302 if ( types != nil )
303 [types release];
304 }
305
306 return GetReturnCode();
307}
308
309void wxFileDialog::ModalFinishedCallback(void* panel, int returnCode)
310{
311 int result = wxID_CANCEL;
312 if (HasFlag(wxFD_SAVE))
313 {
314 if (returnCode == NSOKButton )
315 {
316 NSSavePanel* sPanel = (NSSavePanel*)panel;
317 result = wxID_OK;
318
319 m_path = wxCFStringRef::AsString([sPanel filename]);
320 m_fileName = wxFileNameFromPath(m_path);
321 m_dir = wxPathOnly( m_path );
724999ee 322 }
bfa92264
KO
323 }
324 else
325 {
326 NSOpenPanel* oPanel = (NSOpenPanel*)panel;
b2c47ad3 327 if (returnCode == NSOKButton )
0f9b48d1
SC
328 {
329 panel = oPanel;
330 result = wxID_OK;
331 NSArray* filenames = [oPanel filenames];
332 for ( size_t i = 0 ; i < [filenames count] ; ++ i )
333 {
f66ecdc4 334 wxString fnstr = wxCFStringRef::AsString([filenames objectAtIndex:i]);
0f9b48d1
SC
335 m_paths.Add( fnstr );
336 m_fileNames.Add( wxFileNameFromPath(fnstr) );
337 if ( i == 0 )
338 {
339 m_path = fnstr;
340 m_fileName = wxFileNameFromPath(fnstr);
341 m_dir = wxPathOnly( fnstr );
342 }
343 }
344 }
0f9b48d1 345 }
bfa92264
KO
346 SetReturnCode(result);
347
348 if (GetModality() == wxDIALOG_MODALITY_WINDOW_MODAL)
349 SendWindowModalDialogEvent ( wxEVT_WINDOW_MODAL_DIALOG_CLOSED );
2f30930a
SC
350
351 [(NSSavePanel*) panel setAccessoryView:nil];
0f9b48d1
SC
352}
353
0f9b48d1 354#endif // wxUSE_FILEDLG