added optional context to a localization string to allow multiple translations. Closes #1082

This commit is contained in:
oy 2013-06-04 18:41:32 +02:00
parent 4a88f93683
commit acaaa9723b
5 changed files with 31 additions and 16 deletions

@ -1 +1 @@
Subproject commit f2e678b8b2a07bd3d20819e4715df38cb634577c Subproject commit 2db7e188ba163d9ded067cd771a057d83ef63832

View file

@ -474,7 +474,7 @@ void CMenus::RenderDemoList(CUIRect MainView)
BottomView.VSplitLeft(Spacing, 0, &BottomView); BottomView.VSplitLeft(Spacing, 0, &BottomView);
BottomView.VSplitLeft(ButtonWidth, &Button, &BottomView); BottomView.VSplitLeft(ButtonWidth, &Button, &BottomView);
static int s_PlayButton = 0; static int s_PlayButton = 0;
if(DoButton_Menu(&s_PlayButton, m_DemolistSelectedIsDir?Localize("Open"):Localize("Play"), 0, &Button) || Activated) if(DoButton_Menu(&s_PlayButton, m_DemolistSelectedIsDir?Localize("Open"):Localize("Play", "DemoBrowser"), 0, &Button) || Activated)
{ {
if(m_DemolistSelectedIndex >= 0) if(m_DemolistSelectedIndex >= 0)
{ {

View file

@ -305,6 +305,6 @@ inline vec3 HslToRgb(vec3 HSL)
} }
extern const char *Localize(const char *Str); extern const char *Localize(const char *Str, const char *pContext="");
#endif #endif

View file

@ -8,23 +8,24 @@
#include <engine/console.h> #include <engine/console.h>
#include <engine/storage.h> #include <engine/storage.h>
const char *Localize(const char *pStr) const char *Localize(const char *pStr, const char *pContext)
{ {
const char *pNewStr = g_Localization.FindString(str_quickhash(pStr)); const char *pNewStr = g_Localization.FindString(str_quickhash(pStr), str_quickhash(pContext));
return pNewStr ? pNewStr : pStr; return pNewStr ? pNewStr : pStr;
} }
CLocConstString::CLocConstString(const char *pStr) CLocConstString::CLocConstString(const char *pStr, const char *pContext)
{ {
m_pDefaultStr = pStr; m_pDefaultStr = pStr;
m_Hash = str_quickhash(m_pDefaultStr); m_Hash = str_quickhash(m_pDefaultStr);
m_ContextHash = str_quickhash(pContext);
m_Version = -1; m_Version = -1;
} }
void CLocConstString::Reload() void CLocConstString::Reload()
{ {
m_Version = g_Localization.Version(); m_Version = g_Localization.Version();
const char *pNewStr = g_Localization.FindString(m_Hash); const char *pNewStr = g_Localization.FindString(m_Hash, m_ContextHash);
m_pCurrentStr = pNewStr; m_pCurrentStr = pNewStr;
if(!m_pCurrentStr) if(!m_pCurrentStr)
m_pCurrentStr = m_pDefaultStr; m_pCurrentStr = m_pDefaultStr;
@ -36,10 +37,11 @@ CLocalizationDatabase::CLocalizationDatabase()
m_CurrentVersion = 0; m_CurrentVersion = 0;
} }
void CLocalizationDatabase::AddString(const char *pOrgStr, const char *pNewStr) void CLocalizationDatabase::AddString(const char *pOrgStr, const char *pNewStr, const char *pContext)
{ {
CString s; CString s;
s.m_Hash = str_quickhash(pOrgStr); s.m_Hash = str_quickhash(pOrgStr);
s.m_ContextHash = str_quickhash(pContext);
s.m_Replacement = *pNewStr ? pNewStr : pOrgStr; s.m_Replacement = *pNewStr ? pNewStr : pOrgStr;
m_Strings.add(s); m_Strings.add(s);
} }
@ -87,7 +89,7 @@ bool CLocalizationDatabase::Load(const char *pFilename, IStorage *pStorage, ICon
if(rStart.type == json_array) if(rStart.type == json_array)
{ {
for(unsigned i = 0; i < rStart.u.array.length; ++i) for(unsigned i = 0; i < rStart.u.array.length; ++i)
AddString((const char *)rStart[i]["or"], (const char *)rStart[i]["tr"]); AddString((const char *)rStart[i]["or"], (const char *)rStart[i]["tr"], (const char *)rStart[i]["context"]);
} }
// clean up // clean up
@ -97,14 +99,26 @@ bool CLocalizationDatabase::Load(const char *pFilename, IStorage *pStorage, ICon
return true; return true;
} }
const char *CLocalizationDatabase::FindString(unsigned Hash) const char *CLocalizationDatabase::FindString(unsigned Hash, unsigned ContextHash)
{ {
CString String; CString String;
String.m_Hash = Hash; String.m_Hash = Hash;
sorted_array<CString>::range r = ::find_binary(m_Strings.all(), String); sorted_array<CString>::range r = ::find_binary(m_Strings.all(), String);
if(r.empty()) if(r.empty())
return 0; return 0;
return r.front().m_Replacement;
unsigned DefaultHash = str_quickhash("");
unsigned DefaultIndex = 0;
for(unsigned i = 0; i < r.size(); ++i)
{
const CString &rStr = r.index(i);
if(rStr.m_ContextHash == ContextHash)
return rStr.m_Replacement;
else if(rStr.m_ContextHash == DefaultHash)
DefaultIndex = i;
}
return r.index(DefaultIndex).m_Replacement;
} }
CLocalizationDatabase g_Localization; CLocalizationDatabase g_Localization;

View file

@ -11,6 +11,7 @@ class CLocalizationDatabase
{ {
public: public:
unsigned m_Hash; unsigned m_Hash;
unsigned m_ContextHash;
// TODO: do this as an const char * and put everything on a incremental heap // TODO: do this as an const char * and put everything on a incremental heap
string m_Replacement; string m_Replacement;
@ -31,8 +32,8 @@ public:
int Version() { return m_CurrentVersion; } int Version() { return m_CurrentVersion; }
void AddString(const char *pOrgStr, const char *pNewStr); void AddString(const char *pOrgStr, const char *pNewStr, const char *pContext);
const char *FindString(unsigned Hash); const char *FindString(unsigned Hash, unsigned ContextHash);
}; };
extern CLocalizationDatabase g_Localization; extern CLocalizationDatabase g_Localization;
@ -42,9 +43,10 @@ class CLocConstString
const char *m_pDefaultStr; const char *m_pDefaultStr;
const char *m_pCurrentStr; const char *m_pCurrentStr;
unsigned m_Hash; unsigned m_Hash;
unsigned m_ContextHash;
int m_Version; int m_Version;
public: public:
CLocConstString(const char *pStr); CLocConstString(const char *pStr, const char *pContext="");
void Reload(); void Reload();
inline operator const char *() inline operator const char *()
@ -55,6 +57,5 @@ public:
} }
}; };
extern const char *Localize(const char *pStr, const char *pContext);
extern const char *Localize(const char *pStr);
#endif #endif