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