Coverage Report

Created: 2025-09-27 06:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wxwidgets/include/wx/translation.h
Line
Count
Source
1
/////////////////////////////////////////////////////////////////////////////
2
// Name:        wx/translation.h
3
// Purpose:     Internationalization and localisation for wxWidgets
4
// Author:      Vadim Zeitlin, Vaclav Slavik,
5
//              Michael N. Filippov <michael@idisys.iae.nsk.su>
6
// Created:     2010-04-23
7
// Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
8
//              (c) 2010 Vaclav Slavik <vslavik@fastmail.fm>
9
// Licence:     wxWindows licence
10
/////////////////////////////////////////////////////////////////////////////
11
12
#ifndef _WX_TRANSLATION_H_
13
#define _WX_TRANSLATION_H_
14
15
#include "wx/defs.h"
16
#include "wx/string.h"
17
18
#if wxUSE_INTL
19
20
#include "wx/buffer.h"
21
#include "wx/language.h"
22
#include "wx/strconv.h"
23
24
// This is a hack, but this header used to include wx/hashmap.h which, in turn,
25
// included wx/wxcrt.h and it turns out quite some existing code relied on it
26
// by using the CRT wrapper functions declared there without explicitly
27
// including that header, so keep including it from here to let it continue to
28
// compile.
29
#include "wx/wxcrt.h"
30
31
#include <memory>
32
#include <unordered_map>
33
34
using wxTranslationsHashMap = std::unordered_map<wxString, wxString>;
35
36
// ============================================================================
37
// global decls
38
// ============================================================================
39
40
// ----------------------------------------------------------------------------
41
// macros
42
// ----------------------------------------------------------------------------
43
44
// gettext() style macros (notice that xgettext should be invoked with
45
// --keyword="_" --keyword="wxPLURAL:1,2" options
46
// to extract the strings from the sources)
47
#ifndef WXINTL_NO_GETTEXT_MACRO
48
0
    #define _(s)                               wxUnderscoreWrapper((s))
49
#endif
50
51
0
#define wxPLURAL(sing, plur, n)                wxPluralWrapper((sing), (plur), n)
52
53
// wx-specific macro for translating strings in the given context: if you use
54
// them, you need to also add
55
// --keyword="wxGETTEXT_IN_CONTEXT:1c,2" --keyword="wxGETTEXT_IN_CONTEXT_PLURAL:1c,2,3"
56
// options to xgettext invocation.
57
#define wxGETTEXT_IN_CONTEXT(c, s) \
58
    wxGettextInContextWrapper((c), (s))
59
#define wxGETTEXT_IN_CONTEXT_PLURAL(c, sing, plur, n) \
60
    wxGettextInContextPluralWrapper((c), (sing), (plur), (n))
61
62
// another one which just marks the strings for extraction, but doesn't
63
// perform the translation (use -kwxTRANSLATE with xgettext!)
64
0
#define wxTRANSLATE(str) str
65
66
// another one which just marks the strings, with a context, for extraction,
67
// but doesn't perform the translation (use -kwxTRANSLATE_IN_CONTEXT:1c,2 with
68
// xgettext!)
69
#define wxTRANSLATE_IN_CONTEXT(c, str) str
70
71
// ----------------------------------------------------------------------------
72
// forward decls
73
// ----------------------------------------------------------------------------
74
75
class WXDLLIMPEXP_FWD_BASE wxArrayString;
76
class WXDLLIMPEXP_FWD_BASE wxTranslationsLoader;
77
class WXDLLIMPEXP_FWD_BASE wxLocale;
78
79
class wxPluralFormsCalculator;
80
using wxPluralFormsCalculatorPtr = std::unique_ptr<wxPluralFormsCalculator>;
81
82
// ----------------------------------------------------------------------------
83
// wxMsgCatalog corresponds to one loaded message catalog.
84
// ----------------------------------------------------------------------------
85
86
class WXDLLIMPEXP_BASE wxMsgCatalog
87
{
88
public:
89
    // Ctor is protected, because CreateFromXXX functions must be used,
90
    // but destruction should be unrestricted
91
    ~wxMsgCatalog();
92
93
    // load the catalog from disk or from data; caller is responsible for
94
    // deleting them if not null
95
    static wxMsgCatalog *CreateFromFile(const wxString& filename,
96
                                        const wxString& domain);
97
98
    static wxMsgCatalog *CreateFromData(const wxScopedCharBuffer& data,
99
                                        const wxString& domain);
100
101
    // get name of the catalog
102
0
    wxString GetDomain() const { return m_domain; }
103
104
    // get the translated string: returns nullptr if not found
105
    const wxString *GetString(const wxString& sz, unsigned n = UINT_MAX, const wxString& ct = wxEmptyString) const;
106
107
protected:
108
    wxMsgCatalog(const wxString& domain);
109
110
private:
111
    // variable pointing to the next element in a linked list (or nullptr)
112
    wxMsgCatalog *m_pNext;
113
    friend class wxTranslations;
114
115
    wxTranslationsHashMap   m_messages; // all messages in the catalog
116
    wxString                m_domain;   // name of the domain
117
118
    wxPluralFormsCalculatorPtr m_pluralFormsCalculator;
119
};
120
121
// ----------------------------------------------------------------------------
122
// wxTranslations: message catalogs
123
// ----------------------------------------------------------------------------
124
125
// this class allows to get translations for strings
126
class WXDLLIMPEXP_BASE wxTranslations
127
{
128
public:
129
    wxTranslations();
130
    ~wxTranslations();
131
132
    // returns current translations object, may return nullptr
133
    static wxTranslations *Get();
134
    // sets current translations object (takes ownership; may be null)
135
    static void Set(wxTranslations *t);
136
137
    // changes loader to non-default one; takes ownership of 'loader'
138
    void SetLoader(wxTranslationsLoader *loader);
139
140
    void SetLanguage(wxLanguage lang);
141
    void SetLanguage(const wxString& lang);
142
143
    // get languages available for this app
144
    wxArrayString GetAvailableTranslations(const wxString& domain) const;
145
146
    // find best available translation language for given domain
147
    wxString GetBestAvailableTranslation(const wxString& domain);
148
149
    wxString GetBestTranslation(const wxString& domain, wxLanguage msgIdLanguage);
150
    wxString GetBestTranslation(const wxString& domain,
151
                                const wxString& msgIdLanguage = wxASCII_STR("en"));
152
153
    // add catalog for the given domain returning true if it could be found by
154
    // wxTranslationsLoader
155
    bool AddAvailableCatalog(const wxString& domain, wxLanguage msgIdLanguage = wxLANGUAGE_ENGLISH_US);
156
157
    // add standard wxWidgets catalog ("wxstd")
158
    bool AddStdCatalog();
159
160
    // add catalog with given domain name and language, looking it up via
161
    // wxTranslationsLoader -- unlike AddAvailableCatalog(), this function also
162
    // returns true if this catalog is not needed at all because msgIdLanguage
163
    // is an acceptable language to use directly
164
    bool AddCatalog(const wxString& domain,
165
                    wxLanguage msgIdLanguage = wxLANGUAGE_ENGLISH_US);
166
167
    // check if the given catalog is loaded
168
    bool IsLoaded(const wxString& domain) const;
169
170
    // access to translations
171
    const wxString *GetTranslatedString(const wxString& origString,
172
                                        const wxString& domain = wxEmptyString,
173
                                        const wxString& context = wxEmptyString) const;
174
    const wxString *GetTranslatedString(const wxString& origString,
175
                                        unsigned n,
176
                                        const wxString& domain = wxEmptyString,
177
                                        const wxString& context = wxEmptyString) const;
178
179
    wxString GetHeaderValue(const wxString& header,
180
                            const wxString& domain = wxEmptyString) const;
181
182
    // this is hack to work around a problem with wxGetTranslation() which
183
    // returns const wxString& and not wxString, so when it returns untranslated
184
    // string, it needs to have a copy of it somewhere
185
    static const wxString& GetUntranslatedString(const wxString& str);
186
187
private:
188
    enum class Translations
189
    {
190
      NotNeeded = -1,
191
      NotFound = 0,
192
      Found = 1
193
    };
194
195
    Translations DoAddCatalog(const wxString& domain, wxLanguage msgIdLanguage);
196
197
    // perform loading of the catalog via m_loader
198
    bool LoadCatalog(const wxString& domain, const wxString& lang);
199
200
    // find catalog by name in a linked list, return nullptr if !found
201
    wxMsgCatalog *FindCatalog(const wxString& domain) const;
202
203
    // same as Set(), without taking ownership; only for wxLocale
204
    static void SetNonOwned(wxTranslations *t);
205
    friend class wxLocale;
206
207
    wxString DoGetBestAvailableTranslation(const wxString& domain, const wxString& additionalAvailableLanguage);
208
209
private:
210
    wxString m_lang;
211
    wxTranslationsLoader *m_loader;
212
213
    wxMsgCatalog *m_pMsgCat; // pointer to linked list of catalogs
214
215
    // In addition to keeping all the catalogs in the linked list, we also
216
    // store them in a hash map indexed by the domain name to allow finding
217
    // them by name efficiently.
218
    using wxMsgCatalogMap = std::unordered_map<wxString, wxMsgCatalog*>;
219
    wxMsgCatalogMap m_catalogMap;
220
};
221
222
223
// abstraction of translations discovery and loading
224
class WXDLLIMPEXP_BASE wxTranslationsLoader
225
{
226
public:
227
0
    wxTranslationsLoader() = default;
228
0
    virtual ~wxTranslationsLoader() = default;
229
230
    virtual wxMsgCatalog *LoadCatalog(const wxString& domain,
231
                                      const wxString& lang) = 0;
232
233
    virtual wxArrayString GetAvailableTranslations(const wxString& domain) const = 0;
234
};
235
236
237
// standard wxTranslationsLoader implementation, using filesystem
238
class WXDLLIMPEXP_BASE wxFileTranslationsLoader
239
    : public wxTranslationsLoader
240
{
241
public:
242
    static void AddCatalogLookupPathPrefix(const wxString& prefix);
243
244
    virtual wxMsgCatalog *LoadCatalog(const wxString& domain,
245
                                      const wxString& lang) override;
246
247
    virtual wxArrayString GetAvailableTranslations(const wxString& domain) const override;
248
};
249
250
251
#ifdef __WINDOWS__
252
// loads translations from win32 resources
253
class WXDLLIMPEXP_BASE wxResourceTranslationsLoader
254
    : public wxTranslationsLoader
255
{
256
public:
257
    virtual wxMsgCatalog *LoadCatalog(const wxString& domain,
258
                                      const wxString& lang) override;
259
260
    virtual wxArrayString GetAvailableTranslations(const wxString& domain) const override;
261
262
protected:
263
    // returns resource type to use for translations
264
    virtual wxString GetResourceType() const { return wxASCII_STR("MOFILE"); }
265
266
    // returns module to load resources from
267
    virtual WXHINSTANCE GetModule() const { return nullptr; }
268
};
269
#endif // __WINDOWS__
270
271
272
// ----------------------------------------------------------------------------
273
// global functions
274
// ----------------------------------------------------------------------------
275
276
// get the translation of the string in the current locale
277
inline const wxString& wxGetTranslation(const wxString& str,
278
                                        const wxString& domain = wxString(),
279
                                        const wxString& context = wxString())
280
0
{
281
0
    wxTranslations *trans = wxTranslations::Get();
282
0
    const wxString *transStr = trans ? trans->GetTranslatedString(str, domain, context)
283
0
                                     : nullptr;
284
0
    if ( transStr )
285
0
        return *transStr;
286
0
    else
287
        // NB: this function returns reference to a string, so we have to keep
288
        //     a copy of it somewhere
289
0
        return wxTranslations::GetUntranslatedString(str);
290
0
}
291
292
inline const wxString& wxGetTranslation(const wxString& str1,
293
                                        const wxString& str2,
294
                                        unsigned n,
295
                                        const wxString& domain = wxString(),
296
                                        const wxString& context = wxString())
297
0
{
298
0
    wxTranslations *trans = wxTranslations::Get();
299
0
    const wxString *transStr = trans ? trans->GetTranslatedString(str1, n, domain, context)
300
0
                                     : nullptr;
301
0
    if ( transStr )
302
0
        return *transStr;
303
0
    else
304
        // NB: this function returns reference to a string, so we have to keep
305
        //     a copy of it somewhere
306
0
        return n == 1
307
0
               ? wxTranslations::GetUntranslatedString(str1)
308
0
               : wxTranslations::GetUntranslatedString(str2);
309
0
}
310
311
#ifdef wxNO_IMPLICIT_WXSTRING_ENCODING
312
313
/*
314
 * It must always be possible to call wxGetTranslation() with const
315
 * char* arguments.
316
 */
317
inline const wxString& wxGetTranslation(const char *str,
318
                                        const char *domain = "",
319
                                        const char *context = "") {
320
    const wxMBConv &conv = wxConvWhateverWorks;
321
    return wxGetTranslation(wxString(str, conv), wxString(domain, conv),
322
                            wxString(context, conv));
323
}
324
325
inline const wxString& wxGetTranslation(const char *str1,
326
                                        const char *str2,
327
                                        unsigned n,
328
                                        const char *domain = "",
329
                                        const char *context = "") {
330
    const wxMBConv &conv = wxConvWhateverWorks;
331
    return wxGetTranslation(wxString(str1, conv), wxString(str2, conv), n,
332
                            wxString(domain, conv),
333
                            wxString(context, conv));
334
}
335
336
// We can't construct wxString implicitly in this case, so use a helper.
337
inline wxString wxTRANS_INPUT_STR(const char* s)
338
{
339
    return wxString::FromAscii(s);
340
}
341
342
inline wxString wxTRANS_INPUT_STR(const wchar_t* s)
343
{
344
    return wxString(s);
345
}
346
#else // !wxNO_IMPLICIT_WXSTRING_ENCODING
347
    // We can rely on implicit conversion, so don't bother with the helper.
348
0
    #define wxTRANS_INPUT_STR(s) s
349
#endif // wxNO_IMPLICIT_WXSTRING_ENCODING
350
351
#ifndef wxNO_REQUIRE_LITERAL_MSGIDS
352
353
// Wrapper functions that only accept string literals as arguments,
354
// not variables, not char* pointers, and define the fall backs only in
355
// order to point out to the comment below:
356
357
/*
358
    *** LITERALS-MSGID comment marker ***
359
360
    This comment explains the reason for static assert failures below. Please
361
    see https://wxwidgets.org/help/msgid-literals for a more detailed and
362
    possibly more up-to-date version of this comment.
363
364
    If you get a compile error when using any of the translation macros, i.e.
365
    _(), wxPLURAL() etc, it means that you're passing something other than a
366
    literal string, i.e. just simple "whatever", to wx translation functions.
367
    This most likely indicates a bug in your program which is now detected when
368
    it was silently ignored before and should be fixed by changing the code to
369
    use string literals. For example, existing code doing
370
371
        _(wxString::Format("Hello %s", who))
372
373
    wouldn't work properly even if it were allowed to compile and should be
374
    changed to
375
376
        wxString::Format(_("Hello %s"), who))
377
378
    However if you can't do this, for some reason, you may choose to predefine
379
    wxNO_REQUIRE_LITERAL_MSGIDS which disables these checks. Please note that
380
    this is *NOT* recommended, as the problematic strings still won't be
381
    translated, because they won't have been extracted by xgettext in the first
382
    place and the right thing to do remains to fix the code instead.
383
*/
384
385
template<size_t N, typename T>
386
const wxString& wxUnderscoreWrapper(const T (&msg)[N])
387
0
{
388
0
    return wxGetTranslation(wxTRANS_INPUT_STR(msg));
389
0
}
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<4ul, char>(char const (&) [4ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<7ul, char>(char const (&) [7ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<5ul, char>(char const (&) [5ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<29ul, char>(char const (&) [29ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<25ul, char>(char const (&) [25ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<20ul, char>(char const (&) [20ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<45ul, char>(char const (&) [45ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<30ul, char>(char const (&) [30ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<42ul, char>(char const (&) [42ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<53ul, char>(char const (&) [53ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<49ul, char>(char const (&) [49ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<26ul, char>(char const (&) [26ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<11ul, char>(char const (&) [11ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<47ul, char>(char const (&) [47ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<10ul, char>(char const (&) [10ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<57ul, char>(char const (&) [57ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<77ul, char>(char const (&) [77ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<144ul, char>(char const (&) [144ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<35ul, char>(char const (&) [35ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<40ul, char>(char const (&) [40ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<44ul, char>(char const (&) [44ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<43ul, char>(char const (&) [43ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<41ul, char>(char const (&) [41ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<67ul, char>(char const (&) [67ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<31ul, char>(char const (&) [31ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<48ul, char>(char const (&) [48ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<54ul, char>(char const (&) [54ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<59ul, char>(char const (&) [59ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<58ul, char>(char const (&) [58ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<36ul, char>(char const (&) [36ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<37ul, char>(char const (&) [37ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<38ul, char>(char const (&) [38ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<46ul, char>(char const (&) [46ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<84ul, char>(char const (&) [84ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<28ul, char>(char const (&) [28ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<39ul, char>(char const (&) [39ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<17ul, char>(char const (&) [17ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<22ul, char>(char const (&) [22ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<8ul, char>(char const (&) [8ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<52ul, char>(char const (&) [52ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<34ul, char>(char const (&) [34ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<33ul, char>(char const (&) [33ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<23ul, char>(char const (&) [23ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<64ul, char>(char const (&) [64ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<14ul, char>(char const (&) [14ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<85ul, char>(char const (&) [85ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<65ul, char>(char const (&) [65ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<24ul, char>(char const (&) [24ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<12ul, char>(char const (&) [12ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<60ul, char>(char const (&) [60ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<50ul, char>(char const (&) [50ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<51ul, char>(char const (&) [51ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<21ul, char>(char const (&) [21ul])
Unexecuted instantiation: wxString const& wxUnderscoreWrapper<63ul, char>(char const (&) [63ul])
390
391
template <typename T>
392
wxString wxUnderscoreWrapper(T)
393
{
394
    static_assert(!sizeof(T), "See https://wxwidgets.org/help/msgid-literals or LITERALS-MSGID comment above.");
395
    return {};
396
}
397
398
template<size_t M, size_t N, typename T>
399
const wxString& wxPluralWrapper(const T (&msg)[M],
400
                                const T (&plural)[N],
401
                                int count)
402
0
{
403
0
    return wxGetTranslation(wxTRANS_INPUT_STR(msg), wxTRANS_INPUT_STR(plural),
404
0
                            count);
405
0
}
Unexecuted instantiation: wxString const& wxPluralWrapper<39ul, 40ul, char>(char const (&) [39ul], char const (&) [40ul], int)
Unexecuted instantiation: wxString const& wxPluralWrapper<52ul, 53ul, char>(char const (&) [52ul], char const (&) [53ul], int)
406
407
template <typename T, typename U>
408
wxString wxPluralWrapper(T, U, int)
409
{
410
    static_assert(!sizeof(T), "See https://wxwidgets.org/help/msgid-literals or LITERALS-MSGID comment above.");
411
    return {};
412
}
413
414
template<size_t M, size_t N, typename T>
415
const wxString& wxGettextInContextWrapper(const T (&ctx)[M],
416
                                          const T (&msg)[N])
417
{
418
    return wxGetTranslation(wxTRANS_INPUT_STR(msg), wxString(),
419
                            wxTRANS_INPUT_STR(ctx));
420
}
421
422
template <typename T, typename U>
423
wxString wxGettextInContextWrapper(T, U)
424
{
425
    static_assert(!sizeof(T), "See https://wxwidgets.org/help/msgid-literals or LITERALS-MSGID comment above.");
426
    return {};
427
}
428
429
template<size_t L, size_t M, size_t N, typename T>
430
const wxString& wxGettextInContextPluralWrapper(const T (&ctx)[L],
431
                                                const T (&msg)[M],
432
                                                const T (&plural)[N],
433
                                                int count)
434
{
435
    return wxGetTranslation(wxTRANS_INPUT_STR(msg), wxTRANS_INPUT_STR(plural),
436
                            count, wxString(), wxTRANS_INPUT_STR(ctx));
437
}
438
439
template <typename T, typename U, typename V>
440
wxString wxGettextInContextPluralWrapper(T, U, V, int)
441
{
442
    static_assert(!sizeof(T), "See https://wxwidgets.org/help/msgid-literals or LITERALS-MSGID comment above.");
443
    return {};
444
}
445
446
#else // wxNO_REQUIRE_LITERAL_MSGIDS
447
448
// Wrapper functions that accept both string literals and variables
449
// as arguments.
450
inline const wxString& wxUnderscoreWrapper(const char *msg)
451
{
452
    return wxGetTranslation(wxTRANS_INPUT_STR(msg));
453
}
454
455
inline const wxString& wxPluralWrapper(const char *msg,
456
                                       const char *plural,
457
                                       int count)
458
{
459
    return wxGetTranslation(wxTRANS_INPUT_STR(msg), wxTRANS_INPUT_STR(plural),
460
                            count);
461
}
462
463
inline const wxString& wxGettextInContextWrapper(const char *ctx,
464
                                                 const char *msg)
465
{
466
    return wxGetTranslation(wxTRANS_INPUT_STR(msg), wxString(),
467
                            wxTRANS_INPUT_STR(ctx));
468
}
469
470
inline const wxString& wxGettextInContextPluralWrapper(const char *ctx,
471
                                                       const char *msg,
472
                                                       const char *plural,
473
                                                       int count)
474
{
475
    return wxGetTranslation(wxTRANS_INPUT_STR(msg), wxTRANS_INPUT_STR(plural),
476
                            count, wxString(), wxTRANS_INPUT_STR(ctx));
477
}
478
479
#endif // wxNO_REQUIRE_LITERAL_MSGIDS
480
481
#else // !wxUSE_INTL
482
483
// the macros should still be defined - otherwise compilation would fail
484
485
#if !defined(WXINTL_NO_GETTEXT_MACRO)
486
    #if !defined(_)
487
#ifndef wxNO_IMPLICIT_WXSTRING_ENCODING
488
        #define _(s)                 (s)
489
#else
490
        #define _(s)                 wxASCII_STR(s)
491
#endif
492
    #endif
493
    #define wxPLURAL(sing, plur, n)  ((n) == 1 ? (sing) : (plur))
494
    #define wxGETTEXT_IN_CONTEXT(c, s)                     (s)
495
    #define wxGETTEXT_IN_CONTEXT_PLURAL(c, sing, plur, n)  wxPLURAL(sing, plur, n)
496
#endif
497
498
#define wxTRANSLATE(str) str
499
#define wxTRANSLATE_IN_CONTEXT(c, str) str
500
501
// NB: we use a template here in order to avoid using
502
//     wxLocale::GetUntranslatedString() above, which would be required if
503
//     we returned const wxString&; this way, the compiler should be able to
504
//     optimize wxGetTranslation() away
505
506
template<typename TString>
507
inline TString wxGetTranslation(TString str)
508
    { return str; }
509
510
template<typename TString, typename TDomain>
511
inline TString wxGetTranslation(TString str, TDomain WXUNUSED(domain))
512
    { return str; }
513
514
template<typename TString, typename TDomain, typename TContext>
515
inline TString wxGetTranslation(TString str, TDomain WXUNUSED(domain), TContext WXUNUSED(context))
516
    { return str; }
517
518
template<typename TString, typename TDomain>
519
inline TString wxGetTranslation(TString str1, TString str2, size_t n)
520
    { return n == 1 ? str1 : str2; }
521
522
template<typename TString, typename TDomain>
523
inline TString wxGetTranslation(TString str1, TString str2, size_t n,
524
                                TDomain WXUNUSED(domain))
525
    { return n == 1 ? str1 : str2; }
526
527
template<typename TString, typename TDomain, typename TContext>
528
inline TString wxGetTranslation(TString str1, TString str2, size_t n,
529
                                TDomain WXUNUSED(domain),
530
                                TContext WXUNUSED(context))
531
    { return n == 1 ? str1 : str2; }
532
533
#endif // wxUSE_INTL/!wxUSE_INTL
534
535
// define this one just in case it occurs somewhere (instead of preferred
536
// wxTRANSLATE) too
537
#if !defined(WXINTL_NO_GETTEXT_MACRO)
538
    #if !defined(gettext_noop)
539
0
        #define gettext_noop(str) (str)
540
    #endif
541
    #if !defined(N_)
542
        #define N_(s)             (s)
543
    #endif
544
#endif
545
546
#endif // _WX_TRANSLATION_H_