]> git.saurik.com Git - wxWidgets.git/blob - src/generic/filedlgg.cpp
declare wxVector<wxXmlResourceHandler *> as DLL-exported to avoid VC++ warnings in...
[wxWidgets.git] / src / generic / filedlgg.cpp
1 //////////////////////////////////////////////////////////////////////////////
2 // Name: src/generic/filedlgg.cpp
3 // Purpose: wxGenericFileDialog
4 // Author: Robert Roebling
5 // Modified by:
6 // Created: 12/12/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Robert Roebling
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18
19 #if wxUSE_FILEDLG && (defined(__WXUNIVERSAL__) || defined(__WXGTK__))
20
21 // NOTE : it probably also supports MAC, untested
22 #if !defined(__UNIX__) && !defined(__DOS__) && !defined(__WIN32__) && !defined(__OS2__)
23 #error wxGenericFileDialog currently only supports Unix, win32 and DOS
24 #endif
25
26 #ifndef WX_PRECOMP
27 #ifdef __WXMSW__
28 #include "wx/msw/wrapwin.h"
29 #endif
30 #include "wx/hash.h"
31 #include "wx/intl.h"
32 #include "wx/settings.h"
33 #include "wx/log.h"
34 #include "wx/msgdlg.h"
35 #include "wx/bmpbuttn.h"
36 #include "wx/checkbox.h"
37 #include "wx/choice.h"
38 #include "wx/stattext.h"
39 #include "wx/textctrl.h"
40 #include "wx/sizer.h"
41 #include "wx/filedlg.h" // wxFD_OPEN, wxFD_SAVE...
42 #endif
43
44 #include "wx/longlong.h"
45 #include "wx/config.h"
46 #include "wx/imaglist.h"
47 #include "wx/artprov.h"
48 #include "wx/filefn.h"
49 #include "wx/filectrl.h"
50 #include "wx/generic/filedlgg.h"
51 #include "wx/debug.h"
52
53 #if wxUSE_TOOLTIPS
54 #include "wx/tooltip.h"
55 #endif
56
57 #ifndef __WXWINCE__
58 #include <sys/types.h>
59 #include <sys/stat.h>
60 #endif
61
62 #ifdef __UNIX__
63 #include <dirent.h>
64 #include <pwd.h>
65 #ifndef __VMS
66 # include <grp.h>
67 #endif
68 #endif
69
70 #ifdef __WINDOWS__
71 #include "wx/msw/mslu.h"
72 #endif
73
74 #ifdef __WATCOMC__
75 #include <direct.h>
76 #endif
77
78 #ifndef __WXWINCE__
79 #include <time.h>
80 #endif
81
82 #if defined(__UNIX__) || defined(__DOS__)
83 #include <unistd.h>
84 #endif
85
86 #if defined(__WXWINCE__)
87 #define IsTopMostDir(dir) (dir == wxT("\\") || dir == wxT("/"))
88 #elif (defined(__DOS__) || defined(__WINDOWS__) || defined (__OS2__))
89 #define IsTopMostDir(dir) (dir.empty())
90 #else
91 #define IsTopMostDir(dir) (dir == wxT("/"))
92 #endif
93
94 //-----------------------------------------------------------------------------
95 // wxGenericFileDialog
96 //-----------------------------------------------------------------------------
97
98 #define ID_LIST_MODE (wxID_FILEDLGG )
99 #define ID_REPORT_MODE (wxID_FILEDLGG + 1)
100 #define ID_UP_DIR (wxID_FILEDLGG + 2)
101 #define ID_PARENT_DIR (wxID_FILEDLGG + 3)
102 #define ID_NEW_DIR (wxID_FILEDLGG + 4)
103 #define ID_FILE_CTRL (wxID_FILEDLGG + 5)
104
105 IMPLEMENT_DYNAMIC_CLASS(wxGenericFileDialog, wxFileDialogBase)
106
107 BEGIN_EVENT_TABLE(wxGenericFileDialog,wxDialog)
108 EVT_BUTTON(ID_LIST_MODE, wxGenericFileDialog::OnList)
109 EVT_BUTTON(ID_REPORT_MODE, wxGenericFileDialog::OnReport)
110 EVT_BUTTON(ID_UP_DIR, wxGenericFileDialog::OnUp)
111 EVT_BUTTON(ID_PARENT_DIR, wxGenericFileDialog::OnHome)
112 EVT_BUTTON(ID_NEW_DIR, wxGenericFileDialog::OnNew)
113 EVT_BUTTON(wxID_OK, wxGenericFileDialog::OnOk)
114 EVT_FILECTRL_FILEACTIVATED(ID_FILE_CTRL, wxGenericFileDialog::OnFileActivated)
115 END_EVENT_TABLE()
116
117 long wxGenericFileDialog::ms_lastViewStyle = wxLC_LIST;
118 bool wxGenericFileDialog::ms_lastShowHidden = false;
119
120 void wxGenericFileDialog::Init()
121 {
122 m_bypassGenericImpl = false;
123
124 m_filectrl = NULL;
125 m_upDirButton = NULL;
126 m_newDirButton = NULL;
127 }
128
129 wxGenericFileDialog::wxGenericFileDialog(wxWindow *parent,
130 const wxString& message,
131 const wxString& defaultDir,
132 const wxString& defaultFile,
133 const wxString& wildCard,
134 long style,
135 const wxPoint& pos,
136 const wxSize& sz,
137 const wxString& name,
138 bool bypassGenericImpl ) : wxFileDialogBase()
139 {
140 Init();
141 Create( parent, message, defaultDir, defaultFile, wildCard, style, pos, sz, name, bypassGenericImpl );
142 }
143
144 bool wxGenericFileDialog::Create( wxWindow *parent,
145 const wxString& message,
146 const wxString& defaultDir,
147 const wxString& defaultFile,
148 const wxString& wildCard,
149 long style,
150 const wxPoint& pos,
151 const wxSize& sz,
152 const wxString& name,
153 bool bypassGenericImpl )
154 {
155 m_bypassGenericImpl = bypassGenericImpl;
156
157 parent = GetParentForModalDialog(parent);
158
159 if (!wxFileDialogBase::Create(parent, message, defaultDir, defaultFile,
160 wildCard, style, pos, sz, name))
161 {
162 return false;
163 }
164
165 if (m_bypassGenericImpl)
166 return true;
167
168 if (!wxDialog::Create( parent, wxID_ANY, message, pos, sz,
169 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | style, name
170 ))
171 {
172 return false;
173 }
174
175 #if wxUSE_CONFIG
176 if (wxConfig::Get(false))
177 {
178 wxConfig::Get()->Read(wxT("/wxWindows/wxFileDialog/ViewStyle"),
179 &ms_lastViewStyle);
180 wxConfig::Get()->Read(wxT("/wxWindows/wxFileDialog/ShowHidden"),
181 &ms_lastShowHidden);
182 }
183 #endif
184
185 if ((m_dir.empty()) || (m_dir == wxT(".")))
186 {
187 m_dir = wxGetCwd();
188 if (m_dir.empty())
189 m_dir = wxFILE_SEP_PATH;
190 }
191
192 const size_t len = m_dir.length();
193 if ((len > 1) && (wxEndsWithPathSeparator(m_dir)))
194 m_dir.Remove( len-1, 1 );
195
196 m_path = m_dir;
197 m_path += wxFILE_SEP_PATH;
198 m_path += defaultFile;
199 m_filterExtension = wxEmptyString;
200
201 // layout
202
203 const bool is_pda = (wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA);
204
205 wxBoxSizer *mainsizer = new wxBoxSizer( wxVERTICAL );
206
207 wxBoxSizer *buttonsizer = new wxBoxSizer( wxHORIZONTAL );
208
209 wxBitmapButton *but;
210
211 but = new wxBitmapButton(this, ID_LIST_MODE,
212 wxArtProvider::GetBitmap(wxART_LIST_VIEW, wxART_BUTTON));
213 #if wxUSE_TOOLTIPS
214 but->SetToolTip( _("View files as a list view") );
215 #endif
216 buttonsizer->Add( but, 0, wxALL, 5 );
217
218 but = new wxBitmapButton(this, ID_REPORT_MODE,
219 wxArtProvider::GetBitmap(wxART_REPORT_VIEW, wxART_BUTTON));
220 #if wxUSE_TOOLTIPS
221 but->SetToolTip( _("View files as a detailed view") );
222 #endif
223 buttonsizer->Add( but, 0, wxALL, 5 );
224
225 buttonsizer->Add( 30, 5, 1 );
226
227 m_upDirButton = new wxBitmapButton(this, ID_UP_DIR,
228 wxArtProvider::GetBitmap(wxART_GO_DIR_UP, wxART_BUTTON));
229 #if wxUSE_TOOLTIPS
230 m_upDirButton->SetToolTip( _("Go to parent directory") );
231 #endif
232 buttonsizer->Add( m_upDirButton, 0, wxALL, 5 );
233
234 #ifndef __DOS__ // VS: Home directory is meaningless in MS-DOS...
235 but = new wxBitmapButton(this, ID_PARENT_DIR,
236 wxArtProvider::GetBitmap(wxART_GO_HOME, wxART_BUTTON));
237 #if wxUSE_TOOLTIPS
238 but->SetToolTip( _("Go to home directory") );
239 #endif
240 buttonsizer->Add( but, 0, wxALL, 5);
241
242 buttonsizer->Add( 20, 20 );
243 #endif //!__DOS__
244
245 m_newDirButton = new wxBitmapButton(this, ID_NEW_DIR,
246 wxArtProvider::GetBitmap(wxART_NEW_DIR, wxART_BUTTON));
247 #if wxUSE_TOOLTIPS
248 m_newDirButton->SetToolTip( _("Create new directory") );
249 #endif
250 buttonsizer->Add( m_newDirButton, 0, wxALL, 5 );
251
252 if (is_pda)
253 mainsizer->Add( buttonsizer, 0, wxALL | wxEXPAND, 0 );
254 else
255 mainsizer->Add( buttonsizer, 0, wxALL | wxEXPAND, 5 );
256
257 long style2 = 0;
258 if ( HasFdFlag(wxFD_MULTIPLE) )
259 style2 |= wxFC_MULTIPLE;
260
261 m_filectrl = new wxGenericFileCtrl( this, ID_FILE_CTRL,
262 m_dir, defaultFile,
263 wildCard,
264 style2,
265 wxDefaultPosition, wxSize(540,200)
266 );
267
268 m_filectrl->ShowHidden( ms_lastShowHidden );
269
270 if (ms_lastViewStyle == wxLC_LIST)
271 {
272 m_filectrl->ChangeToListMode();
273 }
274 else if (ms_lastViewStyle == wxLC_REPORT)
275 {
276 m_filectrl->ChangeToReportMode();
277 }
278
279 if (is_pda)
280 {
281 // PDAs have a different screen layout
282 mainsizer->Add(m_filectrl, wxSizerFlags(1).Expand().HorzBorder());
283
284 wxSizer *bsizer = CreateButtonSizer(wxOK | wxCANCEL);
285 if ( bsizer )
286 mainsizer->Add(bsizer, wxSizerFlags().Expand().Border());
287 }
288 else // !is_pda
289 {
290 mainsizer->Add(m_filectrl, wxSizerFlags(1).Expand().DoubleHorzBorder());
291
292 wxBoxSizer *okcancelsizer = new wxBoxSizer( wxHORIZONTAL );
293 okcancelsizer->Add(new wxButton(this, wxID_OK), wxSizerFlags().DoubleBorder().Centre());
294 okcancelsizer->Add(new wxButton(this, wxID_CANCEL), wxSizerFlags().DoubleBorder().Centre());
295 mainsizer->Add(okcancelsizer, wxSizerFlags().Center());
296 }
297
298 SetAutoLayout( true );
299 SetSizer( mainsizer );
300
301 if (!is_pda)
302 {
303 mainsizer->Fit( this );
304 mainsizer->SetSizeHints( this );
305
306 Centre( wxBOTH );
307 }
308
309 return true;
310 }
311
312 wxGenericFileDialog::~wxGenericFileDialog()
313 {
314 if (!m_bypassGenericImpl)
315 {
316 #if wxUSE_CONFIG
317 if (wxConfig::Get(false))
318 {
319 wxConfig::Get()->Write(wxT("/wxWindows/wxFileDialog/ViewStyle"),
320 ms_lastViewStyle);
321 wxConfig::Get()->Write(wxT("/wxWindows/wxFileDialog/ShowHidden"),
322 ms_lastShowHidden);
323 }
324 #endif
325 }
326 }
327
328 int wxGenericFileDialog::ShowModal()
329 {
330 m_filectrl->SetDirectory(m_dir);
331 UpdateControls();
332
333 return wxDialog::ShowModal();
334 }
335
336 bool wxGenericFileDialog::Show( bool show )
337 {
338 // Called by ShowModal, so don't repeate the update
339 #ifndef __WIN32__
340 if (show)
341 {
342 m_filectrl->SetDirectory(m_dir);
343 UpdateControls();
344 }
345 #endif
346
347 return wxDialog::Show( show );
348 }
349
350 void wxGenericFileDialog::SetWildcard(const wxString& wildCard)
351 {
352 m_filectrl->SetWildcard(wildCard);
353 }
354
355 void wxGenericFileDialog::SetFilterIndex( int filterindex )
356 {
357 m_filectrl->SetFilterIndex(filterindex);
358 }
359
360 void wxGenericFileDialog::OnOk( wxCommandEvent &WXUNUSED(event) )
361 {
362 wxArrayString selectedFiles;
363 m_filectrl->GetFilenames(selectedFiles);
364
365 if (selectedFiles.Count() == 0)
366 return;
367
368 if (selectedFiles.Count() == 1)
369 {
370 SetPath( selectedFiles[0] );
371 }
372
373 EndModal(wxID_OK);
374 }
375
376 void wxGenericFileDialog::OnList( wxCommandEvent &WXUNUSED(event) )
377 {
378 m_filectrl->ChangeToListMode();
379 ms_lastViewStyle = wxLC_LIST;
380 m_filectrl->GetFileList()->SetFocus();
381 }
382
383 void wxGenericFileDialog::OnReport( wxCommandEvent &WXUNUSED(event) )
384 {
385 m_filectrl->ChangeToReportMode();
386 ms_lastViewStyle = wxLC_REPORT;
387 m_filectrl->GetFileList()->SetFocus();
388 }
389
390 void wxGenericFileDialog::OnUp( wxCommandEvent &WXUNUSED(event) )
391 {
392 m_filectrl->GoToParentDir();
393 m_filectrl->GetFileList()->SetFocus();
394 UpdateControls();
395 }
396
397 void wxGenericFileDialog::OnHome( wxCommandEvent &WXUNUSED(event) )
398 {
399 m_filectrl->GoToHomeDir();
400 m_filectrl->SetFocus();
401 UpdateControls();
402 }
403
404 void wxGenericFileDialog::OnNew( wxCommandEvent &WXUNUSED(event) )
405 {
406 m_filectrl->GetFileList()->MakeDir();
407 }
408
409 void wxGenericFileDialog::OnFileActivated( wxFileCtrlEvent &WXUNUSED(event) )
410 {
411 wxCommandEvent dummy;
412 OnOk( dummy );
413 }
414
415 void wxGenericFileDialog::SetPath( const wxString& path )
416 {
417 // not only set the full path but also update filename and dir
418 m_path = path;
419
420 m_filectrl->SetPath(path);
421 }
422
423 void wxGenericFileDialog::GetPaths( wxArrayString& paths ) const
424 {
425 m_filectrl->GetPaths(paths);
426 }
427
428 void wxGenericFileDialog::GetFilenames(wxArrayString& files) const
429 {
430 m_filectrl->GetFilenames(files);
431 }
432
433 void wxGenericFileDialog::UpdateControls()
434 {
435 const bool enable = !IsTopMostDir(m_filectrl->GetDirectory());
436 m_upDirButton->Enable(enable);
437
438 #if defined(__DOS__) || defined(__WINDOWS__) || defined(__OS2__)
439 m_newDirButton->Enable(enable);
440 #endif // defined(__DOS__) || defined(__WINDOWS__) || defined(__OS2__)
441 }
442
443 #ifdef wxHAS_GENERIC_FILEDIALOG
444
445 IMPLEMENT_DYNAMIC_CLASS(wxFileDialog, wxGenericFileDialog)
446
447 #endif // wxHAS_GENERIC_FILEDIALOG
448
449 #endif // wxUSE_FILEDLG