]> git.saurik.com Git - wxWidgets.git/blame - src/common/mimecmn.cpp
fixed stupid loop in wxFileSystem::OpenFile
[wxWidgets.git] / src / common / mimecmn.cpp
CommitLineData
7dc3cc31
VS
1/////////////////////////////////////////////////////////////////////////////
2// Name: common/mimecmn.cpp
3// Purpose: classes and functions to manage MIME types
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 23.09.98
7// RCS-ID: $Id$
8// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9// Licence: wxWindows license (part of wxExtra library)
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "mimetypebase.h"
14#endif
15
16// for compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
66806a0b 18#include "wx/module.h"
7dc3cc31
VS
19
20#ifdef __BORLANDC__
21 #pragma hdrstop
22#endif
23
24#ifndef WX_PRECOMP
25 #include "wx/defs.h"
26#endif
27
28#if (wxUSE_FILE && wxUSE_TEXTFILE) || defined(__WXMSW__)
29
30#ifndef WX_PRECOMP
31 #include "wx/string.h"
32 #if wxUSE_GUI
33 #include "wx/icon.h"
34 #endif
35#endif //WX_PRECOMP
36
37// Doesn't compile in WIN16 mode
38#ifndef __WIN16__
39
40#include "wx/log.h"
41#include "wx/file.h"
42#include "wx/intl.h"
43#include "wx/dynarray.h"
44#include "wx/confbase.h"
45
46#ifdef __WXMSW__
47 #include "wx/msw/registry.h"
48 #include "windows.h"
49#elif defined(__UNIX__) || defined(__WXPM__)
50 #include "wx/ffile.h"
51 #include "wx/textfile.h"
52 #include "wx/dir.h"
53 #include "wx/utils.h"
54 #include "wx/tokenzr.h"
55#endif // OS
56
57#include "wx/mimetype.h"
58
59// other standard headers
60#include <ctype.h>
61
62// in case we're compiling in non-GUI mode
63class WXDLLEXPORT wxIcon;
64
65
66// implementation classes:
67
68#if defined(__WXMSW__)
69#include "wx/msw/mimetype.h"
70#elif defined (__WXMAC__)
71#include "wx/mac/mimetype.h"
e1c8c2f8
DW
72#elif defined (__WXPM__)
73#include "wx/os2/mimetype.h"
7dc3cc31
VS
74#else
75#include "wx/unix/mimetype.h"
76#endif
77
78// ============================================================================
79// common classes
80// ============================================================================
81
82// ----------------------------------------------------------------------------
83// wxFileTypeInfo
84// ----------------------------------------------------------------------------
85
86wxFileTypeInfo::wxFileTypeInfo(const char *mimeType,
87 const char *openCmd,
88 const char *printCmd,
89 const char *desc,
90 ...)
91 : m_mimeType(mimeType),
92 m_openCmd(openCmd),
93 m_printCmd(printCmd),
94 m_desc(desc)
95{
96 va_list argptr;
97 va_start(argptr, desc);
98
99 for ( ;; )
100 {
101 const char *ext = va_arg(argptr, const char *);
102 if ( !ext )
103 {
104 // NULL terminates the list
105 break;
106 }
107
108 m_exts.Add(ext);
109 }
110
111 va_end(argptr);
112}
113
114#include "wx/arrimpl.cpp"
115WX_DEFINE_OBJARRAY(wxArrayFileTypeInfo);
116
117
118// ============================================================================
119// implementation of the wrapper classes
120// ============================================================================
121
122// ----------------------------------------------------------------------------
123// wxFileType
124// ----------------------------------------------------------------------------
125
126wxString wxFileType::ExpandCommand(const wxString& command,
127 const wxFileType::MessageParameters& params)
128{
129 bool hasFilename = FALSE;
130
131 wxString str;
132 for ( const wxChar *pc = command.c_str(); *pc != wxT('\0'); pc++ ) {
133 if ( *pc == wxT('%') ) {
134 switch ( *++pc ) {
135 case wxT('s'):
136 // '%s' expands into file name (quoted because it might
137 // contain spaces) - except if there are already quotes
138 // there because otherwise some programs may get confused
139 // by double double quotes
140#if 0
141 if ( *(pc - 2) == wxT('"') )
142 str << params.GetFileName();
143 else
144 str << wxT('"') << params.GetFileName() << wxT('"');
145#endif
146 str << params.GetFileName();
147 hasFilename = TRUE;
148 break;
149
150 case wxT('t'):
151 // '%t' expands into MIME type (quote it too just to be
152 // consistent)
153 str << wxT('\'') << params.GetMimeType() << wxT('\'');
154 break;
155
156 case wxT('{'):
157 {
158 const wxChar *pEnd = wxStrchr(pc, wxT('}'));
159 if ( pEnd == NULL ) {
160 wxString mimetype;
f6bcfd97 161 wxLogWarning(_("Unmatched '{' in an entry for mime type %s."),
7dc3cc31
VS
162 params.GetMimeType().c_str());
163 str << wxT("%{");
164 }
165 else {
166 wxString param(pc + 1, pEnd - pc - 1);
167 str << wxT('\'') << params.GetParamValue(param) << wxT('\'');
168 pc = pEnd;
169 }
170 }
171 break;
172
173 case wxT('n'):
174 case wxT('F'):
175 // TODO %n is the number of parts, %F is an array containing
176 // the names of temp files these parts were written to
177 // and their mime types.
178 break;
179
180 default:
181 wxLogDebug(wxT("Unknown field %%%c in command '%s'."),
182 *pc, command.c_str());
183 str << *pc;
184 }
185 }
186 else {
187 str << *pc;
188 }
189 }
190
191 // metamail(1) man page states that if the mailcap entry doesn't have '%s'
f6bcfd97
BP
192 // the program will accept the data on stdin so normally we should append
193 // "< %s" to the end of the command in such case, but not all commands
194 // behave like this, in particular a common test is 'test -n "$DISPLAY"'
195 // and appending "< %s" to this command makes the test fail... I don't
196 // know of the correct solution, try to guess what we have to do.
197 if ( !hasFilename && !str.IsEmpty()
198#ifdef __UNIX__
199 && !str.StartsWith(_T("test "))
200#endif // Unix
201 ) {
7dc3cc31
VS
202 str << wxT(" < '") << params.GetFileName() << wxT('\'');
203 }
204
205 return str;
206}
207
208wxFileType::wxFileType()
209{
210 m_impl = new wxFileTypeImpl;
211}
212
213wxFileType::~wxFileType()
214{
215 delete m_impl;
216}
217
218bool wxFileType::GetExtensions(wxArrayString& extensions)
219{
220 return m_impl->GetExtensions(extensions);
221}
222
223bool wxFileType::GetMimeType(wxString *mimeType) const
224{
225 return m_impl->GetMimeType(mimeType);
226}
227
4d2976ad
VS
228bool wxFileType::GetMimeTypes(wxArrayString& mimeTypes) const
229{
230 return m_impl->GetMimeTypes(mimeTypes);
231}
232
7dc3cc31
VS
233bool wxFileType::GetIcon(wxIcon *icon) const
234{
235 return m_impl->GetIcon(icon);
236}
237
238bool wxFileType::GetDescription(wxString *desc) const
239{
240 return m_impl->GetDescription(desc);
241}
242
243bool
244wxFileType::GetOpenCommand(wxString *openCmd,
245 const wxFileType::MessageParameters& params) const
246{
247 return m_impl->GetOpenCommand(openCmd, params);
248}
249
250bool
251wxFileType::GetPrintCommand(wxString *printCmd,
252 const wxFileType::MessageParameters& params) const
253{
254 return m_impl->GetPrintCommand(printCmd, params);
255}
256
257// ----------------------------------------------------------------------------
258// wxMimeTypesManager
259// ----------------------------------------------------------------------------
260
261void wxMimeTypesManager::EnsureImpl()
262{
263 if (m_impl == NULL)
264 m_impl = new wxMimeTypesManagerImpl;
265}
266
267bool wxMimeTypesManager::IsOfType(const wxString& mimeType,
268 const wxString& wildcard)
269{
270 wxASSERT_MSG( mimeType.Find(wxT('*')) == wxNOT_FOUND,
271 wxT("first MIME type can't contain wildcards") );
272
273 // all comparaisons are case insensitive (2nd arg of IsSameAs() is FALSE)
274 if ( wildcard.BeforeFirst(wxT('/')).IsSameAs(mimeType.BeforeFirst(wxT('/')), FALSE) )
275 {
276 wxString strSubtype = wildcard.AfterFirst(wxT('/'));
277
278 if ( strSubtype == wxT("*") ||
279 strSubtype.IsSameAs(mimeType.AfterFirst(wxT('/')), FALSE) )
280 {
281 // matches (either exactly or it's a wildcard)
282 return TRUE;
283 }
284 }
285
286 return FALSE;
287}
288
289wxMimeTypesManager::wxMimeTypesManager()
290{
291 m_impl = NULL;
292}
293
294wxMimeTypesManager::~wxMimeTypesManager()
295{
296 if (m_impl != NULL)
297 delete m_impl;
298}
299
300wxFileType *
301wxMimeTypesManager::GetFileTypeFromExtension(const wxString& ext)
302{
303 EnsureImpl();
304 return m_impl->GetFileTypeFromExtension(ext);
305}
306
307wxFileType *
308wxMimeTypesManager::GetFileTypeFromMimeType(const wxString& mimeType)
309{
310 EnsureImpl();
311 return m_impl->GetFileTypeFromMimeType(mimeType);
312}
313
314bool wxMimeTypesManager::ReadMailcap(const wxString& filename, bool fallback)
315{
316 EnsureImpl();
317 return m_impl->ReadMailcap(filename, fallback);
318}
319
320bool wxMimeTypesManager::ReadMimeTypes(const wxString& filename)
321{
322 EnsureImpl();
323 return m_impl->ReadMimeTypes(filename);
324}
325
326void wxMimeTypesManager::AddFallbacks(const wxFileTypeInfo *filetypes)
327{
328 EnsureImpl();
329 for ( const wxFileTypeInfo *ft = filetypes; ft->IsValid(); ft++ ) {
330 m_impl->AddFallback(*ft);
331 }
332}
333
334size_t wxMimeTypesManager::EnumAllFileTypes(wxArrayString& mimetypes)
335{
336 EnsureImpl();
337 return m_impl->EnumAllFileTypes(mimetypes);
338}
339
340
341// ----------------------------------------------------------------------------
342// global data
343// ----------------------------------------------------------------------------
344
345// private object
346static wxMimeTypesManager gs_mimeTypesManager;
347
348// and public pointer
349wxMimeTypesManager * wxTheMimeTypesManager = &gs_mimeTypesManager;
350
351
66806a0b
VS
352
353
354
355class wxMimeTypeCmnModule: public wxModule
356{
357DECLARE_DYNAMIC_CLASS(wxMimeTypeCmnModule)
358public:
359 wxMimeTypeCmnModule() : wxModule() {}
360 bool OnInit() { return TRUE; }
361 void OnExit()
362 { // this avoids false memory leak allerts:
363 if (gs_mimeTypesManager.m_impl != NULL)
364 {
365 delete gs_mimeTypesManager.m_impl;
366 gs_mimeTypesManager.m_impl = NULL;
367 }
368 }
369};
370
371IMPLEMENT_DYNAMIC_CLASS(wxMimeTypeCmnModule, wxModule)
372
373
374
7dc3cc31
VS
375#endif
376 // wxUSE_FILE && wxUSE_TEXTFILE
377
378#endif
379 // __WIN16__