📄 mimetmac.cpp
字号:
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); } virtual ~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 1class 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); } } virtual ~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]; CFDictionaryGetKeysAndValues(m_cfmdRef, pKeys, pValues); // for plist xml format, all dictionary keys must be cfstrings and // no values in the dictionary or subkeys/values can be NULL; // additionally, CFURLs are not allowed for (CFIndex i = 0; i < cfiCount; ++i) { // must be an array, dictionary, string, bool, or int and cannot be null // and dictionaries can only contain cfstring keys CFTypeRef cfRef = pValues[i]; if (!pKeys[i] || CFGetTypeID(pKeys[i]) != CFStringGetTypeID() || !cfRef) { Remove(pKeys[i]); --i; --cfiCount; delete [] pKeys; delete [] pValues; pKeys = new CFTypeRef[cfiCount]; pValues = new CFTypeRef[cfiCount]; CFDictionaryGetKeysAndValues(m_cfmdRef, pKeys, pValues); } else if (CFGetTypeID(cfRef) == CFArrayGetTypeID()) { CFRetain(cfRef); wxCFArray cfaCurrent(cfRef); cfaCurrent.MakeMutable(); cfaCurrent.MakeValidXML(); Set(pKeys[i], cfaCurrent); } else if (CFGetTypeID(cfRef) == CFDictionaryGetTypeID()) { CFRetain(cfRef); wxCFDictionary cfdCurrent(cfRef); cfdCurrent.MakeMutable(); cfdCurrent.MakeValidXML(); Set(pKeys[i], cfdCurrent); } else if ( CFGetTypeID(cfRef) != CFStringGetTypeID() && CFGetTypeID(cfRef) != CFNumberGetTypeID() && CFGetTypeID(cfRef) != CFBooleanGetTypeID() ) { Remove(pKeys[i]); --i; --cfiCount; delete [] pKeys; delete [] pValues; pKeys = new CFTypeRef[cfiCount]; pValues = new CFTypeRef[cfiCount]; CFDictionaryGetKeysAndValues(m_cfmdRef, pKeys, pValues); } } delete [] pValues; delete [] pKeys;}void wxCFArray::MakeValidXML(){ for (CFIndex i = 0; i < GetCount(); ++i) { //must be an array, dictionary, string, bool, or int and cannot be null //and dictionaries can only contain cfstring keys CFTypeRef cfRef = (*this)[i]; if (!cfRef) { Remove(i); --i; } else if (CFGetTypeID(cfRef) == CFArrayGetTypeID()) { CFRetain(cfRef); wxCFArray cfaCurrent(cfRef); cfaCurrent.MakeMutable(); cfaCurrent.MakeValidXML(); Set(i, cfaCurrent); } else if (CFGetTypeID(cfRef) == CFDictionaryGetTypeID()) { CFRetain(cfRef); wxCFDictionary cfdCurrent(cfRef); cfdCurrent.MakeMutable(); cfdCurrent.MakeValidXML(); Set(i, cfdCurrent); } else if ( CFGetTypeID(cfRef) != CFStringGetTypeID() && CFGetTypeID(cfRef) != CFNumberGetTypeID() && CFGetTypeID(cfRef) != CFBooleanGetTypeID() ) { Remove(i); --i; } }}//////// END TODO//////wxFileType* wxMimeTypesManagerImpl::Associate(const wxFileTypeInfo& ftInfo){ bool bInfoSuccess = false; const wxArrayString& asExtensions = ftInfo.GetExtensions(); size_t dwFoundIndex = 0; if (!asExtensions.GetCount()) { wxLogDebug(wxT("Must have extension to associate with")); } // Find and write to Info.plist in main bundle (note that some other // apps have theirs named differently, i.e. IE's is named Info-macos.plist // some apps (non-wx) use the 'plst' resource instead CFBundleRef cfbMain = CFBundleGetMainBundle(); if (cfbMain) { UInt32 dwBundleType, dwBundleCreator; CFBundleGetPackageInfo(cfbMain, &dwBundleType, &dwBundleCreator); // if launching terminal non-app, version will be 'BNDL' (generic bundle, maybe in other cases too), // which will give us the incorrect info.plist path // otherwise it will be 'APPL', or in the case of a framework, 'FMWK' if (dwBundleType == 'APPL') { wxCFURL cfurlBundleLoc((CFTypeRef)CFBundleCopyBundleURL(cfbMain));// wxCFURL cfurlBundleLoc((CFTypeRef)CFBundleCopyExecutableURL(cfbMain)); wxString sInfoPath;// sInfoPath << wxT("file://"); sInfoPath << cfurlBundleLoc.BuildWXString(); sInfoPath << wxT("Contents/Info.plist");// wxCFDictionary cfdInfo( CFBundleGetInfoDictionary(cfbMain), wxCF_RETAIN ); wxCFDictionary cfdInfo; bool bInfoOpenSuccess = false; wxFile indictfile; if (indictfile.Open(sInfoPath, wxFile::read)) { CFIndex cfiBufLen = (CFIndex) indictfile.Length(); const UInt8* pBuffer = new UInt8[cfiBufLen]; indictfile.Read((void*)pBuffer, cfiBufLen); wxCFData cfdaInDict(pBuffer, cfiBufLen); wxString sError; bInfoOpenSuccess = cfdInfo.ReadAsXML(cfdaInDict, &sError); if (!bInfoOpenSuccess) wxLogDebug(sError); indictfile.Close(); } if (bInfoOpenSuccess) { cfdInfo.MakeMutable( cfdInfo.GetCount() + 1 ); wxCFArray cfaDocTypes( cfdInfo[ wxCFString(wxT("CFBundleDocumentTypes")) ], wxCF_RETAIN ); bool bAddDocTypesArrayToDictionary = !cfaDocTypes.IsOk(); if (bAddDocTypesArrayToDictionary) cfaDocTypes.Create(); else cfaDocTypes.MakeMutable( cfaDocTypes.GetCount() + 1 ); bool bEntryFound = false; // search for duplicates CFIndex i; for (i = 0; i < cfaDocTypes.GetCount(); ++i) { wxCFDictionary cfdDocTypeEntry( cfaDocTypes[i], wxCF_RETAIN ); // A lot of apps don't support MIME types for some reason // so we go by extensions only wxCFArray cfaExtensions( cfdDocTypeEntry[ wxCFString(wxT("CFBundleTypeExtensions")) ], wxCF_RETAIN ); if (!cfaExtensions.IsOk()) continue; for (CFIndex iExt = 0; iExt < cfaExtensions.GetCount(); ++iExt) { for (size_t iWXExt = 0; iWXExt < asExtensions.GetCount(); ++iWXExt) { if (asExtensions[iWXExt] == wxCFString(cfaExtensions[iExt], wxCF_RETAIN).BuildWXString()) { bEntryFound = true; dwFoundIndex = iWXExt; break; } } //end of wxstring array if (bEntryFound) break; } //end for cf array if (bEntryFound) break; } //end for doctypes wxCFDictionary cfdNewEntry; if (!ftInfo.GetDescription().empty()) { cfdNewEntry.Add( wxCFString(wxT("CFBundleTypeName")), wxCFString(ftInfo.GetDescription()) ); } if (!ftInfo.GetIconFile().empty()) { cfdNewEntry.Add( wxCFString(wxT("CFBundleTypeIconFile")), wxCFString(ftInfo.GetIconFile()) ); } wxCFArray cfaOSTypes; wxCFArray cfaExtensions; wxCFArray cfaMimeTypes; //OSTypes is a cfarray of four-char-codes - '****' for unrestricted cfaOSTypes.Add( wxCFString(wxT("****")) ); cfdNewEntry.Add( wxCFString(wxT("CFBundleTypeOSTypes")), cfaOSTypes ); //'*' for unrestricted if (ftInfo.GetExtensionsCount() != 0) { for (size_t iExtension = 0; iExtension < ftInfo.GetExtensionsCount(); ++iExtension) { cfaExtensions.Add( wxCFString( asExtensions[iExtension] ) ); } cfdNewEntry.Add( wxCFString(wxT("CFBundleTypeExtensions")), cfaExtensions ); } if (!ftInfo.GetMimeType().empty()) { cfaMimeTypes.Add( wxCFString(ftInfo.GetMimeType()) ); cfdNewEntry.Add( wxCFString(wxT("CFBundleTypeMIMETypes")), cfaMimeTypes ); } // Editor - can perform all actions // Viewer - all actions except manipulation/saving // None - can perform no actions cfdNewEntry.Add( wxCFString(wxT("CFBundleTypeRole")), wxCFString(wxT("Editor")) ); // Is application bundled? cfdNewEntry.Add( wxCFString(wxT("LSTypeIsPackage")), kCFBooleanTrue ); if (bEntryFound) cfaDocTypes.Set(i, cfdNewEntry); else cfaDocTypes.Add(cfdNewEntry); // set the doc types array in the muted dictionary if (bAddDocTypesArrayToDictionary) cfdInfo.Add(wxCFString(wxT("CFBundleDocumentTypes")), cfaDocTypes); else cfdInfo.Set(wxCFString(wxT("CFBundleDocumentTypes")), cfaDocTypes); cfdInfo.MakeValidXML(); wxFile outdictfile; if (outdictfile.Open(sInfoPath, wxFile::write)) { wxCFData cfdaInfo(cfdInfo.WriteAsXML()); if (cfdaInfo.IsOk()) { if (outdictfile.Write(cfdaInfo.GetValue(), cfdaInfo.GetCount()) != (wxFileOffset)cfdaInfo.GetCount()) { wxLogDebug(wxT("error in writing to file")); } else { bInfoSuccess = true;//#if defined(__DARWIN__)// //force launch services to update its database for the finder// OSStatus status = LSRegisterURL((CFURLRef)(CFTypeRef)cfurlBundleLoc, true);// if (status != noErr)// {// wxLogDebug(wxT("LSRegisterURL Failed."));// }//#endif } outdictfile.Close(); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -