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 //_______________________________________________
34 #include <rtl/ustrbuf.hxx>
36 //_______________________________________________
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"));
55 //-----------------------------------------------
56 const Locale
Locale::EN()
58 static Locale
aLocale(
59 ::rtl::OUString::createFromAscii("en"),
64 //-----------------------------------------------
65 const Locale
Locale::EN_US()
67 static Locale
aLocale(
68 ::rtl::OUString::createFromAscii("en"),
69 ::rtl::OUString::createFromAscii("US"));
73 //-----------------------------------------------
74 const Locale
Locale::DE_DE()
76 static Locale
aLocale(
77 ::rtl::OUString::createFromAscii("de"),
78 ::rtl::OUString::createFromAscii("DE"));
82 //-----------------------------------------------
83 const Locale
Locale::DE_CH()
85 static Locale
aLocale(
86 ::rtl::OUString::createFromAscii("de"),
87 ::rtl::OUString::createFromAscii("CH"));
91 //-----------------------------------------------
92 const Locale
Locale::DE_AT()
94 static Locale
aLocale(
95 ::rtl::OUString::createFromAscii("de"),
96 ::rtl::OUString::createFromAscii("AT"));
100 //-----------------------------------------------
101 const Locale
Locale::AR()
103 static Locale
aLocale(
104 ::rtl::OUString::createFromAscii("ar"),
109 //-----------------------------------------------
110 const Locale
Locale::CA()
112 static Locale
aLocale(
113 ::rtl::OUString::createFromAscii("ca"),
118 //-----------------------------------------------
119 const Locale
Locale::CS()
121 static Locale
aLocale(
122 ::rtl::OUString::createFromAscii("cs"),
127 //-----------------------------------------------
128 const Locale
Locale::DA()
130 static Locale
aLocale(
131 ::rtl::OUString::createFromAscii("da"),
136 //-----------------------------------------------
137 const Locale
Locale::EL()
139 static Locale
aLocale(
140 ::rtl::OUString::createFromAscii("el"),
145 //-----------------------------------------------
146 const Locale
Locale::ES()
148 static Locale
aLocale(
149 ::rtl::OUString::createFromAscii("es"),
154 //-----------------------------------------------
155 const Locale
Locale::FI()
157 static Locale
aLocale(
158 ::rtl::OUString::createFromAscii("fi"),
163 //-----------------------------------------------
164 const Locale
Locale::FR()
166 static Locale
aLocale(
167 ::rtl::OUString::createFromAscii("fr"),
172 //-----------------------------------------------
173 const Locale
Locale::HE()
175 static Locale
aLocale(
176 ::rtl::OUString::createFromAscii("he"),
181 //-----------------------------------------------
182 const Locale
Locale::HI_IN()
184 static Locale
aLocale(
185 ::rtl::OUString::createFromAscii("hi"),
186 ::rtl::OUString::createFromAscii("IN"));
190 //-----------------------------------------------
191 const Locale
Locale::HU()
193 static Locale
aLocale(
194 ::rtl::OUString::createFromAscii("hu"),
199 //-----------------------------------------------
200 const Locale
Locale::IT()
202 static Locale
aLocale(
203 ::rtl::OUString::createFromAscii("it"),
208 //-----------------------------------------------
209 const Locale
Locale::JA()
211 static Locale
aLocale(
212 ::rtl::OUString::createFromAscii("ja"),
217 //-----------------------------------------------
218 const Locale
Locale::KO()
220 static Locale
aLocale(
221 ::rtl::OUString::createFromAscii("ko"),
226 //-----------------------------------------------
227 const Locale
Locale::NL()
229 static Locale
aLocale(
230 ::rtl::OUString::createFromAscii("nl"),
235 //-----------------------------------------------
236 const Locale
Locale::PL()
238 static Locale
aLocale(
239 ::rtl::OUString::createFromAscii("pl"),
244 //-----------------------------------------------
245 const Locale
Locale::PT()
247 static Locale
aLocale(
248 ::rtl::OUString::createFromAscii("pt"),
253 //-----------------------------------------------
254 const Locale
Locale::PT_BR()
256 static Locale
aLocale(
257 ::rtl::OUString::createFromAscii("pt"),
258 ::rtl::OUString::createFromAscii("BR"));
262 //-----------------------------------------------
263 const Locale
Locale::RU()
265 static Locale
aLocale(
266 ::rtl::OUString::createFromAscii("ru"),
271 //-----------------------------------------------
272 const Locale
Locale::SK()
274 static Locale
aLocale(
275 ::rtl::OUString::createFromAscii("sk"),
280 //-----------------------------------------------
281 const Locale
Locale::SL()
283 static Locale
aLocale(
284 ::rtl::OUString::createFromAscii("sl"),
289 //-----------------------------------------------
290 const Locale
Locale::SV()
292 static Locale
aLocale(
293 ::rtl::OUString::createFromAscii("sv"),
298 //-----------------------------------------------
299 const Locale
Locale::TH()
301 static Locale
aLocale(
302 ::rtl::OUString::createFromAscii("th"),
307 //-----------------------------------------------
308 const Locale
Locale::TR()
310 static Locale
aLocale(
311 ::rtl::OUString::createFromAscii("tr"),
316 //-----------------------------------------------
317 const Locale
Locale::X_COMMENT()
319 static Locale
aLocale(
320 ::rtl::OUString::createFromAscii("x"),
321 ::rtl::OUString::createFromAscii("comment"));
325 //-----------------------------------------------
326 const Locale
Locale::X_TRANSLATE()
328 static Locale
aLocale(
329 ::rtl::OUString::createFromAscii("x"),
330 ::rtl::OUString::createFromAscii("translate"));
334 //-----------------------------------------------
335 const Locale
Locale::X_NOTRANSLATE()
337 static Locale
aLocale(
338 ::rtl::OUString::createFromAscii("x"),
339 ::rtl::OUString::createFromAscii("notranslate"));
343 //-----------------------------------------------
344 const Locale
Locale::ZH_CN()
346 static Locale
aLocale(
347 ::rtl::OUString::createFromAscii("zh"),
348 ::rtl::OUString::createFromAscii("CN"));
352 //-----------------------------------------------
353 const Locale
Locale::ZH_TW()
355 static Locale
aLocale(
356 ::rtl::OUString::createFromAscii("zh"),
357 ::rtl::OUString::createFromAscii("TW"));
361 //-----------------------------------------------
362 Locale::Locale(const ::rtl::OUString
& sISO
)
363 throw(Locale::MalFormedLocaleException
)
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 //-----------------------------------------------
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
399 //-----------------------------------------------
400 ::rtl::OUString
Locale::getCountry() const
405 //-----------------------------------------------
406 ::rtl::OUString
Locale::getVariant() const
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
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
);
445 sal_Int32 nStart
= 0;
448 // extract language part
449 nEnd
= sParser
.indexOf(SEPERATOR_LC
, nStart
);
452 setLanguage(sParser
);
455 setLanguage(sParser
.copy(nStart
, nEnd
-nStart
));
459 nEnd
= sParser
.indexOf(SEPERATOR_CV
, nStart
);
461 nEnd
= sParser
.indexOf(SEPERATOR_CV_LINUX
, nStart
);
464 setCountry(sParser
.copy(nStart
, sParser
.getLength()-nStart
));
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
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() ;
537 // found Locale, which match with 100% => return it
538 if (aCheck
.equals(aReference
))
541 // found similar Locale => safe it as possible fallback
543 (pSimilar
== lISOList
.end()) &&
544 (aCheck
.similar(aReference
))
550 // found en-US => safe it as fallback
552 (pEN_US
== lISOList
.end()) &&
553 (aCheck
.equals(EN_US()) )
559 // found en[-XX] => safe it as fallback
561 (pEN
== lISOList
.end() ) &&
562 (aCheck
.similar(EN_US()))
568 // found an explicit default value(!) => safe it as fallback
570 (pXDefault
== lISOList
.end()) &&
571 (aCheck
.equals(X_DEFAULT()) )
577 // found an implicit default value(!) => safe it as fallback
579 (pXNoTranslate
== lISOList
.end()) &&
580 (aCheck
.equals(X_NOTRANSLATE()) )
586 // safe the first locale, which isn't an explicit fallback
587 // as "last possible fallback"
588 if (pAny
== lISOList
.end())
592 if (pSimilar
!= lISOList
.end())
595 if (pEN_US
!= lISOList
.end())
598 if (pEN
!= lISOList
.end())
601 if (pXDefault
!= lISOList
.end())
604 if (pXNoTranslate
!= lISOList
.end())
605 return pXNoTranslate
;
607 if (pAny
!= lISOList
.end())
610 return lISOList
.end();
613 //-----------------------------------------------
614 sal_Bool
Locale::getFallback(Locale
& aLocale
)
617 // this was our last fallback!
618 // break any further calls to this method ...
619 if (aLocale
.equals(X_NOTRANSLATE()))
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();
632 // switch from EN to X_DEFAULT
633 // next time we will go to b)
634 if (aLocale
.equals(EN()))
636 aLocale
= X_DEFAULT();
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());
648 // e) "en-US" possible?
649 if (!aLocale
.equals(EN_US()))
655 // f) no more fallbacks
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