📄 mimetmac.cpp
字号:
#include <ApplicationServices/ApplicationServices.h>
wxString 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);
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 implementation
wxString 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 //!DARWIN
bool 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 type
wxFileType* 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 type
wxFileType* 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;
infoRec.processAppSpec = NULL;
if ( pPSN == NULL )
{
localPSN.highLongOfPSN = 0;
localPSN.lowLongOfPSN = kCurrentProcess;
}
else
{
localPSN = *pPSN;
}
anErr = GetProcessInformation(&localPSN, &infoRec);
if (anErr == noErr)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -