/////////////////////////////////////////////////////////////////////////////
-// Name: dirctrlg.cpp
+// Name: src/generic/dirctrlg.cpp
// Purpose: wxGenericDirCtrl
// Author: Harm van der Heijden, Robert Roebling, Julian Smart
// Modified by:
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
-#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
-#pragma implementation "dirctrlg.h"
-#endif
-
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
-#pragma hdrstop
+ #pragma hdrstop
#endif
#if wxUSE_DIRDLG || wxUSE_FILEDLG
#include "wx/generic/dirctrlg.h"
-#include "wx/module.h"
-#include "wx/utils.h"
-#include "wx/button.h"
-#include "wx/layout.h"
-#include "wx/msgdlg.h"
-#include "wx/textctrl.h"
-#include "wx/textdlg.h"
+
+#ifndef WX_PRECOMP
+ #include "wx/hash.h"
+ #include "wx/intl.h"
+ #include "wx/log.h"
+ #include "wx/utils.h"
+ #include "wx/button.h"
+ #include "wx/icon.h"
+ #include "wx/settings.h"
+ #include "wx/msgdlg.h"
+ #include "wx/choice.h"
+ #include "wx/textctrl.h"
+ #include "wx/layout.h"
+ #include "wx/sizer.h"
+ #include "wx/textdlg.h"
+ #include "wx/gdicmn.h"
+ #include "wx/image.h"
+ #include "wx/module.h"
+#endif
+
+#include "wx/filename.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"
-#include "wx/settings.h"
#include "wx/artprov.h"
-#include "wx/hash.h"
#include "wx/mimetype.h"
-#include "wx/image.h"
-#include "wx/choice.h"
#if wxUSE_STATLINE
#include "wx/statline.h"
#endif
#if defined(__WXMAC__)
- #include "wx/mac/private.h" // includes mac headers
+ #include "wx/osx/private.h" // includes mac headers
#endif
#ifdef __WXMSW__
#include <windows.h>
#include "wx/msw/winundef.h"
+#include "wx/volume.h"
// FIXME - Mingw32 1.0 has both _getdrive() and _chdrive(). For now, let's assume
// older releases don't, but it should be verified and the checks modified
// accordingly.
#if !defined(__GNUWIN32__) || (defined(__MINGW32_MAJOR_VERSION) && __MINGW32_MAJOR_VERSION >= 1)
#if !defined(__WXWINCE__)
- #include <direct.h>
+ #include <direct.h>
#endif
- #include <stdlib.h>
- #include <ctype.h>
+ #include <stdlib.h>
+ #include <ctype.h>
#endif
#endif
#if defined(__OS2__) || defined(__DOS__)
- #ifdef __OS2__
- #define INCL_BASE
- #include <os2.h>
- #ifndef __EMX__
- #include <direct.h>
+ #ifdef __OS2__
+ #define INCL_BASE
+ #include <os2.h>
+ #ifndef __EMX__
+ #include <direct.h>
+ #endif
+ #include <stdlib.h>
+ #include <ctype.h>
#endif
- #include <stdlib.h>
- #include <ctype.h>
- #endif
- extern bool wxIsDriveAvailable(const wxString& dirName);
#endif // __OS2__
#if defined(__WXMAC__)
-# include "MoreFilesX.h"
+// #include "MoreFilesX.h"
#endif
#ifdef __BORLANDC__
-#include "dos.h"
+ #include "dos.h"
#endif
+extern WXDLLEXPORT_DATA(const char) wxFileSelectorDefaultWildcardStr[];
+
// If compiled under Windows, this macro can cause problems
#ifdef GetFirstChild
#undef GetFirstChild
#endif
+bool wxIsDriveAvailable(const wxString& dirName);
+
// ----------------------------------------------------------------------------
// wxGetAvailableDrives, for WINDOWS, DOS, OS2, MAC, UNIX (returns "/")
// ----------------------------------------------------------------------------
size_t wxGetAvailableDrives(wxArrayString &paths, wxArrayString &names, wxArrayInt &icon_ids)
{
-#if defined(__WINDOWS__) || defined(__DOS__) || defined(__OS2__)
+#ifdef wxHAS_FILESYSTEM_VOLUMES
#ifdef __WXWINCE__
// No logical drives; return "\"
paths.Add(wxT("\\"));
names.Add(wxT("\\"));
icon_ids.Add(wxFileIconsTable::computer);
-#elif defined(__WIN32__)
- wxChar driveBuffer[256];
- size_t n = (size_t) GetLogicalDriveStrings(255, driveBuffer);
- size_t i = 0;
- while (i < n)
- {
- wxString path, name;
- path.Printf(wxT("%c:\\"), driveBuffer[i]);
- name.Printf(wxT("%c:"), driveBuffer[i]);
+#elif defined(__WIN32__) && wxUSE_FSVOLUME
+ // TODO: this code (using wxFSVolumeBase) should be used for all platforms
+ // but unfortunately wxFSVolumeBase is not implemented everywhere
+ const wxArrayString as = wxFSVolumeBase::GetVolumes();
+ for (size_t i = 0; i < as.GetCount(); i++)
+ {
+ wxString path = as[i];
+ wxFSVolume vol(path);
int imageId;
- int driveType = ::GetDriveType(path);
- switch (driveType)
+ switch (vol.GetKind())
{
- case DRIVE_REMOVABLE:
- if (path == wxT("a:\\") || path == wxT("b:\\"))
+ case wxFS_VOL_FLOPPY:
+ if ( (path == wxT("a:\\")) || (path == wxT("b:\\")) )
imageId = wxFileIconsTable::floppy;
else
imageId = wxFileIconsTable::removeable;
break;
- case DRIVE_CDROM:
+ case wxFS_VOL_DVDROM:
+ case wxFS_VOL_CDROM:
imageId = wxFileIconsTable::cdrom;
break;
- case DRIVE_REMOTE:
- case DRIVE_FIXED:
+ case wxFS_VOL_NETWORK:
+ if (path[0] == wxT('\\'))
+ continue; // skip "\\computer\folder"
+ imageId = wxFileIconsTable::drive;
+ break;
+ case wxFS_VOL_DISK:
+ case wxFS_VOL_OTHER:
default:
imageId = wxFileIconsTable::drive;
break;
}
-
paths.Add(path);
- names.Add(name);
+ names.Add(vol.GetDisplayName());
icon_ids.Add(imageId);
-
- while (driveBuffer[i] != wxT('\0'))
- i ++;
- i ++;
- if (driveBuffer[i] == wxT('\0'))
- break;
}
#elif defined(__OS2__)
APIRET rc;
{
if (ulDriveMap & ( 1 << i ))
{
- wxString path, name;
- path.Printf(wxT("%c:\\"), 'A' + i);
- name.Printf(wxT("%c:"), 'A' + i);
-
+ const wxString path = wxFileName::GetVolumeString(
+ 'A' + i, wxPATH_GET_SEPARATOR);
+ const wxString name = wxFileName::GetVolumeString(
+ 'A' + i, wxPATH_NO_SEPARATOR);
+
+ // Note: If _filesys is unsupported by some compilers,
+ // we can always replace it by DosQueryFSAttach
+ char filesysname[20];
+#ifdef __WATCOMC__
+ ULONG cbBuffer = sizeof(filesysname);
+ PFSQBUFFER2 pfsqBuffer = (PFSQBUFFER2)filesysname;
+ APIRET rc = ::DosQueryFSAttach(name.fn_str(),0,FSAIL_QUERYNAME,pfsqBuffer,&cbBuffer);
+ if (rc != NO_ERROR)
+ {
+ filesysname[0] = '\0';
+ }
+#else
+ _filesys(name.fn_str(), filesysname, sizeof(filesysname));
+#endif
+ /* FAT, LAN, HPFS, CDFS, NFS */
int imageId;
if (path == wxT("A:\\") || path == wxT("B:\\"))
imageId = wxFileIconsTable::floppy;
+ else if (!strcmp(filesysname, "CDFS"))
+ imageId = wxFileIconsTable::cdrom;
+ else if (!strcmp(filesysname, "LAN") ||
+ !strcmp(filesysname, "NFS"))
+ imageId = wxFileIconsTable::drive;
else
imageId = wxFileIconsTable::drive;
paths.Add(path);
}
}
#else // !__WIN32__, !__OS2__
- int drive;
-
/* If we can switch to the drive, it exists. */
- for( drive = 1; drive <= 26; drive++ )
+ for ( char drive = 'A'; drive <= 'Z'; drive++ )
{
- wxString path, name;
- path.Printf(wxT("%c:\\"), (char) (drive + 'a' - 1));
- name.Printf(wxT("%c:"), (char) (drive + 'A' - 1));
+ const wxString
+ path = wxFileName::GetVolumeString(drive, wxPATH_GET_SEPARATOR);
if (wxIsDriveAvailable(path))
{
paths.Add(path);
- names.Add(name);
- icon_ids.Add((drive <= 2) ? wxFileIconsTable::floppy : wxFileIconsTable::drive);
+ names.Add(wxFileName::GetVolumeString(drive, wxPATH_NO_SEPARATOR));
+ icon_ids.Add(drive <= 2 ? wxFileIconsTable::floppy
+ : wxFileIconsTable::drive);
}
}
#endif // __WIN32__/!__WIN32__
-#elif defined(__WXMAC__)
+#elif defined(__WXMAC__) && wxOSX_USE_COCOA_OR_CARBON
ItemCount volumeIndex = 1;
OSErr err = noErr ;
}
}
-#elif defined(__UNIX__)
+#elif defined(__UNIX__) || defined(__WXPALMOS__)
paths.Add(wxT("/"));
names.Add(wxT("/"));
icon_ids.Add(wxFileIconsTable::computer);
bool wxIsDriveAvailable(const wxString& dirName)
{
// FIXME_MGL - this method leads to hang up under Watcom for some reason
-#ifndef __WATCOMC__
- if ( dirName.Len() == 3 && dirName[1u] == wxT(':') )
+#ifdef __WATCOMC__
+ wxUnusedVar(dirName);
+#else
+ if ( dirName.length() == 3 && dirName[1u] == wxT(':') )
{
wxString dirNameLower(dirName.Lower());
// VS: always return true for removable media, since Win95 doesn't
// like it when MS-DOS app accesses empty floppy drive
return (dirNameLower[0u] == wxT('a') ||
dirNameLower[0u] == wxT('b') ||
- wxPathExists(dirNameLower));
+ wxDirExists(dirNameLower));
}
else
#endif
#elif defined(__WINDOWS__) || defined(__OS2__)
-int setdrive(int drive)
+int setdrive(int WXUNUSED_IN_WINCE(drive))
{
#ifdef __WXWINCE__
- wxUnusedVar(drive);
return 0;
#elif defined(__GNUWIN32__) && \
(defined(__MINGW32_MAJOR_VERSION) && __MINGW32_MAJOR_VERSION >= 1)
#endif // !GNUWIN32
}
-bool wxIsDriveAvailable(const wxString& dirName)
+bool wxIsDriveAvailable(const wxString& WXUNUSED_IN_WINCE(dirName))
{
#ifdef __WXWINCE__
- wxUnusedVar(dirName);
return false;
#else
#ifdef __WIN32__
// Check if this is a root directory and if so,
// whether the drive is available.
- if (dirName.Len() == 3 && dirName[(size_t)1] == wxT(':'))
+ if (dirName.length() == 3 && dirName[(size_t)1] == wxT(':'))
{
wxString dirNameLower(dirName.Lower());
#if defined(__GNUWIN32__) && !(defined(__MINGW32_MAJOR_VERSION) && __MINGW32_MAJOR_VERSION >= 1)
- success = wxPathExists(dirNameLower);
+ success = wxDirExists(dirNameLower);
#else
#if defined(__OS2__)
// Avoid changing to drive since no media may be inserted.
// wxGenericDirCtrl
//-----------------------------------------------------------------------------
-
-#if wxUSE_EXTENDED_RTTI
-WX_DEFINE_FLAGS( wxGenericDirCtrlStyle )
-
-wxBEGIN_FLAGS( wxGenericDirCtrlStyle )
- // new style border flags, we put them first to
- // use them for streaming out
- wxFLAGS_MEMBER(wxBORDER_SIMPLE)
- wxFLAGS_MEMBER(wxBORDER_SUNKEN)
- wxFLAGS_MEMBER(wxBORDER_DOUBLE)
- wxFLAGS_MEMBER(wxBORDER_RAISED)
- wxFLAGS_MEMBER(wxBORDER_STATIC)
- wxFLAGS_MEMBER(wxBORDER_NONE)
-
- // old style border flags
- wxFLAGS_MEMBER(wxSIMPLE_BORDER)
- wxFLAGS_MEMBER(wxSUNKEN_BORDER)
- wxFLAGS_MEMBER(wxDOUBLE_BORDER)
- wxFLAGS_MEMBER(wxRAISED_BORDER)
- wxFLAGS_MEMBER(wxSTATIC_BORDER)
- wxFLAGS_MEMBER(wxBORDER)
-
- // standard window styles
- wxFLAGS_MEMBER(wxTAB_TRAVERSAL)
- wxFLAGS_MEMBER(wxCLIP_CHILDREN)
- wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW)
- wxFLAGS_MEMBER(wxWANTS_CHARS)
- wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE)
- wxFLAGS_MEMBER(wxALWAYS_SHOW_SB )
- wxFLAGS_MEMBER(wxVSCROLL)
- wxFLAGS_MEMBER(wxHSCROLL)
-
- wxFLAGS_MEMBER(wxDIRCTRL_DIR_ONLY)
- wxFLAGS_MEMBER(wxDIRCTRL_3D_INTERNAL)
- wxFLAGS_MEMBER(wxDIRCTRL_SELECT_FIRST)
- wxFLAGS_MEMBER(wxDIRCTRL_SHOW_FILTERS)
-
-wxEND_FLAGS( wxGenericDirCtrlStyle )
-
-IMPLEMENT_DYNAMIC_CLASS_XTI(wxGenericDirCtrl, wxControl,"wx/dirctrl.h")
-
-wxBEGIN_PROPERTIES_TABLE(wxGenericDirCtrl)
- wxHIDE_PROPERTY( Children )
- wxPROPERTY( DefaultPath , wxString , SetDefaultPath , GetDefaultPath , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
- wxPROPERTY( Filter , wxString , SetFilter , GetFilter , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group") )
- wxPROPERTY( DefaultFilter , int , SetFilterIndex, GetFilterIndex, EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group") )
- wxPROPERTY_FLAGS( WindowStyle, wxGenericDirCtrlStyle, long, SetWindowStyleFlag, GetWindowStyleFlag, EMPTY_MACROVALUE , 0, wxT("Helpstring"), wxT("group") )
-wxEND_PROPERTIES_TABLE()
-
-wxBEGIN_HANDLERS_TABLE(wxGenericDirCtrl)
-wxEND_HANDLERS_TABLE()
-
-wxCONSTRUCTOR_8( wxGenericDirCtrl , wxWindow* , Parent , wxWindowID , Id , wxString , DefaultPath ,
- wxPoint , Position , wxSize , Size , long , WindowStyle , wxString , Filter , int , DefaultFilter )
-#else
-IMPLEMENT_DYNAMIC_CLASS(wxGenericDirCtrl, wxControl)
-#endif
-
BEGIN_EVENT_TABLE(wxGenericDirCtrl, wxControl)
EVT_TREE_ITEM_EXPANDING (wxID_TREECTRL, wxGenericDirCtrl::OnExpandItem)
EVT_TREE_ITEM_COLLAPSED (wxID_TREECTRL, wxGenericDirCtrl::OnCollapseItem)
Init();
}
+void wxGenericDirCtrl::ExpandRoot()
+{
+ ExpandDir(m_rootId); // automatically expand first level
+
+ // Expand and select the default path
+ if (!m_defaultPath.empty())
+ {
+ ExpandPath(m_defaultPath);
+ }
+#ifdef __UNIX__
+ else
+ {
+ // On Unix, there's only one node under the (hidden) root node. It
+ // represents the / path, so the user would always have to expand it;
+ // let's do it ourselves
+ ExpandPath( wxT("/") );
+ }
+#endif
+}
+
bool wxGenericDirCtrl::Create(wxWindow *parent,
- const wxWindowID id,
+ const wxWindowID treeid,
const wxString& dir,
const wxPoint& pos,
const wxSize& size,
int defaultFilter,
const wxString& name)
{
- if (!wxControl::Create(parent, id, pos, size, style, wxDefaultValidator, name))
+ if (!wxControl::Create(parent, treeid, pos, size, style, wxDefaultValidator, name))
return false;
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
+ SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
Init();
- long treeStyle = wxTR_HAS_BUTTONS | wxTR_HIDE_ROOT;
+ long treeStyle = wxTR_HAS_BUTTONS;
+
+ // On Windows CE, if you hide the root, you get a crash when
+ // attempting to access data for children of the root item.
+#ifndef __WXWINCE__
+ treeStyle |= wxTR_HIDE_ROOT;
+#endif
#ifdef __WXGTK20__
treeStyle |= wxTR_NO_LINES;
if (style & wxDIRCTRL_EDIT_LABELS)
treeStyle |= wxTR_EDIT_LABELS;
- if ((style & wxDIRCTRL_3D_INTERNAL) == 0)
- treeStyle |= wxNO_BORDER;
- else
- treeStyle |= wxBORDER_SUNKEN;
+ if (style & wxDIRCTRL_MULTIPLE)
+ treeStyle |= wxTR_MULTIPLE;
- long filterStyle = 0;
if ((style & wxDIRCTRL_3D_INTERNAL) == 0)
- filterStyle |= wxNO_BORDER;
- else
- filterStyle |= wxBORDER_SUNKEN;
+ treeStyle |= wxNO_BORDER;
m_treeCtrl = CreateTreeCtrl(this, wxID_TREECTRL,
wxPoint(0,0), GetClientSize(), treeStyle);
- if (!filter.empty() && (style & wxDIRCTRL_SHOW_FILTERS))
- m_filterListCtrl = new wxDirFilterListCtrl(this, wxID_FILTERLISTCTRL, wxDefaultPosition, wxDefaultSize, filterStyle);
+ if (!filter.empty())
+ m_filterListCtrl = new wxDirFilterListCtrl(this, wxID_FILTERLISTCTRL);
m_defaultPath = dir;
m_filter = filter;
+ if (m_filter.empty())
+ m_filter = wxFileSelectorDefaultWildcardStr;
+
SetFilterIndex(defaultFilter);
if (m_filterListCtrl)
m_rootId = m_treeCtrl->AddRoot( rootName, 3, -1, rootData);
m_treeCtrl->SetItemHasChildren(m_rootId);
- ExpandDir(m_rootId); // automatically expand first level
- // Expand and select the default path
- if (!m_defaultPath.empty())
- {
- ExpandPath(m_defaultPath);
- }
-#ifdef __UNIX__
- else
- {
- // On Unix, there's only one node under the (hidden) root node. It
- // represents the / path, so the user would always have to expand it;
- // let's do it ourselves
- ExpandPath( wxT("/") );
- }
-#endif
+ ExpandRoot();
- SetBestSize(size);
+ SetInitialSize(size);
DoResize();
return true;
m_filterListCtrl = NULL;
}
-wxTreeCtrl* wxGenericDirCtrl::CreateTreeCtrl(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long treeStyle)
+wxTreeCtrl* wxGenericDirCtrl::CreateTreeCtrl(wxWindow *parent, wxWindowID treeid, const wxPoint& pos, const wxSize& size, long treeStyle)
{
- return new wxTreeCtrl(parent, id, pos, size, treeStyle);
+ return new wxTreeCtrl(parent, treeid, pos, size, treeStyle);
}
void wxGenericDirCtrl::ShowHidden( bool show )
{
+ if ( m_showHidden == show )
+ return;
+
m_showHidden = show;
- wxString path = GetPath();
- ReCreateTree();
- SetPath(path);
+ if ( HasFlag(wxDIRCTRL_MULTIPLE) )
+ {
+ wxArrayString paths;
+ GetPaths(paths);
+ ReCreateTree();
+ for ( unsigned n = 0; n < paths.size(); n++ )
+ {
+ ExpandPath(paths[n]);
+ }
+ }
+ else
+ {
+ wxString path = GetPath();
+ ReCreateTree();
+ SetPath(path);
+ }
}
const wxTreeItemId
{
wxDirItemData *dir_item = new wxDirItemData(path,name,true);
- wxTreeItemId id = AppendItem( m_rootId, name, imageId, -1, dir_item);
+ wxTreeItemId treeid = AppendItem( m_rootId, name, imageId, -1, dir_item);
- m_treeCtrl->SetItemHasChildren(id);
+ m_treeCtrl->SetItemHasChildren(treeid);
- return id;
+ return treeid;
}
void wxGenericDirCtrl::SetupSections()
AddSection(paths[n], names[n], icons[n]);
}
+void wxGenericDirCtrl::SetFocus()
+{
+ // we don't need focus ourselves, give it to the tree so that the user
+ // could navigate it
+ if (m_treeCtrl)
+ m_treeCtrl->SetFocus();
+}
+
void wxGenericDirCtrl::OnBeginEditItem(wxTreeEvent &event)
{
// don't rename the main entry "Sections"
void wxGenericDirCtrl::OnEndEditItem(wxTreeEvent &event)
{
+ if (event.IsEditCancelled())
+ return;
+
if ((event.GetLabel().empty()) ||
- (event.GetLabel() == _(".")) ||
- (event.GetLabel() == _("..")) ||
+ (event.GetLabel() == wxT(".")) ||
+ (event.GetLabel() == wxT("..")) ||
(event.GetLabel().Find(wxT('/')) != wxNOT_FOUND) ||
(event.GetLabel().Find(wxT('\\')) != wxNOT_FOUND) ||
(event.GetLabel().Find(wxT('|')) != wxNOT_FOUND))
return;
}
- wxTreeItemId id = event.GetItem();
- wxDirItemData *data = (wxDirItemData*)m_treeCtrl->GetItemData( id );
+ wxTreeItemId treeid = event.GetItem();
+ wxDirItemData *data = (wxDirItemData*)m_treeCtrl->GetItemData( treeid );
wxASSERT( data );
wxString new_name( wxPathOnly( data->m_path ) );
// ctor when wxTR_HIDE_ROOT was specified
if (!m_rootId.IsOk())
-
m_rootId = m_treeCtrl->GetRootItem();
ExpandDir(parentId);
return;
data->m_isExpanded = false;
- wxTreeItemIdValue cookie;
- /* Workaround because DeleteChildren has disapeared (why?) and
- * CollapseAndReset doesn't work as advertised (deletes parent too) */
- child = m_treeCtrl->GetFirstChild(parentId, cookie);
- while (child.IsOk())
- {
- m_treeCtrl->Delete(child);
- /* Not GetNextChild below, because the cookie mechanism can't
- * handle disappearing children! */
- child = m_treeCtrl->GetFirstChild(parentId, cookie);
- }
+
+ m_treeCtrl->Freeze();
+ if (parentId != m_treeCtrl->GetRootItem())
+ m_treeCtrl->CollapseAndReset(parentId);
+ m_treeCtrl->DeleteChildren(parentId);
+ m_treeCtrl->Thaw();
}
-void wxGenericDirCtrl::ExpandDir(wxTreeItemId parentId)
+void wxGenericDirCtrl::PopulateNode(wxTreeItemId parentId)
{
wxDirItemData *data = (wxDirItemData *) m_treeCtrl->GetItemData(parentId);
wxString dirName(data->m_path);
-#if defined(__WINDOWS__) || defined(__DOS__) || defined(__OS2__)
+#if (defined(__WINDOWS__) && !defined(__WXWINCE__)) || defined(__DOS__) || defined(__OS2__)
// Check if this is a root directory and if so,
// whether the drive is avaiable.
if (!wxIsDriveAvailable(dirName))
dirs.Sort(wxDirCtrlStringCompareFunction);
// Now do the filenames -- but only if we're allowed to
- if ((GetWindowStyle() & wxDIRCTRL_DIR_ONLY) == 0)
+ if (!HasFlag(wxDIRCTRL_DIR_ONLY))
{
- wxLogNull log;
-
d.Open(dirName);
if (d.IsOpened())
filenames.Sort(wxDirCtrlStringCompareFunction);
}
+ // Now we really know whether we have any children so tell the tree control
+ // about it.
+ m_treeCtrl->SetItemHasChildren(parentId, !dirs.empty() || !filenames.empty());
+
// Add the sorted dirs
size_t i;
- for (i = 0; i < dirs.Count(); i++)
+ for (i = 0; i < dirs.GetCount(); i++)
{
- wxString eachFilename(dirs[i]);
+ eachFilename = dirs[i];
path = dirName;
if (!wxEndsWithPathSeparator(path))
path += wxString(wxFILE_SEP_PATH);
path += eachFilename;
wxDirItemData *dir_item = new wxDirItemData(path,eachFilename,true);
- wxTreeItemId id = AppendItem( parentId, eachFilename,
+ wxTreeItemId treeid = AppendItem( parentId, eachFilename,
wxFileIconsTable::folder, -1, dir_item);
- m_treeCtrl->SetItemImage( id, wxFileIconsTable::folder_open,
+ m_treeCtrl->SetItemImage( treeid, wxFileIconsTable::folder_open,
wxTreeItemIcon_Expanded );
- // Has this got any children? If so, make it expandable.
- // (There are two situations when a dir has children: either it
- // 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)) )
- {
- m_treeCtrl->SetItemHasChildren(id);
- }
+ // assume that it does have children by default as it can take a long
+ // time to really check for this (think remote drives...)
+ //
+ // and if we're wrong, we'll correct the icon later if
+ // the user really tries to open this item
+ m_treeCtrl->SetItemHasChildren(treeid);
}
// Add the sorted filenames
- if ((GetWindowStyle() & wxDIRCTRL_DIR_ONLY) == 0)
+ if (!HasFlag(wxDIRCTRL_DIR_ONLY))
{
- for (i = 0; i < filenames.Count(); i++)
+ for (i = 0; i < filenames.GetCount(); i++)
{
- wxString eachFilename(filenames[i]);
+ eachFilename = filenames[i];
path = dirName;
if (!wxEndsWithPathSeparator(path))
path += wxString(wxFILE_SEP_PATH);
}
}
+void wxGenericDirCtrl::ExpandDir(wxTreeItemId parentId)
+{
+ // ExpandDir() will not actually expand the tree node, just populate it
+ PopulateNode(parentId);
+}
+
void wxGenericDirCtrl::ReCreateTree()
{
CollapseDir(m_treeCtrl->GetRootItem());
- ExpandDir(m_treeCtrl->GetRootItem());
+ ExpandRoot();
+}
+
+void wxGenericDirCtrl::CollapseTree()
+{
+ wxTreeItemIdValue cookie;
+ wxTreeItemId child = m_treeCtrl->GetFirstChild(m_rootId, cookie);
+ while (child.IsOk())
+ {
+ CollapseDir(child);
+ child = m_treeCtrl->GetNextChild(m_rootId, cookie);
+ }
}
// Find the child that matches the first part of 'path'.
childPath.MakeLower();
#endif
- if (childPath.Len() <= path2.Len())
+ if (childPath.length() <= path2.length())
{
- wxString path3 = path2.Mid(0, childPath.Len());
+ wxString path3 = path2.Mid(0, childPath.length());
if (childPath == path3)
{
- if (path3.Len() == path2.Len())
+ if (path3.length() == path2.length())
done = true;
else
done = false;
bool wxGenericDirCtrl::ExpandPath(const wxString& path)
{
bool done = false;
- wxTreeItemId id = FindChild(m_rootId, path, done);
- wxTreeItemId lastId = id; // The last non-zero id
- while (id.IsOk() && !done)
+ wxTreeItemId treeid = FindChild(m_rootId, path, done);
+ wxTreeItemId lastId = treeid; // The last non-zero treeid
+ while (treeid.IsOk() && !done)
{
- ExpandDir(id);
+ ExpandDir(treeid);
+
+ treeid = FindChild(treeid, path, done);
+ if (treeid.IsOk())
+ lastId = treeid;
+ }
+ if (!lastId.IsOk())
+ return false;
- id = FindChild(id, path, done);
- if (id.IsOk())
- lastId = id;
+ wxDirItemData *data = (wxDirItemData *) m_treeCtrl->GetItemData(lastId);
+ if (data->m_isDir)
+ {
+ m_treeCtrl->Expand(lastId);
}
- if (lastId.IsOk())
+ if (HasFlag(wxDIRCTRL_SELECT_FIRST) && data->m_isDir)
{
- wxDirItemData *data = (wxDirItemData *) m_treeCtrl->GetItemData(lastId);
- if (data->m_isDir)
+ // Find the first file in this directory
+ wxTreeItemIdValue cookie;
+ wxTreeItemId childId = m_treeCtrl->GetFirstChild(lastId, cookie);
+ bool selectedChild = false;
+ while (childId.IsOk())
{
- m_treeCtrl->Expand(lastId);
- }
- if ((GetWindowStyle() & wxDIRCTRL_SELECT_FIRST) && data->m_isDir)
- {
- // Find the first file in this directory
- wxTreeItemIdValue cookie;
- wxTreeItemId childId = m_treeCtrl->GetFirstChild(lastId, cookie);
- bool selectedChild = false;
- while (childId.IsOk())
- {
- wxDirItemData* data = (wxDirItemData*) m_treeCtrl->GetItemData(childId);
+ data = (wxDirItemData*) m_treeCtrl->GetItemData(childId);
- if (data && data->m_path != wxEmptyString && !data->m_isDir)
- {
- m_treeCtrl->SelectItem(childId);
- m_treeCtrl->EnsureVisible(childId);
- selectedChild = true;
- break;
- }
- childId = m_treeCtrl->GetNextChild(lastId, cookie);
- }
- if (!selectedChild)
+ if (data && data->m_path != wxEmptyString && !data->m_isDir)
{
- m_treeCtrl->SelectItem(lastId);
- m_treeCtrl->EnsureVisible(lastId);
+ m_treeCtrl->SelectItem(childId);
+ m_treeCtrl->EnsureVisible(childId);
+ selectedChild = true;
+ break;
}
+ childId = m_treeCtrl->GetNextChild(lastId, cookie);
}
- else
+ if (!selectedChild)
{
m_treeCtrl->SelectItem(lastId);
m_treeCtrl->EnsureVisible(lastId);
}
-
- return true;
}
else
+ {
+ m_treeCtrl->SelectItem(lastId);
+ m_treeCtrl->EnsureVisible(lastId);
+ }
+
+ return true;
+}
+
+
+bool wxGenericDirCtrl::CollapsePath(const wxString& path)
+{
+ bool done = false;
+ wxTreeItemId treeid = FindChild(m_rootId, path, done);
+ wxTreeItemId lastId = treeid; // The last non-zero treeid
+
+ while ( treeid.IsOk() && !done )
+ {
+ CollapseDir(treeid);
+
+ treeid = FindChild(treeid, path, done);
+
+ if ( treeid.IsOk() )
+ lastId = treeid;
+ }
+
+ if ( !lastId.IsOk() )
return false;
+
+ m_treeCtrl->SelectItem(lastId);
+ m_treeCtrl->EnsureVisible(lastId);
+
+ return true;
}
+
wxString wxGenericDirCtrl::GetPath() const
{
- wxTreeItemId id = m_treeCtrl->GetSelection();
- if (id)
+ // Allow calling GetPath() in multiple selection from OnSelFilter
+ if (m_treeCtrl->HasFlag(wxTR_MULTIPLE))
{
- wxDirItemData* data = (wxDirItemData*) m_treeCtrl->GetItemData(id);
+ wxArrayTreeItemIds items;
+ m_treeCtrl->GetSelections(items);
+ if (items.size() > 0)
+ {
+ // return first string only
+ wxTreeItemId treeid = items[0];
+ wxDirItemData* data = (wxDirItemData*) m_treeCtrl->GetItemData(treeid);
+ return data->m_path;
+ }
+
+ return wxEmptyString;
+ }
+
+ wxTreeItemId treeid = m_treeCtrl->GetSelection();
+ if (treeid)
+ {
+ wxDirItemData* data = (wxDirItemData*) m_treeCtrl->GetItemData(treeid);
return data->m_path;
}
else
return wxEmptyString;
}
+void wxGenericDirCtrl::GetPaths(wxArrayString& paths) const
+{
+ paths.clear();
+
+ wxArrayTreeItemIds items;
+ m_treeCtrl->GetSelections(items);
+ for ( unsigned n = 0; n < items.size(); n++ )
+ {
+ wxTreeItemId treeid = items[n];
+ wxDirItemData* data = (wxDirItemData*) m_treeCtrl->GetItemData(treeid);
+ paths.Add(data->m_path);
+ }
+}
+
wxString wxGenericDirCtrl::GetFilePath() const
{
- wxTreeItemId id = m_treeCtrl->GetSelection();
- if (id)
+ wxTreeItemId treeid = m_treeCtrl->GetSelection();
+ if (treeid)
{
- wxDirItemData* data = (wxDirItemData*) m_treeCtrl->GetItemData(id);
+ wxDirItemData* data = (wxDirItemData*) m_treeCtrl->GetItemData(treeid);
if (data->m_isDir)
return wxEmptyString;
else
return wxEmptyString;
}
+void wxGenericDirCtrl::GetFilePaths(wxArrayString& paths) const
+{
+ paths.clear();
+
+ wxArrayTreeItemIds items;
+ m_treeCtrl->GetSelections(items);
+ for ( unsigned n = 0; n < items.size(); n++ )
+ {
+ wxTreeItemId treeid = items[n];
+ wxDirItemData* data = (wxDirItemData*) m_treeCtrl->GetItemData(treeid);
+ if ( !data->m_isDir )
+ paths.Add(data->m_path);
+ }
+}
+
void wxGenericDirCtrl::SetPath(const wxString& path)
{
m_defaultPath = path;
ExpandPath(path);
}
+void wxGenericDirCtrl::SelectPath(const wxString& path, bool select)
+{
+ bool done = false;
+ wxTreeItemId treeid = FindChild(m_rootId, path, done);
+ wxTreeItemId lastId = treeid; // The last non-zero treeid
+ while ( treeid.IsOk() && !done )
+ {
+ treeid = FindChild(treeid, path, done);
+ if ( treeid.IsOk() )
+ lastId = treeid;
+ }
+ if ( !lastId.IsOk() )
+ return;
+
+ if ( done )
+ {
+ m_treeCtrl->SelectItem(treeid, select);
+ }
+}
+
+void wxGenericDirCtrl::SelectPaths(const wxArrayString& paths)
+{
+ if ( HasFlag(wxDIRCTRL_MULTIPLE) )
+ {
+ UnselectAll();
+ for ( unsigned n = 0; n < paths.size(); n++ )
+ {
+ SelectPath(paths[n]);
+ }
+ }
+}
+
+void wxGenericDirCtrl::UnselectAll()
+{
+ m_treeCtrl->UnselectAll();
+}
+
// Not used
#if 0
-void wxGenericDirCtrl::FindChildFiles(wxTreeItemId id, int dirFlags, wxArrayString& filenames)
+void wxGenericDirCtrl::FindChildFiles(wxTreeItemId treeid, int dirFlags, wxArrayString& filenames)
{
- wxDirItemData *data = (wxDirItemData *) m_treeCtrl->GetItemData(id);
+ wxDirItemData *data = (wxDirItemData *) m_treeCtrl->GetItemData(treeid);
// This may take a longish time. Go to busy cursor
wxBusyCursor busy;
if (ExtractWildcard(m_filter, n, f, d))
m_currentFilterStr = f;
else
+#ifdef __UNIX__
+ m_currentFilterStr = wxT("*");
+#else
m_currentFilterStr = wxT("*.*");
+#endif
}
void wxGenericDirCtrl::SetFilter(const wxString& filter)
{
m_filter = filter;
+ if (!filter.empty() && !m_filterListCtrl)
+ m_filterListCtrl = new wxDirFilterListCtrl(this, wxID_FILTERLISTCTRL);
+ else if (filter.empty() && m_filterListCtrl)
+ {
+ m_filterListCtrl->Destroy();
+ m_filterListCtrl = NULL;
+ }
+
wxString f, d;
if (ExtractWildcard(m_filter, m_currentFilter, f, d))
m_currentFilterStr = f;
else
+#ifdef __UNIX__
+ m_currentFilterStr = wxT("*");
+#else
m_currentFilterStr = wxT("*.*");
+#endif
+ // current filter index is meaningless after filter change, set it to zero
+ SetFilterIndex(0);
+ if (m_filterListCtrl)
+ m_filterListCtrl->FillFilterList(m_filter, 0);
}
// Extract description and actual filter from overall filter string
return false;
}
-#if WXWIN_COMPATIBILITY_2_4
-// Parses the global filter, returning the number of filters.
-// Returns 0 if none or if there's a problem.
-// filterStr is in the form: "All files (*.*)|*.*|JPEG Files (*.jpeg)|*.jpg"
-int wxGenericDirCtrl::ParseFilter(const wxString& filterStr, wxArrayString& filters, wxArrayString& descriptions)
-{
- return wxParseCommonDialogsFilter(filterStr, descriptions, filters );
-}
-#endif // WXWIN_COMPATIBILITY_2_4
void wxGenericDirCtrl::DoResize()
{
wxSize filterSz ;
if (m_filterListCtrl)
{
-#ifdef __WXMSW__
- // For some reason, this is required in order for the
- // correct control height to always be returned, rather
- // than the drop-down list height which is sometimes returned.
- wxSize oldSize = m_filterListCtrl->GetSize();
- m_filterListCtrl->SetSize(wxDefaultCoord,
- wxDefaultCoord,
- oldSize.x+10,
- wxDefaultCoord,
- wxSIZE_USE_EXISTING);
- m_filterListCtrl->SetSize(wxDefaultCoord,
- wxDefaultCoord,
- oldSize.x,
- wxDefaultCoord,
- wxSIZE_USE_EXISTING);
-#endif
filterSz = m_filterListCtrl->GetSize();
sz.y -= (filterSz.y + verticalSpacing);
}
EVT_CHOICE(wxID_ANY, wxDirFilterListCtrl::OnSelFilter)
END_EVENT_TABLE()
-bool wxDirFilterListCtrl::Create(wxGenericDirCtrl* parent, const wxWindowID id,
- const wxPoint& pos,
- const wxSize& size,
- long style)
+bool wxDirFilterListCtrl::Create(wxGenericDirCtrl* parent,
+ const wxWindowID treeid,
+ const wxPoint& pos,
+ const wxSize& size,
+ long style)
{
m_dirCtrl = parent;
- return wxChoice::Create(parent, id, pos, size, 0, NULL, style);
+
+ // by default our border style is determined by the style of our parent
+ if ( !(style & wxBORDER_MASK) )
+ {
+ style |= parent->HasFlag(wxDIRCTRL_3D_INTERNAL) ? wxBORDER_SUNKEN
+ : wxBORDER_NONE;
+ }
+
+ return wxChoice::Create(parent, treeid, pos, size, 0, NULL, style);
}
void wxDirFilterListCtrl::Init()
{
int sel = GetSelection();
- wxString currentPath = m_dirCtrl->GetPath();
+ if (m_dirCtrl->HasFlag(wxDIRCTRL_MULTIPLE))
+ {
+ wxArrayString paths;
+ m_dirCtrl->GetPaths(paths);
+
+ m_dirCtrl->SetFilterIndex(sel);
- m_dirCtrl->SetFilterIndex(sel);
+ // If the filter has changed, the view is out of date, so
+ // collapse the tree.
+ m_dirCtrl->ReCreateTree();
- // If the filter has changed, the view is out of date, so
- // collapse the tree.
- m_dirCtrl->ReCreateTree();
+ // Expand and select the previously selected paths
+ for (unsigned int i = 0; i < paths.GetCount(); i++)
+ {
+ m_dirCtrl->ExpandPath(paths.Item(i));
+ }
+ }
+ else
+ {
+ wxString currentPath = m_dirCtrl->GetPath();
- // Try to restore the selection, or at least the directory
- m_dirCtrl->ExpandPath(currentPath);
+ m_dirCtrl->SetFilterIndex(sel);
+ m_dirCtrl->ReCreateTree();
+
+ // Try to restore the selection, or at least the directory
+ m_dirCtrl->ExpandPath(currentPath);
+ }
}
void wxDirFilterListCtrl::FillFilterList(const wxString& filter, int defaultFilter)
// wxFileIconsTable icons
// ----------------------------------------------------------------------------
-#ifndef __WXGTK24__
-/* Computer */
-static const char * file_icons_tbl_computer_xpm[] = {
-"16 16 7 1",
-" s None c None",
-". c #808080",
-"X c #c0c0c0",
-"o c Black",
-"O c Gray100",
-"+ c #008080",
-"@ c Blue",
-" ........... ",
-" .XXXXXXXXXX.o",
-" .OOOOOOOOO..o",
-" .OoooooooX..o",
-" .Oo+...@+X..o",
-" .Oo+XXX.+X..o",
-" .Oo+....+X..o",
-" .Oo++++++X..o",
-" .OXXXXXXXX.oo",
-" ..........o.o",
-" ...........Xo",
-" .XXXXXXXXXX.o",
-" .o.o.o.o.o...o",
-" .oXoXoXoXoXo.o ",
-".XOXXXXXXXXX.o ",
-"............o "};
-#endif // GTK+ < 2.4
+#ifndef __WXGTK20__
+/* Computer (c) Julian Smart */
+static const char* const file_icons_tbl_computer_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 42 1",
+"r c #4E7FD0",
+"$ c #7198D9",
+"; c #DCE6F6",
+"q c #FFFFFF",
+"u c #4A7CCE",
+"# c #779DDB",
+"w c #95B2E3",
+"y c #7FA2DD",
+"f c #3263B4",
+"= c #EAF0FA",
+"< c #B1C7EB",
+"% c #6992D7",
+"9 c #D9E4F5",
+"o c #9BB7E5",
+"6 c #F7F9FD",
+", c #BED0EE",
+"3 c #F0F5FC",
+"1 c #A8C0E8",
+" c None",
+"0 c #FDFEFF",
+"4 c #C4D5F0",
+"@ c #81A4DD",
+"e c #4377CD",
+"- c #E2EAF8",
+"i c #9FB9E5",
+"> c #CCDAF2",
+"+ c #89A9DF",
+"s c #5584D1",
+"t c #5D89D3",
+": c #D2DFF4",
+"5 c #FAFCFE",
+"2 c #F5F8FD",
+"8 c #DFE8F7",
+"& c #5E8AD4",
+"X c #638ED5",
+"a c #CEDCF2",
+"p c #90AFE2",
+"d c #2F5DA9",
+"* c #5282D0",
+"7 c #E5EDF9",
+". c #A2BCE6",
+"O c #8CACE0",
+/* pixels */
+" ",
+" .XXXXXXXXXXX ",
+" oXO++@#$%&*X ",
+" oX=-;:>,<1%X ",
+" oX23=-;:4,$X ",
+" oX5633789:@X ",
+" oX05623=78+X ",
+" oXqq05623=OX ",
+" oX,,,,,<<<$X ",
+" wXXXXXXXXXXe ",
+" XrtX%$$y@+O,, ",
+" uyiiiiiiiii@< ",
+" ouiiiiiiiiiip<a",
+" rustX%$$y@+Ow,,",
+" dfffffffffffffd",
+" "
+};
+#endif // !GTK+ 2
// ----------------------------------------------------------------------------
// wxFileIconsTable & friends
// ----------------------------------------------------------------------------
// global instance of a wxFileIconsTable
-wxFileIconsTable* wxTheFileIconsTable = (wxFileIconsTable *)NULL;
+wxFileIconsTable* wxTheFileIconsTable = NULL;
// A module to allow icons table cleanup
bool OnInit() { wxTheFileIconsTable = new wxFileIconsTable; return true; }
void OnExit()
{
- if (wxTheFileIconsTable)
- {
- delete wxTheFileIconsTable;
- wxTheFileIconsTable = NULL;
- }
+ wxDELETE(wxTheFileIconsTable);
}
};
class wxFileIconEntry : public wxObject
{
public:
- wxFileIconEntry(int i) { id = i; }
+ wxFileIconEntry(int i) { iconid = i; }
- int id;
+ int iconid;
};
wxFileIconsTable::wxFileIconsTable()
wxART_CMN_DIALOG,
wxSize(16, 16)));
// computer
-#ifdef __WXGTK24__
+#ifdef __WXGTK20__
// GTK24 uses this icon in the file open dialog
m_smallImageList->Add(wxArtProvider::GetBitmap(wxART_HARDDISK,
wxART_CMN_DIALOG,
wxART_CMN_DIALOG,
wxSize(16, 16)));
// executable
- if (GetIconID(wxEmptyString, _T("application/x-executable")) == file)
+ if (GetIconID(wxEmptyString, wxT("application/x-executable")) == file)
{
m_smallImageList->Add(wxArtProvider::GetBitmap(wxART_EXECUTABLE_FILE,
wxART_CMN_DIALOG,
wxSize(16, 16)));
- delete m_HashTable->Get(_T("exe"));
- m_HashTable->Delete(_T("exe"));
- m_HashTable->Put(_T("exe"), new wxFileIconEntry(executable));
+ delete m_HashTable->Get(wxT("exe"));
+ m_HashTable->Delete(wxT("exe"));
+ m_HashTable->Put(wxT("exe"), new wxFileIconEntry(executable));
}
/* else put into list by GetIconID
(KDE defines application/x-executable for *.exe and has nice icon)
return m_smallImageList;
}
-#if wxUSE_MIMETYPE && wxUSE_IMAGE
+#if wxUSE_MIMETYPE && wxUSE_IMAGE && (!defined(__WXMSW__) || wxUSE_WXDIB)
// VS: we don't need this function w/o wxMimeTypesManager because we'll only have
// one icon and we won't resize it
if (!extension.empty())
{
wxFileIconEntry *entry = (wxFileIconEntry*) m_HashTable->Get(extension);
- if (entry) return (entry -> id);
+ if (entry) return (entry -> iconid);
}
wxFileType *ft = (mime.empty()) ?
delete ft;
- if ( !ic.Ok() )
+ if ( !ic.IsOk() )
{
int newid = file;
m_HashTable->Put(extension, new wxFileIconEntry(newid));
wxBitmap bmp;
bmp.CopyFromIcon(ic);
- if ( !bmp.Ok() )
+ if ( !bmp.IsOk() )
{
int newid = file;
m_HashTable->Put(extension, new wxFileIconEntry(newid));
const unsigned int size = 16;
- int id = m_smallImageList->GetImageCount();
+ int treeid = m_smallImageList->GetImageCount();
if ((bmp.GetWidth() == (int) size) && (bmp.GetHeight() == (int) size))
{
m_smallImageList->Add(bmp);
}
-#if wxUSE_IMAGE
+#if wxUSE_IMAGE && (!defined(__WXMSW__) || wxUSE_WXDIB)
else
{
wxImage img = bmp.ConvertToImage();
}
#endif // wxUSE_IMAGE
- m_HashTable->Put(extension, new wxFileIconEntry(id));
- return id;
+ m_HashTable->Put(extension, new wxFileIconEntry(treeid));
+ return treeid;
#else // !wxUSE_MIMETYPE