mimetype.cpp/.h split into unix,mac,msw
[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 #else
72 #include "wx/unix/mimetype.h"
73 #endif
74
75 // ============================================================================
76 // common classes
77 // ============================================================================
78
79 // ----------------------------------------------------------------------------
80 // wxFileTypeInfo
81 // ----------------------------------------------------------------------------
82
83 wxFileTypeInfo::wxFileTypeInfo(const char *mimeType,
84 const char *openCmd,
85 const char *printCmd,
86 const char *desc,
87 ...)
88 : m_mimeType(mimeType),
89 m_openCmd(openCmd),
90 m_printCmd(printCmd),
91 m_desc(desc)
92 {
93 va_list argptr;
94 va_start(argptr, desc);
95
96 for ( ;; )
97 {
98 const char *ext = va_arg(argptr, const char *);
99 if ( !ext )
100 {
101 // NULL terminates the list
102 break;
103 }
104
105 m_exts.Add(ext);
106 }
107
108 va_end(argptr);
109 }
110
111 #include "wx/arrimpl.cpp"
112 WX_DEFINE_OBJARRAY(wxArrayFileTypeInfo);
113
114
115 // ============================================================================
116 // implementation of the wrapper classes
117 // ============================================================================
118
119 // ----------------------------------------------------------------------------
120 // wxFileType
121 // ----------------------------------------------------------------------------
122
123 wxString wxFileType::ExpandCommand(const wxString& command,
124 const wxFileType::MessageParameters& params)
125 {
126 bool hasFilename = FALSE;
127
128 wxString str;
129 for ( const wxChar *pc = command.c_str(); *pc != wxT('\0'); pc++ ) {
130 if ( *pc == wxT('%') ) {
131 switch ( *++pc ) {
132 case wxT('s'):
133 // '%s' expands into file name (quoted because it might
134 // contain spaces) - except if there are already quotes
135 // there because otherwise some programs may get confused
136 // by double double quotes
137 #if 0
138 if ( *(pc - 2) == wxT('"') )
139 str << params.GetFileName();
140 else
141 str << wxT('"') << params.GetFileName() << wxT('"');
142 #endif
143 str << params.GetFileName();
144 hasFilename = TRUE;
145 break;
146
147 case wxT('t'):
148 // '%t' expands into MIME type (quote it too just to be
149 // consistent)
150 str << wxT('\'') << params.GetMimeType() << wxT('\'');
151 break;
152
153 case wxT('{'):
154 {
155 const wxChar *pEnd = wxStrchr(pc, wxT('}'));
156 if ( pEnd == NULL ) {
157 wxString mimetype;
158 wxLogWarning(_("Unmatched '{' in an entry for "
159 "mime type %s."),
160 params.GetMimeType().c_str());
161 str << wxT("%{");
162 }
163 else {
164 wxString param(pc + 1, pEnd - pc - 1);
165 str << wxT('\'') << params.GetParamValue(param) << wxT('\'');
166 pc = pEnd;
167 }
168 }
169 break;
170
171 case wxT('n'):
172 case wxT('F'):
173 // TODO %n is the number of parts, %F is an array containing
174 // the names of temp files these parts were written to
175 // and their mime types.
176 break;
177
178 default:
179 wxLogDebug(wxT("Unknown field %%%c in command '%s'."),
180 *pc, command.c_str());
181 str << *pc;
182 }
183 }
184 else {
185 str << *pc;
186 }
187 }
188
189 // metamail(1) man page states that if the mailcap entry doesn't have '%s'
190 // the program will accept the data on stdin: so give it to it!
191 if ( !hasFilename && !str.IsEmpty() ) {
192 str << wxT(" < '") << params.GetFileName() << wxT('\'');
193 }
194
195 return str;
196 }
197
198 wxFileType::wxFileType()
199 {
200 m_impl = new wxFileTypeImpl;
201 }
202
203 wxFileType::~wxFileType()
204 {
205 delete m_impl;
206 }
207
208 bool wxFileType::GetExtensions(wxArrayString& extensions)
209 {
210 return m_impl->GetExtensions(extensions);
211 }
212
213 bool wxFileType::GetMimeType(wxString *mimeType) const
214 {
215 return m_impl->GetMimeType(mimeType);
216 }
217
218 bool wxFileType::GetIcon(wxIcon *icon) const
219 {
220 return m_impl->GetIcon(icon);
221 }
222
223 bool wxFileType::GetDescription(wxString *desc) const
224 {
225 return m_impl->GetDescription(desc);
226 }
227
228 bool
229 wxFileType::GetOpenCommand(wxString *openCmd,
230 const wxFileType::MessageParameters& params) const
231 {
232 return m_impl->GetOpenCommand(openCmd, params);
233 }
234
235 bool
236 wxFileType::GetPrintCommand(wxString *printCmd,
237 const wxFileType::MessageParameters& params) const
238 {
239 return m_impl->GetPrintCommand(printCmd, params);
240 }
241
242 // ----------------------------------------------------------------------------
243 // wxMimeTypesManager
244 // ----------------------------------------------------------------------------
245
246 void wxMimeTypesManager::EnsureImpl()
247 {
248 if (m_impl == NULL)
249 m_impl = new wxMimeTypesManagerImpl;
250 }
251
252 bool wxMimeTypesManager::IsOfType(const wxString& mimeType,
253 const wxString& wildcard)
254 {
255 wxASSERT_MSG( mimeType.Find(wxT('*')) == wxNOT_FOUND,
256 wxT("first MIME type can't contain wildcards") );
257
258 // all comparaisons are case insensitive (2nd arg of IsSameAs() is FALSE)
259 if ( wildcard.BeforeFirst(wxT('/')).IsSameAs(mimeType.BeforeFirst(wxT('/')), FALSE) )
260 {
261 wxString strSubtype = wildcard.AfterFirst(wxT('/'));
262
263 if ( strSubtype == wxT("*") ||
264 strSubtype.IsSameAs(mimeType.AfterFirst(wxT('/')), FALSE) )
265 {
266 // matches (either exactly or it's a wildcard)
267 return TRUE;
268 }
269 }
270
271 return FALSE;
272 }
273
274 wxMimeTypesManager::wxMimeTypesManager()
275 {
276 m_impl = NULL;
277 }
278
279 wxMimeTypesManager::~wxMimeTypesManager()
280 {
281 if (m_impl != NULL)
282 delete m_impl;
283 }
284
285 wxFileType *
286 wxMimeTypesManager::GetFileTypeFromExtension(const wxString& ext)
287 {
288 EnsureImpl();
289 return m_impl->GetFileTypeFromExtension(ext);
290 }
291
292 wxFileType *
293 wxMimeTypesManager::GetFileTypeFromMimeType(const wxString& mimeType)
294 {
295 EnsureImpl();
296 return m_impl->GetFileTypeFromMimeType(mimeType);
297 }
298
299 bool wxMimeTypesManager::ReadMailcap(const wxString& filename, bool fallback)
300 {
301 EnsureImpl();
302 return m_impl->ReadMailcap(filename, fallback);
303 }
304
305 bool wxMimeTypesManager::ReadMimeTypes(const wxString& filename)
306 {
307 EnsureImpl();
308 return m_impl->ReadMimeTypes(filename);
309 }
310
311 void wxMimeTypesManager::AddFallbacks(const wxFileTypeInfo *filetypes)
312 {
313 EnsureImpl();
314 for ( const wxFileTypeInfo *ft = filetypes; ft->IsValid(); ft++ ) {
315 m_impl->AddFallback(*ft);
316 }
317 }
318
319 size_t wxMimeTypesManager::EnumAllFileTypes(wxArrayString& mimetypes)
320 {
321 EnsureImpl();
322 return m_impl->EnumAllFileTypes(mimetypes);
323 }
324
325
326 // ----------------------------------------------------------------------------
327 // global data
328 // ----------------------------------------------------------------------------
329
330 // private object
331 static wxMimeTypesManager gs_mimeTypesManager;
332
333 // and public pointer
334 wxMimeTypesManager * wxTheMimeTypesManager = &gs_mimeTypesManager;
335
336
337 #endif
338 // wxUSE_FILE && wxUSE_TEXTFILE
339
340 #endif
341 // __WIN16__