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