added wxFileType::GetMimeTypes
[wxWidgets.git] / src / common / mimecmn.cpp
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"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WX_PRECOMP
24 #include "wx/defs.h"
25 #endif
26
27 #if (wxUSE_FILE && wxUSE_TEXTFILE) || defined(__WXMSW__)
28
29 #ifndef WX_PRECOMP
30 #include "wx/string.h"
31 #if wxUSE_GUI
32 #include "wx/icon.h"
33 #endif
34 #endif //WX_PRECOMP
35
36 // Doesn't compile in WIN16 mode
37 #ifndef __WIN16__
38
39 #include "wx/log.h"
40 #include "wx/file.h"
41 #include "wx/intl.h"
42 #include "wx/dynarray.h"
43 #include "wx/confbase.h"
44
45 #ifdef __WXMSW__
46 #include "wx/msw/registry.h"
47 #include "windows.h"
48 #elif defined(__UNIX__) || defined(__WXPM__)
49 #include "wx/ffile.h"
50 #include "wx/textfile.h"
51 #include "wx/dir.h"
52 #include "wx/utils.h"
53 #include "wx/tokenzr.h"
54 #endif // OS
55
56 #include "wx/mimetype.h"
57
58 // other standard headers
59 #include <ctype.h>
60
61 // in case we're compiling in non-GUI mode
62 class WXDLLEXPORT wxIcon;
63
64
65 // implementation classes:
66
67 #if defined(__WXMSW__)
68 #include "wx/msw/mimetype.h"
69 #elif defined (__WXMAC__)
70 #include "wx/mac/mimetype.h"
71 #elif defined (__WXPM__)
72 #include "wx/os2/mimetype.h"
73 #else
74 #include "wx/unix/mimetype.h"
75 #endif
76
77 // ============================================================================
78 // common classes
79 // ============================================================================
80
81 // ----------------------------------------------------------------------------
82 // wxFileTypeInfo
83 // ----------------------------------------------------------------------------
84
85 wxFileTypeInfo::wxFileTypeInfo(const char *mimeType,
86 const char *openCmd,
87 const char *printCmd,
88 const char *desc,
89 ...)
90 : m_mimeType(mimeType),
91 m_openCmd(openCmd),
92 m_printCmd(printCmd),
93 m_desc(desc)
94 {
95 va_list argptr;
96 va_start(argptr, desc);
97
98 for ( ;; )
99 {
100 const char *ext = va_arg(argptr, const char *);
101 if ( !ext )
102 {
103 // NULL terminates the list
104 break;
105 }
106
107 m_exts.Add(ext);
108 }
109
110 va_end(argptr);
111 }
112
113 #include "wx/arrimpl.cpp"
114 WX_DEFINE_OBJARRAY(wxArrayFileTypeInfo);
115
116
117 // ============================================================================
118 // implementation of the wrapper classes
119 // ============================================================================
120
121 // ----------------------------------------------------------------------------
122 // wxFileType
123 // ----------------------------------------------------------------------------
124
125 wxString wxFileType::ExpandCommand(const wxString& command,
126 const wxFileType::MessageParameters& params)
127 {
128 bool hasFilename = FALSE;
129
130 wxString str;
131 for ( const wxChar *pc = command.c_str(); *pc != wxT('\0'); pc++ ) {
132 if ( *pc == wxT('%') ) {
133 switch ( *++pc ) {
134 case wxT('s'):
135 // '%s' expands into file name (quoted because it might
136 // contain spaces) - except if there are already quotes
137 // there because otherwise some programs may get confused
138 // by double double quotes
139 #if 0
140 if ( *(pc - 2) == wxT('"') )
141 str << params.GetFileName();
142 else
143 str << wxT('"') << params.GetFileName() << wxT('"');
144 #endif
145 str << params.GetFileName();
146 hasFilename = TRUE;
147 break;
148
149 case wxT('t'):
150 // '%t' expands into MIME type (quote it too just to be
151 // consistent)
152 str << wxT('\'') << params.GetMimeType() << wxT('\'');
153 break;
154
155 case wxT('{'):
156 {
157 const wxChar *pEnd = wxStrchr(pc, wxT('}'));
158 if ( pEnd == NULL ) {
159 wxString mimetype;
160 wxLogWarning(_("Unmatched '{' in an entry for "
161 "mime type %s."),
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'
192 // the program will accept the data on stdin: so give it to it!
193 if ( !hasFilename && !str.IsEmpty() ) {
194 str << wxT(" < '") << params.GetFileName() << wxT('\'');
195 }
196
197 return str;
198 }
199
200 wxFileType::wxFileType()
201 {
202 m_impl = new wxFileTypeImpl;
203 }
204
205 wxFileType::~wxFileType()
206 {
207 delete m_impl;
208 }
209
210 bool wxFileType::GetExtensions(wxArrayString& extensions)
211 {
212 return m_impl->GetExtensions(extensions);
213 }
214
215 bool wxFileType::GetMimeType(wxString *mimeType) const
216 {
217 return m_impl->GetMimeType(mimeType);
218 }
219
220 bool wxFileType::GetMimeTypes(wxArrayString& mimeTypes) const
221 {
222 return m_impl->GetMimeTypes(mimeTypes);
223 }
224
225 bool wxFileType::GetIcon(wxIcon *icon) const
226 {
227 return m_impl->GetIcon(icon);
228 }
229
230 bool wxFileType::GetDescription(wxString *desc) const
231 {
232 return m_impl->GetDescription(desc);
233 }
234
235 bool
236 wxFileType::GetOpenCommand(wxString *openCmd,
237 const wxFileType::MessageParameters& params) const
238 {
239 return m_impl->GetOpenCommand(openCmd, params);
240 }
241
242 bool
243 wxFileType::GetPrintCommand(wxString *printCmd,
244 const wxFileType::MessageParameters& params) const
245 {
246 return m_impl->GetPrintCommand(printCmd, params);
247 }
248
249 // ----------------------------------------------------------------------------
250 // wxMimeTypesManager
251 // ----------------------------------------------------------------------------
252
253 void wxMimeTypesManager::EnsureImpl()
254 {
255 if (m_impl == NULL)
256 m_impl = new wxMimeTypesManagerImpl;
257 }
258
259 bool wxMimeTypesManager::IsOfType(const wxString& mimeType,
260 const wxString& wildcard)
261 {
262 wxASSERT_MSG( mimeType.Find(wxT('*')) == wxNOT_FOUND,
263 wxT("first MIME type can't contain wildcards") );
264
265 // all comparaisons are case insensitive (2nd arg of IsSameAs() is FALSE)
266 if ( wildcard.BeforeFirst(wxT('/')).IsSameAs(mimeType.BeforeFirst(wxT('/')), FALSE) )
267 {
268 wxString strSubtype = wildcard.AfterFirst(wxT('/'));
269
270 if ( strSubtype == wxT("*") ||
271 strSubtype.IsSameAs(mimeType.AfterFirst(wxT('/')), FALSE) )
272 {
273 // matches (either exactly or it's a wildcard)
274 return TRUE;
275 }
276 }
277
278 return FALSE;
279 }
280
281 wxMimeTypesManager::wxMimeTypesManager()
282 {
283 m_impl = NULL;
284 }
285
286 wxMimeTypesManager::~wxMimeTypesManager()
287 {
288 if (m_impl != NULL)
289 delete m_impl;
290 }
291
292 wxFileType *
293 wxMimeTypesManager::GetFileTypeFromExtension(const wxString& ext)
294 {
295 EnsureImpl();
296 return m_impl->GetFileTypeFromExtension(ext);
297 }
298
299 wxFileType *
300 wxMimeTypesManager::GetFileTypeFromMimeType(const wxString& mimeType)
301 {
302 EnsureImpl();
303 return m_impl->GetFileTypeFromMimeType(mimeType);
304 }
305
306 bool wxMimeTypesManager::ReadMailcap(const wxString& filename, bool fallback)
307 {
308 EnsureImpl();
309 return m_impl->ReadMailcap(filename, fallback);
310 }
311
312 bool wxMimeTypesManager::ReadMimeTypes(const wxString& filename)
313 {
314 EnsureImpl();
315 return m_impl->ReadMimeTypes(filename);
316 }
317
318 void wxMimeTypesManager::AddFallbacks(const wxFileTypeInfo *filetypes)
319 {
320 EnsureImpl();
321 for ( const wxFileTypeInfo *ft = filetypes; ft->IsValid(); ft++ ) {
322 m_impl->AddFallback(*ft);
323 }
324 }
325
326 size_t wxMimeTypesManager::EnumAllFileTypes(wxArrayString& mimetypes)
327 {
328 EnsureImpl();
329 return m_impl->EnumAllFileTypes(mimetypes);
330 }
331
332
333 // ----------------------------------------------------------------------------
334 // global data
335 // ----------------------------------------------------------------------------
336
337 // private object
338 static wxMimeTypesManager gs_mimeTypesManager;
339
340 // and public pointer
341 wxMimeTypesManager * wxTheMimeTypesManager = &gs_mimeTypesManager;
342
343
344 #endif
345 // wxUSE_FILE && wxUSE_TEXTFILE
346
347 #endif
348 // __WIN16__