From: Václav Slavík Date: Sun, 16 Jan 2000 00:31:26 +0000 (+0000) Subject: KDE support for icons and mime types finished (icons searched in more directories... X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/cdf339c9def7d24cb50385f93476aab4e485e32f KDE support for icons and mime types finished (icons searched in more directories, parsed .kdelnk files ever for mime types - mime.types or mailcap is no sufficient) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@5439 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/docs/latex/wx/filetype.tex b/docs/latex/wx/filetype.tex index 364850400f..2407c2f8b4 100644 --- a/docs/latex/wx/filetype.tex +++ b/docs/latex/wx/filetype.tex @@ -147,7 +147,9 @@ function in the first place. If the function returns TRUE, the icon associated with this file type will be created and assigned to the {\it icon} parameter. -{\bf Unix:} This function always returns FALSE under Unix. +{\bf Unix:} MIME manager gathers information about icons from GNOME +and KDE settings and thus GetIcon's success depends on availability +of these desktop environments. \membersection{wxFileType::GetDescription}\label{wxfiletypegetdescription} diff --git a/docs/latex/wx/mimetype.tex b/docs/latex/wx/mimetype.tex index 822e0a553c..cf0b0c9ea5 100644 --- a/docs/latex/wx/mimetype.tex +++ b/docs/latex/wx/mimetype.tex @@ -19,6 +19,9 @@ additional functions \helpref{wxMimeTypesManager::ReadMimeTypes}{wxmimetypesmanagerreadmimetypes} are provided to load additional files. +If GNOME or KDE desktop environment is installed, then wxMimeTypesManager +gathers MIME information from respective files (e.g. .kdelnk files under KDE). + NB: Currently, wxMimeTypesManager is limited to reading MIME type information but it will support modifying it as well in the future versions. diff --git a/src/common/mimetype.cpp b/src/common/mimetype.cpp index 3dab4f75fa..592606ec2d 100644 --- a/src/common/mimetype.cpp +++ b/src/common/mimetype.cpp @@ -50,6 +50,7 @@ #include "wx/textfile.h" #include "wx/dir.h" #include "wx/utils.h" + #include "wx/tokenzr.h" #endif // OS #include "wx/mimetype.h" @@ -354,6 +355,11 @@ class wxMimeTypeIconHandler { public: virtual bool GetIcon(const wxString& mimetype, wxIcon *icon) = 0; + + // this function fills manager with MIME types information gathered + // (as side effect) when searching for icons. This may be particularly + // useful if mime.types is incomplete (e.g. RedHat distributions). + virtual void GetMimeInfoRecords(wxMimeTypesManagerImpl *manager) = 0; }; WX_DEFINE_ARRAY(wxMimeTypeIconHandler *, ArrayIconHandlers); @@ -363,7 +369,8 @@ class wxGNOMEIconHandler : public wxMimeTypeIconHandler { public: virtual bool GetIcon(const wxString& mimetype, wxIcon *icon); - + virtual void GetMimeInfoRecords(wxMimeTypesManagerImpl *manager) {} + private: void Init(); void LoadIconsFromKeyFile(const wxString& filename); @@ -380,20 +387,28 @@ class wxKDEIconHandler : public wxMimeTypeIconHandler { public: virtual bool GetIcon(const wxString& mimetype, wxIcon *icon); + virtual void GetMimeInfoRecords(wxMimeTypesManagerImpl *manager); private: void LoadLinksForMimeSubtype(const wxString& dirbase, const wxString& subdir, - const wxString& filename); + const wxString& filename, + const wxArrayString& icondirs); void LoadLinksForMimeType(const wxString& dirbase, - const wxString& subdir); - void LoadLinkFilesFromDir(const wxString& dirbase); + const wxString& subdir, + const wxArrayString& icondirs); + void LoadLinkFilesFromDir(const wxString& dirbase, + const wxArrayString& icondirs); void Init(); static bool m_inited; static wxSortedArrayString ms_mimetypes; static wxArrayString ms_icons; + + static wxArrayString ms_infoTypes; + static wxArrayString ms_infoDescriptions; + static wxArrayString ms_infoExtensions; }; // this is the real wxMimeTypesManager for Unix @@ -1195,6 +1210,11 @@ bool wxKDEIconHandler::m_inited = FALSE; wxSortedArrayString wxKDEIconHandler::ms_mimetypes; wxArrayString wxKDEIconHandler::ms_icons; +wxArrayString wxKDEIconHandler::ms_infoTypes; +wxArrayString wxKDEIconHandler::ms_infoDescriptions; +wxArrayString wxKDEIconHandler::ms_infoExtensions; + + ArrayIconHandlers wxMimeTypesManagerImpl::ms_iconHandlers; // ---------------------------------------------------------------------------- @@ -1399,18 +1419,71 @@ bool wxGNOMEIconHandler::GetIcon(const wxString& mimetype, wxIcon *icon) void wxKDEIconHandler::LoadLinksForMimeSubtype(const wxString& dirbase, const wxString& subdir, - const wxString& filename) + const wxString& filename, + const wxArrayString& icondirs) { wxFFile file(dirbase + filename); if ( !file.IsOpened() ) return; + // construct mimetype from the directory name and the basename of the + // file (it always has .kdelnk extension) + wxString mimetype; + mimetype << subdir << _T('/') << filename.BeforeLast(_T('.')); + // these files are small, slurp the entire file at once wxString text; if ( !file.ReadAll(&text) ) return; - int pos = text.Find(_T("Icon=")); + int pos; + const wxChar *pc; + + // before trying to find an icon, grab mimetype information + // (because BFU's machine would hardly have well-edited mime.types but (s)he might + // have edited it in control panel...) + + wxString mime_extension, mime_desc; + + pos = wxNOT_FOUND; + if (wxGetLocale() != NULL) + mime_desc = _T("Comment[") + wxGetLocale()->GetName() + _T("]="); + if (pos == wxNOT_FOUND) mime_desc = _T("Comment="); + pos = text.Find(mime_desc); + if (pos == wxNOT_FOUND) mime_desc = wxEmptyString; + else + { + pc = text.c_str() + pos + mime_desc.Length(); + mime_desc = wxEmptyString; + while ( *pc && *pc != _T('\n') ) mime_desc += *pc++; + } + + pos = text.Find(_T("Patterns=")); + if (pos != wxNOT_FOUND) + { + wxString exts; + pc = text.c_str() + pos + 9; + while ( *pc && *pc != _T('\n') ) exts += *pc++; + wxStringTokenizer tokenizer(exts, _T(";")); + wxString e; + + while (tokenizer.HasMoreTokens()) + { + e = tokenizer.GetNextToken(); + if (e.Left(2) != _T("*.")) continue; // don't support too difficult patterns + mime_extension << e.Mid(2); + mime_extension << _T(' '); + } + mime_extension.RemoveLast(); + } + + ms_infoTypes.Add(mimetype); + ms_infoDescriptions.Add(mime_desc); + ms_infoExtensions.Add(mime_extension); + + // ok, now we can take care of icon: + + pos = text.Find(_T("Icon=")); if ( pos == wxNOT_FOUND ) { // no icon info @@ -1419,7 +1492,7 @@ void wxKDEIconHandler::LoadLinksForMimeSubtype(const wxString& dirbase, wxString icon; - const wxChar *pc = text.c_str() + pos + 5; // 5 == strlen("Icon=") + pc = text.c_str() + pos + 5; // 5 == strlen("Icon=") while ( *pc && *pc != _T('\n') ) { icon += *pc++; @@ -1427,13 +1500,16 @@ void wxKDEIconHandler::LoadLinksForMimeSubtype(const wxString& dirbase, if ( !!icon ) { - // don't check that the file actually exists - would be too slow - icon.Prepend(_T("/usr/share/icons/")); - - // construct mimetype from the directory name and the basename of the - // file (it always has .kdelnk extension) - wxString mimetype; - mimetype << subdir << _T('/') << filename.BeforeLast(_T('.')); + // 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++ ) + if (wxFileExists(icondirs[nDir] + icon)) + { + icon.Prepend(icondirs[nDir]); + break; + } + if (nDir == nDirs) return; //does not exist // do we already have this MIME type? int i = ms_mimetypes.Index(mimetype); @@ -1452,7 +1528,8 @@ void wxKDEIconHandler::LoadLinksForMimeSubtype(const wxString& dirbase, } void wxKDEIconHandler::LoadLinksForMimeType(const wxString& dirbase, - const wxString& subdir) + const wxString& subdir, + const wxArrayString& icondirs) { wxString dirname = dirbase; dirname += subdir; @@ -1466,13 +1543,14 @@ void wxKDEIconHandler::LoadLinksForMimeType(const wxString& dirbase, bool cont = dir.GetFirst(&filename, _T("*.kdelnk"), wxDIR_FILES); while ( cont ) { - LoadLinksForMimeSubtype(dirname, subdir, filename); + LoadLinksForMimeSubtype(dirname, subdir, filename, icondirs); cont = dir.GetNext(&filename); } } -void wxKDEIconHandler::LoadLinkFilesFromDir(const wxString& dirbase) +void wxKDEIconHandler::LoadLinkFilesFromDir(const wxString& dirbase, + const wxArrayString& icondirs) { wxASSERT_MSG( !!dirbase && !wxEndsWithPathSeparator(dirbase), _T("base directory shouldn't end with a slash") ); @@ -1494,7 +1572,7 @@ void wxKDEIconHandler::LoadLinkFilesFromDir(const wxString& dirbase) bool cont = dir.GetFirst(&subdir, wxEmptyString, wxDIR_DIRS); while ( cont ) { - LoadLinksForMimeType(dirname, subdir); + LoadLinksForMimeType(dirname, subdir, icondirs); cont = dir.GetNext(&subdir); } @@ -1503,26 +1581,32 @@ void wxKDEIconHandler::LoadLinkFilesFromDir(const wxString& dirbase) void wxKDEIconHandler::Init() { wxArrayString dirs; + wxArrayString icondirs; + + // settings in ~/.kde have maximal priority + dirs.Add(wxGetHomeDir() + _T("/.kde/share")); + icondirs.Add(wxGetHomeDir() + _T("/.kde/share/icons/")); // the variable KDEDIR is set when KDE is running const char *kdedir = getenv("KDEDIR"); if ( kdedir ) { dirs.Add(wxString(kdedir) + _T("/share")); + icondirs.Add(wxString(kdedir) + _T("/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("/opt/kde/share/icons/")); } - dirs.Add(wxGetHomeDir() + _T("/.kde/share")); - size_t nDirs = dirs.GetCount(); for ( size_t nDir = 0; nDir < nDirs; nDir++ ) { - LoadLinkFilesFromDir(dirs[nDir]); + LoadLinkFilesFromDir(dirs[nDir], icondirs); } m_inited = TRUE; @@ -1552,6 +1636,17 @@ bool wxKDEIconHandler::GetIcon(const wxString& mimetype, wxIcon *icon) return TRUE; } + +void wxKDEIconHandler::GetMimeInfoRecords(wxMimeTypesManagerImpl *manager) +{ + if ( !m_inited ) Init(); + + size_t cnt = ms_infoTypes.GetCount(); + for (unsigned i = 0; i < cnt; i++) + manager -> AddMimeTypeInfo(ms_infoTypes[i], ms_infoExtensions[i], ms_infoDescriptions[i]); +} + + // ---------------------------------------------------------------------------- // wxFileTypeImpl (Unix) // ---------------------------------------------------------------------------- @@ -1711,6 +1806,12 @@ wxMimeTypesManagerImpl::wxMimeTypesManagerImpl() if ( wxFile::Exists(strUserMimeTypes) ) { ReadMimeTypes(strUserMimeTypes); } + + // read KDE/GNOME tables + ArrayIconHandlers& handlers = GetIconHandlers(); + size_t count = handlers.GetCount(); + for ( size_t n = 0; n < count; n++ ) + handlers[n]->GetMimeInfoRecords(this); } wxFileType *