From 9c6befef3ab95ce6c250a33dced0e3a32300f23d Mon Sep 17 00:00:00 2001 From: RickS Date: Tue, 20 Sep 2016 20:03:21 +0200 Subject: [PATCH] Support for context-sensitive translations --- include/wx/translation.h | 39 +++++++++++++++++++++++++++----------- src/common/translation.cpp | 28 +++++++++++++++++---------- 2 files changed, 46 insertions(+), 21 deletions(-) diff --git a/include/wx/translation.h b/include/wx/translation.h index a85c2a1612..9837a21f61 100644 --- a/include/wx/translation.h +++ b/include/wx/translation.h @@ -32,11 +32,14 @@ // ---------------------------------------------------------------------------- // gettext() style macros (notice that xgettext should be invoked with -// --keyword="_" --keyword="wxPLURAL:1,2" options -// to extract the strings from the sources) +// --keyword="_" --keyword="wxPLURAL:1,2" --keyword="wxCONTEXT:1c,2" +// --keyword="wxCONTEXTPLURAL:1c,2,3" options to extract the strings from the +// sources) #ifndef WXINTL_NO_GETTEXT_MACRO - #define _(s) wxGetTranslation((s)) - #define wxPLURAL(sing, plur, n) wxGetTranslation((sing), (plur), n) + #define _(s) wxGetTranslation((s)) + #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 // another one which just marks the strings for extraction, but doesn't @@ -79,7 +82,7 @@ public: wxString GetDomain() const { return m_domain; } // 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: wxMsgCatalog(const wxString& domain) @@ -154,10 +157,12 @@ public: // access to translations 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, unsigned n, - const wxString& domain = wxEmptyString) const; + const wxString& domain = wxEmptyString, + const wxString& context = wxEmptyString) const; wxString GetHeaderValue(const wxString& header, const wxString& domain = wxEmptyString) const; @@ -247,10 +252,11 @@ protected: // get the translation of the string in the current locale inline const wxString& wxGetTranslation(const wxString& str, - const wxString& domain = wxString()) + const wxString& domain = wxString(), + const wxString& context = wxString()) { wxTranslations *trans = wxTranslations::Get(); - const wxString *transStr = trans ? trans->GetTranslatedString(str, domain) + const wxString *transStr = trans ? trans->GetTranslatedString(str, domain, context) : NULL; if ( transStr ) return *transStr; @@ -263,10 +269,11 @@ inline const wxString& wxGetTranslation(const wxString& str, inline const wxString& wxGetTranslation(const wxString& str1, const wxString& str2, unsigned n, - const wxString& domain = wxString()) + const wxString& domain = wxString(), + const wxString& context = wxString()) { wxTranslations *trans = wxTranslations::Get(); - const wxString *transStr = trans ? trans->GetTranslatedString(str1, n, domain) + const wxString *transStr = trans ? trans->GetTranslatedString(str1, n, domain, context) : NULL; if ( transStr ) return *transStr; @@ -304,6 +311,10 @@ template inline TString wxGetTranslation(TString str, TDomain WXUNUSED(domain)) { return str; } +template +inline TString wxGetTranslation(TString str, TDomain WXUNUSED(domain), TContext WXUNUSED(context)) + { return str; } + template inline TString wxGetTranslation(TString str1, TString str2, size_t n) { return n == 1 ? str1 : str2; } @@ -313,6 +324,12 @@ inline TString wxGetTranslation(TString str1, TString str2, size_t n, TDomain WXUNUSED(domain)) { return n == 1 ? str1 : str2; } +template +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 // define this one just in case it occurs somewhere (instead of preferred diff --git a/src/common/translation.cpp b/src/common/translation.cpp index 96df133112..21dc0daf50 100644 --- a/src/common/translation.cpp +++ b/src/common/translation.cpp @@ -1352,7 +1352,7 @@ wxMsgCatalog *wxMsgCatalog::CreateFromData(const wxScopedCharBuffer& data, 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; if (n != UINT_MAX) @@ -1362,11 +1362,17 @@ const wxString *wxMsgCatalog::GetString(const wxString& str, unsigned n) const wxStringToStringHashMap::const_iterator i; 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 { - 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() ) @@ -1631,14 +1637,16 @@ const wxString& wxTranslations::GetUntranslatedString(const wxString& str) 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, unsigned n, - const wxString& domain) const + const wxString& domain, + const wxString& context) const { if ( origString.empty() ) return NULL; @@ -1652,14 +1660,14 @@ const wxString *wxTranslations::GetTranslatedString(const wxString& origString, // does the catalog exist? if ( pMsgCat != NULL ) - trans = pMsgCat->GetString(origString, n); + trans = pMsgCat->GetString(origString, n, context); } else { // search in all domains 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 break; } @@ -1670,10 +1678,11 @@ const wxString *wxTranslations::GetTranslatedString(const wxString& origString, wxLogTrace ( TRACE_I18N, - "string \"%s\"%s not found in %slocale '%s'.", + "string \"%s\"%s not found in %s%slocale '%s'.", origString, (n != UINT_MAX ? wxString::Format("[%ld]", (long)n) : wxString()), (!domain.empty() ? wxString::Format("domain '%s' ", domain) : wxString()), + (!context.empty() ? wxString::Format("context '%s' ", context) : wxString()), m_lang ); } @@ -1681,7 +1690,6 @@ const wxString *wxTranslations::GetTranslatedString(const wxString& origString, return trans; } - wxString wxTranslations::GetHeaderValue(const wxString& header, const wxString& domain) const {