]> git.saurik.com Git - wxWidgets.git/blob - samples/internat/internat.cpp
fix a macroscopic error which made Doxygen generate invalid XML
[wxWidgets.git] / samples / internat / internat.cpp
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
45 class MyApp: public wxApp
46 {
47 public:
48 MyApp() { m_lang = wxLANGUAGE_UNKNOWN; }
49
50 virtual void OnInitCmdLine(wxCmdLineParser& parser);
51 virtual bool OnCmdLineParsed(wxCmdLineParser& parser);
52 virtual bool OnInit();
53
54 protected:
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
60 class MyFrame: public wxFrame
61 {
62 public:
63 MyFrame(wxLocale& m_locale);
64
65 public:
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
86 enum
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
96 static const wxLanguage langIds[] =
97 {
98 wxLANGUAGE_DEFAULT,
99 wxLANGUAGE_FRENCH,
100 wxLANGUAGE_GERMAN,
101 wxLANGUAGE_RUSSIAN,
102 wxLANGUAGE_BULGARIAN,
103 wxLANGUAGE_CZECH,
104 wxLANGUAGE_POLISH,
105 wxLANGUAGE_SWEDISH,
106 #if wxUSE_UNICODE || defined(__WXMOTIF__)
107 wxLANGUAGE_JAPANESE,
108 #endif
109 #if wxUSE_UNICODE
110 wxLANGUAGE_GEORGIAN,
111 wxLANGUAGE_ENGLISH,
112 wxLANGUAGE_ENGLISH_US,
113 wxLANGUAGE_ARABIC,
114 wxLANGUAGE_ARABIC_EGYPT
115 #endif
116 };
117
118 // note that it makes no sense to translate these strings, they are
119 // shown before we set the locale anyhow
120 const wxString langNames[] =
121 {
122 _T("System default"),
123 _T("French"),
124 _T("German"),
125 _T("Russian"),
126 _T("Bulgarian"),
127 _T("Czech"),
128 _T("Polish"),
129 _T("Swedish"),
130 #if wxUSE_UNICODE || defined(__WXMOTIF__)
131 _T("Japanese"),
132 #endif
133 #if wxUSE_UNICODE
134 _T("Georgian"),
135 _T("English"),
136 _T("English (U.S.)"),
137 _T("Arabic"),
138 _T("Arabic (Egypt)")
139 #endif
140 };
141
142 // the arrays must be in sync
143 wxCOMPILE_TIME_ASSERT( WXSIZEOF(langNames) == WXSIZEOF(langIds),
144 LangArraysMismatch );
145
146 // ----------------------------------------------------------------------------
147 // wxWidgets macros
148 // ----------------------------------------------------------------------------
149
150 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
151 EVT_MENU(INTERNAT_TEST, MyFrame::OnTestLocaleAvail)
152 EVT_MENU(wxID_ABOUT, MyFrame::OnAbout)
153 EVT_MENU(wxID_EXIT, MyFrame::OnQuit)
154
155 EVT_MENU(INTERNAT_PLAY, MyFrame::OnPlay)
156 EVT_MENU(wxID_OPEN, MyFrame::OnOpen)
157 EVT_MENU(INTERNAT_TEST_1, MyFrame::OnTest1)
158 EVT_MENU(INTERNAT_TEST_2, MyFrame::OnTest2)
159 EVT_MENU(INTERNAT_TEST_3, MyFrame::OnTest3)
160 END_EVENT_TABLE()
161
162 IMPLEMENT_APP(MyApp)
163
164 // ============================================================================
165 // implementation
166 // ============================================================================
167
168 // ----------------------------------------------------------------------------
169 // MyApp
170 // ----------------------------------------------------------------------------
171
172 // command line arguments handling
173 void MyApp::OnInitCmdLine(wxCmdLineParser& parser)
174 {
175 parser.AddParam(_("locale"),
176 wxCMD_LINE_VAL_STRING,
177 wxCMD_LINE_PARAM_OPTIONAL);
178
179 wxApp::OnInitCmdLine(parser);
180 }
181
182 bool MyApp::OnCmdLineParsed(wxCmdLineParser& parser)
183 {
184 if ( !wxApp::OnCmdLineParsed(parser) )
185 return false;
186
187 if ( parser.GetParamCount() )
188 {
189 const wxString loc = parser.GetParam();
190 const wxLanguageInfo * const lang = wxLocale::FindLanguageInfo(loc);
191 if ( !lang )
192 {
193 wxLogError(_("Locale \"%s\" is unknown."), loc);
194 return false;
195 }
196
197 m_lang = wx_static_cast(wxLanguage, lang->Language);
198 }
199
200 return true;
201 }
202
203 // `Main program' equivalent, creating windows and returning main app frame
204 bool MyApp::OnInit()
205 {
206 if ( !wxApp::OnInit() )
207 return false;
208
209 if ( m_lang == wxLANGUAGE_UNKNOWN )
210 {
211 int lng = wxGetSingleChoiceIndex
212 (
213 _("Please choose language:"),
214 _("Language"),
215 WXSIZEOF(langNames),
216 langNames
217 );
218 m_lang = lng == -1 ? wxLANGUAGE_DEFAULT : langIds[lng];
219 }
220
221 if ( m_lang != wxLANGUAGE_DEFAULT )
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
233 // normally this wouldn't be necessary as the catalog files would be found
234 // in the default locations, but when the program is not installed the
235 // catalogs are in the build directory where we wouldn't find them by
236 // default
237 wxLocale::AddCatalogLookupPathPrefix(wxT("."));
238
239 // Initialize the catalogs we'll be using
240 m_locale.AddCatalog(wxT("internat"));
241
242 // this catalog is installed in standard location on Linux systems and
243 // shows that you may make use of the standard message catalogs as well
244 //
245 // if it's not installed on your system, it is just silently ignored
246 #ifdef __LINUX__
247 {
248 wxLogNull noLog;
249 m_locale.AddCatalog(_T("fileutils"));
250 }
251 #endif
252
253 // Create the main frame window
254 MyFrame *frame = new MyFrame(m_locale);
255
256 // Give it an icon
257 frame->SetIcon(wxICON(mondrian));
258
259 // Make a menubar
260 wxMenu *file_menu = new wxMenu;
261 file_menu->Append(INTERNAT_TEST, _("&Test locale availability...\tCtrl-T"));
262 file_menu->AppendSeparator();
263 file_menu->Append(wxID_ABOUT, _("&About..."));
264 file_menu->AppendSeparator();
265 file_menu->Append(wxID_EXIT, _("E&xit"));
266
267 wxMenu *test_menu = new wxMenu;
268 test_menu->Append(wxID_OPEN, _("&Open bogus file"));
269 test_menu->Append(INTERNAT_PLAY, _("&Play a game"));
270 test_menu->AppendSeparator();
271 test_menu->Append(INTERNAT_TEST_1, _("&1 _() (gettext)"));
272 test_menu->Append(INTERNAT_TEST_2, _("&2 _N() (ngettext)"));
273 test_menu->Append(INTERNAT_TEST_3, _("&3 wxTRANSLATE() (gettext_noop)"));
274
275 wxMenuBar *menu_bar = new wxMenuBar;
276 menu_bar->Append(file_menu, _("&File"));
277 menu_bar->Append(test_menu, _("&Test"));
278 frame->SetMenuBar(menu_bar);
279
280 // Show the frame
281 frame->Show(true);
282 SetTopWindow(frame);
283
284 return true;
285 }
286
287 // ----------------------------------------------------------------------------
288 // MyFrame
289 // ----------------------------------------------------------------------------
290
291 // main frame constructor
292 MyFrame::MyFrame(wxLocale& locale)
293 : wxFrame(NULL,
294 wxID_ANY,
295 _("International wxWidgets App")),
296 m_locale(locale)
297 {
298 // this demonstrates RTL layout mirroring for Arabic locales
299 wxSizer *sizer = new wxBoxSizer(wxHORIZONTAL);
300 sizer->Add(new wxStaticText(this, wxID_ANY, _("First")),
301 wxSizerFlags().Border());
302 sizer->Add(new wxStaticText(this, wxID_ANY, _("Second")),
303 wxSizerFlags().Border());
304 SetSizer(sizer);
305 }
306
307 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event) )
308 {
309 Close(true);
310 }
311
312 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
313 {
314 wxString localeInfo;
315 wxString locale = m_locale.GetLocale();
316 wxString sysname = m_locale.GetSysName();
317 wxString canname = m_locale.GetCanonicalName();
318
319 localeInfo.Printf(_("Language: %s\nSystem locale name:\n%s\nCanonical locale name: %s\n"),
320 locale.c_str(), sysname.c_str(), canname.c_str() );
321
322 wxMessageDialog dlg(
323 this,
324 wxString(_("I18n sample\n(c) 1998, 1999 Vadim Zeitlin and Julian Smart"))
325 + wxT("\n\n")
326 + localeInfo,
327 _("About Internat"),
328 wxOK | wxICON_INFORMATION
329 );
330 dlg.ShowModal();
331 }
332
333 void MyFrame::OnPlay(wxCommandEvent& WXUNUSED(event))
334 {
335 wxString str = wxGetTextFromUser
336 (
337 _("Enter your number:"),
338 _("Try to guess my number!"),
339 wxEmptyString,
340 this
341 );
342
343 if ( str.empty() )
344 {
345 // cancelled
346 return;
347 }
348
349 long num;
350 if ( !str.ToLong(&num) || num < 0 )
351 {
352 str = _("You've probably entered an invalid number.");
353 }
354 else if ( num == 9 )
355 {
356 // this message is not translated (not in catalog) because we used _T()
357 // and not _() around it
358 str = _T("You've found a bug in this program!");
359 }
360 else if ( num == 17 )
361 {
362 str.clear();
363
364 // string must be split in two -- otherwise the translation would't be
365 // found
366 str << _("Congratulations! you've won. Here is the magic phrase:")
367 << _("cannot create fifo `%s'");
368 }
369 else
370 {
371 // this is a more implicit way to write _() but note that if you use it
372 // you must ensure that the strings get extracted in the message
373 // catalog as by default xgettext won't do it (it only knows of _(),
374 // not wxGetTranslation())
375 str = wxGetTranslation(_T("Bad luck! try again..."));
376 }
377
378 wxMessageBox(str, _("Result"), wxOK | wxICON_INFORMATION);
379 }
380
381 void MyFrame::OnTestLocaleAvail(wxCommandEvent& WXUNUSED(event))
382 {
383 static wxString s_locale;
384 wxString locale = wxGetTextFromUser
385 (
386 _("Enter the locale to test"),
387 wxGetTextFromUserPromptStr,
388 s_locale,
389 this
390 );
391 if ( locale.empty() )
392 return;
393
394 s_locale = locale;
395 const wxLanguageInfo * const info = wxLocale::FindLanguageInfo(s_locale);
396 if ( !info )
397 {
398 wxLogError(_("Locale \"%s\" is unknown."), s_locale.c_str());
399 return;
400 }
401
402 if ( wxLocale::IsAvailable(info->Language) )
403 wxLogMessage(_("Locale \"%s\" is available."), s_locale.c_str());
404 else
405 wxLogWarning(_("Locale \"%s\" is not available."), s_locale.c_str());
406 }
407
408 void MyFrame::OnOpen(wxCommandEvent& WXUNUSED(event))
409 {
410 // open a bogus file -- the error message should be also translated if
411 // you've got wxstd.mo somewhere in the search path
412 wxFile file(wxT("NOTEXIST.ING"));
413 }
414
415 void MyFrame::OnTest1(wxCommandEvent& WXUNUSED(event))
416 {
417 const wxChar* title = _("Testing _() (gettext)");
418 wxTextEntryDialog d(this, _("Please enter text to translate"),
419 title, wxTRANSLATE("default value"));
420 if (d.ShowModal() == wxID_OK)
421 {
422 wxString v = d.GetValue();
423 wxString s(title);
424 s << _T("\n") << v << _T(" -> ")
425 << wxGetTranslation(v.c_str()) << _T("\n");
426 wxMessageBox(s);
427 }
428 }
429
430 void MyFrame::OnTest2(wxCommandEvent& WXUNUSED(event))
431 {
432 const wxChar* title = _("Testing _N() (ngettext)");
433 wxTextEntryDialog d(this,
434 _("Please enter range for plural forms of \"n files deleted\" phrase"),
435 title, _T("0-10"));
436 if (d.ShowModal() == wxID_OK)
437 {
438 int first, last;
439 wxSscanf(d.GetValue(), _T("%d-%d"), &first, &last);
440 wxString s(title);
441 s << _T("\n");
442 for (int n = first; n <= last; ++n)
443 {
444 s << n << _T(" ") <<
445 wxPLURAL("file deleted", "files deleted", n) <<
446 _T("\n");
447 }
448 wxMessageBox(s);
449 }
450 }
451
452 void MyFrame::OnTest3(wxCommandEvent& WXUNUSED(event))
453 {
454 const char* lines[] =
455 {
456 wxTRANSLATE("line 1"),
457 wxTRANSLATE("line 2"),
458 wxTRANSLATE("line 3"),
459 };
460 wxString s(_("Testing wxTRANSLATE() (gettext_noop)"));
461 s << _T("\n");
462 for (size_t i = 0; i < WXSIZEOF(lines); ++i)
463 {
464 s << lines[i] << _T(" -> ") << wxGetTranslation(lines[i]) << _T("\n");
465 }
466 wxMessageBox(s);
467 }
468
469