Remove identic implementations of wxDir::Exists from platform-specific files and...
[wxWidgets.git] / src / mgl / dirmgl.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mgl/dir.cpp
3 // Purpose: wxDir implementation for MGL
4 // Author: Vaclav Slavik, Vadim Zeitlin
5 // Modified by:
6 // Created: 2001/12/09
7 // RCS-ID: $Id$
8 // Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // (c) 2001-2002 SciTech Software, Inc. (www.scitechsoft.com)
10 // Licence: wxWindows licence
11 /////////////////////////////////////////////////////////////////////////////
12
13 // For compilers that support precompilation, includes "wx.h".
14 #include "wx/wxprec.h"
15
16 #ifdef __BORLANDC__
17 #pragma hdrstop
18 #endif
19
20 // ============================================================================
21 // declarations
22 // ============================================================================
23
24 // ----------------------------------------------------------------------------
25 // headers
26 // ----------------------------------------------------------------------------
27
28 #ifndef __UNIX__
29
30 #ifndef WX_PRECOMP
31 #include "wx/intl.h"
32 #include "wx/log.h"
33 #endif // PCH
34
35 #include "wx/dir.h"
36 #include "wx/filefn.h" // for wxMatchWild
37 #include "wx/mgl/private.h"
38
39 // ----------------------------------------------------------------------------
40 // macros
41 // ----------------------------------------------------------------------------
42
43 #define M_DIR ((wxDirData *)m_data)
44
45 // ----------------------------------------------------------------------------
46 // private classes
47 // ----------------------------------------------------------------------------
48
49 // this class stores everything we need to enumerate the files
50 class wxDirData
51 {
52 public:
53 wxDirData(const wxString& dirname);
54 ~wxDirData();
55
56 bool IsOk() const { return m_dir != NULL; }
57
58 void SetFileSpec(const wxString& filespec);
59 void SetFlags(int flags) { m_flags = flags; }
60
61 void Rewind();
62 bool Read(wxString *filename);
63
64 const wxString& GetName() const { return m_dirname; }
65
66 private:
67 void *m_dir;
68
69 wxString m_dirname;
70 wxString m_filespec;
71
72 int m_flags;
73 };
74
75 // ============================================================================
76 // implementation
77 // ============================================================================
78
79 // ----------------------------------------------------------------------------
80 // wxDirData
81 // ----------------------------------------------------------------------------
82
83 wxDirData::wxDirData(const wxString& dirname)
84 : m_dirname(dirname)
85 {
86 m_dir = NULL;
87
88 // throw away the trailing slashes
89 size_t n = m_dirname.length();
90 wxCHECK_RET( n, wxT("empty dir name in wxDir") );
91
92 while ( n > 0 && m_dirname[--n] == wxFILE_SEP_PATH ) {}
93
94 m_dirname.Truncate(n + 1);
95 }
96
97 wxDirData::~wxDirData()
98 {
99 if ( m_dir )
100 PM_findClose(m_dir);
101 }
102
103 void wxDirData::SetFileSpec(const wxString& filespec)
104 {
105 #ifdef __DOS__
106 if ( filespec.empty() )
107 m_filespec = wxT("*.*");
108 else
109 #endif
110 m_filespec = filespec;
111 }
112
113 void wxDirData::Rewind()
114 {
115 if ( m_dir )
116 {
117 PM_findClose(m_dir);
118 m_dir = NULL;
119 }
120 }
121
122 bool wxDirData::Read(wxString *filename)
123 {
124 PM_findData data;
125 bool matches = false;
126
127 data.dwSize = sizeof(data);
128
129 wxString path = m_dirname;
130 path += wxFILE_SEP_PATH;
131 path.reserve(path.length() + 255); // speed up string concatenation
132
133 while ( !matches )
134 {
135 if ( m_dir )
136 {
137 if ( !PM_findNextFile(m_dir, &data) )
138 return false;
139 }
140 else
141 {
142 m_dir = PM_findFirstFile(path + m_filespec , &data);
143 if ( m_dir == PM_FILE_INVALID )
144 {
145 m_dir = NULL;
146 return false;
147 }
148 }
149
150 // don't return "." and ".." unless asked for
151 if ( data.name[0] == '.' &&
152 ((data.name[1] == '.' && data.name[2] == '\0') ||
153 (data.name[1] == '\0')) )
154 {
155 if ( !(m_flags & wxDIR_DOTDOT) )
156 continue;
157
158 // we found a valid match
159 break;
160 }
161
162 // check the type now
163 if ( !(m_flags & wxDIR_FILES) && !(data.attrib & PM_FILE_DIRECTORY) )
164 {
165 // it's a file, but we don't want them
166 continue;
167 }
168 else if ( !(m_flags & wxDIR_DIRS) && (data.attrib & PM_FILE_DIRECTORY) )
169 {
170 // it's a dir, and we don't want it
171 continue;
172 }
173
174 matches = m_flags & wxDIR_HIDDEN ? true : !(data.attrib & PM_FILE_HIDDEN);
175 }
176
177 *filename = data.name;
178
179 return true;
180 }
181
182 // ----------------------------------------------------------------------------
183 // wxDir construction/destruction
184 // ----------------------------------------------------------------------------
185
186 wxDir::wxDir(const wxString& dirname)
187 {
188 m_data = NULL;
189
190 (void)Open(dirname);
191 }
192
193 bool wxDir::Open(const wxString& dirname)
194 {
195 delete M_DIR;
196 m_data = NULL;
197
198 if ( !wxDir::Exists(dirname) )
199 {
200 wxLogError(_("Directory '%s' doesn't exist!"), dirname.c_str());
201 return false;
202 }
203
204 m_data = new wxDirData(dirname);
205 return true;
206 }
207
208 bool wxDir::IsOpened() const
209 {
210 return m_data != NULL;
211 }
212
213 wxString wxDir::GetName() const
214 {
215 wxString name;
216 if ( m_data )
217 {
218 name = M_DIR->GetName();
219 if ( !name.empty() && (name.Last() == wxFILE_SEP_PATH) )
220 {
221 // chop off the last (back)slash
222 name.Truncate(name.length() - 1);
223 }
224 }
225
226 return name;
227 }
228
229 wxDir::~wxDir()
230 {
231 delete M_DIR;
232 }
233
234 // ----------------------------------------------------------------------------
235 // wxDir enumerating
236 // ----------------------------------------------------------------------------
237
238 bool wxDir::GetFirst(wxString *filename,
239 const wxString& filespec,
240 int flags) const
241 {
242 wxCHECK_MSG( IsOpened(), false, wxT("must wxDir::Open() first") );
243
244 M_DIR->Rewind();
245
246 M_DIR->SetFileSpec(filespec);
247 M_DIR->SetFlags(flags);
248
249 return GetNext(filename);
250 }
251
252 bool wxDir::GetNext(wxString *filename) const
253 {
254 wxCHECK_MSG( IsOpened(), false, wxT("must wxDir::Open() first") );
255
256 wxCHECK_MSG( filename, false, wxT("bad pointer in wxDir::GetNext()") );
257
258 return M_DIR->Read(filename);
259 }
260
261 #endif // !__UNIX__