]> git.saurik.com Git - wxWidgets.git/blame - src/generic/filedlgg.cpp
Add wxAnyScrollHelperBase to reduce code duplication in wxVarScrollHelperBase.
[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
8b17ba72 7// Copyright: (c) Robert Roebling
65571936 8// Licence: wxWindows licence
8b17ba72
RR
9/////////////////////////////////////////////////////////////////////////////
10
8b17ba72
RR
11// For compilers that support precompilation, includes "wx.h".
12#include "wx/wxprec.h"
13
14#ifdef __BORLANDC__
246c5004 15 #pragma hdrstop
8b17ba72
RR
16#endif
17
1db2c81b 18#if wxUSE_FILEDLG
1e6feb95 19
06cc1fb9 20// NOTE : it probably also supports MAC, untested
bd362275 21#if !defined(__UNIX__) && !defined(__DOS__) && !defined(__WIN32__) && !defined(__OS2__)
23254b13 22#error wxGenericFileDialog currently only supports Unix, win32 and DOS
8b17ba72
RR
23#endif
24
88a7a4e1 25#ifndef WX_PRECOMP
57bd4c60
WS
26 #ifdef __WXMSW__
27 #include "wx/msw/wrapwin.h"
28 #endif
88a7a4e1
WS
29 #include "wx/hash.h"
30 #include "wx/intl.h"
9eddec69 31 #include "wx/settings.h"
e7c80f9e 32 #include "wx/log.h"
246c5004 33 #include "wx/msgdlg.h"
910b0053 34 #include "wx/bmpbuttn.h"
ab1ce969 35 #include "wx/checkbox.h"
b36e08d0 36 #include "wx/choice.h"
ccdc11bb 37 #include "wx/stattext.h"
fec9cc08 38 #include "wx/textctrl.h"
ed2fbeb8 39 #include "wx/sizer.h"
949c9f74 40 #include "wx/filedlg.h" // wxFD_OPEN, wxFD_SAVE...
88a7a4e1
WS
41#endif
42
ec524671 43#include "wx/longlong.h"
eaf40b23 44#include "wx/config.h"
48fe8374 45#include "wx/imaglist.h"
60d2cc25 46#include "wx/artprov.h"
619111b9 47#include "wx/filefn.h"
0cf3e587 48#include "wx/filectrl.h"
94c47543 49#include "wx/generic/filedlgg.h"
0cf3e587 50#include "wx/debug.h"
691745ab 51#include "wx/modalhook.h"
8b17ba72 52
e6daf794
RR
53#if wxUSE_TOOLTIPS
54 #include "wx/tooltip.h"
55#endif
a85ad1db
VZ
56#if wxUSE_CONFIG
57 #include "wx/config.h"
58#endif
e6daf794 59
619111b9 60#ifndef __WXWINCE__
e7c80f9e
WS
61 #include <sys/types.h>
62 #include <sys/stat.h>
619111b9 63#endif
4894ae18
VS
64
65#ifdef __UNIX__
66 #include <dirent.h>
67 #include <pwd.h>
68 #ifndef __VMS
69 # include <grp.h>
70 #endif
71#endif
72
6a8c7c70 73#ifdef __WINDOWS__
6a8c7c70
VS
74 #include "wx/msw/mslu.h"
75#endif
76
4894ae18
VS
77#ifdef __WATCOMC__
78 #include <direct.h>
27df579a 79#endif
4894ae18 80
619111b9 81#ifndef __WXWINCE__
7a82dabc 82#include <time.h>
619111b9
JS
83#endif
84
099d4217 85#if defined(__UNIX__) || defined(__DOS__)
ac2def68 86#include <unistd.h>
099d4217 87#endif
8b17ba72 88
619111b9
JS
89#if defined(__WXWINCE__)
90#define IsTopMostDir(dir) (dir == wxT("\\") || dir == wxT("/"))
91#elif (defined(__DOS__) || defined(__WINDOWS__) || defined (__OS2__))
abc2a4cc 92#define IsTopMostDir(dir) (dir.empty())
70a7eb07
MW
93#else
94#define IsTopMostDir(dir) (dir == wxT("/"))
5e673a6a
VS
95#endif
96
8b17ba72 97//-----------------------------------------------------------------------------
23254b13 98// wxGenericFileDialog
8b17ba72
RR
99//-----------------------------------------------------------------------------
100
5e673a6a
VS
101#define ID_LIST_MODE (wxID_FILEDLGG )
102#define ID_REPORT_MODE (wxID_FILEDLGG + 1)
0cf3e587 103#define ID_UP_DIR (wxID_FILEDLGG + 2)
8ce68f7f 104#define ID_HOME_DIR (wxID_FILEDLGG + 3)
0cf3e587
VZ
105#define ID_NEW_DIR (wxID_FILEDLGG + 4)
106#define ID_FILE_CTRL (wxID_FILEDLGG + 5)
8b17ba72 107
f74172ab 108IMPLEMENT_DYNAMIC_CLASS(wxGenericFileDialog, wxFileDialogBase)
23254b13
JS
109
110BEGIN_EVENT_TABLE(wxGenericFileDialog,wxDialog)
0cf3e587
VZ
111 EVT_BUTTON(ID_LIST_MODE, wxGenericFileDialog::OnList)
112 EVT_BUTTON(ID_REPORT_MODE, wxGenericFileDialog::OnReport)
113 EVT_BUTTON(ID_UP_DIR, wxGenericFileDialog::OnUp)
8ce68f7f 114 EVT_BUTTON(ID_HOME_DIR, wxGenericFileDialog::OnHome)
0cf3e587
VZ
115 EVT_BUTTON(ID_NEW_DIR, wxGenericFileDialog::OnNew)
116 EVT_BUTTON(wxID_OK, wxGenericFileDialog::OnOk)
117 EVT_FILECTRL_FILEACTIVATED(ID_FILE_CTRL, wxGenericFileDialog::OnFileActivated)
e5dd66e9
VZ
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__)
8b17ba72
RR
123END_EVENT_TABLE()
124
23254b13 125long wxGenericFileDialog::ms_lastViewStyle = wxLC_LIST;
ca65c044 126bool wxGenericFileDialog::ms_lastShowHidden = false;
655cf310 127
fe6cf128
VZ
128void wxGenericFileDialog::Init()
129{
130 m_bypassGenericImpl = false;
131
0cf3e587 132 m_filectrl = NULL;
fe6cf128
VZ
133 m_upDirButton = NULL;
134 m_newDirButton = NULL;
135}
136
23254b13 137wxGenericFileDialog::wxGenericFileDialog(wxWindow *parent,
9cedab37
VZ
138 const wxString& message,
139 const wxString& defaultDir,
140 const wxString& defaultFile,
141 const wxString& wildCard,
fe6cf128 142 long style,
4e1901b7 143 const wxPoint& pos,
ff3e84ff
VZ
144 const wxSize& sz,
145 const wxString& name,
fe6cf128 146 bool bypassGenericImpl ) : wxFileDialogBase()
8b17ba72 147{
fe6cf128 148 Init();
ff3e84ff 149 Create( parent, message, defaultDir, defaultFile, wildCard, style, pos, sz, name, bypassGenericImpl );
4e1901b7
RR
150}
151
152bool wxGenericFileDialog::Create( wxWindow *parent,
abc2a4cc 153 const wxString& message,
fe6cf128 154 const wxString& defaultDir,
abc2a4cc
WS
155 const wxString& defaultFile,
156 const wxString& wildCard,
fe6cf128
VZ
157 long style,
158 const wxPoint& pos,
ff3e84ff
VZ
159 const wxSize& sz,
160 const wxString& name,
fe6cf128 161 bool bypassGenericImpl )
4e1901b7 162{
fe6cf128
VZ
163 m_bypassGenericImpl = bypassGenericImpl;
164
cdc48273 165 parent = GetParentForModalDialog(parent, style);
2229243b 166
7e4fb3b8 167 if (!wxFileDialogBase::Create(parent, message, defaultDir, defaultFile,
ff3e84ff 168 wildCard, style, pos, sz, name))
fe6cf128
VZ
169 {
170 return false;
171 }
172
173 if (m_bypassGenericImpl)
174 return true;
175
ff3e84ff 176 if (!wxDialog::Create( parent, wxID_ANY, message, pos, sz,
6a305cfb 177 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | style, name
c81c9392 178 ))
4e1901b7
RR
179 {
180 return false;
181 }
f74172ab 182
1a51ca33 183#if wxUSE_CONFIG
ca65c044 184 if (wxConfig::Get(false))
eaf40b23 185 {
e7d9c398 186 wxConfig::Get()->Read(wxT("/wxWindows/wxFileDialog/ViewStyle"),
9cedab37 187 &ms_lastViewStyle);
e7d9c398 188 wxConfig::Get()->Read(wxT("/wxWindows/wxFileDialog/ShowHidden"),
9cedab37 189 &ms_lastShowHidden);
eaf40b23 190 }
1a51ca33 191#endif
eaf40b23 192
353f41cb 193 if ((m_dir.empty()) || (m_dir == wxT(".")))
ac2def68 194 {
75ec8bd4 195 m_dir = wxGetCwd();
619111b9
JS
196 if (m_dir.empty())
197 m_dir = wxFILE_SEP_PATH;
ac2def68 198 }
7a82dabc 199
0cf3e587 200 const size_t len = m_dir.length();
083f7497 201 if ((len > 1) && (wxEndsWithPathSeparator(m_dir)))
353f41cb
RR
202 m_dir.Remove( len-1, 1 );
203
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 );
8ce68f7f
VZ
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 );
0b855868 217 buttonsizer->Add( 30, 5, 1 );
8ce68f7f
VZ
218 m_upDirButton = AddBitmapButton( ID_UP_DIR, wxART_GO_DIR_UP,
219 _("Go to parent directory"), buttonsizer );
c8c0e54c 220
37fd1c97 221#ifndef __DOS__ // VS: Home directory is meaningless in MS-DOS...
8ce68f7f
VZ
222 AddBitmapButton( ID_HOME_DIR, wxART_GO_HOME,
223 _("Go to home directory"), buttonsizer );
e6daf794 224 buttonsizer->Add( 20, 20 );
75ec8bd4 225#endif //!__DOS__
c8c0e54c 226
8ce68f7f
VZ
227 m_newDirButton = AddBitmapButton( ID_NEW_DIR, wxART_NEW_DIR,
228 _("Create new directory"), buttonsizer );
c8c0e54c 229
2b5f62a0 230 if (is_pda)
8ce68f7f 231 mainsizer->Add( buttonsizer, wxSizerFlags().Expand() );
c15521c6 232 else
8ce68f7f
VZ
233 mainsizer->Add( buttonsizer, wxSizerFlags().Expand()
234 .Border( wxLEFT | wxRIGHT | wxTOP ) );
c8c0e54c 235
0cf3e587
VZ
236 long style2 = 0;
237 if ( HasFdFlag(wxFD_MULTIPLE) )
238 style2 |= wxFC_MULTIPLE;
9c884972 239
0cf3e587
VZ
240 m_filectrl = new wxGenericFileCtrl( this, ID_FILE_CTRL,
241 m_dir, defaultFile,
242 wildCard,
243 style2,
244 wxDefaultPosition, wxSize(540,200)
245 );
9cedab37 246
0cf3e587 247 m_filectrl->ShowHidden( ms_lastShowHidden );
619111b9 248
0cf3e587
VZ
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 }
bd9f3519 257
8ce68f7f 258 mainsizer->Add(m_filectrl, wxSizerFlags(1).Expand().HorzBorder());
41fecb44 259
8ce68f7f
VZ
260 wxSizer *bsizer = CreateButtonSizer(wxOK | wxCANCEL);
261 if ( bsizer )
262 {
263 if (is_pda)
bd9f3519 264 mainsizer->Add(bsizer, wxSizerFlags().Expand().Border());
8ce68f7f
VZ
265 else
266 mainsizer->Add(bsizer, wxSizerFlags().Expand().DoubleBorder());
c15521c6 267 }
8b17ba72 268
8b17ba72 269 SetSizer( mainsizer );
c8c0e54c 270
619111b9
JS
271 if (!is_pda)
272 {
619111b9 273 mainsizer->SetSizeHints( this );
ed58dbea 274
619111b9
JS
275 Centre( wxBOTH );
276 }
c81c9392 277
4e1901b7 278 return true;
8b17ba72
RR
279}
280
23254b13 281wxGenericFileDialog::~wxGenericFileDialog()
cae5359f 282{
4e1901b7 283 if (!m_bypassGenericImpl)
eaf40b23 284 {
1a51ca33 285#if wxUSE_CONFIG
4e1901b7
RR
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 }
1a51ca33 293#endif
c5ef41d3 294 }
cae5359f
RR
295}
296
8ce68f7f
VZ
297wxBitmapButton* 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
23254b13 309int wxGenericFileDialog::ShowModal()
9cedab37 310{
691745ab 311 WX_HOOK_MODAL_DIALOG();
643e9cf9 312
8ce68f7f
VZ
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
0cf3e587 321 m_filectrl->SetDirectory(m_dir);
619111b9 322
9cedab37
VZ
323 return wxDialog::ShowModal();
324}
325
16dce3b3
RR
326bool wxGenericFileDialog::Show( bool show )
327{
619111b9
JS
328 // Called by ShowModal, so don't repeate the update
329#ifndef __WIN32__
16dce3b3
RR
330 if (show)
331 {
0cf3e587 332 m_filectrl->SetDirectory(m_dir);
16dce3b3 333 }
619111b9 334#endif
16dce3b3
RR
335
336 return wxDialog::Show( show );
337}
338
0cf3e587 339void wxGenericFileDialog::OnOk( wxCommandEvent &WXUNUSED(event) )
df413171 340{
0cf3e587
VZ
341 wxArrayString selectedFiles;
342 m_filectrl->GetFilenames(selectedFiles);
0b855868 343
0cf3e587 344 if (selectedFiles.Count() == 0)
c8c0e54c 345 return;
c8c0e54c 346
0cf3e587 347 if (selectedFiles.Count() == 1)
ed58dbea 348 {
0cf3e587 349 SetPath( selectedFiles[0] );
3f6638b8
VZ
350 }
351
b28a6678 352 EndModal(wxID_OK);
e1811a01
RR
353}
354
23254b13 355void wxGenericFileDialog::OnList( wxCommandEvent &WXUNUSED(event) )
8b17ba72 356{
0cf3e587 357 m_filectrl->ChangeToListMode();
9cedab37 358 ms_lastViewStyle = wxLC_LIST;
0cf3e587 359 m_filectrl->GetFileList()->SetFocus();
8b17ba72
RR
360}
361
23254b13 362void wxGenericFileDialog::OnReport( wxCommandEvent &WXUNUSED(event) )
8b17ba72 363{
0cf3e587 364 m_filectrl->ChangeToReportMode();
9cedab37 365 ms_lastViewStyle = wxLC_REPORT;
0cf3e587 366 m_filectrl->GetFileList()->SetFocus();
8b17ba72
RR
367}
368
23254b13 369void wxGenericFileDialog::OnUp( wxCommandEvent &WXUNUSED(event) )
8b17ba72 370{
0cf3e587
VZ
371 m_filectrl->GoToParentDir();
372 m_filectrl->GetFileList()->SetFocus();
8b17ba72
RR
373}
374
23254b13 375void wxGenericFileDialog::OnHome( wxCommandEvent &WXUNUSED(event) )
8b17ba72 376{
0cf3e587
VZ
377 m_filectrl->GoToHomeDir();
378 m_filectrl->SetFocus();
0b855868
RR
379}
380
23254b13 381void wxGenericFileDialog::OnNew( wxCommandEvent &WXUNUSED(event) )
0b855868 382{
0cf3e587
VZ
383 m_filectrl->GetFileList()->MakeDir();
384}
619111b9 385
0cf3e587
VZ
386void wxGenericFileDialog::OnFileActivated( wxFileCtrlEvent &WXUNUSED(event) )
387{
388 wxCommandEvent dummy;
389 OnOk( dummy );
8b17ba72
RR
390}
391
e5dd66e9 392void wxGenericFileDialog::OnUpdateButtonsUI(wxUpdateUIEvent& event)
06cc1fb9 393{
91a865a4
VZ
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 )
398eebb1 397 event.Enable( !IsTopMostDir(m_filectrl->GetShownDirectory()) );
06cc1fb9
JS
398}
399
b2f0b934 400#ifdef wxHAS_GENERIC_FILEDIALOG
655cf310 401
412e0d47 402IMPLEMENT_DYNAMIC_CLASS(wxFileDialog, wxGenericFileDialog)
655cf310 403
b2f0b934 404#endif // wxHAS_GENERIC_FILEDIALOG
23254b13 405
4e1901b7 406#endif // wxUSE_FILEDLG