]> git.saurik.com Git - wxWidgets.git/blame_incremental - samples/internat/internat.cpp
add SetCharIncludes and SetCharExcludes utilities to wxTextValidator; use iterators...
[wxWidgets.git] / samples / internat / internat.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: internat.cpp
3// Purpose: Demonstrates internationalisation (i18n) support
4// Author: Vadim Zeitlin/Julian Smart
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
9// Licence: wxWindows license
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20// For compilers that support precompilation, includes "wx/wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24#pragma hdrstop
25#endif
26
27#ifndef WX_PRECOMP
28 #include "wx/wx.h"
29#endif
30
31#include "wx/intl.h"
32#include "wx/file.h"
33#include "wx/log.h"
34#include "wx/cmdline.h"
35
36#if defined(__WXGTK__) || defined(__WXX11__) || defined(__WXMOTIF__) || defined(__WXMAC__) || defined(__WXMGL__)
37#include "mondrian.xpm"
38#endif
39
40// ----------------------------------------------------------------------------
41// private classes
42// ----------------------------------------------------------------------------
43
44// Define a new application type
45class MyApp: public wxApp
46{
47public:
48 MyApp() { m_lang = wxLANGUAGE_UNKNOWN; }
49
50 virtual void OnInitCmdLine(wxCmdLineParser& parser);
51 virtual bool OnCmdLineParsed(wxCmdLineParser& parser);
52 virtual bool OnInit();
53
54protected:
55 wxLanguage m_lang; // language specified by user
56 wxLocale m_locale; // locale we'll be using
57};
58
59// Define a new frame type
60class MyFrame: public wxFrame
61{
62public:
63 MyFrame(wxLocale& m_locale);
64
65public:
66 void OnTestLocaleAvail(wxCommandEvent& event);
67 void OnAbout(wxCommandEvent& event);
68 void OnQuit(wxCommandEvent& event);
69
70 void OnPlay(wxCommandEvent& event);
71 void OnOpen(wxCommandEvent& event);
72 void OnTest1(wxCommandEvent& event);
73 void OnTest2(wxCommandEvent& event);
74 void OnTest3(wxCommandEvent& event);
75
76 DECLARE_EVENT_TABLE()
77
78 wxLocale& m_locale;
79};
80
81// ----------------------------------------------------------------------------
82// constants
83// ----------------------------------------------------------------------------
84
85// ID for the menu commands
86enum
87{
88 INTERNAT_TEST = wxID_HIGHEST + 1,
89 INTERNAT_PLAY,
90 INTERNAT_TEST_1,
91 INTERNAT_TEST_2,
92 INTERNAT_TEST_3
93};
94
95// language data
96static const wxLanguage langIds[] =
97{
98 wxLANGUAGE_DEFAULT,
99 wxLANGUAGE_FRENCH,
100 wxLANGUAGE_ITALIAN,
101 wxLANGUAGE_GERMAN,
102 wxLANGUAGE_RUSSIAN,
103 wxLANGUAGE_BULGARIAN,
104 wxLANGUAGE_CZECH,
105 wxLANGUAGE_POLISH,
106 wxLANGUAGE_SWEDISH,
107#if wxUSE_UNICODE || defined(__WXMOTIF__)
108 wxLANGUAGE_JAPANESE,
109#endif
110#if wxUSE_UNICODE
111 wxLANGUAGE_GEORGIAN,
112 wxLANGUAGE_ENGLISH,
113 wxLANGUAGE_ENGLISH_US,
114 wxLANGUAGE_ARABIC,
115 wxLANGUAGE_ARABIC_EGYPT
116#endif
117};
118
119// note that it makes no sense to translate these strings, they are
120// shown before we set the locale anyhow
121const wxString langNames[] =
122{
123 "System default",
124 "French",
125 "Italian",
126 "German",
127 "Russian",
128 "Bulgarian",
129 "Czech",
130 "Polish",
131 "Swedish",
132#if wxUSE_UNICODE || defined(__WXMOTIF__)
133 "Japanese",
134#endif
135#if wxUSE_UNICODE
136 "Georgian",
137 "English",
138 "English (U.S.)",
139 "Arabic",
140 "Arabic (Egypt)"
141#endif
142};
143
144// the arrays must be in sync
145wxCOMPILE_TIME_ASSERT( WXSIZEOF(langNames) == WXSIZEOF(langIds),
146 LangArraysMismatch );
147
148// ----------------------------------------------------------------------------
149// wxWidgets macros
150// ----------------------------------------------------------------------------
151
152BEGIN_EVENT_TABLE(MyFrame, wxFrame)
153 EVT_MENU(INTERNAT_TEST, MyFrame::OnTestLocaleAvail)
154 EVT_MENU(wxID_ABOUT, MyFrame::OnAbout)
155 EVT_MENU(wxID_EXIT, MyFrame::OnQuit)
156
157 EVT_MENU(INTERNAT_PLAY, MyFrame::OnPlay)
158 EVT_MENU(wxID_OPEN, MyFrame::OnOpen)
159 EVT_MENU(INTERNAT_TEST_1, MyFrame::OnTest1)
160 EVT_MENU(INTERNAT_TEST_2, MyFrame::OnTest2)
161 EVT_MENU(INTERNAT_TEST_3, MyFrame::OnTest3)
162END_EVENT_TABLE()
163
164IMPLEMENT_APP(MyApp)
165
166// ============================================================================
167// implementation
168// ============================================================================
169
170// ----------------------------------------------------------------------------
171// MyApp
172// ----------------------------------------------------------------------------
173
174// command line arguments handling
175void MyApp::OnInitCmdLine(wxCmdLineParser& parser)
176{
177 parser.AddParam(_("locale"),
178 wxCMD_LINE_VAL_STRING,
179 wxCMD_LINE_PARAM_OPTIONAL);
180
181 wxApp::OnInitCmdLine(parser);
182}
183
184bool MyApp::OnCmdLineParsed(wxCmdLineParser& parser)
185{
186 if ( !wxApp::OnCmdLineParsed(parser) )
187 return false;
188
189 if ( parser.GetParamCount() )
190 {
191 const wxString loc = parser.GetParam();
192 const wxLanguageInfo * const lang = wxLocale::FindLanguageInfo(loc);
193 if ( !lang )
194 {
195 wxLogError(_("Locale \"%s\" is unknown."), loc);
196 return false;
197 }
198
199 m_lang = static_cast<wxLanguage>(lang->Language);
200 }
201
202 return true;
203}
204
205// `Main program' equivalent, creating windows and returning main app frame
206bool MyApp::OnInit()
207{
208 if ( !wxApp::OnInit() )
209 return false;
210
211 if ( m_lang == wxLANGUAGE_UNKNOWN )
212 {
213 int lng = wxGetSingleChoiceIndex
214 (
215 _("Please choose language:"),
216 _("Language"),
217 WXSIZEOF(langNames),
218 langNames
219 );
220 m_lang = lng == -1 ? wxLANGUAGE_DEFAULT : langIds[lng];
221 }
222
223 // don't use wxLOCALE_LOAD_DEFAULT flag so that Init() doesn't return
224 // false just because it failed to load wxstd catalog
225 if ( !m_locale.Init(m_lang, wxLOCALE_CONV_ENCODING) )
226 {
227 wxLogWarning(_("This language is not supported by the system."));
228
229 // continue nevertheless
230 }
231
232 // normally this wouldn't be necessary as the catalog files would be found
233 // in the default locations, but when the program is not installed the
234 // catalogs are in the build directory where we wouldn't find them by
235 // default
236 wxLocale::AddCatalogLookupPathPrefix(".");
237
238 // Initialize the catalogs we'll be using
239 if (!m_locale.AddCatalog("internat"))
240 wxLogError(_("Couldn't find/load the 'internat' catalog."));
241
242 // Now try to add wxstd.mo so that loading "NOTEXIST.ING" file will produce
243 // a localized error message:
244 m_locale.AddCatalog("wxstd.mo");
245 // NOTE: it's not an error if we couldn't find it!
246
247 // this catalog is installed in standard location on Linux systems and
248 // shows that you may make use of the standard message catalogs as well
249 //
250 // if it's not installed on your system, it is just silently ignored
251#ifdef __LINUX__
252 {
253 wxLogNull noLog;
254 m_locale.AddCatalog("fileutils");
255 }
256#endif
257
258 // Create the main frame window
259 MyFrame *frame = new MyFrame(m_locale);
260
261 // Give it an icon
262 frame->SetIcon(wxICON(mondrian));
263
264 // Make a menubar
265 wxMenu *file_menu = new wxMenu;
266 file_menu->Append(INTERNAT_TEST, _("&Test locale availability...\tCtrl-T"));
267 file_menu->AppendSeparator();
268 file_menu->Append(wxID_ABOUT, _("&About..."));
269 file_menu->AppendSeparator();
270 file_menu->Append(wxID_EXIT, _("E&xit"));
271
272 wxMenu *test_menu = new wxMenu;
273 test_menu->Append(wxID_OPEN, _("&Open bogus file"));
274 test_menu->Append(INTERNAT_PLAY, _("&Play a game"));
275 test_menu->AppendSeparator();
276 test_menu->Append(INTERNAT_TEST_1, _("&1 _() (gettext)"));
277 test_menu->Append(INTERNAT_TEST_2, _("&2 _N() (ngettext)"));
278 test_menu->Append(INTERNAT_TEST_3, _("&3 wxTRANSLATE() (gettext_noop)"));
279
280 wxMenuBar *menu_bar = new wxMenuBar;
281 menu_bar->Append(file_menu, _("&File"));
282 menu_bar->Append(test_menu, _("&Test"));
283 frame->SetMenuBar(menu_bar);
284
285 // Show the frame
286 frame->Show(true);
287 SetTopWindow(frame);
288
289 return true;
290}
291
292// ----------------------------------------------------------------------------
293// MyFrame
294// ----------------------------------------------------------------------------
295
296// main frame constructor
297MyFrame::MyFrame(wxLocale& locale)
298 : wxFrame(NULL,
299 wxID_ANY,
300 _("International wxWidgets App")),
301 m_locale(locale)
302{
303 // this demonstrates RTL layout mirroring for Arabic locales
304 wxSizer *sizer = new wxBoxSizer(wxHORIZONTAL);
305 sizer->Add(new wxStaticText(this, wxID_ANY, _("First")),
306 wxSizerFlags().Border());
307 sizer->Add(new wxStaticText(this, wxID_ANY, _("Second")),
308 wxSizerFlags().Border());
309 SetSizer(sizer);
310}
311
312void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event) )
313{
314 Close(true);
315}
316
317void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
318{
319 wxString localeInfo;
320 wxString locale = m_locale.GetLocale();
321 wxString sysname = m_locale.GetSysName();
322 wxString canname = m_locale.GetCanonicalName();
323
324 localeInfo.Printf(_("Language: %s\nSystem locale name:\n%s\nCanonical locale name: %s\n"),
325 locale.c_str(), sysname.c_str(), canname.c_str() );
326
327 wxMessageDialog dlg(
328 this,
329 wxString(_("I18n sample\n(c) 1998, 1999 Vadim Zeitlin and Julian Smart"))
330 + "\n\n"
331 + localeInfo,
332 _("About Internat"),
333 wxOK | wxICON_INFORMATION
334 );
335 dlg.ShowModal();
336}
337
338void MyFrame::OnPlay(wxCommandEvent& WXUNUSED(event))
339{
340 wxString str = wxGetTextFromUser
341 (
342 _("Enter your number:"),
343 _("Try to guess my number!"),
344 wxEmptyString,
345 this
346 );
347
348 if ( str.empty() )
349 {
350 // cancelled
351 return;
352 }
353
354 long num;
355 if ( !str.ToLong(&num) || num < 0 )
356 {
357 str = _("You've probably entered an invalid number.");
358 }
359 else if ( num == 9 )
360 {
361 // this message is not translated (not in catalog) because we used _T()
362 // and not _() around it
363 str = _T("You've found a bug in this program!");
364 }
365 else if ( num == 17 )
366 {
367 str.clear();
368
369 // string must be split in two -- otherwise the translation would't be
370 // found
371 str << _("Congratulations! you've won. Here is the magic phrase:")
372 << _("cannot create fifo `%s'");
373 }
374 else
375 {
376 // this is a more implicit way to write _() but note that if you use it
377 // you must ensure that the strings get extracted in the message
378 // catalog as by default xgettext won't do it; it only knows of _(),
379 // not of wxTRANSLATE(). As internat's readme.txt says you should thus
380 // call xgettext with -kwxTRANSLATE.
381 str = wxGetTranslation(wxTRANSLATE("Bad luck! try again..."));
382
383 // note also that if we want 'str' to contain a localized string
384 // we need to use wxGetTranslation explicitely as wxTRANSLATE just
385 // tells xgettext to extract the string but has no effect on the
386 // runtime of the program!
387 }
388
389 wxMessageBox(str, _("Result"), wxOK | wxICON_INFORMATION);
390}
391
392void MyFrame::OnTestLocaleAvail(wxCommandEvent& WXUNUSED(event))
393{
394 static wxString s_locale;
395 wxString locale = wxGetTextFromUser
396 (
397 _("Enter the locale to test"),
398 wxGetTextFromUserPromptStr,
399 s_locale,
400 this
401 );
402 if ( locale.empty() )
403 return;
404
405 s_locale = locale;
406 const wxLanguageInfo * const info = wxLocale::FindLanguageInfo(s_locale);
407 if ( !info )
408 {
409 wxLogError(_("Locale \"%s\" is unknown."), s_locale.c_str());
410 return;
411 }
412
413 if ( wxLocale::IsAvailable(info->Language) )
414 wxLogMessage(_("Locale \"%s\" is available."), s_locale.c_str());
415 else
416 wxLogWarning(_("Locale \"%s\" is not available."), s_locale.c_str());
417}
418
419void MyFrame::OnOpen(wxCommandEvent& WXUNUSED(event))
420{
421 // open a bogus file -- the error message should be also translated if
422 // you've got wxstd.mo somewhere in the search path (see MyApp::OnInit)
423 wxFile file("NOTEXIST.ING");
424}
425
426void MyFrame::OnTest1(wxCommandEvent& WXUNUSED(event))
427{
428 const wxString& title = _("Testing _() (gettext)");
429
430 // NOTE: using the wxTRANSLATE() macro here we won't show a localized
431 // string in the text entry dialog; we'll simply show the un-translated
432 // string; however if the user press "ok" without altering the text,
433 // since the "default value" string has been extracted by xgettext
434 // the wxGetTranslation call later will manage to return a localized
435 // string
436 wxTextEntryDialog d(this, _("Please enter text to translate"),
437 title, wxTRANSLATE("default value"));
438
439 if (d.ShowModal() == wxID_OK)
440 {
441 wxString v = d.GetValue();
442 wxString s(title);
443 s << "\n" << v << " -> "
444 << wxGetTranslation(v.c_str()) << "\n";
445 wxMessageBox(s);
446 }
447}
448
449void MyFrame::OnTest2(wxCommandEvent& WXUNUSED(event))
450{
451 const wxString& title = _("Testing _N() (ngettext)");
452 wxTextEntryDialog d(this,
453 _("Please enter range for plural forms of \"n files deleted\" phrase"),
454 title, "0-10");
455
456 if (d.ShowModal() == wxID_OK)
457 {
458 int first, last;
459 wxSscanf(d.GetValue(), "%d-%d", &first, &last);
460 wxString s(title);
461 s << "\n";
462 for (int n = first; n <= last; ++n)
463 {
464 s << n << " " <<
465 wxPLURAL("file deleted", "files deleted", n) <<
466 "\n";
467 }
468 wxMessageBox(s);
469 }
470}
471
472void MyFrame::OnTest3(wxCommandEvent& WXUNUSED(event))
473{
474 const char* lines[] =
475 {
476 wxTRANSLATE("line 1"),
477 wxTRANSLATE("line 2"),
478 wxTRANSLATE("line 3"),
479 };
480
481 wxString s(_("Testing wxTRANSLATE() (gettext_noop)"));
482 s << "\n";
483 for (size_t i = 0; i < WXSIZEOF(lines); ++i)
484 {
485 s << lines[i] << " -> " << wxGetTranslation(lines[i]) << "\n";
486 }
487 wxMessageBox(s);
488}
489
490