mimetype.cpp

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

CPP
2,012
字号
            int equal_pos = sTmp.Find( wxT('=') );
            if (equal_pos > 0)
            {
                wxString left_of_equal = sTmp.Left( equal_pos );
                const wxChar *right_of_equal = pc;
                right_of_equal += equal_pos+1; 
                
                if (left_of_equal == wxT("icon_filename"))
                {
                    // GNOME 2:
                    curIconFile = right_of_equal;
                    
                    wxFileName newFile( curIconFile );
                    if (newFile.IsRelative() || newFile.FileExists())
                    {
                        size_t nDirs = search_dirs.GetCount();
                        
                        for (size_t nDir = 0; nDir < nDirs; nDir++)
                        {
                            newFile.SetPath( search_dirs[nDir] );
                            newFile.AppendDir( wxT("pixmaps") );
                            newFile.AppendDir( wxT("document-icons") );
                            newFile.SetExt( wxT("png") );
                            if (newFile.FileExists())
                            {
                                curIconFile = newFile.GetFullPath();
                                // reorder search_dirs for speedup (fewer
                                // calls to FileExist() required)
                                if (nDir != 0)
                                {
                                    wxString tmp = search_dirs[nDir];
                                    search_dirs.RemoveAt( nDir );
                                    search_dirs.Insert( tmp, 0 );
                                }
                                break;
                            }
                        }
                    }
                }
                else if (left_of_equal == wxT("open"))
                {
                    sTmp = right_of_equal;
                    sTmp.Replace( wxT("%f"), wxT("%s") );
                    sTmp.Prepend( wxT("open=") );
                    entry->Add(sTmp);
                }
                else if (left_of_equal == wxT("view"))
                {
                    sTmp = right_of_equal;
                    sTmp.Replace( wxT("%f"), wxT("%s") );
                    sTmp.Prepend( wxT("view=") );
                    entry->Add(sTmp);
                }
                else if (left_of_equal == wxT("print"))
                {
                    sTmp = right_of_equal;
                    sTmp.Replace( wxT("%f"), wxT("%s") );
                    sTmp.Prepend( wxT("print=") );
                    entry->Add(sTmp);
                }
                else if (left_of_equal == wxT("description"))
                {
                    strDesc = right_of_equal;
                }
                else if (left_of_equal == wxT("short_list_application_ids_for_novice_user_level"))
                {
                    sTmp = right_of_equal;
                    if (sTmp.Contains( wxT(",") ))
                        sTmp = sTmp.BeforeFirst( wxT(',') );
                    sTmp.Prepend( wxT("open=") );
                    sTmp.Append( wxT(" %s") );
                    entry->Add(sTmp);
                }

            } // emd of has an equals sign
            else
            {
                // not a comment and not an equals sign
                if (sTmp.Contains(wxT('/')))
                {
                    // this is the start of the new mimetype
                    // overwrite any existing data
                    if (! curMimeType.empty())
                    {
                        AddToMimeData( curMimeType, curIconFile, entry, strExtensions, strDesc );

                        // now get ready for next bit
                        entry = new wxMimeTypeCommands;
                    }

                    curMimeType = sTmp.BeforeFirst(wxT(':'));
                }
            }
        } // end of not a comment

        // ignore blank lines
        nLine++;
    } // end of while, save any data

    if (! curMimeType.empty())
        AddToMimeData ( curMimeType, curIconFile, entry, strExtensions, strDesc);
}



void wxMimeTypesManagerImpl::LoadGnomeMimeTypesFromMimeFile(const wxString& filename)
{
    wxTextFile textfile(filename);
    if ( !textfile.Open() )
        return;

    wxLogTrace(TRACE_MIME,
               wxT("--- Opened Gnome file %s  ---"),
               filename.c_str());

    // values for the entry being parsed
    wxString curMimeType, curExtList;

    const wxChar *pc;
    size_t nLineCount = textfile.GetLineCount();
    for ( size_t nLine = 0;; nLine++ )
    {
        if ( nLine < nLineCount )
        {
            pc = textfile[nLine].c_str();
            if ( *pc == wxT('#') )
            {
                // skip comments
                continue;
            }
        }
        else
        {
            // so that we will fall into the "if" below
            pc = NULL;
        }

        if ( !pc || !*pc )
        {
            // end of the entry
            if ( !curMimeType.empty() && !curExtList.empty() )
            {
                 wxLogTrace(TRACE_MIME,
                            wxT("--- At end of Gnome file  finding mimetype %s  ---"),
                            curMimeType.c_str());

                 AddMimeTypeInfo(curMimeType, curExtList, wxEmptyString);
            }

            if ( !pc )
            {
                // the end - this can only happen if nLine == nLineCount
                break;
            }

            curExtList.Empty();

            continue;
        }

        // what do we have here?
        if ( *pc == wxT('\t') )
        {
            // this is a field=value ling
            pc++; // skip leading TAB

            static const int lenField = 5; // strlen("ext: ")
            if ( wxStrncmp(pc, wxT("ext: "), lenField) == 0 )
            {
                // skip it and take everything left until the end of line
                curExtList = pc + lenField;
            }
            //else: some other field, we don't care
        }
        else
        {
            // this is the start of the new section
            wxLogTrace(TRACE_MIME,
                       wxT("--- In Gnome file  finding mimetype %s  ---"),
                       curMimeType.c_str());

            if (! curMimeType.empty())
                AddMimeTypeInfo(curMimeType, curExtList, wxEmptyString);

            curMimeType.Empty();

            while ( *pc != wxT(':') && *pc != wxT('\0') )
            {
                curMimeType += *pc++;
            }
        }
    }
}


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

    wxString dirname = dirbase;
    dirname << wxT("/mime-info");

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

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

    // we will concatenate it with filename to get the full path below
    dirname += wxT('/');

    wxString filename;
    bool cont;
    cont = dir.GetFirst(&filename, _T("*.mime"), wxDIR_FILES);
    while ( cont )
    {
        LoadGnomeMimeTypesFromMimeFile(dirname + filename);

        cont = dir.GetNext(&filename);
    }

    cont = dir.GetFirst(&filename, _T("*.keys"), wxDIR_FILES);
    while ( cont )
    {
        LoadGnomeDataFromKeyFile(dirname + filename, dirs);

        cont = dir.GetNext(&filename);
    }

    // Hack alert: We scan all icons and deduce the
    //             mime-type from the file name.
    dirname = dirbase;
    dirname << wxT("/pixmaps/document-icons");

    // these are always empty in this file
    wxArrayString strExtensions;
    wxString strDesc;

    if ( !wxDir::Exists(dirname) )
    {
        // Jst test for default GPE dir also
        dirname = wxT("/usr/share/gpe/pixmaps/default/filemanager/document-icons");

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

    wxDir dir2( dirname );

    cont = dir2.GetFirst(&filename, wxT("gnome-*.png"), wxDIR_FILES);
    while ( cont )
    {
        wxString mimeType = filename;
        mimeType.Remove( 0, 6 ); // remove "gnome-"
        mimeType.Remove( mimeType.Len()-4, 4 ); // remove ".png"
        int pos = mimeType.Find( wxT("-") );
        if (pos != wxNOT_FOUND)
        {
            mimeType.SetChar( pos, wxT('/') );
            wxString iconFile = dirname;
            iconFile << wxT("/");
            iconFile << filename;
            AddToMimeData ( mimeType, iconFile, NULL, strExtensions, strDesc, true );
        }

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

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

    wxString gnomedir = wxGetenv( wxT("GNOMEDIR") );;
    if (!gnomedir.empty())
    {
        gnomedir << wxT("/share");
        dirs.Add( gnomedir );
    }

    dirs.Add(wxT("/usr/share"));
    dirs.Add(wxT("/usr/local/share"));

    gnomedir = wxGetHomeDir();
    gnomedir << wxT("/.gnome");
    dirs.Add( gnomedir );

    if (!sExtraDir.empty()) dirs.Add( sExtraDir );

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

// ----------------------------------------------------------------------------
// KDE
// ----------------------------------------------------------------------------


// KDE stores the icon info in its .kdelnk files. The file for mimetype/subtype
// may be found in either of the following locations
//
//  1. $KDEDIR/share/mimelnk/mimetype/subtype.kdelnk
//  2. ~/.kde/share/mimelnk/mimetype/subtype.kdelnk
//
// The format of a .kdelnk file is almost the same as the one used by
// wxFileConfig, i.e. there are groups, comments and entries. The icon is the
// value for the entry "Type"

// kde writing; see http://webcvs.kde.org/cgi-bin/cvsweb.cgi/~checkout~/kdelibs/kio/DESKTOP_ENTRY_STANDARD
// for now write to .kdelnk but should eventually do .desktop instead (in preference??)

bool wxMimeTypesManagerImpl::CheckKDEDirsExist ( const wxString &sOK, const wxString &sTest )
{
    if (sTest.empty())
    {
        if (wxDir::Exists(sOK))
            return true;
        else
            return false;
    }
    else
    {
        wxString sStart = sOK + wxT("/") + sTest.BeforeFirst(wxT('/'));
        if (!wxDir::Exists(sStart))  wxMkdir(sStart);
        wxString sEnd = sTest.AfterFirst(wxT('/'));
        return CheckKDEDirsExist(sStart, sEnd);
    }
}

bool wxMimeTypesManagerImpl::WriteKDEMimeFile(int index, bool delete_index)
{
    wxMimeTextFile appoutfile, mimeoutfile;
    wxString sHome = wxGetHomeDir();
    wxString sTmp = wxT(".kde/share/mimelnk/");
    wxString sMime = m_aTypes[index];
    CheckKDEDirsExist (sHome, sTmp + sMime.BeforeFirst(wxT('/')) );
    sTmp = sHome + wxT('/') + sTmp + sMime + wxT(".kdelnk");

    bool bTemp;
    bool bMimeExists = mimeoutfile.Open (sTmp);
    if (!bMimeExists)
    {
        bTemp = mimeoutfile.Create (sTmp);
        // some unknown error eg out of disk space
        if (!bTemp) return false;
    }

    sTmp = wxT(".kde/share/applnk/");
    CheckKDEDirsExist (sHome, sTmp + sMime.AfterFirst(wxT('/')) );
    sTmp = sHome + wxT('/') + sTmp + sMime.AfterFirst(wxT('/')) + wxT(".kdelnk");

    bool bAppExists;
    bAppExists = appoutfile.Open (sTmp);
    if (!bAppExists)
    {
        bTemp = appoutfile.Create (sTmp);
        // some unknown error eg out of disk space
        if (!bTemp) return false;
    }

    // fixed data; write if new file
    if (!bMimeExists)
    {
        mimeoutfile.AddLine(wxT("#KDE Config File"));
        mimeoutfile.AddLine(wxT("[KDE Desktop Entry]"));
        mimeoutfile.AddLine(wxT("Version=1.0"));
        mimeoutfile.AddLine(wxT("Type=MimeType"));
        mimeoutfile.AddLine(wxT("MimeType=") + sMime);
    }

    if (!bAppExists)
    {
        mimeoutfile.AddLine(wxT("#KDE Config File"));
        mimeoutfile.AddLine(wxT("[KDE Desktop Entry]"));
        appoutfile.AddLine(wxT("Version=1.0"));
        appoutfile.AddLine(wxT("Type=Application"));
        appoutfile.AddLine(wxT("MimeType=") + sMime + wxT(';'));
    }

    // variable data
    // ignore locale
    mimeoutfile.CommentLine(wxT("Comment="));
    if (!delete_index)
        mimeoutfile.AddLine(wxT("Comment=") + m_aDescriptions[index]);
    appoutfile.CommentLine(wxT("Name="));
    if (!delete_index)
        appoutfile.AddLine(wxT("Comment=") + m_aDescriptions[index]);

    sTmp = m_aIcons[index];
    // we can either give the full path, or the shortfilename if its in
    // one of the directories we search
    mimeoutfile.CommentLine(wxT("Icon=") );
    if (!delete_index) mimeoutfile.AddLine(wxT("Icon=") + sTmp );
    appoutfile.CommentLine(wxT("Icon=")  );
    if (!delete_index) appoutfile.AddLine(wxT("Icon=") + sTmp );

    sTmp = wxT(" ") + m_aExtensions[index];

⌨️ 快捷键说明

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