#include "wx/module.h"
#include "wx/config.h"
#include "wx/imaglist.h"
+#include "wx/dir.h"
#if wxUSE_TOOLTIPS
#include "wx/tooltip.h"
# include <time.h>
#include <unistd.h>
+// XPM hack: make the arrays const
+#define static static const
+
#ifndef __DOS__
#include "wx/generic/home.xpm"
#endif
#include "wx/generic/deffile.xpm"
#include "wx/generic/exefile.xpm"
+#undef static
+
//-----------------------------------------------------------------------------
// wxFileData
//-----------------------------------------------------------------------------
class wxFileData : public wxObject
{
-private:
- wxString m_name;
- wxString m_fileName;
- long m_size;
- int m_hour;
- int m_minute;
- int m_year;
- int m_month;
- int m_day;
- wxString m_permissions;
- bool m_isDir;
- bool m_isLink;
- bool m_isExe;
-
public:
wxFileData() { }
wxFileData( const wxString &name, const wxString &fname );
void SetNewName( const wxString &name, const wxString &fname );
private:
+ wxString m_name;
+ wxString m_fileName;
+ long m_size;
+ int m_hour;
+ int m_minute;
+ int m_year;
+ int m_month;
+ int m_day;
+ wxString m_permissions;
+ bool m_isDir;
+ bool m_isLink;
+ bool m_isExe;
+
DECLARE_DYNAMIC_CLASS(wxFileData);
};
class wxFileCtrl : public wxListCtrl
{
-private:
- wxString m_dirName;
- bool m_showHidden;
- wxString m_wild;
-
public:
wxFileCtrl();
wxFileCtrl( wxWindow *win,
void ChangeToIconMode();
void ShowHidden( bool show = TRUE );
long Add( wxFileData *fd, wxListItem &item );
- void Update();
+ void UpdateFiles();
virtual void StatusbarText( wxChar *WXUNUSED(text) ) {};
void MakeDir();
void GoToParentDir();
void OnListDeleteItem( wxListEvent &event );
void OnListDeleteAllItems( wxListEvent &event );
void OnListEndLabelEdit( wxListEvent &event );
+
+ // Associate commonly used UI controls with wxFileCtrl so that they can be
+ // disabled when they cannot be used (e.g. can't go to parent directory
+ // if wxFileCtrl already is in the root dir):
+ void SetGoToParentControl(wxWindow *ctrl) { m_goToParentControl = ctrl; }
+ void SetNewDirControl(wxWindow *ctrl) { m_newDirControl = ctrl; }
private:
+ wxString m_dirName;
+ bool m_showHidden;
+ wxString m_wild;
+
+ wxWindow *m_goToParentControl;
+ wxWindow *m_newDirControl;
+
DECLARE_DYNAMIC_CLASS(wxFileCtrl);
DECLARE_EVENT_TABLE()
};
return wxStrcmp( fd1->GetName(), fd2->GetName() );
}
+#ifdef __UNIX__
+#define IsTopMostDir(dir) (dir == wxT("/"))
+#endif
+
+#if defined(__DOS__) || defined(__WINDOWS__)
+#define IsTopMostDir(dir) (dir.IsEmpty())
+#endif
+
+#if defined(__DOS__) || defined(__WINDOWS__)
+extern bool wxIsDriveAvailable(const wxString& dirName);
+#endif
+
//-----------------------------------------------------------------------------
// wxFileData
//-----------------------------------------------------------------------------
{
m_name = name;
m_fileName = fname;
+
+#if defined(__DOS__) || defined(__WINDOWS__)
+ // VS: In case the file is root directory of a volume (e.g. "C:"),
+ // we don't want it stat()ed, since the drive may not be in:
+ if (name.length() == 2 && name[1u] == wxT(':'))
+ {
+ m_isDir = TRUE;
+ m_isExe = m_isLink = FALSE;
+ m_size = 0;
+ return;
+ }
+#endif
struct stat buff;
- stat( m_fileName.fn_str(), &buff );
+ wxStat( m_fileName.fn_str(), &buff );
#if defined(__UNIX__) && (!defined( __EMX__ ) && !defined(__VMS))
struct stat lbuff;
else if (IsExe())
item.m_image = FI_EXECUTABLE;
else if (m_name.Find(wxT('.')) != wxNOT_FOUND)
- item.m_image = g_IconsTable -> GetIconID(m_name.AfterLast(wxT('.')));
+ item.m_image = g_IconsTable->GetIconID(m_name.AfterLast(wxT('.')));
else
item.m_image = FI_UNKNOWN;
#if defined(__UNIX__)
m_dirName = wxT("/");
#elif defined(__DOS__)
- m_dirName = wxT("C:\\");
+ m_dirName = wxT("");
#endif
m_showHidden = FALSE;
}
-wxFileCtrl::wxFileCtrl( wxWindow *win, wxWindowID id,
- const wxString &dirName, const wxString &wild,
- const wxPoint &pos, const wxSize &size,
- long style, const wxValidator &validator, const wxString &name ) :
- wxListCtrl( win, id, pos, size, style, validator, name )
+wxFileCtrl::wxFileCtrl(wxWindow *win, wxWindowID id,
+ const wxString &dirName, const wxString &wild,
+ const wxPoint &pos, const wxSize &size,
+ long style, const wxValidator &validator,
+ const wxString &name)
+ : wxListCtrl(win, id, pos, size, style, validator, name)
{
- if (! g_IconsTable) g_IconsTable = new wxFileIconsTable;
- wxImageList *imageList = g_IconsTable -> GetImageList();
+ if (! g_IconsTable)
+ g_IconsTable = new wxFileIconsTable;
+ wxImageList *imageList = g_IconsTable->GetImageList();
SetImageList( imageList, wxIMAGE_LIST_SMALL );
+ m_goToParentControl = m_newDirControl = NULL;
+
m_dirName = dirName;
m_wild = wild;
m_showHidden = FALSE;
- Update();
+ UpdateFiles();
}
void wxFileCtrl::ChangeToListMode()
{
SetSingleStyle( wxLC_LIST );
- Update();
+ UpdateFiles();
}
void wxFileCtrl::ChangeToReportMode()
{
SetSingleStyle( wxLC_REPORT );
- Update();
+ UpdateFiles();
}
void wxFileCtrl::ChangeToIconMode()
{
SetSingleStyle( wxLC_ICON );
- Update();
+ UpdateFiles();
}
void wxFileCtrl::ShowHidden( bool show )
{
m_showHidden = show;
- Update();
+ UpdateFiles();
}
long wxFileCtrl::Add( wxFileData *fd, wxListItem &item )
return ret;
}
-void wxFileCtrl::Update()
+void wxFileCtrl::UpdateFiles()
{
+ wxBusyCursor bcur; // this may take a while...
+
long my_style = GetWindowStyleFlag();
int name_col_width = 0;
if (my_style & wxLC_REPORT)
item.m_itemId = 0;
item.m_col = 0;
- if (m_dirName != wxT("/"))
- {
- wxString p( wxPathOnly(m_dirName) );
- if (p.IsEmpty()) p = wxT("/");
- fd = new wxFileData( wxT(".."), p );
- Add( fd, item );
- item.m_itemId++;
+#if defined(__DOS__) || defined(__WINDOWS__)
+ if ( IsTopMostDir(m_dirName) )
+ {
+ // Pseudo-directory with all available drives listed...
+ for (int drive = 1; drive <= 26; drive++)
+ {
+ wxString path;
+ path.Printf(wxT("%c:\\"), (char)(drive + 'A' - 1));
+ if ( wxIsDriveAvailable(path) )
+ {
+ path.RemoveLast();
+ fd = new wxFileData(path, path);
+ Add(fd, item);
+ item.m_itemId++;
+ }
+ }
}
-
-#if defined(__UNIX__)
- wxString res = m_dirName + wxT("/*");
-#elif defined(__DOS__)
- wxString res = m_dirName + wxT("\\*.*");
+ else
#endif
- wxString f( wxFindFirstFile( res.GetData(), wxDIR ) );
- while (!f.IsEmpty())
{
- res = wxFileNameFromPath( f );
- fd = new wxFileData( res, f );
- wxString s = fd->GetName();
- if (m_showHidden || (s[0u] != wxT('.')))
+ // Real directory...
+ if ( !IsTopMostDir(m_dirName) )
{
- Add( fd, item );
+ wxString p(wxPathOnly(m_dirName));
+#ifdef __UNIX__
+ if (p.IsEmpty()) p = wxT("/");
+#endif
+ fd = new wxFileData( wxT(".."), p );
+ Add(fd, item);
item.m_itemId++;
}
- f = wxFindNextFile();
- }
- // Tokenize the wildcard string, so we can handle more than 1
- // search pattern in a wildcard.
- wxStringTokenizer tokenWild( m_wild, ";" );
- while ( tokenWild.HasMoreTokens() )
- {
- res = m_dirName + wxFILE_SEP_PATH + tokenWild.GetNextToken();
- f = wxFindFirstFile( res.GetData(), wxFILE );
- while (!f.IsEmpty())
+ wxString dirname(m_dirName);
+#if defined(__DOS__) || defined(__WINDOWS__)
+ if (dirname.length() == 2 && dirname[1u] == wxT(':'))
+ dirname << wxT('\\');
+#endif
+ wxDir dir(dirname);
+
+ if ( dir.IsOpened() )
{
- res = wxFileNameFromPath( f );
- fd = new wxFileData( res, f );
- wxString s = fd->GetName();
- if (m_showHidden || (s[0u] != wxT('.')))
+ wxString dirPrefix(dirname + wxFILE_SEP_PATH);
+ int hiddenFlag = m_showHidden ? wxDIR_HIDDEN : 0;
+
+ bool cont;
+ wxString f;
+
+ // Get the directories first (not matched against wildcards):
+ cont = dir.GetFirst(&f, wxEmptyString, wxDIR_DIRS | hiddenFlag);
+ while (cont)
{
- Add( fd, item );
+ fd = new wxFileData(f, dirPrefix + f);
+ Add(fd, item);
item.m_itemId++;
+ cont = dir.GetNext(&f);
+ }
+
+ // Tokenize the wildcard string, so we can handle more than 1
+ // search pattern in a wildcard.
+ wxStringTokenizer tokenWild(m_wild, wxT(";"));
+ while ( tokenWild.HasMoreTokens() )
+ {
+ cont = dir.GetFirst(&f, tokenWild.GetNextToken(),
+ wxDIR_FILES | hiddenFlag);
+ while (cont)
+ {
+ fd = new wxFileData(f, dirPrefix + f);
+ Add(fd, item);
+ item.m_itemId++;
+ cont = dir.GetNext(&f);
+ }
}
- f = wxFindNextFile();
}
}
- SortItems( ListCompare, 0 );
+ SortItems(ListCompare, 0);
- if (my_style & wxLC_REPORT)
+ if ( my_style & wxLC_REPORT )
{
- SetColumnWidth( 1, wxLIST_AUTOSIZE );
- SetColumnWidth( 2, wxLIST_AUTOSIZE );
- SetColumnWidth( 3, wxLIST_AUTOSIZE );
+ SetColumnWidth(1, wxLIST_AUTOSIZE);
+ SetColumnWidth(2, wxLIST_AUTOSIZE);
+ SetColumnWidth(3, wxLIST_AUTOSIZE);
}
+
+ // Finally, enable/disable context-dependent controls:
+ if ( m_goToParentControl )
+ m_goToParentControl->Enable(!IsTopMostDir(m_dirName));
+#if defined(__DOS__) || defined(__WINDOWS__)
+ if ( m_newDirControl )
+ m_newDirControl->Enable(!IsTopMostDir(m_dirName));
+#endif
}
void wxFileCtrl::SetWild( const wxString &wild )
{
m_wild = wild;
- Update();
+ UpdateFiles();
}
void wxFileCtrl::MakeDir()
{
- wxString new_name( wxT("NewName") );
+ wxString new_name( _("NewName") );
wxString path( m_dirName );
path += wxFILE_SEP_PATH;
path += new_name;
void wxFileCtrl::GoToParentDir()
{
- if (m_dirName != wxT("/"))
+ if (!IsTopMostDir(m_dirName))
{
size_t len = m_dirName.Len();
if (m_dirName[len-1] == wxFILE_SEP_PATH)
m_dirName.Remove( len-1, 1 );
wxString fname( wxFileNameFromPath(m_dirName) );
m_dirName = wxPathOnly( m_dirName );
- if (m_dirName.IsEmpty()) m_dirName = wxT("/");
- Update();
+#ifdef __UNIX__
+ if (m_dirName.IsEmpty())
+ m_dirName = wxT("/");
+#endif
+ UpdateFiles();
long id = FindItem( 0, fname );
if (id != -1)
{
void wxFileCtrl::GoToHomeDir()
{
wxString s = wxGetUserHome( wxString() );
- m_dirName = s;
- Update();
- SetItemState( 0, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED );
- EnsureVisible( 0 );
+ GoToDir(s);
}
void wxFileCtrl::GoToDir( const wxString &dir )
{
m_dirName = dir;
- Update();
+ UpdateFiles();
SetItemState( 0, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED );
EnsureVisible( 0 );
}
// wxFileDialog
//-----------------------------------------------------------------------------
-#define ID_LIST_MODE wxID_FILEDLGG
-#define ID_REPORT_MODE wxID_FILEDLGG + 1
-#define ID_UP_DIR wxID_FILEDLGG + 5
-#define ID_PARENT_DIR wxID_FILEDLGG + 6
-#define ID_NEW_DIR wxID_FILEDLGG + 7
-#define ID_CHOICE wxID_FILEDLGG + 8
-#define ID_TEXT wxID_FILEDLGG + 9
-#define ID_LIST_CTRL wxID_FILEDLGG + 10
-#define ID_ACTIVATED wxID_FILEDLGG + 11
-#define ID_CHECK wxID_FILEDLGG + 12
+#define ID_LIST_MODE (wxID_FILEDLGG )
+#define ID_REPORT_MODE (wxID_FILEDLGG + 1)
+#define ID_UP_DIR (wxID_FILEDLGG + 5)
+#define ID_PARENT_DIR (wxID_FILEDLGG + 6)
+#define ID_NEW_DIR (wxID_FILEDLGG + 7)
+#define ID_CHOICE (wxID_FILEDLGG + 8)
+#define ID_TEXT (wxID_FILEDLGG + 9)
+#define ID_LIST_CTRL (wxID_FILEDLGG + 10)
+#define ID_ACTIVATED (wxID_FILEDLGG + 11)
+#define ID_CHECK (wxID_FILEDLGG + 12)
IMPLEMENT_DYNAMIC_CLASS(wxFileDialog,wxDialog)
const wxPoint& pos ) :
wxDialog( parent, -1, message, pos, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER )
{
- wxBeginBusyCursor();
+ wxBusyCursor bcur;
if (wxConfig::Get(FALSE))
{
- wxConfig::Get() -> Read(wxT("/wxWindows/wxFileDialog/ViewStyle"), &s_lastViewStyle);
- wxConfig::Get() -> Read(wxT("/wxWindows/wxFileDialog/ShowHidden"), &s_lastShowHidden);
+ wxConfig::Get()->Read(wxT("/wxWindows/wxFileDialog/ViewStyle"),
+ &s_lastViewStyle);
+ wxConfig::Get()->Read(wxT("/wxWindows/wxFileDialog/ShowHidden"),
+ &s_lastShowHidden);
}
m_message = message;
buttonsizer->Add( 30, 5, 1 );
- but = new wxBitmapButton( this, ID_UP_DIR, wxBitmap( dir_up_xpm ) );
+ wxWindow *butDirUp =
+ new wxBitmapButton( this, ID_UP_DIR, wxBitmap( dir_up_xpm ) );
#if wxUSE_TOOLTIPS
- but->SetToolTip( _("Go to parent directory") );
+ butDirUp->SetToolTip( _("Go to parent directory") );
#endif
- buttonsizer->Add( but, 0, wxALL, 5 );
+ buttonsizer->Add( butDirUp, 0, wxALL, 5 );
-#ifndef __DOS__ // VS: Home directory is senseless in MS-DOS...
+#ifndef __DOS__ // VS: Home directory is meaningless in MS-DOS...
but = new wxBitmapButton( this, ID_PARENT_DIR, wxBitmap(home_xpm) );
#if wxUSE_TOOLTIPS
but->SetToolTip( _("Go to home directory") );
buttonsizer->Add( 20, 20 );
#endif //!__DOS__
- but = new wxBitmapButton( this, ID_NEW_DIR, wxBitmap(new_dir_xpm) );
+ wxWindow *butNewDir =
+ new wxBitmapButton( this, ID_NEW_DIR, wxBitmap(new_dir_xpm) );
#if wxUSE_TOOLTIPS
- but->SetToolTip( _("Create new directory") );
+ butNewDir->SetToolTip( _("Create new directory") );
#endif
- buttonsizer->Add( but, 0, wxALL, 5 );
+ buttonsizer->Add( butNewDir, 0, wxALL, 5 );
mainsizer->Add( buttonsizer, 0, wxALL | wxEXPAND, 5 );
else
m_list = new wxFileCtrl( this, ID_LIST_CTRL, m_dir, firstWild, wxDefaultPosition,
wxSize(540,200), s_lastViewStyle | wxSUNKEN_BORDER | wxLC_SINGLE_SEL );
- m_list -> ShowHidden(s_lastShowHidden);
+ m_list->ShowHidden(s_lastShowHidden);
+ m_list->SetNewDirControl(butNewDir);
+ m_list->SetGoToParentControl(butDirUp);
+
mainsizer->Add( m_list, 1, wxEXPAND | wxLEFT|wxRIGHT, 10 );
wxBoxSizer *textsizer = new wxBoxSizer( wxHORIZONTAL );
else
*/
m_text->SetFocus();
-
- wxEndBusyCursor();
}
wxFileDialog::~wxFileDialog()
{
if (wxConfig::Get(FALSE))
{
- wxConfig::Get() -> Write(wxT("/wxWindows/wxFileDialog/ViewStyle"), s_lastViewStyle);
- wxConfig::Get() -> Write(wxT("/wxWindows/wxFileDialog/ShowHidden"), s_lastShowHidden);
+ wxConfig::Get()->Write(wxT("/wxWindows/wxFileDialog/ViewStyle"),
+ s_lastViewStyle);
+ wxConfig::Get()->Write(wxT("/wxWindows/wxFileDialog/ShowHidden"),
+ s_lastShowHidden);
}
}
wxString dir;
m_list->GetDir( dir );
- if (dir != wxT("/")) dir += wxFILE_SEP_PATH;
+ if (!IsTopMostDir(dir))
+ dir += wxFILE_SEP_PATH;
dir += filename;
if (wxDirExists(dir)) return;
return;
}
- if (dir != wxT("/")) dir += wxFILE_SEP_PATH;
- if (filename[0u] != wxT('/'))
+ if (!IsTopMostDir(dir))
+ dir += wxFILE_SEP_PATH;
+ if (!wxIsAbsolutePath(filename))
{
dir += filename;
filename = dir;
wxString dir;
m_list->GetDir( dir );
- if (dir != wxT("/")) dir += wxFILE_SEP_PATH;
+#ifdef __UNIX__
+ if (dir != wxT("/"))
+#endif
+ dir += wxFILE_SEP_PATH;
wxListItem item;
item.m_mask = wxLIST_MASK_TEXT;