]> git.saurik.com Git - wxWidgets.git/blame - src/msw/dir.cpp
removed 2nd frame from html test sample; test sample now shows DL,DT,DD support
[wxWidgets.git] / src / msw / dir.cpp
CommitLineData
1944c6bd
VZ
1/////////////////////////////////////////////////////////////////////////////
2// Name: msw/dir.cpp
3// Purpose: wxDir implementation for Win32
4// Author: Vadim Zeitlin
5// Modified by:
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#ifdef __BORLANDC__
28 #pragma hdrstop
29#endif
30
31#ifndef WX_PRECOMP
32 #include "wx/intl.h"
33 #include "wx/log.h"
34#endif // PCH
35
36#include "wx/dir.h"
37#include "wx/filefn.h" // for wxPathExists()
38
8f177c8e
VZ
39// ----------------------------------------------------------------------------
40// define the types and functions used for file searching
41// ----------------------------------------------------------------------------
42
43// under Win16 use compiler-specific functions
44#ifdef __WIN16__
45 #ifdef __VISUALC__
46 #include <dos.h>
47 #include <errno.h>
48
49 typedef struct _find_t FIND_STRUCT;
50 #elif defined(__BORLANDC__)
51 #include <dir.h>
52
53 typedef struct ffblk FIND_STRUCT;
54 #else
55 #error "No directory searching functions for this compiler"
56 #endif
57
58 typedef FIND_STRUCT *FIND_DATA;
59 typedef char FIND_ATTR;
60
61 static inline FIND_DATA InitFindData() { return (FIND_DATA)NULL; }
62 static inline bool IsFindDataOk(FIND_DATA fd) { return fd != NULL; }
63 static inline void FreeFindData(FIND_DATA fd) { free(fd); }
64
65 static inline FIND_DATA FindFirst(const wxString& spec,
66 FIND_STRUCT * WXUNUSED(finddata))
67 {
68 // attribute to find all files
69 static const FIND_ATTR attr = 0x3F;
70
71 FIND_DATA fd = (FIND_DATA)malloc(sizeof(FIND_STRUCT));
72
73 if (
74 #ifdef __VISUALC__
75 _dos_findfirst(spec, attr, fd) == 0
76 #else // Borland
77 findfirst(spec, fd, attr) == 0
78 #endif
79 )
80 {
81 return fd;
82 }
83 else
84 {
85 free(fd);
86
87 return NULL;
88 }
89 }
90
91 static inline bool FindNext(FIND_DATA fd, FIND_STRUCT * WXUNUSED(finddata))
92 {
93 #ifdef __VISUALC__
94 return _dos_findnext(fd) == 0;
95 #else // Borland
96 return findnext(fd) == 0;
97 #endif
98 }
99
100 static const wxChar *GetNameFromFindData(FIND_STRUCT *finddata)
101 {
102 #ifdef __VISUALC__
103 return finddata->name;
104 #else // Borland
105 return finddata->ff_name;
106 #endif
107 }
108
109 static const FIND_ATTR GetAttrFromFindData(FIND_STRUCT *finddata)
110 {
111 #ifdef __VISUALC__
112 return finddata->attrib;
113 #else // Borland
114 return finddata->ff_attrib;
115 #endif
116 }
117
118 static inline bool IsDir(FIND_ATTR attr)
119 {
120 return (attr & _A_SUBDIR) != 0;
121 }
122
123 static inline bool IsHidden(FIND_ATTR attr)
124 {
125 return (attr & (_A_SYSTEM | _A_HIDDEN)) != 0;
126 }
127#else // Win32
128 #include <windows.h>
129
130 typedef WIN32_FIND_DATA FIND_STRUCT;
131 typedef HANDLE FIND_DATA;
132 typedef DWORD FIND_ATTR;
133
134 static inline FIND_DATA InitFindData() { return INVALID_HANDLE_VALUE; }
135
136 static inline bool IsFindDataOk(FIND_DATA fd)
137 {
138 return fd != INVALID_HANDLE_VALUE;
139 }
140
141 static inline void FreeFindData(FIND_DATA fd)
142 {
143 if ( !::FindClose(fd) )
144 {
145 wxLogLastError(_T("FindClose"));
146 }
147 }
148
149 static inline FIND_DATA FindFirst(const wxString& spec,
150 FIND_STRUCT *finddata)
151 {
c5a1681b 152 return ::FindFirstFile(spec, finddata);
8f177c8e
VZ
153 }
154
155 static inline bool FindNext(FIND_DATA fd, FIND_STRUCT *finddata)
156 {
157 return ::FindNextFile(fd, finddata) != 0;
158 }
159
160 static const wxChar *GetNameFromFindData(FIND_STRUCT *finddata)
161 {
162 return finddata->cFileName;
163 }
164
165 static const FIND_ATTR GetAttrFromFindData(FIND_STRUCT *finddata)
166 {
167 return finddata->dwFileAttributes;
168 }
169
170 static inline bool IsDir(FIND_ATTR attr)
171 {
172 return (attr & FILE_ATTRIBUTE_DIRECTORY) != 0;
173 }
174
175 static inline bool IsHidden(FIND_ATTR attr)
176 {
177 return (attr & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) != 0;
178 }
179#endif // __WIN16__
1944c6bd
VZ
180
181// ----------------------------------------------------------------------------
182// constants
183// ----------------------------------------------------------------------------
184
185#ifndef MAX_PATH
186 #define MAX_PATH 260 // from VC++ headers
187#endif
188
189// ----------------------------------------------------------------------------
190// macros
191// ----------------------------------------------------------------------------
192
193#define M_DIR ((wxDirData *)m_data)
194
195// ----------------------------------------------------------------------------
196// private classes
197// ----------------------------------------------------------------------------
198
199// this class stores everything we need to enumerate the files
200class wxDirData
201{
202public:
203 wxDirData(const wxString& dirname);
204 ~wxDirData();
205
206 void SetFileSpec(const wxString& filespec) { m_filespec = filespec; }
207 void SetFlags(int flags) { m_flags = flags; }
208
209 void Close();
210 void Rewind();
211 bool Read(wxString *filename);
212
213private:
8f177c8e 214 FIND_DATA m_finddata;
1944c6bd
VZ
215
216 wxString m_dirname;
217 wxString m_filespec;
218
219 int m_flags;
220};
221
222// ============================================================================
223// implementation
224// ============================================================================
225
226// ----------------------------------------------------------------------------
227// wxDirData
228// ----------------------------------------------------------------------------
229
230wxDirData::wxDirData(const wxString& dirname)
231 : m_dirname(dirname)
232{
8f177c8e 233 m_finddata = InitFindData();
1944c6bd
VZ
234}
235
236wxDirData::~wxDirData()
237{
238 Close();
239}
240
241void wxDirData::Close()
242{
8f177c8e 243 if ( IsFindDataOk(m_finddata) )
1944c6bd 244 {
8f177c8e 245 FreeFindData(m_finddata);
4afd7529 246
8f177c8e 247 m_finddata = InitFindData();
1944c6bd
VZ
248 }
249}
250
251void wxDirData::Rewind()
252{
253 Close();
254}
255
256bool wxDirData::Read(wxString *filename)
257{
258 bool first = FALSE;
259
8f177c8e 260#ifdef __WIN32__
1944c6bd 261 WIN32_FIND_DATA finddata;
8f177c8e
VZ
262 #define PTR_TO_FINDDATA (&finddata)
263#else // Win16
264 #define PTR_TO_FINDDATA (m_finddata)
265#endif
266
267 if ( !IsFindDataOk(m_finddata) )
1944c6bd
VZ
268 {
269 // open first
4afd7529
VZ
270 wxString filespec;
271 filespec << m_dirname << _T('\\')
272 << (!m_filespec ? _T("*.*") : m_filespec.c_str());
273
8f177c8e 274 m_finddata = FindFirst(filespec, PTR_TO_FINDDATA);
1944c6bd
VZ
275
276 first = TRUE;
277 }
278
8f177c8e 279 if ( !IsFindDataOk(m_finddata) )
1944c6bd 280 {
8f177c8e 281#ifdef __WIN32__
1944c6bd
VZ
282 DWORD err = ::GetLastError();
283
4afd7529 284 if ( err != ERROR_FILE_NOT_FOUND )
1944c6bd
VZ
285 {
286 wxLogSysError(err, _("Can not enumerate files in directory '%s'"),
287 m_dirname.c_str());
288 }
8f177c8e 289#endif // __WIN32__
1944c6bd
VZ
290 //else: not an error, just no (such) files
291
292 return FALSE;
293 }
294
1944c6bd 295 const wxChar *name;
8f177c8e 296 FIND_ATTR attr;
1944c6bd 297
4afd7529 298 for ( ;; )
1944c6bd
VZ
299 {
300 if ( first )
301 {
302 first = FALSE;
303 }
304 else
305 {
8f177c8e 306 if ( !FindNext(m_finddata, PTR_TO_FINDDATA) )
1944c6bd 307 {
8f177c8e 308#ifdef __WIN32__
1944c6bd
VZ
309 DWORD err = ::GetLastError();
310
311 if ( err != ERROR_NO_MORE_FILES )
312 {
313 wxLogLastError(_T("FindNext"));
314 }
8f177c8e 315#endif // __WIN32__
1944c6bd
VZ
316 //else: not an error, just no more (such) files
317
318 return FALSE;
319 }
320 }
321
8f177c8e
VZ
322 name = GetNameFromFindData(PTR_TO_FINDDATA);
323 attr = GetAttrFromFindData(PTR_TO_FINDDATA);
1944c6bd
VZ
324
325 // don't return "." and ".." unless asked for
326 if ( name[0] == _T('.') &&
327 ((name[1] == _T('.') && name[2] == _T('\0')) ||
328 (name[1] == _T('\0'))) )
329 {
330 if ( !(m_flags & wxDIR_DOTDOT) )
331 continue;
332 }
333
334 // check the type now
8f177c8e 335 if ( !(m_flags & wxDIR_FILES) && !IsDir(attr) )
1944c6bd
VZ
336 {
337 // it's a file, but we don't want them
338 continue;
339 }
8f177c8e 340 else if ( !(m_flags & wxDIR_DIRS) && IsDir(attr) )
1944c6bd
VZ
341 {
342 // it's a dir, and we don't want it
343 continue;
344 }
345
346 // finally, check whether it's a hidden file
347 if ( !(m_flags & wxDIR_HIDDEN) )
348 {
8f177c8e 349 if ( IsHidden(attr) )
4afd7529
VZ
350 {
351 // it's a hidden file, skip it
352 continue;
353 }
1944c6bd 354 }
1944c6bd 355
4afd7529
VZ
356 *filename = name;
357
358 break;
359 }
1944c6bd
VZ
360
361 return TRUE;
362}
363
364// ----------------------------------------------------------------------------
365// wxDir helpers
366// ----------------------------------------------------------------------------
367
368/* static */
369bool wxDir::Exists(const wxString& dir)
370{
371 return wxPathExists(dir);
372}
373
374// ----------------------------------------------------------------------------
375// wxDir construction/destruction
376// ----------------------------------------------------------------------------
377
378wxDir::wxDir(const wxString& dirname)
379{
380 m_data = NULL;
381
382 (void)Open(dirname);
383}
384
385bool wxDir::Open(const wxString& dirname)
386{
387 delete M_DIR;
388 m_data = new wxDirData(dirname);
389
390 return TRUE;
391}
392
393bool wxDir::IsOpened() const
394{
395 return m_data != NULL;
396}
397
398wxDir::~wxDir()
399{
400 delete M_DIR;
401}
402
403// ----------------------------------------------------------------------------
404// wxDir enumerating
405// ----------------------------------------------------------------------------
406
407bool wxDir::GetFirst(wxString *filename,
408 const wxString& filespec,
409 int flags) const
410{
411 wxCHECK_MSG( IsOpened(), FALSE, _T("must wxDir::Open() first") );
412
413 M_DIR->Rewind();
414
415 M_DIR->SetFileSpec(filespec);
416 M_DIR->SetFlags(flags);
417
418 return GetNext(filename);
419}
420
421bool wxDir::GetNext(wxString *filename) const
422{
423 wxCHECK_MSG( IsOpened(), FALSE, _T("must wxDir::Open() first") );
424
425 wxCHECK_MSG( filename, FALSE, _T("bad pointer in wxDir::GetNext()") );
426
427 return M_DIR->Read(filename);
428}