mimetype.cpp

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

CPP
2,012
字号

    wxStringTokenizer tokenizer(sTmp, _T(" "));
    sTmp = wxT("Patterns=");
    mimeoutfile.CommentLine(sTmp);
    while ( tokenizer.HasMoreTokens() )
    {
        // holds an extension; need to change it to *.ext;
        wxString e = wxT("*.") + tokenizer.GetNextToken() + wxT(";");
        sTmp = sTmp + e;
    }
    if (!delete_index) mimeoutfile.AddLine(sTmp);

    wxMimeTypeCommands * entries = m_aEntries[index];
    // if we don't find open just have an empty string ... FIX this
    sTmp = entries->GetCommandForVerb(_T("open"));
    sTmp.Replace( wxT("%s"), wxT("%f") );

    mimeoutfile.CommentLine(wxT("DefaultApp=") );
    if (!delete_index) mimeoutfile.AddLine(wxT("DefaultApp=") + sTmp);

    sTmp.Replace( wxT("%f"), wxT("") );
    appoutfile.CommentLine(wxT("Exec="));
    if (!delete_index) appoutfile.AddLine(wxT("Exec=") + sTmp);

    if (entries->GetCount() > 1)
    {
        //other actions as well as open

    }
    bTemp = false;
    if (mimeoutfile.Write ()) bTemp = true;
    mimeoutfile.Close ();
    if (appoutfile.Write ()) bTemp = true;
    appoutfile.Close ();

    return bTemp;
}

void wxMimeTypesManagerImpl::LoadKDELinksForMimeSubtype(const wxString& dirbase,
                                               const wxString& subdir,
                                               const wxString& filename,
                                               const wxArrayString& icondirs)
{
    wxMimeTextFile file;
    if ( !file.Open(dirbase + filename) ) return;

    wxLogTrace(TRACE_MIME, wxT("loading KDE file %s"),
                           (dirbase+filename).c_str());

    wxMimeTypeCommands * entry = new wxMimeTypeCommands;
    wxArrayString sExts;
    wxString mimetype, mime_desc, strIcon;

    int nIndex = file.pIndexOf( wxT("MimeType=") );
    if (nIndex == wxNOT_FOUND)
    {
        // construct mimetype from the directory name and the basename of the
        // file (it always has .kdelnk extension)
        mimetype << subdir << wxT('/') << filename.BeforeLast( wxT('.') );
    }
    else mimetype = file.GetCmd (nIndex);

    // first find the description string: it is the value in either "Comment="
    // line or "Comment[<locale_name>]=" one
    nIndex = wxNOT_FOUND;

    wxString comment;
#if wxUSE_INTL
    wxLocale *locale = wxGetLocale();
    if ( locale )
    {
        // try "Comment[locale name]" first
        comment << _T("Comment[") + locale->GetName() + _T("]=");
        nIndex = file.pIndexOf(comment);
    }
#endif // wxUSE_INTL

    if ( nIndex == wxNOT_FOUND )
    {
        comment = _T("Comment=");
        nIndex = file.pIndexOf(comment);
    }

    if ( nIndex != wxNOT_FOUND ) mime_desc = file.GetCmd(nIndex);
    //else: no description

    // next find the extensions
    wxString mime_extension;

    nIndex = file.pIndexOf(_T("Patterns="));
    if ( nIndex != wxNOT_FOUND )
    {
        wxString exts = file.GetCmd (nIndex);

        wxStringTokenizer tokenizer(exts, _T(";"));
        while ( tokenizer.HasMoreTokens() )
        {
            wxString e = tokenizer.GetNextToken();
            if ( e.Left(2) != _T("*.") )
                continue; // don't support too difficult patterns

            if ( !mime_extension.empty() )
            {
                // separate from the previous ext
                mime_extension << _T(' ');
            }

            mime_extension << e.Mid(2);
        }
    }
    sExts.Add(mime_extension);

    // ok, now we can take care of icon:

    nIndex = file.pIndexOf(_T("Icon="));
    if ( nIndex != wxNOT_FOUND )
    {
        strIcon = file.GetCmd(nIndex);
        wxLogTrace(TRACE_MIME, wxT("  icon %s"), strIcon.c_str());
        //it could be the real path, but more often a short name


        if (!wxFileExists(strIcon))
        {
            // icon is just the short name
            if ( !strIcon.empty() )
            {
                // we must check if the file exists because it may be stored
                // in many locations, at least ~/.kde and $KDEDIR
                size_t nDir, nDirs = icondirs.GetCount();
                for ( nDir = 0; nDir < nDirs; nDir++ )
                {
                    wxFileName fnameIcon( strIcon );
                    wxFileName fname( icondirs[nDir], fnameIcon.GetName() );
                    fname.SetExt( wxT("png") );
                    if (fname.FileExists())
                    {
                        strIcon = fname.GetFullPath();
                        wxLogTrace(TRACE_MIME, wxT("  iconfile %s"), strIcon.c_str());
                        break;
                    }
                }
            }
        }
    }
    // now look for lines which know about the application
    // exec= or DefaultApp=

    nIndex = file.pIndexOf(wxT("DefaultApp"));

    if ( nIndex == wxNOT_FOUND )
    {
        // no entry try exec
        nIndex = file.pIndexOf(wxT("Exec"));
    }

    if ( nIndex != wxNOT_FOUND )
    {
        wxString sTmp = file.GetCmd(nIndex);
        // we expect %f; others including  %F and %U and %u are possible
        if (0 == sTmp.Replace ( wxT("%f"), wxT("%s") ))
            sTmp = sTmp + wxT(" %s");
        entry->AddOrReplaceVerb (wxString(wxT("open")), sTmp );
    }

    AddToMimeData (mimetype, strIcon, entry, sExts, mime_desc);
}

void wxMimeTypesManagerImpl::LoadKDELinksForMimeType(const wxString& dirbase,
                                            const wxString& subdir,
                                            const wxArrayString& icondirs)
{
    wxString dirname = dirbase;
    dirname += subdir;
    wxDir dir(dirname);
    if ( !dir.IsOpened() )
        return;

    wxLogTrace(TRACE_MIME, wxT("--- Loading from KDE directory %s  ---"),
                           dirname.c_str());

    dirname += _T('/');

    wxString filename;
    bool cont = dir.GetFirst(&filename, _T("*.kdelnk"), wxDIR_FILES);
    while ( cont )
    {
        LoadKDELinksForMimeSubtype(dirname, subdir, filename, icondirs);

        cont = dir.GetNext(&filename);
    }
    // new standard for Gnome and KDE
    cont = dir.GetFirst(&filename, _T("*.desktop"), wxDIR_FILES);
    while ( cont )
    {
        LoadKDELinksForMimeSubtype(dirname, subdir, filename, icondirs);

        cont = dir.GetNext(&filename);
    }
}

void wxMimeTypesManagerImpl::LoadKDELinkFilesFromDir(const wxString& dirbase,
                                            const wxArrayString& icondirs)
{
    wxASSERT_MSG( !dirbase.empty() && !wxEndsWithPathSeparator(dirbase),
                  _T("base directory shouldn't end with a slash") );

    wxString dirname = dirbase;
    dirname << _T("/mimelnk");

    if ( !wxDir::Exists(dirname) )
        return;

    wxDir dir(dirname);
    if ( !dir.IsOpened() )
        return;

    // we will concatenate it with dir name to get the full path below
    dirname += _T('/');

    wxString subdir;
    bool cont = dir.GetFirst(&subdir, wxEmptyString, wxDIR_DIRS);
    while ( cont )
    {
        LoadKDELinksForMimeType(dirname, subdir, icondirs);

        cont = dir.GetNext(&subdir);
    }
}

void wxMimeTypesManagerImpl::GetKDEMimeInfo(const wxString& sExtraDir)
{
    wxArrayString dirs;
    wxArrayString icondirs;

    // FIXME: This code is heavily broken. There are three bugs in it:
    //        1) it uses only KDEDIR, which is deprecated, instead of using
    //           list of paths from KDEDIRS and using KDEDIR only if KDEDIRS
    //           is not set
    //        2) it doesn't look into ~/.kde/share/config/kdeglobals where
    //           user's settings are stored and thus *ignores* user's settings
    //           instead of respecting them
    //        3) it "tries to guess KDEDIR" and "tries a few likely theme
    //           names", both of which is completely arbitrary; instead, the
    //           code should give up if KDEDIR(S) is not set and/or the icon
    //           theme cannot be determined, because it means that the user is
    //           not using KDE (and thus is not interested in KDE icons anyway)

    // the variable $KDEDIR is set when KDE is running
    wxString kdedir = wxGetenv( wxT("KDEDIR") );

    if (!kdedir.empty())
    {
        // $(KDEDIR)/share/config/kdeglobals holds info
        // the current icons theme
        wxFileName configFile( kdedir, wxEmptyString );
        configFile.AppendDir( wxT("share") );
        configFile.AppendDir( wxT("config") );
        configFile.SetName( wxT("kdeglobals") );

        wxTextFile config;
        if (configFile.FileExists() && config.Open(configFile.GetFullPath()))
        {
            // $(KDEDIR)/share/config -> $(KDEDIR)/share
            configFile.RemoveDir( configFile.GetDirCount()-1 );
            // $(KDEDIR)/share/ -> $(KDEDIR)/share/icons
            configFile.AppendDir( wxT("icons") );

            // Check for entry
            wxString theme(wxT("default.kde"));
            size_t cnt = config.GetLineCount();
            for (size_t i = 0; i < cnt; i++)
            {
                if (config[i].StartsWith(wxT("Theme="), &theme/*rest*/))
                    break;
            }
            configFile.AppendDir(theme);
        }
        else
        {
            // $(KDEDIR)/share/config -> $(KDEDIR)/share
            configFile.RemoveDir( configFile.GetDirCount()-1 );
            // $(KDEDIR)/share/ -> $(KDEDIR)/share/icons
            configFile.AppendDir( wxT("icons") );
            // $(KDEDIR)/share/icons -> $(KDEDIR)/share/icons/default.kde
            configFile.AppendDir( wxT("default.kde") );
        }

        configFile.SetName( wxEmptyString );
        configFile.AppendDir( wxT("32x32") );
        configFile.AppendDir( wxT("mimetypes") );

        // Just try a few likely icons theme names

        int pos = configFile.GetDirCount()-3;

        if (!wxDir::Exists(configFile.GetPath()))
        {
            configFile.RemoveDir( pos );
            configFile.InsertDir( pos, wxT("default.kde") );
        }

        if (!wxDir::Exists(configFile.GetPath()))
        {
            configFile.RemoveDir( pos );
            configFile.InsertDir( pos, wxT("default") );
        }

        if (!wxDir::Exists(configFile.GetPath()))
        {
            configFile.RemoveDir( pos );
            configFile.InsertDir( pos, wxT("crystalsvg") );
        }

        if (!wxDir::Exists(configFile.GetPath()))
        {
            configFile.RemoveDir( pos );
            configFile.InsertDir( pos, wxT("crystal") );
        }

        if (wxDir::Exists(configFile.GetPath()))
            icondirs.Add( configFile.GetFullPath() );
    }

    // settings in ~/.kde have maximal priority
    dirs.Add(wxGetHomeDir() + wxT("/.kde/share"));
    icondirs.Add(wxGetHomeDir() + wxT("/.kde/share/icons/"));

    if (kdedir)
    {
        dirs.Add( wxString(kdedir) + wxT("/share") );
        icondirs.Add( wxString(kdedir) + wxT("/share/icons/") );
    }
    else
    {
        // try to guess KDEDIR
        dirs.Add(_T("/usr/share"));
        dirs.Add(_T("/opt/kde/share"));
        icondirs.Add(_T("/usr/share/icons/"));
        icondirs.Add(_T("/usr/X11R6/share/icons/")); // Debian/Corel linux
        icondirs.Add(_T("/opt/kde/share/icons/"));
    }

    if (!sExtraDir.empty()) dirs.Add (sExtraDir);
    icondirs.Add(sExtraDir + wxT("/icons"));

    size_t nDirs = dirs.GetCount();
    for ( size_t nDir = 0; nDir < nDirs; nDir++ )
    {
        LoadKDELinkFilesFromDir(dirs[nDir], icondirs);
    }
}

// ----------------------------------------------------------------------------
// wxFileTypeImpl (Unix)
// ----------------------------------------------------------------------------

wxString wxFileTypeImpl::GetExpandedCommand(const wxString & verb, const wxFileType::MessageParameters& params) const
{
    wxString sTmp;
    size_t i = 0;
    while ( (i < m_index.GetCount() ) && sTmp.empty() )
    {
            sTmp = m_manager->GetCommand ( verb, m_index[i] );
            i ++;
    }

    return wxFileType::ExpandCommand(sTmp, params);
}

bool wxFileTypeImpl::GetIcon(wxIconLocation *iconLoc) const

{
    wxString sTmp;
    size_t i = 0;
    while ( (i < m_index.GetCount() ) && sTmp.empty() )
    {
        sTmp = m_manager->m_aIcons[m_index[i]];
        i ++;
    }
    if ( sTmp.empty () )
        return false;

    if ( iconLoc )
    {
        iconLoc->SetFileName(sTmp);
    }

    return true;
}


bool
wxFileTypeImpl::GetMimeTypes(wxArrayString& mimeTypes) const
{
    mimeTypes.Clear();
    for (size_t i = 0; i < m_index.GetCount(); i++)
        mimeTypes.Add(m_manager->m_aTypes[m_index[i]]);
    return true;
}


size_t wxFileTypeImpl::GetAllCommands(wxArrayString *verbs,

⌨️ 快捷键说明

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