1///////////////////////////////////////////////////////////////////////////// 2// Name: mac/dirmac.cpp 3// Purpose: wxDir implementation for Mac 4// Author: Stefan Csomor 5// Modified by: 6// Created: 08.12.99 7// RCS-ID: $Id: dirmac.cpp 56405 2008-10-17 19:13:33Z SC $ 8// Copyright: (c) 1999 Stefan Csomor <csomor@advanced.ch> 9// Licence: wxWindows licence 10///////////////////////////////////////////////////////////////////////////// 11 12// ============================================================================ 13// declarations 14// ============================================================================ 15 16// ---------------------------------------------------------------------------- 17// headers 18// ---------------------------------------------------------------------------- 19 20// For compilers that support precompilation, includes "wx.h". 21#include "wx/wxprec.h" 22 23#ifdef __BORLANDC__ 24 #pragma hdrstop 25#endif 26 27#include "wx/dir.h" 28 29#ifndef WX_PRECOMP 30 #include "wx/intl.h" 31 #include "wx/log.h" 32#endif // PCH 33 34#include "wx/filefn.h" // for wxDirExists() 35#include "wx/filename.h" 36#include "wx/mac/private.h" 37 38// ---------------------------------------------------------------------------- 39// private classes 40// ---------------------------------------------------------------------------- 41 42// this class stores everything we need to enumerate the files 43class wxDirData 44{ 45public: 46 wxDirData(const wxString& dirname); 47 ~wxDirData(); 48 49 void Close() ; 50 void SetFileSpec(const wxString& filespec) { m_filespec = filespec; } 51 void SetFlags(int flags) { m_flags = flags; } 52 53 bool Read(wxString *filename); // reads the next 54 void Rewind() ; 55 56 const wxString& GetName() const { return m_dirname; } 57 58private: 59 FSIterator m_iterator ; 60 61 wxString m_dirname; 62 wxString m_filespec; 63 64 int m_flags; 65}; 66 67// ============================================================================ 68// implementation 69// ============================================================================ 70 71// ---------------------------------------------------------------------------- 72// wxDirData 73// ---------------------------------------------------------------------------- 74 75wxDirData::wxDirData(const wxString& dirname) 76 : m_dirname(dirname) 77{ 78 // throw away the trailing slashes 79 size_t n = m_dirname.length(); 80 wxCHECK_RET( n, _T("empty dir name in wxDir") ); 81 82 while ( n > 0 && wxIsPathSeparator(m_dirname[--n]) ) 83 ; 84 85 m_dirname.Truncate(n + 1); 86 m_iterator = NULL ; 87} 88 89wxDirData::~wxDirData() 90{ 91 Close() ; 92} 93 94void wxDirData::Close() 95{ 96 if ( m_iterator ) 97 { 98 FSCloseIterator( m_iterator ) ; 99 m_iterator = NULL ; 100 } 101} 102 103void wxDirData::Rewind() 104{ 105 Close() ; 106} 107 108bool wxDirData::Read(wxString *filename) 109{ 110 wxString result; 111 OSStatus err = noErr ; 112 if ( NULL == m_iterator ) 113 { 114 FSRef dirRef; 115 err = wxMacPathToFSRef( m_dirname , &dirRef ) ; 116 if ( err == noErr ) 117 { 118 Boolean isFolder, wasAliased; 119 FSResolveAliasFile( &dirRef, TRUE, &isFolder, &wasAliased ); 120 err = FSOpenIterator(&dirRef, kFSIterateFlat, &m_iterator); 121 } 122 if ( err ) 123 { 124 Close() ; 125 return false ; 126 } 127 } 128 129 wxString name ; 130 wxString lowerfilespec = m_filespec.Lower(); 131 132 while( noErr == err ) 133 { 134 HFSUniStr255 uniname ; 135 FSRef fileRef; 136 FSCatalogInfo catalogInfo; 137 ItemCount fetched = 0; 138 139 err = FSGetCatalogInfoBulk( m_iterator, 1, &fetched, NULL, kFSCatInfoNodeFlags | kFSCatInfoFinderInfo , &catalogInfo , &fileRef, NULL, &uniname ); 140 141 // expected error codes 142 143 if ( errFSNoMoreItems == err ) 144 return false ; 145 if ( afpAccessDenied == err ) 146 return false ; 147 148 if ( noErr != err ) 149 break ; 150 151 name = wxMacHFSUniStrToString( &uniname ) ; 152 wxString lowername = name.Lower(); 153 154 if ( ( name == wxT(".") || name == wxT("..") ) && !(m_flags & wxDIR_DOTDOT) ) 155 continue; 156 157 if ( ( name[0U] == '.' ) && !(m_flags & wxDIR_HIDDEN ) ) 158 continue ; 159 160 Boolean isFolder, wasAliased; 161 FSResolveAliasFile( &fileRef, TRUE, &isFolder, &wasAliased ); 162 if ( wasAliased ) 163 { 164 FSGetCatalogInfo( &fileRef, kFSCatInfoNodeFlags | kFSCatInfoFinderInfo, &catalogInfo, NULL, NULL, NULL ); 165 } 166 167 if ( (((FileInfo*)&catalogInfo.finderInfo)->finderFlags & kIsInvisible ) && !(m_flags & wxDIR_HIDDEN ) ) 168 continue ; 169 170 // its a dir and we don't want it 171 if ( (catalogInfo.nodeFlags & kFSNodeIsDirectoryMask) && !(m_flags & wxDIR_DIRS) ) 172 continue ; 173 174 // its a file but we don't want it 175 if ( (catalogInfo.nodeFlags & kFSNodeIsDirectoryMask) == 0 && !(m_flags & wxDIR_FILES ) ) 176 continue ; 177 178 if ( m_filespec.empty() || m_filespec == wxT("*.*") || m_filespec == wxT("*") ) 179 { 180 } 181 else if ( !wxMatchWild(lowerfilespec, lowername , false) ) 182 { 183 continue ; 184 } 185 186 break ; 187 } 188 if ( err != noErr ) 189 { 190 return false ; 191 } 192 193 *filename = name ; 194 return true; 195} 196 197// ---------------------------------------------------------------------------- 198// wxDir helpers 199// ---------------------------------------------------------------------------- 200 201/* static */ 202bool wxDir::Exists(const wxString& dir) 203{ 204 return wxDirExists(dir); 205} 206 207// ---------------------------------------------------------------------------- 208// wxDir construction/destruction 209// ---------------------------------------------------------------------------- 210 211wxDir::wxDir(const wxString& dirname) 212{ 213 m_data = NULL; 214 215 (void)Open(dirname); 216} 217 218bool wxDir::Open(const wxString& dirname) 219{ 220 delete m_data; 221 m_data = new wxDirData(dirname); 222 223 return true; 224} 225 226bool wxDir::IsOpened() const 227{ 228 return m_data != NULL; 229} 230 231wxString wxDir::GetName() const 232{ 233 wxString name; 234 if ( m_data ) 235 { 236 name = m_data->GetName(); 237 if ( !name.empty() && (name.Last() == _T('/')) ) 238 { 239 // chop off the last (back)slash 240 name.Truncate(name.length() - 1); 241 } 242 } 243 244 return name; 245} 246 247wxDir::~wxDir() 248{ 249 delete m_data; 250 m_data = NULL; 251} 252 253// ---------------------------------------------------------------------------- 254// wxDir enumerating 255// ---------------------------------------------------------------------------- 256 257bool wxDir::GetFirst(wxString *filename, 258 const wxString& filespec, 259 int flags) const 260{ 261 wxCHECK_MSG( IsOpened(), false, _T("must wxDir::Open() first") ); 262 263 m_data->Rewind(); 264 265 m_data->SetFileSpec(filespec); 266 m_data->SetFlags(flags); 267 268 return GetNext(filename); 269} 270 271bool wxDir::GetNext(wxString *filename) const 272{ 273 wxCHECK_MSG( IsOpened(), false, _T("must wxDir::Open() first") ); 274 275 wxCHECK_MSG( filename, false, _T("bad pointer in wxDir::GetNext()") ); 276 277 return m_data->Read(filename); 278} 279