Support for context-sensitive translations

This commit is contained in:
RickS
2016-09-20 20:03:21 +02:00
committed by Vadim Zeitlin
parent 9592823cde
commit 9c6befef3a
2 changed files with 46 additions and 21 deletions

View File

@@ -32,11 +32,14 @@
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// gettext() style macros (notice that xgettext should be invoked with // gettext() style macros (notice that xgettext should be invoked with
// --keyword="_" --keyword="wxPLURAL:1,2" options // --keyword="_" --keyword="wxPLURAL:1,2" --keyword="wxCONTEXT:1c,2"
// to extract the strings from the sources) // --keyword="wxCONTEXTPLURAL:1c,2,3" options to extract the strings from the
// sources)
#ifndef WXINTL_NO_GETTEXT_MACRO #ifndef WXINTL_NO_GETTEXT_MACRO
#define _(s) wxGetTranslation((s)) #define _(s) wxGetTranslation((s))
#define wxPLURAL(sing, plur, n) wxGetTranslation((sing), (plur), n) #define wxPLURAL(sing, plur, n) wxGetTranslation((sing), (plur), n)
#define wxCONTEXT(c, s) wxGetTranslation((s), wxString(), c)
#define wxCONTEXTPLURAL(c, sing, plur, n) wxGetTranslation((sing), (plur), n, wxString(), c)
#endif #endif
// another one which just marks the strings for extraction, but doesn't // another one which just marks the strings for extraction, but doesn't
@@ -79,7 +82,7 @@ public:
wxString GetDomain() const { return m_domain; } wxString GetDomain() const { return m_domain; }
// get the translated string: returns NULL if not found // get the translated string: returns NULL if not found
const wxString *GetString(const wxString& sz, unsigned n = UINT_MAX) const; const wxString *GetString(const wxString& sz, unsigned n = UINT_MAX, const wxString& ct = wxEmptyString) const;
protected: protected:
wxMsgCatalog(const wxString& domain) wxMsgCatalog(const wxString& domain)
@@ -154,10 +157,12 @@ public:
// access to translations // access to translations
const wxString *GetTranslatedString(const wxString& origString, const wxString *GetTranslatedString(const wxString& origString,
const wxString& domain = wxEmptyString) const; const wxString& domain = wxEmptyString,
const wxString& context = wxEmptyString) const;
const wxString *GetTranslatedString(const wxString& origString, const wxString *GetTranslatedString(const wxString& origString,
unsigned n, unsigned n,
const wxString& domain = wxEmptyString) const; const wxString& domain = wxEmptyString,
const wxString& context = wxEmptyString) const;
wxString GetHeaderValue(const wxString& header, wxString GetHeaderValue(const wxString& header,
const wxString& domain = wxEmptyString) const; const wxString& domain = wxEmptyString) const;
@@ -247,10 +252,11 @@ protected:
// get the translation of the string in the current locale // get the translation of the string in the current locale
inline const wxString& wxGetTranslation(const wxString& str, inline const wxString& wxGetTranslation(const wxString& str,
const wxString& domain = wxString()) const wxString& domain = wxString(),
const wxString& context = wxString())
{ {
wxTranslations *trans = wxTranslations::Get(); wxTranslations *trans = wxTranslations::Get();
const wxString *transStr = trans ? trans->GetTranslatedString(str, domain) const wxString *transStr = trans ? trans->GetTranslatedString(str, domain, context)
: NULL; : NULL;
if ( transStr ) if ( transStr )
return *transStr; return *transStr;
@@ -263,10 +269,11 @@ inline const wxString& wxGetTranslation(const wxString& str,
inline const wxString& wxGetTranslation(const wxString& str1, inline const wxString& wxGetTranslation(const wxString& str1,
const wxString& str2, const wxString& str2,
unsigned n, unsigned n,
const wxString& domain = wxString()) const wxString& domain = wxString(),
const wxString& context = wxString())
{ {
wxTranslations *trans = wxTranslations::Get(); wxTranslations *trans = wxTranslations::Get();
const wxString *transStr = trans ? trans->GetTranslatedString(str1, n, domain) const wxString *transStr = trans ? trans->GetTranslatedString(str1, n, domain, context)
: NULL; : NULL;
if ( transStr ) if ( transStr )
return *transStr; return *transStr;
@@ -304,6 +311,10 @@ template<typename TString, typename TDomain>
inline TString wxGetTranslation(TString str, TDomain WXUNUSED(domain)) inline TString wxGetTranslation(TString str, TDomain WXUNUSED(domain))
{ return str; } { return str; }
template<typename TString, typename TDomain, typename TContext>
inline TString wxGetTranslation(TString str, TDomain WXUNUSED(domain), TContext WXUNUSED(context))
{ return str; }
template<typename TString, typename TDomain> template<typename TString, typename TDomain>
inline TString wxGetTranslation(TString str1, TString str2, size_t n) inline TString wxGetTranslation(TString str1, TString str2, size_t n)
{ return n == 1 ? str1 : str2; } { return n == 1 ? str1 : str2; }
@@ -313,6 +324,12 @@ inline TString wxGetTranslation(TString str1, TString str2, size_t n,
TDomain WXUNUSED(domain)) TDomain WXUNUSED(domain))
{ return n == 1 ? str1 : str2; } { return n == 1 ? str1 : str2; }
template<typename TString, typename TDomain, typename TContext>
inline TString wxGetTranslation(TString str1, TString str2, size_t n,
TDomain WXUNUSED(domain),
TContext WXUNUSED(context))
{ return n == 1 ? str1 : str2; }
#endif // wxUSE_INTL/!wxUSE_INTL #endif // wxUSE_INTL/!wxUSE_INTL
// define this one just in case it occurs somewhere (instead of preferred // define this one just in case it occurs somewhere (instead of preferred

View File

@@ -1352,7 +1352,7 @@ wxMsgCatalog *wxMsgCatalog::CreateFromData(const wxScopedCharBuffer& data,
return cat.release(); return cat.release();
} }
const wxString *wxMsgCatalog::GetString(const wxString& str, unsigned n) const const wxString *wxMsgCatalog::GetString(const wxString& str, unsigned n, const wxString& context) const
{ {
int index = 0; int index = 0;
if (n != UINT_MAX) if (n != UINT_MAX)
@@ -1362,11 +1362,17 @@ const wxString *wxMsgCatalog::GetString(const wxString& str, unsigned n) const
wxStringToStringHashMap::const_iterator i; wxStringToStringHashMap::const_iterator i;
if (index != 0) if (index != 0)
{ {
i = m_messages.find(wxString(str) + wxChar(index)); // plural if (context.IsEmpty())
i = m_messages.find(wxString(str) + wxChar(index)); // plural, no context
else
i = m_messages.find(wxString(context) + wxString('\x04') + wxString(str) + wxChar(index)); // plural, context
} }
else else
{ {
i = m_messages.find(str); if (context.IsEmpty())
i = m_messages.find(str); // no context
else
i = m_messages.find(wxString(context) + wxString('\x04') + wxString(str)); // context
} }
if ( i != m_messages.end() ) if ( i != m_messages.end() )
@@ -1631,14 +1637,16 @@ const wxString& wxTranslations::GetUntranslatedString(const wxString& str)
const wxString *wxTranslations::GetTranslatedString(const wxString& origString, const wxString *wxTranslations::GetTranslatedString(const wxString& origString,
const wxString& domain) const const wxString& domain,
const wxString& context) const
{ {
return GetTranslatedString(origString, UINT_MAX, domain); return GetTranslatedString(origString, UINT_MAX, domain, context);
} }
const wxString *wxTranslations::GetTranslatedString(const wxString& origString, const wxString *wxTranslations::GetTranslatedString(const wxString& origString,
unsigned n, unsigned n,
const wxString& domain) const const wxString& domain,
const wxString& context) const
{ {
if ( origString.empty() ) if ( origString.empty() )
return NULL; return NULL;
@@ -1652,14 +1660,14 @@ const wxString *wxTranslations::GetTranslatedString(const wxString& origString,
// does the catalog exist? // does the catalog exist?
if ( pMsgCat != NULL ) if ( pMsgCat != NULL )
trans = pMsgCat->GetString(origString, n); trans = pMsgCat->GetString(origString, n, context);
} }
else else
{ {
// search in all domains // search in all domains
for ( pMsgCat = m_pMsgCat; pMsgCat != NULL; pMsgCat = pMsgCat->m_pNext ) for ( pMsgCat = m_pMsgCat; pMsgCat != NULL; pMsgCat = pMsgCat->m_pNext )
{ {
trans = pMsgCat->GetString(origString, n); trans = pMsgCat->GetString(origString, n, context);
if ( trans != NULL ) // take the first found if ( trans != NULL ) // take the first found
break; break;
} }
@@ -1670,10 +1678,11 @@ const wxString *wxTranslations::GetTranslatedString(const wxString& origString,
wxLogTrace wxLogTrace
( (
TRACE_I18N, TRACE_I18N,
"string \"%s\"%s not found in %slocale '%s'.", "string \"%s\"%s not found in %s%slocale '%s'.",
origString, origString,
(n != UINT_MAX ? wxString::Format("[%ld]", (long)n) : wxString()), (n != UINT_MAX ? wxString::Format("[%ld]", (long)n) : wxString()),
(!domain.empty() ? wxString::Format("domain '%s' ", domain) : wxString()), (!domain.empty() ? wxString::Format("domain '%s' ", domain) : wxString()),
(!context.empty() ? wxString::Format("context '%s' ", context) : wxString()),
m_lang m_lang
); );
} }
@@ -1681,7 +1690,6 @@ const wxString *wxTranslations::GetTranslatedString(const wxString& origString,
return trans; return trans;
} }
wxString wxTranslations::GetHeaderValue(const wxString& header, wxString wxTranslations::GetHeaderValue(const wxString& header,
const wxString& domain) const const wxString& domain) const
{ {