]> git.saurik.com Git - wxWidgets.git/blame - src/osx/cocoa/filedlg.mm
Border styles create a double-border on native search ctrl, just use the one Apple...
[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"
33
34#include "wx/osx/private.h"
35
36// ============================================================================
37// implementation
38// ============================================================================
39
4dd9fdf8
SC
40// Open Items:
41// - support for old style MacOS creator / type combos
42// - parameter support for descending into packages as directories (setTreatsFilePackagesAsDirectories)
43
0f9b48d1
SC
44IMPLEMENT_CLASS(wxFileDialog, wxFileDialogBase)
45
46wxFileDialog::wxFileDialog(
47 wxWindow *parent, const wxString& message,
48 const wxString& defaultDir, const wxString& defaultFileName, const wxString& wildCard,
49 long style, const wxPoint& pos, const wxSize& sz, const wxString& name)
50 : wxFileDialogBase(parent, message, defaultDir, defaultFileName, wildCard, style, pos, sz, name)
51{
52}
53
0f9b48d1
SC
54NSArray* GetTypesFromFilter( const wxString filter )
55{
56 NSMutableArray* types = nil;
57 if ( !filter.empty() )
58 {
59 wxArrayString names ;
60 wxArrayString extensions;
bd365871 61
0f9b48d1
SC
62 wxString filter2(filter) ;
63 int filterIndex = 0;
64 bool isName = true ;
65 wxString current ;
66
67 for ( unsigned int i = 0; i < filter2.length() ; i++ )
68 {
69 if ( filter2.GetChar(i) == wxT('|') )
70 {
71 if ( isName )
72 {
73 names.Add( current ) ;
74 }
75 else
76 {
77 extensions.Add( current ) ;
78 ++filterIndex ;
79 }
80
81 isName = !isName ;
82 current = wxEmptyString ;
83 }
84 else
85 {
86 current += filter2.GetChar(i) ;
87 }
88 }
89 // we allow for compatibility reason to have a single filter expression (like *.*) without
90 // an explanatory text, in that case the first part is name and extension at the same time
91
92 wxASSERT_MSG( filterIndex == 0 || !isName , wxT("incorrect format of format string") ) ;
93 if ( current.empty() )
94 extensions.Add( names[filterIndex] ) ;
95 else
96 extensions.Add( current ) ;
97 if ( filterIndex == 0 || isName )
98 names.Add( current ) ;
99
100 ++filterIndex ;
101
102 const size_t extCount = extensions.GetCount();
103 for ( size_t i = 0 ; i < extCount; i++ )
104 {
105 wxString extension = extensions[i];
106
107 // Remove leading '*'
108 if (extension.length() && (extension.GetChar(0) == '*'))
109 extension = extension.Mid( 1 );
110
111 // Remove leading '.'
112 if (extension.length() && (extension.GetChar(0) == '.'))
113 extension = extension.Mid( 1 );
114
bd365871 115 if ( extension.IsEmpty() )
0f9b48d1
SC
116 {
117 if ( types != nil )
118 [types release];
119 return nil;
120 }
bd365871
FM
121
122
0f9b48d1
SC
123 if ( types == nil )
124 types = [[NSMutableArray alloc] init];
bd365871 125
0f9b48d1
SC
126 wxCFStringRef cfext(extension);
127 [types addObject: (NSString*)cfext.AsNSString() ];
bd365871 128#if 0
4dd9fdf8 129 // add support for classic fileType / creator here
0f9b48d1 130 wxUint32 fileType, creator;
0f9b48d1
SC
131 // extension -> mactypes
132#endif
133 }
134 }
135 return types;
136}
137
138int wxFileDialog::ShowModal()
139{
140 int result = wxID_CANCEL;
bd365871 141
0f9b48d1 142 NSSavePanel *panel = nil;
bd365871 143
0f9b48d1 144 wxCFStringRef cf( m_message );
bd365871 145
1b447793 146 wxCFStringRef dir( m_dir );
0f9b48d1 147 wxCFStringRef file( m_fileName );
bd365871 148
0f9b48d1
SC
149 m_path = wxEmptyString;
150 m_fileNames.Clear();
724999ee
KO
151
152 wxNonOwnedWindow* parentWindow = NULL;
153 int returnCode = -1;
154
155 if (GetParent())
156 {
157 parentWindow = dynamic_cast<wxNonOwnedWindow*>(wxGetTopLevelParent(GetParent()));
158 }
bd365871 159
0f9b48d1
SC
160 if (HasFlag(wxFD_SAVE))
161 {
162 NSSavePanel* sPanel = [NSSavePanel savePanel];
163 // makes things more convenient:
164 [sPanel setCanCreateDirectories:YES];
165 [sPanel setMessage:cf.AsNSString()];
4dd9fdf8
SC
166 // if we should be able to descend into pacakges we must somehow
167 // be able to pass this in
0f9b48d1 168 [sPanel setTreatsFilePackagesAsDirectories:NO];
4dd9fdf8 169 [sPanel setCanSelectHiddenExtension:YES];
bd365871 170
0f9b48d1
SC
171 if ( HasFlag(wxFD_OVERWRITE_PROMPT) )
172 {
173 }
724999ee
KO
174
175 if (parentWindow)
176 {
177 NSWindow* nativeParent = parentWindow->GetWXWindow();
178 ModalDialogDelegate* sheetDelegate = [[ModalDialogDelegate alloc] init];
179 [sPanel beginSheetForDirectory:dir.AsNSString() file:file.AsNSString()
180 modalForWindow: nativeParent modalDelegate: sheetDelegate
181 didEndSelector: @selector(sheetDidEnd:returnCode:contextInfo:)
182 contextInfo: nil];
183 [sheetDelegate waitForSheetToFinish];
b2c47ad3 184 returnCode = [sheetDelegate code];
724999ee
KO
185 [sheetDelegate release];
186 }
187 else
188 {
b2c47ad3 189 returnCode = [sPanel runModalForDirectory:dir.AsNSString() file:file.AsNSString() ];
724999ee
KO
190 }
191
b2c47ad3 192 if (returnCode == NSOKButton )
0f9b48d1
SC
193 {
194 panel = sPanel;
195 result = wxID_OK;
bd365871 196
0f9b48d1
SC
197 wxCFStringRef filename( [[sPanel filename] retain] );
198
199 m_path = filename.AsString();
200 m_fileName = wxFileNameFromPath(m_path);
201 m_dir = wxPathOnly( m_path );
202 }
203 }
204 else
205 {
206 NSArray* types = GetTypesFromFilter( m_wildCard ) ;
207 NSOpenPanel* oPanel = [NSOpenPanel openPanel];
208 [oPanel setTreatsFilePackagesAsDirectories:NO];
209 [oPanel setCanChooseDirectories:NO];
210 [oPanel setResolvesAliases:YES];
211 [oPanel setCanChooseFiles:YES];
212 [oPanel setMessage:cf.AsNSString()];
bd365871 213
724999ee
KO
214 if (parentWindow)
215 {
216 NSWindow* nativeParent = parentWindow->GetWXWindow();
217 ModalDialogDelegate* sheetDelegate = [[ModalDialogDelegate alloc] init];
218 [oPanel beginSheetForDirectory:dir.AsNSString() file:file.AsNSString()
219 types: types modalForWindow: nativeParent
220 modalDelegate: sheetDelegate
221 didEndSelector: @selector(sheetDidEnd:returnCode:contextInfo:)
222 contextInfo: nil];
223 [sheetDelegate waitForSheetToFinish];
b2c47ad3 224 returnCode = [sheetDelegate code];
724999ee
KO
225 [sheetDelegate release];
226 }
227 else
228 {
b2c47ad3 229 returnCode = [oPanel runModalForDirectory:dir.AsNSString()
724999ee
KO
230 file:file.AsNSString() types:types];
231 }
b2c47ad3 232 if (returnCode == NSOKButton )
0f9b48d1
SC
233 {
234 panel = oPanel;
235 result = wxID_OK;
236 NSArray* filenames = [oPanel filenames];
237 for ( size_t i = 0 ; i < [filenames count] ; ++ i )
238 {
239 wxCFStringRef filename( [(NSString*) [filenames objectAtIndex:i] retain] );
240 wxString fnstr = filename.AsString();
241 m_paths.Add( fnstr );
242 m_fileNames.Add( wxFileNameFromPath(fnstr) );
243 if ( i == 0 )
244 {
245 m_path = fnstr;
246 m_fileName = wxFileNameFromPath(fnstr);
247 m_dir = wxPathOnly( fnstr );
248 }
249 }
250 }
251 if ( types != nil )
252 [types release];
253 }
bd365871 254
0f9b48d1
SC
255 return result;
256}
257
0f9b48d1 258#endif // wxUSE_FILEDLG