home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2233.zip / wxOS2-2_3_3.zip / wxWindows-2.3.3 / src / os2 / mimetype.cpp < prev    next >
C/C++ Source or Header  |  2002-08-31  |  14KB  |  456 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        common/mimetype.cpp
  3. // Purpose:     classes and functions to manage MIME types
  4. // Author:      David Webster
  5. // Modified by:
  6. // Created:     01.21.00
  7. // RCS-ID:      $Id: MIMETYPE.CPP,v 1.5 2002/08/30 21:54:47 DW Exp $
  8. // Copyright:   Adopted from msw port --(c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
  9. // Licence:     wxWindows license (part of wxExtra library)
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. #define INCL_DOS
  13. #define INCL_GPI
  14. #define INCL_WIN
  15. #include <os2.h>
  16.  
  17. #ifndef WX_PRECOMP
  18.   #include "wx/string.h"
  19.   #if wxUSE_GUI
  20.     #include "wx/icon.h"
  21.   #endif
  22. #endif //WX_PRECOMP
  23.  
  24. #include "wx/log.h"
  25. #include "wx/file.h"
  26. #include "wx/intl.h"
  27. #include "wx/dynarray.h"
  28. #include "wx/confbase.h"
  29.  
  30. #if wxUSE_FILE
  31.  
  32. #include "wx/os2/mimetype.h"
  33.  
  34. // other standard headers
  35. #include <ctype.h>
  36.  
  37. // in case we're compiling in non-GUI mode
  38. class WXDLLEXPORT wxIcon;
  39.  
  40. // These classes use Windows registry to retrieve the required information.
  41. //
  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.
  47. //
  48. //  2. "HKCR\.ext" contains
  49. //   a) unnamed value containing the "filetype"
  50. //   b) value "Content Type" containing the MIME type
  51. //
  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
  55. //      an icon file
  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)
  59.  
  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\\");
  63.  
  64. wxString wxFileTypeImpl::GetCommand(const wxChar *verb) const
  65. {
  66. // TODO: OS/2 doesn't have a registry but uses Prf
  67. /*
  68.     // suppress possible error messages
  69.     wxLogNull nolog;
  70.     wxString strKey;
  71.  
  72.     if ( wxRegKey(wxRegKey::HKCR, m_ext + _T("\\shell")).Exists() )
  73.         strKey = m_ext;
  74.     if ( wxRegKey(wxRegKey::HKCR, m_strFileType + _T("\\shell")).Exists() )
  75.         strKey = m_strFileType;
  76.  
  77.     if ( !strKey )
  78.     {
  79.         // no info
  80.         return wxEmptyString;
  81.     }
  82.  
  83.     strKey << wxT("\\shell\\") << verb;
  84.     wxRegKey key(wxRegKey::HKCR, strKey + _T("\\command"));
  85.     wxString command;
  86.     if ( key.Open() ) {
  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
  91.             // same purpose)
  92.  
  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('%') &&
  100.                      (n + 1 < len) &&
  101.                      (command[n + 1] == wxT('1') ||
  102.                       command[n + 1] == wxT('L')) ) {
  103.                     // replace it with '%s'
  104.                     command[n + 1] = wxT('s');
  105.  
  106.                     foundFilename = TRUE;
  107.                 }
  108.             }
  109.  
  110. #if wxUSE_DDE
  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"));
  119.  
  120.                 wxRegKey(wxRegKey::HKCR, strKey + _T("\\Application")).
  121.                     QueryValue(_T(""), ddeServer);
  122.                 wxRegKey(wxRegKey::HKCR, strKey + _T("\\Topic")).
  123.                     QueryValue(_T(""), ddeTopic);
  124.  
  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;
  132.             }
  133.             else
  134. #endif // wxUSE_DDE
  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
  138.                 // subkey)
  139.                 //
  140.                 // HACK: append the filename at the end, hope that it will do
  141.                 command << wxT(" %s");
  142.             }
  143.         }
  144.     }
  145.     //else: no such file type or no value, will return empty string
  146.  
  147.     return command;
  148. */
  149.    return wxEmptyString;
  150. }
  151.  
  152. bool
  153. wxFileTypeImpl::GetOpenCommand(wxString *openCmd,
  154.                                const wxFileType::MessageParameters& params)
  155.                                const
  156. {
  157.     wxString cmd;
  158.     if ( m_info ) {
  159.         cmd = m_info->GetOpenCommand();
  160.     }
  161.     else {
  162.         cmd = GetCommand(wxT("open"));
  163.     }
  164.  
  165.     *openCmd = wxFileType::ExpandCommand(cmd, params);
  166.  
  167.     return !openCmd->IsEmpty();
  168. }
  169.  
  170. bool
  171. wxFileTypeImpl::GetPrintCommand(wxString *printCmd,
  172.                                 const wxFileType::MessageParameters& params)
  173.                                 const
  174. {
  175.     wxString cmd;
  176.     if ( m_info ) {
  177.         cmd = m_info->GetPrintCommand();
  178.     }
  179.     else {
  180.         cmd = GetCommand(wxT("print"));
  181.     }
  182.  
  183.     *printCmd = wxFileType::ExpandCommand(cmd, params);
  184.  
  185.     return !printCmd->IsEmpty();
  186. }
  187.  
  188. // TODO this function is half implemented
  189. bool wxFileTypeImpl::GetExtensions(wxArrayString& extensions)
  190. {
  191.     if ( m_info ) {
  192.         extensions = m_info->GetExtensions();
  193.  
  194.         return TRUE;
  195.     }
  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...
  199.         return FALSE;
  200.     }
  201.     else {
  202.         extensions.Empty();
  203.         extensions.Add(m_ext);
  204.  
  205.         // it's a lie too, we don't return _all_ extensions...
  206.         return TRUE;
  207.     }
  208. }
  209.  
  210. bool wxFileTypeImpl::GetMimeType(wxString *mimeType) const
  211. {
  212.     if ( m_info ) {
  213.         // we already have it
  214.         *mimeType = m_info->GetMimeType();
  215.  
  216.         return TRUE;
  217.     }
  218.  
  219.     // suppress possible error messages
  220.     wxLogNull nolog;
  221. // TODO:  substitue reg key stuff (maybe make a Prf class for OS/2??)
  222. /*
  223.     wxRegKey key(wxRegKey::HKCR, wxT(".") + m_ext);
  224.     if ( key.Open() && key.QueryValue(wxT("Content Type"), *mimeType) ) {
  225.         return TRUE;
  226.     }
  227.     else {
  228.         return FALSE;
  229.     }
  230. */
  231.   return FALSE;
  232. }
  233.  
  234. bool wxFileTypeImpl::GetMimeTypes(wxArrayString& mimeTypes) const
  235. {
  236.     wxString s;
  237.  
  238.     if (GetMimeType(&s))
  239.     {
  240.         mimeTypes.Clear();
  241.         mimeTypes.Add(s);
  242.         return TRUE;
  243.     }
  244.     else
  245.         return FALSE;
  246. }
  247.  
  248. bool wxFileTypeImpl::GetIcon(wxIcon *icon, wxString* psCommand, int* pnIndex) const
  249. {
  250. #if wxUSE_GUI
  251.     if ( m_info ) {
  252.         // we don't have icons in the fallback resources
  253.         return FALSE;
  254.     }
  255.  
  256.     wxString strIconKey;
  257.     strIconKey << m_strFileType << wxT("\\DefaultIcon");
  258.  
  259.     // suppress possible error messages
  260.     wxLogNull nolog;
  261. //TODO:
  262. /*
  263.     wxRegKey key(wxRegKey::HKCR, strIconKey);
  264.  
  265.     if ( key.Open() ) {
  266.         wxString strIcon;
  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(','));
  274.  
  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;
  279.                 strIndex = wxT("0");
  280.             }
  281.  
  282.             wxString strExpPath = wxExpandEnvVars(strFullPath);
  283.             int nIndex = wxAtoi(strIndex);
  284.  
  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());
  291.                     break;
  292.  
  293.                 default:
  294.                     icon->SetHICON((WXHICON)hIcon);
  295.                     return TRUE;
  296.             }
  297.         }
  298.     }
  299.  
  300.     // no such file type or no value or incorrect icon entry
  301. */
  302. #endif // wxUSE_GUI
  303.     return FALSE;
  304. }
  305.  
  306. bool wxFileTypeImpl::GetDescription(wxString *desc) const
  307. {
  308.     if ( m_info ) {
  309.         // we already have it
  310.         *desc = m_info->GetDescription();
  311.  
  312.         return TRUE;
  313.     }
  314.  
  315.     // suppress possible error messages
  316.     wxLogNull nolog;
  317. // TODO:
  318. /*
  319.     wxRegKey key(wxRegKey::HKCR, m_strFileType);
  320.  
  321.     if ( key.Open() ) {
  322.         // it's the default value of the key
  323.         if ( key.QueryValue(wxT(""), *desc) ) {
  324.             return TRUE;
  325.         }
  326.     }
  327. */
  328.     return FALSE;
  329. }
  330.  
  331. // extension -> file type
  332. wxFileType *
  333. wxMimeTypesManagerImpl::GetFileTypeFromExtension(const wxString& ext)
  334. {
  335.     // add the leading point if necessary
  336.     wxString str;
  337.     if ( ext[(size_t) 0] != wxT('.') ) {
  338.         str = wxT('.');
  339.     }
  340.     str << ext;
  341.  
  342.     // suppress possible error messages
  343.     wxLogNull nolog;
  344.  
  345.     bool knownExtension = FALSE;
  346.  
  347.     wxString strFileType;
  348. // TODO:
  349. /*
  350.     wxRegKey key(wxRegKey::HKCR, str);
  351.     if ( key.Open() ) {
  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);
  357.  
  358.             return fileType;
  359.         }
  360.         else {
  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;
  365.         }
  366.     }
  367. */
  368.     // check the fallbacks
  369.     // TODO linear search is potentially slow, perhaps we should use a sorted
  370.     //      array?
  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]);
  376.  
  377.             return fileType;
  378.         }
  379.     }
  380.  
  381.     if ( knownExtension )
  382.     {
  383.         wxFileType *fileType = new wxFileType;
  384.         fileType->m_impl->Init(wxEmptyString, ext);
  385.  
  386.         return fileType;
  387.     }
  388.     else
  389.     {
  390.         // unknown extension
  391.         return NULL;
  392.     }
  393. }
  394.  
  395. // MIME type -> extension -> file type
  396. wxFileType *
  397. wxMimeTypesManagerImpl::GetFileTypeFromMimeType(const wxString& mimeType)
  398. {
  399.     wxString strKey = MIME_DATABASE_KEY;
  400.     strKey << mimeType;
  401.  
  402.     // suppress possible error messages
  403.     wxLogNull nolog;
  404.  
  405.     wxString ext;
  406. // TODO:
  407. /*
  408.     wxRegKey key(wxRegKey::HKCR, strKey);
  409.     if ( key.Open() ) {
  410.         if ( key.QueryValue(wxT("Extension"), ext) ) {
  411.             return GetFileTypeFromExtension(ext);
  412.         }
  413.     }
  414.  
  415.     // check the fallbacks
  416.     // TODO linear search is potentially slow, perhaps we should use a sorted
  417.     //      array?
  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]);
  424.  
  425.             return fileType;
  426.         }
  427.     }
  428. */
  429.     // unknown MIME type
  430.     return NULL;
  431. }
  432.  
  433. size_t wxMimeTypesManagerImpl::EnumAllFileTypes(wxArrayString& mimetypes)
  434. {
  435.     // enumerate all keys under MIME_DATABASE_KEY
  436. // TODO:
  437. /*
  438.     wxRegKey key(wxRegKey::HKCR, MIME_DATABASE_KEY);
  439.  
  440.     wxString type;
  441.     long cookie;
  442.     bool cont = key.GetFirstKey(type, cookie);
  443.     while ( cont )
  444.     {
  445.         mimetypes.Add(type);
  446.  
  447.         cont = key.GetNextKey(type, cookie);
  448.     }
  449.  
  450.     return mimetypes.GetCount();
  451. */
  452.   return 0;
  453. }
  454.  
  455. #endif //wxUSE_FILE
  456.