added gettext plural forms support (patch #785660 with modifications)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@24085 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -69,6 +69,7 @@ All:
|
|||||||
- added wxTextInputStream::ReadChar() (M.J.Wetherell)
|
- added wxTextInputStream::ReadChar() (M.J.Wetherell)
|
||||||
- added translation to Afrikaans (Petri Jooste)
|
- added translation to Afrikaans (Petri Jooste)
|
||||||
- Spanish translations updated (Javier San Jose)
|
- Spanish translations updated (Javier San Jose)
|
||||||
|
- added gettext plural forms support to wxLocale (Michael N. Filippov)
|
||||||
|
|
||||||
All (GUI):
|
All (GUI):
|
||||||
|
|
||||||
|
@@ -2,7 +2,8 @@
|
|||||||
// Name: wx/intl.h
|
// Name: wx/intl.h
|
||||||
// Purpose: Internationalization and localisation for wxWindows
|
// Purpose: Internationalization and localisation for wxWindows
|
||||||
// Author: Vadim Zeitlin
|
// Author: Vadim Zeitlin
|
||||||
// Modified by:
|
// Modified by: Michael N. Filippov <michael@idisys.iae.nsk.su>
|
||||||
|
// (2003/09/30 - plural forms support)
|
||||||
// Created: 29/01/98
|
// Created: 29/01/98
|
||||||
// RCS-ID: $Id$
|
// RCS-ID: $Id$
|
||||||
// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
|
// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
|
||||||
@@ -31,10 +32,13 @@
|
|||||||
// macros
|
// macros
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// gettext() style macro (notice that xgettext should be invoked with "-k_"
|
// gettext() style macros (notice that xgettext should be invoked with
|
||||||
// option to extract the strings inside _() from the sources)
|
// --keyword="_" --keyword="_N:1,2" --keyword="N_" options
|
||||||
|
// to extract the strings from the sources)
|
||||||
#ifndef WXINTL_NO_GETTEXT_MACRO
|
#ifndef WXINTL_NO_GETTEXT_MACRO
|
||||||
#define _(str) wxGetTranslation(_T(str))
|
#define _(s) wxGetTranslation(_T(s))
|
||||||
|
#define _N(s1, s2, n) wxGetTranslation(_T(s1), _T(s2), n)
|
||||||
|
#define N_(s) _T(s)
|
||||||
#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
|
||||||
@@ -474,6 +478,7 @@ public:
|
|||||||
// retrieve the translation for a string in all loaded domains unless
|
// retrieve the translation for a string in all loaded domains unless
|
||||||
// the szDomain parameter is specified (and then only this domain is
|
// the szDomain parameter is specified (and then only this domain is
|
||||||
// searched)
|
// searched)
|
||||||
|
// n - additional parameter for PluralFormsParser
|
||||||
//
|
//
|
||||||
// return original string if translation is not available
|
// return original string if translation is not available
|
||||||
// (in this case an error message is generated the first time
|
// (in this case an error message is generated the first time
|
||||||
@@ -483,6 +488,11 @@ public:
|
|||||||
// added later override those added before.
|
// added later override those added before.
|
||||||
const wxChar *GetString(const wxChar *szOrigString,
|
const wxChar *GetString(const wxChar *szOrigString,
|
||||||
const wxChar *szDomain = (const wxChar *) NULL) const;
|
const wxChar *szDomain = (const wxChar *) NULL) const;
|
||||||
|
// plural form version of the same:
|
||||||
|
const wxChar *GetString(const wxChar *szOrigString,
|
||||||
|
const wxChar *szOrigString2,
|
||||||
|
size_t n,
|
||||||
|
const wxChar *szDomain = (const wxChar *) NULL) const;
|
||||||
|
|
||||||
// Returns the current short name for the locale
|
// Returns the current short name for the locale
|
||||||
const wxString& GetName() const { return m_strShort; }
|
const wxString& GetName() const { return m_strShort; }
|
||||||
@@ -533,13 +543,24 @@ inline const wxChar *wxGetTranslation(const wxChar *sz)
|
|||||||
else
|
else
|
||||||
return sz;
|
return sz;
|
||||||
}
|
}
|
||||||
|
inline const wxChar *wxGetTranslation(const wxChar *sz1, const wxChar *sz2,
|
||||||
|
size_t n)
|
||||||
|
{
|
||||||
|
wxLocale *pLoc = wxGetLocale();
|
||||||
|
if (pLoc)
|
||||||
|
return pLoc->GetString(sz1, sz2, n);
|
||||||
|
else
|
||||||
|
return n == 1 ? sz1 : sz2;
|
||||||
|
}
|
||||||
|
|
||||||
#else // !wxUSE_INTL
|
#else // !wxUSE_INTL
|
||||||
|
|
||||||
// the macros should still be defined - otherwise compilation would fail
|
// the macros should still be defined - otherwise compilation would fail
|
||||||
|
|
||||||
#if !defined(WXINTL_NO_GETTEXT_MACRO) && !defined(_)
|
#if !defined(WXINTL_NO_GETTEXT_MACRO) && !defined(_)
|
||||||
#define _(str) (_T(str))
|
#define _(s) (_T(s))
|
||||||
|
#define _N(s1, s2, n) ((n) == 1 ? _T(s1) : _T(s2))
|
||||||
|
#define N_(s) _T(s)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define wxTRANSLATE(str) _T(str)
|
#define wxTRANSLATE(str) _T(str)
|
||||||
|
@@ -61,7 +61,10 @@ public:
|
|||||||
void OnAbout(wxCommandEvent& event);
|
void OnAbout(wxCommandEvent& event);
|
||||||
void OnPlay(wxCommandEvent& event);
|
void OnPlay(wxCommandEvent& event);
|
||||||
void OnOpen(wxCommandEvent& event);
|
void OnOpen(wxCommandEvent& event);
|
||||||
|
void OnTest1(wxCommandEvent& event);
|
||||||
|
void OnTest2(wxCommandEvent& event);
|
||||||
|
void OnTest3(wxCommandEvent& event);
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
|
|
||||||
wxLocale& m_locale;
|
wxLocale& m_locale;
|
||||||
@@ -77,6 +80,9 @@ enum
|
|||||||
INTERNAT_QUIT = 1,
|
INTERNAT_QUIT = 1,
|
||||||
INTERNAT_TEXT,
|
INTERNAT_TEXT,
|
||||||
INTERNAT_TEST,
|
INTERNAT_TEST,
|
||||||
|
INTERNAT_TEST_1,
|
||||||
|
INTERNAT_TEST_2,
|
||||||
|
INTERNAT_TEST_3,
|
||||||
INTERNAT_OPEN
|
INTERNAT_OPEN
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -89,6 +95,9 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
|||||||
EVT_MENU(wxID_ABOUT, MyFrame::OnAbout)
|
EVT_MENU(wxID_ABOUT, MyFrame::OnAbout)
|
||||||
EVT_MENU(INTERNAT_TEST, MyFrame::OnPlay)
|
EVT_MENU(INTERNAT_TEST, MyFrame::OnPlay)
|
||||||
EVT_MENU(INTERNAT_OPEN, MyFrame::OnOpen)
|
EVT_MENU(INTERNAT_OPEN, MyFrame::OnOpen)
|
||||||
|
EVT_MENU(INTERNAT_TEST_1, MyFrame::OnTest1)
|
||||||
|
EVT_MENU(INTERNAT_TEST_2, MyFrame::OnTest2)
|
||||||
|
EVT_MENU(INTERNAT_TEST_3, MyFrame::OnTest3)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
IMPLEMENT_APP(MyApp)
|
IMPLEMENT_APP(MyApp)
|
||||||
@@ -120,6 +129,7 @@ bool MyApp::OnInit()
|
|||||||
wxLANGUAGE_GERMAN,
|
wxLANGUAGE_GERMAN,
|
||||||
wxLANGUAGE_RUSSIAN,
|
wxLANGUAGE_RUSSIAN,
|
||||||
wxLANGUAGE_BULGARIAN,
|
wxLANGUAGE_BULGARIAN,
|
||||||
|
wxLANGUAGE_CZECH,
|
||||||
#if wxUSE_UNICODE
|
#if wxUSE_UNICODE
|
||||||
wxLANGUAGE_JAPANESE,
|
wxLANGUAGE_JAPANESE,
|
||||||
wxLANGUAGE_GEORGIAN,
|
wxLANGUAGE_GEORGIAN,
|
||||||
@@ -139,6 +149,7 @@ bool MyApp::OnInit()
|
|||||||
_T("German"),
|
_T("German"),
|
||||||
_T("Russian"),
|
_T("Russian"),
|
||||||
_T("Bulgarian"),
|
_T("Bulgarian"),
|
||||||
|
_T("Czech"),
|
||||||
#if wxUSE_UNICODE
|
#if wxUSE_UNICODE
|
||||||
_T("Japanese"),
|
_T("Japanese"),
|
||||||
_T("Georgian"),
|
_T("Georgian"),
|
||||||
@@ -193,6 +204,10 @@ bool MyApp::OnInit()
|
|||||||
wxMenu *test_menu = new wxMenu;
|
wxMenu *test_menu = new wxMenu;
|
||||||
test_menu->Append(INTERNAT_OPEN, _("&Open bogus file"));
|
test_menu->Append(INTERNAT_OPEN, _("&Open bogus file"));
|
||||||
test_menu->Append(INTERNAT_TEST, _("&Play a game"));
|
test_menu->Append(INTERNAT_TEST, _("&Play a game"));
|
||||||
|
test_menu->AppendSeparator();
|
||||||
|
test_menu->Append(INTERNAT_TEST_1, _("&1 _() (gettext)"));
|
||||||
|
test_menu->Append(INTERNAT_TEST_2, _("&2 _N() (ngettext)"));
|
||||||
|
test_menu->Append(INTERNAT_TEST_3, _("&3 N_() (gettext_noop)"));
|
||||||
|
|
||||||
wxMenuBar *menu_bar = new wxMenuBar;
|
wxMenuBar *menu_bar = new wxMenuBar;
|
||||||
menu_bar->Append(file_menu, _("&File"));
|
menu_bar->Append(file_menu, _("&File"));
|
||||||
@@ -298,8 +313,63 @@ void MyFrame::OnPlay(wxCommandEvent& WXUNUSED(event))
|
|||||||
|
|
||||||
void MyFrame::OnOpen(wxCommandEvent&)
|
void MyFrame::OnOpen(wxCommandEvent&)
|
||||||
{
|
{
|
||||||
// open a bogus file -- the error message should be also translated if you've
|
// open a bogus file -- the error message should be also translated if
|
||||||
// got wxstd.mo somewhere in the search path
|
// you've got wxstd.mo somewhere in the search path
|
||||||
wxFile file(wxT("NOTEXIST.ING"));
|
wxFile file(wxT("NOTEXIST.ING"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MyFrame::OnTest1(wxCommandEvent& WXUNUSED(event))
|
||||||
|
{
|
||||||
|
const wxChar* title = _("Testing _() (gettext)");
|
||||||
|
wxTextEntryDialog d(this, _("Please enter text to translate"),
|
||||||
|
title, N_("default value"));
|
||||||
|
if (d.ShowModal() == wxID_OK)
|
||||||
|
{
|
||||||
|
wxString v = d.GetValue();
|
||||||
|
wxString s(title);
|
||||||
|
s << _T("\n") << v << _T(" -> ")
|
||||||
|
<< wxGetTranslation(v.c_str()) << _T("\n");
|
||||||
|
wxMessageBox(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyFrame::OnTest2(wxCommandEvent& WXUNUSED(event))
|
||||||
|
{
|
||||||
|
const wxChar* title = _("Testing _N() (ngettext)");
|
||||||
|
wxTextEntryDialog d(this,
|
||||||
|
_("Please enter range for plural forms of \"n files deleted\""
|
||||||
|
"phrase"),
|
||||||
|
title, _T("0-10"));
|
||||||
|
if (d.ShowModal() == wxID_OK)
|
||||||
|
{
|
||||||
|
int first, last;
|
||||||
|
wxSscanf(d.GetValue(), _T("%d-%d"), &first, &last);
|
||||||
|
wxString s(title);
|
||||||
|
s << _T("\n");
|
||||||
|
for (int n = first; n <= last; ++n)
|
||||||
|
{
|
||||||
|
s << n << _T(" ") << _N("file deleted", "files deleted", n)
|
||||||
|
<< _T("\n");
|
||||||
|
}
|
||||||
|
wxMessageBox(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyFrame::OnTest3(wxCommandEvent& WXUNUSED(event))
|
||||||
|
{
|
||||||
|
const wxChar* lines[] =
|
||||||
|
{
|
||||||
|
N_("line 1"),
|
||||||
|
N_("line 2"),
|
||||||
|
N_("line 3"),
|
||||||
|
};
|
||||||
|
wxString s(_("Testing N_() (gettext_noop)"));
|
||||||
|
s << _T("\n");
|
||||||
|
for (size_t i = 0; i < WXSIZEOF(lines); ++i)
|
||||||
|
{
|
||||||
|
s << lines[i] << _T(" -> ") << wxGetTranslation(lines[i]) << _T("\n");
|
||||||
|
}
|
||||||
|
wxMessageBox(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Binary file not shown.
@@ -11,6 +11,8 @@ msgstr ""
|
|||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=koi8-r\n"
|
"Content-Type: text/plain; charset=koi8-r\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%"
|
||||||
|
"10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||||
|
|
||||||
#: /home/harms.user1/rolinsky/wxGTK-2.2.0/samples/internat/internat.cpp:128
|
#: /home/harms.user1/rolinsky/wxGTK-2.2.0/samples/internat/internat.cpp:128
|
||||||
msgid "International wxWindows App"
|
msgid "International wxWindows App"
|
||||||
@@ -80,3 +82,57 @@ msgstr "
|
|||||||
msgid "Bad luck! try again..."
|
msgid "Bad luck! try again..."
|
||||||
msgstr "<22><> <20><><EFBFBD><EFBFBD><EFBFBD>! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>..."
|
msgstr "<22><> <20><><EFBFBD><EFBFBD><EFBFBD>! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>..."
|
||||||
|
|
||||||
|
#: i18n.cpp:163
|
||||||
|
msgid "file deleted"
|
||||||
|
msgid_plural "files deleted"
|
||||||
|
msgstr[0] "<22><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
|
||||||
|
msgstr[1] "<22><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
|
||||||
|
msgstr[2] "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
|
||||||
|
|
||||||
|
#: i18n.cpp:174
|
||||||
|
msgid "line 1"
|
||||||
|
msgstr "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1"
|
||||||
|
|
||||||
|
#: i18n.cpp:175
|
||||||
|
msgid "line 2"
|
||||||
|
msgstr "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 2"
|
||||||
|
|
||||||
|
#: i18n.cpp:176
|
||||||
|
msgid "line 3"
|
||||||
|
msgstr "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 3"
|
||||||
|
|
||||||
|
#: i18n.cpp:178
|
||||||
|
msgid "Testing N_() (gettext_noop)"
|
||||||
|
msgstr "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> N_() (gettext_noop)"
|
||||||
|
|
||||||
|
#: i18n.cpp:139
|
||||||
|
msgid "Testing _() (gettext)"
|
||||||
|
msgstr "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> _() (gettext)"
|
||||||
|
|
||||||
|
#: i18n.cpp:140
|
||||||
|
msgid "Please enter text to translate"
|
||||||
|
msgstr "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
|
||||||
|
|
||||||
|
#: i18n.cpp:141
|
||||||
|
msgid "default value"
|
||||||
|
msgstr "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
|
||||||
|
|
||||||
|
#: i18n.cpp:153
|
||||||
|
msgid "Testing _N() (ngettext)"
|
||||||
|
msgstr "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> _N() (ngettext)"
|
||||||
|
|
||||||
|
#: i18n.cpp:155
|
||||||
|
msgid "Please enter range for plural forms of \"n files deleted\" phrase"
|
||||||
|
msgstr "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> \"n <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\""
|
||||||
|
|
||||||
|
#: i18n.cpp:102
|
||||||
|
msgid "&1 _() (gettext)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: i18n.cpp:103
|
||||||
|
msgid "&2 _N() (ngettext)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: i18n.cpp:104
|
||||||
|
msgid "&3 N_() (gettext_noop)"
|
||||||
|
msgstr ""
|
||||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user