]>
git.saurik.com Git - wxWidgets.git/blob - src/os2/mimetype.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: common/mimetype.cpp
3 // Purpose: classes and functions to manage MIME types
4 // Author: David Webster
8 // Copyright: Adopted from msw port --(c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows license (part of wxExtra library)
10 /////////////////////////////////////////////////////////////////////////////
18 #include "wx/string.h"
27 #include "wx/dynarray.h"
28 #include "wx/confbase.h"
30 #include "wx/os2/mimetype.h"
32 // other standard headers
35 // in case we're compiling in non-GUI mode
36 class WXDLLEXPORT wxIcon
;
38 // These classes use Windows registry to retrieve the required information.
40 // Keys used (not all of them are documented, so it might actually stop working
41 // in futur versions of Windows...):
42 // 1. "HKCR\MIME\Database\Content Type" contains subkeys for all known MIME
43 // types, each key has a string value "Extension" which gives (dot preceded)
44 // extension for the files of this MIME type.
46 // 2. "HKCR\.ext" contains
47 // a) unnamed value containing the "filetype"
48 // b) value "Content Type" containing the MIME type
50 // 3. "HKCR\filetype" contains
51 // a) unnamed value containing the description
52 // b) subkey "DefaultIcon" with single unnamed value giving the icon index in
54 // c) shell\open\command and shell\open\print subkeys containing the commands
55 // to open/print the file (the positional parameters are introduced by %1,
56 // %2, ... in these strings, we change them to %s ourselves)
58 // although I don't know of any official documentation which mentions this
59 // location, uses it, so it isn't likely to change
60 static const wxChar
*MIME_DATABASE_KEY
= wxT("MIME\\Database\\Content Type\\");
62 wxString
wxFileTypeImpl::GetCommand(const wxChar
*verb
) const
64 // TODO: OS/2 doesn't have a registry but uses Prf
66 // suppress possible error messages
70 if ( wxRegKey(wxRegKey::HKCR, m_ext + _T("\\shell")).Exists() )
72 if ( wxRegKey(wxRegKey::HKCR, m_strFileType + _T("\\shell")).Exists() )
73 strKey = m_strFileType;
81 strKey << wxT("\\shell\\") << verb;
82 wxRegKey key(wxRegKey::HKCR, strKey + _T("\\command"));
85 // it's the default value of the key
86 if ( key.QueryValue(wxT(""), command) ) {
87 // transform it from '%1' to '%s' style format string (now also
88 // test for %L - apparently MS started using it as well for the
91 // NB: we don't make any attempt to verify that the string is valid,
92 // i.e. doesn't contain %2, or second %1 or .... But we do make
93 // sure that we return a string with _exactly_ one '%s'!
94 bool foundFilename = FALSE;
95 size_t len = command.Len();
96 for ( size_t n = 0; (n < len) && !foundFilename; n++ ) {
97 if ( command[n] == wxT('%') &&
99 (command[n + 1] == wxT('1') ||
100 command[n + 1] == wxT('L')) ) {
101 // replace it with '%s'
102 command[n + 1] = wxT('s');
104 foundFilename = TRUE;
109 // look whether we must issue some DDE requests to the application
110 // (and not just launch it)
111 strKey += _T("\\DDEExec");
112 wxRegKey keyDDE(wxRegKey::HKCR, strKey);
113 if ( keyDDE.Open() ) {
114 wxString ddeCommand, ddeServer, ddeTopic;
115 keyDDE.QueryValue(_T(""), ddeCommand);
116 ddeCommand.Replace(_T("%1"), _T("%s"));
118 wxRegKey(wxRegKey::HKCR, strKey + _T("\\Application")).
119 QueryValue(_T(""), ddeServer);
120 wxRegKey(wxRegKey::HKCR, strKey + _T("\\Topic")).
121 QueryValue(_T(""), ddeTopic);
123 // HACK: we use a special feature of wxExecute which exists
124 // just because we need it here: it will establish DDE
125 // conversation with the program it just launched
126 command.Prepend(_T("WX_DDE#"));
127 command << _T('#') << ddeServer
128 << _T('#') << ddeTopic
129 << _T('#') << ddeCommand;
133 if ( !foundFilename ) {
134 // we didn't find any '%1' - the application doesn't know which
135 // file to open (note that we only do it if there is no DDEExec
138 // HACK: append the filename at the end, hope that it will do
139 command << wxT(" %s");
143 //else: no such file type or no value, will return empty string
147 return wxEmptyString
;
151 wxFileTypeImpl::GetOpenCommand(wxString
*openCmd
,
152 const wxFileType::MessageParameters
& params
)
157 cmd
= m_info
->GetOpenCommand();
160 cmd
= GetCommand(wxT("open"));
163 *openCmd
= wxFileType::ExpandCommand(cmd
, params
);
165 return !openCmd
->IsEmpty();
169 wxFileTypeImpl::GetPrintCommand(wxString
*printCmd
,
170 const wxFileType::MessageParameters
& params
)
175 cmd
= m_info
->GetPrintCommand();
178 cmd
= GetCommand(wxT("print"));
181 *printCmd
= wxFileType::ExpandCommand(cmd
, params
);
183 return !printCmd
->IsEmpty();
186 // TODO this function is half implemented
187 bool wxFileTypeImpl::GetExtensions(wxArrayString
& extensions
)
190 extensions
= m_info
->GetExtensions();
194 else if ( m_ext
.IsEmpty() ) {
195 // the only way to get the list of extensions from the file type is to
196 // scan through all extensions in the registry - too slow...
201 extensions
.Add(m_ext
);
203 // it's a lie too, we don't return _all_ extensions...
208 bool wxFileTypeImpl::GetMimeType(wxString
*mimeType
) const
211 // we already have it
212 *mimeType
= m_info
->GetMimeType();
217 // suppress possible error messages
219 // TODO: substitue reg key stuff (maybe make a Prf class for OS/2??)
221 wxRegKey key(wxRegKey::HKCR, wxT(".") + m_ext);
222 if ( key.Open() && key.QueryValue(wxT("Content Type"), *mimeType) ) {
232 bool wxFileTypeImpl::GetMimeTypes(wxArrayString
& mimeTypes
) const
246 bool wxFileTypeImpl::GetIcon(wxIcon
*icon
) const
250 // we don't have icons in the fallback resources
255 strIconKey
<< m_strFileType
<< wxT("\\DefaultIcon");
257 // suppress possible error messages
261 wxRegKey key(wxRegKey::HKCR, strIconKey);
265 // it's the default value of the key
266 if ( key.QueryValue(wxT(""), strIcon) ) {
267 // the format is the following: <full path to file>, <icon index>
268 // NB: icon index may be negative as well as positive and the full
269 // path may contain the environment variables inside '%'
270 wxString strFullPath = strIcon.BeforeLast(wxT(',')),
271 strIndex = strIcon.AfterLast(wxT(','));
273 // index may be omitted, in which case BeforeLast(',') is empty and
274 // AfterLast(',') is the whole string
275 if ( strFullPath.IsEmpty() ) {
276 strFullPath = strIndex;
280 wxString strExpPath = wxExpandEnvVars(strFullPath);
281 int nIndex = wxAtoi(strIndex);
283 HICON hIcon = ExtractIcon(GetModuleHandle(NULL), strExpPath, nIndex);
284 switch ( (int)hIcon ) {
285 case 0: // means no icons were found
286 case 1: // means no such file or it wasn't a DLL/EXE/OCX/ICO/...
287 wxLogDebug(wxT("incorrect registry entry '%s': no such icon."),
288 key.GetName().c_str());
292 icon->SetHICON((WXHICON)hIcon);
298 // no such file type or no value or incorrect icon entry
304 bool wxFileTypeImpl::GetDescription(wxString
*desc
) const
307 // we already have it
308 *desc
= m_info
->GetDescription();
313 // suppress possible error messages
317 wxRegKey key(wxRegKey::HKCR, m_strFileType);
320 // it's the default value of the key
321 if ( key.QueryValue(wxT(""), *desc) ) {
329 // extension -> file type
331 wxMimeTypesManagerImpl::GetFileTypeFromExtension(const wxString
& ext
)
333 // add the leading point if necessary
335 if ( ext
[(size_t) 0] != wxT('.') ) {
340 // suppress possible error messages
343 bool knownExtension
= FALSE
;
345 wxString strFileType
;
348 wxRegKey key(wxRegKey::HKCR, str);
350 // it's the default value of the key
351 if ( key.QueryValue(wxT(""), strFileType) ) {
352 // create the new wxFileType object
353 wxFileType *fileType = new wxFileType;
354 fileType->m_impl->Init(strFileType, ext);
359 // this extension doesn't have a filetype, but it's known to the
360 // system and may be has some other useful keys (open command or
361 // content-type), so still return a file type object for it
362 knownExtension = TRUE;
366 // check the fallbacks
367 // TODO linear search is potentially slow, perhaps we should use a sorted
369 size_t count
= m_fallbacks
.GetCount();
370 for ( size_t n
= 0; n
< count
; n
++ ) {
371 if ( m_fallbacks
[n
].GetExtensions().Index(ext
) != wxNOT_FOUND
) {
372 wxFileType
*fileType
= new wxFileType
;
373 fileType
->m_impl
->Init(m_fallbacks
[n
]);
379 if ( knownExtension
)
381 wxFileType
*fileType
= new wxFileType
;
382 fileType
->m_impl
->Init(wxEmptyString
, ext
);
393 // MIME type -> extension -> file type
395 wxMimeTypesManagerImpl::GetFileTypeFromMimeType(const wxString
& mimeType
)
397 wxString strKey
= MIME_DATABASE_KEY
;
400 // suppress possible error messages
406 wxRegKey key(wxRegKey::HKCR, strKey);
408 if ( key.QueryValue(wxT("Extension"), ext) ) {
409 return GetFileTypeFromExtension(ext);
413 // check the fallbacks
414 // TODO linear search is potentially slow, perhaps we should use a sorted
416 size_t count = m_fallbacks.GetCount();
417 for ( size_t n = 0; n < count; n++ ) {
418 if ( wxMimeTypesManager::IsOfType(mimeType,
419 m_fallbacks[n].GetMimeType()) ) {
420 wxFileType *fileType = new wxFileType;
421 fileType->m_impl->Init(m_fallbacks[n]);
431 size_t wxMimeTypesManagerImpl::EnumAllFileTypes(wxArrayString
& mimetypes
)
433 // enumerate all keys under MIME_DATABASE_KEY
436 wxRegKey key(wxRegKey::HKCR, MIME_DATABASE_KEY);
440 bool cont = key.GetFirstKey(type, cookie);
445 cont = key.GetNextKey(type, cookie);
448 return mimetypes.GetCount();