CWS-TOOLING: integrate CWS os146
[LibreOffice.git] / comphelper / source / misc / locale.cxx
blob53c53f1c3c483ba3a64449487315c80b943ea797
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_comphelper.hxx"
30 #include <comphelper/locale.hxx>
32 //_______________________________________________
33 // includes
34 #include <rtl/ustrbuf.hxx>
36 //_______________________________________________
37 // namespace
39 namespace comphelper{
41 //-----------------------------------------------
42 const sal_Unicode Locale::SEPERATOR_LC = (sal_Unicode)'-';
43 const sal_Unicode Locale::SEPERATOR_CV = (sal_Unicode)'_';
44 const sal_Unicode Locale::SEPERATOR_CV_LINUX = (sal_Unicode)'.';
46 //-----------------------------------------------
47 const Locale Locale::X_DEFAULT()
49 static Locale aLocale(
50 ::rtl::OUString::createFromAscii("x"),
51 ::rtl::OUString::createFromAscii("default"));
52 return aLocale;
55 //-----------------------------------------------
56 const Locale Locale::EN()
58 static Locale aLocale(
59 ::rtl::OUString::createFromAscii("en"),
60 ::rtl::OUString());
61 return aLocale;
64 //-----------------------------------------------
65 const Locale Locale::EN_US()
67 static Locale aLocale(
68 ::rtl::OUString::createFromAscii("en"),
69 ::rtl::OUString::createFromAscii("US"));
70 return aLocale;
73 //-----------------------------------------------
74 const Locale Locale::DE_DE()
76 static Locale aLocale(
77 ::rtl::OUString::createFromAscii("de"),
78 ::rtl::OUString::createFromAscii("DE"));
79 return aLocale;
82 //-----------------------------------------------
83 const Locale Locale::DE_CH()
85 static Locale aLocale(
86 ::rtl::OUString::createFromAscii("de"),
87 ::rtl::OUString::createFromAscii("CH"));
88 return aLocale;
91 //-----------------------------------------------
92 const Locale Locale::DE_AT()
94 static Locale aLocale(
95 ::rtl::OUString::createFromAscii("de"),
96 ::rtl::OUString::createFromAscii("AT"));
97 return aLocale;
100 //-----------------------------------------------
101 const Locale Locale::AR()
103 static Locale aLocale(
104 ::rtl::OUString::createFromAscii("ar"),
105 ::rtl::OUString());
106 return aLocale;
109 //-----------------------------------------------
110 const Locale Locale::CA()
112 static Locale aLocale(
113 ::rtl::OUString::createFromAscii("ca"),
114 ::rtl::OUString());
115 return aLocale;
118 //-----------------------------------------------
119 const Locale Locale::CS()
121 static Locale aLocale(
122 ::rtl::OUString::createFromAscii("cs"),
123 ::rtl::OUString());
124 return aLocale;
127 //-----------------------------------------------
128 const Locale Locale::DA()
130 static Locale aLocale(
131 ::rtl::OUString::createFromAscii("da"),
132 ::rtl::OUString());
133 return aLocale;
136 //-----------------------------------------------
137 const Locale Locale::EL()
139 static Locale aLocale(
140 ::rtl::OUString::createFromAscii("el"),
141 ::rtl::OUString());
142 return aLocale;
145 //-----------------------------------------------
146 const Locale Locale::ES()
148 static Locale aLocale(
149 ::rtl::OUString::createFromAscii("es"),
150 ::rtl::OUString());
151 return aLocale;
154 //-----------------------------------------------
155 const Locale Locale::FI()
157 static Locale aLocale(
158 ::rtl::OUString::createFromAscii("fi"),
159 ::rtl::OUString());
160 return aLocale;
163 //-----------------------------------------------
164 const Locale Locale::FR()
166 static Locale aLocale(
167 ::rtl::OUString::createFromAscii("fr"),
168 ::rtl::OUString());
169 return aLocale;
172 //-----------------------------------------------
173 const Locale Locale::HE()
175 static Locale aLocale(
176 ::rtl::OUString::createFromAscii("he"),
177 ::rtl::OUString());
178 return aLocale;
181 //-----------------------------------------------
182 const Locale Locale::HI_IN()
184 static Locale aLocale(
185 ::rtl::OUString::createFromAscii("hi"),
186 ::rtl::OUString::createFromAscii("IN"));
187 return aLocale;
190 //-----------------------------------------------
191 const Locale Locale::HU()
193 static Locale aLocale(
194 ::rtl::OUString::createFromAscii("hu"),
195 ::rtl::OUString());
196 return aLocale;
199 //-----------------------------------------------
200 const Locale Locale::IT()
202 static Locale aLocale(
203 ::rtl::OUString::createFromAscii("it"),
204 ::rtl::OUString());
205 return aLocale;
208 //-----------------------------------------------
209 const Locale Locale::JA()
211 static Locale aLocale(
212 ::rtl::OUString::createFromAscii("ja"),
213 ::rtl::OUString());
214 return aLocale;
217 //-----------------------------------------------
218 const Locale Locale::KO()
220 static Locale aLocale(
221 ::rtl::OUString::createFromAscii("ko"),
222 ::rtl::OUString());
223 return aLocale;
226 //-----------------------------------------------
227 const Locale Locale::NL()
229 static Locale aLocale(
230 ::rtl::OUString::createFromAscii("nl"),
231 ::rtl::OUString());
232 return aLocale;
235 //-----------------------------------------------
236 const Locale Locale::PL()
238 static Locale aLocale(
239 ::rtl::OUString::createFromAscii("pl"),
240 ::rtl::OUString());
241 return aLocale;
244 //-----------------------------------------------
245 const Locale Locale::PT()
247 static Locale aLocale(
248 ::rtl::OUString::createFromAscii("pt"),
249 ::rtl::OUString());
250 return aLocale;
253 //-----------------------------------------------
254 const Locale Locale::PT_BR()
256 static Locale aLocale(
257 ::rtl::OUString::createFromAscii("pt"),
258 ::rtl::OUString::createFromAscii("BR"));
259 return aLocale;
262 //-----------------------------------------------
263 const Locale Locale::RU()
265 static Locale aLocale(
266 ::rtl::OUString::createFromAscii("ru"),
267 ::rtl::OUString());
268 return aLocale;
271 //-----------------------------------------------
272 const Locale Locale::SK()
274 static Locale aLocale(
275 ::rtl::OUString::createFromAscii("sk"),
276 ::rtl::OUString());
277 return aLocale;
280 //-----------------------------------------------
281 const Locale Locale::SL()
283 static Locale aLocale(
284 ::rtl::OUString::createFromAscii("sl"),
285 ::rtl::OUString());
286 return aLocale;
289 //-----------------------------------------------
290 const Locale Locale::SV()
292 static Locale aLocale(
293 ::rtl::OUString::createFromAscii("sv"),
294 ::rtl::OUString());
295 return aLocale;
298 //-----------------------------------------------
299 const Locale Locale::TH()
301 static Locale aLocale(
302 ::rtl::OUString::createFromAscii("th"),
303 ::rtl::OUString());
304 return aLocale;
307 //-----------------------------------------------
308 const Locale Locale::TR()
310 static Locale aLocale(
311 ::rtl::OUString::createFromAscii("tr"),
312 ::rtl::OUString());
313 return aLocale;
316 //-----------------------------------------------
317 const Locale Locale::X_COMMENT()
319 static Locale aLocale(
320 ::rtl::OUString::createFromAscii("x"),
321 ::rtl::OUString::createFromAscii("comment"));
322 return aLocale;
325 //-----------------------------------------------
326 const Locale Locale::X_TRANSLATE()
328 static Locale aLocale(
329 ::rtl::OUString::createFromAscii("x"),
330 ::rtl::OUString::createFromAscii("translate"));
331 return aLocale;
334 //-----------------------------------------------
335 const Locale Locale::X_NOTRANSLATE()
337 static Locale aLocale(
338 ::rtl::OUString::createFromAscii("x"),
339 ::rtl::OUString::createFromAscii("notranslate"));
340 return aLocale;
343 //-----------------------------------------------
344 const Locale Locale::ZH_CN()
346 static Locale aLocale(
347 ::rtl::OUString::createFromAscii("zh"),
348 ::rtl::OUString::createFromAscii("CN"));
349 return aLocale;
352 //-----------------------------------------------
353 const Locale Locale::ZH_TW()
355 static Locale aLocale(
356 ::rtl::OUString::createFromAscii("zh"),
357 ::rtl::OUString::createFromAscii("TW"));
358 return aLocale;
361 //-----------------------------------------------
362 Locale::Locale(const ::rtl::OUString& sISO)
363 throw(Locale::MalFormedLocaleException)
365 fromISO(sISO);
368 //-----------------------------------------------
369 Locale::Locale(const ::rtl::OUString& sLanguage,
370 const ::rtl::OUString& sCountry ,
371 const ::rtl::OUString& sVariant )
373 // Use set methods to check values too!
374 setLanguage(sLanguage);
375 setCountry (sCountry );
376 setVariant (sVariant );
379 //-----------------------------------------------
380 Locale::Locale()
382 // Initialize instance ... otherwhise user will
383 // may be get exceptions if he e.g. copy this instance ...
384 (*this) = X_NOTRANSLATE();
387 //-----------------------------------------------
388 Locale::Locale(const Locale& aCopy)
390 (*this) = aCopy; // recycle assign operator
393 //-----------------------------------------------
394 ::rtl::OUString Locale::getLanguage() const
396 return m_sLanguage;
399 //-----------------------------------------------
400 ::rtl::OUString Locale::getCountry() const
402 return m_sCountry;
405 //-----------------------------------------------
406 ::rtl::OUString Locale::getVariant() const
408 return m_sVariant;
411 //-----------------------------------------------
412 void Locale::setLanguage(const ::rtl::OUString& sLanguage)
414 m_sLanguage = sLanguage;
417 //-----------------------------------------------
418 void Locale::setCountry(const ::rtl::OUString& sCountry)
420 m_sCountry = sCountry;
423 //-----------------------------------------------
424 void Locale::setVariant(const ::rtl::OUString& sVariant)
426 m_sVariant = sVariant;
429 //-----------------------------------------------
430 /* Attention: Use own interface methods to set the
431 different parts of this locale. Because the
432 check the incoming value and throw an exception
433 automaticly ...
435 void Locale::fromISO(const ::rtl::OUString& sISO)
436 throw(Locale::MalFormedLocaleException)
438 m_sLanguage = ::rtl::OUString();
439 m_sCountry = ::rtl::OUString();
440 m_sVariant = ::rtl::OUString();
442 ::rtl::OUString sParser(sISO);
443 sParser.trim();
445 sal_Int32 nStart = 0;
446 sal_Int32 nEnd = 0;
448 // extract language part
449 nEnd = sParser.indexOf(SEPERATOR_LC, nStart);
450 if (nEnd<0)
452 setLanguage(sParser);
453 return;
455 setLanguage(sParser.copy(nStart, nEnd-nStart));
456 nStart = nEnd+1;
458 // extract country
459 nEnd = sParser.indexOf(SEPERATOR_CV, nStart);
460 if (nEnd<0)
461 nEnd = sParser.indexOf(SEPERATOR_CV_LINUX, nStart);
462 if (nEnd<0)
464 setCountry(sParser.copy(nStart, sParser.getLength()-nStart));
465 return;
467 nStart = nEnd+1;
469 // extract variant
470 setVariant(sParser.copy(nStart, sParser.getLength()-nStart));
473 //-----------------------------------------------
474 ::rtl::OUString Locale::toISO() const
476 ::rtl::OUStringBuffer sISO(64);
478 sISO.append(m_sLanguage);
479 if (m_sCountry.getLength())
481 sISO.append(SEPERATOR_LC);
482 sISO.append(m_sCountry);
484 if (m_sVariant.getLength())
486 sISO.append(SEPERATOR_CV);
487 sISO.append(m_sVariant);
491 return sISO.makeStringAndClear();
494 //-----------------------------------------------
495 sal_Bool Locale::equals(const Locale& aComparable) const
497 return (
498 m_sLanguage.equals(aComparable.m_sLanguage) &&
499 m_sCountry.equals (aComparable.m_sCountry ) &&
500 m_sVariant.equals (aComparable.m_sVariant )
504 //-----------------------------------------------
505 sal_Bool Locale::similar(const Locale& aComparable) const
507 return (m_sLanguage.equals(aComparable.m_sLanguage));
510 //-----------------------------------------------
511 ::std::vector< ::rtl::OUString >::const_iterator Locale::getFallback(const ::std::vector< ::rtl::OUString >& lISOList ,
512 const ::rtl::OUString& sReferenceISO)
513 throw(Locale::MalFormedLocaleException)
515 Locale aReference(sReferenceISO);
517 // Note: The same language or "en"/"en-US" should be preferred as fallback.
518 // On the other side some localized variables doesnt use localzation in real.
519 // May be the use a "fix" value only ... marked as X-DEFAULT or X-NOTRANSLATE.
520 // At least it can be discussed, if any language is a valid fallback ...
521 // But in case some office functionality depends on that (that means real functionality instead
522 // of pure UI descriptions) we should do anything, so it can work.
524 ::std::vector< ::rtl::OUString >::const_iterator pSimilar = lISOList.end();
525 ::std::vector< ::rtl::OUString >::const_iterator pEN_US = lISOList.end();
526 ::std::vector< ::rtl::OUString >::const_iterator pEN = lISOList.end();
527 ::std::vector< ::rtl::OUString >::const_iterator pXDefault = lISOList.end();
528 ::std::vector< ::rtl::OUString >::const_iterator pXNoTranslate = lISOList.end();
529 ::std::vector< ::rtl::OUString >::const_iterator pAny = lISOList.end();
531 ::std::vector< ::rtl::OUString >::const_iterator pIt;
532 for ( pIt = lISOList.begin();
533 pIt != lISOList.end() ;
534 ++pIt )
536 Locale aCheck(*pIt);
537 // found Locale, which match with 100% => return it
538 if (aCheck.equals(aReference))
539 return pIt;
541 // found similar Locale => safe it as possible fallback
542 if (
543 (pSimilar == lISOList.end()) &&
544 (aCheck.similar(aReference))
547 pSimilar = pIt;
549 else
550 // found en-US => safe it as fallback
551 if (
552 (pEN_US == lISOList.end()) &&
553 (aCheck.equals(EN_US()) )
556 pEN_US = pIt;
558 else
559 // found en[-XX] => safe it as fallback
560 if (
561 (pEN == lISOList.end() ) &&
562 (aCheck.similar(EN_US()))
565 pEN = pIt;
567 else
568 // found an explicit default value(!) => safe it as fallback
569 if (
570 (pXDefault == lISOList.end()) &&
571 (aCheck.equals(X_DEFAULT()) )
574 pXDefault = pIt;
576 else
577 // found an implicit default value(!) => safe it as fallback
578 if (
579 (pXNoTranslate == lISOList.end()) &&
580 (aCheck.equals(X_NOTRANSLATE()) )
583 pXNoTranslate = pIt;
585 else
586 // safe the first locale, which isn't an explicit fallback
587 // as "last possible fallback"
588 if (pAny == lISOList.end())
589 pAny = pIt;
592 if (pSimilar != lISOList.end())
593 return pSimilar;
595 if (pEN_US != lISOList.end())
596 return pEN_US;
598 if (pEN != lISOList.end())
599 return pEN;
601 if (pXDefault != lISOList.end())
602 return pXDefault;
604 if (pXNoTranslate != lISOList.end())
605 return pXNoTranslate;
607 if (pAny != lISOList.end())
608 return pAny;
610 return lISOList.end();
613 //-----------------------------------------------
614 sal_Bool Locale::getFallback(Locale& aLocale)
616 // a)
617 // this was our last fallback!
618 // break any further calls to this method ...
619 if (aLocale.equals(X_NOTRANSLATE()))
620 return sal_False;
622 // b)
623 // switch from X_DEFAULT to X_NOTRANSLATE
624 // next time we will go to a)
625 if (aLocale.equals(X_DEFAULT()))
627 aLocale = X_NOTRANSLATE();
628 return sal_True;
631 // c)
632 // switch from EN to X_DEFAULT
633 // next time we will go to b)
634 if (aLocale.equals(EN()))
636 aLocale = X_DEFAULT();
637 return sal_True;
640 // d) remove country from incoming locale
641 // e.g. "de-DE" => "de" or "en-US" => "en"!
642 if (aLocale.getCountry().getLength())
644 aLocale.setCountry(::rtl::OUString());
645 return sal_True;
648 // e) "en-US" possible?
649 if (!aLocale.equals(EN_US()))
651 aLocale = EN_US();
652 return sal_True;
655 // f) no more fallbacks
656 return sal_False;
659 //-----------------------------------------------
660 void Locale::operator=(const Locale& rCopy)
662 // Take over these values without checking ...
663 // They was already checked if the copy was constructed
664 // and must be valid now!
665 m_sLanguage = rCopy.m_sLanguage;
666 m_sCountry = rCopy.m_sCountry;
667 m_sVariant = rCopy.m_sVariant;
670 //-----------------------------------------------
671 sal_Bool Locale::operator==(const Locale& aComparable) const
673 return equals(aComparable);
676 //-----------------------------------------------
677 sal_Bool Locale::operator!=(const Locale& aComparable) const
679 return !equals(aComparable);
682 } // namespace comphelper