X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e65cc56a3b275ef24ab117dfcd84b75dd33ab66f..a4372af60a7eed11d0deea8db2c7d0fdd75d2b76:/src/generic/dirdlgg.cpp diff --git a/src/generic/dirdlgg.cpp b/src/generic/dirdlgg.cpp index f43ff6f7b5..ba118204be 100644 --- a/src/generic/dirdlgg.cpp +++ b/src/generic/dirdlgg.cpp @@ -4,8 +4,9 @@ // Author: Harm van der Heijden and Robert Roebling // Modified by: // Created: 12/12/98 +// RCS-ID: $Id$ // Copyright: (c) Harm van der Heijden and Robert Roebling -// Licence: wxWindows licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #ifdef __GNUG__ @@ -35,6 +36,12 @@ #include "wx/intl.h" #include "wx/imaglist.h" #include "wx/icon.h" +#include "wx/log.h" +#include "wx/sizer.h" + +#if wxUSE_STATLINE + #include "wx/statline.h" +#endif #include "wx/generic/dirdlgg.h" @@ -43,17 +50,18 @@ #undef GetFirstChild #endif +#ifndef __WXMSW__ /* XPM */ static char * icon1_xpm[] = { /* width height ncolors chars_per_pixel */ "16 16 6 1", /* colors */ -" s None c None", -". c #000000", -"+ c #c0c0c0", -"@ c #808080", -"# c #ffff00", -"$ c #ffffff", +" s None c None", +". c #000000", +"+ c #c0c0c0", +"@ c #808080", +"# c #ffff00", +"$ c #ffffff", /* pixels */ " ", " @@@@@ ", @@ -77,12 +85,12 @@ static char * icon2_xpm[] = { /* width height ncolors chars_per_pixel */ "16 16 6 1", /* colors */ -" s None c None", -". c #000000", -"+ c #c0c0c0", -"@ c #808080", -"# c #ffff00", -"$ c #ffffff", +" s None c None", +". c #000000", +"+ c #c0c0c0", +"@ c #808080", +"# c #ffff00", +"$ c #ffffff", /* pixels */ " ", " @@@@@ ", @@ -101,6 +109,8 @@ static char * icon2_xpm[] = { " ", " "}; +#endif // !wxMSW + static const int ID_DIRCTRL = 1000; static const int ID_TEXTCTRL = 1001; static const int ID_OK = 1002; @@ -112,73 +122,34 @@ static const int ID_NEW = 1004; // wxDirItemData //----------------------------------------------------------------------------- -class wxDirItemData : public wxTreeItemData -{ -public: - wxDirItemData(wxString& path, wxString& name); - ~wxDirItemData(); - bool HasSubDirs(); - wxString *m_path, *m_name; - bool m_isHidden; - bool m_hasSubDirs; -}; - -//----------------------------------------------------------------------------- -// wxDirCtrl -//----------------------------------------------------------------------------- - -class wxDirCtrl: public wxTreeCtrl +wxDirItemData::wxDirItemData(wxString& path, wxString& name) { - DECLARE_DYNAMIC_CLASS(wxDirCtrl) - - public: - bool m_showHidden; - wxTreeItemId m_rootId; - - wxDirCtrl(void); - wxDirCtrl(wxWindow *parent, const wxWindowID id = -1, - const wxString &dir = "/", - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - const long style = wxTR_HAS_BUTTONS, - const wxString& name = "wxTreeCtrl" ); - void OnExpandItem(wxTreeEvent &event ); - void OnCollapseItem(wxTreeEvent &event ); - void ShowHidden( const bool yesno ); - DECLARE_EVENT_TABLE() - protected: - void CreateItems(const wxTreeItemId &parent); - void SetupSections(void); - wxArrayString m_paths, m_names; -}; - -//----------------------------------------------------------------------------- -// wxDirItemData -//----------------------------------------------------------------------------- + m_path = path; + m_name = name; + /* Insert logic to detect hidden files here + * In UnixLand we just check whether the first char is a dot + * For FileNameFromPath read LastDirNameInThisPath ;-) */ + // m_isHidden = (bool)(wxFileNameFromPath(*m_path)[0] == '.'); + m_isHidden = FALSE; + m_hasSubDirs = HasSubDirs(); +} -wxDirItemData::wxDirItemData(wxString& path, wxString& name) +wxDirItemData::~wxDirItemData() { - m_path = new wxString(path); - m_name = new wxString(name); - /* Insert logic to detect hidden files here - * In UnixLand we just check whether the first char is a dot - * For FileNameFromPath read LastDirNameInThisPath ;-) */ - // m_isHidden = (bool)(wxFileNameFromPath(*m_path)[0] == '.'); - m_isHidden = FALSE; - m_hasSubDirs = HasSubDirs(); } -wxDirItemData:: ~wxDirItemData() +void wxDirItemData::SetNewDirName( wxString path ) { - delete m_path; - delete m_name; + m_path = path; + m_name = wxFileNameFromPath( path ); } bool wxDirItemData::HasSubDirs() { - wxString search = *m_path + "/*"; - wxString path = wxFindFirstFile( search, wxDIR ); - return (bool)(!path.IsNull()); + wxString search = m_path + wxT("/*"); + wxLogNull log; + wxString path = wxFindFirstFile( search, wxDIR ); + return (bool)(!path.IsNull()); } //----------------------------------------------------------------------------- @@ -190,12 +161,14 @@ IMPLEMENT_DYNAMIC_CLASS(wxDirCtrl,wxTreeCtrl) BEGIN_EVENT_TABLE(wxDirCtrl,wxTreeCtrl) EVT_TREE_ITEM_EXPANDING (-1, wxDirCtrl::OnExpandItem) EVT_TREE_ITEM_COLLAPSED (-1, wxDirCtrl::OnCollapseItem) + EVT_TREE_BEGIN_LABEL_EDIT (-1, wxDirCtrl::OnBeginEditItem) + EVT_TREE_END_LABEL_EDIT (-1, wxDirCtrl::OnEndEditItem) END_EVENT_TABLE() wxDirCtrl::wxDirCtrl(void) { - m_showHidden = FALSE; -}; + m_showHidden = FALSE; +} wxDirCtrl::wxDirCtrl(wxWindow *parent, const wxWindowID id, const wxString &WXUNUSED(dir), const wxPoint& pos, const wxSize& size, @@ -203,117 +176,191 @@ wxDirCtrl::wxDirCtrl(wxWindow *parent, const wxWindowID id, const wxString &WXUN : wxTreeCtrl( parent, id, pos, size, style, wxDefaultValidator, name ) { - m_imageListNormal = new wxImageList(16, 16, TRUE); - m_imageListNormal->Add(wxICON(icon1)); - m_imageListNormal->Add(wxICON(icon2)); - SetImageList(m_imageListNormal); - - m_showHidden = FALSE; - m_rootId = AddRoot("Sections"); - SetItemHasChildren(m_rootId); - Expand(m_rootId); // automatically expand first level -}; + #ifndef __WXMSW__ + m_imageListNormal = new wxImageList(16, 16, TRUE); + m_imageListNormal->Add(wxICON(icon1)); + m_imageListNormal->Add(wxICON(icon2)); + SetImageList(m_imageListNormal); + #endif + + m_showHidden = FALSE; + m_rootId = AddRoot( _("Sections") ); + SetItemHasChildren(m_rootId); + Expand(m_rootId); // automatically expand first level +} /* Quick macro. Don't worry, I'll #undef it later */ #define ADD_SECTION(a,b) \ if (wxPathExists((a))) { m_paths.Add( (a) ); m_names.Add( (b) ); }; -void wxDirCtrl::SetupSections() +void wxDirCtrl::SetupSections() { wxString home; m_paths.Clear(); m_names.Clear(); - ADD_SECTION(_T("/"), _("The Computer") ) +#ifdef __WXMSW__ + // better than nothing + ADD_SECTION(wxT("c:\\"), _("My Harddisk") ) +#else + ADD_SECTION(wxT("/"), _("The Computer") ) wxGetHomeDir(&home); ADD_SECTION(home, _("My Home") ) - ADD_SECTION(_T("/mnt"), _("Mounted Devices") ) - ADD_SECTION(_T("/usr"), _("User") ) - ADD_SECTION(_T("/usr/local"), _("User Local") ) - ADD_SECTION(_T("/var"), _("Variables") ) - ADD_SECTION(_T("/etc"), _("Etcetera") ) - ADD_SECTION(_T("/tmp"), _("Temporary") ) + ADD_SECTION(wxT("/mnt"), _("Mounted Devices") ) + ADD_SECTION(wxT("/usr"), _("User") ) + ADD_SECTION(wxT("/usr/local"), _("User Local") ) + ADD_SECTION(wxT("/var"), _("Variables") ) + ADD_SECTION(wxT("/etc"), _("Etcetera") ) + ADD_SECTION(wxT("/tmp"), _("Temporary") ) +#endif } #undef ADD_SECTION void wxDirCtrl::CreateItems(const wxTreeItemId &parent) { - wxTreeItemId id; - wxDirItemData *dir_item; + wxTreeItemId id; + wxDirItemData *dir_item; // wxASSERT(m_paths.Count() == m_names.Count()); ? - - for (unsigned int i=0; im_hasSubDirs) SetItemHasChildren(id); - } + + for (unsigned int i=0; im_hasSubDirs) SetItemHasChildren(id); + } } -void wxDirCtrl::OnExpandItem(wxTreeEvent &event ) +void wxDirCtrl::OnBeginEditItem(wxTreeEvent &event) { - if (event.GetItem() == m_rootId) - { - SetupSections(); - CreateItems(m_rootId); - return; - }; + // don't rename the main entry "Sections" + if (event.GetItem() == m_rootId) + { + event.Veto(); + return; + } + + // don't rename the individual sections + if (GetParent( event.GetItem() ) == m_rootId) + { + event.Veto(); + return; + } +} + +void wxDirCtrl::OnEndEditItem(wxTreeEvent &event) +{ + if ((event.GetLabel().IsEmpty()) || + (event.GetLabel() == _(".")) || + (event.GetLabel() == _("..")) || + (event.GetLabel().First( wxT("/") ) != wxNOT_FOUND)) + { + wxMessageDialog dialog(this, _("Illegal directory name."), _("Error"), wxOK | wxICON_ERROR ); + dialog.ShowModal(); + event.Veto(); + return; + } - // This may take a longish time. Go to busy cursor - wxBeginBusyCursor(); + wxTreeItemId id = event.GetItem(); + wxDirItemData *data = (wxDirItemData*)GetItemData( id ); + wxASSERT( data ); - wxDirItemData *data = (wxDirItemData *)GetItemData(event.GetItem()); - wxASSERT(data); + wxString new_name( wxPathOnly( data->m_path ) ); + new_name += wxT("/"); + new_name += event.GetLabel(); - wxString search,path,filename; + wxLogNull log; - m_paths.Clear(); - m_names.Clear(); - search = *(data->m_path) + "/*"; - for (path = wxFindFirstFile( search, wxDIR ); !path.IsNull(); - path=wxFindNextFile() ) { - filename = wxFileNameFromPath( path ); - /* Don't add "." and ".." to the tree. I think wxFindNextFile - * also checks this, but I don't quite understand what happens - * there. Also wxFindNextFile seems to swallow hidden dirs */ - if ((filename != ".") && (filename != "..")) { - m_paths.Add(path); - m_names.Add(filename); + if (wxFileExists(new_name)) + { + wxMessageDialog dialog(this, _("File name exists already."), _("Error"), wxOK | wxICON_ERROR ); + dialog.ShowModal(); + event.Veto(); + } + + if (wxRenameFile(data->m_path,new_name)) + { + data->SetNewDirName( new_name ); + } + else + { + wxMessageDialog dialog(this, _("Operation not permitted."), _("Error"), wxOK | wxICON_ERROR ); + dialog.ShowModal(); + event.Veto(); + } +} + +void wxDirCtrl::OnExpandItem(wxTreeEvent &event) +{ + if (event.GetItem() == m_rootId) + { + SetupSections(); + CreateItems(m_rootId); + return; + } + + // This may take a longish time. Go to busy cursor + wxBeginBusyCursor(); + + wxDirItemData *data = (wxDirItemData *)GetItemData(event.GetItem()); + wxASSERT(data); + + wxString search,path,filename; + + m_paths.Clear(); + m_names.Clear(); +#ifdef __WXMSW__ + search = data->m_path + "\\*.*"; +#else + search = data->m_path + "/*"; +#endif + for (path = wxFindFirstFile( search, wxDIR ); !path.IsNull(); + path=wxFindNextFile() ) + { + filename = wxFileNameFromPath( path ); + /* Don't add "." and ".." to the tree. I think wxFindNextFile + * also checks this, but I don't quite understand what happens + * there. Also wxFindNextFile seems to swallow hidden dirs */ + if ((filename != ".") && (filename != "..")) + { + m_paths.Add(path); + m_names.Add(filename); + } } - } - CreateItems(event.GetItem()); - wxEndBusyCursor(); - - SortChildren( event.GetItem() ); -}; + CreateItems( event.GetItem() ); + SortChildren( event.GetItem() ); + + wxEndBusyCursor(); +} void wxDirCtrl::OnCollapseItem(wxTreeEvent &event ) { - wxTreeItemId child, parent = event.GetItem(); - long cookie; - /* Workaround because DeleteChildren has disapeared (why?) and - * CollapseAndReset doesn't work as advertised (deletes parent too) */ - child = GetFirstChild(parent, cookie); - while (child.IsOk()) { - Delete(child); - /* Not GetNextChild below, because the cookie mechanism can't - * handle disappearing children! */ + wxTreeItemId child, parent = event.GetItem(); + long cookie; + /* Workaround because DeleteChildren has disapeared (why?) and + * CollapseAndReset doesn't work as advertised (deletes parent too) */ child = GetFirstChild(parent, cookie); - } -}; + while (child.IsOk()) + { + Delete(child); + /* Not GetNextChild below, because the cookie mechanism can't + * handle disappearing children! */ + child = GetFirstChild(parent, cookie); + } +} //----------------------------------------------------------------------------- // wxDirDialog //----------------------------------------------------------------------------- -#if !USE_SHARED_LIBRARY -IMPLEMENT_CLASS(wxDirDialog, wxDialog) -#else IMPLEMENT_DYNAMIC_CLASS( wxDirDialog, wxDialog ) -#endif BEGIN_EVENT_TABLE( wxDirDialog, wxDialog ) EVT_TREE_KEY_DOWN (ID_DIRCTRL, wxDirDialog::OnTreeKeyDown) @@ -327,115 +374,81 @@ BEGIN_EVENT_TABLE( wxDirDialog, wxDialog ) END_EVENT_TABLE() wxDirDialog::wxDirDialog(wxWindow *parent, const wxString& message, - const wxString& defaultPath, long style, - const wxPoint& pos) : + const wxString& defaultPath, long style, + const wxPoint& pos) : wxDialog(parent, -1, message, pos, wxSize(300,300), - wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) + wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) { - m_message = message; - m_dialogStyle = style; - m_parent = parent; - - m_path = defaultPath; - - m_dir = new wxDirCtrl( this, ID_DIRCTRL, "/", wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS | wxSUNKEN_BORDER ); - m_input = new wxTextCtrl( this, ID_TEXTCTRL, m_path, wxDefaultPosition ); - // m_check = new wxCheckBox( this, ID_CHECK, _("Show hidden") ); - m_ok = new wxButton( this, ID_OK, _("OK") ); - m_cancel = new wxButton( this, ID_CANCEL, _("Cancel"), wxDefaultPosition, wxSize(75,-1) ); - m_new = new wxButton( this, ID_NEW, _("New...") ); - - // m_check->SetValue(TRUE); - m_ok->SetDefault(); - m_dir->SetFocus(); - - doSize(); -} + m_message = message; + m_dialogStyle = style; + m_parent = parent; -void wxDirDialog::OnSize(wxSizeEvent& WXUNUSED(event)) -{ - doSize(); -} + m_path = defaultPath; -void wxDirDialog::doSize() -{ - /* Figure out height of DirCtrl, which is what is left over by - * the textctrl and the buttons. Manually, because I can't seem - * to get the constraints stuff to do this */ - int w,h,h2; - - GetClientSize(&w, &h); - m_input->GetSize(&w,&h2); h -= h2; - m_ok->GetSize(&w, &h2); h -= h2; - //m_check->GetSize(&w, &h2); h -= h2; - h -= 30; - - wxLayoutConstraints *c = new wxLayoutConstraints; - c->left.SameAs (this, wxLeft,5); - c->right.SameAs (this, wxRight,5); - c->height.Absolute (h); - c->top.SameAs (this, wxTop,5); - m_dir->SetConstraints(c); - - c = new wxLayoutConstraints; - c->left.SameAs (this, wxLeft,5); - c->right.SameAs (this, wxRight,5); - c->height.AsIs (); - c->top.Below (m_dir,5); - m_input->SetConstraints(c); - - /* c = new wxLayoutConstraints; - c->left.SameAs (this, wxLeft,5); - c->right.SameAs (this, wxRight,5); - c->height.AsIs (); - c->top.Below (m_input,5); - m_check->SetConstraints(c); */ - - c = new wxLayoutConstraints; - c->width.SameAs (m_cancel, wxWidth); - c->height.AsIs (); - c->top.Below (m_input,10); - c->centreX.PercentOf (this, wxWidth, 20); - m_ok->SetConstraints(c); - - c = new wxLayoutConstraints; - c->width.SameAs (m_cancel, wxWidth); - c->height.AsIs (); - c->top.Below (m_input,10); - c->bottom.SameAs (this, wxBottom, 5); - c->centreX.PercentOf (this, wxWidth, 50); - m_new->SetConstraints(c); - - c = new wxLayoutConstraints; - c->width.AsIs (); - c->height.AsIs (); - c->top.Below (m_input,10); - c->centreX.PercentOf (this, wxWidth, 80); - m_cancel->SetConstraints(c); - - Layout(); + wxBeginBusyCursor(); + + wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL ); + + // 1) dir ctrl + m_dir = new wxDirCtrl( this, ID_DIRCTRL, "/", wxDefaultPosition, wxSize(200,200), + wxTR_HAS_BUTTONS | wxSUNKEN_BORDER | wxTR_EDIT_LABELS); + topsizer->Add( m_dir, 1, wxTOP|wxLEFT|wxRIGHT | wxEXPAND, 10 ); + + // 2) text ctrl + m_input = new wxTextCtrl( this, ID_TEXTCTRL, m_path, wxDefaultPosition ); + topsizer->Add( m_input, 0, wxTOP|wxLEFT|wxRIGHT | wxEXPAND, 10 ); + + // m_check = new wxCheckBox( this, ID_CHECK, _("Show hidden") ); + // m_check->SetValue(TRUE); + +#if wxUSE_STATLINE + // 3) static line + topsizer->Add( new wxStaticLine( this, -1 ), 0, wxEXPAND | wxLEFT|wxRIGHT|wxTOP, 10 ); +#endif + + // 4) buttons + wxSizer* buttonsizer = new wxBoxSizer( wxHORIZONTAL ); + m_ok = new wxButton( this, ID_OK, _("OK") ); + buttonsizer->Add( m_ok, 0, wxLEFT|wxRIGHT, 10 ); + m_cancel = new wxButton( this, ID_CANCEL, _("Cancel") ); + buttonsizer->Add( m_cancel, 0, wxLEFT|wxRIGHT, 10 ); + m_new = new wxButton( this, ID_NEW, _("New...") ); + buttonsizer->Add( m_new, 0, wxLEFT|wxRIGHT, 10 ); + + topsizer->Add( buttonsizer, 0, wxALL | wxCENTER, 10 ); + + m_ok->SetDefault(); + m_dir->SetFocus(); + + SetAutoLayout( TRUE ); + SetSizer( topsizer ); + + topsizer->SetSizeHints( this ); + topsizer->Fit( this ); + + Centre( wxBOTH ); + + wxEndBusyCursor(); } int wxDirDialog::ShowModal() { - m_input->SetValue( m_path ); - return wxDialog::ShowModal(); + m_input->SetValue( m_path ); + return wxDialog::ShowModal(); } void wxDirDialog::OnTreeSelected( wxTreeEvent &event ) { - wxDirItemData *data = - (wxDirItemData*)m_dir->GetItemData(event.GetItem()); - if (data) - m_input->SetValue( *(data->m_path) ); + wxDirItemData *data = (wxDirItemData*)m_dir->GetItemData(event.GetItem()); + if (data) + m_input->SetValue( data->m_path ); }; void wxDirDialog::OnTreeKeyDown( wxTreeEvent &WXUNUSED(event) ) { - wxDirItemData *data = - (wxDirItemData*)m_dir->GetItemData(m_dir->GetSelection()); - if (data) - m_input->SetValue( *(data->m_path) ); + wxDirItemData *data = (wxDirItemData*)m_dir->GetItemData(m_dir->GetSelection()); + if (data) + m_input->SetValue( data->m_path ); }; void wxDirDialog::OnOK( wxCommandEvent& WXUNUSED(event) ) @@ -451,9 +464,10 @@ void wxDirDialog::OnOK( wxCommandEvent& WXUNUSED(event) ) wxString msg( _("The directory ") ); msg = msg + m_path; msg = msg + _("\ndoes not exist\nCreate it now?") ; - wxMessageDialog dialog(this, msg, _("Directory does not exist"), wxYES_NO); + wxMessageDialog dialog(this, msg, _("Directory does not exist"), wxYES_NO | wxICON_WARNING ); if ( dialog.ShowModal() == wxID_YES ) { // Okay, let's make it + wxLogNull log; if (wxMkdir(m_path)) { // The new dir was created okay. EndModal(wxID_OK); @@ -462,8 +476,8 @@ void wxDirDialog::OnOK( wxCommandEvent& WXUNUSED(event) ) else { // Trouble... msg = _("Failed to create directory ")+m_path+ - _("\n(Do you have the required permissions?)"); - wxMessageDialog errmsg(this, msg, _("Error creating directory"), wxOK); + _("\n(Do you have the required permissions?)"); + wxMessageDialog errmsg(this, msg, _("Error creating directory"), wxOK | wxICON_ERROR); errmsg.ShowModal(); // We still don't have a valid dir. Back to the main dialog. } @@ -478,24 +492,53 @@ void wxDirDialog::OnCancel( wxCommandEvent& WXUNUSED(event) ) void wxDirDialog::OnNew( wxCommandEvent& WXUNUSED(event) ) { - wxTextEntryDialog dialog(this, _("Enter the name of the directory to create"), - _("Create New Directory"), m_input->GetValue(), wxOK|wxCANCEL); + wxTreeItemId id = m_dir->GetSelection(); + if ((id == m_dir->GetRootItem()) || + (m_dir->GetParent(id) == m_dir->GetRootItem())) + { + wxMessageDialog msg(this, _("You cannot add a new directory to this section."), + _("Create directory"), wxOK | wxICON_INFORMATION ); + msg.ShowModal(); + return; + } - while (dialog.ShowModal() == wxID_OK) - { - // Okay, let's make it - if (wxMkdir(dialog.GetValue())) { - // The new dir was created okay. - m_path = dialog.GetValue(); - return; + wxTreeItemId parent = m_dir->GetParent( id ); + wxDirItemData *data = (wxDirItemData*)m_dir->GetItemData( parent ); + wxASSERT( data ); + + wxString new_name( wxT("NewName") ); + wxString path( data->m_path ); + path += wxT("/"); + path += new_name; + if (wxFileExists(path)) + { + // try NewName0, NewName1 etc. + int i = 0; + do { + new_name = wxT("NewName"); + wxString num; + num.Printf( wxT("%d"), i ); + new_name += num; + + path = data->m_path; + path += wxT("/"); + path += new_name; + i++; + } while (wxFileExists(path)); } - wxString msg = _("Failed to create directory ")+dialog.GetValue()+ - _("\n(Do you have the required permissions?)") ; - wxMessageDialog errmsg(this, msg, _("Error creating directory"), wxOK); - errmsg.ShowModal(); - // Show the create dialog again, until user clicks cancel or enters - // a valid dir. - } + + wxLogNull log; + if (!wxMkdir(path)) + { + wxMessageDialog dialog(this, _("Operation not permitted."), _("Error"), wxOK | wxICON_ERROR ); + dialog.ShowModal(); + return; + } + + wxDirItemData *new_data = new wxDirItemData( path, new_name ); + wxTreeItemId new_id = m_dir->AppendItem( parent, new_name, 0, 1, new_data ); + m_dir->EnsureVisible( new_id ); + m_dir->EditLabel( new_id ); } /*