X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7a893a3152a6ac676b0409320daef188a7be1b7b..87f0b1323b7ac77f02133b836c8dfee63b0fd387:/src/common/mimecmn.cpp diff --git a/src/common/mimecmn.cpp b/src/common/mimecmn.cpp index 3ac318ce0b..930f70a31e 100644 --- a/src/common/mimecmn.cpp +++ b/src/common/mimecmn.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: common/mimecmn.cpp +// Name: src/common/mimecmn.cpp // Purpose: classes and functions to manage MIME types // Author: Vadim Zeitlin // Modified by: @@ -18,10 +18,6 @@ // headers // ---------------------------------------------------------------------------- -#ifdef __GNUG__ - #pragma implementation "mimetypebase.h" -#endif - // for compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -31,28 +27,29 @@ #if wxUSE_MIMETYPE +#include "wx/mimetype.h" + #ifndef WX_PRECOMP - #include "wx/string.h" + #include "wx/dynarray.h" + #include "wx/string.h" + #include "wx/intl.h" + #include "wx/log.h" + #include "wx/module.h" + #include "wx/crt.h" #endif //WX_PRECOMP -#include "wx/module.h" -#include "wx/log.h" #include "wx/file.h" #include "wx/iconloc.h" -#include "wx/intl.h" -#include "wx/dynarray.h" #include "wx/confbase.h" -#include "wx/mimetype.h" - // other standard headers #include // implementation classes: -#if defined(__WXMSW__) +#if defined(__WINDOWS__) #include "wx/msw/mimetype.h" -#elif defined(__WXMAC__) - #include "wx/mac/mimetype.h" +#elif ( defined(__DARWIN__) ) + #include "wx/osx/mimetype.h" #elif defined(__WXPM__) || defined (__EMX__) #include "wx/os2/mimetype.h" #undef __UNIX__ @@ -66,34 +63,99 @@ // common classes // ============================================================================ +// ---------------------------------------------------------------------------- +// wxMimeTypeCommands +// ---------------------------------------------------------------------------- + +void +wxMimeTypeCommands::AddOrReplaceVerb(const wxString& verb, const wxString& cmd) +{ + int n = m_verbs.Index(verb, false /* ignore case */); + if ( n == wxNOT_FOUND ) + { + m_verbs.Add(verb); + m_commands.Add(cmd); + } + else + { + m_commands[n] = cmd; + } +} + +wxString +wxMimeTypeCommands::GetCommandForVerb(const wxString& verb, size_t *idx) const +{ + wxString s; + + int n = m_verbs.Index(verb); + if ( n != wxNOT_FOUND ) + { + s = m_commands[(size_t)n]; + if ( idx ) + *idx = n; + } + else if ( idx ) + { + // different from any valid index + *idx = (size_t)-1; + } + + return s; +} + +wxString wxMimeTypeCommands::GetVerbCmd(size_t n) const +{ + return m_verbs[n] + wxT('=') + m_commands[n]; +} + // ---------------------------------------------------------------------------- // wxFileTypeInfo // ---------------------------------------------------------------------------- -wxFileTypeInfo::wxFileTypeInfo(const wxChar *mimeType, - const wxChar *openCmd, - const wxChar *printCmd, - const wxChar *desc, - ...) - : m_mimeType(mimeType), - m_openCmd(openCmd), - m_printCmd(printCmd), - m_desc(desc) +void wxFileTypeInfo::DoVarArgInit(const wxString& mimeType, + const wxString& openCmd, + const wxString& printCmd, + const wxString& desc, + va_list argptr) { - va_list argptr; - va_start(argptr, desc); + m_mimeType = mimeType; + m_openCmd = openCmd; + m_printCmd = printCmd; + m_desc = desc; for ( ;; ) { - const wxChar *ext = va_arg(argptr, const wxChar *); + // icc gives this warning in its own va_arg() macro, argh +#ifdef __INTELC__ + #pragma warning(push) + #pragma warning(disable: 1684) +#endif + + wxArgNormalizedString ext(WX_VA_ARG_STRING(argptr)); + +#ifdef __INTELC__ + #pragma warning(pop) +#endif if ( !ext ) { // NULL terminates the list break; } - m_exts.Add(ext); + m_exts.Add(ext.GetString()); } +} + +void wxFileTypeInfo::VarArgInit(const wxString *mimeType, + const wxString *openCmd, + const wxString *printCmd, + const wxString *desc, + ...) +{ + va_list argptr; + va_start(argptr, desc); + + DoVarArgInit(*mimeType, *openCmd, *printCmd, *desc, argptr); va_end(argptr); } @@ -114,7 +176,7 @@ wxFileTypeInfo::wxFileTypeInfo(const wxArrayString& sArray) } #include "wx/arrimpl.cpp" -WX_DEFINE_OBJARRAY(wxArrayFileTypeInfo); +WX_DEFINE_OBJARRAY(wxArrayFileTypeInfo) // ============================================================================ // implementation of the wrapper classes @@ -130,22 +192,28 @@ wxString wxFileType::ExpandCommand(const wxString& command, { bool hasFilename = false; + // We consider that only the file names with spaces in them need to be + // handled specially. This is not perfect, but this can be done easily + // under all platforms while handling the file names with quotes in them, + // for example, needs to be done differently. + const bool needToQuoteFilename = params.GetFileName().find_first_of(" \t") + != wxString::npos; + wxString str; for ( const wxChar *pc = command.c_str(); *pc != wxT('\0'); pc++ ) { if ( *pc == wxT('%') ) { switch ( *++pc ) { case wxT('s'): - // '%s' expands into file name (quoted because it might - // contain spaces) - except if there are already quotes - // there because otherwise some programs may get confused - // by double double quotes -#if 0 - if ( *(pc - 2) == wxT('"') ) - str << params.GetFileName(); - else + // don't quote the file name if it's already quoted: notice + // that we check for a quote following it and not preceding + // it as at least under Windows we can have commands + // containing "file://%s" (with quotes) in them so the + // argument may be quoted even if there is no quote + // directly before "%s" itself + if ( needToQuoteFilename && pc[1] != '"' ) str << wxT('"') << params.GetFileName() << wxT('"'); -#endif - str << params.GetFileName(); + else + str << params.GetFileName(); hasFilename = true; break; @@ -200,10 +268,16 @@ wxString wxFileType::ExpandCommand(const wxString& command, // test now carried out on reading file so test should never get here if ( !hasFilename && !str.empty() #ifdef __UNIX__ - && !str.StartsWith(_T("test ")) + && !str.StartsWith(wxT("test ")) #endif // Unix - ) { - str << wxT(" < '") << params.GetFileName() << wxT('\''); + ) + { + str << wxT(" < "); + if ( needToQuoteFilename ) + str << '"'; + str << params.GetFileName(); + if ( needToQuoteFilename ) + str << '"'; } return str; @@ -240,7 +314,7 @@ bool wxFileType::GetExtensions(wxArrayString& extensions) bool wxFileType::GetMimeType(wxString *mimeType) const { - wxCHECK_MSG( mimeType, false, _T("invalid parameter in GetMimeType") ); + wxCHECK_MSG( mimeType, false, wxT("invalid parameter in GetMimeType") ); if ( m_info ) { @@ -272,9 +346,9 @@ bool wxFileType::GetIcon(wxIconLocation *iconLoc) const if ( iconLoc ) { iconLoc->SetFileName(m_info->GetIconFile()); -#ifdef __WXMSW__ +#ifdef __WINDOWS__ iconLoc->SetIndex(m_info->GetIconIndex()); -#endif // __WXMSW__ +#endif // __WINDOWS__ } return true; @@ -304,7 +378,7 @@ wxFileType::GetIcon(wxIconLocation *iconloc, bool wxFileType::GetDescription(wxString *desc) const { - wxCHECK_MSG( desc, false, _T("invalid parameter in GetDescription") ); + wxCHECK_MSG( desc, false, wxT("invalid parameter in GetDescription") ); if ( m_info ) { @@ -320,7 +394,7 @@ bool wxFileType::GetOpenCommand(wxString *openCmd, const wxFileType::MessageParameters& params) const { - wxCHECK_MSG( openCmd, false, _T("invalid parameter in GetOpenCommand") ); + wxCHECK_MSG( openCmd, false, wxT("invalid parameter in GetOpenCommand") ); if ( m_info ) { @@ -348,7 +422,7 @@ bool wxFileType::GetPrintCommand(wxString *printCmd, const wxFileType::MessageParameters& params) const { - wxCHECK_MSG( printCmd, false, _T("invalid parameter in GetPrintCommand") ); + wxCHECK_MSG( printCmd, false, wxT("invalid parameter in GetPrintCommand") ); if ( m_info ) { @@ -370,9 +444,9 @@ size_t wxFileType::GetAllCommands(wxArrayString *verbs, if ( commands ) commands->Clear(); -#if defined (__WXMSW__) || defined(__UNIX__) +#if defined (__WINDOWS__) || defined(__UNIX__) return m_impl->GetAllCommands(verbs, commands, params); -#else // !__WXMSW__ || Unix +#else // !__WINDOWS__ || __UNIX__ // we don't know how to retrieve all commands, so just try the 2 we know // about size_t count = 0; @@ -380,7 +454,7 @@ size_t wxFileType::GetAllCommands(wxArrayString *verbs, if ( GetOpenCommand(&cmd, params) ) { if ( verbs ) - verbs->Add(_T("Open")); + verbs->Add(wxT("Open")); if ( commands ) commands->Add(cmd); count++; @@ -389,7 +463,7 @@ size_t wxFileType::GetAllCommands(wxArrayString *verbs, if ( GetPrintCommand(&cmd, params) ) { if ( verbs ) - verbs->Add(_T("Print")); + verbs->Add(wxT("Print")); if ( commands ) commands->Add(cmd); @@ -397,17 +471,17 @@ size_t wxFileType::GetAllCommands(wxArrayString *verbs, } return count; -#endif // __WXMSW__/| __UNIX__ +#endif // __WINDOWS__/| __UNIX__ } bool wxFileType::Unassociate() { -#if defined(__WXMSW__) +#if defined(__WINDOWS__) return m_impl->Unassociate(); #elif defined(__UNIX__) return m_impl->Unassociate(this); #else - wxFAIL_MSG( _T("not implemented") ); // TODO + wxFAIL_MSG( wxT("not implemented") ); // TODO return false; #endif } @@ -416,13 +490,13 @@ bool wxFileType::SetCommand(const wxString& cmd, const wxString& verb, bool overwriteprompt) { -#if defined (__WXMSW__) || defined(__UNIX__) +#if defined (__WINDOWS__) || defined(__UNIX__) return m_impl->SetCommand(cmd, verb, overwriteprompt); #else wxUnusedVar(cmd); wxUnusedVar(verb); wxUnusedVar(overwriteprompt); - wxFAIL_MSG(_T("not implemented")); + wxFAIL_MSG(wxT("not implemented")); return false; #endif } @@ -430,23 +504,50 @@ bool wxFileType::SetCommand(const wxString& cmd, bool wxFileType::SetDefaultIcon(const wxString& cmd, int index) { wxString sTmp = cmd; -#ifdef __WXMSW__ +#ifdef __WINDOWS__ // VZ: should we do this? // chris elliott : only makes sense in MS windows if ( sTmp.empty() ) GetOpenCommand(&sTmp, wxFileType::MessageParameters(wxEmptyString, wxEmptyString)); #endif - wxCHECK_MSG( !sTmp.empty(), false, _T("need the icon file") ); + wxCHECK_MSG( !sTmp.empty(), false, wxT("need the icon file") ); -#if defined (__WXMSW__) || defined(__UNIX__) +#if defined (__WINDOWS__) || defined(__UNIX__) return m_impl->SetDefaultIcon (cmd, index); #else wxUnusedVar(index); - wxFAIL_MSG(_T("not implemented")); + wxFAIL_MSG(wxT("not implemented")); return false; #endif } +// ---------------------------------------------------------------------------- +// wxMimeTypesManagerFactory +// ---------------------------------------------------------------------------- + +wxMimeTypesManagerFactory *wxMimeTypesManagerFactory::m_factory = NULL; + +/* static */ +void wxMimeTypesManagerFactory::Set(wxMimeTypesManagerFactory *factory) +{ + delete m_factory; + + m_factory = factory; +} + +/* static */ +wxMimeTypesManagerFactory *wxMimeTypesManagerFactory::Get() +{ + if ( !m_factory ) + m_factory = new wxMimeTypesManagerFactory; + + return m_factory; +} + +wxMimeTypesManagerImpl *wxMimeTypesManagerFactory::CreateMimeTypesManagerImpl() +{ + return new wxMimeTypesManagerImpl; +} // ---------------------------------------------------------------------------- // wxMimeTypesManager @@ -455,7 +556,7 @@ bool wxFileType::SetDefaultIcon(const wxString& cmd, int index) void wxMimeTypesManager::EnsureImpl() { if ( !m_impl ) - m_impl = new wxMimeTypesManagerImpl; + m_impl = wxMimeTypesManagerFactory::Get()->CreateMimeTypesManagerImpl(); } bool wxMimeTypesManager::IsOfType(const wxString& mimeType, @@ -494,6 +595,8 @@ wxMimeTypesManager::~wxMimeTypesManager() bool wxMimeTypesManager::Unassociate(wxFileType *ft) { + EnsureImpl(); + #if defined(__UNIX__) && !defined(__CYGWIN__) && !defined(__WINE__) return m_impl->Unassociate(ft); #else @@ -507,11 +610,11 @@ wxMimeTypesManager::Associate(const wxFileTypeInfo& ftInfo) { EnsureImpl(); -#if defined(__WXMSW__) || defined(__UNIX__) +#if defined(__WINDOWS__) || defined(__UNIX__) return m_impl->Associate(ftInfo); #else // other platforms wxUnusedVar(ftInfo); - wxFAIL_MSG( _T("not implemented") ); // TODO + wxFAIL_MSG( wxT("not implemented") ); // TODO return NULL; #endif // platforms } @@ -520,7 +623,18 @@ wxFileType * wxMimeTypesManager::GetFileTypeFromExtension(const wxString& ext) { EnsureImpl(); - wxFileType *ft = m_impl->GetFileTypeFromExtension(ext); + + wxString::const_iterator i = ext.begin(); + const wxString::const_iterator end = ext.end(); + wxString extWithoutDot; + if ( i != end && *i == '.' ) + extWithoutDot.assign(++i, ext.end()); + else + extWithoutDot = ext; + + wxCHECK_MSG( !ext.empty(), NULL, wxT("extension can't be empty") ); + + wxFileType *ft = m_impl->GetFileTypeFromExtension(extWithoutDot); if ( !ft ) { // check the fallbacks @@ -565,18 +679,6 @@ wxMimeTypesManager::GetFileTypeFromMimeType(const wxString& mimeType) return ft; } -bool wxMimeTypesManager::ReadMailcap(const wxString& filename, bool fallback) -{ - EnsureImpl(); - return m_impl->ReadMailcap(filename, fallback); -} - -bool wxMimeTypesManager::ReadMimeTypes(const wxString& filename) -{ - EnsureImpl(); - return m_impl->ReadMimeTypes(filename); -} - void wxMimeTypesManager::AddFallbacks(const wxFileTypeInfo *filetypes) { EnsureImpl(); @@ -639,14 +741,15 @@ class wxMimeTypeCmnModule: public wxModule { public: wxMimeTypeCmnModule() : wxModule() { } + virtual bool OnInit() { return true; } virtual void OnExit() { - // this avoids false memory leak allerts: + wxMimeTypesManagerFactory::Set(NULL); + if ( gs_mimeTypesManager.m_impl != NULL ) { - delete gs_mimeTypesManager.m_impl; - gs_mimeTypesManager.m_impl = NULL; + wxDELETE(gs_mimeTypesManager.m_impl); gs_mimeTypesManager.m_fallbacks.Clear(); } }