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