]>
git.saurik.com Git - wxWidgets.git/blob - src/os2/mimetype.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/mimetype.cpp
3 // Purpose: classes and functions to manage MIME types
4 // Author: David Webster
7 // Copyright: Adopted from msw port --(c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
8 // Licence: wxWindows licence (part of wxExtra library)
9 /////////////////////////////////////////////////////////////////////////////
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
16 #include "wx/os2/mimetype.h"
19 #include "wx/dynarray.h"
20 #include "wx/string.h"
34 #include "wx/iconloc.h"
35 #include "wx/confbase.h"
37 // other standard headers
40 // in case we're compiling in non-GUI mode
41 class WXDLLEXPORT wxIcon
;
43 // These classes use Windows registry to retrieve the required information.
45 // Keys used (not all of them are documented, so it might actually stop working
46 // in futur versions of Windows...):
47 // 1. "HKCR\MIME\Database\Content Type" contains subkeys for all known MIME
48 // types, each key has a string value "Extension" which gives (dot preceded)
49 // extension for the files of this MIME type.
51 // 2. "HKCR\.ext" contains
52 // a) unnamed value containing the "filetype"
53 // b) value "Content Type" containing the MIME type
55 // 3. "HKCR\filetype" contains
56 // a) unnamed value containing the description
57 // b) subkey "DefaultIcon" with single unnamed value giving the icon index in
59 // c) shell\open\command and shell\open\print subkeys containing the commands
60 // to open/print the file (the positional parameters are introduced by %1,
61 // %2, ... in these strings, we change them to %s ourselves)
63 // although I don't know of any official documentation which mentions this
64 // location, uses it, so it isn't likely to change
65 static const wxChar
*MIME_DATABASE_KEY
= wxT("MIME\\Database\\Content Type\\");
67 wxString
wxFileTypeImpl::GetCommand(const wxChar
*WXUNUSED(verb
)) const
69 // TODO: OS/2 doesn't have a registry but uses Prf
71 // suppress possible error messages
75 if ( wxRegKey(wxRegKey::HKCR, m_ext + wxT("\\shell")).Exists() )
77 if ( wxRegKey(wxRegKey::HKCR, m_strFileType + wxT("\\shell")).Exists() )
78 strKey = m_strFileType;
86 strKey << wxT("\\shell\\") << verb;
87 wxRegKey key(wxRegKey::HKCR, strKey + wxT("\\command"));
90 // it's the default value of the key
91 if ( key.QueryValue(wxT(""), command) ) {
92 // transform it from '%1' to '%s' style format string (now also
93 // test for %L - apparently MS started using it as well for the
96 // NB: we don't make any attempt to verify that the string is valid,
97 // i.e. doesn't contain %2, or second %1 or .... But we do make
98 // sure that we return a string with _exactly_ one '%s'!
99 bool foundFilename = false;
100 size_t len = command.Len();
101 for ( size_t n = 0; (n < len) && !foundFilename; n++ ) {
102 if ( command[n] == wxT('%') &&
104 (command[n + 1] == wxT('1') ||
105 command[n + 1] == wxT('L')) ) {
106 // replace it with '%s'
107 command[n + 1] = wxT('s');
109 foundFilename = true;
114 // look whether we must issue some DDE requests to the application
115 // (and not just launch it)
116 strKey += wxT("\\DDEExec");
117 wxRegKey keyDDE(wxRegKey::HKCR, strKey);
118 if ( keyDDE.Open() ) {
119 wxString ddeCommand, ddeServer, ddeTopic;
120 keyDDE.QueryValue(wxT(""), ddeCommand);
121 ddeCommand.Replace(wxT("%1"), wxT("%s"));
123 wxRegKey(wxRegKey::HKCR, strKey + wxT("\\Application")).
124 QueryValue(wxT(""), ddeServer);
125 wxRegKey(wxRegKey::HKCR, strKey + wxT("\\Topic")).
126 QueryValue(wxT(""), ddeTopic);
128 // HACK: we use a special feature of wxExecute which exists
129 // just because we need it here: it will establish DDE
130 // conversation with the program it just launched
131 command.Prepend(wxT("WX_DDE#"));
132 command << wxT('#') << ddeServer
133 << wxT('#') << ddeTopic
134 << wxT('#') << ddeCommand;
138 if ( !foundFilename ) {
139 // we didn't find any '%1' - the application doesn't know which
140 // file to open (note that we only do it if there is no DDEExec
143 // HACK: append the filename at the end, hope that it will do
144 command << wxT(" %s");
148 //else: no such file type or no value, will return empty string
152 return wxEmptyString
;
156 wxFileTypeImpl::GetOpenCommand(wxString
*openCmd
,
157 const wxFileType::MessageParameters
& params
)
162 cmd
= m_info
->GetOpenCommand();
165 cmd
= GetCommand(wxT("open"));
168 *openCmd
= wxFileType::ExpandCommand(cmd
, params
);
170 return !openCmd
->empty();
174 wxFileTypeImpl::GetPrintCommand(wxString
*printCmd
,
175 const wxFileType::MessageParameters
& params
)
180 cmd
= m_info
->GetPrintCommand();
183 cmd
= GetCommand(wxT("print"));
186 *printCmd
= wxFileType::ExpandCommand(cmd
, params
);
188 return !printCmd
->empty();
191 // TODO this function is half implemented
192 bool wxFileTypeImpl::GetExtensions(wxArrayString
& extensions
)
195 extensions
= m_info
->GetExtensions();
199 else if ( m_ext
.empty() ) {
200 // the only way to get the list of extensions from the file type is to
201 // scan through all extensions in the registry - too slow...
206 extensions
.Add(m_ext
);
208 // it's a lie too, we don't return _all_ extensions...
213 bool wxFileTypeImpl::GetMimeType(wxString
*mimeType
) const
216 // we already have it
217 *mimeType
= m_info
->GetMimeType();
222 // suppress possible error messages
224 // TODO: substitue reg key stuff (maybe make a Prf class for OS/2??)
226 wxRegKey key(wxRegKey::HKCR, wxT(".") + m_ext);
227 if ( key.Open() && key.QueryValue(wxT("Content Type"), *mimeType) ) {
237 bool wxFileTypeImpl::GetMimeTypes(wxArrayString
& mimeTypes
) const
251 bool wxFileTypeImpl::GetIcon(wxIconLocation
*WXUNUSED(iconLoc
)) const
254 // we don't have icons in the fallback resources
259 strIconKey
<< m_strFileType
<< wxT("\\DefaultIcon");
261 // suppress possible error messages
265 wxRegKey key(wxRegKey::HKCR, strIconKey);
269 // it's the default value of the key
270 if ( key.QueryValue(wxEmptyString, strIcon) ) {
271 // the format is the following: <full path to file>, <icon index>
272 // NB: icon index may be negative as well as positive and the full
273 // path may contain the environment variables inside '%'
274 wxString strFullPath = strIcon.BeforeLast(wxT(',')),
275 strIndex = strIcon.AfterLast(wxT(','));
277 // index may be omitted, in which case BeforeLast(',') is empty and
278 // AfterLast(',') is the whole string
279 if ( strFullPath.empty() ) {
280 strFullPath = strIndex;
286 iconLoc->SetFileName(wxExpandEnvVars(strFullPath));
288 iconLoc->SetIndex(wxAtoi(strIndex));
295 // no such file type or no value or incorrect icon entry
300 bool wxFileTypeImpl::GetDescription(wxString
*desc
) const
303 // we already have it
304 *desc
= m_info
->GetDescription();
309 // suppress possible error messages
313 wxRegKey key(wxRegKey::HKCR, m_strFileType);
316 // it's the default value of the key
317 if ( key.QueryValue(wxT(""), *desc) ) {
325 // extension -> file type
327 wxMimeTypesManagerImpl::GetFileTypeFromExtension(const wxString
& ext
)
329 // add the leading point if necessary
331 if ( ext
[(size_t) 0] != wxT('.') ) {
336 // suppress possible error messages
339 bool knownExtension
= false;
341 wxString strFileType
;
344 wxRegKey key(wxRegKey::HKCR, str);
346 // it's the default value of the key
347 if ( key.QueryValue(wxT(""), strFileType) ) {
348 // create the new wxFileType object
349 wxFileType *fileType = new wxFileType;
350 fileType->m_impl->Init(strFileType, ext);
355 // this extension doesn't have a filetype, but it's known to the
356 // system and may be has some other useful keys (open command or
357 // content-type), so still return a file type object for it
358 knownExtension = true;
362 // check the fallbacks
363 // TODO linear search is potentially slow, perhaps we should use a sorted
365 size_t count
= m_fallbacks
.GetCount();
366 for ( size_t n
= 0; n
< count
; n
++ ) {
367 if ( m_fallbacks
[n
].GetExtensions().Index(ext
) != wxNOT_FOUND
) {
368 wxFileType
*fileType
= new wxFileType
;
369 fileType
->m_impl
->Init(m_fallbacks
[n
]);
375 if ( knownExtension
)
377 wxFileType
*fileType
= new wxFileType
;
378 fileType
->m_impl
->Init(wxEmptyString
, ext
);
389 // MIME type -> extension -> file type
391 wxMimeTypesManagerImpl::GetFileTypeFromMimeType(const wxString
& mimeType
)
393 wxString strKey
= MIME_DATABASE_KEY
;
396 // suppress possible error messages
402 wxRegKey key(wxRegKey::HKCR, strKey);
404 if ( key.QueryValue(wxT("Extension"), ext) ) {
405 return GetFileTypeFromExtension(ext);
409 // check the fallbacks
410 // TODO linear search is potentially slow, perhaps we should use a sorted
412 size_t count = m_fallbacks.GetCount();
413 for ( size_t n = 0; n < count; n++ ) {
414 if ( wxMimeTypesManager::IsOfType(mimeType,
415 m_fallbacks[n].GetMimeType()) ) {
416 wxFileType *fileType = new wxFileType;
417 fileType->m_impl->Init(m_fallbacks[n]);
427 size_t wxMimeTypesManagerImpl::EnumAllFileTypes(wxArrayString
& WXUNUSED(mimetypes
))
429 // enumerate all keys under MIME_DATABASE_KEY
432 wxRegKey key(wxRegKey::HKCR, MIME_DATABASE_KEY);
436 bool cont = key.GetFirstKey(type, cookie);
441 cont = key.GetNextKey(type, cookie);
444 return mimetypes.GetCount();
449 #endif //wxUSE_MIMETYPE