1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef _COMPHELPER_LOCALE_HXX_
25 #define _COMPHELPER_LOCALE_HXX_
26 
27 //_______________________________________________
28 // includes
29 
30 #include <vector>
31 #include <rtl/ustring.hxx>
32 #include "comphelper/comphelperdllapi.h"
33 
34 // These are specified by i386 ABI suppl. but
35 // only affect Solaris i386/illumos so far.
36 
37 #if !defined(_XPG4_2) || defined(__EXTENSIONS__)
38 #undef	CS
39 #undef	ES
40 #endif
41 
42 //_______________________________________________
43 // namespace
44 
45 namespace comphelper{
46 
47 //_______________________________________________
48 // definitions
49 
50 /** @short  A Locale object represents a specific geographical, political, or cultural region.
51 
52     @descr  This Locale class can be used to:
53             - provide the different parts of a Locale (Language, Country, Variant)
54             - converting it from/to ISO formatted string values (like e.g. "en-US")
55             - provide some predefined (static) Locale objects
56  */
57 class COMPHELPER_DLLPUBLIC Locale
58 {
59     //-------------------------------------------
60     // const
61 
62     public:
63 
64         /** @short separates LANGUAGE and COUNTRY part of an ISO formatted Locale. */
65         static const sal_Unicode SEPERATOR_LC;
66 
67         /** @short separates COUNTRY and VARIANT part of an ISO formatted Locale. */
68         static const sal_Unicode SEPERATOR_CV;
69 
70         /** @short separates COUNTRY and VARIANT part of an ISO formatted Locale.
71             @descr Its true for some linux derivates only :-( */
72         static const sal_Unicode SEPERATOR_CV_LINUX;
73 
74         /** @short some predefined Locale objects. */
75         static const Locale& EN_US();
76         static const Locale& EN();
77         static const Locale& DE_DE();
78         static const Locale& DE_CH();
79         static const Locale& DE_AT();
80         static const Locale& AR();
81         static const Locale& CA();
82         static const Locale& CS();
83         static const Locale& DA();
84         static const Locale& EL();
85         static const Locale& ES();
86         static const Locale& FI();
87         static const Locale& FR();
88         static const Locale& HE();
89         static const Locale& HI_IN();
90         static const Locale& HU();
91         static const Locale& IT();
92         static const Locale& JA();
93         static const Locale& KO();
94         static const Locale& NL();
95         static const Locale& PL();
96         static const Locale& PT();
97         static const Locale& PT_BR();
98         static const Locale& RU();
99         static const Locale& SK();
100         static const Locale& SL();
101         static const Locale& SV();
102         static const Locale& TH();
103         static const Locale& TR();
104         static const Locale& X_DEFAULT();
105         static const Locale& X_COMMENT();
106         static const Locale& X_TRANSLATE();
107         static const Locale& X_NOTRANSLATE();
108         static const Locale& ZH_CN();
109         static const Locale& ZH_TW();
110 
111     //-------------------------------------------
112     // types
113 
114     public:
115 
116         /** @short will be throw during conversion, if a Locale can't be interpreted. */
117         struct MalFormedLocaleException
118         {
119             public:
120                 ::rtl::OUString Message;
121 
MalFormedLocaleExceptioncomphelper::Locale::MalFormedLocaleException122                 MalFormedLocaleException()
123                 {}
124 
MalFormedLocaleExceptioncomphelper::Locale::MalFormedLocaleException125                 MalFormedLocaleException(const ::rtl::OUString& sMessage)
126                     : Message(sMessage)
127                 {}
128         };
129 
130     //-------------------------------------------
131     // member
132 
133     private :
134 
135         //---------------------------------------
136         /** @short  must be a valid ISO	Language Code.
137 
138             @descr  These codes are the lower-case two-letter codes as defined by ISO-639.
139                     You can find a full list of these codes at a number of sites, such as:
140                     <BR><a href ="http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt">
141                     http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt</a>
142          */
143         ::rtl::OUString m_sLanguage;
144 
145         //---------------------------------------
146         /** @short  must be a valid ISO Country	Code.
147             @descr  These codes are the upper-case two-letter codes	as defined by ISO-3166.
148                     You can find a full list of these codes at a number of sites, such as:
149                     <BR><a href="http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html">
150                     http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html</a>
151          */
152         ::rtl::OUString m_sCountry;
153 
154         //---------------------------------------
155         /** @short  Variant codes are vendor and browser-specific.
156             @descr  For example, use WIN for Windows, MAC for Macintosh, and POSIX for POSIX.
157                     Where there are two variants, separate them with an underscore, and
158                     put the most important one first. For example, a Traditional Spanish collation
159                     might be referenced, with "ES", "ES", "Traditional_WIN".
160          */
161         ::rtl::OUString m_sVariant;
162 
163     //-------------------------------------------
164     // interface
165 
166     public :
167 
168         //---------------------------------------
169         /** @short  needed by outside users!
170 
171             @descr  Otherwise it wouldn't be possible to use
172                     any instance of such Locale static ...
173          */
174         Locale();
175 
176         //---------------------------------------
177         /** @short      construct a Locale from an ISO formatted string value.
178 
179             @seealso    fromISO()
180 
181             @param      sISO
182                         an ISO formatted string value, which can be parsed and
183                         tokenized into a Lamnguage, Country and Variant part.
184 
185             @throw      MalFormedLocaleException
186                         if conversion failed.
187           */
188         Locale(const ::rtl::OUString& sISO)
189             throw(MalFormedLocaleException);
190 
191         //---------------------------------------
192         /** @short      construct a Locale from language, country and variant.
193 
194             @seealso    setLanguage()
195             @seealso    setCountry()
196             @seealso    setVariant()
197 
198             @param      sLanguage
199                         lowercase two-letter ISO-639 code.
200 
201             @param      sCountry
202                         uppercase two-letter ISO-3166 code.
203 
204             @param      sVariant
205                         vendor and browser specific code.
206           */
207         Locale(const ::rtl::OUString& sLanguage                   ,
208                const ::rtl::OUString& sCountry                    ,
209                const ::rtl::OUString& sVariant = ::rtl::OUString());
210 
211         //---------------------------------------
212         /** @short  copy constructor.
213 
214             @param  aCopy
215                     the copy object.
216          */
217         Locale(const Locale& aCopy);
218 
219         //---------------------------------------
220         /** @short  returns the language code for this locale.
221 
222             @descr  That will either be the empty string or
223                     a lowercase ISO 639 code.
224 
225             @return [string]
226                     the language code.
227          */
228         ::rtl::OUString getLanguage() const;
229 
230         //---------------------------------------
231         /** @short  returns the country/region code for this locale.
232 
233             @descr  That will either be the empty string or an
234                     upercase ISO 3166 2-letter code.
235 
236             @return [string]
237                     the country code.
238          */
239         ::rtl::OUString getCountry() const;
240 
241         //---------------------------------------
242         /** @short  returns the variant code for this locale.
243 
244             @return [string]
245                     the variant code.
246          */
247         ::rtl::OUString getVariant() const;
248 
249         //---------------------------------------
250         /** @short  set the new language code for this locale.
251 
252             @descr  That will either be the empty string or
253                     a lowercase ISO 639 code.
254 
255             @param  sLanguage
256                     the language code.
257          */
258         void setLanguage(const ::rtl::OUString& sLanguage);
259 
260         //---------------------------------------
261         /** @short  set the new country/region code for this locale.
262 
263             @descr  That will either be the empty string or an
264                     upercase ISO 3166 2-letter code.
265 
266             @param  sCountry
267                     the country code.
268          */
269         void setCountry(const ::rtl::OUString& sCountry);
270 
271         //---------------------------------------
272         /** @short  set the new variant code for this locale.
273 
274             @param  sVariant
275                     the variant code.
276          */
277         void setVariant(const ::rtl::OUString& sVariant);
278 
279         //---------------------------------------
280         /** @short      take over new Locale informations.
281 
282             @seealso    Locale(const ::rtl::OUString& sISO)
283 
284             @param      sISO
285                         an ISO formatted string value, which can be parsed and
286                         tokenized into a Lamnguage, Country and Variant part.
287                         e.g. "en-US" or "en-US_WIN"
288 
289             @throw      MalFormedLocaleException
290                         if conversion failed.
291           */
292         void fromISO(const ::rtl::OUString& sISO)
293             throw(MalFormedLocaleException);
294 
295         //---------------------------------------
296         /** @short  converts this Locale to an ISO formatted string value.
297 
298             @descr  The different parts of this Locale will be assempled
299                     e.g. to "en-US" or "en-US_WIN"
300 
301             @return [string]
302                     the ISO formatted string.
303           */
304         ::rtl::OUString toISO() const;
305 
306         //---------------------------------------
307         /** @short  check, if two Locale objects are equals.
308 
309             @descr  All parts of a Locale (means Language, Country and Variant)
310                     will be checked.
311 
312             @param  aComparable
313                     the Locale object for compare.
314 
315             @return [boolean]
316                     TRUE if both objects uses the same values for
317                     Language, Country and Variant.
318          */
319         sal_Bool equals(const Locale& aComparable) const;
320 
321         //---------------------------------------
322         /** @short  check, if two Locale objects
323                     uses the same language.
324 
325             @descr  The Country and Variant parts of a Locale
326                     won't be checked here.
327 
328             @return [boolean]
329                     TRUE if both objects uses the same
330                     Language value.
331          */
332         sal_Bool similar(const Locale& aComparable) const;
333 
334         //---------------------------------------
335         /** @short      search for an equal or at least for a similar
336                         Locale in a list of possible ones.
337 
338             @descr      First it searches for a Locale, which is equals
339                         to the reference Locale.
340                         (means: same Language, Country, Variant)
341 
342                         If the reference Locale couldn't be located, it will be
343                         tried again - but we are checking for "similar" Locales then.
344                         (means: same Language)
345 
346                         If no similar Locale could be located, we search
347                         for a Locale "en-US" inside the given Locale list.
348 
349                         If "en-US" could not be located, we search for
350                         a Locale "en" inside the given list.
351 
352                         If no "same" nor any "similar" locale could be found,
353                         we try "x-default" and "x-notranslate" explicitly.
354                         Sometimes localized variables are optimized and don't use
355                         localzation really. E.g. in case the localized value is a fix
356                         product name.
357 
358                         If no locale match till now, we use any other existing
359                         locale, which exists inside the set of given ones!
360 
361             @seealso    equals()
362             @seealso    similar()
363 
364             @param      lISOList
365                         the list of possible Locales
366                         (as formatted ISO strings).
367 
368             @param      sReferenceISO
369                         the reference Locale, which should be searched
370                         if it's equal or similar to any Locale inside
371                         the provided Locale list.
372 
373             @return     An iterator, which points to the found element
374                         inside the given Locale list.
375                         If no matching Locale could be found, it points
376                         to the end of the list.
377 
378             @throw      [MalFormedLocaleException]
379                         if at least one ISO formatted string couldn't
380                         be converted to a valid Locale Object.
381          */
382         static ::std::vector< ::rtl::OUString >::const_iterator getFallback(const ::std::vector< ::rtl::OUString >& lISOList     ,
383                                                                             const ::rtl::OUString&                  sReferenceISO)
384             throw(MalFormedLocaleException);
385 
386         //---------------------------------------
387         /** @short      search for the next possible fallback locale.
388 
389             @descr      Instead of getFallback(vector<>, string) this method
390                         uses the given locale and decide by using an algorithm
391                         which locale can be the next possible one.
392 
393                         Algorithm:
394                         - if locale has country return language only
395                         - if locale different "en-US" return "en-US"
396                         - if locale "en-US" return "en"
397 
398             @param      aLocale [in/out]!
399                         the incoming value will be used to start
400                         search for a possible fallback ...
401                         and in case such fallback was found this parameter
402                         will be used for return too.
403 
404             @return     TRUE if the parameter aLocale contains a new fallback value;
405                         FALSE otherwise.
406          */
407         static sal_Bool getFallback(Locale& aLocale);
408 
409         //---------------------------------------
410         /** @short      assign elements of another locale
411                         to this instance.
412 
413             @param      rCopy
414                         another locale object.
415          */
416         void operator=(const Locale& rCopy);
417 
418         //---------------------------------------
419         /** @short      check if two Locale objects are equals.
420 
421             @seealso    equals()
422 
423             @param      aComparable
424                         the Locale object for compare.
425 
426             @return     [boolean]
427                         TRUE if both objects uses the same values for
428                         Language, Country and Variant.
429          */
430         sal_Bool operator==(const Locale& aComparable) const;
431 
432         //---------------------------------------
433         /** @short  check if two Locale objects are different.
434 
435             @param  aComparable
436                     the Locale object for compare.
437 
438             @return [boolean]
439                     TRUE if at least one part of such Locale
440                     isn't the same.
441          */
442         sal_Bool operator!=(const Locale& aComparable) const;
443 };
444 
445 } // namespace salhelper
446 
447 #endif // _COMPHELPER_LOCALE_HXX_
448