]> git.saurik.com Git - wxWidgets.git/blob - src/common/filename.cpp
Various fixes for wxFilename.
[wxWidgets.git] / src / common / filename.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: filename.cpp
3 // Purpose: wxFileName - encapsulates candy
4 // Author: Robert Roebling
5 // Modified by:
6 // Created: 28.12.2000
7 // RCS-ID: $Id$
8 // Copyright: (c) 2000 Robert Roebling
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "filename.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WX_PRECOMP
24 #include "wx/intl.h"
25 #include "wx/log.h"
26 #endif
27
28 #include "wx/filename.h"
29 #include "wx/tokenzr.h"
30 #include "wx/utils.h"
31
32 //----------------------------------------------------------------------------
33 // wxFileName
34 //----------------------------------------------------------------------------
35
36 wxFileName::wxFileName( const wxFileName &filepath )
37 {
38 m_ext = filepath.GetExt();
39 m_name = filepath.GetName();
40 const wxArrayString &dirs = filepath.GetDirs();
41 for (size_t i = 0; i < dirs.GetCount(); i++)
42 m_dirs.Add( dirs[i] );
43 }
44
45 void wxFileName::Assign( const wxFileName &filepath )
46 {
47 m_dirs.Clear();
48 m_ext = filepath.GetExt();
49 m_name = filepath.GetName();
50 const wxArrayString &dirs = filepath.GetDirs();
51 for (size_t i = 0; i < dirs.GetCount(); i++)
52 m_dirs.Add( dirs[i] );
53 }
54
55 void wxFileName::Assign( const wxString &path, bool dir_only, wxPathFormat format )
56 {
57 m_ext = wxEmptyString;
58 m_name = wxEmptyString;
59 m_dirs.Clear();
60
61 format = GetFormat( format );
62
63 wxString seps;
64 if (format == wxPATH_DOS)
65 {
66 seps = "/\\";
67 }
68 else
69 if (format == wxPATH_UNIX)
70 {
71 seps = "/";
72 }
73 else
74 {
75 seps = ":";
76 }
77
78 wxStringTokenizer tn( path, seps, wxTOKEN_RET_EMPTY_ALL );
79 bool first = TRUE;
80 while (tn.HasMoreTokens())
81 {
82 wxString token( tn.GetNextToken() );
83
84 // If the path starts with a slash, we need the first
85 // dir entry to be an empty for later reassembly.
86
87 if (first || !token.IsEmpty())
88 m_dirs.Add( token );
89 first = FALSE;
90 }
91
92 if (!dir_only)
93 {
94 // make last m_dir -> m_name
95 size_t last = m_dirs.GetCount();
96 if (last == 0) return;
97 last--;
98 m_name = m_dirs[last];
99 m_dirs.Remove( last );
100
101 if (m_name == wxT(".")) return;
102 if (m_name == wxT("..")) return;
103
104 // ext?
105 int pos = m_name.Find( wxT('.') );
106 if (pos == -1) return;
107
108 bool has_starting_dot = (pos == 0);
109 if (has_starting_dot && (format == wxPATH_UNIX))
110 {
111 // remove dot
112 m_name.Remove(0,1);
113
114 // search again
115 pos = m_name.Find( wxT('.') );
116 if (pos == -1)
117 {
118 // add dot back
119 m_name.Prepend( "." );
120 return;
121 }
122 }
123 m_ext = m_name;
124 m_ext.Remove( 0, pos+1 );
125
126 m_name.Remove( pos, m_name.Len()-pos );
127
128 if (has_starting_dot && (format == wxPATH_UNIX))
129 {
130 // add dot back
131 m_name.Prepend( "." );
132 return;
133 }
134 }
135 }
136
137 bool wxFileName::FileExists()
138 {
139 return wxFileName::FileExists( GetFullPath() );
140 }
141
142 bool wxFileName::FileExists( const wxString &file )
143 {
144 return ::wxFileExists( file );
145 }
146
147 bool wxFileName::DirExists()
148 {
149 return wxFileName::DirExists( GetFullPath() );
150 }
151
152 bool wxFileName::DirExists( const wxString &dir )
153 {
154 return ::wxDirExists( dir );
155 }
156
157 void wxFileName::AssignCwd()
158 {
159 Assign( wxFileName::GetCwd(), TRUE );
160 }
161
162 wxString wxFileName::GetCwd()
163 {
164 return ::wxGetCwd();
165 }
166
167 bool wxFileName::SetCwd()
168 {
169 return wxFileName::SetCwd( GetFullPath() );
170 }
171
172 bool wxFileName::SetCwd( const wxString &cwd )
173 {
174 return ::wxSetWorkingDirectory( cwd );
175 }
176
177 void wxFileName::AssignHomeDir()
178 {
179 Assign( wxFileName::GetHomeDir(), TRUE );
180 }
181
182 wxString wxFileName::GetHomeDir()
183 {
184 return ::wxGetHomeDir();
185 }
186
187 void wxFileName::AssignTempFileName( const wxString &prefix )
188 {
189 }
190
191 bool wxFileName::Mkdir( int perm )
192 {
193 return wxFileName::Mkdir( GetFullPath(), perm );
194 }
195
196 bool wxFileName::Mkdir( const wxString &dir, int perm )
197 {
198 return ::wxMkdir( dir, perm );
199 }
200
201 bool wxFileName::Rmdir()
202 {
203 return wxFileName::Rmdir( GetFullPath() );
204 }
205
206 bool wxFileName::Rmdir( const wxString &dir )
207 {
208 return ::wxRmdir( dir );
209 }
210
211 bool wxFileName::Normalize( const wxString &cwd, const wxString &home )
212 {
213 wxFileName tmp( *this );
214 m_dirs.Clear();
215 const wxArrayString &dirs = tmp.GetDirs();
216
217 if (dirs.GetCount() == 0) return FALSE;
218
219 size_t start = 0;
220
221 if (dirs[0] == wxT("."))
222 {
223 if (cwd == wxEmptyString)
224 Assign( wxFileName::GetCwd(), TRUE );
225 else
226 Assign( cwd );
227 start = 1;
228 }
229 else
230 if (dirs[0] == wxT(".."))
231 {
232 if (cwd == wxEmptyString)
233 Assign( wxFileName::GetCwd(), TRUE );
234 else
235 Assign( cwd );
236 m_dirs.Remove( m_dirs.GetCount()-1 );
237 start = 1;
238 }
239 else
240 if (dirs[0] == wxT("~"))
241 {
242 if (home == wxEmptyString)
243 Assign( wxFileName::GetHomeDir(), TRUE );
244 else
245 Assign( home );
246 start = 1;
247 }
248
249 for (size_t i = start; i < dirs.GetCount(); i++)
250 {
251 if (dirs[i] == wxT(".")) continue;
252
253 if (dirs[i] == wxT(".."))
254 {
255 m_dirs.Remove( m_dirs.GetCount()-1 );
256 continue;
257 }
258
259 // expand env vars here ?
260
261 m_dirs.Add( dirs[i] );
262 }
263
264 m_name = tmp.GetName();
265 m_ext = tmp.GetExt();
266
267 return TRUE;
268 }
269
270 bool wxFileName::SameAs( const wxFileName &filepath, bool upper_case )
271 {
272 wxString file1( GetFullPath() );
273 wxString file2( filepath.GetFullPath() );
274
275 if (upper_case)
276 {
277 file1.MakeUpper(); // what does MSW do to non-ascii chars etc? native funcs?
278 file2.MakeUpper();
279 }
280
281 return (file1 == file2);
282 }
283
284 bool wxFileName::IsCaseSensitive( wxPathFormat format )
285 {
286 format = GetFormat( format );
287
288 return (format != wxPATH_DOS);
289 }
290
291 bool wxFileName::IsRelative( wxPathFormat format )
292 {
293 format = GetFormat( format );
294
295 for (size_t i = 0; i < m_dirs.GetCount(); i++)
296 {
297 if ((format == wxPATH_UNIX) && (i == 0) && (m_dirs[0] == wxT("~"))) return TRUE;
298
299 if (m_dirs[i] == wxT(".")) return TRUE;
300 if (m_dirs[i] == wxT("..")) return TRUE;
301 }
302
303 return FALSE;
304 }
305
306 bool wxFileName::IsAbsolute( wxPathFormat format )
307 {
308 return (!IsRelative(format));
309 }
310
311 bool wxFileName::IsWild( wxPathFormat format )
312 {
313 format = GetFormat( format );
314
315 if (format == wxPATH_DOS)
316 {
317 if (m_name.Find( wxT('*') ) != -1) return TRUE;
318 if (m_name.Find( wxT('?') ) != -1) return TRUE;
319 }
320 else
321 {
322 if (m_name.Find( wxT('*') ) != -1) return TRUE;
323 }
324
325 return FALSE;
326 }
327
328 void wxFileName::AppendDir( const wxString &dir )
329 {
330 m_dirs.Add( dir );
331 }
332
333 void wxFileName::PrependDir( const wxString &dir )
334 {
335 m_dirs.Insert( dir, 0 );
336 }
337
338 void wxFileName::InsertDir( int before, const wxString &dir )
339 {
340 m_dirs.Insert( dir, before );
341 }
342
343 void wxFileName::RemoveDir( int pos )
344 {
345 m_dirs.Remove( (size_t)pos );
346 }
347
348 void wxFileName::SetFullName( const wxString name, wxPathFormat format )
349 {
350 format = GetFormat( format );
351
352 m_name = name;
353 m_ext = wxEmptyString;
354
355 if (m_name == wxT(".")) return;
356 if (m_name == wxT("..")) return;
357
358 // ext?
359 int pos = m_name.Find( wxT('.') );
360 if (pos == -1) return;
361
362 bool has_starting_dot = (pos == 0);
363 if (has_starting_dot && (format == wxPATH_UNIX))
364 {
365 // remove dot
366 m_name.Remove(0,1);
367
368 // search again
369 pos = m_name.Find( wxT('.') );
370 if (pos == -1)
371 {
372 // add dot back
373 m_name.Prepend( "." );
374 return;
375 }
376 }
377
378 m_ext = m_name;
379 m_ext.Remove( 0, pos+1 );
380
381 m_name.Remove( pos, m_name.Len()-pos );
382
383 if (has_starting_dot && (format == wxPATH_UNIX))
384 {
385 // add dot back
386 m_name.Prepend( "." );
387 return;
388 }
389 }
390
391 wxString wxFileName::GetFullName()
392 {
393 wxString ret( m_name );
394 if (!m_ext.IsEmpty())
395 {
396 ret += '.';
397 ret += m_ext;
398 }
399 return ret;
400 }
401
402 wxString wxFileName::GetPath( bool add_separator, wxPathFormat format ) const
403 {
404 format = GetFormat( format );
405
406 wxString ret;
407 if (format == wxPATH_DOS)
408 {
409 for (size_t i = 0; i < m_dirs.GetCount(); i++)
410 {
411 ret += m_dirs[i];
412 if (add_separator || (i != m_dirs.GetCount()-1))
413 ret += '\\';
414 }
415 }
416 else
417 if (format == wxPATH_UNIX)
418 {
419 for (size_t i = 0; i < m_dirs.GetCount(); i++)
420 {
421 ret += m_dirs[i];
422 if (add_separator || (i != m_dirs.GetCount()-1))
423 ret += '/';
424 }
425 }
426 else
427 {
428 for (size_t i = 0; i < m_dirs.GetCount(); i++)
429 {
430 ret += m_dirs[i];
431 if (add_separator || (i != m_dirs.GetCount()-1))
432 ret += ":";
433 }
434 }
435
436 return ret;
437 }
438
439 wxString wxFileName::GetFullPath( wxPathFormat format ) const
440 {
441 format = GetFormat( format );
442
443 wxString ret;
444 if (format == wxPATH_DOS)
445 {
446 for (size_t i = 0; i < m_dirs.GetCount(); i++)
447 {
448 ret += m_dirs[i];
449 ret += '\\';
450 }
451 }
452 else
453 if (format == wxPATH_UNIX)
454 {
455 for (size_t i = 0; i < m_dirs.GetCount(); i++)
456 {
457 ret += m_dirs[i];
458 ret += '/';
459 }
460 }
461 else
462 {
463 for (size_t i = 0; i < m_dirs.GetCount(); i++)
464 {
465 ret += m_dirs[i];
466 ret += ':';
467 }
468 }
469
470 ret += m_name;
471
472 if (!m_ext.IsEmpty())
473 {
474 ret += '.';
475 ret += m_ext;
476 }
477
478 return ret;
479 }
480
481 wxPathFormat wxFileName::GetFormat( wxPathFormat format )
482 {
483 if (format == wxPATH_NATIVE)
484 {
485 #if defined(__WXMSW__) || defined(__WXPM__)
486 format = wxPATH_DOS;
487 #endif
488 #if defined(__WXMAC__)
489 format = wxPATH_MAC;
490 #endif
491 #if !defined(__WXMSW__) && !defined(__WXPM__) && !defined(__WXMAC__)
492 format = wxPATH_UNIX;
493 #endif
494 }
495 return format;
496 }
497