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 + -
显示快捷键?