/////////////////////////////////////////////////////////////////////////////
-// Name: msw/dir.cpp
+// Name: mac/dirmac.cpp
// Purpose: wxDir implementation for Mac
// Author: Stefan Csomor
// Modified by:
// Created: 08.12.99
// RCS-ID: $Id$
// Copyright: (c) 1999 Stefan Csomor <csomor@advanced.ch>
-// Licence: wxWidgets licence
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// headers
// ----------------------------------------------------------------------------
-#ifdef __GNUG__
- #pragma implementation "dir.h"
-#endif
-
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#pragma hdrstop
#endif
+#include "wx/dir.h"
+
#ifndef WX_PRECOMP
#include "wx/intl.h"
#include "wx/log.h"
#endif // PCH
-#include "wx/dir.h"
-#include "wx/filefn.h" // for wxPathExists()
-
-#ifndef __DARWIN__
- #include <windows.h>
-#endif
-
+#include "wx/filefn.h" // for wxDirExists()
+#include "wx/filename.h"
#include "wx/mac/private.h"
-#ifdef __DARWIN__
-# include "MoreFilesX.h"
-#else
-# include "MoreFiles.h"
-# include "MoreFilesExtras.h"
-#endif
-
-// ----------------------------------------------------------------------------
-// constants
-// ----------------------------------------------------------------------------
-
-#ifndef MAX_PATH
- #define MAX_PATH 260 // from VC++ headers
-#endif
-
-// ----------------------------------------------------------------------------
-// macros
-// ----------------------------------------------------------------------------
-
-#define M_DIR ((wxDirData *)m_data)
-
// ----------------------------------------------------------------------------
// private classes
// ----------------------------------------------------------------------------
wxDirData(const wxString& dirname);
~wxDirData();
+ void Close() ;
void SetFileSpec(const wxString& filespec) { m_filespec = filespec; }
void SetFlags(int flags) { m_flags = flags; }
- bool Read(wxString *filename); // reads the next
+ bool Read(wxString *filename); // reads the next
void Rewind() ;
const wxString& GetName() const { return m_dirname; }
private:
- CInfoPBRec m_CPB ;
- wxInt16 m_index ;
- long m_dirId ;
- Str255 m_name ;
- Boolean m_isDir ;
+ FSIterator m_iterator ;
wxString m_dirname;
wxString m_filespec;
wxDirData::wxDirData(const wxString& dirname)
: m_dirname(dirname)
{
- OSErr err;
-
// throw away the trailing slashes
size_t n = m_dirname.length();
wxCHECK_RET( n, _T("empty dir name in wxDir") );
;
m_dirname.Truncate(n + 1);
-
-#ifdef __DARWIN__
- FSRef theRef;
-
- // get the FSRef associated with the POSIX path
- err = FSPathMakeRef((const UInt8 *) m_dirname.c_str(), &theRef, NULL);
- FSGetVRefNum(&theRef, &(m_CPB.hFileInfo.ioVRefNum));
-
- err = FSGetNodeID( &theRef , &m_dirId , &m_isDir ) ;
-#else
- FSSpec fsspec ;
-
- wxMacFilename2FSSpec( m_dirname , &fsspec ) ;
- m_CPB.hFileInfo.ioVRefNum = fsspec.vRefNum ;
-
- err = FSpGetDirectoryID( &fsspec , &m_dirId , &m_isDir ) ;
-#endif
- wxASSERT_MSG( (err == noErr) || (err == nsvErr) , wxT("Error accessing directory " + m_dirname)) ;
-
- m_CPB.hFileInfo.ioNamePtr = m_name ;
- m_index = 0 ;
+ m_iterator = NULL ;
}
wxDirData::~wxDirData()
{
+ Close() ;
+}
+
+void wxDirData::Close()
+{
+ if ( m_iterator )
+ {
+ FSCloseIterator( m_iterator ) ;
+ m_iterator = NULL ;
+ }
}
-void wxDirData::Rewind()
+void wxDirData::Rewind()
{
- m_index = 0 ;
+ Close() ;
}
bool wxDirData::Read(wxString *filename)
{
- if ( !m_isDir )
- return FALSE ;
-
wxString result;
+ OSStatus err = noErr ;
+ if ( NULL == m_iterator )
+ {
+ FSRef dirRef;
+ err = wxMacPathToFSRef( m_dirname , &dirRef ) ;
+ if ( err == noErr )
+ {
+ err = FSOpenIterator(&dirRef, kFSIterateFlat, &m_iterator);
+ }
+ if ( err )
+ {
+ Close() ;
+ return false ;
+ }
+ }
+
+ wxString name ;
- short err = noErr ;
-
- while ( err == noErr )
+ while( noErr == err )
{
- m_index++ ;
- m_CPB.dirInfo.ioFDirIndex = m_index;
- m_CPB.dirInfo.ioDrDirID = m_dirId; /* we need to do this every time */
- err = PBGetCatInfoSync((CInfoPBPtr)&m_CPB);
- if ( err != noErr )
- break ;
+ HFSUniStr255 uniname ;
+ FSRef fileRef;
+ FSCatalogInfo catalogInfo;
+ ItemCount fetched = 0;
+
+ err = FSGetCatalogInfoBulk( m_iterator, 1, &fetched, NULL, kFSCatInfoNodeFlags | kFSCatInfoFinderInfo , &catalogInfo , &fileRef, NULL, &uniname );
- // its hidden but we don't want it
- if ( ( m_CPB.hFileInfo.ioFlFndrInfo.fdFlags & kIsInvisible ) && !(m_flags & wxDIR_HIDDEN) )
- continue ;
-#ifdef __DARWIN__
- // under X, names that start with '.' are hidden
- if ( ( m_name[1] == '.' ) && !(m_flags & wxDIR_HIDDEN) )
- continue;
-#endif
-#if TARGET_CARBON
- // under X thats the way the mounting points look like
- if ( ( m_CPB.dirInfo.ioDrDirID == 0 ) && ( m_flags & wxDIR_DIRS) )
- break ;
-#endif
- // we have a directory
- if ( ( m_CPB.dirInfo.ioFlAttrib & ioDirMask) != 0 && (m_flags & wxDIR_DIRS) )
- break ;
+ // expected error codes
+ if ( errFSNoMoreItems == err )
+ return false ;
+ if ( afpAccessDenied == err )
+ return false ;
+
+ if ( noErr != err )
+ break ;
+
+ name = wxMacHFSUniStrToString( &uniname ) ;
+
+ if ( ( name == wxT(".") || name == wxT("..") ) && !(m_flags & wxDIR_DOTDOT) )
+ continue;
+
+ if ( ( name[0U] == '.' ) && !(m_flags & wxDIR_HIDDEN ) )
+ continue ;
+
+ if ( (((FileInfo*)&catalogInfo.finderInfo)->finderFlags & kIsInvisible ) && !(m_flags & wxDIR_HIDDEN ) )
+ continue ;
+
+ // its a dir and we don't want it
+ if ( (catalogInfo.nodeFlags & kFSNodeIsDirectoryMask) && !(m_flags & wxDIR_DIRS) )
+ continue ;
+
// its a file but we don't want it
- if ( ( m_CPB.dirInfo.ioFlAttrib & ioDirMask) == 0 && !(m_flags & wxDIR_FILES ) )
+ if ( (catalogInfo.nodeFlags & kFSNodeIsDirectoryMask) == 0 && !(m_flags & wxDIR_FILES ) )
continue ;
-
- wxString file = wxMacMakeStringFromPascal( m_name ) ;
- if ( m_filespec.IsEmpty() || m_filespec == wxT("*.*") || m_filespec == wxT("*") )
- {
- }
- else if ( m_filespec.Length() > 1 && m_filespec.Left(1) == wxT("*") )
- {
- if ( file.Right( m_filespec.Length() - 1 ).Upper() != m_filespec.Mid(1).Upper() )
- {
- continue ;
- }
- }
- else if ( m_filespec.Length() > 1 && m_filespec.Right(1) == wxT("*") )
+
+ if ( m_filespec.empty() || m_filespec == wxT("*.*") || m_filespec == wxT("*") )
{
- if ( file.Left( m_filespec.Length() - 1 ).Upper() != m_filespec.Left( m_filespec.Length() - 1 ).Upper() )
- {
- continue ;
- }
}
- else if ( file.Upper() != m_filespec.Upper() )
+ else if ( !wxMatchWild(m_filespec, name , false) )
{
continue ;
}
-
+
break ;
}
if ( err != noErr )
{
- return FALSE ;
+ return false ;
}
-
- *filename = wxMacMakeStringFromPascal( m_name ) ;
- return TRUE;
+ *filename = name ;
+ return true;
}
// ----------------------------------------------------------------------------
/* static */
bool wxDir::Exists(const wxString& dir)
{
- return wxPathExists(dir);
+ return wxDirExists(dir);
}
// ----------------------------------------------------------------------------
bool wxDir::Open(const wxString& dirname)
{
- delete M_DIR;
+ delete m_data;
m_data = new wxDirData(dirname);
- return TRUE;
+ return true;
}
bool wxDir::IsOpened() const
wxString name;
if ( m_data )
{
- name = M_DIR->GetName();
- if ( !name.empty() && (name.Last() == _T('/')) )
- {
- // chop off the last (back)slash
- name.Truncate(name.length() - 1);
- }
+ name = m_data->GetName();
+ if ( !name.empty() && (name.Last() == _T('/')) )
+ {
+ // chop off the last (back)slash
+ name.Truncate(name.length() - 1);
+ }
}
return name;
wxDir::~wxDir()
{
- if (M_DIR != NULL) {
- delete M_DIR;
- m_data = NULL;
- }
+ delete m_data;
+ m_data = NULL;
}
// ----------------------------------------------------------------------------
const wxString& filespec,
int flags) const
{
- wxCHECK_MSG( IsOpened(), FALSE, _T("must wxDir::Open() first") );
+ wxCHECK_MSG( IsOpened(), false, _T("must wxDir::Open() first") );
- M_DIR->Rewind();
+ m_data->Rewind();
- M_DIR->SetFileSpec(filespec);
- M_DIR->SetFlags(flags);
+ m_data->SetFileSpec(filespec);
+ m_data->SetFlags(flags);
return GetNext(filename);
}
bool wxDir::GetNext(wxString *filename) const
{
- wxCHECK_MSG( IsOpened(), FALSE, _T("must wxDir::Open() first") );
+ wxCHECK_MSG( IsOpened(), false, _T("must wxDir::Open() first") );
- wxCHECK_MSG( filename, FALSE, _T("bad pointer in wxDir::GetNext()") );
+ wxCHECK_MSG( filename, false, _T("bad pointer in wxDir::GetNext()") );
- return M_DIR->Read(filename);
+ return m_data->Read(filename);
}