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