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