]> git.saurik.com Git - wxWidgets.git/blob - src/generic/filedlgg.cpp
defer queue-resize until after size-allocate processing, to keep it from being ignore...
[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
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 #if wxUSE_CONFIG
57 #include "wx/config.h"
58 #endif
59
60 #ifndef __WXWINCE__
61 #include <sys/types.h>
62 #include <sys/stat.h>
63 #endif
64
65 #ifdef __UNIX__
66 #include <dirent.h>
67 #include <pwd.h>
68 #ifndef __VMS
69 # include <grp.h>
70 #endif
71 #endif
72
73 #ifdef __WINDOWS__
74 #include "wx/msw/mslu.h"
75 #endif
76
77 #ifdef __WATCOMC__
78 #include <direct.h>
79 #endif
80
81 #ifndef __WXWINCE__
82 #include <time.h>
83 #endif
84
85 #if defined(__UNIX__) || defined(__DOS__)
86 #include <unistd.h>
87 #endif
88
89 #if defined(__WXWINCE__)
90 #define IsTopMostDir(dir) (dir == wxT("\\") || dir == wxT("/"))
91 #elif (defined(__DOS__) || defined(__WINDOWS__) || defined (__OS2__))
92 #define IsTopMostDir(dir) (dir.empty())
93 #else
94 #define IsTopMostDir(dir) (dir == wxT("/"))
95 #endif
96
97 //-----------------------------------------------------------------------------
98 // wxGenericFileDialog
99 //-----------------------------------------------------------------------------
100
101 #define ID_LIST_MODE (wxID_FILEDLGG )
102 #define ID_REPORT_MODE (wxID_FILEDLGG + 1)
103 #define ID_UP_DIR (wxID_FILEDLGG + 2)
104 #define ID_HOME_DIR (wxID_FILEDLGG + 3)
105 #define ID_NEW_DIR (wxID_FILEDLGG + 4)
106 #define ID_FILE_CTRL (wxID_FILEDLGG + 5)
107
108 IMPLEMENT_DYNAMIC_CLASS(wxGenericFileDialog, wxFileDialogBase)
109
110 BEGIN_EVENT_TABLE(wxGenericFileDialog,wxDialog)
111 EVT_BUTTON(ID_LIST_MODE, wxGenericFileDialog::OnList)
112 EVT_BUTTON(ID_REPORT_MODE, wxGenericFileDialog::OnReport)
113 EVT_BUTTON(ID_UP_DIR, wxGenericFileDialog::OnUp)
114 EVT_BUTTON(ID_HOME_DIR, wxGenericFileDialog::OnHome)
115 EVT_BUTTON(ID_NEW_DIR, wxGenericFileDialog::OnNew)
116 EVT_BUTTON(wxID_OK, wxGenericFileDialog::OnOk)
117 EVT_FILECTRL_FILEACTIVATED(ID_FILE_CTRL, wxGenericFileDialog::OnFileActivated)
118
119 EVT_UPDATE_UI(ID_UP_DIR, wxGenericFileDialog::OnUpdateButtonsUI)
120 #if defined(__DOS__) || defined(__WINDOWS__) || defined(__OS2__)
121 EVT_UPDATE_UI(ID_NEW_DIR, wxGenericFileDialog::OnUpdateButtonsUI)
122 #endif // defined(__DOS__) || defined(__WINDOWS__) || defined(__OS2__)
123 END_EVENT_TABLE()
124
125 long wxGenericFileDialog::ms_lastViewStyle = wxLC_LIST;
126 bool wxGenericFileDialog::ms_lastShowHidden = false;
127
128 void wxGenericFileDialog::Init()
129 {
130 m_bypassGenericImpl = false;
131
132 m_filectrl = NULL;
133 m_upDirButton = NULL;
134 m_newDirButton = NULL;
135 }
136
137 wxGenericFileDialog::wxGenericFileDialog(wxWindow *parent,
138 const wxString& message,
139 const wxString& defaultDir,
140 const wxString& defaultFile,
141 const wxString& wildCard,
142 long style,
143 const wxPoint& pos,
144 const wxSize& sz,
145 const wxString& name,
146 bool bypassGenericImpl ) : wxFileDialogBase()
147 {
148 Init();
149 Create( parent, message, defaultDir, defaultFile, wildCard, style, pos, sz, name, bypassGenericImpl );
150 }
151
152 bool wxGenericFileDialog::Create( wxWindow *parent,
153 const wxString& message,
154 const wxString& defaultDir,
155 const wxString& defaultFile,
156 const wxString& wildCard,
157 long style,
158 const wxPoint& pos,
159 const wxSize& sz,
160 const wxString& name,
161 bool bypassGenericImpl )
162 {
163 m_bypassGenericImpl = bypassGenericImpl;
164
165 parent = GetParentForModalDialog(parent, style);
166
167 if (!wxFileDialogBase::Create(parent, message, defaultDir, defaultFile,
168 wildCard, style, pos, sz, name))
169 {
170 return false;
171 }
172
173 if (m_bypassGenericImpl)
174 return true;
175
176 if (!wxDialog::Create( parent, wxID_ANY, message, pos, sz,
177 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | style, name
178 ))
179 {
180 return false;
181 }
182
183 #if wxUSE_CONFIG
184 if (wxConfig::Get(false))
185 {
186 wxConfig::Get()->Read(wxT("/wxWindows/wxFileDialog/ViewStyle"),
187 &ms_lastViewStyle);
188 wxConfig::Get()->Read(wxT("/wxWindows/wxFileDialog/ShowHidden"),
189 &ms_lastShowHidden);
190 }
191 #endif
192
193 if ((m_dir.empty()) || (m_dir == wxT(".")))
194 {
195 m_dir = wxGetCwd();
196 if (m_dir.empty())
197 m_dir = wxFILE_SEP_PATH;
198 }
199
200 const size_t len = m_dir.length();
201 if ((len > 1) && (wxEndsWithPathSeparator(m_dir)))
202 m_dir.Remove( len-1, 1 );
203
204 m_filterExtension = wxEmptyString;
205
206 // layout
207
208 const bool is_pda = (wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA);
209
210 wxBoxSizer *mainsizer = new wxBoxSizer( wxVERTICAL );
211
212 wxBoxSizer *buttonsizer = new wxBoxSizer( wxHORIZONTAL );
213 AddBitmapButton( ID_LIST_MODE, wxART_LIST_VIEW,
214 _("View files as a list view"), buttonsizer );
215 AddBitmapButton( ID_REPORT_MODE, wxART_REPORT_VIEW,
216 _("View files as a detailed view"), buttonsizer );
217 buttonsizer->Add( 30, 5, 1 );
218 m_upDirButton = AddBitmapButton( ID_UP_DIR, wxART_GO_DIR_UP,
219 _("Go to parent directory"), buttonsizer );
220
221 #ifndef __DOS__ // VS: Home directory is meaningless in MS-DOS...
222 AddBitmapButton( ID_HOME_DIR, wxART_GO_HOME,
223 _("Go to home directory"), buttonsizer );
224 buttonsizer->Add( 20, 20 );
225 #endif //!__DOS__
226
227 m_newDirButton = AddBitmapButton( ID_NEW_DIR, wxART_NEW_DIR,
228 _("Create new directory"), buttonsizer );
229
230 if (is_pda)
231 mainsizer->Add( buttonsizer, wxSizerFlags().Expand() );
232 else
233 mainsizer->Add( buttonsizer, wxSizerFlags().Expand()
234 .Border( wxLEFT | wxRIGHT | wxTOP ) );
235
236 long style2 = 0;
237 if ( HasFdFlag(wxFD_MULTIPLE) )
238 style2 |= wxFC_MULTIPLE;
239
240 m_filectrl = new wxGenericFileCtrl( this, ID_FILE_CTRL,
241 m_dir, defaultFile,
242 wildCard,
243 style2,
244 wxDefaultPosition, wxSize(540,200)
245 );
246
247 m_filectrl->ShowHidden( ms_lastShowHidden );
248
249 if (ms_lastViewStyle == wxLC_LIST)
250 {
251 m_filectrl->ChangeToListMode();
252 }
253 else if (ms_lastViewStyle == wxLC_REPORT)
254 {
255 m_filectrl->ChangeToReportMode();
256 }
257
258 mainsizer->Add(m_filectrl, wxSizerFlags(1).Expand().HorzBorder());
259
260 wxSizer *bsizer = CreateButtonSizer(wxOK | wxCANCEL);
261 if ( bsizer )
262 {
263 if (is_pda)
264 mainsizer->Add(bsizer, wxSizerFlags().Expand().Border());
265 else
266 mainsizer->Add(bsizer, wxSizerFlags().Expand().DoubleBorder());
267 }
268
269 SetSizer( mainsizer );
270
271 if (!is_pda)
272 {
273 mainsizer->SetSizeHints( this );
274
275 Centre( wxBOTH );
276 }
277
278 return true;
279 }
280
281 wxGenericFileDialog::~wxGenericFileDialog()
282 {
283 if (!m_bypassGenericImpl)
284 {
285 #if wxUSE_CONFIG
286 if (wxConfig::Get(false))
287 {
288 wxConfig::Get()->Write(wxT("/wxWindows/wxFileDialog/ViewStyle"),
289 ms_lastViewStyle);
290 wxConfig::Get()->Write(wxT("/wxWindows/wxFileDialog/ShowHidden"),
291 ms_lastShowHidden);
292 }
293 #endif
294 }
295 }
296
297 wxBitmapButton* wxGenericFileDialog::AddBitmapButton( wxWindowID winId,
298 const wxArtID& artId,
299 const wxString& tip,
300 wxSizer *sizer)
301 {
302 wxBitmapButton *but = new wxBitmapButton(this, winId,
303 wxArtProvider::GetBitmap(artId, wxART_BUTTON));
304 but->SetToolTip(tip);
305 sizer->Add(but, wxSizerFlags().Border());
306 return but;
307 }
308
309 int wxGenericFileDialog::ShowModal()
310 {
311 if (CreateExtraControl())
312 {
313 wxSizer *sizer = GetSizer();
314 sizer->Insert(2 /* after m_filectrl */, m_extraControl,
315 wxSizerFlags().Expand().HorzBorder());
316 sizer->Fit(this);
317 }
318
319 m_filectrl->SetDirectory(m_dir);
320
321 return wxDialog::ShowModal();
322 }
323
324 bool wxGenericFileDialog::Show( bool show )
325 {
326 // Called by ShowModal, so don't repeate the update
327 #ifndef __WIN32__
328 if (show)
329 {
330 m_filectrl->SetDirectory(m_dir);
331 }
332 #endif
333
334 return wxDialog::Show( show );
335 }
336
337 void wxGenericFileDialog::OnOk( wxCommandEvent &WXUNUSED(event) )
338 {
339 wxArrayString selectedFiles;
340 m_filectrl->GetFilenames(selectedFiles);
341
342 if (selectedFiles.Count() == 0)
343 return;
344
345 if (selectedFiles.Count() == 1)
346 {
347 SetPath( selectedFiles[0] );
348 }
349
350 EndModal(wxID_OK);
351 }
352
353 void wxGenericFileDialog::OnList( wxCommandEvent &WXUNUSED(event) )
354 {
355 m_filectrl->ChangeToListMode();
356 ms_lastViewStyle = wxLC_LIST;
357 m_filectrl->GetFileList()->SetFocus();
358 }
359
360 void wxGenericFileDialog::OnReport( wxCommandEvent &WXUNUSED(event) )
361 {
362 m_filectrl->ChangeToReportMode();
363 ms_lastViewStyle = wxLC_REPORT;
364 m_filectrl->GetFileList()->SetFocus();
365 }
366
367 void wxGenericFileDialog::OnUp( wxCommandEvent &WXUNUSED(event) )
368 {
369 m_filectrl->GoToParentDir();
370 m_filectrl->GetFileList()->SetFocus();
371 }
372
373 void wxGenericFileDialog::OnHome( wxCommandEvent &WXUNUSED(event) )
374 {
375 m_filectrl->GoToHomeDir();
376 m_filectrl->SetFocus();
377 }
378
379 void wxGenericFileDialog::OnNew( wxCommandEvent &WXUNUSED(event) )
380 {
381 m_filectrl->GetFileList()->MakeDir();
382 }
383
384 void wxGenericFileDialog::OnFileActivated( wxFileCtrlEvent &WXUNUSED(event) )
385 {
386 wxCommandEvent dummy;
387 OnOk( dummy );
388 }
389
390 void wxGenericFileDialog::OnUpdateButtonsUI(wxUpdateUIEvent& event)
391 {
392 // surprisingly, we can be called before m_filectrl is set in Create() as
393 // wxFileCtrl ctor itself can generate idle events, so we need this test
394 if ( m_filectrl )
395 event.Enable( !IsTopMostDir(m_filectrl->GetShownDirectory()) );
396 }
397
398 #ifdef wxHAS_GENERIC_FILEDIALOG
399
400 IMPLEMENT_DYNAMIC_CLASS(wxFileDialog, wxGenericFileDialog)
401
402 #endif // wxHAS_GENERIC_FILEDIALOG
403
404 #endif // wxUSE_FILEDLG