]>
git.saurik.com Git - wxWidgets.git/blob - src/generic/dirdlgg.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxDirDialog
4 // Author: Harm van der Heijden and Robert Roebling
7 // Copyright: (c) Harm van der Heijden and Robert Roebling
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
12 #pragma implementation "dirdlgg.h"
15 // For compilers that support precompilation, includes "wx.h".
16 #include "wx/wxprec.h"
27 #include "wx/dialog.h"
28 #include "wx/button.h"
29 #include "wx/layout.h"
30 #include "wx/msgdlg.h"
31 #include "wx/textdlg.h"
32 #include "wx/filefn.h"
33 #include "wx/cmndata.h"
34 #include "wx/gdicmn.h"
36 #include "wx/imaglist.h"
39 #include "wx/generic/dirdlgg.h"
41 // If compiled under Windows, this macro can cause problems
47 static char * icon1_xpm
[] = {
48 /* width height ncolors chars_per_pixel */
76 static char * icon2_xpm
[] = {
77 /* width height ncolors chars_per_pixel */
104 static const int ID_DIRCTRL
= 1000;
105 static const int ID_TEXTCTRL
= 1001;
106 static const int ID_OK
= 1002;
107 static const int ID_CANCEL
= 1003;
108 static const int ID_NEW
= 1004;
109 //static const int ID_CHECK = 1005;
111 //-----------------------------------------------------------------------------
113 //-----------------------------------------------------------------------------
115 class wxDirItemData
: public wxTreeItemData
118 wxDirItemData(wxString
& path
, wxString
& name
);
121 wxString
*m_path
, *m_name
;
126 //-----------------------------------------------------------------------------
128 //-----------------------------------------------------------------------------
130 class wxDirCtrl
: public wxTreeCtrl
132 DECLARE_DYNAMIC_CLASS(wxDirCtrl
)
136 wxTreeItemId m_rootId
;
139 wxDirCtrl(wxWindow
*parent
, const wxWindowID id
= -1,
140 const wxString
&dir
= "/",
141 const wxPoint
& pos
= wxDefaultPosition
,
142 const wxSize
& size
= wxDefaultSize
,
143 const long style
= wxTR_HAS_BUTTONS
,
144 const wxString
& name
= "wxTreeCtrl" );
145 void OnExpandItem(wxTreeEvent
&event
);
146 void OnCollapseItem(wxTreeEvent
&event
);
147 void ShowHidden( const bool yesno
);
148 DECLARE_EVENT_TABLE()
150 void CreateItems(const wxTreeItemId
&parent
);
151 void SetupSections(void);
152 wxArrayString m_paths
, m_names
;
155 //-----------------------------------------------------------------------------
157 //-----------------------------------------------------------------------------
159 wxDirItemData::wxDirItemData(wxString
& path
, wxString
& name
)
161 m_path
= new wxString(path
);
162 m_name
= new wxString(name
);
163 /* Insert logic to detect hidden files here
164 * In UnixLand we just check whether the first char is a dot
165 * For FileNameFromPath read LastDirNameInThisPath ;-) */
166 // m_isHidden = (bool)(wxFileNameFromPath(*m_path)[0] == '.');
168 m_hasSubDirs
= HasSubDirs();
171 wxDirItemData:: ~wxDirItemData()
177 bool wxDirItemData::HasSubDirs()
179 wxString search
= *m_path
+ "/*";
180 wxString path
= wxFindFirstFile( search
, wxDIR
);
181 return (bool)(!path
.IsNull());
184 //-----------------------------------------------------------------------------
186 //-----------------------------------------------------------------------------
188 IMPLEMENT_DYNAMIC_CLASS(wxDirCtrl
,wxTreeCtrl
)
190 BEGIN_EVENT_TABLE(wxDirCtrl
,wxTreeCtrl
)
191 EVT_TREE_ITEM_EXPANDING (-1, wxDirCtrl::OnExpandItem
)
192 EVT_TREE_ITEM_COLLAPSED (-1, wxDirCtrl::OnCollapseItem
)
195 wxDirCtrl::wxDirCtrl(void)
197 m_showHidden
= FALSE
;
200 wxDirCtrl::wxDirCtrl(wxWindow
*parent
, const wxWindowID id
, const wxString
&WXUNUSED(dir
),
201 const wxPoint
& pos
, const wxSize
& size
,
202 const long style
, const wxString
& name
)
204 wxTreeCtrl( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
)
206 m_imageListNormal
= new wxImageList(16, 16, TRUE
);
207 m_imageListNormal
->Add(wxICON(icon1
));
208 m_imageListNormal
->Add(wxICON(icon2
));
209 SetImageList(m_imageListNormal
);
211 m_showHidden
= FALSE
;
212 m_rootId
= AddRoot("Sections");
213 SetItemHasChildren(m_rootId
);
214 Expand(m_rootId
); // automatically expand first level
217 /* Quick macro. Don't worry, I'll #undef it later */
218 #define ADD_SECTION(a,b) \
219 if (wxPathExists((a))) { m_paths.Add( (a) ); m_names.Add( (b) ); };
221 void wxDirCtrl::SetupSections()
227 ADD_SECTION(_T("/"), _("The Computer") )
229 ADD_SECTION(home
, _("My Home") )
230 ADD_SECTION(_T("/mnt"), _("Mounted Devices") )
231 ADD_SECTION(_T("/usr"), _("User") )
232 ADD_SECTION(_T("/usr/local"), _("User Local") )
233 ADD_SECTION(_T("/var"), _("Variables") )
234 ADD_SECTION(_T("/etc"), _("Etcetera") )
235 ADD_SECTION(_T("/tmp"), _("Temporary") )
239 void wxDirCtrl::CreateItems(const wxTreeItemId
&parent
)
242 wxDirItemData
*dir_item
;
244 // wxASSERT(m_paths.Count() == m_names.Count()); ?
246 for (unsigned int i
=0; i
<m_paths
.Count(); i
++)
248 dir_item
= new wxDirItemData(m_paths
[i
],m_names
[i
]);
249 id
= AppendItem( parent
, m_names
[i
], 0, 1, dir_item
);
250 if (dir_item
->m_hasSubDirs
) SetItemHasChildren(id
);
254 void wxDirCtrl::OnExpandItem(wxTreeEvent
&event
)
256 if (event
.GetItem() == m_rootId
)
259 CreateItems(m_rootId
);
263 // This may take a longish time. Go to busy cursor
266 wxDirItemData
*data
= (wxDirItemData
*)GetItemData(event
.GetItem());
269 wxString search
,path
,filename
;
273 search
= *(data
->m_path
) + "/*";
274 for (path
= wxFindFirstFile( search
, wxDIR
); !path
.IsNull();
275 path
=wxFindNextFile() ) {
276 filename
= wxFileNameFromPath( path
);
277 /* Don't add "." and ".." to the tree. I think wxFindNextFile
278 * also checks this, but I don't quite understand what happens
279 * there. Also wxFindNextFile seems to swallow hidden dirs */
280 if ((filename
!= ".") && (filename
!= "..")) {
282 m_names
.Add(filename
);
285 CreateItems(event
.GetItem());
288 SortChildren( event
.GetItem() );
292 void wxDirCtrl::OnCollapseItem(wxTreeEvent
&event
)
294 wxTreeItemId child
, parent
= event
.GetItem();
296 /* Workaround because DeleteChildren has disapeared (why?) and
297 * CollapseAndReset doesn't work as advertised (deletes parent too) */
298 child
= GetFirstChild(parent
, cookie
);
299 while (child
.IsOk()) {
301 /* Not GetNextChild below, because the cookie mechanism can't
302 * handle disappearing children! */
303 child
= GetFirstChild(parent
, cookie
);
307 //-----------------------------------------------------------------------------
309 //-----------------------------------------------------------------------------
312 #if !USE_SHARED_LIBRARY
313 IMPLEMENT_CLASS(wxDirDialog
, wxDialog
)
315 IMPLEMENT_DYNAMIC_CLASS( wxDirDialog
, wxDialog
)
318 BEGIN_EVENT_TABLE( wxDirDialog
, wxDialog
)
319 EVT_TREE_KEY_DOWN (ID_DIRCTRL
, wxDirDialog::OnTreeKeyDown
)
320 EVT_TREE_SEL_CHANGED (ID_DIRCTRL
, wxDirDialog::OnTreeSelected
)
321 EVT_SIZE ( wxDirDialog::OnSize
)
322 EVT_BUTTON (ID_OK
, wxDirDialog::OnOK
)
323 EVT_BUTTON (ID_CANCEL
, wxDirDialog::OnCancel
)
324 EVT_BUTTON (ID_NEW
, wxDirDialog::OnNew
)
325 EVT_TEXT_ENTER (ID_TEXTCTRL
, wxDirDialog::OnOK
)
326 // EVT_CHECKBOX (ID_CHECK, wxDirDialog::OnCheck)
329 wxDirDialog::wxDirDialog(wxWindow
*parent
, const wxString
& message
,
330 const wxString
& defaultPath
, long style
,
331 const wxPoint
& pos
) :
332 wxDialog(parent
, -1, message
, pos
, wxSize(300,300),
333 wxDEFAULT_DIALOG_STYLE
| wxRESIZE_BORDER
)
336 m_dialogStyle
= style
;
339 m_path
= defaultPath
;
341 m_dir
= new wxDirCtrl( this, ID_DIRCTRL
, "/", wxDefaultPosition
, wxDefaultSize
, wxTR_HAS_BUTTONS
| wxSUNKEN_BORDER
);
342 m_input
= new wxTextCtrl( this, ID_TEXTCTRL
, m_path
, wxDefaultPosition
);
343 // m_check = new wxCheckBox( this, ID_CHECK, _("Show hidden") );
344 m_ok
= new wxButton( this, ID_OK
, _("OK") );
345 m_cancel
= new wxButton( this, ID_CANCEL
, _("Cancel"), wxDefaultPosition
, wxSize(75,-1) );
346 m_new
= new wxButton( this, ID_NEW
, _("New...") );
348 // m_check->SetValue(TRUE);
355 void wxDirDialog::OnSize(wxSizeEvent
& WXUNUSED(event
))
360 void wxDirDialog::doSize()
362 /* Figure out height of DirCtrl, which is what is left over by
363 * the textctrl and the buttons. Manually, because I can't seem
364 * to get the constraints stuff to do this */
367 GetClientSize(&w
, &h
);
368 m_input
->GetSize(&w
,&h2
); h
-= h2
;
369 m_ok
->GetSize(&w
, &h2
); h
-= h2
;
370 //m_check->GetSize(&w, &h2); h -= h2;
373 wxLayoutConstraints
*c
= new wxLayoutConstraints
;
374 c
->left
.SameAs (this, wxLeft
,5);
375 c
->right
.SameAs (this, wxRight
,5);
376 c
->height
.Absolute (h
);
377 c
->top
.SameAs (this, wxTop
,5);
378 m_dir
->SetConstraints(c
);
380 c
= new wxLayoutConstraints
;
381 c
->left
.SameAs (this, wxLeft
,5);
382 c
->right
.SameAs (this, wxRight
,5);
384 c
->top
.Below (m_dir
,5);
385 m_input
->SetConstraints(c
);
387 /* c = new wxLayoutConstraints;
388 c->left.SameAs (this, wxLeft,5);
389 c->right.SameAs (this, wxRight,5);
391 c->top.Below (m_input,5);
392 m_check->SetConstraints(c); */
394 c
= new wxLayoutConstraints
;
395 c
->width
.SameAs (m_cancel
, wxWidth
);
397 c
->top
.Below (m_input
,10);
398 c
->centreX
.PercentOf (this, wxWidth
, 20);
399 m_ok
->SetConstraints(c
);
401 c
= new wxLayoutConstraints
;
402 c
->width
.SameAs (m_cancel
, wxWidth
);
404 c
->top
.Below (m_input
,10);
405 c
->bottom
.SameAs (this, wxBottom
, 5);
406 c
->centreX
.PercentOf (this, wxWidth
, 50);
407 m_new
->SetConstraints(c
);
409 c
= new wxLayoutConstraints
;
412 c
->top
.Below (m_input
,10);
413 c
->centreX
.PercentOf (this, wxWidth
, 80);
414 m_cancel
->SetConstraints(c
);
419 int wxDirDialog::ShowModal()
421 m_input
->SetValue( m_path
);
422 return wxDialog::ShowModal();
425 void wxDirDialog::OnTreeSelected( wxTreeEvent
&event
)
427 wxDirItemData
*data
=
428 (wxDirItemData
*)m_dir
->GetItemData(event
.GetItem());
430 m_input
->SetValue( *(data
->m_path
) );
433 void wxDirDialog::OnTreeKeyDown( wxTreeEvent
&WXUNUSED(event
) )
435 wxDirItemData
*data
=
436 (wxDirItemData
*)m_dir
->GetItemData(m_dir
->GetSelection());
438 m_input
->SetValue( *(data
->m_path
) );
441 void wxDirDialog::OnOK( wxCommandEvent
& WXUNUSED(event
) )
443 m_path
= m_input
->GetValue();
444 // Does the path exist? (User may have typed anything in m_input)
445 if (wxPathExists(m_path
)) {
446 // OK, path exists, we're done.
450 // Interact with user, find out if the dir is a typo or to be created
451 wxString
msg( _("The directory ") );
453 msg
= msg
+ _("\ndoes not exist\nCreate it now?") ;
454 wxMessageDialog
dialog(this, msg
, _("Directory does not exist"), wxYES_NO
);
455 if ( dialog
.ShowModal() == wxID_YES
) {
456 // Okay, let's make it
457 if (wxMkdir(m_path
)) {
458 // The new dir was created okay.
464 msg
= _("Failed to create directory ")+m_path
+
465 _("\n(Do you have the required permissions?)");
466 wxMessageDialog
errmsg(this, msg
, _("Error creating directory"), wxOK
);
468 // We still don't have a valid dir. Back to the main dialog.
471 // User has answered NO to create dir.
474 void wxDirDialog::OnCancel( wxCommandEvent
& WXUNUSED(event
) )
476 EndModal(wxID_CANCEL
);
479 void wxDirDialog::OnNew( wxCommandEvent
& WXUNUSED(event
) )
481 wxTextEntryDialog
dialog(this, _("Enter the name of the directory to create"),
482 _("Create New Directory"), m_input
->GetValue(), wxOK
|wxCANCEL
);
484 while (dialog
.ShowModal() == wxID_OK
)
486 // Okay, let's make it
487 if (wxMkdir(dialog
.GetValue())) {
488 // The new dir was created okay.
489 m_path
= dialog
.GetValue();
492 wxString msg
= _("Failed to create directory ")+dialog
.GetValue()+
493 _("\n(Do you have the required permissions?)") ;
494 wxMessageDialog
errmsg(this, msg
, _("Error creating directory"), wxOK
);
496 // Show the create dialog again, until user clicks cancel or enters
502 void wxDirDialog::OnCheck( wxCommandEvent& WXUNUSED(event) )
504 printf("Checkbox clicked: %s\n", ( m_check->GetValue() ? "on" : "off" ) );