📄 mimetmac.cpp
字号:
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);
}
virtual ~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);
}
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 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);
}
}
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")) );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -