1. ReadMailcap/MimeTypes returna bool error code
2. 'fallback' flag added to ReadMailcap 3, subtle (and very rare) bug with mailcap entries order corrected git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1962 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -15,7 +15,7 @@ initialization is needed.
|
|||||||
(system-wide) and .mailcap and .mime.types in the current user's home directory:
|
(system-wide) and .mailcap and .mime.types in the current user's home directory:
|
||||||
all of these files are searched for and loaded if found by default. However,
|
all of these files are searched for and loaded if found by default. However,
|
||||||
additional functions
|
additional functions
|
||||||
\helpref{wxMimeTypesManager::ReadMailcap}{wxmimetypesmanagerreadmailcap} and
|
\helpref{wxMimeTypesManager::ReadMailcap}{wxmimetypesmanagerreadmailcap} and
|
||||||
\helpref{wxMimeTypesManager::ReadMimeTypes}{wxmimetypesmanagerreadmimetypes} are
|
\helpref{wxMimeTypesManager::ReadMimeTypes}{wxmimetypesmanagerreadmimetypes} are
|
||||||
provided to load additional files.
|
provided to load additional files.
|
||||||
|
|
||||||
@@ -123,17 +123,29 @@ necessary to convert the strings to the same case before calling it.
|
|||||||
|
|
||||||
\membersection{wxMimeTypesManager::ReadMailcap}\label{wxmimetypesmanagerreadmailcap}
|
\membersection{wxMimeTypesManager::ReadMailcap}\label{wxmimetypesmanagerreadmailcap}
|
||||||
|
|
||||||
\func{void}{ReadMailcap}{\param{const wxString\&}{ filename}}
|
\func{bool}{ReadMailcap}{\param{const wxString\&}{ filename}, \param{bool}{ fallback = FALSE}}
|
||||||
|
|
||||||
Load additional file containing information about MIME types and associated
|
Load additional file containing information about MIME types and associated
|
||||||
information in mailcap format. See metamail(1) and mailcap(5) for more
|
information in mailcap format. See metamail(1) and mailcap(5) for more
|
||||||
information.
|
information.
|
||||||
|
|
||||||
|
{\it fallback} parameter may be used to load additional mailcap files without
|
||||||
|
overriding the settings found in the standard files: normally, entries from
|
||||||
|
files loaded with ReadMailcap will override the entries from files loaded
|
||||||
|
previously (and the standard ones are loaded in the very beginning), but this
|
||||||
|
will not happen if this parameter is set to TRUE (default is FALSE).
|
||||||
|
|
||||||
|
The return value is TRUE if there were no errors in the file or FALSE
|
||||||
|
otherwise.
|
||||||
|
|
||||||
\membersection{wxMimeTypesManager::ReadMimeTypes}\label{wxmimetypesmanagerreadmimetypes}
|
\membersection{wxMimeTypesManager::ReadMimeTypes}\label{wxmimetypesmanagerreadmimetypes}
|
||||||
|
|
||||||
\func{void}{ReadMimeTypes}{\param{const wxString\&}{ filename}}
|
\func{bool}{ReadMimeTypes}{\param{const wxString\&}{ filename}}
|
||||||
|
|
||||||
Load additional file containing information about MIME types and associated
|
Load additional file containing information about MIME types and associated
|
||||||
information in mime.types file format. See metamail(1) and mailcap(5) for more
|
information in mime.types file format. See metamail(1) and mailcap(5) for more
|
||||||
information.
|
information.
|
||||||
|
|
||||||
|
The return value is TRUE if there were no errors in the file or FALSE
|
||||||
|
otherwise.
|
||||||
|
|
||||||
|
@@ -131,12 +131,18 @@ public:
|
|||||||
// get file type from MIME type (in format <category>/<format>)
|
// get file type from MIME type (in format <category>/<format>)
|
||||||
wxFileType *GetFileTypeFromMimeType(const wxString& mimeType);
|
wxFileType *GetFileTypeFromMimeType(const wxString& mimeType);
|
||||||
|
|
||||||
// other operations
|
// other operations: return TRUE if there were no errors or FALSE if there
|
||||||
|
// were some unreckognized entries (the good entries are always read anyhow)
|
||||||
// read in additional file (the standard ones are read automatically)
|
// read in additional file (the standard ones are read automatically)
|
||||||
// in mailcap format (see mimetype.cpp for description)
|
// in mailcap format (see mimetype.cpp for description)
|
||||||
void ReadMailcap(const wxString& filename);
|
//
|
||||||
|
// 'fallback' parameter may be set to TRUE to avoid overriding the
|
||||||
|
// settings from other, previously parsed, files by this one: normally,
|
||||||
|
// the files read most recently would override the older files, but with
|
||||||
|
// fallback == TRUE this won't happen
|
||||||
|
bool ReadMailcap(const wxString& filename, bool fallback = FALSE);
|
||||||
// read in additional file in mime.types format
|
// read in additional file in mime.types format
|
||||||
void ReadMimeTypes(const wxString& filename);
|
bool ReadMimeTypes(const wxString& filename);
|
||||||
|
|
||||||
// dtor (not virtual, shouldn't be derived from)
|
// dtor (not virtual, shouldn't be derived from)
|
||||||
~wxMimeTypesManager();
|
~wxMimeTypesManager();
|
||||||
|
@@ -124,8 +124,8 @@ public:
|
|||||||
wxFileType *GetFileTypeFromMimeType(const wxString& mimeType);
|
wxFileType *GetFileTypeFromMimeType(const wxString& mimeType);
|
||||||
|
|
||||||
// this are NOPs under Windows
|
// this are NOPs under Windows
|
||||||
void ReadMailcap(const wxString& filename) { }
|
bool ReadMailcap(const wxString& filename, bool fallback = TRUE) { }
|
||||||
void ReadMimeTypes(const wxString& filename) { }
|
bool ReadMimeTypes(const wxString& filename) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
#else // Unix
|
#else // Unix
|
||||||
@@ -220,9 +220,27 @@ public:
|
|||||||
// operations
|
// operations
|
||||||
// prepend this element to the list
|
// prepend this element to the list
|
||||||
void Prepend(MailCapEntry *next) { m_next = next; }
|
void Prepend(MailCapEntry *next) { m_next = next; }
|
||||||
// append to the list
|
// insert into the list at given position
|
||||||
|
void Insert(MailCapEntry *next, size_t pos)
|
||||||
|
{
|
||||||
|
// FIXME slooow...
|
||||||
|
MailCapEntry *cur;
|
||||||
|
size_t n = 0;
|
||||||
|
for ( cur = next; cur != NULL; cur = cur->m_next, n++ ) {
|
||||||
|
if ( n == pos )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxASSERT_MSG( n == pos, "invalid position in MailCapEntry::Insert" );
|
||||||
|
|
||||||
|
m_next = cur->m_next;
|
||||||
|
cur->m_next = this;
|
||||||
|
}
|
||||||
|
// append this element to the list
|
||||||
void Append(MailCapEntry *next)
|
void Append(MailCapEntry *next)
|
||||||
{
|
{
|
||||||
|
wxCHECK_RET( next != NULL, "Append()ing to what?" );
|
||||||
|
|
||||||
// FIXME slooow...
|
// FIXME slooow...
|
||||||
MailCapEntry *cur;
|
MailCapEntry *cur;
|
||||||
for ( cur = next; cur->m_next != NULL; cur = cur->m_next )
|
for ( cur = next; cur->m_next != NULL; cur = cur->m_next )
|
||||||
@@ -230,9 +248,7 @@ public:
|
|||||||
|
|
||||||
cur->m_next = this;
|
cur->m_next = this;
|
||||||
|
|
||||||
// we initialize it in the ctor and there is no reason to both Prepend()
|
wxASSERT_MSG( !m_next, "Append()ing element already in the list?" );
|
||||||
// and Append() one and the same entry
|
|
||||||
wxASSERT( m_next == NULL );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -252,15 +268,15 @@ friend class wxFileTypeImpl; // give it access to m_aXXX variables
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// ctor loads all info into memory for quicker access later on
|
// ctor loads all info into memory for quicker access later on
|
||||||
// @@ it would be nice to load them all, but parse on demand only...
|
// TODO it would be nice to load them all, but parse on demand only...
|
||||||
wxMimeTypesManagerImpl();
|
wxMimeTypesManagerImpl();
|
||||||
|
|
||||||
// implement containing class functions
|
// implement containing class functions
|
||||||
wxFileType *GetFileTypeFromExtension(const wxString& ext);
|
wxFileType *GetFileTypeFromExtension(const wxString& ext);
|
||||||
wxFileType *GetFileTypeFromMimeType(const wxString& mimeType);
|
wxFileType *GetFileTypeFromMimeType(const wxString& mimeType);
|
||||||
|
|
||||||
void ReadMailcap(const wxString& filename);
|
bool ReadMailcap(const wxString& filename, bool fallback = FALSE);
|
||||||
void ReadMimeTypes(const wxString& filename);
|
bool ReadMimeTypes(const wxString& filename);
|
||||||
|
|
||||||
// accessors
|
// accessors
|
||||||
// get the string containing space separated extensions for the given
|
// get the string containing space separated extensions for the given
|
||||||
@@ -286,7 +302,7 @@ public:
|
|||||||
bool GetMimeType(wxString *mimeType) const
|
bool GetMimeType(wxString *mimeType) const
|
||||||
{ *mimeType = m_manager->m_aTypes[m_index]; return TRUE; }
|
{ *mimeType = m_manager->m_aTypes[m_index]; return TRUE; }
|
||||||
bool GetIcon(wxIcon * WXUNUSED(icon)) const
|
bool GetIcon(wxIcon * WXUNUSED(icon)) const
|
||||||
{ return FALSE; } // @@ maybe with Gnome/KDE integration...
|
{ return FALSE; } // TODO maybe with Gnome/KDE integration...
|
||||||
bool GetDescription(wxString *desc) const
|
bool GetDescription(wxString *desc) const
|
||||||
{ *desc = m_manager->m_aDescriptions[m_index]; return TRUE; }
|
{ *desc = m_manager->m_aDescriptions[m_index]; return TRUE; }
|
||||||
|
|
||||||
@@ -492,14 +508,14 @@ wxMimeTypesManager::GetFileTypeFromMimeType(const wxString& mimeType)
|
|||||||
return m_impl->GetFileTypeFromMimeType(mimeType);
|
return m_impl->GetFileTypeFromMimeType(mimeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxMimeTypesManager::ReadMailcap(const wxString& filename)
|
bool wxMimeTypesManager::ReadMailcap(const wxString& filename, bool fallback)
|
||||||
{
|
{
|
||||||
m_impl->ReadMailcap(filename);
|
return m_impl->ReadMailcap(filename, fallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxMimeTypesManager::ReadMimeTypes(const wxString& filename)
|
bool wxMimeTypesManager::ReadMimeTypes(const wxString& filename)
|
||||||
{
|
{
|
||||||
m_impl->ReadMimeTypes(filename);
|
return m_impl->ReadMimeTypes(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -520,9 +536,9 @@ bool wxFileTypeImpl::GetCommand(wxString *command, const char *verb) const
|
|||||||
// it's the default value of the key
|
// it's the default value of the key
|
||||||
if ( key.QueryValue("", *command) ) {
|
if ( key.QueryValue("", *command) ) {
|
||||||
// transform it from '%1' to '%s' style format string
|
// transform it from '%1' to '%s' style format string
|
||||||
// @@ we don't make any attempt to verify that the string is valid,
|
// NB: we don't make any attempt to verify that the string is valid,
|
||||||
// i.e. doesn't contain %2, or second %1 or .... But we do make
|
// i.e. doesn't contain %2, or second %1 or .... But we do make
|
||||||
// sure that we return a string with _exactly_ one '%s'!
|
// sure that we return a string with _exactly_ one '%s'!
|
||||||
size_t len = command->Len();
|
size_t len = command->Len();
|
||||||
for ( size_t n = 0; n < len; n++ ) {
|
for ( size_t n = 0; n < len; n++ ) {
|
||||||
if ( command->GetChar(n) == '%' &&
|
if ( command->GetChar(n) == '%' &&
|
||||||
@@ -535,7 +551,7 @@ bool wxFileTypeImpl::GetCommand(wxString *command, const char *verb) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// we didn't find any '%1'!
|
// we didn't find any '%1'!
|
||||||
// @@@ hack: append the filename at the end, hope that it will do
|
// HACK: append the filename at the end, hope that it will do
|
||||||
*command << " %s";
|
*command << " %s";
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -546,7 +562,7 @@ bool wxFileTypeImpl::GetCommand(wxString *command, const char *verb) const
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @@ this function is half implemented
|
// TODO this function is half implemented
|
||||||
bool wxFileTypeImpl::GetExtensions(wxArrayString& extensions)
|
bool wxFileTypeImpl::GetExtensions(wxArrayString& extensions)
|
||||||
{
|
{
|
||||||
if ( m_ext.IsEmpty() ) {
|
if ( m_ext.IsEmpty() ) {
|
||||||
@@ -676,8 +692,8 @@ wxMimeTypesManagerImpl::GetFileTypeFromExtension(const wxString& ext)
|
|||||||
wxFileType *
|
wxFileType *
|
||||||
wxMimeTypesManagerImpl::GetFileTypeFromMimeType(const wxString& mimeType)
|
wxMimeTypesManagerImpl::GetFileTypeFromMimeType(const wxString& mimeType)
|
||||||
{
|
{
|
||||||
// @@@ I don't know of any official documentation which mentions this
|
// HACK I don't know of any official documentation which mentions this
|
||||||
// location, but as a matter of fact IE uses it, so why not we?
|
// location, but as a matter of fact IE uses it, so why not we?
|
||||||
static const char *szMimeDbase = "MIME\\Database\\Content Type\\";
|
static const char *szMimeDbase = "MIME\\Database\\Content Type\\";
|
||||||
|
|
||||||
wxString strKey = szMimeDbase;
|
wxString strKey = szMimeDbase;
|
||||||
@@ -706,7 +722,7 @@ wxFileTypeImpl::GetEntry(const wxFileType::MessageParameters& params) const
|
|||||||
wxString command;
|
wxString command;
|
||||||
MailCapEntry *entry = m_manager->m_aEntries[m_index];
|
MailCapEntry *entry = m_manager->m_aEntries[m_index];
|
||||||
while ( entry != NULL ) {
|
while ( entry != NULL ) {
|
||||||
// notice that an empty command would always succeed (@@ is it ok?)
|
// notice that an empty command would always succeed (it's ok)
|
||||||
command = wxFileType::ExpandCommand(entry->GetTestCmd(), params);
|
command = wxFileType::ExpandCommand(entry->GetTestCmd(), params);
|
||||||
|
|
||||||
if ( command.IsEmpty() || (system(command) == 0) ) {
|
if ( command.IsEmpty() || (system(command) == 0) ) {
|
||||||
@@ -887,13 +903,13 @@ wxMimeTypesManagerImpl::GetFileTypeFromMimeType(const wxString& mimeType)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxMimeTypesManagerImpl::ReadMimeTypes(const wxString& strFileName)
|
bool wxMimeTypesManagerImpl::ReadMimeTypes(const wxString& strFileName)
|
||||||
{
|
{
|
||||||
wxLogTrace("--- Parsing mime.types file '%s' ---", strFileName.c_str());
|
wxLogTrace("--- Parsing mime.types file '%s' ---", strFileName.c_str());
|
||||||
|
|
||||||
wxTextFile file(strFileName);
|
wxTextFile file(strFileName);
|
||||||
if ( !file.Open() )
|
if ( !file.Open() )
|
||||||
return;
|
return FALSE;
|
||||||
|
|
||||||
// the information we extract
|
// the information we extract
|
||||||
wxString strMimeType, strDesc, strExtensions;
|
wxString strMimeType, strDesc, strExtensions;
|
||||||
@@ -1050,18 +1066,26 @@ void wxMimeTypesManagerImpl::ReadMimeTypes(const wxString& strFileName)
|
|||||||
wxASSERT( m_aTypes.Count() == m_aEntries.Count() &&
|
wxASSERT( m_aTypes.Count() == m_aEntries.Count() &&
|
||||||
m_aTypes.Count() == m_aExtensions.Count() &&
|
m_aTypes.Count() == m_aExtensions.Count() &&
|
||||||
m_aTypes.Count() == m_aDescriptions.Count() );
|
m_aTypes.Count() == m_aDescriptions.Count() );
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxMimeTypesManagerImpl::ReadMailcap(const wxString& strFileName)
|
bool wxMimeTypesManagerImpl::ReadMailcap(const wxString& strFileName,
|
||||||
|
bool fallback)
|
||||||
{
|
{
|
||||||
wxLogTrace("--- Parsing mailcap file '%s' ---", strFileName.c_str());
|
wxLogTrace("--- Parsing mailcap file '%s' ---", strFileName.c_str());
|
||||||
|
|
||||||
wxTextFile file(strFileName);
|
wxTextFile file(strFileName);
|
||||||
if ( !file.Open() )
|
if ( !file.Open() )
|
||||||
return;
|
return FALSE;
|
||||||
|
|
||||||
// see the comments near the end of function for the reason we need this
|
// see the comments near the end of function for the reason we need these
|
||||||
|
// variables (search for the next occurence of them)
|
||||||
|
// indices of MIME types (in m_aTypes) we already found in this file
|
||||||
wxArrayInt aEntryIndices;
|
wxArrayInt aEntryIndices;
|
||||||
|
// aLastIndices[n] is the index of last element in
|
||||||
|
// m_aEntries[aEntryIndices[n]] from this file
|
||||||
|
wxArrayInt aLastIndices;
|
||||||
|
|
||||||
size_t nLineCount = file.GetLineCount();
|
size_t nLineCount = file.GetLineCount();
|
||||||
for ( size_t nLine = 0; nLine < nLineCount; nLine++ ) {
|
for ( size_t nLine = 0; nLine < nLineCount; nLine++ ) {
|
||||||
@@ -1256,26 +1280,51 @@ void wxMimeTypesManagerImpl::ReadMailcap(const wxString& strFileName)
|
|||||||
m_aDescriptions.Add(strDesc);
|
m_aDescriptions.Add(strDesc);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// modify the existing entry: the entry in one and the same file
|
// modify the existing entry: the entries in one and the same
|
||||||
// are read in top-to-bottom order, i.e. the entries read first
|
// file are read in top-to-bottom order, i.e. the entries read
|
||||||
// should be tried before the entries below. However, the files
|
// first should be tried before the entries below. However,
|
||||||
// read later should override the settings in the files read
|
// the files read later should override the settings in the
|
||||||
// before, thus we Append() the new entry to the list if it has
|
// files read before (except if fallback is TRUE), thus we
|
||||||
// already occured in _this_ file, but Prepend() it if it
|
// Insert() the new entry to the list if it has already
|
||||||
// occured in some of the previous ones.
|
// occured in _this_ file, but Prepend() it if it occured in
|
||||||
if ( aEntryIndices.Index(nIndex) == wxNOT_FOUND ) {
|
// some of the previous ones and Append() to it in the
|
||||||
// first time in this file
|
// fallback case
|
||||||
aEntryIndices.Add(nIndex);
|
|
||||||
entry->Prepend(m_aEntries[nIndex]);
|
if ( fallback ) {
|
||||||
m_aEntries[nIndex] = entry;
|
// 'fallback' parameter prevents the entries from this
|
||||||
|
// file from overriding the other ones - always append
|
||||||
|
MailCapEntry *entryOld = m_aEntries[nIndex];
|
||||||
|
if ( entryOld )
|
||||||
|
entry->Append(entryOld);
|
||||||
|
else
|
||||||
|
m_aEntries[nIndex] = entry;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// not the first time in _this_ file
|
int entryIndex = aEntryIndices.Index(nIndex);
|
||||||
entry->Append(m_aEntries[nIndex]);
|
if ( entryIndex == wxNOT_FOUND ) {
|
||||||
|
// first time in this file
|
||||||
|
aEntryIndices.Add(nIndex);
|
||||||
|
aLastIndices.Add(0);
|
||||||
|
|
||||||
|
entry->Prepend(m_aEntries[nIndex]);
|
||||||
|
m_aEntries[nIndex] = entry;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// not the first time in _this_ file
|
||||||
|
size_t nEntryIndex = (size_t)entryIndex;
|
||||||
|
MailCapEntry *entryOld = m_aEntries[nIndex];
|
||||||
|
if ( entryOld )
|
||||||
|
entry->Insert(entryOld, aLastIndices[nEntryIndex]);
|
||||||
|
else
|
||||||
|
m_aEntries[nIndex] = entry;
|
||||||
|
|
||||||
|
// the indices were shifted by 1
|
||||||
|
aLastIndices[nEntryIndex]++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !strDesc.IsEmpty() ) {
|
if ( !strDesc.IsEmpty() ) {
|
||||||
// @@ replace the old one - what else can we do??
|
// replace the old one - what else can we do??
|
||||||
m_aDescriptions[nIndex] = strDesc;
|
m_aDescriptions[nIndex] = strDesc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1286,6 +1335,8 @@ void wxMimeTypesManagerImpl::ReadMailcap(const wxString& strFileName)
|
|||||||
m_aTypes.Count() == m_aExtensions.Count() &&
|
m_aTypes.Count() == m_aExtensions.Count() &&
|
||||||
m_aTypes.Count() == m_aDescriptions.Count() );
|
m_aTypes.Count() == m_aDescriptions.Count() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // OS type
|
#endif // OS type
|
||||||
|
Reference in New Issue
Block a user