X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/92218ce60024b07e9ae5a5790a85582db083e55c..a3a8d81d487ae4f03d8b70bce20bddbfc48c5776:/src/msw/mimetype.cpp diff --git a/src/msw/mimetype.cpp b/src/msw/mimetype.cpp index 3db2218e44..a067ac7de3 100644 --- a/src/msw/mimetype.cpp +++ b/src/msw/mimetype.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: msw/mimetype.cpp +// Name: src/msw/mimetype.cpp // Purpose: classes and functions to manage MIME types // Author: Vadim Zeitlin // Modified by: @@ -9,32 +9,31 @@ // Licence: wxWindows licence (part of wxExtra library) ///////////////////////////////////////////////////////////////////////////// -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) -#pragma implementation "mimetype.h" -#endif - // for compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ - #pragma hdrstop + #pragma hdrstop #endif #if wxUSE_MIMETYPE +#include "wx/msw/mimetype.h" + #ifndef WX_PRECOMP + #include "wx/dynarray.h" #include "wx/string.h" + #include "wx/intl.h" + #include "wx/log.h" + #include "wx/crt.h" #if wxUSE_GUI #include "wx/icon.h" #include "wx/msgdlg.h" #endif #endif //WX_PRECOMP -#include "wx/log.h" #include "wx/file.h" #include "wx/iconloc.h" -#include "wx/intl.h" -#include "wx/dynarray.h" #include "wx/confbase.h" #ifdef __WXMSW__ @@ -42,13 +41,11 @@ #include "wx/msw/private.h" #endif // OS -#include "wx/msw/mimetype.h" - // other standard headers #include // in case we're compiling in non-GUI mode -class WXDLLEXPORT wxIcon; +class WXDLLIMPEXP_FWD_CORE wxIcon; // These classes use Windows registry to retrieve the required information. // @@ -98,13 +95,22 @@ static bool CanonicalizeParams(wxString& command) } } + if ( foundFilename ) + { + // Some values also contain an addition %* expansion string which is + // presumably supposed to be replaced with the names of the other files + // accepted by the command. As we don't support more than one file + // anyhow, simply ignore it. + command.Replace(" %*", ""); + } + return foundFilename; } void wxFileTypeImpl::Init(const wxString& strFileType, const wxString& ext) { // VZ: does it? (FIXME) - wxCHECK_RET( !ext.empty(), _T("needs an extension") ); + wxCHECK_RET( !ext.empty(), wxT("needs an extension") ); if ( ext[0u] != wxT('.') ) { m_ext = wxT('.'); @@ -113,14 +119,14 @@ void wxFileTypeImpl::Init(const wxString& strFileType, const wxString& ext) m_strFileType = strFileType; if ( !strFileType ) { - m_strFileType = m_ext.AfterFirst('.') + _T("_auto_file"); + m_strFileType = m_ext.AfterFirst('.') + wxT("_auto_file"); } } wxString wxFileTypeImpl::GetVerbPath(const wxString& verb) const { wxString path; - path << m_strFileType << _T("\\shell\\") << verb << _T("\\command"); + path << m_strFileType << wxT("\\shell\\") << verb << wxT("\\command"); return path; } @@ -128,7 +134,7 @@ size_t wxFileTypeImpl::GetAllCommands(wxArrayString *verbs, wxArrayString *commands, const wxFileType::MessageParameters& params) const { - wxCHECK_MSG( !m_ext.empty(), 0, _T("GetAllCommands() needs an extension") ); + wxCHECK_MSG( !m_ext.empty(), 0, wxT("GetAllCommands() needs an extension") ); if ( m_strFileType.empty() ) { @@ -137,7 +143,7 @@ size_t wxFileTypeImpl::GetAllCommands(wxArrayString *verbs, wxRegKey rkey(wxRegKey::HKCR, m_ext); if ( !rkey.Exists() || !rkey.QueryValue(wxEmptyString, self->m_strFileType) ) { - wxLogDebug(_T("Can't get the filetype for extension '%s'."), + wxLogDebug(wxT("Can't get the filetype for extension '%s'."), m_ext.c_str()); return 0; @@ -146,7 +152,7 @@ size_t wxFileTypeImpl::GetAllCommands(wxArrayString *verbs, // enum all subkeys of HKCR\filetype\shell size_t count = 0; - wxRegKey rkey(wxRegKey::HKCR, m_strFileType + _T("\\shell")); + wxRegKey rkey(wxRegKey::HKCR, m_strFileType + wxT("\\shell")); long dummy; wxString verb; bool ok = rkey.GetFirstKey(verb, dummy); @@ -156,7 +162,7 @@ size_t wxFileTypeImpl::GetAllCommands(wxArrayString *verbs, // we want the open bverb to eb always the first - if ( verb.CmpNoCase(_T("open")) == 0 ) + if ( verb.CmpNoCase(wxT("open")) == 0 ) { if ( verbs ) verbs->Insert(verb, 0); @@ -203,16 +209,47 @@ bool wxFileTypeImpl::EnsureExtKeyExists() // get the command to use // ---------------------------------------------------------------------------- -wxString wxFileTypeImpl::GetCommand(const wxChar *verb) const +static wxString wxFileTypeImplGetCurVer(const wxString& progId) +{ + wxRegKey key(wxRegKey::HKCR, progId + wxT("\\CurVer")); + if (key.Exists()) + { + wxString value; + if (key.QueryValue(wxEmptyString, value)) + return value; + } + return progId; +} + +wxString wxFileTypeImpl::GetCommand(const wxString& verb) const { // suppress possible error messages wxLogNull nolog; wxString strKey; - if ( wxRegKey(wxRegKey::HKCR, m_ext + _T("\\shell")).Exists() ) + { + wxRegKey explorerKey(wxRegKey::HKCU, wxT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\") + m_ext); + if (explorerKey.Exists()) + { + if (explorerKey.Open(wxRegKey::Read)) + { + if (explorerKey.QueryValue(wxT("Progid"), strKey)) + { + strKey = wxFileTypeImplGetCurVer(strKey); + } + } + } + } + + if (!strKey && wxRegKey(wxRegKey::HKCR, m_ext + wxT("\\shell")).Exists()) strKey = m_ext; - if ( wxRegKey(wxRegKey::HKCR, m_strFileType + _T("\\shell")).Exists() ) - strKey = m_strFileType; + + if ( !strKey && !m_strFileType.empty()) + { + wxString fileType = wxFileTypeImplGetCurVer(m_strFileType); + if (wxRegKey(wxRegKey::HKCR, fileType + wxT("\\shell")).Exists()) + strKey = fileType; + } if ( !strKey ) { @@ -221,7 +258,7 @@ wxString wxFileTypeImpl::GetCommand(const wxChar *verb) const } strKey << wxT("\\shell\\") << verb; - wxRegKey key(wxRegKey::HKCR, strKey + _T("\\command")); + wxRegKey key(wxRegKey::HKCR, strKey + wxT("\\command")); wxString command; if ( key.Open(wxRegKey::Read) ) { // it's the default value of the key @@ -231,16 +268,16 @@ wxString wxFileTypeImpl::GetCommand(const wxChar *verb) const #if wxUSE_IPC // look whether we must issue some DDE requests to the application // (and not just launch it) - strKey += _T("\\DDEExec"); + strKey += wxT("\\DDEExec"); wxRegKey keyDDE(wxRegKey::HKCR, strKey); if ( keyDDE.Open(wxRegKey::Read) ) { wxString ddeCommand, ddeServer, ddeTopic; keyDDE.QueryValue(wxEmptyString, ddeCommand); - ddeCommand.Replace(_T("%1"), _T("%s")); + ddeCommand.Replace(wxT("%1"), wxT("%s")); - wxRegKey keyServer(wxRegKey::HKCR, strKey + _T("\\Application")); + wxRegKey keyServer(wxRegKey::HKCR, strKey + wxT("\\Application")); keyServer.QueryValue(wxEmptyString, ddeServer); - wxRegKey keyTopic(wxRegKey::HKCR, strKey + _T("\\Topic")); + wxRegKey keyTopic(wxRegKey::HKCR, strKey + wxT("\\Topic")); keyTopic.QueryValue(wxEmptyString, ddeTopic); if (ddeTopic.empty()) @@ -249,10 +286,10 @@ wxString wxFileTypeImpl::GetCommand(const wxChar *verb) const // HACK: we use a special feature of wxExecute which exists // just because we need it here: it will establish DDE // conversation with the program it just launched - command.Prepend(_T("WX_DDE#")); - command << _T('#') << ddeServer - << _T('#') << ddeTopic - << _T('#') << ddeCommand; + command.Prepend(wxT("WX_DDE#")); + command << wxT('#') << ddeServer + << wxT('#') << ddeTopic + << wxT('#') << ddeCommand; } else #endif // wxUSE_IPC @@ -510,20 +547,20 @@ size_t wxMimeTypesManagerImpl::EnumAllFileTypes(wxArrayString& mimetypes) wxFileType *wxMimeTypesManagerImpl::Associate(const wxFileTypeInfo& ftInfo) { wxCHECK_MSG( !ftInfo.GetExtensions().empty(), NULL, - _T("Associate() needs extension") ); + wxT("Associate() needs extension") ); bool ok; - int iExtCount = 0 ; + size_t iExtCount = 0; wxString filetype; wxString extWithDot; wxString ext = ftInfo.GetExtensions()[iExtCount]; wxCHECK_MSG( !ext.empty(), NULL, - _T("Associate() needs non empty extension") ); + wxT("Associate() needs non empty extension") ); - if ( ext[0u] != _T('.') ) - extWithDot = _T('.'); + if ( ext[0u] != wxT('.') ) + extWithDot = wxT('.'); extWithDot += ext; // start by setting the HKCR\\.ext entries @@ -541,7 +578,7 @@ wxFileType *wxMimeTypesManagerImpl::Associate(const wxFileTypeInfo& ftInfo) if ( filetypeOrig.empty() ) { // make it up from the extension - filetype << extWithDot.c_str() + 1 << _T("_file"); + filetype << extWithDot.c_str() + 1 << wxT("_file"); } else { @@ -571,7 +608,7 @@ wxFileType *wxMimeTypesManagerImpl::Associate(const wxFileTypeInfo& ftInfo) if ( !mimetype.empty() ) { // set the MIME type - ok = key.SetValue(_T("Content Type"), mimetype); + ok = key.SetValue(wxT("Content Type"), mimetype); if ( ok ) { @@ -584,7 +621,7 @@ wxFileType *wxMimeTypesManagerImpl::Associate(const wxFileTypeInfo& ftInfo) if ( ok ) { // and provide a back link to the extension - keyMIME.SetValue(_T("Extension"), extWithDot); + keyMIME.SetValue(wxT("Extension"), extWithDot); } } } @@ -595,8 +632,8 @@ wxFileType *wxMimeTypesManagerImpl::Associate(const wxFileTypeInfo& ftInfo) for (iExtCount=1; iExtCount < ftInfo.GetExtensionsCount(); iExtCount++ ) { ext = ftInfo.GetExtensions()[iExtCount]; - if ( ext[0u] != _T('.') ) - extWithDot = _T('.'); + if ( ext[0u] != wxT('.') ) + extWithDot = wxT('.'); extWithDot += ext; wxRegKey key(wxRegKey::HKCR, extWithDot); @@ -608,7 +645,7 @@ wxFileType *wxMimeTypesManagerImpl::Associate(const wxFileTypeInfo& ftInfo) if ( !mimetype.empty() ) { // set the MIME type - ok = key.SetValue(_T("Content Type"), mimetype); + ok = key.SetValue(wxT("Content Type"), mimetype); if ( ok ) { @@ -621,7 +658,7 @@ wxFileType *wxMimeTypesManagerImpl::Associate(const wxFileTypeInfo& ftInfo) if ( ok ) { // and provide a back link to the extension - keyMIME.SetValue(_T("Extension"), extWithDot); + keyMIME.SetValue(wxT("Extension"), extWithDot); } } } @@ -653,7 +690,7 @@ bool wxFileTypeImpl::SetCommand(const wxString& cmd, bool WXUNUSED(overwriteprompt)) { wxCHECK_MSG( !m_ext.empty() && !verb.empty(), false, - _T("SetCommand() needs an extension and a verb") ); + wxT("SetCommand() needs an extension and a verb") ); if ( !EnsureExtKeyExists() ) return false; @@ -688,13 +725,13 @@ bool wxFileTypeImpl::SetCommand(const wxString& cmd, // TODO: // 1. translate '%s' to '%1' instead of always adding it // 2. create DDEExec value if needed (undo GetCommand) - return rkey.Create() && rkey.SetValue(wxEmptyString, cmd + _T(" \"%1\"") ); + return rkey.Create() && rkey.SetValue(wxEmptyString, cmd + wxT(" \"%1\"") ); } /* // no longer used bool wxFileTypeImpl::SetMimeType(const wxString& mimeTypeOrig) { - wxCHECK_MSG( !m_ext.empty(), false, _T("SetMimeType() needs extension") ); + wxCHECK_MSG( !m_ext.empty(), false, wxT("SetMimeType() needs extension") ); if ( !EnsureExtKeyExists() ) return false; @@ -705,8 +742,8 @@ bool wxFileTypeImpl::SetMimeType(const wxString& mimeTypeOrig) { // make up a default value for it wxString cmd; - wxSplitPath(GetCommand(_T("open")), NULL, &cmd, NULL); - mimeType << _T("application/x-") << cmd; + wxFileName::SplitPath(GetCommand(wxT("open")), NULL, &cmd, NULL); + mimeType << wxT("application/x-") << cmd; } else { @@ -714,31 +751,31 @@ bool wxFileTypeImpl::SetMimeType(const wxString& mimeTypeOrig) } wxRegKey rkey(wxRegKey::HKCR, m_ext); - return rkey.Create() && rkey.SetValue(_T("Content Type"), mimeType); + return rkey.Create() && rkey.SetValue(wxT("Content Type"), mimeType); } */ bool wxFileTypeImpl::SetDefaultIcon(const wxString& cmd, int index) { - wxCHECK_MSG( !m_ext.empty(), false, _T("SetDefaultIcon() needs extension") ); - wxCHECK_MSG( !m_strFileType.empty(), false, _T("File key not found") ); + wxCHECK_MSG( !m_ext.empty(), false, wxT("SetDefaultIcon() needs extension") ); + wxCHECK_MSG( !m_strFileType.empty(), false, wxT("File key not found") ); // the next line fails on a SMBshare, I think because it is case mangled -// wxCHECK_MSG( !wxFileExists(cmd), false, _T("Icon file not found.") ); +// wxCHECK_MSG( !wxFileExists(cmd), false, wxT("Icon file not found.") ); if ( !EnsureExtKeyExists() ) return false; - wxRegKey rkey(wxRegKey::HKCR, m_strFileType + _T("\\DefaultIcon")); + wxRegKey rkey(wxRegKey::HKCR, m_strFileType + wxT("\\DefaultIcon")); return rkey.Create() && rkey.SetValue(wxEmptyString, - wxString::Format(_T("%s,%d"), cmd.c_str(), index)); + wxString::Format(wxT("%s,%d"), cmd.c_str(), index)); } bool wxFileTypeImpl::SetDescription (const wxString& desc) { - wxCHECK_MSG( !m_strFileType.empty(), false, _T("File key not found") ); - wxCHECK_MSG( !desc.empty(), false, _T("No file description supplied") ); + wxCHECK_MSG( !m_strFileType.empty(), false, wxT("File key not found") ); + wxCHECK_MSG( !desc.empty(), false, wxT("No file description supplied") ); if ( !EnsureExtKeyExists() ) return false; @@ -780,13 +817,13 @@ bool wxFileTypeImpl::Unassociate() bool wxFileTypeImpl::RemoveOpenCommand() { - return RemoveCommand(_T("open")); + return RemoveCommand(wxT("open")); } bool wxFileTypeImpl::RemoveCommand(const wxString& verb) { wxCHECK_MSG( !m_ext.empty() && !verb.empty(), false, - _T("RemoveCommand() needs an extension and a verb") ); + wxT("RemoveCommand() needs an extension and a verb") ); wxRegKey rkey(wxRegKey::HKCR, GetVerbPath(verb)); @@ -796,7 +833,7 @@ bool wxFileTypeImpl::RemoveCommand(const wxString& verb) bool wxFileTypeImpl::RemoveMimeType() { - wxCHECK_MSG( !m_ext.empty(), false, _T("RemoveMimeType() needs extension") ); + wxCHECK_MSG( !m_ext.empty(), false, wxT("RemoveMimeType() needs extension") ); wxRegKey rkey(wxRegKey::HKCR, m_ext); return !rkey.Exists() || rkey.DeleteSelf(); @@ -805,16 +842,16 @@ bool wxFileTypeImpl::RemoveMimeType() bool wxFileTypeImpl::RemoveDefaultIcon() { wxCHECK_MSG( !m_ext.empty(), false, - _T("RemoveDefaultIcon() needs extension") ); + wxT("RemoveDefaultIcon() needs extension") ); - wxRegKey rkey (wxRegKey::HKCR, m_strFileType + _T("\\DefaultIcon")); + wxRegKey rkey (wxRegKey::HKCR, m_strFileType + wxT("\\DefaultIcon")); return !rkey.Exists() || rkey.DeleteSelf(); } bool wxFileTypeImpl::RemoveDescription() { wxCHECK_MSG( !m_ext.empty(), false, - _T("RemoveDescription() needs extension") ); + wxT("RemoveDescription() needs extension") ); wxRegKey rkey (wxRegKey::HKCR, m_strFileType ); return !rkey.Exists() || rkey.DeleteSelf();