Add support for storing translations in win32 resources.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@64155 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Václav Slavík
2010-04-26 20:51:22 +00:00
parent 076c0a8ee8
commit bc71c3cdd5
4 changed files with 208 additions and 35 deletions

View File

@@ -809,13 +809,17 @@ WX_DECLARE_EXPORTED_STRING_HASH_MAP(wxString, wxMessagesHash);
class wxMsgCatalogFile
{
public:
typedef wxScopedCharTypeBuffer<char> DataBuffer;
// ctor & dtor
wxMsgCatalogFile();
~wxMsgCatalogFile();
// load the catalog from disk
bool Load(const wxString& filename,
wxPluralFormsCalculatorPtr& rPluralFormsCalculator);
bool LoadFile(const wxString& filename,
wxPluralFormsCalculatorPtr& rPluralFormsCalculator);
bool LoadData(const DataBuffer& data,
wxPluralFormsCalculatorPtr& rPluralFormsCalculator);
// fills the hash with string-translation pairs
bool FillHash(wxMessagesHash& hash, const wxString& msgIdCharset) const;
@@ -847,7 +851,7 @@ private:
};
// all data is stored here
wxMemoryBuffer m_data;
DataBuffer m_data;
// data description
size_t32 m_numStrings; // number of strings in this domain
@@ -865,25 +869,18 @@ private:
: ui;
}
// just return the pointer to the start of the data as "char *" to
// facilitate doing pointer arithmetic with it
char *StringData() const
{
return static_cast<char *>(m_data.GetData());
}
const char *StringAtOfs(wxMsgTableEntry *pTable, size_t32 n) const
{
const wxMsgTableEntry * const ent = pTable + n;
// this check could fail for a corrupt message catalog
size_t32 ofsString = Swap(ent->ofsString);
if ( ofsString + Swap(ent->nLen) > m_data.GetDataLen())
if ( ofsString + Swap(ent->nLen) > m_data.length())
{
return NULL;
}
return StringData() + ofsString;
return m_data.data() + ofsString;
}
bool m_bSwapped; // wrong endianness?
@@ -908,9 +905,13 @@ public:
#endif
// load the catalog from disk
bool Load(const wxString& filename,
const wxString& domain,
const wxString& msgIdCharset);
bool LoadFile(const wxString& filename,
const wxString& domain,
const wxString& msgIdCharset);
bool LoadData(const wxScopedCharTypeBuffer<char>& data,
const wxString& domain,
const wxString& msgIdCharset);
// get name of the catalog
wxString GetDomain() const { return m_domain; }
@@ -947,8 +948,8 @@ wxMsgCatalogFile::~wxMsgCatalogFile()
}
// open disk file and read in it's contents
bool wxMsgCatalogFile::Load(const wxString& filename,
wxPluralFormsCalculatorPtr& rPluralFormsCalculator)
bool wxMsgCatalogFile::LoadFile(const wxString& filename,
wxPluralFormsCalculatorPtr& rPluralFormsCalculator)
{
wxFile fileMsg(filename);
if ( !fileMsg.IsOpened() )
@@ -962,17 +963,36 @@ bool wxMsgCatalogFile::Load(const wxString& filename,
size_t nSize = wx_truncate_cast(size_t, lenFile);
wxASSERT_MSG( nSize == lenFile + size_t(0), wxS("message catalog bigger than 4GB?") );
wxMemoryBuffer filedata;
// read the whole file in memory
if ( fileMsg.Read(m_data.GetWriteBuf(nSize), nSize) != lenFile )
if ( fileMsg.Read(filedata.GetWriteBuf(nSize), nSize) != lenFile )
return false;
m_data.UngetWriteBuf(nSize);
filedata.UngetWriteBuf(nSize);
bool ok = LoadData
(
DataBuffer::CreateOwned((char*)filedata.release(), nSize),
rPluralFormsCalculator
);
if ( !ok )
{
wxLogWarning(_("'%s' is not a valid message catalog."), filename.c_str());
return false;
}
return true;
}
bool wxMsgCatalogFile::LoadData(const DataBuffer& data,
wxPluralFormsCalculatorPtr& rPluralFormsCalculator)
{
// examine header
bool bValid = m_data.GetDataLen() > sizeof(wxMsgCatalogHeader);
bool bValid = data.length() > sizeof(wxMsgCatalogHeader);
const wxMsgCatalogHeader *pHeader = (wxMsgCatalogHeader *)m_data.GetData();
const wxMsgCatalogHeader *pHeader = (wxMsgCatalogHeader *)data.data();
if ( bValid ) {
// we'll have to swap all the integers if it's true
m_bSwapped = pHeader->magic == MSGCATALOG_MAGIC_SW;
@@ -983,16 +1003,17 @@ bool wxMsgCatalogFile::Load(const wxString& filename,
if ( !bValid ) {
// it's either too short or has incorrect magic number
wxLogWarning(_("'%s' is not a valid message catalog."), filename.c_str());
wxLogWarning(_("Invalid message catalog."));
return false;
}
m_data = data;
// initialize
m_numStrings = Swap(pHeader->numStrings);
m_pOrigTable = (wxMsgTableEntry *)(StringData() +
m_pOrigTable = (wxMsgTableEntry *)(data.data() +
Swap(pHeader->ofsOrigTable));
m_pTransTable = (wxMsgTableEntry *)(StringData() +
m_pTransTable = (wxMsgTableEntry *)(data.data() +
Swap(pHeader->ofsTransTable));
// now parse catalog's header and try to extract catalog charset and
@@ -1177,15 +1198,32 @@ wxMsgCatalog::~wxMsgCatalog()
}
#endif // !wxUSE_UNICODE
bool wxMsgCatalog::Load(const wxString& filename,
const wxString& domain,
const wxString& msgIdCharset)
bool wxMsgCatalog::LoadFile(const wxString& filename,
const wxString& domain,
const wxString& msgIdCharset)
{
wxMsgCatalogFile file;
m_domain = domain;
if ( !file.Load(filename, m_pluralFormsCalculator) )
if ( !file.LoadFile(filename, m_pluralFormsCalculator) )
return false;
if ( !file.FillHash(m_messages, msgIdCharset) )
return false;
return true;
}
bool wxMsgCatalog::LoadData(const wxScopedCharTypeBuffer<char>& data,
const wxString& domain,
const wxString& msgIdCharset)
{
wxMsgCatalogFile file;
m_domain = domain;
if ( !file.LoadData(data, m_pluralFormsCalculator) )
return false;
if ( !file.FillHash(m_messages, msgIdCharset) )
@@ -1417,10 +1455,38 @@ bool wxTranslations::LoadCatalogFile(const wxString& filename,
wxMsgCatalog *pMsgCat = new wxMsgCatalog;
#if wxUSE_UNICODE
const bool ok = pMsgCat->Load(filename, domain, wxEmptyString/*unused*/);
const bool ok = pMsgCat->LoadFile(filename, domain, wxEmptyString/*unused*/);
#else
const bool ok = pMsgCat->Load(filename, domain,
m_msgIdCharset[domain]);
const bool ok = pMsgCat->LoadFile(filename, domain,
m_msgIdCharset[domain]);
#endif
if ( !ok )
{
// don't add it because it couldn't be loaded anyway
delete pMsgCat;
return false;
}
// add it to the head of the list so that in GetString it will
// be searched before the catalogs added earlier
pMsgCat->m_pNext = m_pMsgCat;
m_pMsgCat = pMsgCat;
return true;
}
bool wxTranslations::LoadCatalogData(const wxScopedCharTypeBuffer<char>& data,
const wxString& domain)
{
wxMsgCatalog *pMsgCat = new wxMsgCatalog;
#if wxUSE_UNICODE
const bool ok = pMsgCat->LoadData(data, domain, wxEmptyString/*unused*/);
#else
const bool ok = pMsgCat->LoadData(data, domain,
m_msgIdCharset[domain]);
#endif
if ( !ok )
@@ -1728,6 +1794,41 @@ bool wxFileTranslationsLoader::LoadCatalog(wxTranslations *translations,
return translations->LoadCatalogFile(strFullName, domain);
}
// ----------------------------------------------------------------------------
// wxResourceTranslationsLoader
// ----------------------------------------------------------------------------
#ifdef __WINDOWS__
bool wxResourceTranslationsLoader::LoadCatalog(wxTranslations *translations,
const wxString& domain,
const wxString& lang)
{
const void *mo_data = NULL;
size_t mo_size = 0;
const wxString resname = wxString::Format("%s_%s", domain, lang);
if ( !wxLoadUserResource(&mo_data, &mo_size,
resname,
GetResourceType(),
GetModule()) )
return false;
wxLogTrace(TRACE_I18N,
"Using catalog from Windows resource \"%s\".", resname);
const bool ok = translations->LoadCatalogData(
wxCharBuffer::CreateNonOwned(static_cast<const char*>(mo_data), mo_size));
if ( !ok )
wxLogWarning(_("Resource '%s' is not a valid message catalog."), resname);
return ok;
}
#endif // __WINDOWS__
// ----------------------------------------------------------------------------
// wxTranslationsModule module (for destruction of gs_translations)
// ----------------------------------------------------------------------------