merged both implementations of wxGenericDirCtrl

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@13422 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Václav Slavík
2002-01-06 23:10:56 +00:00
parent e0fd69f760
commit 748fcded3c
5 changed files with 295 additions and 983 deletions

View File

@@ -27,8 +27,6 @@ WXDLLEXPORT_DATA(extern const wxChar*) wxEmptyString;
#include "wx/mac/dirdlg.h" #include "wx/mac/dirdlg.h"
#elif defined(__WXPM__) #elif defined(__WXPM__)
#include "wx/os2/dirdlg.h" #include "wx/os2/dirdlg.h"
#elif defined(__WXSTUBS__)
#include "wx/stubs/dirdlg.h"
#endif #endif
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -4,11 +4,11 @@
// Builds on wxDirCtrl class written by Robert Roebling for the // Builds on wxDirCtrl class written by Robert Roebling for the
// wxFile application, modified by Harm van der Heijden. // wxFile application, modified by Harm van der Heijden.
// Further modified for Windows. // Further modified for Windows.
// Author: Julian Smart et al // Author: Robert Roebling, Harm van der Heijden, Julian Smart et al
// Modified by: // Modified by:
// Created: 21/3/2000 // Created: 21/3/2000
// RCS-ID: $Id$ // RCS-ID: $Id$
// Copyright: (c) Julian Smart // Copyright: (c) Robert Roebling, Harm van der Heijden, Julian Smart
// Licence: wxWindows licence // Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@@ -22,6 +22,7 @@
#if wxUSE_DIRDLG #if wxUSE_DIRDLG
#include "wx/treectrl.h" #include "wx/treectrl.h"
#include "wx/dialog.h"
#include "wx/dirdlg.h" #include "wx/dirdlg.h"
#include "wx/choice.h" #include "wx/choice.h"
@@ -29,34 +30,42 @@
// classes // classes
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
class WXDLLEXPORT wxTextCtrl;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Extra styles for wxGenericDirCtrl // Extra styles for wxGenericDirCtrl
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Only allow directory viewing/selection, no files enum
#define wxDIRCTRL_DIR_ONLY 0x0010 {
// When setting the default path, select the first file in the directory // Only allow directory viewing/selection, no files
#define wxDIRCTRL_SELECT_FIRST 0x0020 wxDIRCTRL_DIR_ONLY = 0x0010,
// Show the filter list // When setting the default path, select the first file in the directory
#define wxDIRCTRL_SHOW_FILTERS 0x0040 wxDIRCTRL_SELECT_FIRST = 0x0020,
// Use 3D borders on internal controls // Show the filter list
#define wxDIRCTRL_3D_INTERNAL 0x0080 wxDIRCTRL_SHOW_FILTERS = 0x0040,
// Use 3D borders on internal controls
wxDIRCTRL_3D_INTERNAL = 0x0080
};
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// wxDirItemData // wxDirItemData
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
class WXDLLEXPORT wxDirItemDataEx : public wxTreeItemData class WXDLLEXPORT wxDirItemData : public wxTreeItemData
{ {
public: public:
wxDirItemDataEx(const wxString& path, const wxString& name, bool isDir); wxDirItemData(const wxString& path, const wxString& name, bool isDir);
~wxDirItemDataEx(); ~wxDirItemData();
void SetNewDirName( wxString path ); void SetNewDirName(const wxString& path);
wxString m_path, m_name;
bool m_isHidden; bool HasSubDirs() const;
bool m_hasSubDirs; bool HasFiles(const wxString& spec = wxEmptyString) const;
bool m_isExpanded;
bool m_isDir; wxString m_path, m_name;
bool m_isHidden;
bool m_isExpanded;
bool m_isDir;
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -127,7 +136,7 @@ public:
wxTreeCtrl* GetTreeCtrl() const { return m_treeCtrl; } wxTreeCtrl* GetTreeCtrl() const { return m_treeCtrl; }
wxDirFilterListCtrl* GetFilterListCtrl() const { return m_filterListCtrl; } wxDirFilterListCtrl* GetFilterListCtrl() const { return m_filterListCtrl; }
//// Helpers //// Helpers
void SetupSections(); void SetupSections();
// Parse the filter into an array of filters and an array of descriptions // Parse the filter into an array of filters and an array of descriptions
int ParseFilter(const wxString& filterStr, wxArrayString& filters, wxArrayString& descriptions); int ParseFilter(const wxString& filterStr, wxArrayString& filters, wxArrayString& descriptions);
@@ -190,10 +199,10 @@ public:
~wxDirFilterListCtrl() {}; ~wxDirFilterListCtrl() {};
//// Operations //// Operations
void FillFilterList(const wxString& filter, int defaultFilter); void FillFilterList(const wxString& filter, int defaultFilter);
//// Events //// Events
void OnSelFilter(wxCommandEvent& event); void OnSelFilter(wxCommandEvent& event);
protected: protected:
@@ -203,51 +212,9 @@ protected:
DECLARE_CLASS(wxDirFilterListCtrl) DECLARE_CLASS(wxDirFilterListCtrl)
}; };
#define wxID_TREECTRL 7000 #if !defined(__WXMSW__) && !defined(__WXMAC__) && !defined(__WXPM__)
#define wxID_FILTERLISTCTRL 7001 #define wxDirCtrl wxGenericDirCtrl
#endif
//-----------------------------------------------------------------------------
// wxGenericDirDialog
//
//-----------------------------------------------------------------------------
class wxGenericDirDialog: public wxDialog
{
DECLARE_EVENT_TABLE()
public:
wxGenericDirDialog(): wxDialog() {}
wxGenericDirDialog(wxWindow* parent, const wxString& title,
const wxString& defaultPath = wxEmptyString, long style = wxDEFAULT_DIALOG_STYLE, const wxPoint& pos = wxDefaultPosition, const wxSize& sz = wxSize(450, 550), const wxString& name = "dialog");
//// Event handlers
void OnCloseWindow(wxCloseEvent& event);
void OnOK(wxCommandEvent& event);
void OnTreeSelected( wxTreeEvent &event );
void OnTreeKeyDown( wxTreeEvent &event );
void OnNew(wxCommandEvent& event);
//// Accessors
inline void SetMessage(const wxString& message) { m_message = message; }
void SetPath(const wxString& path) ;
inline void SetStyle(long style) { m_dialogStyle = style; }
inline wxString GetMessage(void) const { return m_message; }
wxString GetPath(void) const ;
inline long GetStyle(void) const { return m_dialogStyle; }
wxTextCtrl* GetInputCtrl() const { return m_input; }
//// Overrides
int ShowModal();
protected:
wxString m_message;
long m_dialogStyle;
wxString m_path;
wxGenericDirCtrl* m_dirCtrl;
wxTextCtrl* m_input;
};
#endif // wxUSE_DIRDLG #endif // wxUSE_DIRDLG

View File

@@ -1,51 +1,15 @@
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Name: dirdlgg.h // Name: dirdlgg.h
// Purpose: wxDirDialog // Purpose: wxGenericDirCtrl class
// Author: Harm van der Heijden and Robert Roebling // Builds on wxDirCtrl class written by Robert Roebling for the
// wxFile application, modified by Harm van der Heijden.
// Further modified for Windows.
// Author: Robert Roebling, Harm van der Heijden, Julian Smart et al
// Modified by: // Modified by:
// Created: 12/12/98 // Created: 21/3/2000
// Copyright: (c) Harm van der Heijden and Robert Roebling
// RCS-ID: $Id$ // RCS-ID: $Id$
// Licence: wxWindows licence // Copyright: (c) Robert Roebling, Harm van der Heijden, Julian Smart
// // Licence: wxWindows licence
// Notes: wxDirDialog class written by Harm van der Heijden,
// uses wxDirCtrl class written by Robert Roebling for the
// wxFile application, modified by Harm van der Heijden
//
// Description: This generic dirdialog implementation defines three classes:
// 1) wxDirItemData(public wxTreeItemData) stores pathname and
// displayed name for each item in the directory tree
// 2) wxDirCtrl(public wxTreeCtrl) is a tree widget that
// displays a directory tree. It is possible to define sections
// for fast access to parts of the file system (such as the
// user's homedir, /usr/local, /tmp ...etc), similar to
// Win95 Explorer's shortcuts to 'My Computer', 'Desktop', etc.
// 3) wxDirDialog is the dialog box itself. The user can choose
// a directory by navigating the tree, or by typing a dir
// in an inputbox. The inputbox displays paths selected in the
// tree. It is possible to create new directories. The user
// will automatically be prompted for dir creation if he
// enters a non-existing dir.
//
// TODO/BUGS: - standard sections only have reasonable defaults for Unix
// (but others are easily added in wxDirCtrl::SetupSections)
// - No direct support for "show hidden" toggle. Partly due
// to laziness on my part and partly because
// wxFindFirst/NextFile never seems to find hidden dirs
// anyway.
// - No automatic update of the tree (branch) after directory
// creation.
// - I call wxBeginBusyCursor while expanding items (creating
// a new branch might take a few seconds, especially if a
// CDROM drive or something is involved) but that doesn't
// seem to do anything. Need to look into that.
// - Am still looking for an efficient way to delete wxTreeCtrl
// branches. DeleteChildren has disappeared and
// CollapseAndReset( parent ) deletes the parent as well.
// - The dialog window layout is done using wxConstraints. It
// works, but it's not as simple as I'd like it to be (see
// comments in wxDirDialog::doSize)
//
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
#ifndef _WX_DIRDLGG_H_ #ifndef _WX_DIRDLGG_H_
@@ -60,124 +24,60 @@
#if wxUSE_DIRDLG #if wxUSE_DIRDLG
#include "wx/dialog.h" #include "wx/dialog.h"
#include "wx/treectrl.h" class WXDLLEXPORT wxGenericDirCtrl;
class WXDLLEXPORT wxButton;
class WXDLLEXPORT wxCheckBox;
class WXDLLEXPORT wxTextCtrl; class WXDLLEXPORT wxTextCtrl;
class WXDLLEXPORT wxTreeEvent;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// data // wxGenericDirDialog
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
WXDLLEXPORT_DATA(extern const wxChar*) wxFileSelectorPromptStr; class wxGenericDirDialog: public wxDialog
WXDLLEXPORT_DATA(extern const wxChar*) wxDirDialogDefaultFolderStr;
//-----------------------------------------------------------------------------
// classes
//-----------------------------------------------------------------------------
class wxDirItemData;
class wxDirCtrl;
class wxDirDialog;
//-----------------------------------------------------------------------------
// wxDirItemData
//-----------------------------------------------------------------------------
class WXDLLEXPORT wxDirItemData : public wxTreeItemData
{ {
public: public:
wxDirItemData(wxString& path, wxString& name); wxGenericDirDialog(): wxDialog() {}
~wxDirItemData(); wxGenericDirDialog(wxWindow* parent, const wxString& title,
bool HasSubDirs(); const wxString& defaultPath = wxEmptyString,
void SetNewDirName( wxString path ); long style = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER,
wxString m_path, m_name; const wxPoint& pos = wxDefaultPosition,
bool m_isHidden; const wxSize& sz = wxSize(450, 550),
bool m_hasSubDirs; const wxString& name = _T("dialog"));
};
//----------------------------------------------------------------------------- //// Accessors
// wxDirCtrl
//-----------------------------------------------------------------------------
class WXDLLEXPORT wxDirCtrl: public wxTreeCtrl
{
public:
bool m_showHidden;
wxTreeItemId m_rootId;
wxDirCtrl();
wxDirCtrl(wxWindow *parent, const wxWindowID id = -1,
const wxString &dir = wxDirDialogDefaultFolderStr,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
const long style = wxTR_HAS_BUTTONS,
const wxString& name = wxTreeCtrlNameStr );
void ShowHidden( const bool yesno );
void OnExpandItem(wxTreeEvent &event );
void OnCollapseItem(wxTreeEvent &event );
void OnBeginEditItem(wxTreeEvent &event );
void OnEndEditItem(wxTreeEvent &event );
protected:
friend class wxDirDialog;
void CreateItems(const wxTreeItemId &parent);
void SetupSections();
wxArrayString m_paths, m_names;
private:
DECLARE_EVENT_TABLE()
DECLARE_DYNAMIC_CLASS(wxDirCtrl)
};
//-----------------------------------------------------------------------------
// wxDirDialog
//-----------------------------------------------------------------------------
class WXDLLEXPORT wxDirDialog: public wxDialog
{
public:
wxDirDialog() {}
wxDirDialog(wxWindow *parent,
const wxString& message = wxFileSelectorPromptStr,
const wxString& defaultPath = wxEmptyString,
long style = 0, const wxPoint& pos = wxDefaultPosition);
inline void SetMessage(const wxString& message) { m_message = message; } inline void SetMessage(const wxString& message) { m_message = message; }
inline void SetPath(const wxString& path) { m_path = path; } void SetPath(const wxString& path);
inline void SetStyle(long style) { m_dialogStyle = style; } inline void SetStyle(long style) { m_dialogStyle = style; }
inline wxString GetMessage() const { return m_message; } inline wxString GetMessage(void) const { return m_message; }
inline wxString GetPath() const { return m_path; } wxString GetPath(void) const;
inline long GetStyle() const { return m_dialogStyle; } inline long GetStyle(void) const { return m_dialogStyle; }
wxTextCtrl* GetInputCtrl() const { return m_input; }
//// Overrides
int ShowModal(); int ShowModal();
void OnTreeSelected( wxTreeEvent &event );
void OnTreeKeyDown( wxTreeEvent &event );
void OnOK(wxCommandEvent& event);
void OnCancel(wxCommandEvent& event);
void OnNew(wxCommandEvent& event);
// void OnCheck(wxCommandEvent& event);
protected: protected:
// implementation //// Event handlers
wxString m_message; void OnCloseWindow(wxCloseEvent& event);
long m_dialogStyle; void OnOK(wxCommandEvent& event);
wxString m_path; void OnTreeSelected(wxTreeEvent &event);
wxDirCtrl *m_dir; void OnTreeKeyDown(wxTreeEvent &event);
wxTextCtrl *m_input; void OnNew(wxCommandEvent& event);
wxCheckBox *m_check; // not yet used
wxButton *m_ok, *m_cancel, *m_new; wxString m_message;
long m_dialogStyle;
wxString m_path;
wxGenericDirCtrl* m_dirCtrl;
wxTextCtrl* m_input;
private:
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
DECLARE_DYNAMIC_CLASS(wxDirDialog)
}; };
#if !defined(__WXMSW__) && !defined(__WXMAC__) && !defined(__WXPM__)
#define wxDirDialog wxGenericDirDialog
#endif #endif
#endif #endif // wxUSE_DIRDLG
// _WX_DIRDLGG_H_
#endif // _WX_DIRDLGG_H_

View File

@@ -311,14 +311,15 @@ static char * icon8_xpm[] = {
" ", " ",
" "}; " "};
static const int ID_DIRCTRL = 1000;
static const int ID_TEXTCTRL = 1001;
static const int ID_OK = 1002;
static const int ID_CANCEL = 1003;
static const int ID_NEW = 1004;
//static const int ID_CHECK = 1005;
#if defined(__WXMSW__) || defined(__WXPM__) || defined(__DOS__) #define wxID_TREECTRL 7000
#define wxID_FILTERLISTCTRL 7001
#if defined(__DOS__)
#ifdef __DJGPP__
#define setdrive(drive) setdisk(drive)
#endif
#elif defined(__WXMSW__) || defined(__WXPM__)
int setdrive(int drive) int setdrive(int drive)
{ {
#if defined(__GNUWIN32__) && \ #if defined(__GNUWIN32__) && \
@@ -394,11 +395,11 @@ static int LINKAGEMODE wxDirCtrlStringCompareFunction(const void *first, const v
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// wxDirItemDataEx // wxDirItemData
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
wxDirItemDataEx::wxDirItemDataEx(const wxString& path, const wxString& name, wxDirItemData::wxDirItemData(const wxString& path, const wxString& name,
bool isDir) bool isDir)
{ {
m_path = path; m_path = path;
m_name = name; m_name = name;
@@ -407,20 +408,48 @@ wxDirItemDataEx::wxDirItemDataEx(const wxString& path, const wxString& name,
* For FileNameFromPath read LastDirNameInThisPath ;-) */ * For FileNameFromPath read LastDirNameInThisPath ;-) */
// m_isHidden = (bool)(wxFileNameFromPath(*m_path)[0] == '.'); // m_isHidden = (bool)(wxFileNameFromPath(*m_path)[0] == '.');
m_isHidden = FALSE; m_isHidden = FALSE;
// m_hasSubDirs is no longer needed
m_hasSubDirs = TRUE; // HasSubDirs();
m_isExpanded = FALSE; m_isExpanded = FALSE;
m_isDir = isDir; m_isDir = isDir;
} }
wxDirItemDataEx::~wxDirItemDataEx() wxDirItemData::~wxDirItemData()
{ {
} }
void wxDirItemDataEx::SetNewDirName( wxString path ) void wxDirItemData::SetNewDirName(const wxString& path)
{ {
m_path = path; m_path = path;
m_name = wxFileNameFromPath( path ); m_name = wxFileNameFromPath(path);
}
bool wxDirItemData::HasSubDirs() const
{
if (m_path.IsEmpty())
return FALSE;
wxDir dir;
{
wxLogNull nolog;
if ( !dir.Open(m_path) )
return FALSE;
}
return dir.HasSubDirs();
}
bool wxDirItemData::HasFiles(const wxString& spec) const
{
if (m_path.IsEmpty())
return FALSE;
wxDir dir;
{
wxLogNull nolog;
if ( !dir.Open(m_path) )
return FALSE;
}
return dir.HasFiles();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -443,14 +472,14 @@ wxGenericDirCtrl::wxGenericDirCtrl(void)
} }
bool wxGenericDirCtrl::Create(wxWindow *parent, bool wxGenericDirCtrl::Create(wxWindow *parent,
const wxWindowID id, const wxWindowID id,
const wxString& dir, const wxString& dir,
const wxPoint& pos, const wxPoint& pos,
const wxSize& size, const wxSize& size,
long style, long style,
const wxString& filter, const wxString& filter,
int defaultFilter, int defaultFilter,
const wxString& name ) const wxString& name)
{ {
if (!wxControl::Create(parent, id, pos, size, style, wxDefaultValidator, name)) if (!wxControl::Create(parent, id, pos, size, style, wxDefaultValidator, name))
return FALSE; return FALSE;
@@ -459,7 +488,7 @@ bool wxGenericDirCtrl::Create(wxWindow *parent,
Init(); Init();
long treeStyle = wxTR_HAS_BUTTONS ; // | wxTR_EDIT_LABELS; long treeStyle = wxTR_HAS_BUTTONS | wxTR_EDIT_LABELS | wxTR_HIDE_ROOT;
if ((style & wxDIRCTRL_3D_INTERNAL) == 0) if ((style & wxDIRCTRL_3D_INTERNAL) == 0)
treeStyle |= wxNO_BORDER; treeStyle |= wxNO_BORDER;
@@ -489,10 +518,10 @@ bool wxGenericDirCtrl::Create(wxWindow *parent,
m_imageList->Add(wxIcon(icon6_xpm)); m_imageList->Add(wxIcon(icon6_xpm));
m_imageList->Add(wxIcon(icon7_xpm)); m_imageList->Add(wxIcon(icon7_xpm));
m_imageList->Add(wxIcon(icon8_xpm)); m_imageList->Add(wxIcon(icon8_xpm));
m_treeCtrl->SetImageList(m_imageList); m_treeCtrl->AssignImageList(m_imageList);
m_showHidden = FALSE; m_showHidden = FALSE;
wxDirItemDataEx* rootData = new wxDirItemDataEx(wxT(""), wxT(""), TRUE); wxDirItemData* rootData = new wxDirItemData(wxT(""), wxT(""), TRUE);
wxString rootName; wxString rootName;
@@ -517,8 +546,6 @@ bool wxGenericDirCtrl::Create(wxWindow *parent,
wxGenericDirCtrl::~wxGenericDirCtrl() wxGenericDirCtrl::~wxGenericDirCtrl()
{ {
m_treeCtrl->SetImageList(NULL);
delete m_imageList;
} }
void wxGenericDirCtrl::Init() void wxGenericDirCtrl::Init()
@@ -533,17 +560,9 @@ void wxGenericDirCtrl::Init()
void wxGenericDirCtrl::AddSection(const wxString& path, const wxString& name, int imageId) void wxGenericDirCtrl::AddSection(const wxString& path, const wxString& name, int imageId)
{ {
wxDirItemDataEx *dir_item = new wxDirItemDataEx(path,name,TRUE); wxDirItemData *dir_item = new wxDirItemData(path,name,TRUE);
#if defined(__WXMSW__) || defined(__WXPM__)
// Windows and OS/2: sections are displayed as drives
wxTreeItemId id = m_treeCtrl->AppendItem( m_rootId, name, imageId, -1, dir_item); wxTreeItemId id = m_treeCtrl->AppendItem( m_rootId, name, imageId, -1, dir_item);
#else
// Unix: sections are displayed as folders
wxTreeItemId id = m_treeCtrl->AppendItem( m_rootId, name, 0, -1, dir_item);
m_treeCtrl->SetItemImage( id, 1, wxTreeItemIcon_Expanded );
#endif
// TODO: other operating systems.
m_treeCtrl->SetItemHasChildren(id); m_treeCtrl->SetItemHasChildren(id);
} }
@@ -552,7 +571,7 @@ void wxGenericDirCtrl::SetupSections()
{ {
#if defined(__WXMSW__) || defined(__WXPM__) #if defined(__WXMSW__) || defined(__WXPM__)
# ifdef __WIN32__ #ifdef __WIN32__
wxChar driveBuffer[256]; wxChar driveBuffer[256];
size_t n = (size_t) GetLogicalDriveStrings(255, driveBuffer); size_t n = (size_t) GetLogicalDriveStrings(255, driveBuffer);
size_t i = 0; size_t i = 0;
@@ -624,14 +643,7 @@ void wxGenericDirCtrl::SetupSections()
AddSection(name + wxFILE_SEP_PATH, name, 0); AddSection(name + wxFILE_SEP_PATH, name, 0);
} }
#else #else
AddSection(wxT("/"), _("The Computer"), 0); AddSection(wxT("/"), wxT("/"), 3/*computer icon*/);
AddSection(wxGetHomeDir(), _("My Home"), 0 );
AddSection(wxT("/mnt"), _("Mounted Devices"), 0 );
AddSection(wxT("/usr/local"), _("User Local"), 0 );
AddSection(wxT("/usr"), _("User"), 0 );
AddSection(wxT("/var"), _("Variables"), 0 );
AddSection(wxT("/etc"), _("Etcetera"), 0 );
AddSection(wxT("/tmp"), _("Temporary"), 0 );
#endif #endif
} }
@@ -666,7 +678,7 @@ void wxGenericDirCtrl::OnEndEditItem(wxTreeEvent &event)
} }
wxTreeItemId id = event.GetItem(); wxTreeItemId id = event.GetItem();
wxDirItemDataEx *data = (wxDirItemDataEx*)m_treeCtrl->GetItemData( id ); wxDirItemData *data = (wxDirItemData*)m_treeCtrl->GetItemData( id );
wxASSERT( data ); wxASSERT( data );
wxString new_name( wxPathOnly( data->m_path ) ); wxString new_name( wxPathOnly( data->m_path ) );
@@ -698,6 +710,11 @@ void wxGenericDirCtrl::OnExpandItem(wxTreeEvent &event)
{ {
wxTreeItemId parentId = event.GetItem(); wxTreeItemId parentId = event.GetItem();
// VS: this is needed because the event handler is called from wxTreeCtrl
// ctor when wxTR_HIDE_ROOT was specified
if (m_rootId == 0)
m_rootId = m_treeCtrl->GetRootItem();
ExpandDir(parentId); ExpandDir(parentId);
} }
@@ -705,7 +722,7 @@ void wxGenericDirCtrl::OnCollapseItem(wxTreeEvent &event )
{ {
wxTreeItemId child, parent = event.GetItem(); wxTreeItemId child, parent = event.GetItem();
wxDirItemDataEx *data = (wxDirItemDataEx *) m_treeCtrl->GetItemData(event.GetItem()); wxDirItemData *data = (wxDirItemData *) m_treeCtrl->GetItemData(event.GetItem());
if (!data->m_isExpanded) if (!data->m_isExpanded)
return; return;
@@ -725,14 +742,14 @@ void wxGenericDirCtrl::OnCollapseItem(wxTreeEvent &event )
void wxGenericDirCtrl::ExpandDir(wxTreeItemId parentId) void wxGenericDirCtrl::ExpandDir(wxTreeItemId parentId)
{ {
wxDirItemDataEx *data = (wxDirItemDataEx *) m_treeCtrl->GetItemData(parentId); wxDirItemData *data = (wxDirItemData *) m_treeCtrl->GetItemData(parentId);
if (data->m_isExpanded) if (data->m_isExpanded)
return; return;
data->m_isExpanded = TRUE; data->m_isExpanded = TRUE;
if (parentId == m_rootId) if (parentId == m_treeCtrl->GetRootItem())
{ {
SetupSections(); SetupSections();
return; return;
@@ -774,7 +791,7 @@ void wxGenericDirCtrl::ExpandDir(wxTreeItemId parentId)
if (d.IsOpened()) if (d.IsOpened())
{ {
if (d.GetFirst(& eachFilename, wxEmptyString, wxDIR_DIRS)) if (d.GetFirst(& eachFilename, wxEmptyString, wxDIR_DIRS | wxDIR_HIDDEN))
{ {
do do
{ {
@@ -783,7 +800,7 @@ void wxGenericDirCtrl::ExpandDir(wxTreeItemId parentId)
dirs.Add(eachFilename); dirs.Add(eachFilename);
} }
} }
while (d.GetNext(& eachFilename)) ; while (d.GetNext(& eachFilename));
} }
} }
dirs.Sort((wxArrayString::CompareFunction) wxDirCtrlStringCompareFunction); dirs.Sort((wxArrayString::CompareFunction) wxDirCtrlStringCompareFunction);
@@ -806,7 +823,7 @@ void wxGenericDirCtrl::ExpandDir(wxTreeItemId parentId)
filenames.Add(eachFilename); filenames.Add(eachFilename);
} }
} }
while (d.GetNext(& eachFilename)) ; while (d.GetNext(& eachFilename));
} }
} }
filenames.Sort((wxArrayString::CompareFunction) wxDirCtrlStringCompareFunction); filenames.Sort((wxArrayString::CompareFunction) wxDirCtrlStringCompareFunction);
@@ -822,29 +839,20 @@ void wxGenericDirCtrl::ExpandDir(wxTreeItemId parentId)
path += wxString(wxFILE_SEP_PATH); path += wxString(wxFILE_SEP_PATH);
path += eachFilename; path += eachFilename;
wxDirItemDataEx *dir_item = new wxDirItemDataEx(path,eachFilename,TRUE); wxDirItemData *dir_item = new wxDirItemData(path,eachFilename,TRUE);
wxTreeItemId id = m_treeCtrl->AppendItem( parentId, eachFilename, 0, -1, dir_item); wxTreeItemId id = m_treeCtrl->AppendItem( parentId, eachFilename, 0, -1, dir_item);
m_treeCtrl->SetItemImage( id, 1, wxTreeItemIcon_Expanded ); m_treeCtrl->SetItemImage( id, 1, wxTreeItemIcon_Expanded );
// Has this got any children? If so, make it expandable. // Has this got any children? If so, make it expandable.
int options = wxDIR_DEFAULT; // (There are two situations when a dir has children: either it
if (GetWindowStyle() & wxDIRCTRL_DIR_ONLY) // If only showing dirs, then we specify dirs only here // has subdirectories or it contains files that weren't filtered
// out. The latter only applies to dirctrl with files.)
if ( dir_item->HasSubDirs() ||
(((GetWindowStyle() & wxDIRCTRL_DIR_ONLY) == 0) &&
dir_item->HasFiles(m_currentFilterStr)) )
{ {
options = wxDIR_DIRS; m_treeCtrl->SetItemHasChildren(id);
} }
wxLogNull log;
wxDir dir2;
if (dir2.Open(path))
{
wxString str;
// Have to test for wxDIR_DIRS separately in case m_currentFilterStr is non-empty and
// and filters out any directories
if (dir2.GetFirst(& str, m_currentFilterStr, options) || dir2.GetFirst(& str, wxEmptyString, wxDIR_DIRS))
{
m_treeCtrl->SetItemHasChildren(id);
}
}
} }
// Add the sorted filenames // Add the sorted filenames
@@ -858,7 +866,7 @@ void wxGenericDirCtrl::ExpandDir(wxTreeItemId parentId)
path += wxString(wxFILE_SEP_PATH); path += wxString(wxFILE_SEP_PATH);
path += eachFilename; path += eachFilename;
//path = dirName + wxString(wxT("/")) + eachFilename; //path = dirName + wxString(wxT("/")) + eachFilename;
wxDirItemDataEx *dir_item = new wxDirItemDataEx(path,eachFilename,FALSE); wxDirItemData *dir_item = new wxDirItemData(path,eachFilename,FALSE);
(void)m_treeCtrl->AppendItem( parentId, eachFilename, 2, -1, dir_item); (void)m_treeCtrl->AppendItem( parentId, eachFilename, 2, -1, dir_item);
} }
} }
@@ -887,9 +895,9 @@ wxTreeItemId wxGenericDirCtrl::FindChild(wxTreeItemId parentId, const wxString&
wxTreeItemId childId = m_treeCtrl->GetFirstChild(parentId, cookie); wxTreeItemId childId = m_treeCtrl->GetFirstChild(parentId, cookie);
while (childId.IsOk()) while (childId.IsOk())
{ {
wxDirItemDataEx* data = (wxDirItemDataEx*) m_treeCtrl->GetItemData(childId); wxDirItemData* data = (wxDirItemData*) m_treeCtrl->GetItemData(childId);
if (data && data->m_path != "") if (data && !data->m_path.IsEmpty())
{ {
wxString childPath(data->m_path); wxString childPath(data->m_path);
if (childPath.Last() != wxFILE_SEP_PATH) if (childPath.Last() != wxFILE_SEP_PATH)
@@ -914,7 +922,7 @@ wxTreeItemId wxGenericDirCtrl::FindChild(wxTreeItemId parentId, const wxString&
} }
} }
childId = m_treeCtrl->GetNextChild(childId, cookie); childId = m_treeCtrl->GetNextChild(parentId, cookie);
} }
wxTreeItemId invalid; wxTreeItemId invalid;
return invalid; return invalid;
@@ -937,7 +945,7 @@ bool wxGenericDirCtrl::ExpandPath(const wxString& path)
} }
if (lastId.IsOk()) if (lastId.IsOk())
{ {
wxDirItemDataEx *data = (wxDirItemDataEx *) m_treeCtrl->GetItemData(lastId); wxDirItemData *data = (wxDirItemData *) m_treeCtrl->GetItemData(lastId);
if (data->m_isDir) if (data->m_isDir)
{ {
m_treeCtrl->Expand(lastId); m_treeCtrl->Expand(lastId);
@@ -950,7 +958,7 @@ bool wxGenericDirCtrl::ExpandPath(const wxString& path)
bool selectedChild = FALSE; bool selectedChild = FALSE;
while (childId.IsOk()) while (childId.IsOk())
{ {
wxDirItemDataEx* data = (wxDirItemDataEx*) m_treeCtrl->GetItemData(childId); wxDirItemData* data = (wxDirItemData*) m_treeCtrl->GetItemData(childId);
if (data && data->m_path != "" && !data->m_isDir) if (data && data->m_path != "" && !data->m_isDir)
{ {
@@ -984,7 +992,7 @@ wxString wxGenericDirCtrl::GetPath() const
wxTreeItemId id = m_treeCtrl->GetSelection(); wxTreeItemId id = m_treeCtrl->GetSelection();
if (id) if (id)
{ {
wxDirItemDataEx* data = (wxDirItemDataEx*) m_treeCtrl->GetItemData(id); wxDirItemData* data = (wxDirItemData*) m_treeCtrl->GetItemData(id);
return data->m_path; return data->m_path;
} }
else else
@@ -996,7 +1004,7 @@ wxString wxGenericDirCtrl::GetFilePath() const
wxTreeItemId id = m_treeCtrl->GetSelection(); wxTreeItemId id = m_treeCtrl->GetSelection();
if (id) if (id)
{ {
wxDirItemDataEx* data = (wxDirItemDataEx*) m_treeCtrl->GetItemData(id); wxDirItemData* data = (wxDirItemData*) m_treeCtrl->GetItemData(id);
if (data->m_isDir) if (data->m_isDir)
return wxEmptyString; return wxEmptyString;
else else
@@ -1017,7 +1025,7 @@ void wxGenericDirCtrl::SetPath(const wxString& path)
#if 0 #if 0
void wxGenericDirCtrl::FindChildFiles(wxTreeItemId id, int dirFlags, wxArrayString& filenames) void wxGenericDirCtrl::FindChildFiles(wxTreeItemId id, int dirFlags, wxArrayString& filenames)
{ {
wxDirItemDataEx *data = (wxDirItemDataEx *) m_treeCtrl->GetItemData(id); wxDirItemData *data = (wxDirItemData *) m_treeCtrl->GetItemData(id);
// This may take a longish time. Go to busy cursor // This may take a longish time. Go to busy cursor
wxBusyCursor busy; wxBusyCursor busy;
@@ -1216,204 +1224,5 @@ void wxDirFilterListCtrl::FillFilterList(const wxString& filter, int defaultFilt
} }
} }
// wxGenericDirDialog implementation
// This should be moved into dirdlgg.cpp eventually
BEGIN_EVENT_TABLE(wxGenericDirDialog, wxDialog)
EVT_BUTTON(wxID_OK, wxGenericDirDialog::OnOK)
EVT_BUTTON(wxID_NEW, wxGenericDirDialog::OnNew)
EVT_BUTTON (wxID_NEW, wxGenericDirDialog::OnNew)
EVT_CLOSE(wxGenericDirDialog::OnCloseWindow)
EVT_TREE_KEY_DOWN (-1, wxGenericDirDialog::OnTreeKeyDown)
EVT_TREE_SEL_CHANGED (-1, wxGenericDirDialog::OnTreeSelected)
EVT_TEXT_ENTER (ID_TEXTCTRL, wxGenericDirDialog::OnOK)
END_EVENT_TABLE()
wxGenericDirDialog::wxGenericDirDialog(wxWindow* parent, const wxString& title,
const wxString& defaultPath, long style, const wxPoint& pos, const wxSize& sz, const wxString& name):
wxDialog(parent, ID_DIRCTRL, title, pos, sz, style, name)
{
m_dirCtrl = NULL;
m_path = defaultPath;
wxBusyCursor cursor;
wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
// 1) dir ctrl
m_dirCtrl = new wxGenericDirCtrl(this, ID_DIRCTRL,
defaultPath, wxPoint(5, 5),
wxSize(300, 200), wxDIRCTRL_DIR_ONLY|wxSUNKEN_BORDER);
topsizer->Add( m_dirCtrl, 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 );
#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 );
wxButton* okButton = new wxButton(this, wxID_OK, _("OK"));
buttonsizer->Add( okButton, 0, wxLEFT|wxRIGHT, 10 );
wxButton* cancelButton = new wxButton(this, wxID_CANCEL, _("Cancel"));
buttonsizer->Add( cancelButton, 0, wxLEFT|wxRIGHT, 10 );
// I'm not convinced we need a New button, and we tend to get annoying
// accidental-editing with label editing enabled.
#if 0
wxButton* newButton = new wxButton( this, wxID_NEW, _("New...") );
buttonsizer->Add( newButton, 0, wxLEFT|wxRIGHT, 10 );
#endif
topsizer->Add( buttonsizer, 0, wxALL | wxCENTER, 10 );
okButton->SetDefault();
m_dirCtrl->SetFocus();
SetAutoLayout( TRUE );
SetSizer( topsizer );
topsizer->SetSizeHints( this );
topsizer->Fit( this );
Centre( wxBOTH );
}
void wxGenericDirDialog::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
{
EndModal(wxID_CANCEL);
}
void wxGenericDirDialog::OnOK(wxCommandEvent& WXUNUSED(event))
{
m_path = m_input->GetValue();
// Does the path exist? (User may have typed anything in m_input)
if (wxPathExists(m_path)) {
// OK, path exists, we're done.
EndModal(wxID_OK);
return;
}
// Interact with user, find out if the dir is a typo or to be created
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 | 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);
return;
}
else {
// Trouble...
msg = _("Failed to create directory ")+m_path+
_("\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.
}
}
// User has answered NO to create dir.
}
void wxGenericDirDialog::SetPath(const wxString& path)
{
m_dirCtrl->SetPath(path);
m_path = path;
}
wxString wxGenericDirDialog::GetPath(void) const
{
return m_path;
}
int wxGenericDirDialog::ShowModal()
{
//m_input->SetValue( m_path );
return wxDialog::ShowModal();
}
void wxGenericDirDialog::OnTreeSelected( wxTreeEvent &event )
{
if (!m_dirCtrl)
return;
wxDirItemDataEx *data = (wxDirItemDataEx*)m_dirCtrl->GetTreeCtrl()->GetItemData(event.GetItem());
if (data)
m_input->SetValue( data->m_path );
};
void wxGenericDirDialog::OnTreeKeyDown( wxTreeEvent &WXUNUSED(event) )
{
if (!m_dirCtrl)
return;
wxDirItemDataEx *data = (wxDirItemDataEx*)m_dirCtrl->GetTreeCtrl()->GetItemData(m_dirCtrl->GetTreeCtrl()->GetSelection());
if (data)
m_input->SetValue( data->m_path );
};
void wxGenericDirDialog::OnNew( wxCommandEvent& WXUNUSED(event) )
{
wxTreeItemId id = m_dirCtrl->GetTreeCtrl()->GetSelection();
if ((id == m_dirCtrl->GetTreeCtrl()->GetRootItem()) ||
(m_dirCtrl->GetTreeCtrl()->GetParent(id) == m_dirCtrl->GetTreeCtrl()->GetRootItem()))
{
wxMessageDialog msg(this, _("You cannot add a new directory to this section."),
_("Create directory"), wxOK | wxICON_INFORMATION );
msg.ShowModal();
return;
}
wxTreeItemId parent = id ; // m_dirCtrl->GetTreeCtrl()->GetParent( id );
wxDirItemDataEx *data = (wxDirItemDataEx*)m_dirCtrl->GetTreeCtrl()->GetItemData( parent );
wxASSERT( data );
wxString new_name( wxT("NewName") );
wxString path( data->m_path );
if (path.Last() != wxFILE_SEP_PATH)
path += wxFILE_SEP_PATH;
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;
if (path.Last() != wxFILE_SEP_PATH)
path += wxFILE_SEP_PATH;
path += new_name;
i++;
} while (wxFileExists(path));
}
wxLogNull log;
if (!wxMkdir(path))
{
wxMessageDialog dialog(this, _("Operation not permitted."), _("Error"), wxOK | wxICON_ERROR );
dialog.ShowModal();
return;
}
wxDirItemDataEx *new_data = new wxDirItemDataEx( path, new_name, TRUE );
// TODO: THIS CODE DOESN'T WORK YET. We need to avoid duplication of the first child
// of the parent.
wxTreeItemId new_id = m_dirCtrl->GetTreeCtrl()->AppendItem( parent, new_name, 0, 0, new_data );
m_dirCtrl->GetTreeCtrl()->EnsureVisible( new_id );
m_dirCtrl->GetTreeCtrl()->EditLabel( new_id );
}
#endif // wxUSE_DIRDLG #endif // wxUSE_DIRDLG

View File

@@ -1,11 +1,11 @@
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Name: dirdlg.cpp // Name: dirdlg.cpp
// Purpose: wxDirDialog // Purpose: wxDirDialog
// Author: Harm van der Heijden and Robert Roebling // Author: Harm van der Heijden, Robert Roebling & Julian Smart
// Modified by: // Modified by:
// Created: 12/12/98 // Created: 12/12/98
// RCS-ID: $Id$ // RCS-ID: $Id$
// Copyright: (c) Harm van der Heijden and Robert Roebling // Copyright: (c) Harm van der Heijden, Robert Roebling, Julian Smart
// Licence: wxWindows licence // Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@@ -13,6 +13,7 @@
#pragma implementation "dirdlgg.h" #pragma implementation "dirdlgg.h"
#endif #endif
// For compilers that support precompilation, includes "wx.h". // For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h" #include "wx/wxprec.h"
@@ -24,95 +25,22 @@
#if wxUSE_DIRDLG #if wxUSE_DIRDLG
#include "wx/utils.h" #ifndef WX_PRECOMP
#include "wx/dialog.h" #include "wx/textctrl.h"
#include "wx/button.h" #include "wx/button.h"
#include "wx/layout.h" #include "wx/sizer.h"
#include "wx/msgdlg.h"
#include "wx/textctrl.h"
#include "wx/textdlg.h"
#include "wx/filefn.h"
#include "wx/cmndata.h"
#include "wx/gdicmn.h"
#include "wx/intl.h"
#include "wx/imaglist.h"
#include "wx/icon.h"
#include "wx/log.h"
#include "wx/sizer.h"
#include "wx/tokenzr.h"
#include "wx/dir.h"
#if wxUSE_STATLINE
#include "wx/statline.h" #include "wx/statline.h"
#include "wx/intl.h"
#include "wx/log.h"
#include "wx/msgdlg.h"
#endif #endif
#include "wx/generic/dirctrlg.h"
#include "wx/generic/dirdlgg.h" #include "wx/generic/dirdlgg.h"
// If compiled under Windows, this macro can cause problems //-----------------------------------------------------------------------------
#ifdef GetFirstChild // wxGenericDirDialog
#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",
/* pixels */
" ",
" @@@@@ ",
" @#+#+#@ ",
" @#+#+#+#@@@@@@ ",
" @$$$$$$$$$$$$@.",
" @$#+#+#+#+#+#@.",
" @$+#+#+#+#+#+@.",
" @$#+#+#+#+#+#@.",
" @$+#+#+#+#+#+@.",
" @$#+#+#+#+#+#@.",
" @$+#+#+#+#+#+@.",
" @$#+#+#+#+#+#@.",
" @@@@@@@@@@@@@@.",
" ..............",
" ",
" "};
/* XPM */
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",
/* pixels */
" ",
" @@@@@ ",
" @$$$$$@ ",
" @$#+#+#$@@@@@@ ",
" @$+#+#+$$$$$$@.",
" @$#+#+#+#+#+#@.",
"@@@@@@@@@@@@@#@.",
"@$$$$$$$$$$@@+@.",
"@$#+#+#+#+##.@@.",
" @$#+#+#+#+#+.@.",
" @$+#+#+#+#+#.@.",
" @$+#+#+#+##@..",
" @@@@@@@@@@@@@.",
" .............",
" ",
" "};
#endif // !wxMSW
static const int ID_DIRCTRL = 1000; static const int ID_DIRCTRL = 1000;
static const int ID_TEXTCTRL = 1001; static const int ID_TEXTCTRL = 1001;
@@ -121,309 +49,64 @@ static const int ID_CANCEL = 1003;
static const int ID_NEW = 1004; static const int ID_NEW = 1004;
//static const int ID_CHECK = 1005; //static const int ID_CHECK = 1005;
//----------------------------------------------------------------------------- BEGIN_EVENT_TABLE(wxGenericDirDialog, wxDialog)
// wxDirItemData EVT_BUTTON (wxID_OK, wxGenericDirDialog::OnOK)
//----------------------------------------------------------------------------- EVT_BUTTON (wxID_NEW, wxGenericDirDialog::OnNew)
EVT_CLOSE (wxGenericDirDialog::OnCloseWindow)
wxDirItemData::wxDirItemData(wxString& path, wxString& name) EVT_TREE_KEY_DOWN (-1, wxGenericDirDialog::OnTreeKeyDown)
{ EVT_TREE_SEL_CHANGED (-1, wxGenericDirDialog::OnTreeSelected)
m_path = path; EVT_TEXT_ENTER (ID_TEXTCTRL, wxGenericDirDialog::OnOK)
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()
{
}
void wxDirItemData::SetNewDirName( wxString path )
{
m_path = path;
m_name = wxFileNameFromPath( path );
}
bool wxDirItemData::HasSubDirs()
{
return wxDir(m_path).HasSubDirs();
}
//-----------------------------------------------------------------------------
// wxDirCtrl
//-----------------------------------------------------------------------------
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() END_EVENT_TABLE()
wxDirCtrl::wxDirCtrl(void) wxGenericDirDialog::wxGenericDirDialog(wxWindow* parent, const wxString& title,
const wxString& defaultPath, long style,
const wxPoint& pos, const wxSize& sz,
const wxString& name):
wxDialog(parent, ID_DIRCTRL, title, pos, sz, style, name)
{ {
m_showHidden = FALSE; wxBusyCursor cursor;
}
wxDirCtrl::wxDirCtrl(wxWindow *parent,
const wxWindowID id,
const wxString &WXUNUSED(dir),
const wxPoint& pos,
const wxSize& size,
const long style,
const wxString& name )
: wxTreeCtrl( parent, id, pos, size, style, wxDefaultValidator, name )
{
#ifndef __WXMSW__
m_imageListNormal = new wxImageList(16, 16, TRUE);
m_imageListNormal->Add(wxICON(icon1));
m_imageListNormal->Add(wxICON(icon2));
SetImageList(m_imageListNormal);
#endif // !MSW
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()
{
wxString home;
m_paths.Clear();
m_names.Clear();
#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(wxT("/mnt"), _("Mounted Devices") )
ADD_SECTION(wxT("/usr/local"), _("User Local") )
ADD_SECTION(wxT("/usr"), _("User") )
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;
// wxASSERT(m_paths.Count() == m_names.Count()); ?
size_t count = m_paths.GetCount();
for ( size_t i=0; i<count; i++)
{
dir_item = new wxDirItemData(m_paths[i],m_names[i]);
#ifdef __WXMSW__
id = AppendItem( parent, m_names[i], -1, -1, dir_item);
#else
id = AppendItem( parent, m_names[i], 0, -1, dir_item);
SetItemImage( id, 1, wxTreeItemIcon_Expanded );
#endif
if (dir_item->m_hasSubDirs) SetItemHasChildren(id);
}
}
void wxDirCtrl::OnBeginEditItem(wxTreeEvent &event)
{
// 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;
}
wxTreeItemId id = event.GetItem();
wxDirItemData *data = (wxDirItemData*)GetItemData( id );
wxASSERT( data );
wxString new_name( wxPathOnly( data->m_path ) );
new_name += wxT("/");
new_name += event.GetLabel();
wxLogNull log;
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());
m_paths.Clear();
m_names.Clear();
wxString path = data->m_path;
wxDir dir(path);
path += _T('/');
wxString filename;
bool cont = dir.GetFirst(&filename, "", wxDIR_DIRS | wxDIR_HIDDEN);
while ( cont )
{
m_paths.Add(path + filename);
m_names.Add(filename);
cont = dir.GetNext(&filename);
}
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! */
child = GetFirstChild(parent, cookie);
}
}
//-----------------------------------------------------------------------------
// wxDirDialog
//-----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS( wxDirDialog, wxDialog )
BEGIN_EVENT_TABLE( wxDirDialog, wxDialog )
EVT_TREE_KEY_DOWN (ID_DIRCTRL, wxDirDialog::OnTreeKeyDown)
EVT_TREE_SEL_CHANGED (ID_DIRCTRL, wxDirDialog::OnTreeSelected)
EVT_SIZE ( wxDirDialog::OnSize)
EVT_BUTTON (ID_OK, wxDirDialog::OnOK)
EVT_BUTTON (ID_CANCEL, wxDirDialog::OnCancel)
EVT_BUTTON (ID_NEW, wxDirDialog::OnNew)
EVT_TEXT_ENTER (ID_TEXTCTRL, wxDirDialog::OnOK)
// EVT_CHECKBOX (ID_CHECK, wxDirDialog::OnCheck)
END_EVENT_TABLE()
wxDirDialog::wxDirDialog(wxWindow *parent,
const wxString& message,
const wxString& defaultPath,
long style,
const wxPoint& pos)
: wxDialog(parent, -1, message, pos, wxSize(300,300),
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
m_message = message;
m_dialogStyle = style;
m_parent = parent;
m_path = defaultPath; m_path = defaultPath;
if (m_path == wxT("~"))
wxBeginBusyCursor(); wxGetHomeDir( &m_path );
wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL ); wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
// 1) dir ctrl // 1) dir ctrl
m_dir = new wxDirCtrl( this, ID_DIRCTRL, _T("/"), m_dirCtrl = NULL; // this is neccessary, event handler called from
wxDefaultPosition, // wxGenericDirCtrl would crash otherwise!
wxSize(200,200), m_dirCtrl = new wxGenericDirCtrl(this, ID_DIRCTRL,
wxTR_HAS_BUTTONS | m_path, wxPoint(5, 5),
wxSUNKEN_BORDER | wxSize(300, 200),
wxTR_EDIT_LABELS ); wxDIRCTRL_DIR_ONLY|wxSUNKEN_BORDER);
topsizer->Add( m_dir, 1, wxTOP|wxLEFT|wxRIGHT | wxEXPAND, 10 );
topsizer->Add( m_dirCtrl, 1, wxTOP|wxLEFT|wxRIGHT | wxEXPAND, 10 );
// 2) text ctrl // 2) text ctrl
m_input = new wxTextCtrl( this, ID_TEXTCTRL, m_path, wxDefaultPosition ); m_input = new wxTextCtrl( this, ID_TEXTCTRL, m_path, wxDefaultPosition );
topsizer->Add( m_input, 0, wxTOP|wxLEFT|wxRIGHT | wxEXPAND, 10 ); 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 #if wxUSE_STATLINE
// 3) static line // 3) Static line
topsizer->Add( new wxStaticLine( this, -1 ), 0, wxEXPAND | wxLEFT|wxRIGHT|wxTOP, 10 ); topsizer->Add( new wxStaticLine( this, -1 ), 0, wxEXPAND | wxLEFT|wxRIGHT|wxTOP, 10 );
#endif #endif
// 4) buttons // 4) Buttons
wxSizer* buttonsizer = new wxBoxSizer( wxHORIZONTAL ); wxSizer* buttonsizer = new wxBoxSizer( wxHORIZONTAL );
m_ok = new wxButton( this, ID_OK, _("OK") ); wxButton* okButton = new wxButton(this, wxID_OK, _("OK"));
buttonsizer->Add( m_ok, 0, wxLEFT|wxRIGHT, 10 ); buttonsizer->Add( okButton, 0, wxLEFT|wxRIGHT, 10 );
m_cancel = new wxButton( this, ID_CANCEL, _("Cancel") ); wxButton* cancelButton = new wxButton(this, wxID_CANCEL, _("Cancel"));
buttonsizer->Add( m_cancel, 0, wxLEFT|wxRIGHT, 10 ); buttonsizer->Add( cancelButton, 0, wxLEFT|wxRIGHT, 10 );
m_new = new wxButton( this, ID_NEW, _("New...") );
buttonsizer->Add( m_new, 0, wxLEFT|wxRIGHT, 10 ); // I'm not convinced we need a New button, and we tend to get annoying
// accidental-editing with label editing enabled.
wxButton* newButton = new wxButton( this, wxID_NEW, _("New...") );
buttonsizer->Add( newButton, 0, wxLEFT|wxRIGHT, 10 );
topsizer->Add( buttonsizer, 0, wxALL | wxCENTER, 10 ); topsizer->Add( buttonsizer, 0, wxALL | wxCENTER, 10 );
m_ok->SetDefault(); okButton->SetDefault();
m_dir->SetFocus(); m_dirCtrl->SetFocus();
SetAutoLayout( TRUE ); SetAutoLayout( TRUE );
SetSizer( topsizer ); SetSizer( topsizer );
@@ -432,134 +115,91 @@ wxDirDialog::wxDirDialog(wxWindow *parent,
topsizer->Fit( this ); topsizer->Fit( this );
Centre( wxBOTH ); Centre( wxBOTH );
if (m_path == wxT("~"))
wxGetHomeDir( &m_path );
// choose the directory corresponding to defaultPath in the tree
// VZ: using wxStringTokenizer is probably unsafe here (escaped slashes
// will not be processed correctly...)
wxStringTokenizer tk(m_path, wxFILE_SEP_PATH, wxTOKEN_STRTOK);
wxString path;
long cookie = 0;
// default to root dir
wxTreeItemId item = m_dir->GetFirstChild(m_dir->GetRootItem(), cookie);
if (!m_path.IsEmpty() && (m_path != wxT("/")) && (m_dir->m_paths.Count() > 1))
{
size_t count = m_dir->m_paths.GetCount();
for ( size_t i=1; i<count; i++)
{
if (m_path.Find( m_dir->m_paths[i] ) == 0)
{
path = m_dir->m_paths[i];
for (size_t j = 0; j < i; j++)
item = m_dir->GetNextChild(m_dir->GetRootItem(), cookie);
wxStringTokenizer tk2(path, wxFILE_SEP_PATH, wxTOKEN_STRTOK);
for (size_t h = 0; h < tk2.CountTokens(); h++)
tk.GetNextToken();
break;
}
}
}
while ( tk.HasMoreTokens() && item.IsOk() )
{
path << wxFILE_SEP_PATH << tk.GetNextToken();
m_dir->Expand(item);
wxTreeItemId child = m_dir->GetFirstChild(item, cookie);
while ( child.IsOk() )
{
wxDirItemData *data = (wxDirItemData*)m_dir->GetItemData(child);
if ( data->m_path == path )
break;
child = m_dir->GetNextChild(item, cookie);
}
item = child;
}
if ( item.IsOk() )
{
m_dir->Expand(item);
m_dir->SelectItem(item);
m_dir->EnsureVisible(item);
}
wxEndBusyCursor();
} }
int wxDirDialog::ShowModal() void wxGenericDirDialog::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
{
EndModal(wxID_CANCEL);
}
void wxGenericDirDialog::OnOK(wxCommandEvent& WXUNUSED(event))
{
m_path = m_input->GetValue();
// Does the path exist? (User may have typed anything in m_input)
if (wxPathExists(m_path)) {
// OK, path exists, we're done.
EndModal(wxID_OK);
return;
}
// Interact with user, find out if the dir is a typo or to be created
wxString msg;
msg.Printf(_("The directory '%s' does not exist\nCreate it now?"),
m_path.c_str());
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);
return;
}
else {
// Trouble...
msg.Printf(_("Failed to create directory '%s'\n(Do you have the required permissions?)"),
m_path.c_str());
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.
}
}
// User has answered NO to create dir.
}
void wxGenericDirDialog::SetPath(const wxString& path)
{
m_dirCtrl->SetPath(path);
m_path = path;
}
wxString wxGenericDirDialog::GetPath(void) const
{
return m_path;
}
int wxGenericDirDialog::ShowModal()
{ {
m_input->SetValue( m_path ); m_input->SetValue( m_path );
return wxDialog::ShowModal(); return wxDialog::ShowModal();
} }
void wxDirDialog::OnTreeSelected( wxTreeEvent &event ) void wxGenericDirDialog::OnTreeSelected( wxTreeEvent &event )
{ {
wxDirItemData *data = (wxDirItemData*)m_dir->GetItemData(event.GetItem()); if (!m_dirCtrl)
return;
wxDirItemData *data = (wxDirItemData*)m_dirCtrl->GetTreeCtrl()->GetItemData(event.GetItem());
if (data) if (data)
m_input->SetValue( data->m_path ); m_input->SetValue( data->m_path );
}; };
void wxDirDialog::OnTreeKeyDown( wxTreeEvent &WXUNUSED(event) ) void wxGenericDirDialog::OnTreeKeyDown( wxTreeEvent &WXUNUSED(event) )
{ {
wxDirItemData *data = (wxDirItemData*)m_dir->GetItemData(m_dir->GetSelection()); if (!m_dirCtrl)
return;
wxDirItemData *data = (wxDirItemData*)m_dirCtrl->GetTreeCtrl()->GetItemData(m_dirCtrl->GetTreeCtrl()->GetSelection());
if (data) if (data)
m_input->SetValue( data->m_path ); m_input->SetValue( data->m_path );
}; };
void wxDirDialog::OnOK( wxCommandEvent& WXUNUSED(event) ) void wxGenericDirDialog::OnNew( wxCommandEvent& WXUNUSED(event) )
{ {
m_path = m_input->GetValue(); wxTreeItemId id = m_dirCtrl->GetTreeCtrl()->GetSelection();
// Does the path exist? (User may have typed anything in m_input) if ((id == m_dirCtrl->GetTreeCtrl()->GetRootItem()) ||
if (wxPathExists(m_path)) { (m_dirCtrl->GetTreeCtrl()->GetParent(id) == m_dirCtrl->GetTreeCtrl()->GetRootItem()))
// OK, path exists, we're done.
EndModal(wxID_OK);
return;
}
// Interact with user, find out if the dir is a typo or to be created
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 | 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);
return;
}
else {
// Trouble...
msg = _("Failed to create directory ")+m_path+
_("\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.
}
}
// User has answered NO to create dir.
}
void wxDirDialog::OnCancel( wxCommandEvent& WXUNUSED(event) )
{
EndModal(wxID_CANCEL);
}
void wxDirDialog::OnNew( wxCommandEvent& WXUNUSED(event) )
{
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."), wxMessageDialog msg(this, _("You cannot add a new directory to this section."),
_("Create directory"), wxOK | wxICON_INFORMATION ); _("Create directory"), wxOK | wxICON_INFORMATION );
@@ -567,26 +207,28 @@ void wxDirDialog::OnNew( wxCommandEvent& WXUNUSED(event) )
return; return;
} }
wxTreeItemId parent = m_dir->GetParent( id ); wxTreeItemId parent = id ; // m_dirCtrl->GetTreeCtrl()->GetParent( id );
wxDirItemData *data = (wxDirItemData*)m_dir->GetItemData( parent ); wxDirItemData *data = (wxDirItemData*)m_dirCtrl->GetTreeCtrl()->GetItemData( parent );
wxASSERT( data ); wxASSERT( data );
wxString new_name( wxT("NewName") ); wxString new_name( _("NewName") );
wxString path( data->m_path ); wxString path( data->m_path );
path += wxT("/"); if (path.Last() != wxFILE_SEP_PATH)
path += wxFILE_SEP_PATH;
path += new_name; path += new_name;
if (wxFileExists(path)) if (wxFileExists(path))
{ {
// try NewName0, NewName1 etc. // try NewName0, NewName1 etc.
int i = 0; int i = 0;
do { do {
new_name = wxT("NewName"); new_name = _("NewName");
wxString num; wxString num;
num.Printf( wxT("%d"), i ); num.Printf( wxT("%d"), i );
new_name += num; new_name += num;
path = data->m_path; path = data->m_path;
path += wxT("/"); if (path.Last() != wxFILE_SEP_PATH)
path += wxFILE_SEP_PATH;
path += new_name; path += new_name;
i++; i++;
} while (wxFileExists(path)); } while (wxFileExists(path));
@@ -600,17 +242,13 @@ void wxDirDialog::OnNew( wxCommandEvent& WXUNUSED(event) )
return; return;
} }
wxDirItemData *new_data = new wxDirItemData( path, new_name ); wxDirItemData *new_data = new wxDirItemData( path, new_name, TRUE );
wxTreeItemId new_id = m_dir->AppendItem( parent, new_name, 0, 1, new_data );
m_dir->EnsureVisible( new_id );
m_dir->EditLabel( new_id );
}
/* // TODO: THIS CODE DOESN'T WORK YET. We need to avoid duplication of the first child
void wxDirDialog::OnCheck( wxCommandEvent& WXUNUSED(event) ) // of the parent.
{ wxTreeItemId new_id = m_dirCtrl->GetTreeCtrl()->AppendItem( parent, new_name, 0, 0, new_data );
printf("Checkbox clicked: %s\n", ( m_check->GetValue() ? "on" : "off" ) ); m_dirCtrl->GetTreeCtrl()->EnsureVisible( new_id );
m_dirCtrl->GetTreeCtrl()->EditLabel( new_id );
} }
*/
#endif // wxUSE_DIRDLG #endif // wxUSE_DIRDLG