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:
@@ -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)
|
||||
// ----------------------------------------------------------------------------
|
||||
|
Reference in New Issue
Block a user