Bitmap code, icon code and dir code updates
[wxWidgets.git] / src / os2 / dir.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: os2/dir.cpp
3 // Purpose: wxDir implementation for OS/2
4 // Author: Vadim Zeitlin
5 // Modified by: Stefan Neis
6 // Created: 08.12.99
7 // RCS-ID: $Id$
8 // Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "dir.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifndef WX_PRECOMP
28 #include "wx/intl.h"
29 #include "wx/log.h"
30 #endif // PCH
31
32 #include "wx/dir.h"
33 #include "wx/filefn.h" // for wxMatchWild
34
35 #include <sys/types.h>
36
37 #define INCL_DOSFILEMGR
38 #include <os2.h>
39
40 #ifdef __EMX__
41 #include <dirent.h>
42 #endif
43
44 // ----------------------------------------------------------------------------
45 // define the types and functions used for file searching
46 // ----------------------------------------------------------------------------
47
48 typedef FILEFINDBUF3 FIND_STRUCT;
49 typedef HDIR FIND_DATA;
50 typedef ULONG FIND_ATTR;
51
52 static inline FIND_DATA InitFindData() { return ERROR_INVALID_HANDLE; }
53
54 static inline bool IsFindDataOk(
55 FIND_DATA vFd
56 )
57 {
58 return vFd != ERROR_INVALID_HANDLE;
59 }
60
61 static inline void FreeFindData(
62 FIND_DATA vFd
63 )
64 {
65 if (!::DosFindClose(vFd))
66 {
67 wxLogLastError(_T("DosFindClose"));
68 }
69 }
70
71 static inline FIND_DATA FindFirst(
72 const wxString& rsSpec
73 , FIND_STRUCT* pFinddata
74 )
75 {
76 ULONG ulFindCount = 1;
77 FIND_DATA hDir;
78 FIND_ATTR rc;
79
80 rc = ::DosFindFirst( rsSpec.c_str()
81 ,&hDir
82 ,FILE_NORMAL
83 ,pFinddata
84 ,sizeof(FILEFINDBUF3)
85 ,&ulFindCount
86 ,FIL_STANDARD
87 );
88 if (rc != 0)
89 return 0;
90 return hDir;
91 }
92
93 static inline bool FindNext(
94 FIND_DATA vFd
95 , FIND_STRUCT* pFinddata
96 )
97 {
98 ULONG ulFindCount = 1;
99
100 return ::DosFindNext( vFd
101 ,pFinddata
102 ,sizeof(FILEFINDBUF3)
103 ,&ulFindCount
104 ) != 0;
105 }
106
107 static const wxChar* GetNameFromFindData(
108 FIND_STRUCT* pFinddata
109 )
110 {
111 return pFinddata->achName;
112 }
113
114 static const FIND_ATTR GetAttrFromFindData(
115 FIND_STRUCT* pFinddata
116 )
117 {
118 return pFinddata->attrFile;
119 }
120
121 static inline bool IsDir(
122 FIND_ATTR vAttr
123 )
124 {
125 return (vAttr & FILE_DIRECTORY) != 0;
126 }
127
128 static inline bool IsHidden(
129 FIND_ATTR vAttr
130 )
131 {
132 return (vAttr & (FILE_HIDDEN | FILE_SYSTEM)) != 0;
133 }
134
135 // ----------------------------------------------------------------------------
136 // constants
137 // ----------------------------------------------------------------------------
138
139 #ifndef MAX_PATH
140 #define MAX_PATH 260 // from PM++ headers
141 #endif
142
143 // ----------------------------------------------------------------------------
144 // macros
145 // ----------------------------------------------------------------------------
146
147 #define M_DIR ((wxDirData *)m_data)
148
149 // ----------------------------------------------------------------------------
150 // private classes
151 // ----------------------------------------------------------------------------
152
153 // this class stores everything we need to enumerate the files
154 class wxDirData
155 {
156 public:
157 wxDirData(const wxString& rsDirname);
158 ~wxDirData();
159
160 void SetFileSpec(const wxString& rsFilespec) { m_sFilespec = rsFilespec; }
161 void SetFlags(int nFlags) { m_nFlags = nFlags; }
162
163 void Close();
164 void Rewind();
165 bool Read(wxString* rsFilename);
166
167 private:
168 FIND_DATA m_vFinddata;
169 wxString m_sDirname;
170 wxString m_sFilespec;
171 int m_nFlags;
172 }; // end of CLASS wxDirData
173
174 // ============================================================================
175 // implementation
176 // ============================================================================
177
178 // ----------------------------------------------------------------------------
179 // wxDirData
180 // ----------------------------------------------------------------------------
181
182 wxDirData::wxDirData(
183 const wxString& rsDirname
184 )
185 : m_sDirname(rsDirname)
186 {
187 m_vFinddata = InitFindData();
188 } // end of wxDirData::wxDirData
189
190 wxDirData::~wxDirData()
191 {
192 Close();
193 } // end of wxDirData::~wxDirData
194
195 void wxDirData::Close()
196 {
197 if ( IsFindDataOk(m_vFinddata) )
198 {
199 FreeFindData(m_vFinddata);
200 m_vFinddata = InitFindData();
201 }
202 } // end of wxDirData::Close
203
204 void wxDirData::Rewind()
205 {
206 Close();
207 } // end of wxDirData::Rewind
208
209 bool wxDirData::Read(
210 wxString* psFilename
211 )
212 {
213 bool bFirst = FALSE;
214
215 FILEFINDBUF3 vFinddata;
216 #define PTR_TO_FINDDATA (&vFinddata)
217
218 if (!IsFindDataOk(m_vFinddata))
219 {
220 //
221 // Open first
222 //
223 wxString sFilespec = m_sDirname;
224
225 if ( !wxEndsWithPathSeparator(sFilespec) )
226 {
227 sFilespec += _T('\\');
228 }
229 sFilespec += (!m_sFilespec ? _T("*.*") : m_sFilespec.c_str());
230
231 m_vFinddata = FindFirst( sFilespec
232 ,PTR_TO_FINDDATA
233 );
234 bFirst = TRUE;
235 }
236
237 if ( !IsFindDataOk(m_vFinddata) )
238 {
239 return FALSE;
240 }
241
242 const wxChar* zName;
243 FIND_ATTR vAttr;
244
245 for ( ;; )
246 {
247 if (bFirst)
248 {
249 bFirst = FALSE;
250 }
251 else
252 {
253 if (!FindNext( m_vFinddata
254 ,PTR_TO_FINDDATA
255 ))
256 {
257 return FALSE;
258 }
259 }
260
261 zName = GetNameFromFindData(PTR_TO_FINDDATA);
262 vAttr = GetAttrFromFindData(PTR_TO_FINDDATA);
263
264 //
265 // Don't return "." and ".." unless asked for
266 //
267 if ( zName[0] == _T('.') &&
268 ((zName[1] == _T('.') && zName[2] == _T('\0')) ||
269 (zName[1] == _T('\0'))) )
270 {
271 if (!(m_nFlags & wxDIR_DOTDOT))
272 continue;
273 }
274
275 //
276 // Check the type now
277 //
278 if (!(m_nFlags & wxDIR_FILES) && !IsDir(vAttr))
279 {
280 //
281 // It's a file, but we don't want them
282 //
283 continue;
284 }
285 else if (!(m_nFlags & wxDIR_DIRS) && IsDir(vAttr) )
286 {
287 //
288 // It's a dir, and we don't want it
289 //
290 continue;
291 }
292
293 //
294 // Finally, check whether it's a hidden file
295 //
296 if (!(m_nFlags & wxDIR_HIDDEN))
297 {
298 if (IsHidden(vAttr))
299 {
300 //
301 // It's a hidden file, skip it
302 //
303 continue;
304 }
305 }
306 *psFilename = zName;
307 break;
308 }
309 return TRUE;
310 } // end of wxDirData::Read
311
312 // ----------------------------------------------------------------------------
313 // wxDir helpers
314 // ----------------------------------------------------------------------------
315
316 /* static */
317 bool wxDir::Exists(
318 const wxString& rsDir
319 )
320 {
321 return wxPathExists(rsDir);
322 } // end of wxDir::Exists
323
324 // ----------------------------------------------------------------------------
325 // wxDir construction/destruction
326 // ----------------------------------------------------------------------------
327
328 wxDir::wxDir(
329 const wxString& rsDirname
330 )
331 {
332 m_data = NULL;
333
334 (void)Open(rsDirname);
335 } // end of wxDir::wxDir
336
337 bool wxDir::Open(
338 const wxString& rsDirname
339 )
340 {
341 delete M_DIR;
342 m_data = new wxDirData(rsDirname);
343 return TRUE;
344 } // end of wxDir::Open
345
346 bool wxDir::IsOpened() const
347 {
348 return m_data != NULL;
349 } // end of wxDir::IsOpen
350
351 wxDir::~wxDir()
352 {
353 delete M_DIR;
354 } // end of wxDir::~wxDir
355
356 // ----------------------------------------------------------------------------
357 // wxDir enumerating
358 // ----------------------------------------------------------------------------
359
360 bool wxDir::GetFirst(
361 wxString* psFilename
362 , const wxString& rsFilespec
363 , int nFlags
364 ) const
365 {
366 wxCHECK_MSG( IsOpened(), FALSE, _T("must wxDir::Open() first") );
367 M_DIR->Rewind();
368 M_DIR->SetFileSpec(rsFilespec);
369 M_DIR->SetFlags(nFlags);
370 return GetNext(psFilename);
371 } // end of wxDir::GetFirst
372
373 bool wxDir::GetNext(
374 wxString* psFilename
375 ) const
376 {
377 wxCHECK_MSG( IsOpened(), FALSE, _T("must wxDir::Open() first") );
378 wxCHECK_MSG( psFilename, FALSE, _T("bad pointer in wxDir::GetNext()") );
379 return M_DIR->Read(psFilename);
380 } // end of wxDir::GetNext
381