1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: locale.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_comphelper.hxx"
33 #include <comphelper/locale.hxx>
35 //_______________________________________________
37 #include <rtl/ustrbuf.hxx>
39 //_______________________________________________
44 //-----------------------------------------------
45 const sal_Unicode
Locale::SEPERATOR_LC
= (sal_Unicode
)'-';
46 const sal_Unicode
Locale::SEPERATOR_CV
= (sal_Unicode
)'_';
47 const sal_Unicode
Locale::SEPERATOR_CV_LINUX
= (sal_Unicode
)'.';
49 //-----------------------------------------------
50 const Locale
Locale::X_DEFAULT()
52 static Locale
aLocale(
53 ::rtl::OUString::createFromAscii("x"),
54 ::rtl::OUString::createFromAscii("default"));
58 //-----------------------------------------------
59 const Locale
Locale::EN()
61 static Locale
aLocale(
62 ::rtl::OUString::createFromAscii("en"),
67 //-----------------------------------------------
68 const Locale
Locale::EN_US()
70 static Locale
aLocale(
71 ::rtl::OUString::createFromAscii("en"),
72 ::rtl::OUString::createFromAscii("US"));
76 //-----------------------------------------------
77 const Locale
Locale::DE_DE()
79 static Locale
aLocale(
80 ::rtl::OUString::createFromAscii("de"),
81 ::rtl::OUString::createFromAscii("DE"));
85 //-----------------------------------------------
86 const Locale
Locale::DE_CH()
88 static Locale
aLocale(
89 ::rtl::OUString::createFromAscii("de"),
90 ::rtl::OUString::createFromAscii("CH"));
94 //-----------------------------------------------
95 const Locale
Locale::DE_AT()
97 static Locale
aLocale(
98 ::rtl::OUString::createFromAscii("de"),
99 ::rtl::OUString::createFromAscii("AT"));
103 //-----------------------------------------------
104 const Locale
Locale::AR()
106 static Locale
aLocale(
107 ::rtl::OUString::createFromAscii("ar"),
112 //-----------------------------------------------
113 const Locale
Locale::CA()
115 static Locale
aLocale(
116 ::rtl::OUString::createFromAscii("ca"),
121 //-----------------------------------------------
122 const Locale
Locale::CS()
124 static Locale
aLocale(
125 ::rtl::OUString::createFromAscii("cs"),
130 //-----------------------------------------------
131 const Locale
Locale::DA()
133 static Locale
aLocale(
134 ::rtl::OUString::createFromAscii("da"),
139 //-----------------------------------------------
140 const Locale
Locale::EL()
142 static Locale
aLocale(
143 ::rtl::OUString::createFromAscii("el"),
148 //-----------------------------------------------
149 const Locale
Locale::ES()
151 static Locale
aLocale(
152 ::rtl::OUString::createFromAscii("es"),
157 //-----------------------------------------------
158 const Locale
Locale::FI()
160 static Locale
aLocale(
161 ::rtl::OUString::createFromAscii("fi"),
166 //-----------------------------------------------
167 const Locale
Locale::FR()
169 static Locale
aLocale(
170 ::rtl::OUString::createFromAscii("fr"),
175 //-----------------------------------------------
176 const Locale
Locale::HE()
178 static Locale
aLocale(
179 ::rtl::OUString::createFromAscii("he"),
184 //-----------------------------------------------
185 const Locale
Locale::HI_IN()
187 static Locale
aLocale(
188 ::rtl::OUString::createFromAscii("hi"),
189 ::rtl::OUString::createFromAscii("IN"));
193 //-----------------------------------------------
194 const Locale
Locale::HU()
196 static Locale
aLocale(
197 ::rtl::OUString::createFromAscii("hu"),
202 //-----------------------------------------------
203 const Locale
Locale::IT()
205 static Locale
aLocale(
206 ::rtl::OUString::createFromAscii("it"),
211 //-----------------------------------------------
212 const Locale
Locale::JA()
214 static Locale
aLocale(
215 ::rtl::OUString::createFromAscii("ja"),
220 //-----------------------------------------------
221 const Locale
Locale::KO()
223 static Locale
aLocale(
224 ::rtl::OUString::createFromAscii("ko"),
229 //-----------------------------------------------
230 const Locale
Locale::NL()
232 static Locale
aLocale(
233 ::rtl::OUString::createFromAscii("nl"),
238 //-----------------------------------------------
239 const Locale
Locale::PL()
241 static Locale
aLocale(
242 ::rtl::OUString::createFromAscii("pl"),
247 //-----------------------------------------------
248 const Locale
Locale::PT()
250 static Locale
aLocale(
251 ::rtl::OUString::createFromAscii("pt"),
256 //-----------------------------------------------
257 const Locale
Locale::PT_BR()
259 static Locale
aLocale(
260 ::rtl::OUString::createFromAscii("pt"),
261 ::rtl::OUString::createFromAscii("BR"));
265 //-----------------------------------------------
266 const Locale
Locale::RU()
268 static Locale
aLocale(
269 ::rtl::OUString::createFromAscii("ru"),
274 //-----------------------------------------------
275 const Locale
Locale::SK()
277 static Locale
aLocale(
278 ::rtl::OUString::createFromAscii("sk"),
283 //-----------------------------------------------
284 const Locale
Locale::SL()
286 static Locale
aLocale(
287 ::rtl::OUString::createFromAscii("sl"),
292 //-----------------------------------------------
293 const Locale
Locale::SV()
295 static Locale
aLocale(
296 ::rtl::OUString::createFromAscii("sv"),
301 //-----------------------------------------------
302 const Locale
Locale::TH()
304 static Locale
aLocale(
305 ::rtl::OUString::createFromAscii("th"),
310 //-----------------------------------------------
311 const Locale
Locale::TR()
313 static Locale
aLocale(
314 ::rtl::OUString::createFromAscii("tr"),
319 //-----------------------------------------------
320 const Locale
Locale::X_COMMENT()
322 static Locale
aLocale(
323 ::rtl::OUString::createFromAscii("x"),
324 ::rtl::OUString::createFromAscii("comment"));
328 //-----------------------------------------------
329 const Locale
Locale::X_TRANSLATE()
331 static Locale
aLocale(
332 ::rtl::OUString::createFromAscii("x"),
333 ::rtl::OUString::createFromAscii("translate"));
337 //-----------------------------------------------
338 const Locale
Locale::X_NOTRANSLATE()
340 static Locale
aLocale(
341 ::rtl::OUString::createFromAscii("x"),
342 ::rtl::OUString::createFromAscii("notranslate"));
346 //-----------------------------------------------
347 const Locale
Locale::ZH_CN()
349 static Locale
aLocale(
350 ::rtl::OUString::createFromAscii("zh"),
351 ::rtl::OUString::createFromAscii("CN"));
355 //-----------------------------------------------
356 const Locale
Locale::ZH_TW()
358 static Locale
aLocale(
359 ::rtl::OUString::createFromAscii("zh"),
360 ::rtl::OUString::createFromAscii("TW"));
364 //-----------------------------------------------
365 Locale::Locale(const ::rtl::OUString
& sISO
)
366 throw(Locale::MalFormedLocaleException
)
371 //-----------------------------------------------
372 Locale::Locale(const ::rtl::OUString
& sLanguage
,
373 const ::rtl::OUString
& sCountry
,
374 const ::rtl::OUString
& sVariant
)
376 // Use set methods to check values too!
377 setLanguage(sLanguage
);
378 setCountry (sCountry
);
379 setVariant (sVariant
);
382 //-----------------------------------------------
385 // Initialize instance ... otherwhise user will
386 // may be get exceptions if he e.g. copy this instance ...
387 (*this) = X_NOTRANSLATE();
390 //-----------------------------------------------
391 Locale::Locale(const Locale
& aCopy
)
393 (*this) = aCopy
; // recycle assign operator
396 //-----------------------------------------------
397 ::rtl::OUString
Locale::getLanguage() const
402 //-----------------------------------------------
403 ::rtl::OUString
Locale::getCountry() const
408 //-----------------------------------------------
409 ::rtl::OUString
Locale::getVariant() const
414 //-----------------------------------------------
415 void Locale::setLanguage(const ::rtl::OUString
& sLanguage
)
417 m_sLanguage
= sLanguage
;
420 //-----------------------------------------------
421 void Locale::setCountry(const ::rtl::OUString
& sCountry
)
423 m_sCountry
= sCountry
;
426 //-----------------------------------------------
427 void Locale::setVariant(const ::rtl::OUString
& sVariant
)
429 m_sVariant
= sVariant
;
432 //-----------------------------------------------
433 /* Attention: Use own interface methods to set the
434 different parts of this locale. Because the
435 check the incoming value and throw an exception
438 void Locale::fromISO(const ::rtl::OUString
& sISO
)
439 throw(Locale::MalFormedLocaleException
)
441 m_sLanguage
= ::rtl::OUString();
442 m_sCountry
= ::rtl::OUString();
443 m_sVariant
= ::rtl::OUString();
445 ::rtl::OUString
sParser(sISO
);
448 sal_Int32 nStart
= 0;
451 // extract language part
452 nEnd
= sParser
.indexOf(SEPERATOR_LC
, nStart
);
455 setLanguage(sParser
);
458 setLanguage(sParser
.copy(nStart
, nEnd
-nStart
));
462 nEnd
= sParser
.indexOf(SEPERATOR_CV
, nStart
);
464 nEnd
= sParser
.indexOf(SEPERATOR_CV_LINUX
, nStart
);
467 setCountry(sParser
.copy(nStart
, sParser
.getLength()-nStart
));
473 setVariant(sParser
.copy(nStart
, sParser
.getLength()-nStart
));
476 //-----------------------------------------------
477 ::rtl::OUString
Locale::toISO() const
479 ::rtl::OUStringBuffer
sISO(64);
481 sISO
.append(m_sLanguage
);
482 if (m_sCountry
.getLength())
484 sISO
.append(SEPERATOR_LC
);
485 sISO
.append(m_sCountry
);
487 if (m_sVariant
.getLength())
489 sISO
.append(SEPERATOR_CV
);
490 sISO
.append(m_sVariant
);
494 return sISO
.makeStringAndClear();
497 //-----------------------------------------------
498 sal_Bool
Locale::equals(const Locale
& aComparable
) const
501 m_sLanguage
.equals(aComparable
.m_sLanguage
) &&
502 m_sCountry
.equals (aComparable
.m_sCountry
) &&
503 m_sVariant
.equals (aComparable
.m_sVariant
)
507 //-----------------------------------------------
508 sal_Bool
Locale::similar(const Locale
& aComparable
) const
510 return (m_sLanguage
.equals(aComparable
.m_sLanguage
));
513 //-----------------------------------------------
514 ::std::vector
< ::rtl::OUString
>::const_iterator
Locale::getFallback(const ::std::vector
< ::rtl::OUString
>& lISOList
,
515 const ::rtl::OUString
& sReferenceISO
)
516 throw(Locale::MalFormedLocaleException
)
518 Locale
aReference(sReferenceISO
);
520 // Note: The same language or "en"/"en-US" should be preferred as fallback.
521 // On the other side some localized variables doesnt use localzation in real.
522 // May be the use a "fix" value only ... marked as X-DEFAULT or X-NOTRANSLATE.
523 // At least it can be discussed, if any language is a valid fallback ...
524 // But in case some office functionality depends on that (that means real functionality instead
525 // of pure UI descriptions) we should do anything, so it can work.
527 ::std::vector
< ::rtl::OUString
>::const_iterator pSimilar
= lISOList
.end();
528 ::std::vector
< ::rtl::OUString
>::const_iterator pEN_US
= lISOList
.end();
529 ::std::vector
< ::rtl::OUString
>::const_iterator pEN
= lISOList
.end();
530 ::std::vector
< ::rtl::OUString
>::const_iterator pXDefault
= lISOList
.end();
531 ::std::vector
< ::rtl::OUString
>::const_iterator pXNoTranslate
= lISOList
.end();
532 ::std::vector
< ::rtl::OUString
>::const_iterator pAny
= lISOList
.end();
534 ::std::vector
< ::rtl::OUString
>::const_iterator pIt
;
535 for ( pIt
= lISOList
.begin();
536 pIt
!= lISOList
.end() ;
540 // found Locale, which match with 100% => return it
541 if (aCheck
.equals(aReference
))
544 // found similar Locale => safe it as possible fallback
546 (pSimilar
== lISOList
.end()) &&
547 (aCheck
.similar(aReference
))
553 // found en-US => safe it as fallback
555 (pEN_US
== lISOList
.end()) &&
556 (aCheck
.equals(EN_US()) )
562 // found en[-XX] => safe it as fallback
564 (pEN
== lISOList
.end() ) &&
565 (aCheck
.similar(EN_US()))
571 // found an explicit default value(!) => safe it as fallback
573 (pXDefault
== lISOList
.end()) &&
574 (aCheck
.equals(X_DEFAULT()) )
580 // found an implicit default value(!) => safe it as fallback
582 (pXNoTranslate
== lISOList
.end()) &&
583 (aCheck
.equals(X_NOTRANSLATE()) )
589 // safe the first locale, which isn't an explicit fallback
590 // as "last possible fallback"
591 if (pAny
== lISOList
.end())
595 if (pSimilar
!= lISOList
.end())
598 if (pEN_US
!= lISOList
.end())
601 if (pEN
!= lISOList
.end())
604 if (pXDefault
!= lISOList
.end())
607 if (pXNoTranslate
!= lISOList
.end())
608 return pXNoTranslate
;
610 if (pAny
!= lISOList
.end())
613 return lISOList
.end();
616 //-----------------------------------------------
617 sal_Bool
Locale::getFallback(Locale
& aLocale
)
620 // this was our last fallback!
621 // break any further calls to this method ...
622 if (aLocale
.equals(X_NOTRANSLATE()))
626 // switch from X_DEFAULT to X_NOTRANSLATE
627 // next time we will go to a)
628 if (aLocale
.equals(X_DEFAULT()))
630 aLocale
= X_NOTRANSLATE();
635 // switch from EN to X_DEFAULT
636 // next time we will go to b)
637 if (aLocale
.equals(EN()))
639 aLocale
= X_DEFAULT();
643 // d) remove country from incoming locale
644 // e.g. "de-DE" => "de" or "en-US" => "en"!
645 if (aLocale
.getCountry().getLength())
647 aLocale
.setCountry(::rtl::OUString());
651 // e) "en-US" possible?
652 if (!aLocale
.equals(EN_US()))
658 // f) no more fallbacks
662 //-----------------------------------------------
663 void Locale::operator=(const Locale
& rCopy
)
665 // Take over these values without checking ...
666 // They was already checked if the copy was constructed
667 // and must be valid now!
668 m_sLanguage
= rCopy
.m_sLanguage
;
669 m_sCountry
= rCopy
.m_sCountry
;
670 m_sVariant
= rCopy
.m_sVariant
;
673 //-----------------------------------------------
674 sal_Bool
Locale::operator==(const Locale
& aComparable
) const
676 return equals(aComparable
);
679 //-----------------------------------------------
680 sal_Bool
Locale::operator!=(const Locale
& aComparable
) const
682 return !equals(aComparable
);
685 } // namespace comphelper