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