1 /////////////////////////////////////////////////////////////////////////////
2 // Name: common/mimecmn.cpp
3 // Purpose: classes and functions to manage MIME types
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows license (part of wxExtra library)
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "mimetypebase.h"
16 // for compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18 #include "wx/module.h"
28 #if (wxUSE_FILE && wxUSE_TEXTFILE) || defined(__WXMSW__)
31 #include "wx/string.h"
37 // Doesn't compile in WIN16 mode
43 #include "wx/dynarray.h"
44 #include "wx/confbase.h"
47 #include "wx/msw/registry.h"
49 #elif defined(__UNIX__) || defined(__WXPM__)
51 #include "wx/textfile.h"
54 #include "wx/tokenzr.h"
57 #include "wx/mimetype.h"
59 // other standard headers
62 // in case we're compiling in non-GUI mode
63 class WXDLLEXPORT wxIcon
;
66 // implementation classes:
68 #if defined(__WXMSW__)
69 #include "wx/msw/mimetype.h"
70 #elif defined (__WXMAC__)
71 #include "wx/mac/mimetype.h"
72 #elif defined (__WXPM__)
73 #include "wx/os2/mimetype.h"
75 #include "wx/unix/mimetype.h"
78 // ============================================================================
80 // ============================================================================
82 // ----------------------------------------------------------------------------
84 // ----------------------------------------------------------------------------
86 wxFileTypeInfo::wxFileTypeInfo(const char *mimeType
,
91 : m_mimeType(mimeType
),
97 va_start(argptr
, desc
);
101 const char *ext
= va_arg(argptr
, const char *);
104 // NULL terminates the list
114 #include "wx/arrimpl.cpp"
115 WX_DEFINE_OBJARRAY(wxArrayFileTypeInfo
);
118 // ============================================================================
119 // implementation of the wrapper classes
120 // ============================================================================
122 // ----------------------------------------------------------------------------
124 // ----------------------------------------------------------------------------
126 wxString
wxFileType::ExpandCommand(const wxString
& command
,
127 const wxFileType::MessageParameters
& params
)
129 bool hasFilename
= FALSE
;
132 for ( const wxChar
*pc
= command
.c_str(); *pc
!= wxT('\0'); pc
++ ) {
133 if ( *pc
== wxT('%') ) {
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
141 if ( *(pc
- 2) == wxT('"') )
142 str
<< params
.GetFileName();
144 str
<< wxT('"') << params
.GetFileName() << wxT('"');
146 str
<< params
.GetFileName();
151 // '%t' expands into MIME type (quote it too just to be
153 str
<< wxT('\'') << params
.GetMimeType() << wxT('\'');
158 const wxChar
*pEnd
= wxStrchr(pc
, wxT('}'));
159 if ( pEnd
== NULL
) {
161 wxLogWarning(_("Unmatched '{' in an entry for mime type %s."),
162 params
.GetMimeType().c_str());
166 wxString
param(pc
+ 1, pEnd
- pc
- 1);
167 str
<< wxT('\'') << params
.GetParamValue(param
) << wxT('\'');
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.
181 wxLogDebug(wxT("Unknown field %%%c in command '%s'."),
182 *pc
, command
.c_str());
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 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()
199 && !str
.StartsWith(_T("test "))
202 str
<< wxT(" < '") << params
.GetFileName() << wxT('\'');
208 wxFileType::wxFileType()
210 m_impl
= new wxFileTypeImpl
;
213 wxFileType::~wxFileType()
218 bool wxFileType::GetExtensions(wxArrayString
& extensions
)
220 return m_impl
->GetExtensions(extensions
);
223 bool wxFileType::GetMimeType(wxString
*mimeType
) const
225 return m_impl
->GetMimeType(mimeType
);
228 bool wxFileType::GetMimeTypes(wxArrayString
& mimeTypes
) const
230 return m_impl
->GetMimeTypes(mimeTypes
);
233 bool wxFileType::GetIcon(wxIcon
*icon
) const
235 return m_impl
->GetIcon(icon
);
238 bool wxFileType::GetDescription(wxString
*desc
) const
240 return m_impl
->GetDescription(desc
);
244 wxFileType::GetOpenCommand(wxString
*openCmd
,
245 const wxFileType::MessageParameters
& params
) const
247 return m_impl
->GetOpenCommand(openCmd
, params
);
251 wxFileType::GetPrintCommand(wxString
*printCmd
,
252 const wxFileType::MessageParameters
& params
) const
254 return m_impl
->GetPrintCommand(printCmd
, params
);
257 // ----------------------------------------------------------------------------
258 // wxMimeTypesManager
259 // ----------------------------------------------------------------------------
261 void wxMimeTypesManager::EnsureImpl()
264 m_impl
= new wxMimeTypesManagerImpl
;
267 bool wxMimeTypesManager::IsOfType(const wxString
& mimeType
,
268 const wxString
& wildcard
)
270 wxASSERT_MSG( mimeType
.Find(wxT('*')) == wxNOT_FOUND
,
271 wxT("first MIME type can't contain wildcards") );
273 // all comparaisons are case insensitive (2nd arg of IsSameAs() is FALSE)
274 if ( wildcard
.BeforeFirst(wxT('/')).IsSameAs(mimeType
.BeforeFirst(wxT('/')), FALSE
) )
276 wxString strSubtype
= wildcard
.AfterFirst(wxT('/'));
278 if ( strSubtype
== wxT("*") ||
279 strSubtype
.IsSameAs(mimeType
.AfterFirst(wxT('/')), FALSE
) )
281 // matches (either exactly or it's a wildcard)
289 wxMimeTypesManager::wxMimeTypesManager()
294 wxMimeTypesManager::~wxMimeTypesManager()
301 wxMimeTypesManager::GetFileTypeFromExtension(const wxString
& ext
)
304 return m_impl
->GetFileTypeFromExtension(ext
);
308 wxMimeTypesManager::GetFileTypeFromMimeType(const wxString
& mimeType
)
311 return m_impl
->GetFileTypeFromMimeType(mimeType
);
314 bool wxMimeTypesManager::ReadMailcap(const wxString
& filename
, bool fallback
)
317 return m_impl
->ReadMailcap(filename
, fallback
);
320 bool wxMimeTypesManager::ReadMimeTypes(const wxString
& filename
)
323 return m_impl
->ReadMimeTypes(filename
);
326 void wxMimeTypesManager::AddFallbacks(const wxFileTypeInfo
*filetypes
)
329 for ( const wxFileTypeInfo
*ft
= filetypes
; ft
->IsValid(); ft
++ ) {
330 m_impl
->AddFallback(*ft
);
334 size_t wxMimeTypesManager::EnumAllFileTypes(wxArrayString
& mimetypes
)
337 return m_impl
->EnumAllFileTypes(mimetypes
);
341 // ----------------------------------------------------------------------------
343 // ----------------------------------------------------------------------------
346 static wxMimeTypesManager gs_mimeTypesManager
;
348 // and public pointer
349 wxMimeTypesManager
* wxTheMimeTypesManager
= &gs_mimeTypesManager
;
355 class wxMimeTypeCmnModule
: public wxModule
357 DECLARE_DYNAMIC_CLASS(wxMimeTypeCmnModule
)
359 wxMimeTypeCmnModule() : wxModule() {}
360 bool OnInit() { return TRUE
; }
362 { // this avoids false memory leak allerts:
363 if (gs_mimeTypesManager
.m_impl
!= NULL
)
365 delete gs_mimeTypesManager
.m_impl
;
366 gs_mimeTypesManager
.m_impl
= NULL
;
371 IMPLEMENT_DYNAMIC_CLASS(wxMimeTypeCmnModule
, wxModule
)
376 // wxUSE_FILE && wxUSE_TEXTFILE