diff --git a/docs/changes.txt b/docs/changes.txt index 8321344178..4f3d302a27 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -76,6 +76,7 @@ All: - Add wxSecretStore for storing passwords using the OS-provided facilities. - Add support for compiling application code with wxNO_UNSAFE_WXSTRING_CONV. +- Add support for translating strings in different contexts (RickS). - Add support for the micro version (third component) to OS and toolkit version functions. See wxGetOsVersion(), wxPlatformInfo, and wxAppTraits. - wxLogInfo() now logs messages if the log level is high enough, even without diff --git a/include/wx/translation.h b/include/wx/translation.h index 9837a21f61..3d5d5b0b83 100644 --- a/include/wx/translation.h +++ b/include/wx/translation.h @@ -32,16 +32,22 @@ // ---------------------------------------------------------------------------- // gettext() style macros (notice that xgettext should be invoked with -// --keyword="_" --keyword="wxPLURAL:1,2" --keyword="wxCONTEXT:1c,2" -// --keyword="wxCONTEXTPLURAL:1c,2,3" options to extract the strings from the -// sources) +// --keyword="_" --keyword="wxPLURAL:1,2" 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 wxCONTEXT(c, s) wxGetTranslation((s), wxString(), c) - #define wxCONTEXTPLURAL(c, sing, plur, n) wxGetTranslation((sing), (plur), n, wxString(), c) #endif +// wx-specific macro for translating strings in the given context: if you use +// them, you need to also add +// --keyword="wxGETTEXT_IN_CONTEXT:1c,2" --keyword="wxGETTEXT_IN_CONTEXT_PLURAL:1c,2,3" +// options to xgettext invocation. +#define wxGETTEXT_IN_CONTEXT(c, s) \ + wxGetTranslation((s), wxString(), c) +#define wxGETTEXT_IN_CONTEXT_PLURAL(c, sing, plur, n) \ + wxGetTranslation((sing), (plur), n, wxString(), c) + // another one which just marks the strings for extraction, but doesn't // perform the translation (use -kwxTRANSLATE with xgettext!) #define wxTRANSLATE(str) str @@ -294,6 +300,8 @@ inline const wxString& wxGetTranslation(const wxString& str1, #define _(s) (s) #endif #define wxPLURAL(sing, plur, n) ((n) == 1 ? (sing) : (plur)) + #define wxGETTEXT_IN_CONTEXT(c, s) (s) + #define wxGETTEXT_IN_CONTEXT_PLURAL(c, sing, plur, n) wxPLURAL(sing, plur, n) #endif #define wxTRANSLATE(str) str @@ -326,7 +334,7 @@ inline TString wxGetTranslation(TString str1, TString str2, size_t n, template inline TString wxGetTranslation(TString str1, TString str2, size_t n, - TDomain WXUNUSED(domain), + TDomain WXUNUSED(domain), TContext WXUNUSED(context)) { return n == 1 ? str1 : str2; } diff --git a/interface/wx/translation.h b/interface/wx/translation.h index ad7146cd14..eed6355d0b 100644 --- a/interface/wx/translation.h +++ b/interface/wx/translation.h @@ -454,6 +454,28 @@ public: */ #define wxPLURAL(string, plural, n) +/** + Similar to _() but translates the string in the given context. + + See the description of @c context argument of wxGetTranslation(). + + @see wxGETTEXT_IN_CONTEXT_PLURAL() + + @since 3.1.1 + */ +#define wxGETTEXT_IN_CONTEXT(context, string) + +/** + Similar to wxPLURAL() but translates the string in the given context. + + See the description of @c context argument of wxGetTranslation(). + + @see wxGETTEXT_IN_CONTEXT() + + @since 3.1.1 + */ +#define wxGETTEXT_IN_CONTEXT_PLURAL(context, string, plural, n) + /** This macro doesn't do anything in the program code -- it simply expands to the value of its argument. @@ -515,6 +537,16 @@ public: also common in Unix world) syntax is provided: the _() macro is defined to do the same thing as wxGetTranslation(). + If @a context is not empty (notice that this argument is only available + starting from wxWidgets 3.1.1), item translation is looked up in the + specified context. This allows to have different translations for the same + string appearing in different contexts, e.g. it may be necessary to + translate the same English "Open" verb differently depending on the object + it applies to. To do this, you need to use @c msgctxt in the source message + catalog and specify different contexts for the different occurrences of the + string and then use the same contexts in the calls to this function (or + wxGETTEXT_IN_CONTEXT() or wxGETTEXT_IN_CONTEXT_PLURAL() macros). + This function is thread-safe. @note This function is not suitable for literal strings using wxT() macro @@ -527,7 +559,8 @@ public: @header{wx/intl.h} */ const wxString& wxGetTranslation(const wxString& string, - const wxString& domain = wxEmptyString); + const wxString& domain = wxEmptyString, + const wxString& context = wxEmptyString); /** This is an overloaded version of @@ -553,7 +586,8 @@ const wxString& wxGetTranslation(const wxString& string, */ const wxString& wxGetTranslation(const wxString& string, const wxString& plural, unsigned n, - const wxString& domain = wxEmptyString); + const wxString& domain = wxEmptyString, + const wxString& context = wxEmptyString); /** Macro to be used around all literal strings that should be translated. diff --git a/samples/internat/fr/internat.mo b/samples/internat/fr/internat.mo index 8c31175070..f65c6b7003 100644 Binary files a/samples/internat/fr/internat.mo and b/samples/internat/fr/internat.mo differ diff --git a/samples/internat/fr/internat.po b/samples/internat/fr/internat.po index 8130249688..fcd9a5cafe 100644 --- a/samples/internat/fr/internat.po +++ b/samples/internat/fr/internat.po @@ -17,32 +17,32 @@ msgstr "" "X-Generator: Poedit 1.8.7\n" msgid "item" -msgstr "item0" +msgstr "Item without context" -msgctxt "cont1" +msgctxt "context_1" msgid "item" -msgstr "item1" +msgstr "Item in context 1" -msgctxt "cont2" +msgctxt "context_2" msgid "item" -msgstr "item2" +msgstr "Item in context 2" msgid "sing" msgid_plural "plur" -msgstr[0] "sing0" -msgstr[1] "plur0" +msgstr[0] "Singular form without context" +msgstr[1] "Plural form without context" -msgctxt "cont1" +msgctxt "context_1" msgid "sing" msgid_plural "plur" -msgstr[0] "sing1" -msgstr[1] "plur1" +msgstr[0] "Singular form in context 1" +msgstr[1] "Plural form in context 1" -msgctxt "cont2" +msgctxt "context_2" msgid "sing" msgid_plural "plur" -msgstr[0] "sing2" -msgstr[1] "plur2" +msgstr[0] "Singular form in context 2" +msgstr[1] "Plural form in context 2" #: internat.cpp:98 msgid "International wxWindows App" diff --git a/samples/internat/internat.cpp b/samples/internat/internat.cpp index f3f706d9c3..abc4f0c6a8 100644 --- a/samples/internat/internat.cpp +++ b/samples/internat/internat.cpp @@ -317,16 +317,18 @@ MyFrame::MyFrame(wxLocale& locale) test_menu->Append(INTERNAT_TEST_MSGBOX, _("&Message box test"), _("Tests message box buttons labels translation")); + // Note that all these strings are currently "translated" only in French + // catalog, so you need to use French locale to see them in action. wxMenu *macro_menu = new wxMenu; macro_menu->Append(INTERNAT_MACRO_1, _("item")); - macro_menu->Append(INTERNAT_MACRO_2, wxCONTEXT("cont1", "item")); - macro_menu->Append(INTERNAT_MACRO_3, wxCONTEXT("cont2", "item")); + macro_menu->Append(INTERNAT_MACRO_2, wxGETTEXT_IN_CONTEXT("context_1", "item")); + macro_menu->Append(INTERNAT_MACRO_3, wxGETTEXT_IN_CONTEXT("context_2", "item")); macro_menu->Append(INTERNAT_MACRO_4, wxPLURAL("sing", "plur", 1)); macro_menu->Append(INTERNAT_MACRO_5, wxPLURAL("sing", "plur", 2)); - macro_menu->Append(INTERNAT_MACRO_6, wxCONTEXTPLURAL("cont1", "sing", "plur", 1)); - macro_menu->Append(INTERNAT_MACRO_7, wxCONTEXTPLURAL("cont1", "sing", "plur", 2)); - macro_menu->Append(INTERNAT_MACRO_8, wxCONTEXTPLURAL("cont2", "sing", "plur", 1)); - macro_menu->Append(INTERNAT_MACRO_9, wxCONTEXTPLURAL("cont2", "sing", "plur", 2)); + macro_menu->Append(INTERNAT_MACRO_6, wxGETTEXT_IN_CONTEXT_PLURAL("context_1", "sing", "plur", 1)); + macro_menu->Append(INTERNAT_MACRO_7, wxGETTEXT_IN_CONTEXT_PLURAL("context_1", "sing", "plur", 2)); + macro_menu->Append(INTERNAT_MACRO_8, wxGETTEXT_IN_CONTEXT_PLURAL("context_2", "sing", "plur", 1)); + macro_menu->Append(INTERNAT_MACRO_9, wxGETTEXT_IN_CONTEXT_PLURAL("context_2", "sing", "plur", 2)); wxMenuBar *menu_bar = new wxMenuBar; menu_bar->Append(file_menu, _("&File"));