1 /*
2 *****************************************************************
3 *****************************************************************
4 *******                                                  ********
5 ****** Copyright (C) 1988-2010 Tecplot, Inc.              *******
6 *******                                                  ********
7 *****************************************************************
8 *****************************************************************
9 */
10 
11 #ifndef TECPLOT_STRUTIL_TRANSLATEDSTRING
12 #define TECPLOT_STRUTIL_TRANSLATEDSTRING
13 
14 #if defined MSWIN
15 #pragma warning(disable : 4181)
16 #endif
17 
18 namespace tecplot
19 {
20 namespace strutil
21 {
22 
23 /**
24  * Class responsible for translating strings for internationalization. This
25  * class is used both to perform the translation and to identify which strings
26  * are/aren't in need of translation.
27  *
28  * With the exception of the empty constructor all translated strings are
29  * created via static methods or inline helper functions named translate() and
30  * dontTranslate(). Translated strings created with a call to translate() are
31  * flagged as needing human translation and return the translated value at
32  * runtime. Translated strings created with a call to dontTranslate() are
33  * flagged as not needing human translation and return the non-translated value
34  * at runtime. Examples:
35  *
36  *   ErrMsg(translate("Can I have %d cookies?", numCookies);
37  *   ErrMsg(dontTranslate("%s"), errMsgString);
38  *
39  * Conversion methods exists for std::string so that they operate well
40  * together. Therefore you can pass translated strings to methods or functions
41  * that receive std::string or std::string references. Additionally you can
42  * perform std::string operations by casting the translated string to a
43  * std::string. For example:
44  *
45  *   if (string(dialogTitle).size() != 0)
46  *     ...do something useful
47  *
48  * We have intentionally not provided conversion methods for "const char*" (an
49  * internal representation of the object's string) because of the risk of the
50  * client using the pointer after the translated string object goes out of
51  * scope.
52  *
53  * @author David Ossorio
54  */
55 class TranslatedString
56 {
57 public:
58     /**
59      * Enumeration describing available translation modes.
60      */
61     typedef enum { DontTranslate, DoTranslate } Mode;
62 
63     /**
64      * Constructs an empty translated string. It is equivalent to calling
65      * TranslatedString::null().
66      */
67     TranslatedString();
68 
69     /**
70      * Convenience function for creating a NULL translated string.
71      *
72      * @return
73      *     NULL translated string.
74      */
75     static TranslatedString null();
76 
77     /**
78      * Creates a translated string object and marks it as a string needing
79      * translation.
80      *
81      * @param str
82      *     Character string to translate.
83      * @param translatorNotes
84      *     Optional notes for the human translator describing the meaning
85      *     of the string.
86      */
87     static TranslatedString translate(const char* str,
88                                       const char* translatorNotes = NULL);
89 
90     /**
91      * Creates a translated string object and marks it as a string not needing
92      * translation.
93      *
94      * @param str
95      *     Character string to translate. The str parameter can be a NULL
96      *     pointer.
97      */
98     static TranslatedString dontTranslate(const char* str);
99 
100     /**
101      * Destructor.
102      */
103     virtual ~TranslatedString();
104 
105     /**
106      * Indicates if the object's string is NULL.
107      *
108      * @return
109      *     true if the object's string is NULL, false otherwise.
110      */
111     virtual bool isNull() const;
112 
113     /**
114      * Indicates if the object's string is NULL or zero length.
115      *
116      * @return
117      *     true if the object's string is NULL or zero length, false otherwise.
118      */
119     virtual bool isNullOrZeroLength() const;
120 
121     /**
122      * Returns the internal representation of the object's string. Use this
123      * result carefully. When this object goes out of scope so does this
124      * references.
125      *
126      * @return
127      *     Pointer to the internal representation of the object's string.
128      */
129     virtual const char* c_str();
130 
131 #if defined MSWIN
132     /**
133      * Returns the internal representation of the wide character version of the
134      * object's string. Use this result carefully. When this object goes out of
135      * scope so does this references.
136      *
137      * @return
138      *     Pointer to the internal representation of the object's string.
139      */
140     virtual const wchar_t* c_wstr();
141 #endif
142 
143     /**
144      * Returns a copy of the object's string by this object. The result is
145      * translated or not depending on the platform and how it was created.
146      *
147      * @return
148      *     Copy of the object's string.
149      */
150     virtual operator std::string();
151 
152 #if defined MSWIN
153     /**
154      * Returns a copy of the wide character version of the object's string.
155      * The result is translated or not depending on the platform and how it was
156      * created.
157      *
158      * @return
159      *     Copy of the wide character version of the object's string.
160      */
161     virtual operator std::wstring();
162 #endif
163 
164     /**
165      * Assignment operator.
166      */
167     virtual TranslatedString& operator =(const TranslatedString& other);
168 
169     /**
170      * Copy constructor.
171      */
172     TranslatedString(const TranslatedString& other);
173 
174 #if !defined NO_ASSERTS
175     /**
176      * Used only for assertions.
177      */
178     virtual bool isValid() const;
179 #endif /* !NO_ASSERTS */
180 
181 private:
182     /**
183      * Constructs a translated string. This is declared private to make sure
184      * clients use translate() or dontTranslate() so that Tecplot's translation
185      * parser can easily extract strings from the source code.
186      *
187      * @param mode
188      *     Indicates if this string is to be translated or not at runtime.
189      * @param str
190      *     Character string to translate.
191      * @param translatorNotes
192      *     Optional notes for the human translator describing the meaning
193      *     of the string.
194      */
195     TranslatedString(TranslatedString::Mode mode,
196                      const char*            str,
197                      const char*            translatorNotes);
198 
199     /**
200      * Convenience method for initialize a translated string.
201      *
202      * @param mode
203      *     Indicates if this string is to be translated or not at runtime.
204      * @param str
205      *     Character string to translate.
206      * @param translatorNotes
207      *     Optional notes for the human translator describing the meaning
208      *     of the string.
209      */
210     void init(TranslatedString::Mode mode,
211               const char*            str,
212               const char*            translatorNotes);
213 
214     /**
215      * Private instance data.
216      */
217     TranslatedString::Mode  m_mode;
218     bool                    m_isNull;
219     std::string             m_string;
220     std::string            *m_utf8String;
221 #if defined MSWIN
222     std::wstring           *m_wideString;
223 #endif
224 };
225 
226 /**
227  * Convenience function for creating a translated string object and marking it
228  * as a string needing translation.
229  *
230  * @param str
231  *     Character string to translate.
232  * @param translatorNotes
233  *     Optional notes for the human translator describing the meaning
234  *     of the string.
235  */
236 inline TranslatedString translate(const char* str,
237                                   const char* translatorNotes = NULL)
238 {
239     return TranslatedString::translate(str, translatorNotes);
240 }
241 
242 /**
243  * Convenience function for creating a translated string object and marking it
244  * as a string not needing translation.
245  *
246  * @param str
247  *     Character string to translate. The str parameter can be a NULL
248  *     pointer.
249  */
dontTranslate(const char * str)250 inline TranslatedString dontTranslate(const char* str)
251 {
252     return TranslatedString::dontTranslate(str);
253 }
254 
255 /**
256  * Convenience function for creating a translated string object and marks it as
257  * a string not needing translation.
258  *
259  * @param str
260  *     String to translate.
261  */
dontTranslate(const std::string & str)262 inline TranslatedString dontTranslate(const std::string& str)
263 {
264     return TranslatedString::dontTranslate(str.c_str());
265 }
266 
267 }
268 }
269 
270 #endif
271