From 13068d36032fea5028169e523b2eae7eb60006cb Mon Sep 17 00:00:00 2001 From: David Hart Date: Fri, 24 Jun 2016 23:34:58 +0200 Subject: [PATCH 1/2] Strip mnemonics from CJK translations of menu items too Chinese, Japanese etc translations use a special style for the menu mnemonics and append them to the translated menu label in brackets, e.g. the menu label could have the form of " (&F)". Check for this style of mnemonics in wxStripMenuCodes() too and strip them as well. --- src/common/utilscmn.cpp | 23 ++++++++++++++++++++++ tests/Makefile.in | 16 +++++++++++++-- tests/intl/ja/internat.mo | Bin 0 -> 731 bytes tests/intl/ja/internat.po | 40 ++++++++++++++++++++++++++++++++++++++ tests/makefile.bcc | 6 +++++- tests/makefile.gcc | 8 ++++++-- tests/makefile.vc | 6 +++++- tests/menu/menu.cpp | 32 ++++++++++++++++++++++++++++++ tests/test.bkl | 1 + 9 files changed, 126 insertions(+), 6 deletions(-) create mode 100644 tests/intl/ja/internat.mo create mode 100644 tests/intl/ja/internat.po diff --git a/src/common/utilscmn.cpp b/src/common/utilscmn.cpp index 7394fe3c85..4d612202c8 100644 --- a/src/common/utilscmn.cpp +++ b/src/common/utilscmn.cpp @@ -1155,6 +1155,29 @@ wxString wxStripMenuCodes(const wxString& in, int flags) size_t len = in.length(); out.reserve(len); + // In some East Asian languages _("&File") translates as "(&F)" + // Check for this first, otherwise fall through to the standard situation + if (flags & wxStrip_Mnemonics) + { + wxString label(in), accel; + int pos = in.Find('\t'); + if (pos != wxNOT_FOUND) + { + label = in.Left(pos+1).Trim(); + if (!(flags & wxStrip_Accel)) + { + accel = in.Mid(pos); + } + } + + // The initial '?' means we match "Foo(&F)" but not "(&F)" + if (label.Matches("?*(&?)") > 0) + { + label = label.Left( label.Len()-4 ).Trim(); + return label + accel; + } + } + for ( wxString::const_iterator it = in.begin(); it != in.end(); ++it ) { wxChar ch = *it; diff --git a/tests/Makefile.in b/tests/Makefile.in index d0af8d4e79..c389570dda 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -391,7 +391,7 @@ COND_wxUSE_REGEX_builtin___LIB_REGEX_p = \ ### Targets: ### -all: test$(EXEEXT) $(__test_drawing___depname) $(__test_drawingplugin___depname) $(__test_gui___depname) $(__test_gui_bundle___depname) data data-images fr +all: test$(EXEEXT) $(__test_drawing___depname) $(__test_drawingplugin___depname) $(__test_gui___depname) $(__test_gui_bundle___depname) data data-images fr ja install: @@ -496,6 +496,18 @@ fr: esac; \ done +ja: + @mkdir -p ./intl/ja + @for f in internat.po internat.mo; do \ + if test ! -f ./intl/ja/$$f -a ! -d ./intl/ja/$$f ; \ + then x=yep ; \ + else x=`find $(srcdir)/intl/ja/$$f -newer ./intl/ja/$$f -print` ; \ + fi; \ + case "$$x" in ?*) \ + cp -pRf $(srcdir)/intl/ja/$$f ./intl/ja ;; \ + esac; \ + done + test_test.o: $(srcdir)/test.cpp $(TEST_ODEP) $(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/test.cpp @@ -1075,4 +1087,4 @@ failtest_weakref: # Include dependency info, if present: @IF_GNU_MAKE@-include ./.deps/*.d -.PHONY: all install uninstall clean distclean test_gui_bundle data data-images fr +.PHONY: all install uninstall clean distclean test_gui_bundle data data-images fr ja diff --git a/tests/intl/ja/internat.mo b/tests/intl/ja/internat.mo new file mode 100644 index 0000000000000000000000000000000000000000..341bd595e2d75cf7ba32a5015621f5e8b8beade7 GIT binary patch literal 731 zcmYL`zi-n(6vq!JKWc%1vUWI@lcVTjn=&Lu3?*@uL3@nMn z!dyUNKuCyIzyw1jHvR`@1oBWiu(BcXu5r~Tee}Ke?)|uD|5#btL14?kD&PT^fKPz3 zpTJq*SD^=>7l1#&Ip8mF5%>oz0otjBe;HKytDtS*I&cO2;Pj&ZQ_ySRKL=I)-hf^O z-2+v9zk;rSek=U%pwQyT)O(Ii)hdJQqaDtJo&nTs)d!Ic5pYDBJcto-V=1CAMR!Q# zPg3L%PsruEOoFn595|!C;3Qi_`pU^rH;K0SK+={+`#edZ+{W2-ON3sOrT9k0#KNkE zIA!BF;9A%1(R#v}8bcdQavNKRbGU%-9nPngeXkF&9j+bm`wPdU~{ zQpUDnWLZ{`s$2~Dv@(dsM!Z-kHDcpt7m|&jXklzKqoj3O9p_|It72;PD3m;eS3HSf z9m%KChyy0VTX-;HNy_Ezi5$}ENuC-vKcDaB^DjDaOYrqM%qAW>*xx&R{Y)o~(((UVM9|@j&%fXA NVx4RiH~k`n{sT(|#5({0 literal 0 HcmV?d00001 diff --git a/tests/intl/ja/internat.po b/tests/intl/ja/internat.po new file mode 100644 index 0000000000..fd62c4e497 --- /dev/null +++ b/tests/intl/ja/internat.po @@ -0,0 +1,40 @@ +# Message catalog file template for the wxWindows i18n sample +# Copyright (C) 1999 wxWindows development team +# Vadim Zeitlin +# +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" +"Last-Translator: Tadashi Jokagi\n" +"Language-Team: Japanese (http://www.transifex.com/projects/p/4Pane/language/ja/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "&File" +msgstr "ファイル(&F)" + +msgid "E&dit\tCtrl+E" +msgstr "編集(&D)\tCtrl+E" + +msgid "Vie&w\tCtrl+V" +msgstr "閲覧 (&W)\tCtrl+V" + +msgid "&Options" +msgstr "オプション(&O)" + +msgid "&Help" +msgstr "ヘルプ(&H)" + +# Supply a non-mnemonic, non-shortcut translation for easier comparison +msgid "Edit" +msgstr "編集" + +msgid "View" +msgstr "閲覧" + +# Nothing to do with Japanese; here to test a translation with a 'normal' mnenomic +msgid "B&ogus" +msgstr "Preten&d" diff --git a/tests/makefile.bcc b/tests/makefile.bcc index 18075e7ae0..0c131e6393 100644 --- a/tests/makefile.bcc +++ b/tests/makefile.bcc @@ -462,7 +462,7 @@ $(OBJS): ### Targets: ### -all: $(OBJS)\test.exe $(__test_drawing___depname) $(__test_drawingplugin___depname) $(__test_gui___depname) data data-images fr +all: $(OBJS)\test.exe $(__test_drawing___depname) $(__test_drawingplugin___depname) $(__test_gui___depname) data data-images fr ja clean: -if exist $(OBJS)\*.obj del $(OBJS)\*.obj @@ -531,6 +531,10 @@ fr: if not exist $(OBJS)\intl\fr mkdir $(OBJS)\intl\fr for %f in (internat.po internat.mo) do if not exist $(OBJS)\intl\fr\%f copy .\intl\fr\%f $(OBJS)\intl\fr +ja: + if not exist $(OBJS)\intl\ja mkdir $(OBJS)\intl\ja + for %f in (internat.po internat.mo) do if not exist $(OBJS)\intl\ja\%f copy .\intl\ja\%f $(OBJS)\intl\ja + $(OBJS)\test_dummy.obj: .\dummy.cpp $(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) -H .\dummy.cpp diff --git a/tests/makefile.gcc b/tests/makefile.gcc index 81be8d735c..c390f2567d 100644 --- a/tests/makefile.gcc +++ b/tests/makefile.gcc @@ -465,7 +465,7 @@ $(OBJS): ### Targets: ### -all: $(OBJS)\test.exe $(__test_drawing___depname) $(__test_drawingplugin___depname) $(__test_gui___depname) data data-images fr +all: $(OBJS)\test.exe $(__test_drawing___depname) $(__test_drawingplugin___depname) $(__test_gui___depname) data data-images fr ja clean: -if exist $(OBJS)\*.o del $(OBJS)\*.o @@ -507,6 +507,10 @@ fr: if not exist $(OBJS)\intl\fr mkdir $(OBJS)\intl\fr for %%f in (internat.po internat.mo) do if not exist $(OBJS)\intl\fr\%%f copy .\intl\fr\%%f $(OBJS)\intl\fr +ja: + if not exist $(OBJS)\intl\ja mkdir $(OBJS)\intl\ja + for %%f in (internat.po internat.mo) do if not exist $(OBJS)\intl\ja\%%f copy .\intl\ja\%%f $(OBJS)\intl\ja + $(OBJS)\test_dummy.o: ./dummy.cpp $(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $< @@ -1056,7 +1060,7 @@ $(OBJS)\test_gui_setsize.o: ./window/setsize.cpp $(OBJS)\test_gui_xrctest.o: ./xml/xrctest.cpp $(CXX) -c -o $@ $(TEST_GUI_CXXFLAGS) $(CPPDEPS) $< -.PHONY: all clean data data-images fr +.PHONY: all clean data data-images fr ja SHELL := $(COMSPEC) diff --git a/tests/makefile.vc b/tests/makefile.vc index be038677e2..075f84b817 100644 --- a/tests/makefile.vc +++ b/tests/makefile.vc @@ -651,7 +651,7 @@ $(OBJS): ### Targets: ### -all: $(OBJS)\test.exe $(__test_drawing___depname) $(__test_drawingplugin___depname) $(__test_gui___depname) data data-images fr +all: $(OBJS)\test.exe $(__test_drawing___depname) $(__test_drawingplugin___depname) $(__test_gui___depname) data data-images fr ja clean: -if exist $(OBJS)\*.obj del $(OBJS)\*.obj @@ -708,6 +708,10 @@ fr: if not exist $(OBJS)\intl\fr mkdir $(OBJS)\intl\fr for %f in (internat.po internat.mo) do if not exist $(OBJS)\intl\fr\%f copy .\intl\fr\%f $(OBJS)\intl\fr +ja: + if not exist $(OBJS)\intl\ja mkdir $(OBJS)\intl\ja + for %f in (internat.po internat.mo) do if not exist $(OBJS)\intl\ja\%f copy .\intl\ja\%f $(OBJS)\intl\ja + $(OBJS)\test_dummy.obj: .\dummy.cpp $(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) /Yctestprec.h .\dummy.cpp diff --git a/tests/menu/menu.cpp b/tests/menu/menu.cpp index 454baac66c..0c53934587 100644 --- a/tests/menu/menu.cpp +++ b/tests/menu/menu.cpp @@ -86,6 +86,7 @@ private: CPPUNIT_TEST( EnableTop ); CPPUNIT_TEST( Count ); CPPUNIT_TEST( Labels ); + CPPUNIT_TEST( i18n ); CPPUNIT_TEST( RadioItems ); CPPUNIT_TEST( RemoveAdd ); CPPUNIT_TEST( ChangeBitmap ); @@ -99,6 +100,7 @@ private: void EnableTop(); void Count(); void Labels(); + void i18n(); void RadioItems(); void RemoveAdd(); void ChangeBitmap(); @@ -334,6 +336,36 @@ void MenuTestCase::Labels() CPPUNIT_ASSERT_EQUAL( "Foo", wxMenuItem::GetLabelText("&Foo\tCtrl-F") ); } +void MenuTestCase::i18n() +{ + // Check that appended mnemonics are correctly stripped; + // see http://trac.wxwidgets.org/ticket/16736 + wxLocale::AddCatalogLookupPathPrefix("./intl"); + CPPUNIT_ASSERT( wxLocale::IsAvailable(wxLANGUAGE_JAPANESE) ); + + wxLocale locale(wxLANGUAGE_JAPANESE, wxLOCALE_DONT_LOAD_DEFAULT); + locale.AddCatalog("internat"); + + // Check the translation is being used: + CPPUNIT_ASSERT( wxString("&File") != wxString(_("&File")) ); + + wxString filemenu = m_frame->GetMenuBar()->GetMenuLabel(0); + CPPUNIT_ASSERT_EQUAL + ( wxStripMenuCodes(_("&File")), + wxStripMenuCodes(wxGetTranslation(filemenu)) + ); + + // Test strings that have shortcuts. Duplicate non-mnemonic translations + // exist for both "Edit" and "View", for ease of comparison + CPPUNIT_ASSERT_EQUAL( _("Edit"), wxStripMenuCodes(_("E&dit\tCtrl+E")) ); + + //"Vie&w" also has a space before the (&W) + CPPUNIT_ASSERT_EQUAL( _("View"), wxStripMenuCodes(_("Vie&w\tCtrl+V")) ); + + // Test a 'normal' mnemonic too: the translation is "Preten&d" + CPPUNIT_ASSERT_EQUAL( "Pretend", wxStripMenuCodes(_("B&ogus")) ); +} + void MenuTestCase::RadioItems() { wxMenuBar * const bar = m_frame->GetMenuBar(); diff --git a/tests/test.bkl b/tests/test.bkl index 3a12c9aa32..10595fd001 100644 --- a/tests/test.bkl +++ b/tests/test.bkl @@ -328,6 +328,7 @@ + From 68b2e06f70bc05921113cdb84d98ac8e866e4e1e Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 24 Jun 2016 23:56:49 +0200 Subject: [PATCH 2/2] Improve translated mnemonics unit test Don't switch locale to Japanese, which might not be supported, but just use wxTranslations directly because we only need translations, not full locale support. Also rename the test method to a more descriptive name. --- tests/menu/menu.cpp | 59 +++++++++++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 16 deletions(-) diff --git a/tests/menu/menu.cpp b/tests/menu/menu.cpp index 0c53934587..1a0e48b6f2 100644 --- a/tests/menu/menu.cpp +++ b/tests/menu/menu.cpp @@ -21,6 +21,7 @@ #endif // WX_PRECOMP #include "wx/menu.h" +#include "wx/translation.h" #include "wx/uiaction.h" #include @@ -86,7 +87,9 @@ private: CPPUNIT_TEST( EnableTop ); CPPUNIT_TEST( Count ); CPPUNIT_TEST( Labels ); - CPPUNIT_TEST( i18n ); +#if wxUSE_INTL + CPPUNIT_TEST( TranslatedMnemonics ); +#endif // wxUSE_INTL CPPUNIT_TEST( RadioItems ); CPPUNIT_TEST( RemoveAdd ); CPPUNIT_TEST( ChangeBitmap ); @@ -100,7 +103,9 @@ private: void EnableTop(); void Count(); void Labels(); - void i18n(); +#if wxUSE_INTL + void TranslatedMnemonics(); +#endif // wxUSE_INTL void RadioItems(); void RemoveAdd(); void ChangeBitmap(); @@ -336,35 +341,57 @@ void MenuTestCase::Labels() CPPUNIT_ASSERT_EQUAL( "Foo", wxMenuItem::GetLabelText("&Foo\tCtrl-F") ); } -void MenuTestCase::i18n() +#if wxUSE_INTL + +static wxString +GetTranslatedString(const wxTranslations& trans, const wxString& s) +{ + const wxString* t = trans.GetTranslatedString(s); + return t ? *t : s; +} + +void MenuTestCase::TranslatedMnemonics() { // Check that appended mnemonics are correctly stripped; // see http://trac.wxwidgets.org/ticket/16736 - wxLocale::AddCatalogLookupPathPrefix("./intl"); - CPPUNIT_ASSERT( wxLocale::IsAvailable(wxLANGUAGE_JAPANESE) ); - - wxLocale locale(wxLANGUAGE_JAPANESE, wxLOCALE_DONT_LOAD_DEFAULT); - locale.AddCatalog("internat"); + wxTranslations trans; + trans.SetLanguage(wxLANGUAGE_JAPANESE); + wxFileTranslationsLoader::AddCatalogLookupPathPrefix("./intl"); + CPPUNIT_ASSERT( trans.AddCatalog("internat") ); // Check the translation is being used: - CPPUNIT_ASSERT( wxString("&File") != wxString(_("&File")) ); + CPPUNIT_ASSERT( wxString("&File") != GetTranslatedString(trans, "&File") ); wxString filemenu = m_frame->GetMenuBar()->GetMenuLabel(0); CPPUNIT_ASSERT_EQUAL - ( wxStripMenuCodes(_("&File")), - wxStripMenuCodes(wxGetTranslation(filemenu)) - ); + ( + wxStripMenuCodes(GetTranslatedString(trans, "&File")), + wxStripMenuCodes(GetTranslatedString(trans, filemenu)) + ); // Test strings that have shortcuts. Duplicate non-mnemonic translations // exist for both "Edit" and "View", for ease of comparison - CPPUNIT_ASSERT_EQUAL( _("Edit"), wxStripMenuCodes(_("E&dit\tCtrl+E")) ); + CPPUNIT_ASSERT_EQUAL + ( + GetTranslatedString(trans, "Edit"), + wxStripMenuCodes(GetTranslatedString(trans, "E&dit\tCtrl+E")) + ); - //"Vie&w" also has a space before the (&W) - CPPUNIT_ASSERT_EQUAL( _("View"), wxStripMenuCodes(_("Vie&w\tCtrl+V")) ); + // "Vie&w" also has a space before the (&W) + CPPUNIT_ASSERT_EQUAL + ( + GetTranslatedString(trans, "View"), + wxStripMenuCodes(GetTranslatedString(trans, "Vie&w\tCtrl+V")) + ); // Test a 'normal' mnemonic too: the translation is "Preten&d" - CPPUNIT_ASSERT_EQUAL( "Pretend", wxStripMenuCodes(_("B&ogus")) ); + CPPUNIT_ASSERT_EQUAL + ( + "Pretend", + wxStripMenuCodes(GetTranslatedString(trans, "B&ogus")) + ); } +#endif // wxUSE_INTL void MenuTestCase::RadioItems() {