mimetype.cpp

来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 2,012 行 · 第 1/5 页

CPP
2,012
字号
                                  wxArrayString *commands,
                                  const wxFileType::MessageParameters& params) const
{

    wxString vrb, cmd, sTmp;
    size_t count = 0;
    wxMimeTypeCommands * sPairs;

    // verbs and commands have been cleared already in mimecmn.cpp...
    // if we find no entries in the exact match, try the inexact match
    for (size_t n = 0; ((count ==0) && (n < m_index.GetCount())); n++)
    {
        // list of verb = command pairs for this mimetype
        sPairs = m_manager->m_aEntries [m_index[n]];
        size_t i;
        for ( i = 0; i < sPairs->GetCount (); i++ )
            {
                vrb = sPairs->GetVerb(i);
                // some gnome entries have . inside
                vrb = vrb.AfterLast(wxT('.'));
                cmd = sPairs->GetCmd (i);
                if (! cmd.empty() )
                     {
                     cmd = wxFileType::ExpandCommand(cmd, params);
                     count ++;
                     if ( vrb.IsSameAs (wxT("open")))
                         {
                         verbs->Insert(vrb,0u);
                         commands ->Insert(cmd,0u);
                         }
                     else
                         {
                         verbs->Add (vrb);
                         commands->Add (cmd);
                         }
                     }

        }

    }
    return count;

}

bool wxFileTypeImpl::GetExtensions(wxArrayString& extensions)
{
    wxString strExtensions = m_manager->GetExtension(m_index[0]);
    extensions.Empty();

    // one extension in the space or comma delimitid list
    wxString strExt;
    for ( const wxChar *p = strExtensions;; p++ ) {
        if ( *p == wxT(' ') || *p == wxT(',') || *p == wxT('\0') ) {
            if ( !strExt.empty() ) {
                extensions.Add(strExt);
                strExt.Empty();
            }
            //else: repeated spaces (shouldn't happen, but it's not that
            //      important if it does happen)

            if ( *p == wxT('\0') )
                break;
        }
        else if ( *p == wxT('.') ) {
            // remove the dot from extension (but only if it's the first char)
            if ( !strExt.empty() ) {
                strExt += wxT('.');
            }
            //else: no, don't append it
        }
        else {
            strExt += *p;
        }
    }

    return true;
}

// set an arbitrary command,
// could adjust the code to ask confirmation if it already exists and
// overwriteprompt is true, but this is currently ignored as *Associate* has
// no overwrite prompt
bool wxFileTypeImpl::SetCommand(const wxString& cmd, const wxString& verb, bool overwriteprompt /*= true*/)
{
    wxArrayString strExtensions;
    wxString strDesc, strIcon;

    wxMimeTypeCommands *entry = new wxMimeTypeCommands ();
    entry->Add(verb + wxT("=")  + cmd + wxT(" %s "));

    wxArrayString strTypes;
    GetMimeTypes (strTypes);
    if (strTypes.GetCount() < 1) return false;

    size_t i;
    bool Ok = true;
    for (i = 0; i < strTypes.GetCount(); i++)
    {
        if (!m_manager->DoAssociation (strTypes[i], strIcon, entry, strExtensions, strDesc))
            Ok = false;
    }

    return Ok;
}

// ignore index on the grouds that we only have one icon in a Unix file
bool wxFileTypeImpl::SetDefaultIcon(const wxString& strIcon /*= wxEmptyString*/, int /*index = 0*/)
{
    if (strIcon.empty()) return false;
    wxArrayString strExtensions;
    wxString strDesc;

    wxMimeTypeCommands *entry = new wxMimeTypeCommands ();

    wxArrayString strTypes;
    GetMimeTypes (strTypes);
    if (strTypes.GetCount() < 1) return false;

    size_t i;
    bool Ok = true;
    for (i = 0; i < strTypes.GetCount(); i++)
    {
        if (!m_manager->DoAssociation (strTypes[i], strIcon, entry, strExtensions, strDesc))
            Ok = false;
    }

    return Ok;
}

// ----------------------------------------------------------------------------
// wxMimeTypesManagerImpl (Unix)
// ----------------------------------------------------------------------------


wxMimeTypesManagerImpl::wxMimeTypesManagerImpl()
{
    m_initialized = false;
    m_mailcapStylesInited = 0;
}

void wxMimeTypesManagerImpl::InitIfNeeded()
{
    if ( !m_initialized )
    {
        // set the flag first to prevent recursion
        m_initialized = true;

        wxString wm = wxGetenv( wxT("WINDOWMANAGER") );

        if (wm.Find( wxT("kde") ) != wxNOT_FOUND)
            Initialize( wxMAILCAP_KDE );
        else if (wm.Find( wxT("gnome") ) != wxNOT_FOUND)
            Initialize( wxMAILCAP_GNOME );
        else
            Initialize();
    }
}

// read system and user mailcaps and other files
void wxMimeTypesManagerImpl::Initialize(int mailcapStyles,
                                        const wxString& sExtraDir)
{
    // read mimecap amd mime.types
    if ( (mailcapStyles & wxMAILCAP_NETSCAPE) ||
         (mailcapStyles & wxMAILCAP_STANDARD) )
        GetMimeInfo(sExtraDir);

    // read GNOME tables
    if (mailcapStyles & wxMAILCAP_GNOME)
        GetGnomeMimeInfo(sExtraDir);

    // read KDE tables
    if (mailcapStyles & wxMAILCAP_KDE)
        GetKDEMimeInfo(sExtraDir);

    m_mailcapStylesInited |= mailcapStyles;
}

// clear data so you can read another group of WM files
void wxMimeTypesManagerImpl::ClearData()
{
    m_aTypes.Clear ();
    m_aIcons.Clear ();
    m_aExtensions.Clear ();
    m_aDescriptions.Clear ();

    WX_CLEAR_ARRAY(m_aEntries);
    m_aEntries.Empty();

    m_mailcapStylesInited = 0;
}

wxMimeTypesManagerImpl::~wxMimeTypesManagerImpl()
{
    ClearData();
}


void wxMimeTypesManagerImpl::GetMimeInfo (const wxString& sExtraDir)
{
    // read this for netscape or Metamail formats

    // directories where we look for mailcap and mime.types by default
    // used by netscape and pine and other mailers, using 2 different formats!

    // (taken from metamail(1) sources)
    //
    // although RFC 1524 specifies the search path of
    // /etc/:/usr/etc:/usr/local/etc only, it doesn't hurt to search in more
    // places - OTOH, the RFC also says that this path can be changed with
    // MAILCAPS environment variable (containing the colon separated full
    // filenames to try) which is not done yet (TODO?)

    wxString strHome = wxGetenv(wxT("HOME"));

    wxArrayString dirs;
    dirs.Add ( strHome + wxT("/.") );
    dirs.Add ( wxT("/etc/") );
    dirs.Add ( wxT("/usr/etc/") );
    dirs.Add ( wxT("/usr/local/etc/") );
    dirs.Add ( wxT("/etc/mail/") );
    dirs.Add ( wxT("/usr/public/lib/") );
    if (!sExtraDir.empty()) dirs.Add ( sExtraDir + wxT("/") );

    size_t nDirs = dirs.GetCount();
    for ( size_t nDir = 0; nDir < nDirs; nDir++ )
    {
        wxString file = dirs[nDir] + wxT("mailcap");
        if ( wxFile::Exists(file) ) {
            ReadMailcap(file);
        }

        file = dirs[nDir] + wxT("mime.types");
        if ( wxFile::Exists(file) ) {
            ReadMimeTypes(file);
        }
    }

}

bool wxMimeTypesManagerImpl::WriteToMimeTypes (int index, bool delete_index)
{
    // check we have the right manager
    if (! ( m_mailcapStylesInited & wxMAILCAP_STANDARD) )
        return false;

    bool bTemp;
    wxString strHome = wxGetenv(wxT("HOME"));

    // and now the users mailcap
    wxString strUserMailcap = strHome + wxT("/.mime.types");

    wxMimeTextFile file;
    if ( wxFile::Exists(strUserMailcap) )
    {
        bTemp =  file.Open(strUserMailcap);
    }
    else
    {
        if (delete_index) return false;
        bTemp = file.Create(strUserMailcap);
    }
    if (bTemp)
    {
        int nIndex;
        // test for netscape's header and return false if its found
        nIndex = file.pIndexOf (wxT("#--Netscape"));
        if (nIndex != wxNOT_FOUND)
        {
            wxASSERT_MSG(false,wxT("Error in .mime.types \nTrying to mix Netscape and Metamail formats\nFile not modiifed"));
            return false;
        }
        // write it in alternative format
        // get rid of unwanted entries
        wxString strType = m_aTypes[index];
        nIndex = file.pIndexOf (strType);
        // get rid of all the unwanted entries...
        if (nIndex != wxNOT_FOUND) file.CommentLine (nIndex);

        if (!delete_index)
        {
            // add the new entries in
            wxString sTmp = strType.Append (wxT(' '), 40-strType.Len() );
            sTmp = sTmp + m_aExtensions[index];
            file.AddLine (sTmp);
        }


        bTemp = file.Write ();
        file.Close ();
    }
    return bTemp;
}

bool wxMimeTypesManagerImpl::WriteToNSMimeTypes (int index, bool delete_index)
{
    //check we have the right managers
    if (! ( m_mailcapStylesInited & wxMAILCAP_NETSCAPE) )
        return false;

    bool bTemp;
    wxString strHome = wxGetenv(wxT("HOME"));

    // and now the users mailcap
    wxString strUserMailcap = strHome + wxT("/.mime.types");

    wxMimeTextFile file;
    if ( wxFile::Exists(strUserMailcap) )
    {
        bTemp =  file.Open(strUserMailcap);
    }
    else
    {
        if (delete_index) return false;
        bTemp = file.Create(strUserMailcap);
    }
    if (bTemp)
    {

        // write it in the format that Netscape uses
        int nIndex;
        // test for netscape's header and insert if required...
        // this is a comment so use true
        nIndex = file.pIndexOf (wxT("#--Netscape"), true);
        if (nIndex == wxNOT_FOUND)
        {
            // either empty file or metamail format
            // at present we can't cope with mixed formats, so exit to preseve
            // metamail entreies
            if (file.GetLineCount () > 0)
            {
                wxASSERT_MSG(false, wxT(".mime.types File not in Netscape format\nNo entries written to\n.mime.types or to .mailcap"));
                return false;
            }
            file.InsertLine (wxT( "#--Netscape Communications Corporation MIME Information" ), 0);
            nIndex = 0;
        }

        wxString strType = wxT("type=") + m_aTypes[index];
        nIndex = file.pIndexOf (strType);
        // get rid of all the unwanted entries...
        if (nIndex != wxNOT_FOUND)
        {
            wxString sOld = file[nIndex];
            while ( (sOld.Contains(wxT("\\"))) && (nIndex < (int) file.GetLineCount()) )
            {
                file.CommentLine(nIndex);
                sOld = file[nIndex];
                wxLogTrace(TRACE_MIME, wxT("--- Deleting from mime.types line '%d %s' ---"), nIndex, sOld.c_str());
                nIndex ++;
            }
            if (nIndex < (int) file.GetLineCount()) file.CommentLine (nIndex);
        }
        else nIndex = (int) file.GetLineCount();

        wxString sTmp = strType + wxT(" \\");
        if (!delete_index) file.InsertLine (sTmp, nIndex);
        if ( ! m_aDescriptions.Item(index).empty() )
        {
            sTmp =     wxT("desc=\"") + m_aDescriptions[index]+ wxT("\" \\"); //.trim ??
            if (!delete_index)
            {
                nIndex ++;
                file.InsertLine (sTmp, nIndex);
            }
        }
        wxString sExts =  m_aExtensions.Item(index);
        sTmp =     wxT("exts=\"") + sExts.Trim(false).Trim() + wxT("\"");
        if (!delete_index)
        {
            nIndex ++;
            file.InsertLine (sTmp, nIndex);
        }

        bTemp = file.Write ();
        file.Close ();
    }
    return bTemp;
}


bool wxMimeTypesManagerImpl::WriteToMailCap (int index, bool delete_index)
{
    //check we have the right managers
    if ( !( ( m_mailcapStylesInited & wxMAILCAP_NETSCAPE) ||
            ( m_mailcapStylesInited & wxMAILCAP_STANDARD) ) )
        return false;

    bool bTemp;
    wxString strHome = wxGetenv(wxT("HOME"));

    // and now the users mailcap
    wxString strUserMailcap = strHome + wxT("/.mailcap");

    wxMimeTextFile file;
    if ( wxFile::Exists(strUserMailcap) )
    {
        bTemp =  file.Open(strUserMailcap);
    }
    else
    {
        if (delete_index) return false;
        bTemp = file.Create(strUserMailcap);

⌨️ 快捷键说明

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