mimetype common implementation
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@55140 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
785
src/osx/core/mimetype.cpp
Normal file
785
src/osx/core/mimetype.cpp
Normal file
@@ -0,0 +1,785 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: src/osx/core/mimetype.cpp
|
||||||
|
// Purpose: classes and functions to manage MIME types
|
||||||
|
// Author: Vadim Zeitlin, Stefan Csomor
|
||||||
|
// Modified by:
|
||||||
|
// Created: 23.09.98
|
||||||
|
// RCS-ID: $Id: mimetype.cpp 54734 2008-07-21 01:33:51Z VZ $
|
||||||
|
// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
|
||||||
|
// Licence: wxWindows licence (part of wxExtra library)
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// for compilers that support precompilation, includes "wx.h".
|
||||||
|
#include "wx/wxprec.h"
|
||||||
|
|
||||||
|
#ifdef __BORLANDC__
|
||||||
|
#pragma hdrstop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if wxUSE_MIMETYPE && wxUSE_FILE
|
||||||
|
|
||||||
|
#include "wx/unix/mimetype.h"
|
||||||
|
|
||||||
|
#ifndef WX_PRECOMP
|
||||||
|
#include "wx/dynarray.h"
|
||||||
|
#include "wx/string.h"
|
||||||
|
#include "wx/intl.h"
|
||||||
|
#include "wx/log.h"
|
||||||
|
#include "wx/utils.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "wx/file.h"
|
||||||
|
#include "wx/confbase.h"
|
||||||
|
|
||||||
|
#include "wx/ffile.h"
|
||||||
|
#include "wx/dir.h"
|
||||||
|
#include "wx/tokenzr.h"
|
||||||
|
#include "wx/iconloc.h"
|
||||||
|
#include "wx/filename.h"
|
||||||
|
#include "wx/app.h"
|
||||||
|
#include "wx/apptrait.h"
|
||||||
|
|
||||||
|
// other standard headers
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// constants
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// MIME code tracing mask
|
||||||
|
#define TRACE_MIME wxT("mime")
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// 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();
|
||||||
|
size_t nCount = m_index.GetCount();
|
||||||
|
for (size_t i = 0; i < nCount; i++)
|
||||||
|
mimeTypes.Add(m_manager->m_aTypes[m_index[i]]);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t wxFileTypeImpl::GetAllCommands(wxArrayString *verbs,
|
||||||
|
wxArrayString *commands,
|
||||||
|
const wxFileType::MessageParameters& params) const
|
||||||
|
{
|
||||||
|
wxString vrb, cmd, sTmp;
|
||||||
|
size_t count = 0;
|
||||||
|
wxMimeTypeCommands * sPairs;
|
||||||
|
|
||||||
|
// verbs and commands have been cleared already in mimecmn.cpp...
|
||||||
|
// if we find no entries in the exact match, try the inexact match
|
||||||
|
for (size_t n = 0; ((count == 0) && (n < m_index.GetCount())); n++)
|
||||||
|
{
|
||||||
|
// list of verb = command pairs for this mimetype
|
||||||
|
sPairs = m_manager->m_aEntries [m_index[n]];
|
||||||
|
size_t i;
|
||||||
|
for ( i = 0; i < sPairs->GetCount(); i++ )
|
||||||
|
{
|
||||||
|
vrb = sPairs->GetVerb(i);
|
||||||
|
// some gnome entries have "." inside
|
||||||
|
vrb = vrb.AfterLast(wxT('.'));
|
||||||
|
cmd = sPairs->GetCmd(i);
|
||||||
|
if (! cmd.empty() )
|
||||||
|
{
|
||||||
|
cmd = wxFileType::ExpandCommand(cmd, params);
|
||||||
|
count++;
|
||||||
|
if ( vrb.IsSameAs(wxT("open")))
|
||||||
|
{
|
||||||
|
if ( verbs )
|
||||||
|
verbs->Insert(vrb, 0u);
|
||||||
|
if ( commands )
|
||||||
|
commands ->Insert(cmd, 0u);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( verbs )
|
||||||
|
verbs->Add(vrb);
|
||||||
|
if ( commands )
|
||||||
|
commands->Add(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxFileTypeImpl::GetExtensions(wxArrayString& extensions)
|
||||||
|
{
|
||||||
|
const wxString strExtensions = m_manager->GetExtension(m_index[0]);
|
||||||
|
extensions.Empty();
|
||||||
|
|
||||||
|
// one extension in the space or comma-delimited list
|
||||||
|
wxString strExt;
|
||||||
|
wxString::const_iterator end = strExtensions.end();
|
||||||
|
for ( wxString::const_iterator p = strExtensions.begin(); /* nothing */; ++p )
|
||||||
|
{
|
||||||
|
if ( p == end || *p == wxT(' ') || *p == wxT(',') )
|
||||||
|
{
|
||||||
|
if ( !strExt.empty() )
|
||||||
|
{
|
||||||
|
extensions.Add(strExt);
|
||||||
|
strExt.Empty();
|
||||||
|
}
|
||||||
|
//else: repeated spaces
|
||||||
|
// (shouldn't happen, but it's not that important if it does happen)
|
||||||
|
|
||||||
|
if ( p == end )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if ( *p == wxT('.') )
|
||||||
|
{
|
||||||
|
// remove the dot from extension (but only if it's the first char)
|
||||||
|
if ( !strExt.empty() )
|
||||||
|
{
|
||||||
|
strExt += wxT('.');
|
||||||
|
}
|
||||||
|
//else: no, don't append it
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strExt += *p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set an arbitrary command:
|
||||||
|
// could adjust the code to ask confirmation if it already exists and
|
||||||
|
// overwriteprompt is true, but this is currently ignored as *Associate* has
|
||||||
|
// no overwrite prompt
|
||||||
|
bool
|
||||||
|
wxFileTypeImpl::SetCommand(const wxString& cmd,
|
||||||
|
const wxString& verb,
|
||||||
|
bool WXUNUSED(overwriteprompt))
|
||||||
|
{
|
||||||
|
wxArrayString strExtensions;
|
||||||
|
wxString strDesc, strIcon;
|
||||||
|
|
||||||
|
wxArrayString strTypes;
|
||||||
|
GetMimeTypes(strTypes);
|
||||||
|
if ( strTypes.IsEmpty() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
wxMimeTypeCommands *entry = new wxMimeTypeCommands();
|
||||||
|
entry->Add(verb + wxT("=") + cmd + wxT(" %s "));
|
||||||
|
|
||||||
|
bool ok = false;
|
||||||
|
size_t nCount = strTypes.GetCount();
|
||||||
|
for ( size_t i = 0; i < nCount; i++ )
|
||||||
|
{
|
||||||
|
if ( m_manager->DoAssociation
|
||||||
|
(
|
||||||
|
strTypes[i],
|
||||||
|
strIcon,
|
||||||
|
entry,
|
||||||
|
strExtensions,
|
||||||
|
strDesc
|
||||||
|
) )
|
||||||
|
{
|
||||||
|
// DoAssociation() took ownership of entry, don't delete it below
|
||||||
|
ok = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !ok )
|
||||||
|
delete entry;
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore index on the grounds that we only have one icon in a Unix file
|
||||||
|
bool wxFileTypeImpl::SetDefaultIcon(const wxString& strIcon, int WXUNUSED(index))
|
||||||
|
{
|
||||||
|
if (strIcon.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
wxArrayString strExtensions;
|
||||||
|
wxString strDesc;
|
||||||
|
|
||||||
|
wxArrayString strTypes;
|
||||||
|
GetMimeTypes(strTypes);
|
||||||
|
if ( strTypes.IsEmpty() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
wxMimeTypeCommands *entry = new wxMimeTypeCommands();
|
||||||
|
bool ok = false;
|
||||||
|
size_t nCount = strTypes.GetCount();
|
||||||
|
for ( size_t i = 0; i < nCount; i++ )
|
||||||
|
{
|
||||||
|
if ( m_manager->DoAssociation
|
||||||
|
(
|
||||||
|
strTypes[i],
|
||||||
|
strIcon,
|
||||||
|
entry,
|
||||||
|
strExtensions,
|
||||||
|
strDesc
|
||||||
|
) )
|
||||||
|
{
|
||||||
|
// we don't need to free entry now, DoAssociation() took ownership
|
||||||
|
// of it
|
||||||
|
ok = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !ok )
|
||||||
|
delete entry;
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxMimeTypesManagerImpl (Unix)
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
wxMimeTypesManagerImpl::wxMimeTypesManagerImpl()
|
||||||
|
{
|
||||||
|
m_initialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxMimeTypesManagerImpl::InitIfNeeded()
|
||||||
|
{
|
||||||
|
if ( !m_initialized )
|
||||||
|
{
|
||||||
|
// set the flag first to prevent recursion
|
||||||
|
m_initialized = true;
|
||||||
|
|
||||||
|
wxString wm = wxTheApp->GetTraits()->GetDesktopEnvironment();
|
||||||
|
|
||||||
|
if (wm == wxT("KDE"))
|
||||||
|
Initialize( wxMAILCAP_KDE );
|
||||||
|
else if (wm == wxT("GNOME"))
|
||||||
|
Initialize( wxMAILCAP_GNOME );
|
||||||
|
else
|
||||||
|
Initialize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// read system and user mailcaps and other files
|
||||||
|
void wxMimeTypesManagerImpl::Initialize(int mailcapStyles,
|
||||||
|
const wxString& sExtraDir)
|
||||||
|
{
|
||||||
|
#ifdef __VMS
|
||||||
|
// XDG tables are never installed on OpenVMS
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
#if 0
|
||||||
|
// Read MIME type - extension associations
|
||||||
|
LoadXDGGlobs( "/usr/share/mime/globs" );
|
||||||
|
LoadXDGGlobs( "/usr/local/share/mime/globs" );
|
||||||
|
|
||||||
|
// Load desktop files for XDG, and then override them with the defaults.
|
||||||
|
// We will override them one desktop file at a time, rather
|
||||||
|
// than one mime type at a time, but it should be a reasonable
|
||||||
|
// heuristic.
|
||||||
|
{
|
||||||
|
wxString xdgDataHome = wxGetenv("XDG_DATA_HOME");
|
||||||
|
if ( xdgDataHome.empty() )
|
||||||
|
xdgDataHome = wxGetHomeDir() + "/.local/share";
|
||||||
|
wxString xdgDataDirs = wxGetenv("XDG_DATA_DIRS");
|
||||||
|
if ( xdgDataDirs.empty() )
|
||||||
|
{
|
||||||
|
xdgDataDirs = "/usr/local/share:/usr/share";
|
||||||
|
if (mailcapStyles & wxMAILCAP_GNOME)
|
||||||
|
xdgDataDirs += ":/usr/share/gnome:/opt/gnome/share";
|
||||||
|
if (mailcapStyles & wxMAILCAP_KDE)
|
||||||
|
xdgDataDirs += ":/usr/share/kde3:/opt/kde3/share";
|
||||||
|
}
|
||||||
|
if ( !sExtraDir.empty() )
|
||||||
|
{
|
||||||
|
xdgDataDirs += ':';
|
||||||
|
xdgDataDirs += sExtraDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxArrayString dirs;
|
||||||
|
wxStringTokenizer tokenizer(xdgDataDirs, ":");
|
||||||
|
while ( tokenizer.HasMoreTokens() )
|
||||||
|
{
|
||||||
|
wxString p = tokenizer.GetNextToken();
|
||||||
|
dirs.Add(p);
|
||||||
|
}
|
||||||
|
dirs.insert(dirs.begin(), xdgDataHome);
|
||||||
|
|
||||||
|
wxString defaultsList;
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < dirs.GetCount(); i++)
|
||||||
|
{
|
||||||
|
wxString f = dirs[i];
|
||||||
|
if (f.Last() != '/') f += '/';
|
||||||
|
f += "applications/defaults.list";
|
||||||
|
if (wxFileExists(f))
|
||||||
|
{
|
||||||
|
defaultsList = f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load application files and associate them to corresponding mime types.
|
||||||
|
size_t nDirs = dirs.GetCount();
|
||||||
|
for (size_t nDir = 0; nDir < nDirs; nDir++)
|
||||||
|
{
|
||||||
|
wxString dirStr = dirs[nDir];
|
||||||
|
if (dirStr.Last() != '/') dirStr += '/';
|
||||||
|
dirStr += "applications";
|
||||||
|
LoadXDGAppsFilesFromDir(dirStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!defaultsList.IsEmpty())
|
||||||
|
{
|
||||||
|
wxArrayString deskTopFilesSeen;
|
||||||
|
|
||||||
|
wxMimeTextFile textfile(defaultsList);
|
||||||
|
if ( textfile.Open() )
|
||||||
|
{
|
||||||
|
int nIndex = textfile.pIndexOf( wxT("[Default Applications]") );
|
||||||
|
if (nIndex != wxNOT_FOUND)
|
||||||
|
{
|
||||||
|
for (i = nIndex+1; i < textfile.GetLineCount(); i++)
|
||||||
|
{
|
||||||
|
if (textfile.GetLine(i).Find(wxT("=")) != wxNOT_FOUND)
|
||||||
|
{
|
||||||
|
wxString mimeType = textfile.GetVerb(i);
|
||||||
|
wxString desktopFile = textfile.GetCmd(i);
|
||||||
|
|
||||||
|
if (deskTopFilesSeen.Index(desktopFile) == wxNOT_FOUND)
|
||||||
|
{
|
||||||
|
deskTopFilesSeen.Add(desktopFile);
|
||||||
|
size_t j;
|
||||||
|
for (j = 0; j < dirs.GetCount(); j++)
|
||||||
|
{
|
||||||
|
wxString desktopPath = dirs[j];
|
||||||
|
if (desktopPath.Last() != '/') desktopPath += '/';
|
||||||
|
desktopPath += "applications/";
|
||||||
|
desktopPath += desktopFile;
|
||||||
|
|
||||||
|
if (wxFileExists(desktopPath))
|
||||||
|
LoadXDGApp(desktopPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear data so you can read another group of WM files
|
||||||
|
void wxMimeTypesManagerImpl::ClearData()
|
||||||
|
{
|
||||||
|
m_aTypes.Clear();
|
||||||
|
m_aIcons.Clear();
|
||||||
|
m_aExtensions.Clear();
|
||||||
|
m_aDescriptions.Clear();
|
||||||
|
|
||||||
|
WX_CLEAR_ARRAY(m_aEntries);
|
||||||
|
m_aEntries.Empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
wxMimeTypesManagerImpl::~wxMimeTypesManagerImpl()
|
||||||
|
{
|
||||||
|
ClearData();
|
||||||
|
}
|
||||||
|
|
||||||
|
wxFileType * wxMimeTypesManagerImpl::Associate(const wxFileTypeInfo& ftInfo)
|
||||||
|
{
|
||||||
|
InitIfNeeded();
|
||||||
|
|
||||||
|
wxString strType = ftInfo.GetMimeType();
|
||||||
|
wxString strDesc = ftInfo.GetDescription();
|
||||||
|
wxString strIcon = ftInfo.GetIconFile();
|
||||||
|
|
||||||
|
wxMimeTypeCommands *entry = new wxMimeTypeCommands();
|
||||||
|
|
||||||
|
if ( ! ftInfo.GetOpenCommand().empty())
|
||||||
|
entry->Add(wxT("open=") + ftInfo.GetOpenCommand() + wxT(" %s "));
|
||||||
|
if ( ! ftInfo.GetPrintCommand().empty())
|
||||||
|
entry->Add(wxT("print=") + ftInfo.GetPrintCommand() + wxT(" %s "));
|
||||||
|
|
||||||
|
// now find where these extensions are in the data store and remove them
|
||||||
|
wxArrayString sA_Exts = ftInfo.GetExtensions();
|
||||||
|
wxString sExt, sExtStore;
|
||||||
|
size_t i, nIndex;
|
||||||
|
size_t nExtCount = sA_Exts.GetCount();
|
||||||
|
for (i=0; i < nExtCount; i++)
|
||||||
|
{
|
||||||
|
sExt = sA_Exts.Item(i);
|
||||||
|
|
||||||
|
// clean up to just a space before and after
|
||||||
|
sExt.Trim().Trim(false);
|
||||||
|
sExt = wxT(' ') + sExt + wxT(' ');
|
||||||
|
size_t nCount = m_aExtensions.GetCount();
|
||||||
|
for (nIndex = 0; nIndex < nCount; nIndex++)
|
||||||
|
{
|
||||||
|
sExtStore = m_aExtensions.Item(nIndex);
|
||||||
|
if (sExtStore.Replace(sExt, wxT(" ") ) > 0)
|
||||||
|
m_aExtensions.Item(nIndex) = sExtStore;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !DoAssociation(strType, strIcon, entry, sA_Exts, strDesc) )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return GetFileTypeFromMimeType(strType);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxMimeTypesManagerImpl::DoAssociation(const wxString& strType,
|
||||||
|
const wxString& strIcon,
|
||||||
|
wxMimeTypeCommands *entry,
|
||||||
|
const wxArrayString& strExtensions,
|
||||||
|
const wxString& strDesc)
|
||||||
|
{
|
||||||
|
int nIndex = AddToMimeData(strType, strIcon, entry, strExtensions, strDesc, true);
|
||||||
|
|
||||||
|
if ( nIndex == wxNOT_FOUND )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int wxMimeTypesManagerImpl::AddToMimeData(const wxString& strType,
|
||||||
|
const wxString& strIcon,
|
||||||
|
wxMimeTypeCommands *entry,
|
||||||
|
const wxArrayString& strExtensions,
|
||||||
|
const wxString& strDesc,
|
||||||
|
bool replaceExisting)
|
||||||
|
{
|
||||||
|
InitIfNeeded();
|
||||||
|
|
||||||
|
// ensure mimetype is always lower case
|
||||||
|
wxString mimeType = strType.Lower();
|
||||||
|
|
||||||
|
// is this a known MIME type?
|
||||||
|
int nIndex = m_aTypes.Index(mimeType);
|
||||||
|
if ( nIndex == wxNOT_FOUND )
|
||||||
|
{
|
||||||
|
// new file type
|
||||||
|
m_aTypes.Add(mimeType);
|
||||||
|
m_aIcons.Add(strIcon);
|
||||||
|
m_aEntries.Add(entry ? entry : new wxMimeTypeCommands);
|
||||||
|
|
||||||
|
// change nIndex so we can use it below to add the extensions
|
||||||
|
m_aExtensions.Add(wxEmptyString);
|
||||||
|
nIndex = m_aExtensions.size() - 1;
|
||||||
|
|
||||||
|
m_aDescriptions.Add(strDesc);
|
||||||
|
}
|
||||||
|
else // yes, we already have it
|
||||||
|
{
|
||||||
|
if ( replaceExisting )
|
||||||
|
{
|
||||||
|
// if new description change it
|
||||||
|
if ( !strDesc.empty())
|
||||||
|
m_aDescriptions[nIndex] = strDesc;
|
||||||
|
|
||||||
|
// if new icon change it
|
||||||
|
if ( !strIcon.empty())
|
||||||
|
m_aIcons[nIndex] = strIcon;
|
||||||
|
|
||||||
|
if ( entry )
|
||||||
|
{
|
||||||
|
delete m_aEntries[nIndex];
|
||||||
|
m_aEntries[nIndex] = entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // add data we don't already have ...
|
||||||
|
{
|
||||||
|
// if new description add only if none
|
||||||
|
if ( m_aDescriptions[nIndex].empty() )
|
||||||
|
m_aDescriptions[nIndex] = strDesc;
|
||||||
|
|
||||||
|
// if new icon and no existing icon
|
||||||
|
if ( m_aIcons[nIndex].empty() )
|
||||||
|
m_aIcons[nIndex] = strIcon;
|
||||||
|
|
||||||
|
// add any new entries...
|
||||||
|
if ( entry )
|
||||||
|
{
|
||||||
|
wxMimeTypeCommands *entryOld = m_aEntries[nIndex];
|
||||||
|
|
||||||
|
size_t count = entry->GetCount();
|
||||||
|
for ( size_t i = 0; i < count; i++ )
|
||||||
|
{
|
||||||
|
const wxString& verb = entry->GetVerb(i);
|
||||||
|
if ( !entryOld->HasVerb(verb) )
|
||||||
|
{
|
||||||
|
entryOld->AddOrReplaceVerb(verb, entry->GetCmd(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// as we don't store it anywhere, it won't be deleted later as
|
||||||
|
// usual -- do it immediately instead
|
||||||
|
delete entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// always add the extensions to this mimetype
|
||||||
|
wxString& exts = m_aExtensions[nIndex];
|
||||||
|
|
||||||
|
// add all extensions we don't have yet
|
||||||
|
wxString ext;
|
||||||
|
size_t count = strExtensions.GetCount();
|
||||||
|
for ( size_t i = 0; i < count; i++ )
|
||||||
|
{
|
||||||
|
ext = strExtensions[i];
|
||||||
|
ext += wxT(' ');
|
||||||
|
|
||||||
|
if ( exts.Find(ext) == wxNOT_FOUND )
|
||||||
|
{
|
||||||
|
exts += ext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check data integrity
|
||||||
|
wxASSERT( m_aTypes.GetCount() == m_aEntries.GetCount() &&
|
||||||
|
m_aTypes.GetCount() == m_aExtensions.GetCount() &&
|
||||||
|
m_aTypes.GetCount() == m_aIcons.GetCount() &&
|
||||||
|
m_aTypes.GetCount() == m_aDescriptions.GetCount() );
|
||||||
|
|
||||||
|
return nIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxFileType * wxMimeTypesManagerImpl::GetFileTypeFromExtension(const wxString& ext)
|
||||||
|
{
|
||||||
|
if (ext.empty() )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
InitIfNeeded();
|
||||||
|
|
||||||
|
size_t count = m_aExtensions.GetCount();
|
||||||
|
for ( size_t n = 0; n < count; n++ )
|
||||||
|
{
|
||||||
|
wxStringTokenizer tk(m_aExtensions[n], wxT(' '));
|
||||||
|
|
||||||
|
while ( tk.HasMoreTokens() )
|
||||||
|
{
|
||||||
|
// consider extensions as not being case-sensitive
|
||||||
|
if ( tk.GetNextToken().IsSameAs(ext, false /* no case */) )
|
||||||
|
{
|
||||||
|
// found
|
||||||
|
wxFileType *fileType = new wxFileType;
|
||||||
|
fileType->m_impl->Init(this, n);
|
||||||
|
|
||||||
|
return fileType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxFileType * wxMimeTypesManagerImpl::GetFileTypeFromMimeType(const wxString& mimeType)
|
||||||
|
{
|
||||||
|
InitIfNeeded();
|
||||||
|
|
||||||
|
wxFileType * fileType = NULL;
|
||||||
|
// mime types are not case-sensitive
|
||||||
|
wxString mimetype(mimeType);
|
||||||
|
mimetype.MakeLower();
|
||||||
|
|
||||||
|
// first look for an exact match
|
||||||
|
int index = m_aTypes.Index(mimetype);
|
||||||
|
|
||||||
|
if ( index != wxNOT_FOUND )
|
||||||
|
{
|
||||||
|
fileType = new wxFileType;
|
||||||
|
fileType->m_impl->Init(this, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// then try to find "text/*" as match for "text/plain" (for example)
|
||||||
|
// NB: if mimeType doesn't contain '/' at all, BeforeFirst() will return
|
||||||
|
// the whole string - ok.
|
||||||
|
|
||||||
|
index = wxNOT_FOUND;
|
||||||
|
wxString strCategory = mimetype.BeforeFirst(wxT('/'));
|
||||||
|
|
||||||
|
size_t nCount = m_aTypes.GetCount();
|
||||||
|
for ( size_t n = 0; n < nCount; n++ )
|
||||||
|
{
|
||||||
|
if ( (m_aTypes[n].BeforeFirst(wxT('/')) == strCategory ) &&
|
||||||
|
m_aTypes[n].AfterFirst(wxT('/')) == wxT("*") )
|
||||||
|
{
|
||||||
|
index = n;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( index != wxNOT_FOUND )
|
||||||
|
{
|
||||||
|
// don't throw away fileType that was already found
|
||||||
|
if (!fileType)
|
||||||
|
fileType = new wxFileType;
|
||||||
|
fileType->m_impl->Init(this, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileType;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString wxMimeTypesManagerImpl::GetCommand(const wxString & verb, size_t nIndex) const
|
||||||
|
{
|
||||||
|
wxString command, testcmd, sV, sTmp;
|
||||||
|
sV = verb + wxT("=");
|
||||||
|
|
||||||
|
// list of verb = command pairs for this mimetype
|
||||||
|
wxMimeTypeCommands * sPairs = m_aEntries [nIndex];
|
||||||
|
|
||||||
|
size_t i;
|
||||||
|
size_t nCount = sPairs->GetCount();
|
||||||
|
for ( i = 0; i < nCount; i++ )
|
||||||
|
{
|
||||||
|
sTmp = sPairs->GetVerbCmd (i);
|
||||||
|
if ( sTmp.Contains(sV) )
|
||||||
|
command = sTmp.AfterFirst(wxT('='));
|
||||||
|
}
|
||||||
|
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxMimeTypesManagerImpl::AddFallback(const wxFileTypeInfo& filetype)
|
||||||
|
{
|
||||||
|
InitIfNeeded();
|
||||||
|
|
||||||
|
wxString extensions;
|
||||||
|
const wxArrayString& exts = filetype.GetExtensions();
|
||||||
|
size_t nExts = exts.GetCount();
|
||||||
|
for ( size_t nExt = 0; nExt < nExts; nExt++ )
|
||||||
|
{
|
||||||
|
if ( nExt > 0 )
|
||||||
|
extensions += wxT(' ');
|
||||||
|
|
||||||
|
extensions += exts[nExt];
|
||||||
|
}
|
||||||
|
|
||||||
|
AddMimeTypeInfo(filetype.GetMimeType(),
|
||||||
|
extensions,
|
||||||
|
filetype.GetDescription());
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxMimeTypesManagerImpl::AddMimeTypeInfo(const wxString& strMimeType,
|
||||||
|
const wxString& strExtensions,
|
||||||
|
const wxString& strDesc)
|
||||||
|
{
|
||||||
|
// reading mailcap may find image/* , while
|
||||||
|
// reading mime.types finds image/gif and no match is made
|
||||||
|
// this means all the get functions don't work fix this
|
||||||
|
wxString strIcon;
|
||||||
|
wxString sTmp = strExtensions;
|
||||||
|
|
||||||
|
wxArrayString sExts;
|
||||||
|
sTmp.Trim().Trim(false);
|
||||||
|
|
||||||
|
while (!sTmp.empty())
|
||||||
|
{
|
||||||
|
sExts.Add(sTmp.AfterLast(wxT(' ')));
|
||||||
|
sTmp = sTmp.BeforeLast(wxT(' '));
|
||||||
|
}
|
||||||
|
|
||||||
|
AddToMimeData(strMimeType, strIcon, NULL, sExts, strDesc, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t wxMimeTypesManagerImpl::EnumAllFileTypes(wxArrayString& mimetypes)
|
||||||
|
{
|
||||||
|
InitIfNeeded();
|
||||||
|
|
||||||
|
mimetypes.Empty();
|
||||||
|
|
||||||
|
size_t count = m_aTypes.GetCount();
|
||||||
|
for ( size_t n = 0; n < count; n++ )
|
||||||
|
{
|
||||||
|
// don't return template types from here (i.e. anything containg '*')
|
||||||
|
const wxString &type = m_aTypes[n];
|
||||||
|
if ( type.Find(wxT('*')) == wxNOT_FOUND )
|
||||||
|
{
|
||||||
|
mimetypes.Add(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mimetypes.GetCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// writing to MIME type files
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool wxMimeTypesManagerImpl::Unassociate(wxFileType *ft)
|
||||||
|
{
|
||||||
|
InitIfNeeded();
|
||||||
|
|
||||||
|
wxArrayString sMimeTypes;
|
||||||
|
ft->GetMimeTypes(sMimeTypes);
|
||||||
|
|
||||||
|
size_t i;
|
||||||
|
size_t nCount = sMimeTypes.GetCount();
|
||||||
|
for (i = 0; i < nCount; i ++)
|
||||||
|
{
|
||||||
|
const wxString &sMime = sMimeTypes.Item(i);
|
||||||
|
int nIndex = m_aTypes.Index(sMime);
|
||||||
|
if ( nIndex == wxNOT_FOUND)
|
||||||
|
{
|
||||||
|
// error if we get here ??
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_aTypes.RemoveAt(nIndex);
|
||||||
|
m_aEntries.RemoveAt(nIndex);
|
||||||
|
m_aExtensions.RemoveAt(nIndex);
|
||||||
|
m_aDescriptions.RemoveAt(nIndex);
|
||||||
|
m_aIcons.RemoveAt(nIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// check data integrity
|
||||||
|
wxASSERT( m_aTypes.GetCount() == m_aEntries.GetCount() &&
|
||||||
|
m_aTypes.GetCount() == m_aExtensions.GetCount() &&
|
||||||
|
m_aTypes.GetCount() == m_aIcons.GetCount() &&
|
||||||
|
m_aTypes.GetCount() == m_aDescriptions.GetCount() );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
// wxUSE_MIMETYPE && wxUSE_FILE
|
Reference in New Issue
Block a user