X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/dd9b4b7f114427e2fc089c4f1b2d4d43d7b003d4..aacd14428971b5e199f88597f76a895c68dd298f:/src/mac/carbon/mimetmac.cpp diff --git a/src/mac/carbon/mimetmac.cpp b/src/mac/carbon/mimetmac.cpp index 87a187113c..9c0f3be67b 100644 --- a/src/mac/carbon/mimetmac.cpp +++ b/src/mac/carbon/mimetmac.cpp @@ -9,6 +9,23 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// +// +// +// TODO: Search Info[-macos](classic).plist dictionary in addition +// to Internet Config database. +// +// Maybe try a brainstorm a way to change the wxMimeTypesManager API +// to get info from a file instead/addition to current get all stuff +// API so that we can use Launch Services to get mime type info. +// +// Implement geticon from one of the finder info functions - or +// use launch services and search that app's plist for the icon. +// +// Put some special juice in for the print command. +// +// +// + #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "mimetype.h" #endif @@ -567,6 +584,15 @@ void wxMimeTypesManagerImpl::Initialize(int mailcapStyles, const wxString& extra { wxASSERT_MSG(m_hIC == NULL, wxT("Already initialized wxMimeTypesManager!")); + //some apps (non-wx) use the 'plst' resource instead +/* + CFBundleRef cfbMain = CFBundleGetMainBundle(); + wxCFDictionary cfdInfo( CFBundleGetInfoDictionary(cfbMain), wxCF_RETAIN ); + wxString sLog; + cfdInfo.PrintOut(sLog); + wxLogDebug(sLog); +*/ + //start internet config - log if there's an error //the second param is the signature of the application, also known //as resource ID 0. However, as per some recent discussions, we may not @@ -754,11 +780,542 @@ pascal OSStatus MoreProcGetProcessTypeSignature( return anErr; }//end MoreProcGetProcessTypeSignature -#include "wx/mac/corefoundation/cfwrappers.h" +// +// +// TODO: clean this up, its messy +// +// +// + +#include "wx/mac/corefoundation/cfstring.h" +#include "wx/intl.h" //wxLocale for wxCFString -void wxCFDictionary::MakeValidXML() +#define wxCF_RELEASE true +#define wxCF_RETAIN false + +// ---------------------------------------------------------------------------- +// wxCFDictionary +// ---------------------------------------------------------------------------- + +class wxCFDictionary +{ +public: + wxCFDictionary(CFTypeRef ref, bool bRetain = wxCF_RELEASE) + { + m_cfmdRef = (CFMutableDictionaryRef) ref; + if(bRetain == wxCF_RETAIN && ref) + CFRetain(ref); + } + + wxCFDictionary(CFIndex cfiSize = 0) + { + CFDictionaryKeyCallBacks kcbs; + CFDictionaryValueCallBacks vcbs; + BuildKeyCallbacks(&kcbs); + BuildValueCallbacks(&vcbs); + + m_cfmdRef = CFDictionaryCreateMutable( + kCFAllocatorDefault, cfiSize, &kcbs, &vcbs); + + } + + ~wxCFDictionary() + { Clear(); } + + void Clear() + {if(m_cfmdRef) CFRelease(m_cfmdRef);} + + static const void* RetainProc(CFAllocatorRef, const void* v) + { return (const void*) CFRetain(v); } + + static void ReleaseProc(CFAllocatorRef, const void* v) + { CFRelease(v); } + + void MakeMutable(CFIndex cfiSize = 0) + { + CFDictionaryRef oldref = (CFDictionaryRef) m_cfmdRef; + + m_cfmdRef = CFDictionaryCreateMutableCopy( + kCFAllocatorDefault, + cfiSize, + oldref); + + CFRelease(oldref); + } + + void BuildKeyCallbacks(CFDictionaryKeyCallBacks* pCbs) + { + pCbs->version = 0; + pCbs->retain = RetainProc; + pCbs->release = ReleaseProc; + pCbs->copyDescription = NULL; + pCbs->equal = NULL; + pCbs->hash = NULL; + } + + void BuildValueCallbacks(CFDictionaryValueCallBacks* pCbs) + { + pCbs->version = 0; + pCbs->retain = RetainProc; + pCbs->release = ReleaseProc; + pCbs->copyDescription = NULL; + pCbs->equal = NULL; + } + + operator CFTypeRef () const + { return (CFTypeRef)m_cfmdRef; } + + CFDictionaryRef GetCFDictionary() const + { return (CFDictionaryRef)m_cfmdRef; } + + CFMutableDictionaryRef GetCFMutableDictionary() + { return (CFMutableDictionaryRef) m_cfmdRef; } + + CFTypeRef operator [] (CFTypeRef cftEntry) const + { + wxASSERT(IsValid()); + return (CFTypeRef) CFDictionaryGetValue((CFDictionaryRef)m_cfmdRef, cftEntry); + } + + CFIndex GetCount() const + { + wxASSERT(IsValid()); + return CFDictionaryGetCount((CFDictionaryRef)m_cfmdRef); + } + + void Add(CFTypeRef cftKey, CFTypeRef cftValue) + { + wxASSERT(IsValid()); + wxASSERT(Exists(cftKey) == false); + CFDictionaryAddValue(m_cfmdRef, cftKey, cftValue); + } + + void Remove(CFTypeRef cftKey) + { + wxASSERT(IsValid()); + wxASSERT(Exists(cftKey)); + CFDictionaryRemoveValue(m_cfmdRef, cftKey); + } + + void Set(CFTypeRef cftKey, CFTypeRef cftValue) + { + wxASSERT(IsValid()); + wxASSERT(Exists(cftKey)); + CFDictionarySetValue(m_cfmdRef, cftKey, cftValue); + } + + bool Exists(CFTypeRef cftKey) const + { + wxASSERT(IsValid()); + return CFDictionaryContainsKey((CFDictionaryRef)m_cfmdRef, cftKey) == true; + } + + bool IsOk() const {return m_cfmdRef != NULL; } + + bool IsValid() const + { + return IsOk() && CFGetTypeID((CFTypeRef)m_cfmdRef) == CFDictionaryGetTypeID(); + } + + void PrintOut(wxString& sMessage) + { + PrintOutDictionary(sMessage, m_cfmdRef); + } + + static void PrintOutDictionary(wxString& sMessage, CFDictionaryRef cfdRef) + { + CFIndex cfiCount = CFDictionaryGetCount(cfdRef); + CFTypeRef* pKeys = new CFTypeRef[cfiCount]; + CFTypeRef* pValues = new CFTypeRef[cfiCount]; + + CFDictionaryGetKeysAndValues(cfdRef, pKeys, pValues); + + for(CFIndex i = 0; i < cfiCount; ++i) + { + wxString sKey = wxMacCFStringHolder(CFCopyTypeIDDescription(CFGetTypeID(pKeys[i]))).AsString(); + wxString sValue = wxMacCFStringHolder(CFCopyTypeIDDescription(CFGetTypeID(pValues[i]))).AsString(); + + sMessage << + wxString::Format(wxT("[{#%d} Key : %s]"), (int) i, + sKey.c_str()); + + PrintOutType(sMessage, sKey, pKeys[i]); + + sMessage << + wxString::Format(wxT("\n\t[Value : %s]"), + sValue.c_str()); + + PrintOutType(sMessage, sValue, pValues[i]); + + sMessage << wxT("\n"); + } + + delete[] pKeys; + delete[] pValues; + } + + static void PrintOutArray(wxString& sMessage, CFArrayRef cfaRef) + { + + for(CFIndex i = 0; i < CFArrayGetCount(cfaRef); ++i) + { + wxString sValue = wxMacCFStringHolder(CFCopyTypeIDDescription(CFGetTypeID( + CFArrayGetValueAtIndex(cfaRef, i) + ))).AsString(); + + sMessage << + wxString::Format(wxT("\t\t[{#%d} ArrayValue : %s]\n"), (int) i, + sValue.c_str()); + + PrintOutType(sMessage, sValue, CFArrayGetValueAtIndex(cfaRef, i)); + } + } + + static void PrintOutType(wxString& sMessage, wxString sValue, CFTypeRef cfRef) + { + sMessage << wxT(" {"); + + if(sValue == wxT("CFString")) + { + sMessage << wxMacCFStringHolder((CFStringRef)cfRef, false).AsString(); + } + else if(sValue == wxT("CFNumber")) + { + int nOut; + CFNumberGetValue((CFNumberRef)cfRef, kCFNumberIntType, &nOut); + sMessage << nOut; + } + else if(sValue == wxT("CFDictionary")) + { + PrintOutDictionary(sMessage, (CFDictionaryRef)cfRef); + } + else if(sValue == wxT("CFArray")) + { + PrintOutArray(sMessage, (CFArrayRef)cfRef); + } + else if(sValue == wxT("CFBoolean")) + { + sMessage << (cfRef == kCFBooleanTrue ? wxT("true") : wxT("false")); + } + else if(sValue == wxT("CFURL")) + { + sMessage << wxMacCFStringHolder(CFURLCopyPath((CFURLRef) cfRef)).AsString(); + } + else + { + sMessage << wxT("*****UNKNOWN TYPE******"); + } + + sMessage << wxT("} "); + } + +#if wxUSE_MIMETYPE + void MakeValidXML(); +#endif + + CFTypeRef WriteAsXML() + { + return CFPropertyListCreateXMLData(kCFAllocatorDefault, m_cfmdRef); + } + + bool ReadAsXML(CFTypeRef cfData, wxString* pErrorMsg = NULL) + { + Clear(); + CFStringRef cfsError=NULL; + m_cfmdRef = (CFMutableDictionaryRef) CFPropertyListCreateFromXMLData( + kCFAllocatorDefault, + (CFDataRef)cfData, + kCFPropertyListMutableContainersAndLeaves, + &cfsError ); + if(cfsError) + { + if(pErrorMsg) + *pErrorMsg = wxMacCFStringHolder(cfsError).AsString(); + else + CFRelease(cfsError); + } + + return m_cfmdRef != NULL; + } + private: + CFMutableDictionaryRef m_cfmdRef; +}; + +// ---------------------------------------------------------------------------- +// wxCFArray +// ---------------------------------------------------------------------------- + +class wxCFArray +{ +public: + wxCFArray(CFTypeRef ref, bool bRetain = wxCF_RELEASE) + { + m_cfmaRef = (CFMutableArrayRef)ref; + if(bRetain == wxCF_RETAIN && ref) + CFRetain(ref); + } + + wxCFArray(CFIndex cfiSize = 0) : m_cfmaRef(NULL) + { Create(cfiSize); } + + ~wxCFArray() + { Clear(); } + + void MakeMutable(CFIndex cfiSize = 0) + { + wxASSERT(IsValid()); + + CFMutableArrayRef oldref = m_cfmaRef; + m_cfmaRef = CFArrayCreateMutableCopy( + kCFAllocatorDefault, + cfiSize, + (CFArrayRef)oldref); + CFRelease(oldref); + } + + void BuildCallbacks(CFArrayCallBacks* pCbs) + { + pCbs->version = 0; + pCbs->retain = RetainProc; + pCbs->release = ReleaseProc; + pCbs->copyDescription = NULL; + pCbs->equal = NULL; + } + + void Create(CFIndex cfiSize = 0) + { + Clear(); + CFArrayCallBacks cb; + BuildCallbacks(&cb); + + m_cfmaRef = CFArrayCreateMutable(kCFAllocatorDefault, cfiSize, &cb); + } + + void Clear() + {if(m_cfmaRef) CFRelease(m_cfmaRef);} + + static const void* RetainProc(CFAllocatorRef, const void* v) + { return (const void*) CFRetain(v); } + + static void ReleaseProc(CFAllocatorRef, const void* v) + { CFRelease(v); } + + operator CFTypeRef () const + { return (CFTypeRef)m_cfmaRef; } + + CFArrayRef GetCFArray() const + { return (CFArrayRef)m_cfmaRef; } + + CFMutableArrayRef GetCFMutableArray() + { return (CFMutableArrayRef) m_cfmaRef; } + + CFTypeRef operator [] (CFIndex cfiIndex) const + { + wxASSERT(IsValid()); + return (CFTypeRef) CFArrayGetValueAtIndex((CFArrayRef)m_cfmaRef, cfiIndex); + } + + CFIndex GetCount() + { + wxASSERT(IsValid()); + return CFArrayGetCount((CFArrayRef)m_cfmaRef); + } + + void Add(CFTypeRef cftValue) + { + wxASSERT(IsValid()); + CFArrayAppendValue(m_cfmaRef, cftValue); + } + + void Remove(CFIndex cfiIndex) + { + wxASSERT(IsValid()); + wxASSERT(cfiIndex < GetCount()); + CFArrayRemoveValueAtIndex(m_cfmaRef, cfiIndex); + } + + void Set(CFIndex cfiIndex, CFTypeRef cftValue) + { + wxASSERT(IsValid()); + wxASSERT(cfiIndex < GetCount()); + CFArraySetValueAtIndex(m_cfmaRef, cfiIndex, cftValue); + } + + bool IsOk() const {return m_cfmaRef != NULL; } + + bool IsValid() const + { + return IsOk() && CFGetTypeID((CFTypeRef)m_cfmaRef) == CFArrayGetTypeID(); + } + +#if wxUSE_MIMETYPE + void MakeValidXML(); +#endif + +private: + CFMutableArrayRef m_cfmaRef; +}; + +// ---------------------------------------------------------------------------- +// wxCFString +// ---------------------------------------------------------------------------- + +class wxCFString +{ +public: + wxCFString(CFTypeRef ref, bool bRetain = wxCF_RELEASE) : m_Holder((CFStringRef)ref, bRetain == wxCF_RELEASE) + { } + + wxCFString(const wxChar* szString) : m_Holder(wxString(szString), wxLocale::GetSystemEncoding()) + { } + + wxCFString(const wxString& sString) : m_Holder(sString, wxLocale::GetSystemEncoding()) + { } + + operator CFTypeRef() const + {return (CFTypeRef) ((CFStringRef) m_Holder); } + + bool IsOk() { return ((CFTypeRef)(*this)) != NULL; } + + wxString BuildWXString() {return m_Holder.AsString(); } + +private: + wxMacCFStringHolder m_Holder; +}; + +// ---------------------------------------------------------------------------- +// wxCFNumber +// ---------------------------------------------------------------------------- + +class wxCFNumber +{ +public: + wxCFNumber(int nValue) + { + m_cfnRef = CFNumberCreate(kCFAllocatorDefault, + kCFNumberIntType, &nValue); + } + + wxCFNumber(CFTypeRef ref, bool bRetain = wxCF_RELEASE) : m_cfnRef((CFNumberRef)ref) + { + if(bRetain == wxCF_RETAIN && ref) + CFRetain(ref); + } + + ~wxCFNumber() + { if(m_cfnRef) CFRelease(m_cfnRef); } + + + operator CFTypeRef() const + { return (CFTypeRef) m_cfnRef; } + + int GetValue() + { + int nOut; + CFNumberGetValue( + m_cfnRef, + kCFNumberIntType, + &nOut + ); + + return nOut; + } + + bool IsOk() { return m_cfnRef != NULL; } + +private: + CFNumberRef m_cfnRef; +}; + +// ---------------------------------------------------------------------------- +// wxCFURL +// ---------------------------------------------------------------------------- + +class wxCFURL +{ +public: + wxCFURL(CFTypeRef ref = NULL, bool bRetain = wxCF_RELEASE) : m_cfurlRef((CFURLRef)ref) + { + if(bRetain == wxCF_RETAIN && ref) + CFRetain(ref); + } + wxCFURL(const wxCFString& URLString, CFTypeRef BaseURL = NULL) + { + Create(URLString, BaseURL); + } + + void Create(const wxCFString& URLString, CFTypeRef BaseURL = NULL) + { + m_cfurlRef = CFURLCreateWithString( + kCFAllocatorDefault, + (CFStringRef)(CFTypeRef)URLString, + (CFURLRef) BaseURL); + } + + ~wxCFURL() {if(m_cfurlRef) CFRelease(m_cfurlRef);} + + wxString BuildWXString() + { + return wxCFString(CFURLCopyPath(m_cfurlRef)).BuildWXString(); + } + + operator CFTypeRef() const + { return (CFTypeRef)m_cfurlRef; } + + bool IsOk() { return m_cfurlRef != NULL; } +private: + CFURLRef m_cfurlRef; +}; + +// ---------------------------------------------------------------------------- +// wxCFData +// ---------------------------------------------------------------------------- + +#define wxCFDATA_RELEASEBUFFER 1 +#define wxCFDATA_RETAINBUFFER 0 + +class wxCFData { +public: + wxCFData(CFTypeRef ref, bool bRetain = wxCF_RELEASE) : m_cfdaRef((CFDataRef)ref) { + if(bRetain == wxCF_RETAIN && ref) + CFRetain(ref); + } + wxCFData(const UInt8* pBytes, CFIndex len, bool bKeep = wxCFDATA_RELEASEBUFFER) + { + if(bKeep == wxCFDATA_RELEASEBUFFER) + { + m_cfdaRef = CFDataCreateWithBytesNoCopy + (kCFAllocatorDefault, pBytes, len, kCFAllocatorDefault); + } + else + { + m_cfdaRef = CFDataCreate(kCFAllocatorDefault, pBytes, len); + } + } + ~wxCFData() {if(m_cfdaRef) CFRelease(m_cfdaRef);} + + const UInt8* GetValue() + { + return CFDataGetBytePtr(m_cfdaRef); + } + + CFIndex GetCount() + { + return CFDataGetLength(m_cfdaRef); + } + + operator CFTypeRef() const + { return (CFTypeRef)m_cfdaRef; } + + bool IsOk() { return m_cfdaRef != NULL; } +private: + CFDataRef m_cfdaRef; +}; + +void wxCFDictionary::MakeValidXML() +{ CFIndex cfiCount = GetCount(); CFTypeRef* pKeys = new CFTypeRef[cfiCount]; CFTypeRef* pValues = new CFTypeRef[cfiCount]; @@ -819,11 +1376,9 @@ void wxCFDictionary::MakeValidXML() delete[] pValues; delete[] pKeys; - } } void wxCFArray::MakeValidXML() -{ { for(CFIndex i = 0; i < GetCount(); ++i) { @@ -859,9 +1414,16 @@ void wxCFArray::MakeValidXML() --i; } } - } } +// +// +// +// END TODO +// +// +// + wxFileType* wxMimeTypesManagerImpl::Associate(const wxFileTypeInfo& ftInfo) { bool bInfoSuccess = false; @@ -896,7 +1458,7 @@ wxFileType* wxMimeTypesManagerImpl::Associate(const wxFileTypeInfo& ftInfo) sInfoPath << cfurlBundleLoc.BuildWXString(); sInfoPath << wxT("Contents/Info.plist"); -// wxCFDictionary cfdInfo( (CFTypeRef) CFBundleGetInfoDictionary(cfbMain), wxCF_RETAIN ); +// wxCFDictionary cfdInfo( CFBundleGetInfoDictionary(cfbMain), wxCF_RETAIN ); wxCFDictionary cfdInfo; bool bInfoOpenSuccess = false; wxFile indictfile; @@ -1108,7 +1670,7 @@ wxFileType* wxMimeTypesManagerImpl::Associate(const wxFileTypeInfo& ftInfo) ICGetMapEntry( (ICInstance) m_hIC, (Handle) m_hDatabase, pFileType->m_impl->m_lIndex, &entry); - entry.creatorAppName = psCreatorName; + memcpy(entry.creatorAppName, psCreatorName, sizeof(Str255)); entry.fileCreator = creator; status = ICSetMapEntry( (ICInstance) m_hIC, (Handle) m_hDatabase, @@ -1143,7 +1705,7 @@ wxFileType* wxMimeTypesManagerImpl::Associate(const wxFileTypeInfo& ftInfo) Str255 psMimeType; Str255 psDescription; - wxMacStringToPascal(ftInfo.GetExtensions()[0], psExtension); + wxMacStringToPascal(wxString(wxT(".")) + ftInfo.GetExtensions()[0], psExtension); wxMacStringToPascal(ftInfo.GetMimeType(), psMimeType); wxMacStringToPascal(ftInfo.GetDescription(), psDescription); @@ -1160,11 +1722,11 @@ wxFileType* wxMimeTypesManagerImpl::Associate(const wxFileTypeInfo& ftInfo) entry.fileCreator = creator; entry.postCreator = 0; entry.flags = kICMapDataForkBit; //TODO: Maybe resource is valid by default too? - entry.extension = psExtension; - entry.creatorAppName = psCreatorName; - entry.postAppName = psPostCreatorName; - entry.MIMEType = psMimeType; - entry.entryName = psDescription; + PLstrcpy( entry.extension , psExtension ) ; + memcpy(entry.creatorAppName, psCreatorName, sizeof(Str255)); + memcpy(entry.postAppName, psPostCreatorName, sizeof(Str255)); + memcpy(entry.MIMEType, psMimeType, sizeof(Str255)); + memcpy(entry.entryName, psDescription, sizeof(Str255)); status = ICAddMapEntry( (ICInstance) m_hIC, (Handle) m_hDatabase, &entry); @@ -1375,7 +1937,7 @@ wxMimeTypesManagerImpl::Unassociate(wxFileType *pFileType) #if defined(__DARWIN__) if(!bInfoSuccess) - return NULL; + return FALSE; #endif //this should be as easy as removing the entry from the database and then saving