1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/generic/dirdlgg.cpp
3 // Purpose: wxDirDialog
4 // Author: Harm van der Heijden, Robert Roebling & Julian Smart
7 // Copyright: (c) Harm van der Heijden, Robert Roebling, Julian Smart
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
21 #include "wx/textctrl.h"
22 #include "wx/button.h"
23 #include "wx/checkbox.h"
27 #include "wx/msgdlg.h"
28 #include "wx/bmpbuttn.h"
31 #include "wx/statline.h"
32 #include "wx/dirctrl.h"
33 #include "wx/generic/dirdlgg.h"
34 #include "wx/artprov.h"
37 // ----------------------------------------------------------------------------
39 // ----------------------------------------------------------------------------
41 static const int ID_DIRCTRL
= 1000;
42 static const int ID_TEXTCTRL
= 1001;
43 static const int ID_NEW
= 1004;
44 static const int ID_SHOW_HIDDEN
= 1005;
45 static const int ID_GO_HOME
= 1006;
47 //-----------------------------------------------------------------------------
49 //-----------------------------------------------------------------------------
51 IMPLEMENT_DYNAMIC_CLASS(wxGenericDirDialog
, wxDialog
)
53 BEGIN_EVENT_TABLE(wxGenericDirDialog
, wxDialog
)
54 EVT_CLOSE (wxGenericDirDialog::OnCloseWindow
)
55 EVT_BUTTON (wxID_OK
, wxGenericDirDialog::OnOK
)
56 EVT_BUTTON (ID_NEW
, wxGenericDirDialog::OnNew
)
57 EVT_BUTTON (ID_GO_HOME
, wxGenericDirDialog::OnGoHome
)
58 EVT_TREE_KEY_DOWN (wxID_ANY
, wxGenericDirDialog::OnTreeKeyDown
)
59 EVT_TREE_SEL_CHANGED (wxID_ANY
, wxGenericDirDialog::OnTreeSelected
)
60 EVT_TEXT_ENTER (ID_TEXTCTRL
, wxGenericDirDialog::OnOK
)
61 EVT_CHECKBOX (ID_SHOW_HIDDEN
, wxGenericDirDialog::OnShowHidden
)
64 wxGenericDirDialog::wxGenericDirDialog(wxWindow
* parent
, const wxString
& title
,
65 const wxString
& defaultPath
, long style
,
66 const wxPoint
& pos
, const wxSize
& sz
,
69 Create(parent
, title
, defaultPath
, style
, pos
, sz
, name
);
72 bool wxGenericDirDialog::Create(wxWindow
* parent
,
73 const wxString
& title
,
74 const wxString
& defaultPath
, long style
,
81 parent
= GetParentForModalDialog(parent
, style
);
83 if (!wxDirDialogBase::Create(parent
, title
, defaultPath
, style
, pos
, sz
, name
))
87 if (m_path
== wxT("~"))
88 wxGetHomeDir(&m_path
);
89 if (m_path
== wxT("."))
92 wxBoxSizer
*topsizer
= new wxBoxSizer( wxVERTICAL
);
94 // smartphones does not support or do not waste space for wxButtons
95 #if defined(__SMARTPHONE__)
97 wxMenu
*dirMenu
= new wxMenu
;
98 dirMenu
->Append(ID_GO_HOME
, _("Home"));
100 if (!HasFlag(wxDD_DIR_MUST_EXIST
))
102 dirMenu
->Append(ID_NEW
, _("New directory"));
105 dirMenu
->AppendCheckItem(ID_SHOW_HIDDEN
, _("Show hidden directories"));
106 dirMenu
->AppendSeparator();
107 dirMenu
->Append(wxID_CANCEL
, _("Cancel"));
111 // 0) 'New' and 'Home' Buttons
112 wxSizer
* buttonsizer
= new wxBoxSizer( wxHORIZONTAL
);
114 // VS: 'Home directory' concept is unknown to MS-DOS
115 #if !defined(__DOS__)
116 wxBitmapButton
* homeButton
=
117 new wxBitmapButton(this, ID_GO_HOME
,
118 wxArtProvider::GetBitmap(wxART_GO_HOME
, wxART_BUTTON
));
119 buttonsizer
->Add( homeButton
, 0, wxLEFT
|wxRIGHT
, 10 );
122 // I'm not convinced we need a New button, and we tend to get annoying
123 // accidental-editing with label editing enabled.
124 if (!HasFlag(wxDD_DIR_MUST_EXIST
))
126 wxBitmapButton
* newButton
=
127 new wxBitmapButton(this, ID_NEW
,
128 wxArtProvider::GetBitmap(wxART_NEW_DIR
, wxART_BUTTON
));
129 buttonsizer
->Add( newButton
, 0, wxRIGHT
, 10 );
131 newButton
->SetToolTip(_("Create new directory"));
136 homeButton
->SetToolTip(_("Go to home directory"));
139 topsizer
->Add( buttonsizer
, 0, wxTOP
| wxALIGN_RIGHT
, 10 );
141 #endif // __SMARTPHONE__/!__SMARTPHONE__
144 m_dirCtrl
= NULL
; // this is necessary, event handler called from
145 // wxGenericDirCtrl would crash otherwise!
146 long dirStyle
= wxDIRCTRL_DIR_ONLY
| wxDEFAULT_CONTROL_BORDER
;
149 if (!HasFlag(wxDD_DIR_MUST_EXIST
))
151 // Only under Windows do we need the wxTR_EDIT_LABEL tree control style
152 // before we can call EditLabel (required for "New directory")
153 dirStyle
|= wxDIRCTRL_EDIT_LABELS
;
157 m_dirCtrl
= new wxGenericDirCtrl(this, ID_DIRCTRL
,
158 m_path
, wxDefaultPosition
,
162 wxSizerFlags flagsBorder2
;
163 flagsBorder2
.DoubleBorder(wxTOP
| wxLEFT
| wxRIGHT
);
165 topsizer
->Add(m_dirCtrl
, wxSizerFlags(flagsBorder2
).Proportion(1).Expand());
167 #ifndef __SMARTPHONE__
168 // TODO: Make this an option depending on a flag?
170 check
= new wxCheckBox(this, ID_SHOW_HIDDEN
, _("Show &hidden directories"));
171 topsizer
->Add(check
, wxSizerFlags(flagsBorder2
).Right());
172 #endif // !__SMARTPHONE__
175 m_input
= new wxTextCtrl( this, ID_TEXTCTRL
, m_path
, wxDefaultPosition
);
176 topsizer
->Add(m_input
, wxSizerFlags(flagsBorder2
).Expand());
179 wxSizer
*buttonSizer
= CreateSeparatedButtonSizer(wxOK
| wxCANCEL
);
182 topsizer
->Add(buttonSizer
, wxSizerFlags().Expand().DoubleBorder());
185 #ifdef __SMARTPHONE__
186 // overwrite menu set by CreateSeparatedButtonSizer() call above
187 SetRightMenu(wxID_ANY
, _("Options"), dirMenu
);
192 SetAutoLayout( true );
193 SetSizer( topsizer
);
195 topsizer
->SetSizeHints( this );
196 topsizer
->Fit( this );
203 void wxGenericDirDialog::EndModal(int retCode
)
205 // before proceeding, change the current working directory if user asked so
206 if (retCode
== wxID_OK
&& HasFlag(wxDD_CHANGE_DIR
))
207 wxSetWorkingDirectory(m_path
);
209 wxDialog::EndModal(retCode
);
212 void wxGenericDirDialog::OnCloseWindow(wxCloseEvent
& WXUNUSED(event
))
214 EndModal(wxID_CANCEL
);
217 void wxGenericDirDialog::OnOK(wxCommandEvent
& WXUNUSED(event
))
219 m_path
= m_input
->GetValue();
221 // Does the path exist? (User may have typed anything in m_input)
222 if (wxDirExists(m_path
))
224 // OK, path exists, we're done.
229 // Interact with user, find out if the dir is a typo or to be created
231 msg
.Printf(_("The directory '%s' does not exist\nCreate it now?"),
233 wxMessageDialog
dialog(this, msg
, _("Directory does not exist"),
234 wxYES_NO
| wxICON_WARNING
);
236 if ( dialog
.ShowModal() == wxID_YES
)
238 // Okay, let's make it
242 // The new dir was created okay.
249 msg
.Printf(_("Failed to create directory '%s'\n(Do you have the required permissions?)"),
251 wxMessageDialog
errmsg(this, msg
, _("Error creating directory"), wxOK
| wxICON_ERROR
);
253 // We still don't have a valid dir. Back to the main dialog.
256 // User has answered NO to create dir.
259 void wxGenericDirDialog::SetPath(const wxString
& path
)
261 m_dirCtrl
->SetPath(path
);
265 wxString
wxGenericDirDialog::GetPath(void) const
270 int wxGenericDirDialog::ShowModal()
272 m_input
->SetValue( m_path
);
273 return wxDialog::ShowModal();
276 void wxGenericDirDialog::OnTreeSelected( wxTreeEvent
&event
)
281 wxTreeItemId item
= event
.GetItem();
283 wxDirItemData
*data
= NULL
;
286 data
= (wxDirItemData
*)m_dirCtrl
->GetTreeCtrl()->GetItemData(item
);
289 m_input
->SetValue( data
->m_path
);
292 void wxGenericDirDialog::OnTreeKeyDown( wxTreeEvent
&WXUNUSED(event
) )
297 wxDirItemData
*data
= (wxDirItemData
*)m_dirCtrl
->GetTreeCtrl()->GetItemData(m_dirCtrl
->GetTreeCtrl()->GetSelection());
299 m_input
->SetValue( data
->m_path
);
302 void wxGenericDirDialog::OnShowHidden( wxCommandEvent
& event
)
307 m_dirCtrl
->ShowHidden( event
.GetInt() != 0 );
310 void wxGenericDirDialog::OnNew( wxCommandEvent
& WXUNUSED(event
) )
312 wxTreeItemId id
= m_dirCtrl
->GetTreeCtrl()->GetSelection();
313 if ((id
== m_dirCtrl
->GetTreeCtrl()->GetRootItem()) ||
314 (m_dirCtrl
->GetTreeCtrl()->GetItemParent(id
) == m_dirCtrl
->GetTreeCtrl()->GetRootItem()))
316 wxMessageDialog
msg(this, _("You cannot add a new directory to this section."),
317 _("Create directory"), wxOK
| wxICON_INFORMATION
);
322 wxTreeItemId parent
= id
; // m_dirCtrl->GetTreeCtrl()->GetItemParent( id );
323 wxDirItemData
*data
= (wxDirItemData
*)m_dirCtrl
->GetTreeCtrl()->GetItemData( parent
);
326 wxString
new_name( _("NewName") );
327 wxString
path( data
->m_path
);
328 if (!wxEndsWithPathSeparator(path
))
329 path
+= wxFILE_SEP_PATH
;
331 if (wxDirExists(path
))
333 // try NewName0, NewName1 etc.
336 new_name
= _("NewName");
338 num
.Printf( wxT("%d"), i
);
342 if (!wxEndsWithPathSeparator(path
))
343 path
+= wxFILE_SEP_PATH
;
346 } while (wxDirExists(path
));
352 wxMessageDialog
dialog(this, _("Operation not permitted."), _("Error"), wxOK
| wxICON_ERROR
);
357 wxDirItemData
*new_data
= new wxDirItemData( path
, new_name
, true );
359 // TODO: THIS CODE DOESN'T WORK YET. We need to avoid duplication of the first child
361 wxTreeItemId new_id
= m_dirCtrl
->GetTreeCtrl()->AppendItem( parent
, new_name
, 0, 0, new_data
);
362 m_dirCtrl
->GetTreeCtrl()->EnsureVisible( new_id
);
363 m_dirCtrl
->GetTreeCtrl()->EditLabel( new_id
);
366 void wxGenericDirDialog::OnGoHome(wxCommandEvent
& WXUNUSED(event
))
368 SetPath(wxGetUserHome());
371 #endif // wxUSE_DIRDLG