From 4d2976ad6b56ff1650e15f2b949c10ec92385309 Mon Sep 17 00:00:00 2001 From: =?utf8?q?V=C3=A1clav=20Slav=C3=ADk?= Date: Sun, 23 Jan 2000 01:03:17 +0000 Subject: [PATCH] added wxFileType::GetMimeTypes git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@5601 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/latex/wx/filetype.tex | 10 ++ include/wx/mac/mimetype.h | 1 + include/wx/mimetype.h | 1 + include/wx/msw/mimetype.h | 3 +- include/wx/unix/mimetype.h | 11 ++- src/common/mimecmn.cpp | 5 + src/mac/carbon/mimetype.cpp | 14 +++ src/mac/mimetype.cpp | 14 +++ src/msw/mimetype.cpp | 18 +++- src/unix/mimetype.cpp | 192 +++++++++++++++++++++++++++++++----- 10 files changed, 236 insertions(+), 33 deletions(-) diff --git a/docs/latex/wx/filetype.tex b/docs/latex/wx/filetype.tex index 2407c2f8b4..c76595f4b2 100644 --- a/docs/latex/wx/filetype.tex +++ b/docs/latex/wx/filetype.tex @@ -125,6 +125,16 @@ The destructor of this class is not virtual, so it should not be derived from. If the function returns TRUE, the string pointed to by {\it mimeType} is filled with full MIME type specification for this file type: for example, "text/plain". +\membersection{wxFileType::GetMimeTypes}\label{wxfiletypegetmimetypes} + +\func{bool}{GetMimeType}{\param{wxArrayString&}{ mimeTypes}} + +Same as \helpref{GetMimeType}{wxfiletypegetmimetype} but returns array of MIME +types. This array will contain only one item in most cases but sometimes, +notably under Unix with KDE, may contain more MIME types. This happens when +one file extension is mapped to different MIME types by KDE, mailcap and +mime.types. + \membersection{wxFileType::GetExtensions}\label{wxfiletypegetextensions} \func{bool}{GetExtensions}{\param{wxArrayString\&}{ extensions}} diff --git a/include/wx/mac/mimetype.h b/include/wx/mac/mimetype.h index 9f88165669..3eaebfdf3b 100644 --- a/include/wx/mac/mimetype.h +++ b/include/wx/mac/mimetype.h @@ -51,6 +51,7 @@ public: // implement accessor functions bool GetExtensions(wxArrayString& extensions); bool GetMimeType(wxString *mimeType) const; + bool GetMimeTypes(wxArrayString& mimeTypes) const; bool GetIcon(wxIcon *icon) const; bool GetDescription(wxString *desc) const; bool GetOpenCommand(wxString *openCmd, diff --git a/include/wx/mimetype.h b/include/wx/mimetype.h index 0626bba4d4..58a6bf7e2d 100644 --- a/include/wx/mimetype.h +++ b/include/wx/mimetype.h @@ -75,6 +75,7 @@ public: // parameters are unchanged) // return the MIME type for this file type bool GetMimeType(wxString *mimeType) const; + bool GetMimeTypes(wxArrayString& mimeTypes) const; // fill passed in array with all extensions associated with this file // type bool GetExtensions(wxArrayString& extensions); diff --git a/include/wx/msw/mimetype.h b/include/wx/msw/mimetype.h index 5b069f9d5e..605c00fe01 100644 --- a/include/wx/msw/mimetype.h +++ b/include/wx/msw/mimetype.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: wx/mimetype.h +// Name: wx/msw/mimetype.h // Purpose: classes and functions to manage MIME types // Author: Vadim Zeitlin // Modified by: @@ -43,6 +43,7 @@ public: // implement accessor functions bool GetExtensions(wxArrayString& extensions); bool GetMimeType(wxString *mimeType) const; + bool GetMimeTypes(wxArrayString& mimeTypes) const; bool GetIcon(wxIcon *icon) const; bool GetDescription(wxString *desc) const; bool GetOpenCommand(wxString *openCmd, diff --git a/include/wx/unix/mimetype.h b/include/wx/unix/mimetype.h index 2677c1ffe7..3b9bcab6cd 100644 --- a/include/wx/unix/mimetype.h +++ b/include/wx/unix/mimetype.h @@ -76,20 +76,23 @@ private: static ArrayIconHandlers ms_iconHandlers; }; + + class WXDLLEXPORT wxFileTypeImpl { public: // initialization functions void Init(wxMimeTypesManagerImpl *manager, size_t index) - { m_manager = manager; m_index = index; } + { m_manager = manager; m_index.Add(index); } // accessors bool GetExtensions(wxArrayString& extensions); bool GetMimeType(wxString *mimeType) const - { *mimeType = m_manager->m_aTypes[m_index]; return TRUE; } + { *mimeType = m_manager->m_aTypes[m_index[0]]; return TRUE; } + bool GetMimeTypes(wxArrayString& mimeTypes) const; bool GetIcon(wxIcon *icon) const; bool GetDescription(wxString *desc) const - { *desc = m_manager->m_aDescriptions[m_index]; return TRUE; } + { *desc = m_manager->m_aDescriptions[m_index[0]]; return TRUE; } bool GetOpenCommand(wxString *openCmd, const wxFileType::MessageParameters& params) const @@ -113,7 +116,7 @@ private: bool open) const; wxMimeTypesManagerImpl *m_manager; - size_t m_index; // in the wxMimeTypesManagerImpl arrays + wxArrayInt m_index; // in the wxMimeTypesManagerImpl arrays }; diff --git a/src/common/mimecmn.cpp b/src/common/mimecmn.cpp index b3aaa70eaf..dc28cce7a5 100644 --- a/src/common/mimecmn.cpp +++ b/src/common/mimecmn.cpp @@ -217,6 +217,11 @@ bool wxFileType::GetMimeType(wxString *mimeType) const return m_impl->GetMimeType(mimeType); } +bool wxFileType::GetMimeTypes(wxArrayString& mimeTypes) const +{ + return m_impl->GetMimeTypes(mimeTypes); +} + bool wxFileType::GetIcon(wxIcon *icon) const { return m_impl->GetIcon(icon); diff --git a/src/mac/carbon/mimetype.cpp b/src/mac/carbon/mimetype.cpp index c4944d12f8..77e60cbc20 100644 --- a/src/mac/carbon/mimetype.cpp +++ b/src/mac/carbon/mimetype.cpp @@ -73,6 +73,20 @@ bool wxFileTypeImpl::GetMimeType(wxString *mimeType) const return FALSE; } +bool wxFileTypeImpl::GetMimeTypes(wxArrayString& mimeTypes) const +{ + wxString s; + + if (GetMimeType(&s)) + { + mimeTypes.Clear(); + mimeTypes.Add(s); + return TRUE; + } + else + return FALSE; +} + bool wxFileTypeImpl::GetIcon(wxIcon *icon) const { // no such file type or no value or incorrect icon entry diff --git a/src/mac/mimetype.cpp b/src/mac/mimetype.cpp index c4944d12f8..77e60cbc20 100644 --- a/src/mac/mimetype.cpp +++ b/src/mac/mimetype.cpp @@ -73,6 +73,20 @@ bool wxFileTypeImpl::GetMimeType(wxString *mimeType) const return FALSE; } +bool wxFileTypeImpl::GetMimeTypes(wxArrayString& mimeTypes) const +{ + wxString s; + + if (GetMimeType(&s)) + { + mimeTypes.Clear(); + mimeTypes.Add(s); + return TRUE; + } + else + return FALSE; +} + bool wxFileTypeImpl::GetIcon(wxIcon *icon) const { // no such file type or no value or incorrect icon entry diff --git a/src/msw/mimetype.cpp b/src/msw/mimetype.cpp index 1efa93f7a8..e78a77cac0 100644 --- a/src/msw/mimetype.cpp +++ b/src/msw/mimetype.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: common/mimetype.cpp +// Name: msw/mimetype.cpp // Purpose: classes and functions to manage MIME types // Author: Vadim Zeitlin // Modified by: @@ -235,6 +235,22 @@ bool wxFileTypeImpl::GetMimeType(wxString *mimeType) const } } + +bool wxFileTypeImpl::GetMimeTypes(wxArrayString& mimeTypes) const +{ + wxString s; + + if (GetMimeType(&s)) + { + mimeTypes.Clear(); + mimeTypes.Add(s); + return TRUE; + } + else + return FALSE; +} + + bool wxFileTypeImpl::GetIcon(wxIcon *icon) const { #if wxUSE_GUI diff --git a/src/unix/mimetype.cpp b/src/unix/mimetype.cpp index 95d459d3bb..8130ffda6e 100644 --- a/src/unix/mimetype.cpp +++ b/src/unix/mimetype.cpp @@ -208,13 +208,16 @@ class wxGNOMEIconHandler : public wxMimeTypeIconHandler { public: virtual bool GetIcon(const wxString& mimetype, wxIcon *icon); - virtual void GetMimeInfoRecords(wxMimeTypesManagerImpl *manager) {} + virtual void GetMimeInfoRecords(wxMimeTypesManagerImpl *manager); private: void Init(); void LoadIconsFromKeyFile(const wxString& filename); void LoadKeyFilesFromDir(const wxString& dirbase); + void LoadMimeTypesFromMimeFile(const wxString& filename, wxMimeTypesManagerImpl *manager); + void LoadMimeFilesFromDir(const wxString& dirbase, wxMimeTypesManagerImpl *manager); + static bool m_inited; static wxSortedArrayString ms_mimetypes; @@ -375,21 +378,116 @@ void wxGNOMEIconHandler::LoadIconsFromKeyFile(const wxString& filename) { curMimeType += *pc++; } + } + } +} + +void wxGNOMEIconHandler::LoadKeyFilesFromDir(const wxString& dirbase) +{ + wxASSERT_MSG( !!dirbase && !wxEndsWithPathSeparator(dirbase), + _T("base directory shouldn't end with a slash") ); + + wxString dirname = dirbase; + dirname << _T("/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 += _T('/'); + + wxString filename; + bool cont = dir.GetFirst(&filename, _T("*.keys"), wxDIR_FILES); + while ( cont ) + { + LoadIconsFromKeyFile(dirname + filename); + + cont = dir.GetNext(&filename); + } +} + + +void wxGNOMEIconHandler::LoadMimeTypesFromMimeFile(const wxString& filename, wxMimeTypesManagerImpl *manager) +{ + wxTextFile textfile(filename); + if ( !textfile.Open() ) + return; + + // 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 == _T('#') ) + { + // skip comments + continue; + } + } + else + { + // so that we will fall into the "if" below + pc = NULL; + } - if ( !*pc ) + if ( !pc || !*pc ) + { + // end of the entry + if ( !!curMimeType && !!curExtList ) { - // we reached the end of line without finding the colon, - // something is wrong - ignore this line completely - wxLogDebug(_T("Unreckognized line %d in file '%s' ignored"), - nLine + 1, filename.c_str()); + manager -> 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 == _T('\t') ) + { + // this is a field=value ling + pc++; // skip leading TAB + + static const int lenField = 4; // strlen("ext:") + if ( wxStrncmp(pc, _T("ext:"), lenField) == 0 ) + { + // skip ' ' which follows and take everything left until the end + // of line + curExtList = pc + lenField + 1; + } + //else: some other field, we don't care + } + else + { + // this is the start of the new section + curMimeType.Empty(); + + while ( *pc != _T(':') && *pc != _T('\0') ) + { + curMimeType += *pc++; + } } } } -void wxGNOMEIconHandler::LoadKeyFilesFromDir(const wxString& dirbase) + +void wxGNOMEIconHandler::LoadMimeFilesFromDir(const wxString& dirbase, wxMimeTypesManagerImpl *manager) { wxASSERT_MSG( !!dirbase && !wxEndsWithPathSeparator(dirbase), _T("base directory shouldn't end with a slash") ); @@ -408,15 +506,16 @@ void wxGNOMEIconHandler::LoadKeyFilesFromDir(const wxString& dirbase) dirname += _T('/'); wxString filename; - bool cont = dir.GetFirst(&filename, _T("*.keys"), wxDIR_FILES); + bool cont = dir.GetFirst(&filename, _T("*.mime"), wxDIR_FILES); while ( cont ) { - LoadIconsFromKeyFile(dirname + filename); + LoadMimeTypesFromMimeFile(dirname + filename, manager); cont = dir.GetNext(&filename); } } + void wxGNOMEIconHandler::Init() { wxArrayString dirs; @@ -437,6 +536,31 @@ void wxGNOMEIconHandler::Init() m_inited = TRUE; } + +void wxGNOMEIconHandler::GetMimeInfoRecords(wxMimeTypesManagerImpl *manager) +{ + if ( !m_inited ) + { + Init(); + } + + wxArrayString dirs; + dirs.Add(_T("/usr/share")); + dirs.Add(_T("/usr/local/share")); + + wxString gnomedir; + wxGetHomeDir( &gnomedir ); + gnomedir += _T("/.gnome"); + dirs.Add( gnomedir ); + + size_t nDirs = dirs.GetCount(); + for ( size_t nDir = 0; nDir < nDirs; nDir++ ) + { + LoadMimeFilesFromDir(dirs[nDir], manager); + } +} + + bool wxGNOMEIconHandler::GetIcon(const wxString& mimetype, wxIcon *icon) { if ( !m_inited ) @@ -727,7 +851,7 @@ MailCapEntry * wxFileTypeImpl::GetEntry(const wxFileType::MessageParameters& params) const { wxString command; - MailCapEntry *entry = m_manager->m_aEntries[m_index]; + MailCapEntry *entry = m_manager->m_aEntries[m_index[0]]; while ( entry != NULL ) { // notice that an empty command would always succeed (it's ok) command = wxFileType::ExpandCommand(entry->GetTestCmd(), params); @@ -751,20 +875,35 @@ wxFileTypeImpl::GetEntry(const wxFileType::MessageParameters& params) const bool wxFileTypeImpl::GetIcon(wxIcon *icon) const { - wxString mimetype; - (void)GetMimeType(&mimetype); + wxArrayString mimetypes; + GetMimeTypes(mimetypes); ArrayIconHandlers& handlers = m_manager->GetIconHandlers(); size_t count = handlers.GetCount(); + size_t counttypes = mimetypes.GetCount(); for ( size_t n = 0; n < count; n++ ) { - if ( handlers[n]->GetIcon(mimetype, icon) ) - return TRUE; + for ( size_t n2 = 0; n2 < counttypes; n2++ ) + { + if ( handlers[n]->GetIcon(mimetypes[n2], icon) ) + return TRUE; + } } return FALSE; } + +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; +} + + bool wxFileTypeImpl::GetExpandedCommand(wxString *expandedCmd, const wxFileType::MessageParameters& params, @@ -788,7 +927,7 @@ wxFileTypeImpl::GetExpandedCommand(wxString *expandedCmd, bool wxFileTypeImpl::GetExtensions(wxArrayString& extensions) { - wxString strExtensions = m_manager->GetExtension(m_index); + wxString strExtensions = m_manager->GetExtension(m_index[0]); extensions.Empty(); // one extension in the space or comma delimitid list @@ -829,8 +968,8 @@ ArrayIconHandlers& wxMimeTypesManagerImpl::GetIconHandlers() { if ( ms_iconHandlers.GetCount() == 0 ) { - ms_iconHandlers.Add(&gs_iconHandlerKDE); ms_iconHandlers.Add(&gs_iconHandlerGNOME); + ms_iconHandlers.Add(&gs_iconHandlerKDE); } return ms_iconHandlers; @@ -839,12 +978,6 @@ ArrayIconHandlers& wxMimeTypesManagerImpl::GetIconHandlers() // read system and user mailcaps (TODO implement mime.types support) wxMimeTypesManagerImpl::wxMimeTypesManagerImpl() { - // read KDE/GNOME tables - ArrayIconHandlers& handlers = GetIconHandlers(); - size_t count = handlers.GetCount(); - for ( size_t hn = 0; hn < count; hn++ ) - handlers[hn]->GetMimeInfoRecords(this); - // directories where we look for mailcap and mime.types by default // (taken from metamail(1) sources) static const wxChar *aStandardLocations[] = @@ -885,11 +1018,18 @@ wxMimeTypesManagerImpl::wxMimeTypesManagerImpl() if ( wxFile::Exists(strUserMimeTypes) ) { ReadMimeTypes(strUserMimeTypes); } + + // read KDE/GNOME tables + ArrayIconHandlers& handlers = GetIconHandlers(); + size_t count = handlers.GetCount(); + for ( size_t hn = 0; hn < count; hn++ ) + handlers[hn]->GetMimeInfoRecords(this); } wxFileType * wxMimeTypesManagerImpl::GetFileTypeFromExtension(const wxString& ext) { + wxFileType *fileType = NULL; size_t count = m_aExtensions.GetCount(); for ( size_t n = 0; n < count; n++ ) { wxString extensions = m_aExtensions[n]; @@ -900,16 +1040,14 @@ wxMimeTypesManagerImpl::GetFileTypeFromExtension(const wxString& ext) // consider extensions as not being case-sensitive if ( field.IsSameAs(ext, FALSE /* no case */) ) { // found - wxFileType *fileType = new wxFileType; + if (fileType == NULL) fileType = new wxFileType; fileType->m_impl->Init(this, n); - - return fileType; + // adds this mime type to _list_ of mime types with this extension } } } - // not found - return NULL; + return fileType; } wxFileType * -- 2.47.2