]> git.saurik.com Git - wxWidgets.git/blame - src/unix/dir.cpp
AddBook ignores wxMac paths (still won't work)
[wxWidgets.git] / src / unix / dir.cpp
CommitLineData
1944c6bd
VZ
1/////////////////////////////////////////////////////////////////////////////
2// Name: unix/dir.cpp
3// Purpose: wxDir implementation for Unix/POSIX systems
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 wxMatchWild
38
39#include <sys/types.h>
40
41#include <dirent.h>
42
43// ----------------------------------------------------------------------------
44// macros
45// ----------------------------------------------------------------------------
46
47#define M_DIR ((wxDirData *)m_data)
48
49// ----------------------------------------------------------------------------
50// private classes
51// ----------------------------------------------------------------------------
52
53// this class stores everything we need to enumerate the files
54class wxDirData
55{
56public:
57 wxDirData(const wxString& dirname);
58 ~wxDirData();
59
60 bool IsOk() const { return m_dir != NULL; }
61
62 void SetFileSpec(const wxString& filespec) { m_filespec = filespec; }
63 void SetFlags(int flags) { m_flags = flags; }
64
65 void Rewind() { rewinddir(m_dir); }
66 bool Read(wxString *filename);
67
35332784
VZ
68 const wxString& GetName() const { return m_dirname; }
69
1944c6bd
VZ
70private:
71 DIR *m_dir;
72
73 wxString m_dirname;
74 wxString m_filespec;
75
76 int m_flags;
77};
78
79// ============================================================================
80// implementation
81// ============================================================================
82
83// ----------------------------------------------------------------------------
84// wxDirData
85// ----------------------------------------------------------------------------
86
87#if !defined( __VMS__ ) || ( __VMS_VER >= 70000000 )
88
89wxDirData::wxDirData(const wxString& dirname)
90 : m_dirname(dirname)
91{
92 m_dir = NULL;
93
94 // throw away the trailing slashes
95 size_t n = m_dirname.length();
96 wxCHECK_RET( n, _T("empty dir name in wxDir") );
97
98 while ( n > 0 && m_dirname[--n] == '/' )
99 ;
100
101 m_dirname.Truncate(n + 1);
102
103 // do open the dir
104 m_dir = opendir(m_dirname.fn_str());
105}
106
107wxDirData::~wxDirData()
108{
109 if ( m_dir )
110 {
111 if ( closedir(m_dir) != 0 )
112 {
113 wxLogLastError(_T("closedir"));
114 }
115 }
116}
117
118bool wxDirData::Read(wxString *filename)
119{
dc3d889d 120 dirent *de = (dirent *)NULL; // just to silent compiler warnings
1944c6bd
VZ
121 bool matches = FALSE;
122
123 while ( !matches )
124 {
125 de = readdir(m_dir);
126 if ( !de )
127 return FALSE;
128
129 // don't return "." and ".." unless asked for
130 if ( de->d_name[0] == '.' &&
131 ((de->d_name[1] == '.' && de->d_name[2] == '\0') ||
132 (de->d_name[1] == '\0')) )
133 {
134 if ( !(m_flags & wxDIR_DOTDOT) )
135 continue;
136 }
137
138 // check the type now
139 if ( !(m_flags & wxDIR_FILES) &&
140 !wxDir::Exists(m_dirname + _T('/') + de->d_name) )
141 {
142 // it's a file, but we don't want them
143 continue;
144 }
145 else if ( !(m_flags & wxDIR_DIRS) &&
146 wxDir::Exists(m_dirname + _T('/') + de->d_name) )
147 {
148 // it's a dir, and we don't want it
149 continue;
150 }
151
152 // finally, check the name
153 if ( !m_filespec )
154 {
155 matches = m_flags & wxDIR_HIDDEN ? TRUE : de->d_name[0] != '.';
156 }
157 else
158 {
159 // test against the pattern
160 matches = wxMatchWild(m_filespec, de->d_name,
161 !(m_flags & wxDIR_HIDDEN));
162 }
163 }
164
165 *filename = de->d_name;
166
167 return TRUE;
168}
169
170#else // old VMS (TODO)
171
172wxDirData::wxDirData(const wxString& WXUNUSED(dirname))
173{
174 wxFAIL_MSG(_T("not implemented"));
175}
176
177wxDirData::~wxDirData()
178{
179}
180
181bool wxDirData::Read(wxString * WXUNUSED(filename))
182{
183 return FALSE;
184}
185
186#endif // not or new VMS/old VMS
187
188// ----------------------------------------------------------------------------
189// wxDir helpers
190// ----------------------------------------------------------------------------
191
192/* static */
193bool wxDir::Exists(const wxString& dir)
194{
195 return wxPathExists(dir);
196}
197
198// ----------------------------------------------------------------------------
199// wxDir construction/destruction
200// ----------------------------------------------------------------------------
201
202wxDir::wxDir(const wxString& dirname)
203{
204 m_data = NULL;
205
206 (void)Open(dirname);
207}
208
209bool wxDir::Open(const wxString& dirname)
210{
211 delete M_DIR;
212 m_data = new wxDirData(dirname);
213
214 if ( !M_DIR->IsOk() )
215 {
216 wxLogSysError(_("Can not enumerate files in directory '%s'"),
217 dirname.c_str());
218
219 delete M_DIR;
220 m_data = NULL;
221
222 return FALSE;
223 }
224
225 return TRUE;
226}
227
228bool wxDir::IsOpened() const
229{
230 return m_data != NULL;
231}
232
35332784
VZ
233wxString wxDir::GetName() const
234{
235 wxString name;
236 if ( m_data )
237 {
238 name = M_DIR->GetName();
239 if ( !name.empty() && (name.Last() == _T('/')) )
240 {
241 // chop off the last (back)slash
242 name.Truncate(name.length() - 1);
243 }
244 }
245
246 return name;
247}
248
1944c6bd
VZ
249wxDir::~wxDir()
250{
251 delete M_DIR;
252}
253
254// ----------------------------------------------------------------------------
255// wxDir enumerating
256// ----------------------------------------------------------------------------
257
258bool wxDir::GetFirst(wxString *filename,
259 const wxString& filespec,
260 int flags) const
261{
262 wxCHECK_MSG( IsOpened(), FALSE, _T("must wxDir::Open() first") );
263
264 M_DIR->Rewind();
265
266 M_DIR->SetFileSpec(filespec);
267 M_DIR->SetFlags(flags);
268
269 return GetNext(filename);
270}
271
272bool wxDir::GetNext(wxString *filename) const
273{
274 wxCHECK_MSG( IsOpened(), FALSE, _T("must wxDir::Open() first") );
275
276 wxCHECK_MSG( filename, FALSE, _T("bad pointer in wxDir::GetNext()") );
277
278 return M_DIR->Read(filename);
279}