Document domain parameter of wxTranslations::GetTranslatedString().
[wxWidgets.git] / src / 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 // Copyright:   (c) Ryan Norton
8 // Licence:     wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21
22 #if wxUSE_FILEDLG
23
24 #include "wx/filedlg.h"
25
26 #ifndef WX_PRECOMP
27     #include "wx/msgdlg.h"
28     #include "wx/app.h"
29 #endif
30
31 #include "wx/filename.h"
32
33 #include "wx/cocoa/autorelease.h"
34 #include "wx/cocoa/string.h"
35 #include "wx/modalhook.h"
36
37 #import <AppKit/NSOpenPanel.h>
38 #import <AppKit/NSSavePanel.h>
39
40 #import <Foundation/NSArray.h>
41 // ============================================================================
42 // implementation
43 // ============================================================================
44
45 IMPLEMENT_CLASS(wxCocoaFileDialog, wxFileDialogBase)
46
47 // ----------------------------------------------------------------------------
48 // wxFileDialog
49 // ----------------------------------------------------------------------------
50
51 wxFileDialog::wxFileDialog(wxWindow *parent,
52                            const wxString& message,
53                            const wxString& defaultDir,
54                            const wxString& defaultFileName,
55                            const wxString& wildCard,
56                            long style,
57                            const wxPoint& pos,
58                            const wxSize& sz,
59                            const wxString& name)
60             : wxFileDialogBase(parent, message, defaultDir, defaultFileName,
61                                wildCard, style, pos, sz, name)
62 {
63     wxTopLevelWindows.Append(this);
64
65     wxASSERT(CreateBase(parent,wxID_ANY,pos,wxDefaultSize,style,wxDefaultValidator,wxDialogNameStr));
66
67     if ( parent )
68         parent->AddChild(this);
69
70     m_cocoaNSWindow = nil;
71     m_cocoaNSView = nil;
72
73     //Init the wildcard array
74     m_wildcards = [[NSMutableArray alloc] initWithCapacity:0];
75
76     //If the user requests to save - use a NSSavePanel
77     //else use a NSOpenPanel
78     if (HasFlag(wxFD_SAVE))
79     {
80         SetNSPanel([NSSavePanel savePanel]);
81
82         [GetNSSavePanel() setTitle:wxNSStringWithWxString(message)];
83
84         [GetNSSavePanel() setPrompt:@"Save"];
85         [GetNSSavePanel() setTreatsFilePackagesAsDirectories:YES];
86         [GetNSSavePanel() setCanSelectHiddenExtension:YES];
87
88 //        Cached as per-app in obj-c
89 //        [GetNSSavePanel() setExtensionHidden:YES];
90
91         //
92         // NB:  Note that only Panther supports wildcards
93         // with save dialogs - not that wildcards in save
94         // dialogs are all that useful, anyway :)
95         //
96     }
97     else //m_dialogStyle & wxFD_OPEN
98     {
99         SetNSPanel([NSOpenPanel openPanel]);
100         [m_cocoaNSWindow setTitle:wxNSStringWithWxString(message)];
101
102         [(NSOpenPanel*)m_cocoaNSWindow setAllowsMultipleSelection:(HasFlag(wxFD_MULTIPLE))];
103         [(NSOpenPanel*)m_cocoaNSWindow setResolvesAliases:YES];
104         [(NSOpenPanel*)m_cocoaNSWindow setCanChooseFiles:YES];
105         [(NSOpenPanel*)m_cocoaNSWindow setCanChooseDirectories:NO];
106         [GetNSSavePanel() setPrompt:@"Open"];
107
108         //convert wildcards - open panel only takes file extensions -
109         //no actual wildcards here :)
110         size_t lastwcpos = 0;
111         bool bDescription = true;
112         size_t i;
113         for(i = wildCard.find('|');
114                 i != wxString::npos;
115                 i = wildCard.find('|', lastwcpos+1))
116         {
117             size_t oldi = i;
118
119             if(!bDescription)
120             {
121                 bDescription = !bDescription;
122
123                 //work backwards looking for a period
124                 while(i != lastwcpos && wildCard[--i] != '.') {}
125
126                 if(i == lastwcpos)
127                 {
128                     //no extension - can't use this wildcard
129                     lastwcpos = oldi;
130                     continue;
131                 }
132
133                 [m_wildcards addObject:wxNSStringWithWxString(wildCard.substr(i+1, oldi-i-1))];
134             }
135             else
136                 bDescription = !bDescription;
137             lastwcpos = oldi;
138         }
139
140         if (!bDescription)
141         {
142             //get last wildcard
143             size_t oldi = wildCard.length();
144             i = oldi;
145
146             //work backwards looking for a period
147             while(i != lastwcpos && wildCard[--i] != '.') {}
148
149             if(i != lastwcpos)
150                 [m_wildcards addObject:wxNSStringWithWxString(wildCard.substr(i+1, oldi-i-1))];
151         }
152
153         if ([m_wildcards count] == 0)
154         {
155             [m_wildcards release];
156             m_wildcards = nil;
157         }
158     }
159 }
160
161 wxFileDialog::~wxFileDialog()
162 {
163     [m_wildcards release];
164 }
165
166 void wxFileDialog::GetPaths(wxArrayString& paths) const
167 {
168     paths.Empty();
169
170     wxString dir(m_dir);
171     if ( m_dir.Last() != wxT('\\') )
172         dir += wxT('\\');
173
174     size_t count = m_fileNames.GetCount();
175     for ( size_t n = 0; n < count; n++ )
176     {
177         if (wxFileName(m_fileNames[n]).IsAbsolute())
178             paths.Add(m_fileNames[n]);
179         else
180             paths.Add(dir + m_fileNames[n]);
181     }
182 }
183
184 void wxFileDialog::GetFilenames(wxArrayString& files) const
185 {
186     files = m_fileNames;
187 }
188
189 void wxFileDialog::SetPath(const wxString& path)
190 {
191     wxString ext;
192     wxFileName::SplitPath(path, &m_dir, &m_fileName, &ext);
193     if ( !ext.empty() )
194         m_fileName << wxT('.') << ext;
195 }
196
197 int wxFileDialog::ShowModal()
198 {
199     WX_HOOK_MODAL_DIALOG();
200
201     wxAutoNSAutoreleasePool thePool;
202
203     m_fileNames.Empty();
204
205     int nResult;
206
207     if (HasFlag(wxFD_SAVE))
208     {
209         nResult = [GetNSSavePanel()
210                     runModalForDirectory:wxNSStringWithWxString(m_dir)
211                     file:wxNSStringWithWxString(m_fileName)];
212
213         if (nResult == NSOKButton)
214         {
215             m_fileNames.Add(wxStringWithNSString([GetNSSavePanel() filename]));
216             m_path = m_fileNames[0];
217         }
218     }
219     else //m_dialogStyle & wxFD_OPEN
220     {
221         nResult = [(NSOpenPanel*)m_cocoaNSWindow
222                     runModalForDirectory:wxNSStringWithWxString(m_dir)
223                     file:wxNSStringWithWxString(m_fileName)
224                     types:m_wildcards];
225
226         if (nResult == NSOKButton)
227         {
228             for(unsigned i = 0; i < [[(NSOpenPanel*)m_cocoaNSWindow filenames] count]; ++i)
229             {
230                 m_fileNames.Add(wxStringWithNSString([[(NSOpenPanel*)m_cocoaNSWindow filenames] objectAtIndex:(i)]));
231             }
232
233             m_path = m_fileNames[0];
234         }
235     }
236
237     return nResult == NSOKButton ? wxID_OK : wxID_CANCEL;
238 }
239
240 #endif // wxUSE_FILEDLG