]>
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