]>
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" 
  32 #include "wx/os2/mimetype.h" 
  34 // other standard headers 
  37 // in case we're compiling in non-GUI mode 
  38 class WXDLLEXPORT wxIcon
; 
  40 // These classes use Windows registry to retrieve the required information. 
  42 // Keys used (not all of them are documented, so it might actually stop working 
  43 // in futur versions of Windows...): 
  44 //  1. "HKCR\MIME\Database\Content Type" contains subkeys for all known MIME 
  45 //     types, each key has a string value "Extension" which gives (dot preceded) 
  46 //     extension for the files of this MIME type. 
  48 //  2. "HKCR\.ext" contains 
  49 //   a) unnamed value containing the "filetype" 
  50 //   b) value "Content Type" containing the MIME type 
  52 // 3. "HKCR\filetype" contains 
  53 //   a) unnamed value containing the description 
  54 //   b) subkey "DefaultIcon" with single unnamed value giving the icon index in 
  56 //   c) shell\open\command and shell\open\print subkeys containing the commands 
  57 //      to open/print the file (the positional parameters are introduced by %1, 
  58 //      %2, ... in these strings, we change them to %s ourselves) 
  60 // although I don't know of any official documentation which mentions this 
  61 // location, uses it, so it isn't likely to change 
  62 static const wxChar 
*MIME_DATABASE_KEY 
= wxT("MIME\\Database\\Content Type\\"); 
  64 wxString 
wxFileTypeImpl::GetCommand(const wxChar 
*verb
) const 
  66 // TODO: OS/2 doesn't have a registry but uses Prf 
  68     // suppress possible error messages 
  72     if ( wxRegKey(wxRegKey::HKCR, m_ext + _T("\\shell")).Exists() ) 
  74     if ( wxRegKey(wxRegKey::HKCR, m_strFileType + _T("\\shell")).Exists() ) 
  75         strKey = m_strFileType; 
  83     strKey << wxT("\\shell\\") << verb; 
  84     wxRegKey key(wxRegKey::HKCR, strKey + _T("\\command")); 
  87         // it's the default value of the key 
  88         if ( key.QueryValue(wxT(""), command) ) { 
  89             // transform it from '%1' to '%s' style format string (now also 
  90             // test for %L - apparently MS started using it as well for the 
  93             // NB: we don't make any attempt to verify that the string is valid, 
  94             //     i.e. doesn't contain %2, or second %1 or .... But we do make 
  95             //     sure that we return a string with _exactly_ one '%s'! 
  96             bool foundFilename = FALSE; 
  97             size_t len = command.Len(); 
  98             for ( size_t n = 0; (n < len) && !foundFilename; n++ ) { 
  99                 if ( command[n] == wxT('%') && 
 101                      (command[n + 1] == wxT('1') || 
 102                       command[n + 1] == wxT('L')) ) { 
 103                     // replace it with '%s' 
 104                     command[n + 1] = wxT('s'); 
 106                     foundFilename = TRUE; 
 111             // look whether we must issue some DDE requests to the application 
 112             // (and not just launch it) 
 113             strKey += _T("\\DDEExec"); 
 114             wxRegKey keyDDE(wxRegKey::HKCR, strKey); 
 115             if ( keyDDE.Open() ) { 
 116                 wxString ddeCommand, ddeServer, ddeTopic; 
 117                 keyDDE.QueryValue(_T(""), ddeCommand); 
 118                 ddeCommand.Replace(_T("%1"), _T("%s")); 
 120                 wxRegKey(wxRegKey::HKCR, strKey + _T("\\Application")). 
 121                     QueryValue(_T(""), ddeServer); 
 122                 wxRegKey(wxRegKey::HKCR, strKey + _T("\\Topic")). 
 123                     QueryValue(_T(""), ddeTopic); 
 125                 // HACK: we use a special feature of wxExecute which exists 
 126                 //       just because we need it here: it will establish DDE 
 127                 //       conversation with the program it just launched 
 128                 command.Prepend(_T("WX_DDE#")); 
 129                 command << _T('#') << ddeServer 
 130                         << _T('#') << ddeTopic 
 131                         << _T('#') << ddeCommand; 
 135                 if ( !foundFilename ) { 
 136                 // we didn't find any '%1' - the application doesn't know which 
 137                 // file to open (note that we only do it if there is no DDEExec 
 140                 // HACK: append the filename at the end, hope that it will do 
 141                 command << wxT(" %s"); 
 145     //else: no such file type or no value, will return empty string 
 149    return wxEmptyString
; 
 153 wxFileTypeImpl::GetOpenCommand(wxString 
*openCmd
, 
 154                                const wxFileType::MessageParameters
& params
) 
 159         cmd 
= m_info
->GetOpenCommand(); 
 162         cmd 
= GetCommand(wxT("open")); 
 165     *openCmd 
= wxFileType::ExpandCommand(cmd
, params
); 
 167     return !openCmd
->IsEmpty(); 
 171 wxFileTypeImpl::GetPrintCommand(wxString 
*printCmd
, 
 172                                 const wxFileType::MessageParameters
& params
) 
 177         cmd 
= m_info
->GetPrintCommand(); 
 180         cmd 
= GetCommand(wxT("print")); 
 183     *printCmd 
= wxFileType::ExpandCommand(cmd
, params
); 
 185     return !printCmd
->IsEmpty(); 
 188 // TODO this function is half implemented 
 189 bool wxFileTypeImpl::GetExtensions(wxArrayString
& extensions
) 
 192         extensions 
= m_info
->GetExtensions(); 
 196     else if ( m_ext
.IsEmpty() ) { 
 197         // the only way to get the list of extensions from the file type is to 
 198         // scan through all extensions in the registry - too slow... 
 203         extensions
.Add(m_ext
); 
 205         // it's a lie too, we don't return _all_ extensions... 
 210 bool wxFileTypeImpl::GetMimeType(wxString 
*mimeType
) const 
 213         // we already have it 
 214         *mimeType 
= m_info
->GetMimeType(); 
 219     // suppress possible error messages 
 221 // TODO:  substitue reg key stuff (maybe make a Prf class for OS/2??) 
 223     wxRegKey key(wxRegKey::HKCR, wxT(".") + m_ext); 
 224     if ( key.Open() && key.QueryValue(wxT("Content Type"), *mimeType) ) { 
 234 bool wxFileTypeImpl::GetMimeTypes(wxArrayString
& mimeTypes
) const 
 248 bool wxFileTypeImpl::GetIcon(wxIcon 
*icon
) 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(wxT(""), 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; 
 282             wxString strExpPath = wxExpandEnvVars(strFullPath); 
 283             int nIndex = wxAtoi(strIndex); 
 285             HICON hIcon = ExtractIcon(GetModuleHandle(NULL), strExpPath, nIndex); 
 286             switch ( (int)hIcon ) { 
 287                 case 0: // means no icons were found 
 288                 case 1: // means no such file or it wasn't a DLL/EXE/OCX/ICO/... 
 289                     wxLogDebug(wxT("incorrect registry entry '%s': no such icon."), 
 290                                key.GetName().c_str()); 
 294                     icon->SetHICON((WXHICON)hIcon); 
 300     // no such file type or no value or incorrect icon entry 
 306 bool wxFileTypeImpl::GetDescription(wxString 
*desc
) const 
 309         // we already have it 
 310         *desc 
= m_info
->GetDescription(); 
 315     // suppress possible error messages 
 319     wxRegKey key(wxRegKey::HKCR, m_strFileType); 
 322         // it's the default value of the key 
 323         if ( key.QueryValue(wxT(""), *desc) ) { 
 331 // extension -> file type 
 333 wxMimeTypesManagerImpl::GetFileTypeFromExtension(const wxString
& ext
) 
 335     // add the leading point if necessary 
 337     if ( ext
[(size_t) 0] != wxT('.') ) { 
 342     // suppress possible error messages 
 345     bool knownExtension 
= FALSE
; 
 347     wxString strFileType
; 
 350     wxRegKey key(wxRegKey::HKCR, str); 
 352         // it's the default value of the key 
 353         if ( key.QueryValue(wxT(""), strFileType) ) { 
 354             // create the new wxFileType object 
 355             wxFileType *fileType = new wxFileType; 
 356             fileType->m_impl->Init(strFileType, ext); 
 361             // this extension doesn't have a filetype, but it's known to the 
 362             // system and may be has some other useful keys (open command or 
 363             // content-type), so still return a file type object for it 
 364             knownExtension = TRUE; 
 368     // check the fallbacks 
 369     // TODO linear search is potentially slow, perhaps we should use a sorted 
 371     size_t count 
= m_fallbacks
.GetCount(); 
 372     for ( size_t n 
= 0; n 
< count
; n
++ ) { 
 373         if ( m_fallbacks
[n
].GetExtensions().Index(ext
) != wxNOT_FOUND 
) { 
 374             wxFileType 
*fileType 
= new wxFileType
; 
 375             fileType
->m_impl
->Init(m_fallbacks
[n
]); 
 381     if ( knownExtension 
) 
 383         wxFileType 
*fileType 
= new wxFileType
; 
 384         fileType
->m_impl
->Init(wxEmptyString
, ext
); 
 395 // MIME type -> extension -> file type 
 397 wxMimeTypesManagerImpl::GetFileTypeFromMimeType(const wxString
& mimeType
) 
 399     wxString strKey 
= MIME_DATABASE_KEY
; 
 402     // suppress possible error messages 
 408     wxRegKey key(wxRegKey::HKCR, strKey); 
 410         if ( key.QueryValue(wxT("Extension"), ext) ) { 
 411             return GetFileTypeFromExtension(ext); 
 415     // check the fallbacks 
 416     // TODO linear search is potentially slow, perhaps we should use a sorted 
 418     size_t count = m_fallbacks.GetCount(); 
 419     for ( size_t n = 0; n < count; n++ ) { 
 420         if ( wxMimeTypesManager::IsOfType(mimeType, 
 421                                           m_fallbacks[n].GetMimeType()) ) { 
 422             wxFileType *fileType = new wxFileType; 
 423             fileType->m_impl->Init(m_fallbacks[n]); 
 433 size_t wxMimeTypesManagerImpl::EnumAllFileTypes(wxArrayString
& mimetypes
) 
 435     // enumerate all keys under MIME_DATABASE_KEY 
 438     wxRegKey key(wxRegKey::HKCR, MIME_DATABASE_KEY); 
 442     bool cont = key.GetFirstKey(type, cookie); 
 447         cont = key.GetNextKey(type, cookie); 
 450     return mimetypes.GetCount();