wxMimeTypesManager now supports creating associations as well as querying

them (MSW only, thanks to Chris Elliott)


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@8936 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2000-12-18 04:48:37 +00:00
parent 189e08b45a
commit c7ce8392e0
5 changed files with 638 additions and 49 deletions

View File

@ -3,6 +3,7 @@
// Purpose: classes and functions to manage MIME types
// Author: Vadim Zeitlin
// Modified by:
// Chris Elliott (biol75@york.ac.uk) 5 Dec 00: write support for Win32
// Created: 23.09.98
// RCS-ID: $Id$
// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
@ -81,8 +82,12 @@ public:
// fill passed in array with all extensions associated with this file
// type
bool GetExtensions(wxArrayString& extensions);
// get the icon corresponding to this file type
bool GetIcon(wxIcon *icon) const;
// get the icon corresponding to this file type, the name of the file
// where the icon resides is return in iconfile if !NULL and its index
// in this file (Win-only) is in iconIndex
bool GetIcon(wxIcon *icon,
wxString *iconFile = NULL,
int *iconIndex = NULL) const;
// get a brief file type description ("*.txt" => "text document")
bool GetDescription(wxString *desc) const;
@ -94,6 +99,39 @@ public:
bool GetPrintCommand(wxString *printCmd,
const MessageParameters& params) const;
// return the number of commands defined for this file type, 0 if none
size_t GetAllCommands(wxArrayString *verbs, wxArrayString *commands,
const wxFileType::MessageParameters& params) const;
// the methods which modify the system database are only implemented under
// Win32 so far (on other platforms they will just return FALSE)
//
// also, they should only be used with the objects created using
// wxMimeTypesManager::Associate()
// set the command to be used for opening the file
bool SetOpenCommand(const wxString& cmd, bool overwriteprompt = TRUE);
// set an arbitrary command, ask confirmation if it already exists and
// overwriteprompt is TRUE
bool SetCommand(const wxString& cmd, const wxString& verb,
bool overwriteprompt = TRUE);
// set the MIME type for this filetype
bool SetMimeType(const wxString& mimeType);
// set the default icon for this filetype
bool SetDefaultIcon(const wxString& cmd = wxEmptyString, int index = 0);
// remove the association from the system database
bool Unassociate();
// delete registration info
bool RemoveOpenCommand();
bool RemoveCommand(const wxString& verb);
bool RemoveMimeType();
bool RemoveDefaultIcon();
// operations
// expand a string in the format of GetOpenCommand (which may contain
// '%s' and '%t' format specificators for the file name and mime type
@ -186,6 +224,7 @@ public:
// deleting it.
// get file type from file extension
wxFileType *GetFileTypeFromExtension(const wxString& ext);
wxFileType *GetOrAllocateFileTypeFromExtension(const wxString& ext);
// get file type from MIME type (in format <category>/<format>)
wxFileType *GetFileTypeFromMimeType(const wxString& mimeType);
@ -218,6 +257,14 @@ public:
// The filetypes array should be terminated by a NULL entry
void AddFallbacks(const wxFileTypeInfo *filetypes);
// create a new association between the given extension and MIME type and
// return the wxFileType object corresponding (which should be deleted by
// caller) or NULL if something went wrong
wxFileType *Associate(const wxString& ext,
const wxString& mimeType,
const wxString& filetype = wxEmptyString,
const wxString& desc = wxEmptyString);
// dtor (not virtual, shouldn't be derived from)
~wxMimeTypesManager();
@ -227,10 +274,10 @@ private:
wxMimeTypesManager& operator=(const wxMimeTypesManager&);
wxMimeTypesManagerImpl *m_impl;
// if m_impl is NULL, create one
void EnsureImpl();
friend class wxMimeTypeCmnModule;
};

View File

@ -32,8 +32,7 @@ public:
// initialize us with our file type name and extension - in this case
// we will read all other data from the registry
void Init(const wxString& strFileType, const wxString& ext)
{ m_strFileType = strFileType; m_ext = ext; }
void Init(const wxString& strFileType, const wxString& ext);
// initialize us with a wxFileTypeInfo object - it contains all the
// data
@ -44,26 +43,43 @@ public:
bool GetExtensions(wxArrayString& extensions);
bool GetMimeType(wxString *mimeType) const;
bool GetMimeTypes(wxArrayString& mimeTypes) const;
bool GetIcon(wxIcon *icon) const;
bool GetIcon(wxIcon *icon, wxString *sCommand = NULL, int *iIndex = NULL) const;
bool GetDescription(wxString *desc) const;
bool GetOpenCommand(wxString *openCmd,
const wxFileType::MessageParameters& params) const;
bool GetPrintCommand(wxString *printCmd,
const wxFileType::MessageParameters& params) const;
size_t GetAllCommands(wxArrayString * verbs, wxArrayString * commands,
const wxFileType::MessageParameters& params) const;
bool SetCommand(const wxString& cmd, const wxString& verb,
bool overwriteprompt = true);
bool SetMimeType(const wxString& mimeType);
bool SetDefaultIcon(const wxString& cmd = wxEmptyString, int index = 0);
bool RemoveCommand(const wxString& verb);
bool RemoveMimeType();
bool RemoveDefaultIcon();
private:
// helper function: reads the command corresponding to the specified verb
// from the registry (returns an empty string if not found)
wxString GetCommand(const wxChar *verb) const;
// get the registry path for the given verb
wxString GetVerbPath(const wxString& verb) const;
// check that the registry key for our extension exists, create it if it
// doesn't, return FALSE if this failed
bool EnsureExtKeyExists();
// we use either m_info or read the data from the registry if m_info == NULL
const wxFileTypeInfo *m_info;
wxString m_strFileType, // may be empty
m_ext;
};
class WXDLLEXPORT wxMimeTypesManagerImpl
{
public:
@ -73,6 +89,7 @@ public:
// implement containing class functions
wxFileType *GetFileTypeFromExtension(const wxString& ext);
wxFileType *GetOrAllocateFileTypeFromExtension(const wxString& ext) ;
wxFileType *GetFileTypeFromMimeType(const wxString& mimeType);
size_t EnumAllFileTypes(wxArrayString& mimetypes);
@ -85,6 +102,9 @@ public:
void AddFallback(const wxFileTypeInfo& ft) { m_fallbacks.Add(ft); }
// create a new filetype with the given name and extension
wxFileType *CreateFileType(const wxString& filetype, const wxString& ext);
private:
wxArrayFileTypeInfo m_fallbacks;
};

View File

@ -40,7 +40,7 @@
//#define TEST_DATETIME
//#define TEST_DIR
//#define TEST_DLLLOADER
#define TEST_ENVIRON
//#define TEST_ENVIRON
//#define TEST_EXECUTE
//#define TEST_FILE
//#define TEST_FILECONF
@ -48,7 +48,7 @@
//#define TEST_LIST
//#define TEST_LOG
//#define TEST_LONGLONG
//#define TEST_MIME
#define TEST_MIME
//#define TEST_INFO_FUNCTIONS
//#define TEST_REGISTRY
//#define TEST_SOCKETS
@ -763,6 +763,32 @@ static void TestMimeFilename()
}
}
static void TestMimeAssociate()
{
wxPuts(_T("*** Testing creation of filetype association ***\n"));
wxFileType *ft = g_mimeManager.Associate
(
_T(".xyz"),
_T("application/x-xyz"),
_T("XYZFile"), // filetype (MSW only)
_T("XYZ File") // description (Unix only)
);
if ( !ft )
{
wxPuts(_T("ERROR: failed to create association!"));
}
else
{
if ( !ft->SetOpenCommand(_T("myprogram")) )
{
wxPuts(_T("ERROR: failed to set open command!"));
}
delete ft;
}
}
#endif // TEST_MIME
// ----------------------------------------------------------------------------
@ -3809,9 +3835,12 @@ int main(int argc, char **argv)
#ifdef TEST_MIME
wxLog::AddTraceMask(_T("mime"));
if ( 0 )
{
TestMimeEnum();
TestMimeOverride();
TestMimeFilename();
TestMimeOverride();
TestMimeFilename();
}
TestMimeAssociate();
#endif // TEST_MIME
#ifdef TEST_INFO_FUNCTIONS

View File

@ -3,6 +3,7 @@
// Purpose: classes and functions to manage MIME types
// Author: Vadim Zeitlin
// Modified by:
// Chris Elliott (biol75@york.ac.uk) 5 Dec 00: write support for Win32
// Created: 23.09.98
// RCS-ID: $Id$
// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
@ -66,13 +67,13 @@ class WXDLLEXPORT wxIcon;
// implementation classes:
#if defined(__WXMSW__)
#include "wx/msw/mimetype.h"
#include "wx/msw/mimetype.h"
#elif defined (__WXMAC__)
#include "wx/mac/mimetype.h"
#include "wx/mac/mimetype.h"
#elif defined (__WXPM__)
#include "wx/os2/mimetype.h"
#else
#include "wx/unix/mimetype.h"
#include "wx/os2/mimetype.h"
#else // Unix
#include "wx/unix/mimetype.h"
#endif
// ============================================================================
@ -230,9 +231,15 @@ bool wxFileType::GetMimeTypes(wxArrayString& mimeTypes) const
return m_impl->GetMimeTypes(mimeTypes);
}
bool wxFileType::GetIcon(wxIcon *icon) const
bool wxFileType::GetIcon(wxIcon *icon,
wxString *iconFile,
int *iconIndex) const
{
#ifdef __WXMSW__
return m_impl->GetIcon(icon, iconFile, iconIndex);
#else
return m_impl->GetIcon(icon);
#endif
}
bool wxFileType::GetDescription(wxString *desc) const
@ -254,13 +261,156 @@ wxFileType::GetPrintCommand(wxString *printCmd,
return m_impl->GetPrintCommand(printCmd, params);
}
size_t wxFileType::GetAllCommands(wxArrayString *verbs,
wxArrayString *commands,
const wxFileType::MessageParameters& params) const
{
if ( verbs )
verbs->Clear();
if ( commands )
commands->Clear();
#ifdef __WXMSW__
return m_impl->GetAllCommands(verbs, commands, params);
#else // !__WXMSW__
// we don't know how to retrieve all commands, so just try the 2 we know
// about
size_t count = 0;
wxString cmd;
if ( m_impl->GetOpenCommand(&cmd, params) )
{
if ( verbs )
verbs->Add(_T("Open"));
if ( commands )
commands->Add(cmd);
count++;
}
if ( GetPrintCommand(&cmd, params) )
{
if ( verbs )
verbs->Add(_T("Print"));
if ( commands )
commands->Add(cmd);
count++;
}
return count;
#endif // __WXMSW__/!__WXMSW__
}
bool wxFileType::SetOpenCommand(const wxString& cmd, bool overwriteprompt)
{
return SetCommand(cmd, _T("open"), overwriteprompt);
}
bool wxFileType::SetCommand(const wxString& cmd, const wxString& verb,
bool overwriteprompt)
{
#ifdef __WXMSW__
return m_impl->SetCommand(cmd, verb, overwriteprompt);
#else
wxFAIL_MSG(_T("not implemented"));
return FALSE;
#endif
}
bool wxFileType::SetMimeType(const wxString& mimeType)
{
// empty MIME type is meaningless here
wxCHECK_MSG( !mimeType.empty(), FALSE, _T("use RemoveMimeType()") );
#ifdef __WXMSW__
return m_impl->SetMimeType(mimeType);
#else
wxFAIL_MSG(_T("not implemented"));
return FALSE;
#endif
}
bool wxFileType::SetDefaultIcon(const wxString& cmd, int index)
{
wxString sTmp = cmd;
// VZ: should we do this?
if ( sTmp.empty() )
GetOpenCommand(&sTmp, wxFileType::MessageParameters("", ""));
wxCHECK_MSG( !sTmp.empty(), false, _T("need the icon file") );
#ifdef __WXMSW__
return m_impl->SetDefaultIcon (cmd, index);
#else
wxFAIL_MSG(_T("not implemented"));
return FALSE;
#endif
}
// now do remove functions
bool wxFileType::RemoveOpenCommand()
{
return RemoveCommand(_T("open"));
}
bool wxFileType::RemoveCommand(const wxString& verb)
{
#ifdef __WXMSW__
return m_impl->RemoveCommand(verb);
#else
wxFAIL_MSG(_T("not implemented"));
return FALSE;
#endif
}
bool wxFileType::RemoveMimeType()
{
#ifdef __WXMSW__
return m_impl->RemoveMimeType ();
#else
wxFAIL_MSG(_T("not implemented"));
return FALSE;
#endif
}
bool wxFileType::RemoveDefaultIcon()
{
#ifdef __WXMSW__
return m_impl->RemoveDefaultIcon();
#else
wxFAIL_MSG(_T("not implemented"));
return FALSE;
#endif
}
bool wxFileType::Unassociate()
{
bool result = TRUE;
if ( !RemoveOpenCommand() )
result = FALSE;
if ( !RemoveDefaultIcon() )
result = FALSE;
if ( !RemoveMimeType() )
result = FALSE;
// in MSW this leaves a HKCR.xzy key
return result;
}
// ----------------------------------------------------------------------------
// wxMimeTypesManager
// ----------------------------------------------------------------------------
void wxMimeTypesManager::EnsureImpl()
{
if (m_impl == NULL)
if ( !m_impl )
m_impl = new wxMimeTypesManagerImpl;
}
@ -293,8 +443,7 @@ wxMimeTypesManager::wxMimeTypesManager()
wxMimeTypesManager::~wxMimeTypesManager()
{
if (m_impl != NULL)
delete m_impl;
delete m_impl;
}
wxFileType *
@ -304,6 +453,34 @@ wxMimeTypesManager::GetFileTypeFromExtension(const wxString& ext)
return m_impl->GetFileTypeFromExtension(ext);
}
wxFileType *
wxMimeTypesManager::GetOrAllocateFileTypeFromExtension(const wxString& ext)
{
EnsureImpl();
#ifdef __WXMSW__
// this writes a root entry to the registry in HKCR.ext
return m_impl->GetOrAllocateFileTypeFromExtension(ext);
#else // !__WXMSW__
// VZ: "static const"??? (FIXME)
// just make a dummy entry with no writing to file
static const wxFileTypeInfo fallback[] =
{
wxFileTypeInfo("application/x-" + ext,
"",
"",
ext + " format file",
ext, NULL),
// must terminate the table with this!
wxFileTypeInfo()
};
AddFallbacks (fallback);
return m_impl->GetFileTypeFromExtension(ext);
#endif // __WXMSW__/!__WXMSW__
}
wxFileType *
wxMimeTypesManager::GetFileTypeFromMimeType(const wxString& mimeType)
{
@ -348,30 +525,26 @@ static wxMimeTypesManager gs_mimeTypesManager;
// and public pointer
wxMimeTypesManager * wxTheMimeTypesManager = &gs_mimeTypesManager;
class wxMimeTypeCmnModule: public wxModule
{
DECLARE_DYNAMIC_CLASS(wxMimeTypeCmnModule)
public:
wxMimeTypeCmnModule() : wxModule() {}
bool OnInit() { return TRUE; }
void OnExit()
{ // this avoids false memory leak allerts:
if (gs_mimeTypesManager.m_impl != NULL)
{
delete gs_mimeTypesManager.m_impl;
gs_mimeTypesManager.m_impl = NULL;
}
wxMimeTypeCmnModule() : wxModule() { }
virtual bool OnInit() { return TRUE; }
virtual void OnExit()
{
// this avoids false memory leak allerts:
if ( gs_mimeTypesManager.m_impl != NULL )
{
delete gs_mimeTypesManager.m_impl;
gs_mimeTypesManager.m_impl = NULL;
}
}
DECLARE_DYNAMIC_CLASS(wxMimeTypeCmnModule)
};
IMPLEMENT_DYNAMIC_CLASS(wxMimeTypeCmnModule, wxModule)
#endif
// wxUSE_FILE && wxUSE_TEXTFILE

View File

@ -52,7 +52,7 @@ class WXDLLEXPORT wxIcon;
// These classes use Windows registry to retrieve the required information.
//
// Keys used (not all of them are documented, so it might actually stop working
// in futur versions of Windows...):
// in future versions of Windows...):
// 1. "HKCR\MIME\Database\Content Type" contains subkeys for all known MIME
// types, each key has a string value "Extension" which gives (dot preceded)
// extension for the files of this MIME type.
@ -73,6 +73,218 @@ class WXDLLEXPORT wxIcon;
// location, uses it, so it isn't likely to change
static const wxChar *MIME_DATABASE_KEY = wxT("MIME\\Database\\Content Type\\");
void wxFileTypeImpl::Init(const wxString& strFileType, const wxString& ext)
{
// VZ: does it? (FIXME)
wxCHECK_RET( !ext.IsEmpty(), _T("needs an extension") );
if ( ext[0u] != wxT('.') ) {
m_ext = wxT('.');
}
m_ext << ext;
m_strFileType = strFileType;
if ( !strFileType ) {
m_strFileType = m_ext.AfterFirst('.') + "_auto_file";
}
}
wxString wxFileTypeImpl::GetVerbPath(const wxString& verb) const
{
wxString path;
path << m_strFileType << _T("\\shell\\") << verb << _T("\\command");
return path;
}
size_t wxFileTypeImpl::GetAllCommands(wxArrayString *verbs,
wxArrayString *commands,
const wxFileType::MessageParameters& params) const
{
wxCHECK_MSG( !m_ext.IsEmpty(), 0, _T("GetAllCommands() needs an extension") );
if ( m_strFileType.IsEmpty() )
{
// get it from the registry
wxFileTypeImpl *self = wxConstCast(this, wxFileTypeImpl);
wxRegKey rkey(wxRegKey::HKCR, m_ext);
if ( !rkey.Exists() || !rkey.QueryValue(_T(""), self->m_strFileType) )
{
wxLogDebug(_T("Can't get the filetype for extension '%s'."),
m_ext.c_str());
return 0;
}
}
// enum all subkeys of HKCR\filetype\shell
size_t count = 0;
wxRegKey rkey(wxRegKey::HKCR, m_strFileType + _T("\\shell"));
long dummy;
wxString verb;
bool ok = rkey.GetFirstKey(verb, dummy);
while ( ok )
{
wxString command = wxFileType::ExpandCommand(GetCommand(verb), params);
// we want the open bverb to eb always the first
if ( verb.CmpNoCase(_T("open")) == 0 )
{
if ( verbs )
verbs->Insert(verb, 0);
if ( commands )
commands->Insert(command, 0);
}
else // anything else than "open"
{
if ( verbs )
verbs->Add(verb);
if ( commands )
commands->Add(command);
}
ok = rkey.GetNextKey(verb, dummy);
}
return count;
}
// ----------------------------------------------------------------------------
// modify the registry database
// ----------------------------------------------------------------------------
bool wxFileTypeImpl::EnsureExtKeyExists()
{
wxRegKey rkey(wxRegKey::HKCR, m_ext);
if ( !rkey.Exists() )
{
if ( !rkey.Create() || !rkey.SetValue(_T(""), m_strFileType) )
{
wxLogError(_("Failed to create registry entry for '%s' files."),
m_ext.c_str());
return FALSE;
}
}
return TRUE;
}
bool wxFileTypeImpl::SetCommand(const wxString& cmd,
const wxString& verb,
bool overwriteprompt)
{
wxCHECK_MSG( !m_ext.IsEmpty() && !verb.IsEmpty(), FALSE,
_T("SetCommand() needs an extension and a verb") );
if ( !EnsureExtKeyExists() )
return FALSE;
wxRegKey rkey(wxRegKey::HKCR, GetVerbPath(verb));
if ( rkey.Exists() && overwriteprompt )
{
#if wxUSE_GUI
wxString old;
rkey.QueryValue(wxT(""), old);
if ( wxMessageBox
(
wxString::Format(
_("Do you want to overwrite the command used to %s "
"files with extension \"%s\" (current value is '%s', "
"new value is '%s')?"),
verb.c_str(),
m_ext.c_str(),
old.c_str(),
cmd.c_str()),
_("Confirm registry update"),
wxYES_NO | wxICON_QUESTION
) != wxYES )
#endif // wxUSE_GUI
{
// cancelled by user
return FALSE;
}
}
// TODO:
// 1. translate '%s' to '%1' instead of always adding it
// 2. create DDEExec value if needed (undo GetCommand)
return rkey.Create() && rkey.SetValue(_T(""), cmd + _T(" \"%1\"") );
}
bool wxFileTypeImpl::SetMimeType(const wxString& mimeTypeOrig)
{
wxCHECK_MSG( !m_ext.IsEmpty(), FALSE, _T("SetMimeType() needs extension") );
if ( !EnsureExtKeyExists() )
return FALSE;
// VZ: is this really useful? (FIXME)
wxString mimeType;
if ( !mimeTypeOrig )
{
// make up a default value for it
wxString cmd;
wxSplitPath(GetCommand(_T("open")), NULL, &cmd, NULL);
mimeType << _T("application/x-") << cmd;
}
else
{
mimeType = mimeTypeOrig;
}
wxRegKey rkey(wxRegKey::HKCR, m_ext);
return rkey.Create() && rkey.SetValue(_T("Content Type"), mimeType);
}
bool wxFileTypeImpl::SetDefaultIcon(const wxString& cmd, int index)
{
wxCHECK_MSG( !m_ext.IsEmpty(), FALSE, _T("SetMimeType() needs extension") );
wxCHECK_MSG( wxFileExists(cmd), FALSE, _T("Icon file not found.") );
if ( !EnsureExtKeyExists() )
return FALSE;
wxRegKey rkey(wxRegKey::HKCR, m_strFileType + _T("\\DefaultIcon"));
return rkey.Create() &&
rkey.SetValue(_T(""),
wxString::Format(_T("%s,%d"), cmd.c_str(), index));
}
// ----------------------------------------------------------------------------
// remove file association
// ----------------------------------------------------------------------------
bool wxFileTypeImpl::RemoveCommand(const wxString& verb)
{
wxCHECK_MSG( !m_ext.IsEmpty() && !verb.IsEmpty(), FALSE,
_T("RemoveCommand() needs an extension and a verb") );
wxString sKey = m_strFileType;
wxRegKey rkey(wxRegKey::HKCR, GetVerbPath(verb));
// if the key already doesn't exist, it's a success
return !rkey.Exists() || rkey.DeleteSelf();
}
bool wxFileTypeImpl::RemoveMimeType()
{
wxCHECK_MSG( !m_ext.IsEmpty(), FALSE, _T("RemoveMimeType() needs extension") );
wxRegKey rkey(wxRegKey::HKCR, m_ext);
return !rkey.Exists() || rkey.DeleteSelf();
}
bool wxFileTypeImpl::RemoveDefaultIcon()
{
wxCHECK_MSG( !m_ext.IsEmpty(), FALSE,
_T("RemoveDefaultIcon() needs extension") );
wxRegKey rkey (wxRegKey::HKCR, m_strFileType + _T("\\DefaultIcon"));
return !rkey.Exists() || rkey.DeleteSelf();
}
wxString wxFileTypeImpl::GetCommand(const wxChar *verb) const
{
// suppress possible error messages
@ -226,12 +438,11 @@ bool wxFileTypeImpl::GetMimeType(wxString *mimeType) const
// suppress possible error messages
wxLogNull nolog;
wxRegKey key(wxRegKey::HKCR, wxT(".") + m_ext);
wxRegKey key(wxRegKey::HKCR, m_ext);
return key.Open() && key.QueryValue(wxT("Content Type"), *mimeType);
}
bool wxFileTypeImpl::GetMimeTypes(wxArrayString& mimeTypes) const
{
wxString s;
@ -247,7 +458,9 @@ bool wxFileTypeImpl::GetMimeTypes(wxArrayString& mimeTypes) const
}
bool wxFileTypeImpl::GetIcon(wxIcon *icon) const
bool wxFileTypeImpl::GetIcon(wxIcon *icon,
wxString *iconFile,
int *iconIndex) const
{
#if wxUSE_GUI
if ( m_info ) {
@ -280,7 +493,7 @@ bool wxFileTypeImpl::GetIcon(wxIcon *icon) const
}
wxString strExpPath = wxExpandEnvVars(strFullPath);
int nIndex = wxAtoi(strIndex);
int nIndex = wxAtoi(strIndex) - 1 ; //bug here we need C based counting!!
HICON hIcon = ExtractIcon(GetModuleHandle(NULL), strExpPath, nIndex);
switch ( (int)hIcon ) {
@ -292,6 +505,10 @@ bool wxFileTypeImpl::GetIcon(wxIcon *icon) const
default:
icon->SetHICON((WXHICON)hIcon);
if ( iconIndex )
*iconIndex = nIndex;
if ( iconFile )
*iconFile = strFullPath;
return TRUE;
}
}
@ -326,6 +543,15 @@ bool wxFileTypeImpl::GetDescription(wxString *desc) const
return FALSE;
}
// helper function
wxFileType *
wxMimeTypesManagerImpl::CreateFileType(const wxString& filetype, const wxString& ext)
{
wxFileType *fileType = new wxFileType;
fileType->m_impl->Init(filetype, ext);
return fileType;
}
// extension -> file type
wxFileType *
wxMimeTypesManagerImpl::GetFileTypeFromExtension(const wxString& ext)
@ -348,10 +574,7 @@ wxMimeTypesManagerImpl::GetFileTypeFromExtension(const wxString& ext)
// it's the default value of the key
if ( key.QueryValue(wxT(""), strFileType) ) {
// create the new wxFileType object
wxFileType *fileType = new wxFileType;
fileType->m_impl->Init(strFileType, ext);
return fileType;
return CreateFileType(strFileType, ext);
}
else {
// this extension doesn't have a filetype, but it's known to the
@ -380,12 +603,22 @@ wxMimeTypesManagerImpl::GetFileTypeFromExtension(const wxString& ext)
return NULL;
}
wxFileType *fileType = new wxFileType;
fileType->m_impl->Init(wxEmptyString, ext);
return CreateFileType(wxEmptyString, ext);
}
wxFileType *
wxMimeTypesManagerImpl::GetOrAllocateFileTypeFromExtension(const wxString& ext)
{
wxFileType *fileType = GetFileTypeFromExtension(ext);
if ( !fileType )
{
fileType = CreateFileType(wxEmptyString, ext);
}
return fileType;
}
// MIME type -> extension -> file type
wxFileType *
wxMimeTypesManagerImpl::GetFileTypeFromMimeType(const wxString& mimeType)
@ -440,6 +673,93 @@ size_t wxMimeTypesManagerImpl::EnumAllFileTypes(wxArrayString& mimetypes)
return mimetypes.GetCount();
}
// ----------------------------------------------------------------------------
// create a new association
// ----------------------------------------------------------------------------
wxFileType *wxMimeTypesManager::Associate(const wxString& ext,
const wxString& mimetype,
const wxString& filetypeOrig,
const wxString& WXUNUSED(desc))
{
wxCHECK_MSG( !ext.empty(), NULL, _T("Associate() needs extension") );
wxString extWithDot;
if ( ext[0u] != _T('.') )
extWithDot = _T('.');
extWithDot += ext;
wxRegKey key(wxRegKey::HKCR, extWithDot);
wxFileType *ft = NULL;
if ( !key.Exists() )
{
wxString filetype;
// create the mapping from the extension to the filetype
bool ok = key.Create();
if ( ok )
{
if ( filetypeOrig.empty() )
{
// make it up from the extension
filetype << extWithDot.c_str() + 1 << _T("_auto_file");
}
else
{
// just use the provided one
filetype = filetypeOrig;
}
ok = key.SetValue(_T(""), filetype);
}
if ( ok && !mimetype.empty() )
{
// set the MIME type
ok = key.SetValue(_T("Content Type"), mimetype);
if ( ok )
{
// create the MIME key
wxString strKey = MIME_DATABASE_KEY;
strKey << mimetype;
wxRegKey keyMIME(wxRegKey::HKCR, strKey);
ok = keyMIME.Create();
if ( ok )
{
// and provide a back link to the extension
ok = keyMIME.SetValue(_T("Extension"), extWithDot);
}
}
}
if ( ok )
{
// create the filetype key itself (it will be empty for now, but
// SetCommand(), SetDefaultIcon() &c will use it later)
wxRegKey keyFT(wxRegKey::HKCR, filetype);
ok = keyFT.Create();
}
if ( ok )
{
// ok, we've created everything correctly
ft = m_impl->CreateFileType(filetype, extWithDot);
}
else
{
// one of the registry operations failed
wxLogError(_("Failed to register extension '%s'."), ext.c_str());
}
}
else // key already exists
{
// FIXME we probably should return an existing file type then?
}
return ft;
}
#endif
// __WIN16__