]>
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 licence (part of wxExtra library)
10 /////////////////////////////////////////////////////////////////////////////
18 #include "wx/string.h"
26 #include "wx/iconloc.h"
28 #include "wx/dynarray.h"
29 #include "wx/confbase.h"
33 #include "wx/os2/mimetype.h"
35 // other standard headers
38 // in case we're compiling in non-GUI mode
39 class WXDLLEXPORT wxIcon
;
41 // These classes use Windows registry to retrieve the required information.
43 // Keys used (not all of them are documented, so it might actually stop working
44 // in futur versions of Windows...):
45 // 1. "HKCR\MIME\Database\Content Type" contains subkeys for all known MIME
46 // types, each key has a string value "Extension" which gives (dot preceded)
47 // extension for the files of this MIME type.
49 // 2. "HKCR\.ext" contains
50 // a) unnamed value containing the "filetype"
51 // b) value "Content Type" containing the MIME type
53 // 3. "HKCR\filetype" contains
54 // a) unnamed value containing the description
55 // b) subkey "DefaultIcon" with single unnamed value giving the icon index in
57 // c) shell\open\command and shell\open\print subkeys containing the commands
58 // to open/print the file (the positional parameters are introduced by %1,
59 // %2, ... in these strings, we change them to %s ourselves)
61 // although I don't know of any official documentation which mentions this
62 // location, uses it, so it isn't likely to change
63 static const wxChar
*MIME_DATABASE_KEY
= wxT("MIME\\Database\\Content Type\\");
65 wxString
wxFileTypeImpl::GetCommand(const wxChar
*verb
) const
67 // TODO: OS/2 doesn't have a registry but uses Prf
69 // suppress possible error messages
73 if ( wxRegKey(wxRegKey::HKCR, m_ext + _T("\\shell")).Exists() )
75 if ( wxRegKey(wxRegKey::HKCR, m_strFileType + _T("\\shell")).Exists() )
76 strKey = m_strFileType;
84 strKey << wxT("\\shell\\") << verb;
85 wxRegKey key(wxRegKey::HKCR, strKey + _T("\\command"));
88 // it's the default value of the key
89 if ( key.QueryValue(wxT(""), command) ) {
90 // transform it from '%1' to '%s' style format string (now also
91 // test for %L - apparently MS started using it as well for the
94 // NB: we don't make any attempt to verify that the string is valid,
95 // i.e. doesn't contain %2, or second %1 or .... But we do make
96 // sure that we return a string with _exactly_ one '%s'!
97 bool foundFilename = FALSE;
98 size_t len = command.Len();
99 for ( size_t n = 0; (n < len) && !foundFilename; n++ ) {
100 if ( command[n] == wxT('%') &&
102 (command[n + 1] == wxT('1') ||
103 command[n + 1] == wxT('L')) ) {
104 // replace it with '%s'
105 command[n + 1] = wxT('s');
107 foundFilename = TRUE;
112 // look whether we must issue some DDE requests to the application
113 // (and not just launch it)
114 strKey += _T("\\DDEExec");
115 wxRegKey keyDDE(wxRegKey::HKCR, strKey);
116 if ( keyDDE.Open() ) {
117 wxString ddeCommand, ddeServer, ddeTopic;
118 keyDDE.QueryValue(_T(""), ddeCommand);
119 ddeCommand.Replace(_T("%1"), _T("%s"));
121 wxRegKey(wxRegKey::HKCR, strKey + _T("\\Application")).
122 QueryValue(_T(""), ddeServer);
123 wxRegKey(wxRegKey::HKCR, strKey + _T("\\Topic")).
124 QueryValue(_T(""), ddeTopic);
126 // HACK: we use a special feature of wxExecute which exists
127 // just because we need it here: it will establish DDE
128 // conversation with the program it just launched
129 command.Prepend(_T("WX_DDE#"));
130 command << _T('#') << ddeServer
131 << _T('#') << ddeTopic
132 << _T('#') << ddeCommand;
136 if ( !foundFilename ) {
137 // we didn't find any '%1' - the application doesn't know which
138 // file to open (note that we only do it if there is no DDEExec
141 // HACK: append the filename at the end, hope that it will do
142 command << wxT(" %s");
146 //else: no such file type or no value, will return empty string
150 return wxEmptyString
;
154 wxFileTypeImpl::GetOpenCommand(wxString
*openCmd
,
155 const wxFileType::MessageParameters
& params
)
160 cmd
= m_info
->GetOpenCommand();
163 cmd
= GetCommand(wxT("open"));
166 *openCmd
= wxFileType::ExpandCommand(cmd
, params
);
168 return !openCmd
->IsEmpty();
172 wxFileTypeImpl::GetPrintCommand(wxString
*printCmd
,
173 const wxFileType::MessageParameters
& params
)
178 cmd
= m_info
->GetPrintCommand();
181 cmd
= GetCommand(wxT("print"));
184 *printCmd
= wxFileType::ExpandCommand(cmd
, params
);
186 return !printCmd
->IsEmpty();
189 // TODO this function is half implemented
190 bool wxFileTypeImpl::GetExtensions(wxArrayString
& extensions
)
193 extensions
= m_info
->GetExtensions();
197 else if ( m_ext
.IsEmpty() ) {
198 // the only way to get the list of extensions from the file type is to
199 // scan through all extensions in the registry - too slow...
204 extensions
.Add(m_ext
);
206 // it's a lie too, we don't return _all_ extensions...
211 bool wxFileTypeImpl::GetMimeType(wxString
*mimeType
) const
214 // we already have it
215 *mimeType
= m_info
->GetMimeType();
220 // suppress possible error messages
222 // TODO: substitue reg key stuff (maybe make a Prf class for OS/2??)
224 wxRegKey key(wxRegKey::HKCR, wxT(".") + m_ext);
225 if ( key.Open() && key.QueryValue(wxT("Content Type"), *mimeType) ) {
235 bool wxFileTypeImpl::GetMimeTypes(wxArrayString
& mimeTypes
) const
249 bool wxFileTypeImpl::GetIcon(wxIconLocation
*iconLoc
) const
252 // we don't have icons in the fallback resources
257 strIconKey
<< m_strFileType
<< wxT("\\DefaultIcon");
259 // suppress possible error messages
263 wxRegKey key(wxRegKey::HKCR, strIconKey);
267 // it's the default value of the key
268 if ( key.QueryValue(wxEmptyString, strIcon) ) {
269 // the format is the following: <full path to file>, <icon index>
270 // NB: icon index may be negative as well as positive and the full
271 // path may contain the environment variables inside '%'
272 wxString strFullPath = strIcon.BeforeLast(wxT(',')),
273 strIndex = strIcon.AfterLast(wxT(','));
275 // index may be omitted, in which case BeforeLast(',') is empty and
276 // AfterLast(',') is the whole string
277 if ( strFullPath.IsEmpty() ) {
278 strFullPath = strIndex;
284 iconLoc->SetFileName(wxExpandEnvVars(strFullPath));
286 iconLoc->SetIndex(wxAtoi(strIndex));
293 // no such file type or no value or incorrect icon entry
298 bool wxFileTypeImpl::GetDescription(wxString
*desc
) const
301 // we already have it
302 *desc
= m_info
->GetDescription();
307 // suppress possible error messages
311 wxRegKey key(wxRegKey::HKCR, m_strFileType);
314 // it's the default value of the key
315 if ( key.QueryValue(wxT(""), *desc) ) {
323 // extension -> file type
325 wxMimeTypesManagerImpl::GetFileTypeFromExtension(const wxString
& ext
)
327 // add the leading point if necessary
329 if ( ext
[(size_t) 0] != wxT('.') ) {
334 // suppress possible error messages
337 bool knownExtension
= FALSE
;
339 wxString strFileType
;
342 wxRegKey key(wxRegKey::HKCR, str);
344 // it's the default value of the key
345 if ( key.QueryValue(wxT(""), strFileType) ) {
346 // create the new wxFileType object
347 wxFileType *fileType = new wxFileType;
348 fileType->m_impl->Init(strFileType, ext);
353 // this extension doesn't have a filetype, but it's known to the
354 // system and may be has some other useful keys (open command or
355 // content-type), so still return a file type object for it
356 knownExtension = TRUE;
360 // check the fallbacks
361 // TODO linear search is potentially slow, perhaps we should use a sorted
363 size_t count
= m_fallbacks
.GetCount();
364 for ( size_t n
= 0; n
< count
; n
++ ) {
365 if ( m_fallbacks
[n
].GetExtensions().Index(ext
) != wxNOT_FOUND
) {
366 wxFileType
*fileType
= new wxFileType
;
367 fileType
->m_impl
->Init(m_fallbacks
[n
]);
373 if ( knownExtension
)
375 wxFileType
*fileType
= new wxFileType
;
376 fileType
->m_impl
->Init(wxEmptyString
, ext
);
387 // MIME type -> extension -> file type
389 wxMimeTypesManagerImpl::GetFileTypeFromMimeType(const wxString
& mimeType
)
391 wxString strKey
= MIME_DATABASE_KEY
;
394 // suppress possible error messages
400 wxRegKey key(wxRegKey::HKCR, strKey);
402 if ( key.QueryValue(wxT("Extension"), ext) ) {
403 return GetFileTypeFromExtension(ext);
407 // check the fallbacks
408 // TODO linear search is potentially slow, perhaps we should use a sorted
410 size_t count = m_fallbacks.GetCount();
411 for ( size_t n = 0; n < count; n++ ) {
412 if ( wxMimeTypesManager::IsOfType(mimeType,
413 m_fallbacks[n].GetMimeType()) ) {
414 wxFileType *fileType = new wxFileType;
415 fileType->m_impl->Init(m_fallbacks[n]);
425 size_t wxMimeTypesManagerImpl::EnumAllFileTypes(wxArrayString
& mimetypes
)
427 // enumerate all keys under MIME_DATABASE_KEY
430 wxRegKey key(wxRegKey::HKCR, MIME_DATABASE_KEY);
434 bool cont = key.GetFirstKey(type, cookie);
439 cont = key.GetNextKey(type, cookie);
442 return mimetypes.GetCount();
447 #endif //wxUSE_MIMETYPE