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
This commit is contained in:
Václav Slavík
2000-01-16 00:31:26 +00:00
parent e0c734faa5
commit cdf339c9de
3 changed files with 128 additions and 22 deletions

View File

@@ -147,7 +147,9 @@ function in the first place.
If the function returns TRUE, the icon associated with this file type will be If the function returns TRUE, the icon associated with this file type will be
created and assigned to the {\it icon} parameter. 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} \membersection{wxFileType::GetDescription}\label{wxfiletypegetdescription}

View File

@@ -19,6 +19,9 @@ additional functions
\helpref{wxMimeTypesManager::ReadMimeTypes}{wxmimetypesmanagerreadmimetypes} are \helpref{wxMimeTypesManager::ReadMimeTypes}{wxmimetypesmanagerreadmimetypes} are
provided to load additional files. 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 NB: Currently, wxMimeTypesManager is limited to reading MIME type information
but it will support modifying it as well in the future versions. but it will support modifying it as well in the future versions.

View File

@@ -50,6 +50,7 @@
#include "wx/textfile.h" #include "wx/textfile.h"
#include "wx/dir.h" #include "wx/dir.h"
#include "wx/utils.h" #include "wx/utils.h"
#include "wx/tokenzr.h"
#endif // OS #endif // OS
#include "wx/mimetype.h" #include "wx/mimetype.h"
@@ -354,6 +355,11 @@ class wxMimeTypeIconHandler
{ {
public: public:
virtual bool GetIcon(const wxString& mimetype, wxIcon *icon) = 0; 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); WX_DEFINE_ARRAY(wxMimeTypeIconHandler *, ArrayIconHandlers);
@@ -363,6 +369,7 @@ class wxGNOMEIconHandler : public wxMimeTypeIconHandler
{ {
public: public:
virtual bool GetIcon(const wxString& mimetype, wxIcon *icon); virtual bool GetIcon(const wxString& mimetype, wxIcon *icon);
virtual void GetMimeInfoRecords(wxMimeTypesManagerImpl *manager) {}
private: private:
void Init(); void Init();
@@ -380,20 +387,28 @@ class wxKDEIconHandler : public wxMimeTypeIconHandler
{ {
public: public:
virtual bool GetIcon(const wxString& mimetype, wxIcon *icon); virtual bool GetIcon(const wxString& mimetype, wxIcon *icon);
virtual void GetMimeInfoRecords(wxMimeTypesManagerImpl *manager);
private: private:
void LoadLinksForMimeSubtype(const wxString& dirbase, void LoadLinksForMimeSubtype(const wxString& dirbase,
const wxString& subdir, const wxString& subdir,
const wxString& filename); const wxString& filename,
const wxArrayString& icondirs);
void LoadLinksForMimeType(const wxString& dirbase, void LoadLinksForMimeType(const wxString& dirbase,
const wxString& subdir); const wxString& subdir,
void LoadLinkFilesFromDir(const wxString& dirbase); const wxArrayString& icondirs);
void LoadLinkFilesFromDir(const wxString& dirbase,
const wxArrayString& icondirs);
void Init(); void Init();
static bool m_inited; static bool m_inited;
static wxSortedArrayString ms_mimetypes; static wxSortedArrayString ms_mimetypes;
static wxArrayString ms_icons; static wxArrayString ms_icons;
static wxArrayString ms_infoTypes;
static wxArrayString ms_infoDescriptions;
static wxArrayString ms_infoExtensions;
}; };
// this is the real wxMimeTypesManager for Unix // this is the real wxMimeTypesManager for Unix
@@ -1195,6 +1210,11 @@ bool wxKDEIconHandler::m_inited = FALSE;
wxSortedArrayString wxKDEIconHandler::ms_mimetypes; wxSortedArrayString wxKDEIconHandler::ms_mimetypes;
wxArrayString wxKDEIconHandler::ms_icons; wxArrayString wxKDEIconHandler::ms_icons;
wxArrayString wxKDEIconHandler::ms_infoTypes;
wxArrayString wxKDEIconHandler::ms_infoDescriptions;
wxArrayString wxKDEIconHandler::ms_infoExtensions;
ArrayIconHandlers wxMimeTypesManagerImpl::ms_iconHandlers; ArrayIconHandlers wxMimeTypesManagerImpl::ms_iconHandlers;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -1399,18 +1419,71 @@ bool wxGNOMEIconHandler::GetIcon(const wxString& mimetype, wxIcon *icon)
void wxKDEIconHandler::LoadLinksForMimeSubtype(const wxString& dirbase, void wxKDEIconHandler::LoadLinksForMimeSubtype(const wxString& dirbase,
const wxString& subdir, const wxString& subdir,
const wxString& filename) const wxString& filename,
const wxArrayString& icondirs)
{ {
wxFFile file(dirbase + filename); wxFFile file(dirbase + filename);
if ( !file.IsOpened() ) if ( !file.IsOpened() )
return; 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 // these files are small, slurp the entire file at once
wxString text; wxString text;
if ( !file.ReadAll(&text) ) if ( !file.ReadAll(&text) )
return; 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 ) if ( pos == wxNOT_FOUND )
{ {
// no icon info // no icon info
@@ -1419,7 +1492,7 @@ void wxKDEIconHandler::LoadLinksForMimeSubtype(const wxString& dirbase,
wxString icon; 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') ) while ( *pc && *pc != _T('\n') )
{ {
icon += *pc++; icon += *pc++;
@@ -1427,13 +1500,16 @@ void wxKDEIconHandler::LoadLinksForMimeSubtype(const wxString& dirbase,
if ( !!icon ) if ( !!icon )
{ {
// don't check that the file actually exists - would be too slow // we must check if the file exists because it may be stored
icon.Prepend(_T("/usr/share/icons/")); // in many locations, at least ~/.kde and $KDEDIR
size_t nDir, nDirs = icondirs.GetCount();
// construct mimetype from the directory name and the basename of the for ( nDir = 0; nDir < nDirs; nDir++ )
// file (it always has .kdelnk extension) if (wxFileExists(icondirs[nDir] + icon))
wxString mimetype; {
mimetype << subdir << _T('/') << filename.BeforeLast(_T('.')); icon.Prepend(icondirs[nDir]);
break;
}
if (nDir == nDirs) return; //does not exist
// do we already have this MIME type? // do we already have this MIME type?
int i = ms_mimetypes.Index(mimetype); int i = ms_mimetypes.Index(mimetype);
@@ -1452,7 +1528,8 @@ void wxKDEIconHandler::LoadLinksForMimeSubtype(const wxString& dirbase,
} }
void wxKDEIconHandler::LoadLinksForMimeType(const wxString& dirbase, void wxKDEIconHandler::LoadLinksForMimeType(const wxString& dirbase,
const wxString& subdir) const wxString& subdir,
const wxArrayString& icondirs)
{ {
wxString dirname = dirbase; wxString dirname = dirbase;
dirname += subdir; dirname += subdir;
@@ -1466,13 +1543,14 @@ void wxKDEIconHandler::LoadLinksForMimeType(const wxString& dirbase,
bool cont = dir.GetFirst(&filename, _T("*.kdelnk"), wxDIR_FILES); bool cont = dir.GetFirst(&filename, _T("*.kdelnk"), wxDIR_FILES);
while ( cont ) while ( cont )
{ {
LoadLinksForMimeSubtype(dirname, subdir, filename); LoadLinksForMimeSubtype(dirname, subdir, filename, icondirs);
cont = dir.GetNext(&filename); cont = dir.GetNext(&filename);
} }
} }
void wxKDEIconHandler::LoadLinkFilesFromDir(const wxString& dirbase) void wxKDEIconHandler::LoadLinkFilesFromDir(const wxString& dirbase,
const wxArrayString& icondirs)
{ {
wxASSERT_MSG( !!dirbase && !wxEndsWithPathSeparator(dirbase), wxASSERT_MSG( !!dirbase && !wxEndsWithPathSeparator(dirbase),
_T("base directory shouldn't end with a slash") ); _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); bool cont = dir.GetFirst(&subdir, wxEmptyString, wxDIR_DIRS);
while ( cont ) while ( cont )
{ {
LoadLinksForMimeType(dirname, subdir); LoadLinksForMimeType(dirname, subdir, icondirs);
cont = dir.GetNext(&subdir); cont = dir.GetNext(&subdir);
} }
@@ -1503,26 +1581,32 @@ void wxKDEIconHandler::LoadLinkFilesFromDir(const wxString& dirbase)
void wxKDEIconHandler::Init() void wxKDEIconHandler::Init()
{ {
wxArrayString dirs; 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 // the variable KDEDIR is set when KDE is running
const char *kdedir = getenv("KDEDIR"); const char *kdedir = getenv("KDEDIR");
if ( kdedir ) if ( kdedir )
{ {
dirs.Add(wxString(kdedir) + _T("/share")); dirs.Add(wxString(kdedir) + _T("/share"));
icondirs.Add(wxString(kdedir) + _T("/share/icons/"));
} }
else else
{ {
// try to guess KDEDIR // try to guess KDEDIR
dirs.Add(_T("/usr/share")); dirs.Add(_T("/usr/share"));
dirs.Add(_T("/opt/kde/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(); size_t nDirs = dirs.GetCount();
for ( size_t nDir = 0; nDir < nDirs; nDir++ ) for ( size_t nDir = 0; nDir < nDirs; nDir++ )
{ {
LoadLinkFilesFromDir(dirs[nDir]); LoadLinkFilesFromDir(dirs[nDir], icondirs);
} }
m_inited = TRUE; m_inited = TRUE;
@@ -1552,6 +1636,17 @@ bool wxKDEIconHandler::GetIcon(const wxString& mimetype, wxIcon *icon)
return TRUE; 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) // wxFileTypeImpl (Unix)
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -1711,6 +1806,12 @@ wxMimeTypesManagerImpl::wxMimeTypesManagerImpl()
if ( wxFile::Exists(strUserMimeTypes) ) { if ( wxFile::Exists(strUserMimeTypes) ) {
ReadMimeTypes(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 * wxFileType *