From 9c6befef3ab95ce6c250a33dced0e3a32300f23d Mon Sep 17 00:00:00 2001 From: RickS Date: Tue, 20 Sep 2016 20:03:21 +0200 Subject: [PATCH 1/3] 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 { From 205841d6c46cf0e5abce71a6e1e7b7ad7f3f088a Mon Sep 17 00:00:00 2001 From: RickS Date: Tue, 20 Sep 2016 20:03:50 +0200 Subject: [PATCH 2/3] Test sample for context-sensitive translations --- samples/internat/fr/internat.mo | Bin 1368 -> 1708 bytes samples/internat/fr/internat.po | 42 ++++++++++++++++++++++++++++---- samples/internat/internat.cpp | 23 ++++++++++++++++- 3 files changed, 59 insertions(+), 6 deletions(-) diff --git a/samples/internat/fr/internat.mo b/samples/internat/fr/internat.mo index ec2d79a202471ce923e6a5e07da75b42f95b57db..8c3117507012d35a911899a2f0a2c878afb22c36 100644 GIT binary patch delta 777 zcmYL`&ubGw6vtVl;_fx}fGu2m$I6=;n zpU4Gr;IR-t;C}cM?t_2fQTPu|!s&^TKM#+f&pRYgi--U-@4xcd8pwxdT9>n*US{nOM`Yb@X$Rf)u z{nauXjj;|J@HUh`?!YN`YBG+=(Etk4M<5nhKJ#x)Gtc?vea)%{T6!k zcOf^Cz;m~eiFpY3q(B`b;xFNO?(#DOr{--Oc)i zTH0)PcAt3-Z{uE;7N*)RlCBzUd+oHP9(DS;({`_9t9vE)`?1{qIPq}KhNc#TYk>{5 zS&J^#FN8J>x0{unJ6jwUcY@6<@Ae{{%Gq(J*R%~i+BVOndR?3I4gXr4w)$}^32r2D zH_~Gr=?A%gGq{qZNgfwj9_g(tx!*3dS*fqA?tZB}^=dMbQ8JTp;~OQ8b&hq8bx!D< I&^e*{57oJLwEzGB delta 428 zcmXxgJx>Bb5P;!1?*K(k2?mM5Vhck7p|CLqsw0wUftT1}NoQq6f(ZmF{s0&YD5;1Y z6%~KMPHAjtX|*sW`p$7oGW+b_e$4H@x*zfGXUcgNB1xW-V=|+Ci-u@n6rV7HJ=C>* zOyEoSeS!y!r+AEWyui0`KDHy0V(j828qA7xrA|i+G*Jt;F^@w$Ve # -#: internat.cpp:146 -#, fuzzy msgid "" msgstr "" "Project-Id-Version: wxWindows 2.0 i18n sample\n" "POT-Creation-Date: 1999-01-13 18:19+0100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"PO-Revision-Date: 2016-09-20 19:38+0200\n" "Last-Translator: Vadim Zeitlin \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"Language-Team: \n" +"Language: fr\n" +"X-Generator: Poedit 1.8.7\n" + +msgid "item" +msgstr "item0" + +msgctxt "cont1" +msgid "item" +msgstr "item1" + +msgctxt "cont2" +msgid "item" +msgstr "item2" + +msgid "sing" +msgid_plural "plur" +msgstr[0] "sing0" +msgstr[1] "plur0" + +msgctxt "cont1" +msgid "sing" +msgid_plural "plur" +msgstr[0] "sing1" +msgstr[1] "plur1" + +msgctxt "cont2" +msgid "sing" +msgid_plural "plur" +msgstr[0] "sing2" +msgstr[1] "plur2" #: internat.cpp:98 msgid "International wxWindows App" @@ -43,9 +73,11 @@ msgid "&Test" msgstr "&Test" #: internat.cpp:138 -msgid "I18n sample\n" +msgid "" +"I18n sample\n" "© 1998, 1999 Vadim Zeitlin and Julian Smart" -msgstr "Exemple d'i18n\n" +msgstr "" +"Exemple d'i18n\n" "© 1998, 1999 Vadim Zeitlin et Julian Smart" #: internat.cpp:139 diff --git a/samples/internat/internat.cpp b/samples/internat/internat.cpp index 5f2646f9fe..f3f706d9c3 100644 --- a/samples/internat/internat.cpp +++ b/samples/internat/internat.cpp @@ -94,7 +94,16 @@ enum INTERNAT_TEST_1, INTERNAT_TEST_2, INTERNAT_TEST_3, - INTERNAT_TEST_MSGBOX + INTERNAT_TEST_MSGBOX, + INTERNAT_MACRO_1, + INTERNAT_MACRO_2, + INTERNAT_MACRO_3, + INTERNAT_MACRO_4, + INTERNAT_MACRO_5, + INTERNAT_MACRO_6, + INTERNAT_MACRO_7, + INTERNAT_MACRO_8, + INTERNAT_MACRO_9 }; // language data @@ -308,9 +317,21 @@ MyFrame::MyFrame(wxLocale& locale) test_menu->Append(INTERNAT_TEST_MSGBOX, _("&Message box test"), _("Tests message box buttons labels translation")); + 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_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)); + wxMenuBar *menu_bar = new wxMenuBar; menu_bar->Append(file_menu, _("&File")); menu_bar->Append(test_menu, _("&Test")); + menu_bar->Append(macro_menu, _("&Macro")); SetMenuBar(menu_bar); // this demonstrates RTL support in wxStatusBar: From 91385acd5d099b681552624891c08fe7eb2c3c07 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 29 Jul 2017 14:23:29 +0200 Subject: [PATCH 3/3] Rename context-specific translation macros and document them Try to use more clear names for the macros and also try to make the sample more self-explanatory. --- docs/changes.txt | 1 + include/wx/translation.h | 20 ++++++++++++----- interface/wx/translation.h | 38 ++++++++++++++++++++++++++++++-- samples/internat/fr/internat.mo | Bin 1708 -> 1889 bytes samples/internat/fr/internat.po | 26 +++++++++++----------- samples/internat/internat.cpp | 14 +++++++----- 6 files changed, 72 insertions(+), 27 deletions(-) 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 8c3117507012d35a911899a2f0a2c878afb22c36..f65c6b70033be0a727acbd21f044102334272392 100644 GIT binary patch delta 581 zcmZ|KJxjwt9LMp0Ok;Jh+SEEY-5>~pLsB2G?t+U5I*A}bS`EZRVuB(_(ZR_ZX~1&-nso?9X} zrmi|7BlOqN#c3SIdE}J^emb{}3O8^S6V&S-9qCGw#xosle8m}bNYNAKP+l?5jKp;{!R4^7Nd>rv^2Cy nToC;+P)_mxPw}OgvRl~NmqE;Fm>nj0_I;vKQhBr(Rv!BVgT;Ac delta 399 zcmYL_u}T9$6h-g28;KF4CdNV#0tO4KorNeUSV+DgeXtOffQhP z&Oh)o{0OnldBcFq-Z^vcdpo?@pX%qr)7xD|(oP~R!UJf&8+{L^_yL@Q1-y0AIQl<| zWpY=NYOn%l;X341i=_^?U=!}cJ$MN1yVsIV)L`>LunWIn3;xE2HBM{dH=u_dNJ%$v z9*(1bi2gD9m+0Ri^GeV6uHLp0XHeA=o@KO(>_i*WMzY_qf|d}slqTPf-FW2tNNWO)is0vTdDS*5pH%mnC^f@{r^q$wHEaB-0d_-8B#Z 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"));