1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        translation.h
3 // Purpose:     wxTranslation class
4 // Author:      wxWidgets team
5 // Licence:     wxWindows licence
6 /////////////////////////////////////////////////////////////////////////////
7 
8 
9 /**
10     This class allows getting translations for strings.
11 
12     In wxWidgets this class manages message catalogs which contain the
13     translations of the strings used to the current language. Unlike wxLocale,
14     it isn't bound to locale. It can be used either independently of, or in
15     conjunction with wxLocale. In the latter case, you should initialize
16     wxLocale (which creates wxTranslations instance) first; in the former, you
17     need to create a wxTranslations object and Set() it manually.
18 
19     Only one wxTranslations instance is active at a time; it is set with the
20     Set() method and obtained using Get().
21 
22     Unlike wxLocale, wxTranslations' primary mean of identifying language
23     is by its "canonical name", i.e. ISO 639 code, possibly combined with
24     ISO 3166 country code and additional modifiers (examples include
25     "fr", "en_GB" or "ca@valencia"; see wxLocale::GetCanonicalName() for
26     more information). This allows apps using wxTranslations API to use even
27     languages not recognized by the operating system or not listed in
28     wxLanguage enum.
29 
30     @since 2.9.1
31 
32     @see wxLocale, wxTranslationsLoader, wxFileTranslationsLoader
33  */
34 class wxTranslations
35 {
36 public:
37     /// Constructor
38     wxTranslations();
39 
40     /**
41         Returns current translations object, may return NULL.
42 
43         You must either call this early in app initialization code, or let
44         wxLocale do it for you.
45      */
46     static wxTranslations *Get();
47 
48     /**
49         Sets current translations object.
50 
51         Deletes previous translation object and takes ownership of @a t.
52      */
53     static void Set(wxTranslations *t);
54 
55     /**
56         Changes loader use to read catalogs to a non-default one.
57 
58         Deletes previous loader and takes ownership of @a loader.
59 
60         @see wxTranslationsLoader, wxFileTranslationsLoader, wxResourceTranslationsLoader
61      */
62     void SetLoader(wxTranslationsLoader *loader);
63 
64     /**
65         Sets translations language to use.
66 
67         wxLANGUAGE_DEFAULT has special meaning: best suitable translation,
68         given user's preference and available translations, will be used.
69      */
70     void SetLanguage(wxLanguage lang);
71 
72     /**
73         Sets translations language to use.
74 
75         Empty @a lang string has the same meaning as wxLANGUAGE_DEFAULT in
76         SetLanguage(wxLanguage): best suitable translation, given user's
77         preference and available translations, will be used.
78      */
79     void SetLanguage(const wxString& lang);
80 
81     /**
82         Returns list of all translations of @a domain that were found.
83 
84         This method can be used e.g. to populate list of application's
85         translations offered to the user. To do this, pass the app's main
86         catalog as @a domain.
87 
88         @see GetBestTranslation()
89      */
90     wxArrayString GetAvailableTranslations(const wxString& domain) const;
91 
92     /**
93         Returns the best UI language for the @a domain.
94 
95         The language is determined from the preferred UI language or languages
96         list the user configured in the OS. Notice that this may or may not
97         correspond to the default @em locale as obtained from
98         wxLocale::GetSystemLanguage(); modern operation systems (Windows
99         Vista+, OS X) have separate language and regional (= locale) settings.
100 
101         @param domain
102             The catalog domain to look for.
103 
104         @param msgIdLanguage
105             Specifies the language of "msgid" strings in source code
106             (i.e. arguments to GetString(), wxGetTranslation() and the _() macro).
107 
108         @return Language code if a suitable match was found, empty string
109                 otherwise.
110 
111         @since 2.9.5
112      */
113     wxString GetBestTranslation(const wxString& domain, wxLanguage msgIdLanguage);
114 
115     /**
116         Returns the best UI language for the @a domain.
117 
118         The language is determined from the preferred UI language or languages
119         list the user configured in the OS. Notice that this may or may not
120         correspond to the default @em locale as obtained from
121         wxLocale::GetSystemLanguage(); modern operation systems (Windows
122         Vista+, OS X) have separate language and regional (= locale) settings.
123 
124         @param domain
125             The catalog domain to look for.
126 
127         @param msgIdLanguage
128             Specifies the language of "msgid" strings in source code
129             (i.e. arguments to GetString(), wxGetTranslation() and the _() macro).
130 
131         @return Language code if a suitable match was found, empty string
132                 otherwise.
133 
134         @since 2.9.5
135      */
136     wxString GetBestTranslation(const wxString& domain,
137                                 const wxString& msgIdLanguage = "en");
138 
139     /**
140         Add standard wxWidgets catalogs ("wxstd" and possible port-specific
141         catalogs).
142 
143         @return @true if a suitable catalog was found, @false otherwise
144 
145         @see AddCatalog()
146      */
147     bool AddStdCatalog();
148 
149     /**
150         Add a catalog for use with the current locale.
151 
152         By default, it is searched for in standard places (see
153         wxFileTranslationsLoader), but you may also prepend additional
154         directories to the search path with
155         wxFileTranslationsLoader::AddCatalogLookupPathPrefix().
156 
157         All loaded catalogs will be used for message lookup by GetString() for
158         the current locale.
159 
160         In this overload, @c msgid strings are assumed
161         to be in English and written only using 7-bit ASCII characters.
162         If you have to deal with non-English strings or 8-bit characters in the
163         source code, see the instructions in @ref overview_nonenglish.
164 
165         @return
166             @true if catalog was successfully loaded, @false otherwise (which might
167             mean that the catalog is not found or that it isn't in the correct format).
168      */
169     bool AddCatalog(const wxString& domain);
170 
171     /**
172         Same as AddCatalog(const wxString&), but takes an additional argument,
173         @a msgIdLanguage.
174 
175         @param domain
176             The catalog domain to add.
177 
178         @param msgIdLanguage
179             Specifies the language of "msgid" strings in source code
180             (i.e. arguments to GetString(), wxGetTranslation() and the _() macro).
181             It is used if AddCatalog() cannot find any catalog for current language:
182             if the language is same as source code language, then strings from source
183             code are used instead.
184 
185         @return
186             @true if catalog was successfully loaded, @false otherwise (which might
187             mean that the catalog is not found or that it isn't in the correct format).
188      */
189     bool AddCatalog(const wxString& domain, wxLanguage msgIdLanguage);
190 
191     /**
192         Same as AddCatalog(const wxString&, wxLanguage), but takes two
193         additional arguments, @a msgIdLanguage and @a msgIdCharset.
194 
195         This overload is only available in non-Unicode build.
196 
197         @param domain
198             The catalog domain to add.
199 
200         @param msgIdLanguage
201             Specifies the language of "msgid" strings in source code
202             (i.e. arguments to GetString(), wxGetTranslation() and the _() macro).
203             It is used if AddCatalog() cannot find any catalog for current language:
204             if the language is same as source code language, then strings from source
205             code are used instead.
206 
207         @param msgIdCharset
208             Lets you specify the charset used for msgids in sources
209             in case they use 8-bit characters (e.g. German or French strings).
210 
211         @return
212             @true if catalog was successfully loaded, @false otherwise (which might
213             mean that the catalog is not found or that it isn't in the correct format).
214      */
215     bool AddCatalog(const wxString& domain,
216                     wxLanguage msgIdLanguage,
217                     const wxString& msgIdCharset);
218 
219     /**
220         Check if the given catalog is loaded, and returns @true if it is.
221 
222         According to GNU gettext tradition, each catalog normally corresponds to
223         'domain' which is more or less the application name.
224 
225         @see AddCatalog()
226      */
227     bool IsLoaded(const wxString& domain) const;
228 
229     /**
230         Retrieves the translation for a string in all loaded domains unless the @a domain
231         parameter is specified (and then only this catalog/domain is searched).
232 
233         Returns @NULL if translation is not available.
234 
235         This function is thread-safe.
236 
237         @remarks Domains are searched in the last to first order, i.e. catalogs
238                  added later override those added before.
239 
240         @since 3.0
241     */
242     const wxString *GetTranslatedString(const wxString& origString,
243                                         const wxString& domain = wxEmptyString) const;
244 
245     /**
246         Retrieves the translation for a string in all loaded domains unless the @a domain
247         parameter is specified (and then only this catalog/domain is searched).
248 
249         Returns @NULL if translation is not available.
250 
251         This form is used when retrieving translation of string that has different
252         singular and plural form in English or different plural forms in some
253         other language.
254 
255         @param origString  The singular form of the string to be converted.
256         @param n           The number on which the plural form choice depends on.
257                            (In some languages, there are different plural forms
258                            for e.g. n=2 and n=3 etc., in addition to the singular
259                            form (n=1) being different.)
260         @param domain      The only domain (i.e. message catalog) to search if
261                            specified. By default this parameter is empty,
262                            indicating that all loaded catalogs should be
263                            searched.
264 
265         See GNU gettext manual for additional information on plural forms handling.
266         This method is called by the wxGetTranslation() function and _() macro.
267 
268         This function is thread-safe.
269 
270         @remarks Domains are searched in the last to first order, i.e. catalogs
271                  added later override those added before.
272 
273         @since 3.0
274     */
275     const wxString *GetTranslatedString(const wxString& origString,
276                                         unsigned n,
277                                         const wxString& domain = wxEmptyString) const;
278 
279     /**
280         Returns the header value for header @a header.
281         The search for @a header is case sensitive. If an @a domain is passed,
282         this domain is searched. Else all domains will be searched until a
283         header has been found.
284 
285         The return value is the value of the header if found. Else this will be empty.
286     */
287     wxString GetHeaderValue(const wxString& header,
288                             const wxString& domain = wxEmptyString) const;
289 };
290 
291 
292 /**
293     Abstraction of translations discovery and loading.
294 
295     This interface makes it possible to override wxWidgets' default catalogs
296     loading mechanism and load MO files from locations other than the
297     filesystem (e.g. embed them in executable).
298 
299     Implementations must implement the LoadCatalog() method.
300 
301     @see wxFileTranslationsLoader, wxResourceTranslationsLoader
302 
303     @since 2.9.1
304  */
305 class wxTranslationsLoader
306 {
307 public:
308     /// Trivial default constructor.
309     wxTranslationsLoader();
310 
311     /**
312         Called to load requested catalog.
313 
314         If the catalog is found, LoadCatalog() should create wxMsgCatalog
315         instance with its data and return it. The caller will take ownership
316         of the catalog.
317 
318         @param domain        Domain to load.
319         @param lang          Language to look for. This is "canonical name"
320                              (see wxLocale::GetCanonicalName()), i.e. ISO 639
321                              code, possibly combined with country code or
322                              additional modifiers (e.g. "fr", "en_GB" or
323                              "ca@valencia").
324 
325         @return Loaded catalog or NULL on failure.
326      */
327     virtual wxMsgCatalog *LoadCatalog(const wxString& domain,
328                                       const wxString& lang) = 0;
329 
330     /**
331         Implements wxTranslations::GetAvailableTranslations().
332      */
333     virtual wxArrayString GetAvailableTranslations(const wxString& domain) const = 0;
334 };
335 
336 /**
337     Standard wxTranslationsLoader implementation.
338 
339     This finds catalogs in the filesystem, using the standard Unix layout.
340     This is the default unless you change the loader with
341     wxTranslations::SetLoader().
342 
343     Catalogs are searched for in standard places (system locales directory,
344     `LC_PATH` on Unix systems, Resources subdirectory of the application bundle
345     on OS X, executable's directory on Windows), but you may also prepend
346     additional directories to the search path with
347     AddCatalogLookupPathPrefix().
348 
349     @since 2.9.1
350  */
351 class wxFileTranslationsLoader : public wxTranslationsLoader
352 {
353 public:
354     /**
355         Add a prefix to the catalog lookup path: the message catalog files will
356         be looked up under prefix/lang/LC_MESSAGES and prefix/lang directories
357         (in this order).
358 
359         This only applies to subsequent invocations of
360         wxTranslations::AddCatalog().
361     */
362     static void AddCatalogLookupPathPrefix(const wxString& prefix);
363 };
364 
365 /**
366     This loader makes it possible to load translations from Windows
367     resources.
368 
369     If you wish to store translation MO files in resources, you have to
370     enable this loader before calling wxTranslations::AddCatalog() or
371     wxLocale::AddCatalog():
372 
373     @code
374     wxTranslations::Get()->SetLoader(new wxResourceTranslationsLoader);
375     @endcode
376 
377     Translations are stored in resources as compiled MO files, with type
378     set to "MOFILE" (unless you override GetResourceType()) and name
379     consisting of the domain, followed by underscore, followed by language
380     identification. For example, the relevant part of .rc file would look
381     like this:
382 
383     @code
384     myapp_de     MOFILE   "catalogs/de/myapp.mo"
385     myapp_fr     MOFILE   "catalogs/fr/myapp.mo"
386     myapp_en_GB  MOFILE   "catalogs/en_GB/myapp.mo"
387     @endcode
388 
389     This class is only available on Windows.
390 
391     @since 2.9.1
392  */
393 class wxResourceTranslationsLoader : public wxTranslationsLoader
394 {
395 protected:
396     /**
397         Returns resource type to use for translations.
398 
399         Default type is "MOFILE".
400      */
401     virtual wxString GetResourceType() const;
402 
403     /**
404         Returns handle of the module to load resources from.
405 
406         By default, the main executable is used.
407      */
408     virtual WXHINSTANCE GetModule() const;
409 };
410 
411 
412 /**
413     Represents a loaded translations message catalog.
414 
415     This class should only be used directly by wxTranslationsLoader
416     implementations.
417 
418     @since 2.9.1
419  */
420 class wxMsgCatalog
421 {
422 public:
423     /**
424         Creates catalog loaded from a MO file.
425 
426         @param filename  Path to the MO file to load.
427         @param domain    Catalog's domain. This typically matches
428                          the @a filename.
429 
430         @return Successfully loaded catalog or NULL on failure.
431      */
432     static wxMsgCatalog *CreateFromFile(const wxString& filename,
433                                         const wxString& domain);
434 
435     /**
436         Creates catalog from MO file data in memory buffer.
437 
438         @param data      Data in MO file format.
439         @param domain    Catalog's domain. This typically matches
440                          the @a filename.
441 
442         @return Successfully loaded catalog or NULL on failure.
443      */
444     static wxMsgCatalog *CreateFromData(const wxScopedCharBuffer& data,
445                                         const wxString& domain);
446 };
447 
448 
449 // ============================================================================
450 // Global functions/macros
451 // ============================================================================
452 
453 /** @addtogroup group_funcmacro_string */
454 //@{
455 
456 /**
457     This macro is identical to _() but for the plural variant of
458     wxGetTranslation().
459 
460     @return A const wxString.
461 
462     @header{wx/intl.h}
463 */
464 #define wxPLURAL(string, plural, n)
465 
466 /**
467     This macro doesn't do anything in the program code -- it simply expands to
468     the value of its argument.
469 
470     However it does have a purpose which is to mark the literal strings for the
471     extraction into the message catalog created by @c xgettext program. Usually
472     this is achieved using _() but that macro not only marks the string for
473     extraction but also expands into a wxGetTranslation() call which means that
474     it cannot be used in some situations, notably for static array
475     initialization.
476 
477     Here is an example which should make it more clear: suppose that you have a
478     static array of strings containing the weekday names and which have to be
479     translated (note that it is a bad example, really, as wxDateTime already
480     can be used to get the localized week day names already). If you write:
481 
482     @code
483     static const char * const weekdays[] = { _("Mon"), ..., _("Sun") };
484     ...
485     // use weekdays[n] as usual
486     @endcode
487 
488     The code wouldn't compile because the function calls are forbidden in the
489     array initializer. So instead you should do this:
490 
491     @code
492     static const char * const weekdays[] = { wxTRANSLATE("Mon"), ...,
493     wxTRANSLATE("Sun") };
494     ...
495     // use wxGetTranslation(weekdays[n])
496     @endcode
497 
498     Note that although the code @b would compile if you simply omit
499     wxTRANSLATE() in the above, it wouldn't work as expected because there
500     would be no translations for the weekday names in the program message
501     catalog and wxGetTranslation() wouldn't find them.
502 
503     @return A const wxChar*.
504 
505     @header{wx/intl.h}
506 */
507 #define wxTRANSLATE(string)
508 
509 /**
510     This function returns the translation of @a string in the current
511     @c locale(). If the string is not found in any of the loaded message
512     catalogs (see @ref overview_i18n), the original string is returned. In
513     debug build, an error message is logged -- this should help to find the
514     strings which were not yet translated.  If @a domain is specified then only
515     that domain/catalog is searched for a matching string.  As this function is
516     used very often, an alternative (and also common in Unix world) syntax is
517     provided: the _() macro is defined to do the same thing as
518     wxGetTranslation().
519 
520     This function is thread-safe.
521 
522     @note This function is not suitable for literal strings in Unicode builds
523           since the literal strings must be enclosed in wxT() macro which makes
524           them unrecognised by @c xgettext, and so they are not extracted to
525           the message catalog. Instead, use the _() and wxPLURAL() macro for
526           all literal strings.
527 
528     @see wxGetTranslation(const wxString&, const wxString&, unsigned, const wxString&)
529 
530     @header{wx/intl.h}
531 */
532 const wxString& wxGetTranslation(const wxString& string,
533                                  const wxString& domain = wxEmptyString);
534 
535 /**
536     This is an overloaded version of
537     wxGetTranslation(const wxString&, const wxString&), please see its
538     documentation for general information.
539 
540     This version is used when retrieving translation of string that has
541     different singular and plural forms in English or different plural forms in
542     some other language. Like wxGetTranslation(const wxString&,const wxString&),
543     the @a string parameter must contain the singular form of the string to be
544     converted and is used as the key for the search in the catalog. The
545     @a plural parameter is the plural form (in English). The parameter @a n is
546     used to determine the plural form. If no message catalog is found,
547     @a string is returned if "n == 1", otherwise @a plural is returned.
548 
549     See GNU gettext Manual for additional information on plural forms handling:
550     <http://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms>
551     For a shorter alternative see the wxPLURAL() macro.
552 
553     This function is thread-safe.
554 
555     @header{wx/intl.h}
556 */
557 const wxString& wxGetTranslation(const wxString& string,
558                                  const wxString& plural, unsigned n,
559                                  const wxString& domain = wxEmptyString);
560 
561 /**
562     Macro to be used around all literal strings that should be translated.
563 
564     This macro expands into a call to wxGetTranslation(), so it marks the
565     message for the extraction by @c xgettext just as wxTRANSLATE() does, but
566     also returns the translation of the string for the current locale during
567     execution.
568 
569     This macro is thread-safe.
570 
571     @header{wx/intl.h}
572 */
573 const wxString& _(const wxString& string);
574 
575 //@}
576 
577