]> git.saurik.com Git - wxWidgets.git/blame - src/osx/carbon/dirmac.cpp
speeding up rectangle drawing by using specific methods, needs 40% less time
[wxWidgets.git] / src / osx / carbon / dirmac.cpp
CommitLineData
489468fe 1/////////////////////////////////////////////////////////////////////////////
80fdcdb9 2// Name: src/osx/carbon/dirmac.cpp
489468fe
SC
3// Purpose: wxDir implementation for Mac
4// Author: Stefan Csomor
5// Modified by:
6// Created: 08.12.99
7// RCS-ID: $Id$
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
489468fe 34#include "wx/filename.h"
1f0c8f31 35#include "wx/osx/private.h"
489468fe
SC
36
37// ----------------------------------------------------------------------------
38// private classes
39// ----------------------------------------------------------------------------
40
41// this class stores everything we need to enumerate the files
42class wxDirData
43{
44public:
45 wxDirData(const wxString& dirname);
46 ~wxDirData();
47
48 void Close() ;
49 void SetFileSpec(const wxString& filespec) { m_filespec = filespec; }
50 void SetFlags(int flags) { m_flags = flags; }
51
52 bool Read(wxString *filename); // reads the next
53 void Rewind() ;
54
55 const wxString& GetName() const { return m_dirname; }
56
57private:
58 FSIterator m_iterator ;
59
60 wxString m_dirname;
61 wxString m_filespec;
62
63 int m_flags;
64};
65
66// ============================================================================
67// implementation
68// ============================================================================
69
70// ----------------------------------------------------------------------------
71// wxDirData
72// ----------------------------------------------------------------------------
73
74wxDirData::wxDirData(const wxString& dirname)
75 : m_dirname(dirname)
76{
77 // throw away the trailing slashes
78 size_t n = m_dirname.length();
9a83f860 79 wxCHECK_RET( n, wxT("empty dir name in wxDir") );
489468fe
SC
80
81 while ( n > 0 && wxIsPathSeparator(m_dirname[--n]) )
82 ;
83
84 m_dirname.Truncate(n + 1);
85 m_iterator = NULL ;
86}
87
88wxDirData::~wxDirData()
89{
90 Close() ;
91}
92
93void wxDirData::Close()
94{
95 if ( m_iterator )
96 {
97 FSCloseIterator( m_iterator ) ;
98 m_iterator = NULL ;
99 }
100}
101
102void wxDirData::Rewind()
103{
104 Close() ;
105}
106
107bool wxDirData::Read(wxString *filename)
108{
109 wxString result;
110 OSStatus err = noErr ;
111 if ( NULL == m_iterator )
112 {
113 FSRef dirRef;
114 err = wxMacPathToFSRef( m_dirname , &dirRef ) ;
115 if ( err == noErr )
116 {
117 err = FSOpenIterator(&dirRef, kFSIterateFlat, &m_iterator);
118 }
119 if ( err )
120 {
121 Close() ;
122 return false ;
123 }
124 }
125
126 wxString name ;
127 wxString lowerfilespec = m_filespec.Lower();
128
129 while( noErr == err )
130 {
131 HFSUniStr255 uniname ;
132 FSRef fileRef;
133 FSCatalogInfo catalogInfo;
134 ItemCount fetched = 0;
135
136 err = FSGetCatalogInfoBulk( m_iterator, 1, &fetched, NULL, kFSCatInfoNodeFlags | kFSCatInfoFinderInfo , &catalogInfo , &fileRef, NULL, &uniname );
03647350
VZ
137
138 // expected error codes
139
489468fe
SC
140 if ( errFSNoMoreItems == err )
141 return false ;
142 if ( afpAccessDenied == err )
143 return false ;
144
145 if ( noErr != err )
146 break ;
147
148 name = wxMacHFSUniStrToString( &uniname ) ;
149 wxString lowername = name.Lower();
150
151 if ( ( name == wxT(".") || name == wxT("..") ) && !(m_flags & wxDIR_DOTDOT) )
152 continue;
153
154 if ( ( name[0U] == '.' ) && !(m_flags & wxDIR_HIDDEN ) )
155 continue ;
156
157 if ( (((FileInfo*)&catalogInfo.finderInfo)->finderFlags & kIsInvisible ) && !(m_flags & wxDIR_HIDDEN ) )
158 continue ;
159
160 // its a dir and we don't want it
161 if ( (catalogInfo.nodeFlags & kFSNodeIsDirectoryMask) && !(m_flags & wxDIR_DIRS) )
162 continue ;
163
164 // its a file but we don't want it
165 if ( (catalogInfo.nodeFlags & kFSNodeIsDirectoryMask) == 0 && !(m_flags & wxDIR_FILES ) )
166 continue ;
167
168 if ( m_filespec.empty() || m_filespec == wxT("*.*") || m_filespec == wxT("*") )
169 {
170 }
171 else if ( !wxMatchWild(lowerfilespec, lowername , false) )
172 {
173 continue ;
174 }
175
176 break ;
177 }
178 if ( err != noErr )
179 {
180 return false ;
181 }
182
183 *filename = name ;
184 return true;
185}
186
489468fe
SC
187// ----------------------------------------------------------------------------
188// wxDir construction/destruction
189// ----------------------------------------------------------------------------
190
191wxDir::wxDir(const wxString& dirname)
192{
193 m_data = NULL;
194
195 (void)Open(dirname);
196}
197
198bool wxDir::Open(const wxString& dirname)
199{
200 delete m_data;
201 m_data = new wxDirData(dirname);
202
203 return true;
204}
205
206bool wxDir::IsOpened() const
207{
208 return m_data != NULL;
209}
210
211wxString wxDir::GetName() const
212{
213 wxString name;
214 if ( m_data )
215 {
216 name = m_data->GetName();
9a83f860 217 if ( !name.empty() && (name.Last() == wxT('/')) )
489468fe
SC
218 {
219 // chop off the last (back)slash
220 name.Truncate(name.length() - 1);
221 }
222 }
223
224 return name;
225}
226
227wxDir::~wxDir()
228{
5276b0a5 229 wxDELETE(m_data);
489468fe
SC
230}
231
232// ----------------------------------------------------------------------------
233// wxDir enumerating
234// ----------------------------------------------------------------------------
235
236bool wxDir::GetFirst(wxString *filename,
237 const wxString& filespec,
238 int flags) const
239{
9a83f860 240 wxCHECK_MSG( IsOpened(), false, wxT("must wxDir::Open() first") );
489468fe
SC
241
242 m_data->Rewind();
243
244 m_data->SetFileSpec(filespec);
245 m_data->SetFlags(flags);
246
247 return GetNext(filename);
248}
249
250bool wxDir::GetNext(wxString *filename) const
251{
9a83f860 252 wxCHECK_MSG( IsOpened(), false, wxT("must wxDir::Open() first") );
489468fe 253
9a83f860 254 wxCHECK_MSG( filename, false, wxT("bad pointer in wxDir::GetNext()") );
489468fe
SC
255
256 return m_data->Read(filename);
257}