⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mimetmac.cpp

📁 Wxpython Implemented on Windows CE, Source code
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                // 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();
                    }
                    else
                    {
                        outdictfile.Close();
                        wxLogDebug(wxT("Could not read in new dictionary"));
                    }
                }
                else
                {
                    wxLogDebug(wxString(wxT("Could not open [")) +
                    sInfoPath + wxT("] for writing."));
                }
            }
            else
            {
                wxLogDebug(wxT("No info dictionary in main bundle"));
            }
        }
        else
        {
            wxLogDebug(wxT("Can only call associate from bundled app within XXX.app"));
        }
    }
    else
    {
        wxLogDebug(wxT("No main bundle"));
    }

#if defined(__DARWIN__)
    if (!bInfoSuccess)
        return NULL;
#endif

    // on mac you have to embed it into the mac's file reference resource ('FREF' I believe)
    // or, alternately, you could just add an entry to m_hDatabase, but you'd need to get
    // the app's signature somehow...

    OSType processType, creator;
    OSStatus status = MoreProcGetProcessTypeSignature(NULL, &processType, &creator);

    if (status == noErr)
    {
        Str255 psCreatorName;
        FSSpec dummySpec;
        status = FindApplication(creator, false, psCreatorName, &dummySpec);

        if (status == noErr)
        {
            //get the file type if it exists -
            //if it really does then modify the database then save it,
            //otherwise we need to create a whole new entry
            wxFileType* pFileType = GetFileTypeFromExtension(asExtensions[dwFoundIndex]);
            if (pFileType)
            {
                ICMapEntry entry;
                ICGetMapEntry( (ICInstance) m_hIC, (Handle) m_hDatabase,
                    pFileType->m_impl->m_lIndex, &entry );

                memcpy(entry.creatorAppName, psCreatorName, sizeof(Str255));
                entry.fileCreator = creator;

                status = ICSetMapEntry( (ICInstance) m_hIC, (Handle) m_hDatabase,
                    pFileType->m_impl->m_lIndex, &entry );

                //success
                if (status == noErr)
                {
                     return pFileType;

                    //kICAttrNoChange means we don't care about attributes such as
                    //locking in the database
//                    status = ICSetPrefHandle((ICInstance) m_hIC, kICMapping,
//                                             kICAttrNoChange, (Handle) m_hDatabase);
//                    if (status == noErr)
//                        return pFileType;
//                    else
//                    {
//                        wxLogDebug(wxString::Format(wxT("%i - %s"), (int)status, wxT("ICSetPrefHandle failed.")));
//                    }
                }
                else
                {
                    wxLogDebug(wxString::Format(wxT("%i - %s"), __LINE__, wxT("ICSetMapEntry failed.")));
                }

                // failure - cleanup
                delete pFileType;
            }
            else
            {
                // TODO: Maybe force all 3 of these to be non-empty?
                Str255 psExtension, psMimeType, psDescription;

                wxMacStringToPascal(wxString(wxT(".")) + ftInfo.GetExtensions()[0], psExtension);
                wxMacStringToPascal(ftInfo.GetMimeType(), psMimeType);
                wxMacStringToPascal(ftInfo.GetDescription(), psDescription);

                Str255 psPostCreatorName;
                wxMacStringToPascal(wxEmptyString, psPostCreatorName);

                //add the entry to the database
                ICMapEntry entry;
                entry.totalLength = sizeof(ICMapEntry);
                entry.fixedLength = kICMapFixedLength;
                entry.version = 0;
                entry.fileType = 0; //TODO:  File type?
                entry.fileCreator = creator;
                entry.postCreator = 0;
                entry.flags = kICMapDataForkBit; //TODO:  Maybe resource is valid by default too?
                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);
                if (status == noErr)
                {
                    return GetFileTypeFromExtension(ftInfo.GetMimeType());

//                    kICAttrNoChange means we don't care about attributes such as
//                    locking in the database
//                    status = ICSetPrefHandle((ICInstance) m_hIC, kICMapping,
//                                             kICAttrNoChange, (Handle) m_hDatabase);

                    // return the entry in the database if successful
//                    if (status == noErr)
//                        return GetFileTypeFromExtension(ftInfo.GetMimeType());
//                    else
//                    {
//                        wxLogDebug(wxString::Format(wxT("%i - %s"), __LINE__, wxT("ICSetPrefHandle failed.")));
 //                   }
                }
                else
                {
                    wxLogDebug(wxString::Format(wxT("%i - %s"), __LINE__, wxT("ICAppMapEntry failed.")));
                }
            }
        } // end if FindApplcation was successful
        else
        {
            wxLogDebug(wxString::Format(wxT("%i - %s"), __LINE__, wxT("FindApplication failed.")));
        }
    } // end if it could obtain app's signature
    else
    {
        wxLogDebug(wxString::Format(wxT("%i - %s"), __LINE__, wxT("GetProcessSignature failed.")));
    }

    return NULL;
}

bool
wxMimeTypesManagerImpl::Unassociate(wxFileType *pFileType)
{
    wxASSERT(pFileType);
    bool bInfoSuccess = false;

    wxArrayString asExtensions;
    pFileType->GetExtensions(asExtensions);

    if (!asExtensions.GetCount())
    {
        wxLogDebug(wxT("Must have extension to disassociate"));
        return false;
    }

    // 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( (CFTypeRef) 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 );

                if (cfaDocTypes.IsOk())
                {
                    bool bEntryFound = false;

                    //search for duplicate
                    CFIndex i;
                    for (i = 0; i < cfaDocTypes.GetCount(); ++i)
                    {
                        wxCFDictionary cfdDocTypeEntry( cfaDocTypes[i], wxCF_RETAIN );

                        //A lot of apps dont do to 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;
                                    cfaDocTypes.Remove(i);
                                    cfdInfo.Set( wxCFString(wxT("CFBundleDocumentTypes")) , cfaDocTypes );
                                    break;
                                }
                            } //end of wxstring array

                            if (bEntryFound)
                                break;
                        } //end for cf array

                        if (bEntryFound)
                            break;
                    }//end for doctypes

                    if (bEntryFound)
                    {
                        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();
                            }
                            else
                            {
                                outdictfile.Close();
                                wxLogDebug(wxT("Could not read in new dictionary"));
                            }
                        }
                        else
                        {
                            wxLogDebug(
                                wxString(wxT("Could not open [")) +
                                sInfoPath + wxT("] for writing."));
                        }
                    }
                    else
                    {
                        wxLogDebug(wxT("Entry not found to remove"));

                        wxString sPrintOut;
                        wxCFDictionary::PrintOutArray(sPrintOut, (CFArrayRef)(CFTypeRef)cfaDocTypes);
                        wxLogDebug(sPrintOut);

                        for (size_t i = 0; i < asExtensions.GetCount(); ++i)
                            wxLogDebug(asExtensions[i]);
                    }
                }
                else
                {
                    wxLogDebug(wxT("No doc types array found"));
                    wxString sPrintOut;  cfdInfo.PrintOut(sPrintOut);  wxLogDebug(sPrintOut);
                }
            }
            else
            {
                wxLogDebug(wxT("No info dictionary in main bundle"));
            }
        }
        else
        {
            wxLogDebug(wxT("Can only call associate from bundled app within XXX.app"));
        }
    }
    else
    {
        wxLogDebug(wxT("No main bundle"));
    }

#if defined(__DARWIN__)
    if (!bInfoSuccess)
        return false;
#endif

    // this should be as easy as removing the entry from the database
    // and then saving the database
    OSStatus status = ICDeleteMapEntry( (ICInstance) m_hIC, (Handle) m_hDatabase,
                            pFileType->m_impl->m_lIndex);

    if (status == noErr)
    {
            return true;

        //kICAttrNoChange means we don't care about attributes such as
        //locking in the database
//        status = ICSetPrefHandle((ICInstance) m_hIC, kICMapping,
//                    kICAttrNoChange, (Handle) m_hDatabase);

//        if (status == noErr)
//        {
//            return true;
//        }
//        else
//        {
//            wxLogDebug(wxString::Format(wxT("%i - %s"), __LINE__, wxT("ICSetPrefHandle failed.")));
//        }
    }
    else
    {
        wxLogDebug(wxString::Format(wxT("%i - %s

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -