]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/generic/filedlgg.cpp
fix bug with adding entries to a root group containing only subgroups (as shown by...
[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__)
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
105IMPLEMENT_DYNAMIC_CLASS(wxGenericFileDialog, wxFileDialogBase)
106
107BEGIN_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
116 EVT_UPDATE_UI(ID_UP_DIR, wxGenericFileDialog::OnUpdateButtonsUI)
117#if defined(__DOS__) || defined(__WINDOWS__) || defined(__OS2__)
118 EVT_UPDATE_UI(ID_NEW_DIR, wxGenericFileDialog::OnUpdateButtonsUI)
119#endif // defined(__DOS__) || defined(__WINDOWS__) || defined(__OS2__)
120END_EVENT_TABLE()
121
122long wxGenericFileDialog::ms_lastViewStyle = wxLC_LIST;
123bool wxGenericFileDialog::ms_lastShowHidden = false;
124
125void wxGenericFileDialog::Init()
126{
127 m_bypassGenericImpl = false;
128
129 m_filectrl = NULL;
130 m_upDirButton = NULL;
131 m_newDirButton = NULL;
132}
133
134wxGenericFileDialog::wxGenericFileDialog(wxWindow *parent,
135 const wxString& message,
136 const wxString& defaultDir,
137 const wxString& defaultFile,
138 const wxString& wildCard,
139 long style,
140 const wxPoint& pos,
141 const wxSize& sz,
142 const wxString& name,
143 bool bypassGenericImpl ) : wxFileDialogBase()
144{
145 Init();
146 Create( parent, message, defaultDir, defaultFile, wildCard, style, pos, sz, name, bypassGenericImpl );
147}
148
149bool wxGenericFileDialog::Create( wxWindow *parent,
150 const wxString& message,
151 const wxString& defaultDir,
152 const wxString& defaultFile,
153 const wxString& wildCard,
154 long style,
155 const wxPoint& pos,
156 const wxSize& sz,
157 const wxString& name,
158 bool bypassGenericImpl )
159{
160 m_bypassGenericImpl = bypassGenericImpl;
161
162 parent = GetParentForModalDialog(parent);
163
164 if (!wxFileDialogBase::Create(parent, message, defaultDir, defaultFile,
165 wildCard, style, pos, sz, name))
166 {
167 return false;
168 }
169
170 if (m_bypassGenericImpl)
171 return true;
172
173 if (!wxDialog::Create( parent, wxID_ANY, message, pos, sz,
174 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | style, name
175 ))
176 {
177 return false;
178 }
179
180#if wxUSE_CONFIG
181 if (wxConfig::Get(false))
182 {
183 wxConfig::Get()->Read(wxT("/wxWindows/wxFileDialog/ViewStyle"),
184 &ms_lastViewStyle);
185 wxConfig::Get()->Read(wxT("/wxWindows/wxFileDialog/ShowHidden"),
186 &ms_lastShowHidden);
187 }
188#endif
189
190 if ((m_dir.empty()) || (m_dir == wxT(".")))
191 {
192 m_dir = wxGetCwd();
193 if (m_dir.empty())
194 m_dir = wxFILE_SEP_PATH;
195 }
196
197 const size_t len = m_dir.length();
198 if ((len > 1) && (wxEndsWithPathSeparator(m_dir)))
199 m_dir.Remove( len-1, 1 );
200
201 m_filterExtension = wxEmptyString;
202
203 // layout
204
205 const bool is_pda = (wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA);
206
207 wxBoxSizer *mainsizer = new wxBoxSizer( wxVERTICAL );
208
209 wxBoxSizer *buttonsizer = new wxBoxSizer( wxHORIZONTAL );
210
211 wxBitmapButton *but;
212
213 but = new wxBitmapButton(this, ID_LIST_MODE,
214 wxArtProvider::GetBitmap(wxART_LIST_VIEW, wxART_BUTTON));
215#if wxUSE_TOOLTIPS
216 but->SetToolTip( _("View files as a list view") );
217#endif
218 buttonsizer->Add( but, 0, wxALL, 5 );
219
220 but = new wxBitmapButton(this, ID_REPORT_MODE,
221 wxArtProvider::GetBitmap(wxART_REPORT_VIEW, wxART_BUTTON));
222#if wxUSE_TOOLTIPS
223 but->SetToolTip( _("View files as a detailed view") );
224#endif
225 buttonsizer->Add( but, 0, wxALL, 5 );
226
227 buttonsizer->Add( 30, 5, 1 );
228
229 m_upDirButton = new wxBitmapButton(this, ID_UP_DIR,
230 wxArtProvider::GetBitmap(wxART_GO_DIR_UP, wxART_BUTTON));
231#if wxUSE_TOOLTIPS
232 m_upDirButton->SetToolTip( _("Go to parent directory") );
233#endif
234 buttonsizer->Add( m_upDirButton, 0, wxALL, 5 );
235
236#ifndef __DOS__ // VS: Home directory is meaningless in MS-DOS...
237 but = new wxBitmapButton(this, ID_PARENT_DIR,
238 wxArtProvider::GetBitmap(wxART_GO_HOME, wxART_BUTTON));
239#if wxUSE_TOOLTIPS
240 but->SetToolTip( _("Go to home directory") );
241#endif
242 buttonsizer->Add( but, 0, wxALL, 5);
243
244 buttonsizer->Add( 20, 20 );
245#endif //!__DOS__
246
247 m_newDirButton = new wxBitmapButton(this, ID_NEW_DIR,
248 wxArtProvider::GetBitmap(wxART_NEW_DIR, wxART_BUTTON));
249#if wxUSE_TOOLTIPS
250 m_newDirButton->SetToolTip( _("Create new directory") );
251#endif
252 buttonsizer->Add( m_newDirButton, 0, wxALL, 5 );
253
254 if (is_pda)
255 mainsizer->Add( buttonsizer, 0, wxALL | wxEXPAND, 0 );
256 else
257 mainsizer->Add( buttonsizer, 0, wxALL | wxEXPAND, 5 );
258
259 long style2 = 0;
260 if ( HasFdFlag(wxFD_MULTIPLE) )
261 style2 |= wxFC_MULTIPLE;
262
263 m_filectrl = new wxGenericFileCtrl( this, ID_FILE_CTRL,
264 m_dir, defaultFile,
265 wildCard,
266 style2,
267 wxDefaultPosition, wxSize(540,200)
268 );
269
270 m_filectrl->ShowHidden( ms_lastShowHidden );
271
272 if (ms_lastViewStyle == wxLC_LIST)
273 {
274 m_filectrl->ChangeToListMode();
275 }
276 else if (ms_lastViewStyle == wxLC_REPORT)
277 {
278 m_filectrl->ChangeToReportMode();
279 }
280
281 if (is_pda)
282 {
283 // PDAs have a different screen layout
284 mainsizer->Add(m_filectrl, wxSizerFlags(1).Expand().HorzBorder());
285
286 wxSizer *bsizer = CreateButtonSizer(wxOK | wxCANCEL);
287 if ( bsizer )
288 mainsizer->Add(bsizer, wxSizerFlags().Expand().Border());
289 }
290 else // !is_pda
291 {
292 mainsizer->Add(m_filectrl, wxSizerFlags(1).Expand().DoubleHorzBorder());
293
294 wxBoxSizer *okcancelsizer = new wxBoxSizer( wxHORIZONTAL );
295 okcancelsizer->Add(new wxButton(this, wxID_OK), wxSizerFlags().DoubleBorder().Centre());
296 okcancelsizer->Add(new wxButton(this, wxID_CANCEL), wxSizerFlags().DoubleBorder().Centre());
297 mainsizer->Add(okcancelsizer, wxSizerFlags().Center());
298 }
299
300 SetAutoLayout( true );
301 SetSizer( mainsizer );
302
303 if (!is_pda)
304 {
305 mainsizer->Fit( this );
306 mainsizer->SetSizeHints( this );
307
308 Centre( wxBOTH );
309 }
310
311 return true;
312}
313
314wxGenericFileDialog::~wxGenericFileDialog()
315{
316 if (!m_bypassGenericImpl)
317 {
318#if wxUSE_CONFIG
319 if (wxConfig::Get(false))
320 {
321 wxConfig::Get()->Write(wxT("/wxWindows/wxFileDialog/ViewStyle"),
322 ms_lastViewStyle);
323 wxConfig::Get()->Write(wxT("/wxWindows/wxFileDialog/ShowHidden"),
324 ms_lastShowHidden);
325 }
326#endif
327 }
328}
329
330int wxGenericFileDialog::ShowModal()
331{
332 m_filectrl->SetDirectory(m_dir);
333
334 return wxDialog::ShowModal();
335}
336
337bool wxGenericFileDialog::Show( bool show )
338{
339 // Called by ShowModal, so don't repeate the update
340#ifndef __WIN32__
341 if (show)
342 {
343 m_filectrl->SetDirectory(m_dir);
344 }
345#endif
346
347 return wxDialog::Show( show );
348}
349
350void wxGenericFileDialog::OnOk( wxCommandEvent &WXUNUSED(event) )
351{
352 wxArrayString selectedFiles;
353 m_filectrl->GetFilenames(selectedFiles);
354
355 if (selectedFiles.Count() == 0)
356 return;
357
358 if (selectedFiles.Count() == 1)
359 {
360 SetPath( selectedFiles[0] );
361 }
362
363 EndModal(wxID_OK);
364}
365
366void wxGenericFileDialog::OnList( wxCommandEvent &WXUNUSED(event) )
367{
368 m_filectrl->ChangeToListMode();
369 ms_lastViewStyle = wxLC_LIST;
370 m_filectrl->GetFileList()->SetFocus();
371}
372
373void wxGenericFileDialog::OnReport( wxCommandEvent &WXUNUSED(event) )
374{
375 m_filectrl->ChangeToReportMode();
376 ms_lastViewStyle = wxLC_REPORT;
377 m_filectrl->GetFileList()->SetFocus();
378}
379
380void wxGenericFileDialog::OnUp( wxCommandEvent &WXUNUSED(event) )
381{
382 m_filectrl->GoToParentDir();
383 m_filectrl->GetFileList()->SetFocus();
384}
385
386void wxGenericFileDialog::OnHome( wxCommandEvent &WXUNUSED(event) )
387{
388 m_filectrl->GoToHomeDir();
389 m_filectrl->SetFocus();
390}
391
392void wxGenericFileDialog::OnNew( wxCommandEvent &WXUNUSED(event) )
393{
394 m_filectrl->GetFileList()->MakeDir();
395}
396
397void wxGenericFileDialog::OnFileActivated( wxFileCtrlEvent &WXUNUSED(event) )
398{
399 wxCommandEvent dummy;
400 OnOk( dummy );
401}
402
403void wxGenericFileDialog::OnUpdateButtonsUI(wxUpdateUIEvent& event)
404{
405 // surprisingly, we can be called before m_filectrl is set in Create() as
406 // wxFileCtrl ctor itself can generate idle events, so we need this test
407 if ( m_filectrl )
408 event.Enable( !IsTopMostDir(m_filectrl->GetShownDirectory()) );
409}
410
411#ifdef wxHAS_GENERIC_FILEDIALOG
412
413IMPLEMENT_DYNAMIC_CLASS(wxFileDialog, wxGenericFileDialog)
414
415#endif // wxHAS_GENERIC_FILEDIALOG
416
417#endif // wxUSE_FILEDLG