]> git.saurik.com Git - wxWidgets.git/blame - src/common/filesys.cpp
Improved selection mode handling in wxGrid::SelectBlock
[wxWidgets.git] / src / common / filesys.cpp
CommitLineData
5526e819
VS
1/////////////////////////////////////////////////////////////////////////////
2// Name: filesys.cpp
3// Purpose: wxFileSystem class - interface for opening files
4// Author: Vaclav Slavik
5// Copyright: (c) 1999 Vaclav Slavik
5be0cf65 6// CVS-ID: $Id$
5526e819
VS
7// Licence: wxWindows Licence
8/////////////////////////////////////////////////////////////////////////////
9
10#ifdef __GNUG__
11#pragma implementation
12#endif
13
d30e0edd 14#include "wx/wxprec.h"
5526e819
VS
15
16#ifdef __BORDLANDC__
17#pragma hdrstop
18#endif
19
31528cd3 20
24528b0c 21#if wxUSE_FILESYSTEM
5526e819 22
d30e0edd
RR
23#include "wx/wfstream.h"
24#include "wx/module.h"
25#include "wx/filesys.h"
73725567
VS
26#include "wx/mimetype.h"
27
28
29
5526e819
VS
30
31//--------------------------------------------------------------------------------
32// wxFileSystemHandler
33//--------------------------------------------------------------------------------
34
35IMPLEMENT_ABSTRACT_CLASS(wxFileSystemHandler, wxObject)
36
5526e819
VS
37
38wxString wxFileSystemHandler::GetMimeTypeFromExt(const wxString& location)
39{
40 wxString ext = wxEmptyString, mime = wxEmptyString;
41 wxString loc = GetRightLocation(location);
42 char c;
43 int l = loc.Length(), l2;
44 wxFileType *ft;
45
46 l2 = l;
47 for (int i = l-1; i >= 0; i--) {
ea4f5235 48 c = loc[(unsigned int) i];
223d09f6
KB
49 if (c == wxT('#')) l2 = i + 1;
50 if (c == wxT('.')) {ext = loc.Right(l2-i-1); break;}
51 if ((c == wxT('/')) || (c == wxT('\\')) || (c == wxT(':'))) {return wxEmptyString;}
5526e819 52 }
956418ab 53
73725567
VS
54 static bool s_MinimalMimeEnsured = FALSE;
55 if (!s_MinimalMimeEnsured) {
956418ab
VS
56 static const wxFileTypeInfo fallbacks[] =
57 {
58 wxFileTypeInfo("image/jpeg",
59 "",
60 "",
61 "JPEG image (from fallback)",
62 "jpg", "jpeg", NULL),
63 wxFileTypeInfo("image/gif",
64 "",
65 "",
66 "GIF image (from fallback)",
67 "gif", NULL),
68 wxFileTypeInfo("image/png",
69 "",
70 "",
71 "PNG image (from fallback)",
72 "png", NULL),
73 wxFileTypeInfo("image/bmp",
74 "",
75 "",
76 "windows bitmap image (from fallback)",
77 "bmp", NULL),
78 wxFileTypeInfo("text/html",
79 "",
80 "",
81 "HTML document (from fallback)",
82 "htm", "html", NULL),
83
84 // must terminate the table with this!
85 wxFileTypeInfo()
86 };
87
73725567 88 wxTheMimeTypesManager -> AddFallbacks(fallbacks);
956418ab
VS
89 }
90
73725567 91 ft = wxTheMimeTypesManager -> GetFileTypeFromExtension(ext);
51f79d5c
VS
92 if (ft && (ft -> GetMimeType(&mime))) {
93 delete ft;
94 return mime;
95 }
96 else {
97 delete ft;
98 return wxEmptyString;
99 }
5526e819
VS
100}
101
102
103
104wxString wxFileSystemHandler::GetProtocol(const wxString& location) const
105{
106 wxString s = wxEmptyString;
107 int i, l = location.Length();
108 bool fnd;
109
110 fnd = FALSE;
223d09f6
KB
111 for (i = l-1; (i >= 0) && ((location[i] != wxT('#')) || (!fnd)); i--) {
112 if ((location[i] == wxT(':')) && (i != 1 /*win: C:\path*/)) fnd = TRUE;
5526e819 113 }
223d09f6
KB
114 if (!fnd) return wxT("file");
115 for (++i; (i < l) && (location[i] != wxT(':')); i++) s << location[i];
5526e819
VS
116 return s;
117}
118
119
5526e819
VS
120wxString wxFileSystemHandler::GetLeftLocation(const wxString& location) const
121{
122 int i;
123 bool fnd;
124
125 fnd = FALSE;
126 for (i = location.Length()-1; i >= 0; i--) {
223d09f6
KB
127 if ((location[i] == wxT(':')) && (i != 1 /*win: C:\path*/)) fnd = TRUE;
128 else if (fnd && (location[i] == wxT('#'))) return location.Left(i);
5526e819
VS
129 }
130 return wxEmptyString;
131}
132
5526e819
VS
133wxString wxFileSystemHandler::GetRightLocation(const wxString& location) const
134{
135 int i, l = location.Length();
136 int l2 = l + 1;
223d09f6 137 for (i = l-1; (i >= 0) && ((location[i] != wxT(':')) || (i == 1) || (location[i-2] == wxT(':'))); i--) {if (location[i] == wxT('#')) l2 = i + 1;}
5526e819
VS
138 if (i == 0) return wxEmptyString;
139 else return location.Mid(i + 1, l2 - i - 2);
140}
141
5526e819
VS
142wxString wxFileSystemHandler::GetAnchor(const wxString& location) const
143{
144 char c;
145 int l = location.Length();
146
147 for (int i = l-1; i >= 0; i--) {
148 c = location[i];
223d09f6
KB
149 if (c == wxT('#')) return location.Right(l-i-1);
150 else if ((c == wxT('.')) || (c == wxT('/')) || (c == wxT('\\')) || (c == wxT(':'))) return wxEmptyString;
5526e819
VS
151 }
152 return wxEmptyString;
153}
154
aaa66113 155
f76dbc4d
VZ
156wxString wxFileSystemHandler::FindFirst(const wxString& WXUNUSED(spec),
157 int WXUNUSED(flags))
158{
159 return wxEmptyString;
160}
aaa66113 161
f76dbc4d
VZ
162wxString wxFileSystemHandler::FindNext()
163{
164 return wxEmptyString;
165}
aaa66113 166
5526e819
VS
167//--------------------------------------------------------------------------------
168// wxLocalFSHandler
169//--------------------------------------------------------------------------------
170
171class wxLocalFSHandler : public wxFileSystemHandler
172{
173 public:
174 virtual bool CanOpen(const wxString& location);
175 virtual wxFSFile* OpenFile(wxFileSystem& fs, const wxString& location);
aaa66113
VS
176 virtual wxString FindFirst(const wxString& spec, int flags = 0);
177 virtual wxString FindNext();
5526e819
VS
178};
179
180
5526e819
VS
181bool wxLocalFSHandler::CanOpen(const wxString& location)
182{
223d09f6 183 return GetProtocol(location) == wxT("file");
5526e819
VS
184}
185
5526e819
VS
186wxFSFile* wxLocalFSHandler::OpenFile(wxFileSystem& WXUNUSED(fs), const wxString& location)
187{
188 wxString right = GetRightLocation(location);
189 if (wxFileExists(right))
190 return new wxFSFile(new wxFileInputStream(right),
191 right,
192 GetMimeTypeFromExt(location),
6ee654e6
VS
193 GetAnchor(location),
194 wxDateTime(wxFileModificationTime(right)));
d30e0edd 195 else return (wxFSFile*) NULL;
5526e819
VS
196}
197
aaa66113
VS
198wxString wxLocalFSHandler::FindFirst(const wxString& spec, int flags)
199{
200 wxString right = GetRightLocation(spec);
201 return wxFindFirstFile(right, flags);
202}
203
204wxString wxLocalFSHandler::FindNext()
205{
206 return wxFindNextFile();
207}
208
209
210
5526e819
VS
211//-----------------------------------------------------------------------------
212// wxFileSystem
213//-----------------------------------------------------------------------------
214
215IMPLEMENT_DYNAMIC_CLASS(wxFileSystem, wxObject)
216
217
218wxList wxFileSystem::m_Handlers;
219
220
5be0cf65
VS
221static wxString MakeCorrectPath(const wxString& path)
222{
223 wxString p(path);
224 wxString r;
225 int i, j, cnt;
226
227 cnt = p.Length();
228 for (i = 0; i < cnt; i++)
f6081a04 229 if (p.GetChar(i) == wxT('\\')) p.GetWritableChar(i) = wxT('/'); // Want to be windows-safe
5be0cf65
VS
230
231 if (p.Left(2) == wxT("./")) { p = p.Mid(2); cnt -= 2; }
232
233 if (cnt < 3) return p;
234
b2f60e03 235 r << p.GetChar(0) << p.GetChar(1);
5be0cf65
VS
236
237 // skip trailing ../.., if any
b2f60e03 238 for (i = 2; i < cnt && (p.GetChar(i) == wxT('/') || p.GetChar(i) == wxT('.')); i++) r << p.GetChar(i);
5be0cf65
VS
239
240 // remove back references: translate dir1/../dir2 to dir2
241 for (; i < cnt; i++)
242 {
b2f60e03
BJ
243 r << p.GetChar(i);
244 if (p.GetChar(i) == wxT('/') && p.GetChar(i-1) == wxT('.') && p.GetChar(i-2) == wxT('.'))
5be0cf65 245 {
b2f60e03
BJ
246 for (j = r.Length() - 2; j >= 0 && r.GetChar(j) != wxT('/') && r.GetChar(j) != wxT(':'); j--) {}
247 if (j >= 0 && r.GetChar(j) != wxT(':'))
5be0cf65 248 {
b2f60e03 249 for (j = j - 1; j >= 0 && r.GetChar(j) != wxT('/') && r.GetChar(j) != wxT(':'); j--) {}
5be0cf65
VS
250 r.Remove(j + 1);
251 }
252 }
253 }
254
b2f60e03 255 for (; i < cnt; i++) r << p.GetChar(i);
5be0cf65
VS
256
257 return r;
258}
259
5526e819
VS
260
261void wxFileSystem::ChangePathTo(const wxString& location, bool is_dir)
262{
263 int i, pathpos = -1;
5526e819 264
5be0cf65 265 m_Path = MakeCorrectPath(location);
d30e0edd 266
aaa66113
VS
267 if (is_dir)
268 {
269 if (m_Path.Length() > 0 && m_Path.Last() != wxT('/') && m_Path.Last() != wxT(':'))
270 m_Path << wxT('/');
271 }
272
273 else
d30e0edd 274 {
269e8200 275 for (i = m_Path.Length()-1; i >= 0; i--)
aaa66113 276 {
223d09f6 277 if (m_Path[(unsigned int) i] == wxT('/'))
aaa66113 278 {
223d09f6 279 if ((i > 1) && (m_Path[(unsigned int) (i-1)] == wxT('/')) && (m_Path[(unsigned int) (i-2)] == wxT(':')))
aaa66113 280 {
5526e819
VS
281 i -= 2;
282 continue;
283 }
269e8200 284 else
aaa66113 285 {
269e8200 286 pathpos = i;
5526e819
VS
287 break;
288 }
289 }
aaa66113
VS
290 else if (m_Path[(unsigned int) i] == wxT(':')) {
291 pathpos = i;
292 break;
293 }
5526e819 294 }
269e8200 295 if (pathpos == -1)
aaa66113 296 {
269e8200 297 for (i = 0; i < (int) m_Path.Length(); i++)
aaa66113 298 {
223d09f6 299 if (m_Path[(unsigned int) i] == wxT(':'))
aaa66113 300 {
5526e819
VS
301 m_Path.Remove(i+1);
302 break;
303 }
304 }
269e8200 305 if (i == (int) m_Path.Length())
aaa66113 306 m_Path = wxEmptyString;
5526e819 307 }
269e8200 308 else
aaa66113 309 {
5526e819
VS
310 m_Path.Remove(pathpos+1);
311 }
312 }
313}
314
315
316
317wxFSFile* wxFileSystem::OpenFile(const wxString& location)
318{
5be0cf65
VS
319 wxString loc = MakeCorrectPath(location);
320 unsigned i, ln;
5526e819
VS
321 char meta;
322 wxFSFile *s = NULL;
323 wxNode *node;
324
325 ln = loc.Length();
326 meta = 0;
269e8200 327 for (i = 0; i < ln; i++)
d30e0edd 328 {
aaa66113 329 if (!meta)
5be0cf65 330 switch (loc[i])
aaa66113 331 {
5be0cf65 332 case wxT('/') : case wxT(':') : case wxT('#') : meta = loc[i];
aaa66113 333 }
5526e819
VS
334 }
335 m_LastName = wxEmptyString;
336
337 // try relative paths first :
223d09f6 338 if (meta != wxT(':'))
d30e0edd 339 {
5526e819 340 node = m_Handlers.GetFirst();
d30e0edd 341 while (node)
aaa66113 342 {
5526e819 343 wxFileSystemHandler *h = (wxFileSystemHandler*) node -> GetData();
7dee4b2b 344 if (h->CanOpen(m_Path + loc))
aaa66113 345 {
7dee4b2b
VS
346 s = h->OpenFile(*this, m_Path + loc);
347 if (s) { m_LastName = m_Path + loc; break; }
5526e819 348 }
d30e0edd 349 node = node->GetNext();
5526e819
VS
350 }
351 }
352
353 // if failed, try absolute paths :
269e8200 354 if (s == NULL)
d30e0edd 355 {
5526e819 356 node = m_Handlers.GetFirst();
d30e0edd 357 while (node)
aaa66113 358 {
d30e0edd 359 wxFileSystemHandler *h = (wxFileSystemHandler*) node->GetData();
7dee4b2b 360 if (h->CanOpen(loc))
aaa66113 361 {
7dee4b2b
VS
362 s = h->OpenFile(*this, loc);
363 if (s) { m_LastName = loc; break; }
5526e819 364 }
d30e0edd 365 node = node->GetNext();
5526e819
VS
366 }
367 }
368 return (s);
369}
370
371
aaa66113
VS
372
373wxString wxFileSystem::FindFirst(const wxString& spec, int flags)
374{
375 wxNode *node;
376 wxString spec2(spec);
377
378 m_FindFileHandler = NULL;
379
380 for (int i = spec2.Length()-1; i >= 0; i--)
f6081a04 381 if (spec2[(unsigned int) i] == wxT('\\')) spec2.GetWritableChar(i) = wxT('/'); // Want to be windows-safe
aaa66113
VS
382
383 node = m_Handlers.GetFirst();
384 while (node)
385 {
386 m_FindFileHandler = (wxFileSystemHandler*) node -> GetData();
387 if (m_FindFileHandler -> CanOpen(m_Path + spec2))
388 return m_FindFileHandler -> FindFirst(m_Path + spec2, flags);
389 node = node->GetNext();
390 }
391
392 node = m_Handlers.GetFirst();
393 while (node)
394 {
395 m_FindFileHandler = (wxFileSystemHandler*) node -> GetData();
396 if (m_FindFileHandler -> CanOpen(spec2))
397 return m_FindFileHandler -> FindFirst(spec2, flags);
398 node = node->GetNext();
399 }
400
401 return wxEmptyString;
402}
403
404
405
406wxString wxFileSystem::FindNext()
407{
408 if (m_FindFileHandler == NULL) return wxEmptyString;
409 else return m_FindFileHandler -> FindNext();
410}
411
412
413
5526e819
VS
414void wxFileSystem::AddHandler(wxFileSystemHandler *handler)
415{
416 m_Handlers.Append(handler);
417}
418
419
269e8200
RD
420void wxFileSystem::CleanUpHandlers()
421{
422 m_Handlers.DeleteContents(TRUE);
423 m_Handlers.Clear();
424}
425
5526e819 426
aaa66113
VS
427
428
5526e819
VS
429///// Module:
430
431class wxFileSystemModule : public wxModule
432{
433 DECLARE_DYNAMIC_CLASS(wxFileSystemModule)
434
435 public:
436 virtual bool OnInit()
437 {
438 wxFileSystem::AddHandler(new wxLocalFSHandler);
439 return TRUE;
440 }
269e8200 441 virtual void OnExit()
aaa66113 442 {
269e8200 443 wxFileSystem::CleanUpHandlers();
aaa66113 444 }
5526e819
VS
445};
446
447IMPLEMENT_DYNAMIC_CLASS(wxFileSystemModule, wxModule)
448
269e8200 449#endif
24528b0c 450 // wxUSE_FILESYSTEM
5526e819 451
a76015e6
VS
452
453