X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c7ce8392e0fa752d121000b7732c8f4ac3e3088d..dd91da4ed1e9d2ba5d3bc2fae64a8e4ea86b5d41:/src/common/mimecmn.cpp diff --git a/src/common/mimecmn.cpp b/src/common/mimecmn.cpp index 8bf7953030..bffbdd0d96 100644 --- a/src/common/mimecmn.cpp +++ b/src/common/mimecmn.cpp @@ -10,23 +10,32 @@ // Licence: wxWindows license (part of wxExtra library) ///////////////////////////////////////////////////////////////////////////// +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + #ifdef __GNUG__ -#pragma implementation "mimetypebase.h" + #pragma implementation "mimetypebase.h" #endif // for compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" -#include "wx/module.h" #ifdef __BORLANDC__ - #pragma hdrstop + #pragma hdrstop #endif +#if wxUSE_MIMETYPE + #ifndef WX_PRECOMP - #include "wx/defs.h" + #include "wx/module.h" #endif - -#if (wxUSE_FILE && wxUSE_TEXTFILE) || defined(__WXMSW__) +// this one is needed for MSVC5 +#include "wx/module.h" #ifndef WX_PRECOMP #include "wx/string.h" @@ -35,42 +44,23 @@ #endif #endif //WX_PRECOMP -// Doesn't compile in WIN16 mode -#ifndef __WIN16__ - #include "wx/log.h" #include "wx/file.h" #include "wx/intl.h" #include "wx/dynarray.h" #include "wx/confbase.h" -#ifdef __WXMSW__ - #include "wx/msw/registry.h" - #include "windows.h" -#elif defined(__UNIX__) || defined(__WXPM__) - #include "wx/ffile.h" - #include "wx/textfile.h" - #include "wx/dir.h" - #include "wx/utils.h" - #include "wx/tokenzr.h" -#endif // OS - #include "wx/mimetype.h" // other standard headers #include -// in case we're compiling in non-GUI mode -class WXDLLEXPORT wxIcon; - - // implementation classes: - #if defined(__WXMSW__) #include "wx/msw/mimetype.h" -#elif defined (__WXMAC__) +#elif defined(__WXMAC__) #include "wx/mac/mimetype.h" -#elif defined (__WXPM__) +#elif defined(__WXPM__) #include "wx/os2/mimetype.h" #else // Unix #include "wx/unix/mimetype.h" @@ -84,10 +74,10 @@ class WXDLLEXPORT wxIcon; // wxFileTypeInfo // ---------------------------------------------------------------------------- -wxFileTypeInfo::wxFileTypeInfo(const char *mimeType, - const char *openCmd, - const char *printCmd, - const char *desc, +wxFileTypeInfo::wxFileTypeInfo(const wxChar *mimeType, + const wxChar *openCmd, + const wxChar *printCmd, + const wxChar *desc, ...) : m_mimeType(mimeType), m_openCmd(openCmd), @@ -99,7 +89,7 @@ wxFileTypeInfo::wxFileTypeInfo(const char *mimeType, for ( ;; ) { - const char *ext = va_arg(argptr, const char *); + const wxChar *ext = va_arg(argptr, const wxChar *); if ( !ext ) { // NULL terminates the list @@ -112,10 +102,24 @@ wxFileTypeInfo::wxFileTypeInfo(const char *mimeType, va_end(argptr); } + +wxFileTypeInfo::wxFileTypeInfo(const wxArrayString& sArray) +{ + m_mimeType = sArray [0u]; + m_openCmd = sArray [1u]; + m_printCmd = sArray [2u]; + m_desc = sArray [3u]; + + size_t count = sArray.GetCount(); + for ( size_t i = 4; i < count; i++ ) + { + m_exts.Add(sArray[i]); + } +} + #include "wx/arrimpl.cpp" WX_DEFINE_OBJARRAY(wxArrayFileTypeInfo); - // ============================================================================ // implementation of the wrapper classes // ============================================================================ @@ -124,6 +128,7 @@ WX_DEFINE_OBJARRAY(wxArrayFileTypeInfo); // wxFileType // ---------------------------------------------------------------------------- +/* static */ wxString wxFileType::ExpandCommand(const wxString& command, const wxFileType::MessageParameters& params) { @@ -195,6 +200,8 @@ wxString wxFileType::ExpandCommand(const wxString& command, // behave like this, in particular a common test is 'test -n "$DISPLAY"' // and appending "< %s" to this command makes the test fail... I don't // know of the correct solution, try to guess what we have to do. + + // test now carried out on reading file so test should never get here if ( !hasFilename && !str.IsEmpty() #ifdef __UNIX__ && !str.StartsWith(_T("test ")) @@ -206,28 +213,59 @@ wxString wxFileType::ExpandCommand(const wxString& command, return str; } +wxFileType::wxFileType(const wxFileTypeInfo& info) +{ + m_info = &info; + m_impl = NULL; +} + wxFileType::wxFileType() { + m_info = NULL; m_impl = new wxFileTypeImpl; } wxFileType::~wxFileType() { - delete m_impl; + if ( m_impl ) + delete m_impl; } bool wxFileType::GetExtensions(wxArrayString& extensions) { + if ( m_info ) + { + extensions = m_info->GetExtensions(); + return TRUE; + } + return m_impl->GetExtensions(extensions); } bool wxFileType::GetMimeType(wxString *mimeType) const { + wxCHECK_MSG( mimeType, FALSE, _T("invalid parameter in GetMimeType") ); + + if ( m_info ) + { + *mimeType = m_info->GetMimeType(); + + return TRUE; + } + return m_impl->GetMimeType(mimeType); } bool wxFileType::GetMimeTypes(wxArrayString& mimeTypes) const { + if ( m_info ) + { + mimeTypes.Clear(); + mimeTypes.Add(m_info->GetMimeType()); + + return TRUE; + } + return m_impl->GetMimeTypes(mimeTypes); } @@ -235,7 +273,25 @@ bool wxFileType::GetIcon(wxIcon *icon, wxString *iconFile, int *iconIndex) const { -#ifdef __WXMSW__ + if ( m_info ) + { + if ( iconFile ) + *iconFile = m_info->GetIconFile(); + if ( iconIndex ) + *iconIndex = m_info->GetIconIndex(); + +#if wxUSE_GUI + if ( icon && !m_info->GetIconFile().empty() ) + { + // FIXME: what about the index? + icon->LoadFile(m_info->GetIconFile()); + } +#endif // wxUSE_GUI + + return TRUE; + } + +#if defined(__WXMSW__) || defined(__UNIX__) return m_impl->GetIcon(icon, iconFile, iconIndex); #else return m_impl->GetIcon(icon); @@ -244,6 +300,15 @@ bool wxFileType::GetIcon(wxIcon *icon, bool wxFileType::GetDescription(wxString *desc) const { + wxCHECK_MSG( desc, FALSE, _T("invalid parameter in GetDescription") ); + + if ( m_info ) + { + *desc = m_info->GetDescription(); + + return TRUE; + } + return m_impl->GetDescription(desc); } @@ -251,13 +316,43 @@ bool wxFileType::GetOpenCommand(wxString *openCmd, const wxFileType::MessageParameters& params) const { + wxCHECK_MSG( openCmd, FALSE, _T("invalid parameter in GetOpenCommand") ); + + if ( m_info ) + { + *openCmd = ExpandCommand(m_info->GetOpenCommand(), params); + + return TRUE; + } + return m_impl->GetOpenCommand(openCmd, params); } +wxString wxFileType::GetOpenCommand(const wxString& filename) const +{ + wxString cmd; + if ( !GetOpenCommand(&cmd, filename) ) + { + // return empty string to indicate an error + cmd.clear(); + } + + return cmd; +} + bool wxFileType::GetPrintCommand(wxString *printCmd, const wxFileType::MessageParameters& params) const { + wxCHECK_MSG( printCmd, FALSE, _T("invalid parameter in GetPrintCommand") ); + + if ( m_info ) + { + *printCmd = ExpandCommand(m_info->GetPrintCommand(), params); + + return TRUE; + } + return m_impl->GetPrintCommand(printCmd, params); } @@ -271,14 +366,14 @@ size_t wxFileType::GetAllCommands(wxArrayString *verbs, if ( commands ) commands->Clear(); -#ifdef __WXMSW__ +#if defined (__WXMSW__) || defined(__UNIX__) return m_impl->GetAllCommands(verbs, commands, params); -#else // !__WXMSW__ +#else // !__WXMSW__ || Unix // we don't know how to retrieve all commands, so just try the 2 we know // about size_t count = 0; wxString cmd; - if ( m_impl->GetOpenCommand(&cmd, params) ) + if ( GetOpenCommand(&cmd, params) ) { if ( verbs ) verbs->Add(_T("Open")); @@ -298,36 +393,28 @@ size_t wxFileType::GetAllCommands(wxArrayString *verbs, } return count; -#endif // __WXMSW__/!__WXMSW__ +#endif // __WXMSW__/| __UNIX__ } -bool wxFileType::SetOpenCommand(const wxString& cmd, bool overwriteprompt) -{ - return SetCommand(cmd, _T("open"), overwriteprompt); -} - -bool wxFileType::SetCommand(const wxString& cmd, const wxString& verb, - bool overwriteprompt) +bool wxFileType::Unassociate() { -#ifdef __WXMSW__ - return m_impl->SetCommand(cmd, verb, overwriteprompt); +#if defined(__WXMSW__) + return m_impl->Unassociate(); +#elif defined(__UNIX__) && !defined(__WXPM__) + return m_impl->Unassociate(this); #else - wxFAIL_MSG(_T("not implemented")); - + wxFAIL_MSG( _T("not implemented") ); // TODO return FALSE; #endif } -bool wxFileType::SetMimeType(const wxString& mimeType) +bool wxFileType::SetCommand(const wxString& cmd, const wxString& verb, +bool overwriteprompt) { - // empty MIME type is meaningless here - wxCHECK_MSG( !mimeType.empty(), FALSE, _T("use RemoveMimeType()") ); - -#ifdef __WXMSW__ - return m_impl->SetMimeType(mimeType); +#if defined (__WXMSW__) || defined(__UNIX__) + return m_impl->SetCommand(cmd, verb, overwriteprompt); #else wxFAIL_MSG(_T("not implemented")); - return FALSE; #endif } @@ -335,54 +422,16 @@ bool wxFileType::SetMimeType(const wxString& mimeType) bool wxFileType::SetDefaultIcon(const wxString& cmd, int index) { wxString sTmp = cmd; +#ifdef __WXMSW__ // VZ: should we do this? + // chris elliott : only makes sense in MS windows if ( sTmp.empty() ) - GetOpenCommand(&sTmp, wxFileType::MessageParameters("", "")); - - wxCHECK_MSG( !sTmp.empty(), false, _T("need the icon file") ); - - -#ifdef __WXMSW__ - return m_impl->SetDefaultIcon (cmd, index); -#else - wxFAIL_MSG(_T("not implemented")); - - return FALSE; + GetOpenCommand(&sTmp, wxFileType::MessageParameters(wxT(""), wxT(""))); #endif -} + wxCHECK_MSG( !sTmp.empty(), FALSE, _T("need the icon file") ); -// now do remove functions -bool wxFileType::RemoveOpenCommand() -{ - return RemoveCommand(_T("open")); -} - -bool wxFileType::RemoveCommand(const wxString& verb) -{ -#ifdef __WXMSW__ - return m_impl->RemoveCommand(verb); -#else - wxFAIL_MSG(_T("not implemented")); - - return FALSE; -#endif -} - -bool wxFileType::RemoveMimeType() -{ -#ifdef __WXMSW__ - return m_impl->RemoveMimeType (); -#else - wxFAIL_MSG(_T("not implemented")); - - return FALSE; -#endif -} - -bool wxFileType::RemoveDefaultIcon() -{ -#ifdef __WXMSW__ - return m_impl->RemoveDefaultIcon(); +#if defined (__WXMSW__) || defined(__UNIX__) + return m_impl->SetDefaultIcon (cmd, index); #else wxFAIL_MSG(_T("not implemented")); @@ -390,19 +439,6 @@ bool wxFileType::RemoveDefaultIcon() #endif } -bool wxFileType::Unassociate() -{ - bool result = TRUE; - if ( !RemoveOpenCommand() ) - result = FALSE; - if ( !RemoveDefaultIcon() ) - result = FALSE; - if ( !RemoveMimeType() ) - result = FALSE; - - // in MSW this leaves a HKCR.xzy key - return result; -} // ---------------------------------------------------------------------------- // wxMimeTypesManager @@ -421,7 +457,8 @@ bool wxMimeTypesManager::IsOfType(const wxString& mimeType, wxT("first MIME type can't contain wildcards") ); // all comparaisons are case insensitive (2nd arg of IsSameAs() is FALSE) - if ( wildcard.BeforeFirst(wxT('/')).IsSameAs(mimeType.BeforeFirst(wxT('/')), FALSE) ) + if ( wildcard.BeforeFirst(wxT('/')). + IsSameAs(mimeType.BeforeFirst(wxT('/')), FALSE) ) { wxString strSubtype = wildcard.AfterFirst(wxT('/')); @@ -443,49 +480,80 @@ wxMimeTypesManager::wxMimeTypesManager() wxMimeTypesManager::~wxMimeTypesManager() { - delete m_impl; + if ( m_impl ) + delete m_impl; } +bool wxMimeTypesManager::Unassociate(wxFileType *ft) +{ +#if defined(__UNIX__) && !defined(__WXPM__) && !defined(__CYGWIN__) && !defined(__WINE__) + return m_impl->Unassociate(ft); +#else + return ft->Unassociate(); +#endif +} + + wxFileType * -wxMimeTypesManager::GetFileTypeFromExtension(const wxString& ext) +wxMimeTypesManager::Associate(const wxFileTypeInfo& ftInfo) { EnsureImpl(); - return m_impl->GetFileTypeFromExtension(ext); + +#if defined(__WXMSW__) || (defined(__UNIX__) && !defined(__WXPM__)) + return m_impl->Associate(ftInfo); +#else // other platforms + wxFAIL_MSG( _T("not implemented") ); // TODO + return NULL; +#endif // platforms } wxFileType * -wxMimeTypesManager::GetOrAllocateFileTypeFromExtension(const wxString& ext) +wxMimeTypesManager::GetFileTypeFromExtension(const wxString& ext) { EnsureImpl(); + wxFileType *ft = m_impl->GetFileTypeFromExtension(ext); + + if ( !ft ) { + // check the fallbacks + // + // TODO linear search is potentially slow, perhaps we should use a + // sorted array? + size_t count = m_fallbacks.GetCount(); + for ( size_t n = 0; n < count; n++ ) { + if ( m_fallbacks[n].GetExtensions().Index(ext) != wxNOT_FOUND ) { + ft = new wxFileType(m_fallbacks[n]); + + break; + } + } + } -#ifdef __WXMSW__ - // this writes a root entry to the registry in HKCR.ext - return m_impl->GetOrAllocateFileTypeFromExtension(ext); -#else // !__WXMSW__ - // VZ: "static const"??? (FIXME) - // just make a dummy entry with no writing to file - static const wxFileTypeInfo fallback[] = - { - wxFileTypeInfo("application/x-" + ext, - "", - "", - ext + " format file", - ext, NULL), - // must terminate the table with this! - wxFileTypeInfo() - }; - - AddFallbacks (fallback); - return m_impl->GetFileTypeFromExtension(ext); -#endif // __WXMSW__/!__WXMSW__ + return ft; } - wxFileType * wxMimeTypesManager::GetFileTypeFromMimeType(const wxString& mimeType) { EnsureImpl(); - return m_impl->GetFileTypeFromMimeType(mimeType); + wxFileType *ft = m_impl->GetFileTypeFromMimeType(mimeType); + + if ( ft ) { + // check the fallbacks + // + // TODO linear search is potentially slow, perhaps we should use a sorted + // array? + size_t count = m_fallbacks.GetCount(); + for ( size_t n = 0; n < count; n++ ) { + if ( wxMimeTypesManager::IsOfType(mimeType, + m_fallbacks[n].GetMimeType()) ) { + ft = new wxFileType(m_fallbacks[n]); + + break; + } + } + } + + return ft; } bool wxMimeTypesManager::ReadMailcap(const wxString& filename, bool fallback) @@ -503,27 +571,60 @@ bool wxMimeTypesManager::ReadMimeTypes(const wxString& filename) void wxMimeTypesManager::AddFallbacks(const wxFileTypeInfo *filetypes) { EnsureImpl(); - for ( const wxFileTypeInfo *ft = filetypes; ft->IsValid(); ft++ ) { - m_impl->AddFallback(*ft); + for ( const wxFileTypeInfo *ft = filetypes; ft && ft->IsValid(); ft++ ) { + AddFallback(*ft); } } size_t wxMimeTypesManager::EnumAllFileTypes(wxArrayString& mimetypes) { EnsureImpl(); - return m_impl->EnumAllFileTypes(mimetypes); + size_t countAll = m_impl->EnumAllFileTypes(mimetypes); + + // add the fallback filetypes + size_t count = m_fallbacks.GetCount(); + for ( size_t n = 0; n < count; n++ ) { + if ( mimetypes.Index(m_fallbacks[n].GetMimeType()) == wxNOT_FOUND ) { + mimetypes.Add(m_fallbacks[n].GetMimeType()); + countAll++; + } + } + + return countAll; +} + +void wxMimeTypesManager::Initialize(int mcapStyle, + const wxString& sExtraDir) +{ +#if defined(__UNIX__) && !defined(__WXPM__) && !defined(__CYGWIN__) && !defined(__WINE__) + EnsureImpl(); + + m_impl->Initialize(mcapStyle, sExtraDir); +#else + (void)mcapStyle; + (void)sExtraDir; +#endif // Unix } +// and this function clears all the data from the manager +void wxMimeTypesManager::ClearData() +{ +#if defined(__UNIX__) && !defined(__WXPM__) && !defined(__CYGWIN__) && !defined(__WINE__) + EnsureImpl(); + + m_impl->ClearData(); +#endif // Unix +} // ---------------------------------------------------------------------------- -// global data +// global data and wxMimeTypeCmnModule // ---------------------------------------------------------------------------- // private object static wxMimeTypesManager gs_mimeTypesManager; // and public pointer -wxMimeTypesManager * wxTheMimeTypesManager = &gs_mimeTypesManager; +wxMimeTypesManager *wxTheMimeTypesManager = &gs_mimeTypesManager; class wxMimeTypeCmnModule: public wxModule { @@ -537,6 +638,7 @@ public: { delete gs_mimeTypesManager.m_impl; gs_mimeTypesManager.m_impl = NULL; + gs_mimeTypesManager.m_fallbacks.Clear(); } } @@ -545,8 +647,4 @@ public: IMPLEMENT_DYNAMIC_CLASS(wxMimeTypeCmnModule, wxModule) -#endif - // wxUSE_FILE && wxUSE_TEXTFILE - -#endif - // __WIN16__ +#endif // wxUSE_MIMETYPE