don't use deprecated toolbar API
[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
7// RCS-ID: $Id$
6aa89a22 8// Copyright: (c) Julian Smart
c7f3b78b 9// Licence: wxWindows license
c801d85f
KB
10/////////////////////////////////////////////////////////////////////////////
11
017fcf32
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
c801d85f
KB
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
3a331275 28 #include "wx/wx.h"
c801d85f
KB
29#endif
30
31#include "wx/intl.h"
c7f3b78b 32#include "wx/file.h"
c801d85f 33#include "wx/log.h"
3a331275 34#include "wx/cmdline.h"
c801d85f 35
618f2efa 36#if defined(__WXGTK__) || defined(__WXX11__) || defined(__WXMOTIF__) || defined(__WXMAC__) || defined(__WXMGL__)
47908e25
RR
37#include "mondrian.xpm"
38#endif
39
017fcf32
VZ
40// ----------------------------------------------------------------------------
41// private classes
42// ----------------------------------------------------------------------------
43
c801d85f
KB
44// Define a new application type
45class MyApp: public wxApp
46{
47public:
3a331275
VZ
48 MyApp() { m_lang = wxLANGUAGE_UNKNOWN; }
49
50 virtual void OnInitCmdLine(wxCmdLineParser& parser);
51 virtual bool OnCmdLineParsed(wxCmdLineParser& parser);
aec18ff7 52 virtual bool OnInit();
c7f3b78b 53
c801d85f 54protected:
3a331275
VZ
55 wxLanguage m_lang; // language specified by user
56 wxLocale m_locale; // locale we'll be using
c801d85f
KB
57};
58
59// Define a new frame type
60class MyFrame: public wxFrame
aec18ff7 61{
c7f3b78b 62public:
017fcf32 63 MyFrame(wxLocale& m_locale);
c7f3b78b
VZ
64
65public:
cec5ffc4 66 void OnTestLocaleAvail(wxCommandEvent& event);
aec18ff7 67 void OnAbout(wxCommandEvent& event);
cec5ffc4
VZ
68 void OnQuit(wxCommandEvent& event);
69
aec18ff7
MB
70 void OnPlay(wxCommandEvent& event);
71 void OnOpen(wxCommandEvent& event);
849a28d0
VS
72 void OnTest1(wxCommandEvent& event);
73 void OnTest2(wxCommandEvent& event);
74 void OnTest3(wxCommandEvent& event);
f13880a9 75
aec18ff7
MB
76 DECLARE_EVENT_TABLE()
77
78 wxLocale& m_locale;
c801d85f
KB
79};
80
017fcf32
VZ
81// ----------------------------------------------------------------------------
82// constants
83// ----------------------------------------------------------------------------
84
c801d85f 85// ID for the menu commands
c7f3b78b
VZ
86enum
87{
cec5ffc4
VZ
88 INTERNAT_TEST = wxID_HIGHEST + 1,
89 INTERNAT_PLAY,
849a28d0
VS
90 INTERNAT_TEST_1,
91 INTERNAT_TEST_2,
6ea0cc70 92 INTERNAT_TEST_3
c7f3b78b 93};
c801d85f 94
79b4079f
VZ
95// language data
96static 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,
978af864
VZ
112 wxLANGUAGE_ENGLISH_US,
113 wxLANGUAGE_ARABIC,
114 wxLANGUAGE_ARABIC_EGYPT
79b4079f
VZ
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
120const 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"),
978af864
VZ
136 _T("English (U.S.)"),
137 _T("Arabic"),
138 _T("Arabic (Egypt)")
79b4079f
VZ
139#endif
140};
141
142// the arrays must be in sync
143wxCOMPILE_TIME_ASSERT( WXSIZEOF(langNames) == WXSIZEOF(langIds),
144 LangArraysMismatch );
145
017fcf32 146// ----------------------------------------------------------------------------
be5a51fb 147// wxWidgets macros
017fcf32
VZ
148// ----------------------------------------------------------------------------
149
c801d85f 150BEGIN_EVENT_TABLE(MyFrame, wxFrame)
cec5ffc4 151 EVT_MENU(INTERNAT_TEST, MyFrame::OnTestLocaleAvail)
aec18ff7 152 EVT_MENU(wxID_ABOUT, MyFrame::OnAbout)
cec5ffc4
VZ
153 EVT_MENU(wxID_EXIT, MyFrame::OnQuit)
154
155 EVT_MENU(INTERNAT_PLAY, MyFrame::OnPlay)
6ea0cc70 156 EVT_MENU(wxID_OPEN, MyFrame::OnOpen)
849a28d0
VS
157 EVT_MENU(INTERNAT_TEST_1, MyFrame::OnTest1)
158 EVT_MENU(INTERNAT_TEST_2, MyFrame::OnTest2)
159 EVT_MENU(INTERNAT_TEST_3, MyFrame::OnTest3)
c801d85f
KB
160END_EVENT_TABLE()
161
162IMPLEMENT_APP(MyApp)
163
017fcf32
VZ
164// ============================================================================
165// implementation
166// ============================================================================
167
168// ----------------------------------------------------------------------------
169// MyApp
170// ----------------------------------------------------------------------------
c801d85f 171
3a331275
VZ
172// command line arguments handling
173void MyApp::OnInitCmdLine(wxCmdLineParser& parser)
c801d85f 174{
3a331275
VZ
175 parser.AddParam(_("locale"),
176 wxCMD_LINE_VAL_STRING,
177 wxCMD_LINE_PARAM_OPTIONAL);
45e6e6f8 178
3a331275
VZ
179 wxApp::OnInitCmdLine(parser);
180}
017fcf32 181
3a331275
VZ
182bool MyApp::OnCmdLineParsed(wxCmdLineParser& parser)
183{
184 if ( !wxApp::OnCmdLineParsed(parser) )
185 return false;
186
187 if ( parser.GetParamCount() )
aec18ff7 188 {
3a331275
VZ
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);
017fcf32
VZ
198 }
199
3a331275
VZ
200 return true;
201}
202
203// `Main program' equivalent, creating windows and returning main app frame
204bool MyApp::OnInit()
205{
206 if ( !wxApp::OnInit() )
207 return false;
208
209 if ( m_lang == wxLANGUAGE_UNKNOWN )
017fcf32 210 {
3a331275
VZ
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];
017fcf32
VZ
219 }
220
3a331275 221 if ( m_lang != wxLANGUAGE_DEFAULT )
346f4231
VZ
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
3a331275 225 if ( !m_locale.Init(m_lang, wxLOCALE_CONV_ENCODING) )
346f4231 226 {
3a331275
VZ
227 wxLogWarning(_("This language is not supported by the system."));
228
229 // continue nevertheless
346f4231
VZ
230 }
231 }
aec18ff7 232
89611d4d
VZ
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("."));
017fcf32 238
aec18ff7 239 // Initialize the catalogs we'll be using
017fcf32
VZ
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
8e97b17b 246#ifdef __LINUX__
aec18ff7 247 {
017fcf32
VZ
248 wxLogNull noLog;
249 m_locale.AddCatalog(_T("fileutils"));
aec18ff7 250 }
8e97b17b 251#endif
aec18ff7
MB
252
253 // Create the main frame window
017fcf32 254 MyFrame *frame = new MyFrame(m_locale);
aec18ff7
MB
255
256 // Give it an icon
257 frame->SetIcon(wxICON(mondrian));
258
259 // Make a menubar
260 wxMenu *file_menu = new wxMenu;
cec5ffc4
VZ
261 file_menu->Append(INTERNAT_TEST, _("&Test locale availability...\tCtrl-T"));
262 file_menu->AppendSeparator();
aec18ff7
MB
263 file_menu->Append(wxID_ABOUT, _("&About..."));
264 file_menu->AppendSeparator();
f13880a9 265 file_menu->Append(wxID_EXIT, _("E&xit"));
aec18ff7
MB
266
267 wxMenu *test_menu = new wxMenu;
6ea0cc70 268 test_menu->Append(wxID_OPEN, _("&Open bogus file"));
cec5ffc4 269 test_menu->Append(INTERNAT_PLAY, _("&Play a game"));
849a28d0
VS
270 test_menu->AppendSeparator();
271 test_menu->Append(INTERNAT_TEST_1, _("&1 _() (gettext)"));
272 test_menu->Append(INTERNAT_TEST_2, _("&2 _N() (ngettext)"));
4c3590e4 273 test_menu->Append(INTERNAT_TEST_3, _("&3 wxTRANSLATE() (gettext_noop)"));
aec18ff7
MB
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
f13880a9 281 frame->Show(true);
aec18ff7
MB
282 SetTopWindow(frame);
283
f13880a9 284 return true;
c801d85f
KB
285}
286
017fcf32
VZ
287// ----------------------------------------------------------------------------
288// MyFrame
289// ----------------------------------------------------------------------------
290
291// main frame constructor
292MyFrame::MyFrame(wxLocale& locale)
293 : wxFrame(NULL,
f13880a9
WS
294 wxID_ANY,
295 _("International wxWidgets App")),
017fcf32 296 m_locale(locale)
c7f3b78b 297{
978af864
VZ
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);
c7f3b78b 305}
c801d85f 306
bd7d06f2 307void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event) )
c801d85f 308{
f13880a9 309 Close(true);
c801d85f
KB
310}
311
bd7d06f2 312void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
c801d85f 313{
aec18ff7 314 wxString localeInfo;
2b5f62a0
VZ
315 wxString locale = m_locale.GetLocale();
316 wxString sysname = m_locale.GetSysName();
317 wxString canname = m_locale.GetCanonicalName();
318
f13880a9 319 localeInfo.Printf(_("Language: %s\nSystem locale name:\n%s\nCanonical locale name: %s\n"),
2b5f62a0 320 locale.c_str(), sysname.c_str(), canname.c_str() );
aec18ff7 321
925e9792
WS
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();
c801d85f
KB
331}
332
bd7d06f2 333void MyFrame::OnPlay(wxCommandEvent& WXUNUSED(event))
c7f3b78b 334{
085c26ac
VZ
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 }
aec18ff7 348
085c26ac
VZ
349 long num;
350 if ( !str.ToLong(&num) || num < 0 )
351 {
aec18ff7 352 str = _("You've probably entered an invalid number.");
085c26ac
VZ
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
2b5f62a0 358 str = _T("You've found a bug in this program!");
085c26ac
VZ
359 }
360 else if ( num == 17 )
aec18ff7 361 {
085c26ac
VZ
362 str.clear();
363
364 // string must be split in two -- otherwise the translation would't be
365 // found
aec18ff7
MB
366 str << _("Congratulations! you've won. Here is the magic phrase:")
367 << _("cannot create fifo `%s'");
368 }
085c26ac
VZ
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 }
aec18ff7
MB
377
378 wxMessageBox(str, _("Result"), wxOK | wxICON_INFORMATION);
c7f3b78b
VZ
379}
380
cec5ffc4
VZ
381void 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
408void MyFrame::OnOpen(wxCommandEvent& WXUNUSED(event))
c7f3b78b 409{
849a28d0
VS
410 // open a bogus file -- the error message should be also translated if
411 // you've got wxstd.mo somewhere in the search path
aec18ff7 412 wxFile file(wxT("NOTEXIST.ING"));
071cc2be 413}
085c26ac 414
849a28d0
VS
415void MyFrame::OnTest1(wxCommandEvent& WXUNUSED(event))
416{
79478afa 417 const wxString title = _("Testing _() (gettext)");
849a28d0 418 wxTextEntryDialog d(this, _("Please enter text to translate"),
f13880a9 419 title, wxTRANSLATE("default value"));
849a28d0
VS
420 if (d.ShowModal() == wxID_OK)
421 {
f13880a9
WS
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);
849a28d0
VS
427 }
428}
429
430void MyFrame::OnTest2(wxCommandEvent& WXUNUSED(event))
431{
79478afa 432 const wxString title = _("Testing _N() (ngettext)");
849a28d0 433 wxTextEntryDialog d(this,
f13880a9
WS
434 _("Please enter range for plural forms of \"n files deleted\" phrase"),
435 title, _T("0-10"));
849a28d0
VS
436 if (d.ShowModal() == wxID_OK)
437 {
f13880a9
WS
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)
849a28d0 443 {
f13880a9 444 s << n << _T(" ") <<
15d06954 445 wxPLURAL("file deleted", "files deleted", n) <<
552973e0 446 _T("\n");
f13880a9 447 }
849a28d0
VS
448 wxMessageBox(s);
449 }
450}
451
452void MyFrame::OnTest3(wxCommandEvent& WXUNUSED(event))
453{
ad4814e7 454 const char* lines[] =
849a28d0 455 {
f13880a9
WS
456 wxTRANSLATE("line 1"),
457 wxTRANSLATE("line 2"),
458 wxTRANSLATE("line 3"),
849a28d0 459 };
4c3590e4 460 wxString s(_("Testing wxTRANSLATE() (gettext_noop)"));
849a28d0
VS
461 s << _T("\n");
462 for (size_t i = 0; i < WXSIZEOF(lines); ++i)
463 {
f13880a9 464 s << lines[i] << _T(" -> ") << wxGetTranslation(lines[i]) << _T("\n");
849a28d0
VS
465 }
466 wxMessageBox(s);
467}
468
469