]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/mimetmac.cpp
Fix STL compilation (note: this is not the correct fix, but since
[wxWidgets.git] / src / mac / carbon / mimetmac.cpp
index 87a187113cbb2b531669ca72fda8f699662dedf6..9c0f3be67b51b5b10335ddf78d3918fe9a409a0b 100644 (file)
@@ -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