1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/filepickercmn.cpp
3 // Purpose: wxFilePickerCtrl class implementation
4 // Author: Francesco Montorsi (readapted code written by Vadim Zeitlin)
5 // Modified by:
6 // Created: 15/04/2006
7 // Copyright: (c) Vadim Zeitlin, Francesco Montorsi
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21
22
23 #if wxUSE_FILEPICKERCTRL || wxUSE_DIRPICKERCTRL
24
25 #include "wx/filepicker.h"
26 #include "wx/filename.h"
27
28 #ifndef WX_PRECOMP
29 #include "wx/textctrl.h"
30 #endif
31
32 // ============================================================================
33 // implementation
34 // ============================================================================
35
36 const char wxFilePickerCtrlNameStr[] = "filepicker";
37 const char wxFilePickerWidgetNameStr[] = "filepickerwidget";
38 const char wxDirPickerCtrlNameStr[] = "dirpicker";
39 const char wxDirPickerWidgetNameStr[] = "dirpickerwidget";
40 const char wxFilePickerWidgetLabel[] = wxTRANSLATE("Browse");
41 const char wxDirPickerWidgetLabel[] = wxTRANSLATE("Browse");
42
43 wxDEFINE_EVENT( wxEVT_FILEPICKER_CHANGED, wxFileDirPickerEvent );
44 wxDEFINE_EVENT( wxEVT_DIRPICKER_CHANGED, wxFileDirPickerEvent );
45 wxIMPLEMENT_DYNAMIC_CLASS(wxFileDirPickerEvent, wxCommandEvent);
46
47 // ----------------------------------------------------------------------------
48 // wxFileDirPickerCtrlBase
49 // ----------------------------------------------------------------------------
50
CreateBase(wxWindow * parent,wxWindowID id,const wxString & path,const wxString & message,const wxString & wildcard,const wxPoint & pos,const wxSize & size,long style,const wxValidator & validator,const wxString & name)51 bool wxFileDirPickerCtrlBase::CreateBase(wxWindow *parent,
52 wxWindowID id,
53 const wxString &path,
54 const wxString &message,
55 const wxString &wildcard,
56 const wxPoint &pos,
57 const wxSize &size,
58 long style,
59 const wxValidator& validator,
60 const wxString &name )
61 {
62 if (!wxPickerBase::CreateBase(parent, id, path, pos, size,
63 style, validator, name))
64 return false;
65
66 if (!HasFlag(wxFLP_OPEN) && !HasFlag(wxFLP_SAVE))
67 m_windowStyle |= wxFLP_OPEN; // wxFD_OPEN is the default
68
69 // check that the styles are not contradictory
70 wxASSERT_MSG( !(HasFlag(wxFLP_SAVE) && HasFlag(wxFLP_OPEN)),
71 wxT("can't specify both wxFLP_SAVE and wxFLP_OPEN at once") );
72
73 wxASSERT_MSG( !HasFlag(wxFLP_SAVE) || !HasFlag(wxFLP_FILE_MUST_EXIST),
74 wxT("wxFLP_FILE_MUST_EXIST can't be used with wxFLP_SAVE" ) );
75
76 wxASSERT_MSG( !HasFlag(wxFLP_OPEN) || !HasFlag(wxFLP_OVERWRITE_PROMPT),
77 wxT("wxFLP_OVERWRITE_PROMPT can't be used with wxFLP_OPEN") );
78
79 // create a wxFilePickerWidget or a wxDirPickerWidget...
80 m_pickerIface = CreatePicker(this, path, message, wildcard);
81 if ( !m_pickerIface )
82 return false;
83 m_picker = m_pickerIface->AsControl();
84
85 // complete sizer creation
86 wxPickerBase::PostCreation();
87
88 DoConnect( m_picker, this );
89
90 // default's wxPickerBase textctrl limit is too small for this control:
91 // make it bigger
92 if (m_text) m_text->SetMaxLength(512);
93
94 return true;
95 }
96
GetPath() const97 wxString wxFileDirPickerCtrlBase::GetPath() const
98 {
99 return m_pickerIface->GetPath();
100 }
101
SetPath(const wxString & path)102 void wxFileDirPickerCtrlBase::SetPath(const wxString &path)
103 {
104 m_pickerIface->SetPath(path);
105 UpdateTextCtrlFromPicker();
106 }
107
UpdatePickerFromTextCtrl()108 void wxFileDirPickerCtrlBase::UpdatePickerFromTextCtrl()
109 {
110 wxASSERT(m_text);
111
112 // remove the eventually present path-separator from the end of the textctrl
113 // string otherwise we would generate a wxFileDirPickerEvent when changing
114 // from e.g. /home/user to /home/user/ and we want to avoid it !
115 wxString newpath(GetTextCtrlValue());
116
117 // Notice that we use to check here whether the current path is valid, i.e.
118 // if the corresponding file or directory exists for the controls with
119 // wxFLP_FILE_MUST_EXIST or wxDIRP_DIR_MUST_EXIST flag, however we don't do
120 // this any more as we still must notify the program about any changes in
121 // the control, otherwise its view of it would be different from what is
122 // actually shown on the screen, resulting in very confusing UI.
123
124 if (m_pickerIface->GetPath() != newpath)
125 {
126 m_pickerIface->SetPath(newpath);
127
128 // update current working directory, if necessary
129 // NOTE: the path separator is required because if newpath is "C:"
130 // then no change would happen
131 if (IsCwdToUpdate())
132 wxSetWorkingDirectory(newpath);
133
134 // fire an event
135 wxFileDirPickerEvent event(GetEventType(), this, GetId(), newpath);
136 GetEventHandler()->ProcessEvent(event);
137 }
138 }
139
UpdateTextCtrlFromPicker()140 void wxFileDirPickerCtrlBase::UpdateTextCtrlFromPicker()
141 {
142 if (!m_text)
143 return; // no textctrl to update
144
145 // Take care to use ChangeValue() here and not SetValue() to avoid
146 // generating an event that would trigger UpdateTextCtrlFromPicker()
147 // resulting in infinite recursion.
148 m_text->ChangeValue(m_pickerIface->GetPath());
149 }
150
151
152
153 // ----------------------------------------------------------------------------
154 // wxFileDirPickerCtrlBase - event handlers
155 // ----------------------------------------------------------------------------
156
OnFileDirChange(wxFileDirPickerEvent & ev)157 void wxFileDirPickerCtrlBase::OnFileDirChange(wxFileDirPickerEvent &ev)
158 {
159 UpdateTextCtrlFromPicker();
160
161 // the wxFilePickerWidget sent us a colour-change notification.
162 // forward this event to our parent
163 wxFileDirPickerEvent event(GetEventType(), this, GetId(), ev.GetPath());
164 GetEventHandler()->ProcessEvent(event);
165 }
166
167 #endif // wxUSE_FILEPICKERCTRL || wxUSE_DIRPICKERCTRL
168
169 // ----------------------------------------------------------------------------
170 // wxFileDirPickerCtrl
171 // ----------------------------------------------------------------------------
172
173 #if wxUSE_FILEPICKERCTRL
174
175 wxIMPLEMENT_DYNAMIC_CLASS(wxFilePickerCtrl, wxPickerBase);
176
Create(wxWindow * parent,wxWindowID id,const wxString & path,const wxString & message,const wxString & wildcard,const wxPoint & pos,const wxSize & size,long style,const wxValidator & validator,const wxString & name)177 bool wxFilePickerCtrl::Create(wxWindow *parent,
178 wxWindowID id,
179 const wxString& path,
180 const wxString& message,
181 const wxString& wildcard,
182 const wxPoint& pos,
183 const wxSize& size,
184 long style,
185 const wxValidator& validator,
186 const wxString& name)
187 {
188 if ( !wxFileDirPickerCtrlBase::CreateBase
189 (
190 parent, id, path, message, wildcard,
191 pos, size, style, validator, name
192 ) )
193 return false;
194
195 if ( HasTextCtrl() )
196 GetTextCtrl()->AutoCompleteFileNames();
197
198 return true;
199 }
200
GetTextCtrlValue() const201 wxString wxFilePickerCtrl::GetTextCtrlValue() const
202 {
203 wxCHECK_MSG( m_text, wxString(), "Can't be used if no text control" );
204
205 // filter it through wxFileName to remove any spurious path separator
206 return wxFileName(m_text->GetValue()).GetFullPath();
207 }
208
209 #endif // wxUSE_FILEPICKERCTRL
210
211 // ----------------------------------------------------------------------------
212 // wxDirPickerCtrl
213 // ----------------------------------------------------------------------------
214
215 #if wxUSE_DIRPICKERCTRL
216 wxIMPLEMENT_DYNAMIC_CLASS(wxDirPickerCtrl, wxPickerBase);
217
Create(wxWindow * parent,wxWindowID id,const wxString & path,const wxString & message,const wxPoint & pos,const wxSize & size,long style,const wxValidator & validator,const wxString & name)218 bool wxDirPickerCtrl::Create(wxWindow *parent,
219 wxWindowID id,
220 const wxString& path,
221 const wxString& message,
222 const wxPoint& pos,
223 const wxSize& size,
224 long style,
225 const wxValidator& validator,
226 const wxString& name)
227 {
228 if ( !wxFileDirPickerCtrlBase::CreateBase
229 (
230 parent, id, path, message, wxString(),
231 pos, size, style, validator, name
232 ) )
233 return false;
234
235 if ( HasTextCtrl() )
236 GetTextCtrl()->AutoCompleteDirectories();
237
238 return true;
239 }
240
GetTextCtrlValue() const241 wxString wxDirPickerCtrl::GetTextCtrlValue() const
242 {
243 wxCHECK_MSG( m_text, wxString(), "Can't be used if no text control" );
244
245 // filter it through wxFileName to remove any spurious path separator
246 return wxFileName::DirName(m_text->GetValue()).GetPath();
247 }
248
249 #endif // wxUSE_DIRPICKERCTRL
250