Include wx/arrstr.h according to precompiled headers of wx/wx.h (with other minor...
[wxWidgets.git] / src / common / dircmn.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/dircmn.cpp
3 // Purpose: wxDir methods common to all implementations
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 19.05.01
7 // RCS-ID: $Id$
8 // Copyright: (c) 2001 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // License: 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 #ifndef WX_PRECOMP
28 #include "wx/string.h"
29 #include "wx/log.h"
30 #include "wx/intl.h"
31 #include "wx/filefn.h"
32 #include "wx/arrstr.h"
33 #endif //WX_PRECOMP
34
35 #include "wx/dir.h"
36
37 // ============================================================================
38 // implementation
39 // ============================================================================
40
41 // ----------------------------------------------------------------------------
42 // wxDirTraverser
43 // ----------------------------------------------------------------------------
44
45 wxDirTraverseResult
46 wxDirTraverser::OnOpenError(const wxString& WXUNUSED(dirname))
47 {
48 return wxDIR_IGNORE;
49 }
50
51 // ----------------------------------------------------------------------------
52 // wxDir::HasFiles() and HasSubDirs()
53 // ----------------------------------------------------------------------------
54
55 // dumb generic implementation
56
57 bool wxDir::HasFiles(const wxString& spec)
58 {
59 wxString s;
60 return GetFirst(&s, spec, wxDIR_FILES | wxDIR_HIDDEN);
61 }
62
63 // we have a (much) faster version for Unix
64 #if (defined(__CYGWIN__) && defined(__WINDOWS__)) || !defined(__UNIX_LIKE__) || defined(__WXMAC__) || defined(__EMX__) || defined(__WINE__)
65
66 bool wxDir::HasSubDirs(const wxString& spec)
67 {
68 wxString s;
69 return GetFirst(&s, spec, wxDIR_DIRS | wxDIR_HIDDEN);
70 }
71
72 #endif // !Unix
73
74 // ----------------------------------------------------------------------------
75 // wxDir::Traverse()
76 // ----------------------------------------------------------------------------
77
78 size_t wxDir::Traverse(wxDirTraverser& sink,
79 const wxString& filespec,
80 int flags) const
81 {
82 wxCHECK_MSG( IsOpened(), (size_t)-1,
83 _T("dir must be opened before traversing it") );
84
85 // the total number of files found
86 size_t nFiles = 0;
87
88 // the name of this dir with path delimiter at the end
89 wxString prefix = GetName();
90 prefix += wxFILE_SEP_PATH;
91
92 // first, recurse into subdirs
93 if ( flags & wxDIR_DIRS )
94 {
95 wxString dirname;
96 for ( bool cont = GetFirst(&dirname, wxEmptyString, wxDIR_DIRS | (flags & wxDIR_HIDDEN) );
97 cont;
98 cont = cont && GetNext(&dirname) )
99 {
100 const wxString fulldirname = prefix + dirname;
101
102 switch ( sink.OnDir(fulldirname) )
103 {
104 default:
105 wxFAIL_MSG(_T("unexpected OnDir() return value") );
106 // fall through
107
108 case wxDIR_STOP:
109 cont = false;
110 break;
111
112 case wxDIR_CONTINUE:
113 {
114 wxDir subdir;
115
116 // don't give the error messages for the directories
117 // which we can't open: there can be all sorts of good
118 // reason for this (e.g. insufficient privileges) and
119 // this shouldn't be treated as an error -- instead
120 // let the user code decide what to do
121 bool ok;
122 do
123 {
124 wxLogNull noLog;
125 ok = subdir.Open(fulldirname);
126 if ( !ok )
127 {
128 // ask the user code what to do
129 bool tryagain;
130 switch ( sink.OnOpenError(fulldirname) )
131 {
132 default:
133 wxFAIL_MSG(_T("unexpected OnOpenError() return value") );
134 // fall through
135
136 case wxDIR_STOP:
137 cont = false;
138 // fall through
139
140 case wxDIR_IGNORE:
141 tryagain = false;
142 break;
143
144 case wxDIR_CONTINUE:
145 tryagain = true;
146 }
147
148 if ( !tryagain )
149 break;
150 }
151 }
152 while ( !ok );
153
154 if ( ok )
155 {
156 nFiles += subdir.Traverse(sink, filespec, flags);
157 }
158 }
159 break;
160
161 case wxDIR_IGNORE:
162 // nothing to do
163 ;
164 }
165 }
166 }
167
168 // now enum our own files
169 if ( flags & wxDIR_FILES )
170 {
171 flags &= ~wxDIR_DIRS;
172
173 wxString filename;
174 bool cont = GetFirst(&filename, filespec, flags);
175 while ( cont )
176 {
177 wxDirTraverseResult res = sink.OnFile(prefix + filename);
178 if ( res == wxDIR_STOP )
179 break;
180
181 wxASSERT_MSG( res == wxDIR_CONTINUE,
182 _T("unexpected OnFile() return value") );
183
184 nFiles++;
185
186 cont = GetNext(&filename);
187 }
188 }
189
190 return nFiles;
191 }
192
193 // ----------------------------------------------------------------------------
194 // wxDir::GetAllFiles()
195 // ----------------------------------------------------------------------------
196
197 class wxDirTraverserSimple : public wxDirTraverser
198 {
199 public:
200 wxDirTraverserSimple(wxArrayString& files) : m_files(files) { }
201
202 virtual wxDirTraverseResult OnFile(const wxString& filename)
203 {
204 m_files.push_back(filename);
205 return wxDIR_CONTINUE;
206 }
207
208 virtual wxDirTraverseResult OnDir(const wxString& WXUNUSED(dirname))
209 {
210 return wxDIR_CONTINUE;
211 }
212
213 private:
214 wxArrayString& m_files;
215
216 DECLARE_NO_COPY_CLASS(wxDirTraverserSimple)
217 };
218
219 /* static */
220 size_t wxDir::GetAllFiles(const wxString& dirname,
221 wxArrayString *files,
222 const wxString& filespec,
223 int flags)
224 {
225 wxCHECK_MSG( files, (size_t)-1, _T("NULL pointer in wxDir::GetAllFiles") );
226
227 size_t nFiles = 0;
228
229 wxDir dir(dirname);
230 if ( dir.IsOpened() )
231 {
232 wxDirTraverserSimple traverser(*files);
233
234 nFiles += dir.Traverse(traverser, filespec, flags);
235 }
236
237 return nFiles;
238 }