📄 mimetmac.cpp
字号:
m_lIndex, &entry); wxString sCurrentExtension = wxMacMakeStringFromPascal(entry.extension); sCurrentExtension = sCurrentExtension.Right(sCurrentExtension.length()-1 ); //type, creator, ext, roles, outapp (FSRef), outappurl CFURLRef cfurlAppPath; OSStatus status = LSGetApplicationForInfo( kLSUnknownType, kLSUnknownCreator, wxMacCFStringHolder(sCurrentExtension, wxLocale::GetSystemEncoding()), kLSRolesAll, NULL, &cfurlAppPath ); if (status == noErr) { CFStringRef cfsUnixPath = CFURLCopyFileSystemPath(cfurlAppPath, kCFURLPOSIXPathStyle); CFRelease(cfurlAppPath); // PHEW! Success! // Since a filename might have spaces in it, so surround it with quotes if (cfsUnixPath) { wxString resultStr; resultStr = wxString(wxT("'")) + wxMacCFStringHolder(cfsUnixPath).AsString(wxLocale::GetSystemEncoding()) + wxString(wxT("'")); return resultStr; } } else { wxLogDebug(wxString::Format(wxT("%i - %s - %i"), __LINE__, wxT("LSGetApplicationForInfo failed."), (int)status)); } } return wxEmptyString;}#else //carbon/classic implementationwxString wxFileTypeImpl::GetCommand(const wxString& verb) const{ wxASSERT_MSG( m_manager != NULL , wxT("Bad wxFileType") ); if (verb == wxT("open")) { ICMapEntry entry; ICGetMapEntry( (ICInstance) m_manager->m_hIC, (Handle) m_manager->m_hDatabase, m_lIndex, &entry); //The entry in the mimetype database only contains the app //that's registered - it may not exist... we need to remap the creator //type and find the right application // THIS IS REALLY COMPLICATED :\. // There are a lot of conversions going on here. Str255 outName; FSSpec outSpec; OSErr err = FindApplication( entry.fileCreator, false, outName, &outSpec ); if (err != noErr) return wxEmptyString; Handle outPathHandle; short outPathSize; err = FSpGetFullPath( &outSpec, &outPathSize, &outPathHandle ); if (err == noErr) { char* szPath = *outPathHandle; wxString sClassicPath(szPath, wxConvLocal, outPathSize);#if defined(__DARWIN__) // Classic Path --> Unix (OSX) Path CFURLRef finalURL = CFURLCreateWithFileSystemPath( kCFAllocatorDefault, wxMacCFStringHolder(sClassicPath, wxLocale::GetSystemEncoding()), kCFURLHFSPathStyle, false ); //false == not a directory //clean up memory from the classic path handle DisposeHandle( outPathHandle ); if (finalURL) { CFStringRef cfsUnixPath = CFURLCopyFileSystemPath(finalURL, kCFURLPOSIXPathStyle); CFRelease(finalURL); // PHEW! Success! if (cfsUnixPath) return wxMacCFStringHolder(cfsUnixPath).AsString(wxLocale::GetSystemEncoding()); }#else //classic HFS path acceptable return sClassicPath;#endif } else { wxLogMimeDebug(wxT("FSpGetFullPath failed."), (OSStatus)err); } } return wxEmptyString;}#endif //!DARWINbool wxFileTypeImpl::GetDescription(wxString *desc) const{ wxASSERT_MSG( m_manager != NULL , wxT("Bad wxFileType") ); ICMapEntry entry; ICGetMapEntry( (ICInstance) m_manager->m_hIC, (Handle) m_manager->m_hDatabase, m_lIndex, &entry ); *desc = wxMacMakeStringFromPascal( entry.entryName ); return true;}bool wxFileTypeImpl::GetExtensions(wxArrayString& extensions){ wxASSERT_MSG( m_manager != NULL , wxT("Bad wxFileType") ); ICMapEntry entry; ICGetMapEntry( (ICInstance) m_manager->m_hIC, (Handle) m_manager->m_hDatabase, m_lIndex, &entry ); //entry has period in it wxString sCurrentExtension = wxMacMakeStringFromPascal( entry.extension ); extensions.Add( sCurrentExtension.Right( sCurrentExtension.length() - 1 ) ); return true;}bool wxFileTypeImpl::GetMimeType(wxString *mimeType) const{ wxASSERT_MSG( m_manager != NULL , wxT("Bad wxFileType") ); ICMapEntry entry; ICGetMapEntry( (ICInstance) m_manager->m_hIC, (Handle) m_manager->m_hDatabase, m_lIndex, &entry ); *mimeType = wxMacMakeStringFromPascal(entry.MIMEType); return true;}bool wxFileTypeImpl::GetMimeTypes(wxArrayString& mimeTypes) const{ wxString s; if (GetMimeType(&s)) { mimeTypes.Clear(); mimeTypes.Add(s); return true; } return false;}bool wxFileTypeImpl::GetIcon(wxIconLocation *WXUNUSED(icon)) const{ wxASSERT_MSG( m_manager != NULL , wxT("Bad wxFileType") ); // no such file type or no value or incorrect icon entry return false;}size_t wxFileTypeImpl::GetAllCommands(wxArrayString * verbs, wxArrayString * commands, const wxFileType::MessageParameters& params) const{ wxASSERT_MSG( m_manager != NULL , wxT("Bad wxFileType") ); wxString sCommand; size_t ulCount = 0; if (GetOpenCommand(&sCommand, params)) { verbs->Add(wxString(wxT("open"))); commands->Add(sCommand); ++ulCount; } return ulCount;}void wxMimeTypesManagerImpl::Initialize(int mailcapStyles, const wxString& extraDir){ wxASSERT_MSG(m_hIC == NULL, wxT("Already initialized wxMimeTypesManager!")); // some apps (non-wx) use the 'plst' resource instead#if 0 CFBundleRef cfbMain = CFBundleGetMainBundle(); wxCFDictionary cfdInfo( CFBundleGetInfoDictionary(cfbMain), wxCF_RETAIN ); wxString sLog; cfdInfo.PrintOut(sLog); wxLogDebug(sLog);#endif // 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 // have a signature for this app, so a generic 'APPL' which is the executable // type will work for now. OSStatus status = ICStart( (ICInstance*)&m_hIC, 'APPL' ); if (status != noErr) { wxLogDebug(wxT("Could not initialize wxMimeTypesManager!")); wxFAIL; m_hIC = NULL; return; } ICAttr attr; m_hDatabase = (void**) NewHandle(0); status = ICFindPrefHandle( (ICInstance) m_hIC, kICMapping, &attr, (Handle) m_hDatabase ); //the database file can be corrupt (on OSX its //~/Library/Preferences/com.apple.internetconfig.plist) //- bail if it is if (status != noErr) { ClearData(); wxLogDebug(wxT("Corrupt MIME database!")); return; } //obtain the number of entries in the map status = ICCountMapEntries( (ICInstance) m_hIC, (Handle) m_hDatabase, &m_lCount ); wxASSERT( status == noErr );#if 0 //debug stuff ICMapEntry entry; long pos; for (long i = 1; i <= m_lCount; ++i) { OSStatus status = ICGetIndMapEntry( (ICInstance) m_hIC, (Handle) m_hDatabase, i, &pos, &entry ); if (status == noErr) { wxString sCreator = wxMacMakeStringFromPascal(entry.creatorAppName); wxString sCurrentExtension = wxMacMakeStringFromPascal(entry.extension); wxString sMIMEType = wxMacMakeStringFromPascal(entry.MIMEType); wxFileTypeImpl impl; impl.Init(this, pos); if (sMIMEType == wxT("text/html") && sCurrentExtension == wxT(".html")) { wxString cmd; impl.GetOpenCommand( &cmd, wxFileType::MessageParameters (wxT("http://www.google.com"))); wxPrintf(wxT("APP: [%s]\n"), cmd.c_str()); } } }#endif}void wxMimeTypesManagerImpl::ClearData(){ if (m_hIC != NULL) { DisposeHandle( (Handle)m_hDatabase ); // this can return an error, but we don't really care that much about it ICStop( (ICInstance)m_hIC ); m_hIC = NULL; }}//// Q) Iterating through the map - why does it use if (err == noErr) instead of just asserting?// A) Some intermediate indexes are bad while subsequent ones may be good. Its wierd, I know.//// extension -> file typewxFileType* wxMimeTypesManagerImpl::GetFileTypeFromExtension(const wxString& e){ wxASSERT_MSG( m_hIC != NULL, wxT("wxMimeTypesManager not Initialized!") ); //low level functions - iterate through the database ICMapEntry entry; long pos; for (long i = 1; i <= m_lCount; ++i) { OSStatus status = ICGetIndMapEntry( (ICInstance) m_hIC, (Handle) m_hDatabase, i, &pos, &entry ); if (status == noErr) { wxString sCurrentExtension = wxMacMakeStringFromPascal(entry.extension); if ( sCurrentExtension.Right(sCurrentExtension.length() - 1) == e ) // entry has period in it { wxFileType* pFileType = new wxFileType(); pFileType->m_impl->Init((wxMimeTypesManagerImpl*)this, pos); return pFileType; } } } return NULL;}// MIME type -> extension -> file typewxFileType* wxMimeTypesManagerImpl::GetFileTypeFromMimeType(const wxString& mimeType){ wxASSERT_MSG( m_hIC != NULL, wxT("wxMimeTypesManager not Initialized!") ); ICMapEntry entry; long pos; // low level functions - iterate through the database for (long i = 1; i <= m_lCount; ++i) { OSStatus status = ICGetIndMapEntry( (ICInstance) m_hIC, (Handle) m_hDatabase, i, &pos, &entry ); wxASSERT_MSG( status == noErr, wxString::Format(wxT("Error: %d"), (int)status) ); if (status == noErr) { if ( wxMacMakeStringFromPascal(entry.MIMEType) == mimeType) { wxFileType* pFileType = new wxFileType(); pFileType->m_impl->Init((wxMimeTypesManagerImpl*)this, pos); return pFileType; } } } return NULL;}size_t wxMimeTypesManagerImpl::EnumAllFileTypes(wxArrayString& mimetypes){ wxASSERT_MSG( m_hIC != NULL, wxT("wxMimeTypesManager not Initialized!") ); ICMapEntry entry; long pos, lStartCount; // low level functions - iterate through the database lStartCount = (long) mimetypes.GetCount(); for (long i = 1; i <= m_lCount; ++i) { OSStatus status = ICGetIndMapEntry( (ICInstance) m_hIC, (Handle) m_hDatabase, i, &pos, &entry ); if ( status == noErr ) mimetypes.Add( wxMacMakeStringFromPascal(entry.MIMEType) ); } return mimetypes.GetCount() - lStartCount;}pascal OSStatus MoreProcGetProcessTypeSignature( const ProcessSerialNumberPtr pPSN, OSType *pProcessType, OSType *pCreator){ OSStatus anErr = noErr; ProcessInfoRec infoRec; ProcessSerialNumber localPSN; infoRec.processInfoLength = sizeof(ProcessInfoRec); infoRec.processName = NULL;#ifndef __LP64__ infoRec.processAppSpec = NULL;#endif if ( pPSN == NULL ) { localPSN.highLongOfPSN = 0; localPSN.lowLongOfPSN = kCurrentProcess; } else { localPSN = *pPSN; } anErr = GetProcessInformation(&localPSN, &infoRec); if (anErr == noErr) { *pProcessType = infoRec.processType; *pCreator = infoRec.processSignature; } return anErr;}////// TODO: clean this up, its messy//////#include "wx/mac/corefoundation/cfstring.h"#define wxCF_RELEASE true#define wxCF_RETAIN false
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -