Translator.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
3 
4  This file is part of the TerraLib - a Framework for building GIS enabled applications.
5 
6  TerraLib is free software: you can redistribute it and/or modify
7  it under the terms of the GNU Lesser General Public License as published by
8  the Free Software Foundation, either version 3 of the License,
9  or (at your option) any later version.
10 
11  TerraLib is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public License
17  along with TerraLib. See COPYING. If not, write to
18  TerraLib Team at <terralib-team@terralib.org>.
19  */
20 
21 /*!
22  \file terralib/core/translator/Translator.h
23 
24  \brief This class is designed for dealing with multi-language text translation in TerraLib.
25 
26  \author Matheus Cavassan Zaglia
27  \author Gilberto Ribeiro de Queiroz
28 */
29 
30 #ifndef __TERRALIB_CORE_TRANSLATOR_TRANSLATOR_H__
31 #define __TERRALIB_CORE_TRANSLATOR_TRANSLATOR_H__
32 
33 // TerraLib
34 #include "../Config.h"
35 
36 // STL
37 #include <locale>
38 #include <string>
39 #include <map>
40 #include <vector>
41 
42 namespace boost
43 {
44  namespace locale
45  {
46  class generator;
47  }
48 }
49 
50 namespace te
51 {
52  namespace core
53  {
54  /*!
55  \class Translator
56 
57  \brief This singleton is designed to deal with multi-language text translation in TerraLib.
58 
59  The Translator job is to manage "Internationalization" of the TerraLib messages.
60  This class is all about Native Language Support.
61  For each string you want to have a translation, you have to use
62  the special macro TR_TR("string") or TE_TR_PLURAL("string1","string2", int). This macro does nothing with your code;
63  its job is just to mark the code fragment that you want to translate and it does
64  all the job of calling the translation for you. The translations
65  are created with the GNU Gettext Utilities.
66 
67  We provide a cmake module that searchs for all the necessary GNU Gettext tools, and adds a macro that creates the files for
68  your translations.
69  This macro searchs in a given directory for all ".cpp" files and for the given keywords inside the found files,
70  then automatically generates the ".po", ".pot" and ".mo" files when you build your project.
71  The macro implementation can be found in the file build/cmake/modules/FindGettext.cmake.
72 
73  \code
74  #include <terralib/core/translator/Translator.h>
75  ...
76  TE_ADD_TEXT_DOMAIN("terralib_mod_core");
77  ...
78  std::string msg = TE_TR("My Message");
79  ...
80  or
81  ...
82  std::cout << TE_TR_PLURAL("One message", "Two messages", 1);
83  ...
84  \endcode
85 
86  Note that all marked messages will be part of a .pot file from where you can
87  create several po documents, one for each idiom. These .po files
88  can be used to generate a .mo binary file with the translation.
89 
90  \warning It is supposed that PO files are UTF-8 encoded.
91 
92  \ingroup core
93  */
95  {
96 
97  public:
98 
99  static Translator& instance();
100 
101  /*!
102  \brief It tries to translate the specified text string.
103 
104  If no translation is available it will return the
105  original message (always in English).
106 
107  \param message The text to be translated.
108 
109  \return A string of the translated message. You must not delete the memory pointed by the returned pointer.
110 
111  \note The returned message is UTF-8 encoded.
112  */
113  std::string translate(const std::string& message);
114 
115  /*!
116  \brief It tries to translate the specified text string.
117 
118  If no translation is available it will return the
119  original message (always in English).
120 
121  \param message The text to be translated.
122 
123  \return A string of the translated message. You must not delete the memory pointed by the returned pointer.
124 
125  \note The returned message is UTF-8 encoded.
126  */
127  std::string translate(const char* message);
128 
129  /*!
130  \brief It tries to translate the specified text string accounting for plural forms.
131 
132  If no translation is available it will return the
133  original message (always in English).
134 
135  \param msg1 The singular form of the text to be translated.
136  \param msg2 The plural form of the text to be translated.
137  \param n This parameter is used to determine the plural form.
138 
139  \return A string of the translated message. You must not delete the memory pointed by the returned pointer.
140 
141  \note The returned message is UTF-8 encoded.
142  */
143  std::string translate(const std::string& msg1,
144  const std::string& msg2,
145  unsigned int n);
146 
147  /*!
148  \brief It tries to translate the specified text string accounting for plural forms.
149 
150  If no translation is available it will return the
151  original message (always in English).
152 
153  \param msg1 The singular form of the text to be translated.
154  \param msg2 The plural form of the text to be translated.
155  \param n This parameter is used to determine the plural form.
156 
157  \return A string of the translated message. You must not delete the memory pointed by the returned pointer.
158 
159  \note The returned message is UTF-8 encoded.
160  */
161  std::string translate(const char* msg1,
162  const char* msg2,
163  unsigned int n);
164 
165  /*!
166  \brief It sets the locale for the Translator.
167 
168  \param locale A string of the new locale.
169  */
170  void setLocale(const std::string &locale);
171 
172  /*!
173  \brief It adds a new text domain (text catalog).
174 
175  \param textDomain A given message domain (just a name). A text domain is the name of the catalog used to translate the message.
176 
177  \param dir Where the text domain is located.
178 
179  \exception Exception If the text domain already exists it raises an exception. If you are not sure about the existence of a text domain, use the exist() method.
180  */
181  void addTextDomain(const std::string& textDomain, const std::string& dir);
182 
183 
184  /*!
185  \brief It returns true if the text domain (text catalog) exists and false otherwise.
186 
187  \param textDomain A given message domain (just a name).
188  */
189  bool exist(const std::string& textDomain);
190 
191  /*!
192  \brief It loads all translations on the translation share folder.
193  */
194  void loadAllTranslations(const std::string& translationsDir);
195 
196  private:
197 
198  /*! \brief Singleton constructor must be private or protected. */
200 
201  /*! \brief Singleton destructor must be private or protected. */
203 
204  /*! \brief Singleton copy constructor must be private or protected. */
205  Translator(Translator const&); //No copy allowed
206 
207  /*! \brief Singleton copy assignment operator must be private or protected. */
208  Translator& operator=(Translator const&); //No copy allowed
209 
210  /*!
211  \brief Initializes the translation files, loading it into memory. It will overwrite the pior loaded list.
212  */
214 
215  private:
216 
217  std::string m_locale; //!< If not empty, it is the current locale.
218  std::map<std::string, std::vector<std::string> > m_textDomainMap; //!< A vector from text domains to base directory for the message catalog.
220  boost::locale::generator* m_localeGenerator;
221  std::locale m_translationLocale;
222  };
223 
224  } // end namespace core
225 } // end namespace te
226 
227 // Check if the TR macro has already been defined
228 // by another application... if so, it will output
229 // an error message and stop compiling!
230 #ifdef TERRALIB_TRANSLATOR_ENABLED
231 #ifdef TE_TR
232 #error "The TE_TR macro has been already defined by another application or code. Please, inform TerraLib Development Team <terralib-team@dpi.inpe.br>, we will be glad to help solving this problem!"
233 #endif
234 #endif
235 
236 /*!
237  \def TE_ADD_TEXT_DOMAIN
238 
239  \brief It adds the given text domain and its directory to the multilingual system.
240 
241  \param domain A given message domain (just a name). A text domain is the name of the catalog used to translate the message.
242  \param dir Where the text domain is located.
243 */
244 #ifdef TERRALIB_TRANSLATOR_ENABLED
245  #define TE_ADD_TEXT_DOMAIN(domain, dir) te::core::Translator::instance().addTextDomain(domain, dir)
246 #else
247  #define TE_ADD_TEXT_DOMAIN(domain, dir) ((void)0)
248 #endif
249 
250 /*!
251  \def TE_TR
252 
253  \brief It marks a string in order to get translated.
254 
255  \param message The text to be translated.
256 
257  Example of usage:
258  \code
259  std::cout << TE_TR("My message!");
260 
261  throw Exception(TE_TR("My other message!"));
262  \endcode
263  */
264 #define TE_TR(message) te::core::Translator::instance().translate(message).c_str()
265 
266 /*!
267  \def TE_TR_PLURAL
268 
269  \brief It marks a string in order to get translated according to plural form.
270 
271  \param message1 The singular form of the text to be translated.
272  \param message2 The plural form of the text to be translated.
273  \param n This parameter is used to determine the plural form.
274 
275  Example of usage:
276  \code
277  int n = f(...);
278 
279  std::cout << TE_TR_PLURAL("One Message!", "Two Messages", n);
280 
281  throw Exception(TE_TR_PLURAL("One Message!", "Two Messages", n));
282  \endcode
283 
284  In the above example, the parameter n can be
285  a threshold that helps to choose between the first or the second construction.
286  If your trabslation file is configured with a theashold of 1,
287  indicating that if n > 1 must choose the second construction,
288  the plural versin will be choosed, otherwise, it will choose the
289  singular form (the fisrt one).
290  */
291 #define TE_TR_PLURAL(message1, message2, n) te::core::Translator::instance().translate(message1, message2, n).c_str()
292 
293 /*!
294  \def TE_TR_LANGUAGE
295 
296  \brief It sets the locale for the Translator.
297 
298  \param locale A string of the new locale.
299  */
300 #define TE_TR_LANGUAGE(locale) te::core::Translator::instance().setLocale(locale)
301 
302 #endif // __TERRALIB_CORE_TRANSLATOR_TRANSLATOR_H__
te::core::Translator
This singleton is designed to deal with multi-language text translation in TerraLib.
Definition: Translator.h:95
te
TerraLib.
Definition: AddressGeocodingOp.h:52
te::core::Translator::loadAllTranslations
void loadAllTranslations(const std::string &translationsDir)
It loads all translations on the translation share folder.
te::core::Translator::Translator
Translator()
Singleton constructor must be private or protected.
te::core::Translator::setLocale
void setLocale(const std::string &locale)
It sets the locale for the Translator.
te::core::Translator::translate
std::string translate(const char *message)
It tries to translate the specified text string.
te::core::Translator::operator=
Translator & operator=(Translator const &)
Singleton copy assignment operator must be private or protected.
boost
Definition: Translator.h:43
te::core::Translator::translate
std::string translate(const std::string &msg1, const std::string &msg2, unsigned int n)
It tries to translate the specified text string accounting for plural forms.
TECOREEXPORT
#define TECOREEXPORT
Definition: Config.h:52
te::core::Translator::m_locale
std::string m_locale
If not empty, it is the current locale.
Definition: Translator.h:217
te::core::Translator::Translator
Translator(Translator const &)
Singleton copy constructor must be private or protected.
te::core::Translator::translate
std::string translate(const std::string &message)
It tries to translate the specified text string.
te::core::Translator::m_localeGenerator
boost::locale::generator * m_localeGenerator
Definition: Translator.h:220
te::core::Translator::addTextDomain
void addTextDomain(const std::string &textDomain, const std::string &dir)
It adds a new text domain (text catalog).
te::core::Translator::updateTranslationFiles
void updateTranslationFiles()
Initializes the translation files, loading it into memory. It will overwrite the pior loaded list.
te::core::Translator::~Translator
~Translator()
Singleton destructor must be private or protected.
te::core::Translator::m_loadTranslationFiles
bool m_loadTranslationFiles
Definition: Translator.h:219
te::core::Translator::m_translationLocale
std::locale m_translationLocale
Definition: Translator.h:221
te::core::Translator::m_textDomainMap
std::map< std::string, std::vector< std::string > > m_textDomainMap
A vector from text domains to base directory for the message catalog.
Definition: Translator.h:218
te::core::Translator::translate
std::string translate(const char *msg1, const char *msg2, unsigned int n)
It tries to translate the specified text string accounting for plural forms.
te::core::Translator::exist
bool exist(const std::string &textDomain)
It returns true if the text domain (text catalog) exists and false otherwise.
te::core::Translator::instance
static Translator & instance()