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>
7 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
8 // (c) 2010 Vaclav Slavik <vslavik@fastmail.fm>
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #ifndef _WX_TRANSLATION_H_
13 #define _WX_TRANSLATION_H_
16 #include "wx/string.h"
20 #include "wx/buffer.h"
21 #include "wx/language.h"
22 #include "wx/hashmap.h"
23 #include "wx/strconv.h"
24 #include "wx/scopedptr.h"
26 // ============================================================================
28 // ============================================================================
30 // ----------------------------------------------------------------------------
32 // ----------------------------------------------------------------------------
34 // gettext() style macros (notice that xgettext should be invoked with
35 // --keyword="_" --keyword="wxPLURAL:1,2" options
36 // to extract the strings from the sources)
37 #ifndef WXINTL_NO_GETTEXT_MACRO
38 #define _(s) wxGetTranslation((s))
39 #define wxPLURAL(sing, plur, n) wxGetTranslation((sing), (plur), n)
42 // another one which just marks the strings for extraction, but doesn't
43 // perform the translation (use -kwxTRANSLATE with xgettext!)
44 #define wxTRANSLATE(str) str
46 // ----------------------------------------------------------------------------
48 // ----------------------------------------------------------------------------
50 class WXDLLIMPEXP_FWD_BASE wxArrayString
;
51 class WXDLLIMPEXP_FWD_BASE wxTranslationsLoader
;
52 class WXDLLIMPEXP_FWD_BASE wxLocale
;
54 class wxPluralFormsCalculator
;
55 wxDECLARE_SCOPED_PTR(wxPluralFormsCalculator
, wxPluralFormsCalculatorPtr
)
57 // ----------------------------------------------------------------------------
58 // wxMsgCatalog corresponds to one loaded message catalog.
59 // ----------------------------------------------------------------------------
61 class WXDLLIMPEXP_BASE wxMsgCatalog
64 // Ctor is protected, because CreateFromXXX functions must be used,
65 // but destruction should be unrestricted
70 // load the catalog from disk or from data; caller is responsible for
71 // deleting them if not NULL
72 static wxMsgCatalog
*CreateFromFile(const wxString
& filename
,
73 const wxString
& domain
);
75 static wxMsgCatalog
*CreateFromData(const wxScopedCharBuffer
& data
,
76 const wxString
& domain
);
78 // get name of the catalog
79 wxString
GetDomain() const { return m_domain
; }
81 // get the translated string: returns NULL if not found
82 const wxString
*GetString(const wxString
& sz
, unsigned n
= UINT_MAX
) const;
85 wxMsgCatalog(const wxString
& domain
)
86 : m_pNext(NULL
), m_domain(domain
)
93 // variable pointing to the next element in a linked list (or NULL)
94 wxMsgCatalog
*m_pNext
;
95 friend class wxTranslations
;
97 wxStringToStringHashMap m_messages
; // all messages in the catalog
98 wxString m_domain
; // name of the domain
101 // the conversion corresponding to this catalog charset if we installed it
106 wxPluralFormsCalculatorPtr m_pluralFormsCalculator
;
109 // ----------------------------------------------------------------------------
110 // wxTranslations: message catalogs
111 // ----------------------------------------------------------------------------
113 // this class allows to get translations for strings
114 class WXDLLIMPEXP_BASE wxTranslations
120 // returns current translations object, may return NULL
121 static wxTranslations
*Get();
122 // sets current translations object (takes ownership; may be NULL)
123 static void Set(wxTranslations
*t
);
125 // changes loader to non-default one; takes ownership of 'loader'
126 void SetLoader(wxTranslationsLoader
*loader
);
128 void SetLanguage(wxLanguage lang
);
129 void SetLanguage(const wxString
& lang
);
131 // get languages available for this app
132 wxArrayString
GetAvailableTranslations(const wxString
& domain
) const;
134 // find best translation language for given domain
135 wxString
GetBestTranslation(const wxString
& domain
, wxLanguage msgIdLanguage
);
136 wxString
GetBestTranslation(const wxString
& domain
,
137 const wxString
& msgIdLanguage
= "en");
139 // add standard wxWidgets catalog ("wxstd")
140 bool AddStdCatalog();
142 // add catalog with given domain name and language, looking it up via
143 // wxTranslationsLoader
144 bool AddCatalog(const wxString
& domain
);
145 bool AddCatalog(const wxString
& domain
, wxLanguage msgIdLanguage
);
147 bool AddCatalog(const wxString
& domain
,
148 wxLanguage msgIdLanguage
,
149 const wxString
& msgIdCharset
);
152 // check if the given catalog is loaded
153 bool IsLoaded(const wxString
& domain
) const;
155 // access to translations
156 const wxString
*GetTranslatedString(const wxString
& origString
,
157 const wxString
& domain
= wxEmptyString
) const;
158 const wxString
*GetTranslatedString(const wxString
& origString
,
160 const wxString
& domain
= wxEmptyString
) const;
162 wxString
GetHeaderValue(const wxString
& header
,
163 const wxString
& domain
= wxEmptyString
) const;
165 // this is hack to work around a problem with wxGetTranslation() which
166 // returns const wxString& and not wxString, so when it returns untranslated
167 // string, it needs to have a copy of it somewhere
168 static const wxString
& GetUntranslatedString(const wxString
& str
);
171 // perform loading of the catalog via m_loader
172 bool LoadCatalog(const wxString
& domain
, const wxString
& lang
);
174 // find catalog by name in a linked list, return NULL if !found
175 wxMsgCatalog
*FindCatalog(const wxString
& domain
) const;
177 // same as Set(), without taking ownership; only for wxLocale
178 static void SetNonOwned(wxTranslations
*t
);
179 friend class wxLocale
;
183 wxTranslationsLoader
*m_loader
;
185 wxMsgCatalog
*m_pMsgCat
; // pointer to linked list of catalogs
189 // abstraction of translations discovery and loading
190 class WXDLLIMPEXP_BASE wxTranslationsLoader
193 wxTranslationsLoader() {}
194 virtual ~wxTranslationsLoader() {}
196 virtual wxMsgCatalog
*LoadCatalog(const wxString
& domain
,
197 const wxString
& lang
) = 0;
199 virtual wxArrayString
GetAvailableTranslations(const wxString
& domain
) const = 0;
203 // standard wxTranslationsLoader implementation, using filesystem
204 class WXDLLIMPEXP_BASE wxFileTranslationsLoader
205 : public wxTranslationsLoader
208 static void AddCatalogLookupPathPrefix(const wxString
& prefix
);
210 virtual wxMsgCatalog
*LoadCatalog(const wxString
& domain
,
211 const wxString
& lang
);
213 virtual wxArrayString
GetAvailableTranslations(const wxString
& domain
) const;
218 // loads translations from win32 resources
219 class WXDLLIMPEXP_BASE wxResourceTranslationsLoader
220 : public wxTranslationsLoader
223 virtual wxMsgCatalog
*LoadCatalog(const wxString
& domain
,
224 const wxString
& lang
);
226 virtual wxArrayString
GetAvailableTranslations(const wxString
& domain
) const;
229 // returns resource type to use for translations
230 virtual wxString
GetResourceType() const { return "MOFILE"; }
232 // returns module to load resources from
233 virtual WXHINSTANCE
GetModule() const { return 0; }
235 #endif // __WINDOWS__
238 // ----------------------------------------------------------------------------
240 // ----------------------------------------------------------------------------
242 // get the translation of the string in the current locale
243 inline const wxString
& wxGetTranslation(const wxString
& str
,
244 const wxString
& domain
= wxString())
246 wxTranslations
*trans
= wxTranslations::Get();
247 const wxString
*transStr
= trans
? trans
->GetTranslatedString(str
, domain
)
252 // NB: this function returns reference to a string, so we have to keep
253 // a copy of it somewhere
254 return wxTranslations::GetUntranslatedString(str
);
257 inline const wxString
& wxGetTranslation(const wxString
& str1
,
258 const wxString
& str2
,
260 const wxString
& domain
= wxString())
262 wxTranslations
*trans
= wxTranslations::Get();
263 const wxString
*transStr
= trans
? trans
->GetTranslatedString(str1
, n
, domain
)
268 // NB: this function returns reference to a string, so we have to keep
269 // a copy of it somewhere
271 ? wxTranslations::GetUntranslatedString(str1
)
272 : wxTranslations::GetUntranslatedString(str2
);
277 // the macros should still be defined - otherwise compilation would fail
279 #if !defined(WXINTL_NO_GETTEXT_MACRO)
283 #define wxPLURAL(sing, plur, n) ((n) == 1 ? (sing) : (plur))
286 #define wxTRANSLATE(str) str
288 // NB: we use a template here in order to avoid using
289 // wxLocale::GetUntranslatedString() above, which would be required if
290 // we returned const wxString&; this way, the compiler should be able to
291 // optimize wxGetTranslation() away
293 template<typename TString
>
294 inline TString
wxGetTranslation(TString str
)
297 template<typename TString
, typename TDomain
>
298 inline TString
wxGetTranslation(TString str
, TDomain
WXUNUSED(domain
))
301 template<typename TString
, typename TDomain
>
302 inline TString
wxGetTranslation(TString str1
, TString str2
, size_t n
)
303 { return n
== 1 ? str1
: str2
; }
305 template<typename TString
, typename TDomain
>
306 inline TString
wxGetTranslation(TString str1
, TString str2
, size_t n
,
307 TDomain
WXUNUSED(domain
))
308 { return n
== 1 ? str1
: str2
; }
310 #endif // wxUSE_INTL/!wxUSE_INTL
312 // define this one just in case it occurs somewhere (instead of preferred
314 #if !defined(WXINTL_NO_GETTEXT_MACRO)
315 #if !defined(gettext_noop)
316 #define gettext_noop(str) (str)
323 #endif // _WX_TRANSLATION_H_