merge the formfield patch from ooo-build
[ooovba.git] / comphelper / source / misc / locale.cxx
blob192d31ced501d839ead956e65017bb0dc9e035c5
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: locale.cxx,v $
10 * $Revision: 1.8 $
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 //_______________________________________________
36 // includes
37 #include <rtl/ustrbuf.hxx>
39 //_______________________________________________
40 // namespace
42 namespace comphelper{
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"));
55 return aLocale;
58 //-----------------------------------------------
59 const Locale Locale::EN()
61 static Locale aLocale(
62 ::rtl::OUString::createFromAscii("en"),
63 ::rtl::OUString());
64 return aLocale;
67 //-----------------------------------------------
68 const Locale Locale::EN_US()
70 static Locale aLocale(
71 ::rtl::OUString::createFromAscii("en"),
72 ::rtl::OUString::createFromAscii("US"));
73 return aLocale;
76 //-----------------------------------------------
77 const Locale Locale::DE_DE()
79 static Locale aLocale(
80 ::rtl::OUString::createFromAscii("de"),
81 ::rtl::OUString::createFromAscii("DE"));
82 return aLocale;
85 //-----------------------------------------------
86 const Locale Locale::DE_CH()
88 static Locale aLocale(
89 ::rtl::OUString::createFromAscii("de"),
90 ::rtl::OUString::createFromAscii("CH"));
91 return aLocale;
94 //-----------------------------------------------
95 const Locale Locale::DE_AT()
97 static Locale aLocale(
98 ::rtl::OUString::createFromAscii("de"),
99 ::rtl::OUString::createFromAscii("AT"));
100 return aLocale;
103 //-----------------------------------------------
104 const Locale Locale::AR()
106 static Locale aLocale(
107 ::rtl::OUString::createFromAscii("ar"),
108 ::rtl::OUString());
109 return aLocale;
112 //-----------------------------------------------
113 const Locale Locale::CA()
115 static Locale aLocale(
116 ::rtl::OUString::createFromAscii("ca"),
117 ::rtl::OUString());
118 return aLocale;
121 //-----------------------------------------------
122 const Locale Locale::CS()
124 static Locale aLocale(
125 ::rtl::OUString::createFromAscii("cs"),
126 ::rtl::OUString());
127 return aLocale;
130 //-----------------------------------------------
131 const Locale Locale::DA()
133 static Locale aLocale(
134 ::rtl::OUString::createFromAscii("da"),
135 ::rtl::OUString());
136 return aLocale;
139 //-----------------------------------------------
140 const Locale Locale::EL()
142 static Locale aLocale(
143 ::rtl::OUString::createFromAscii("el"),
144 ::rtl::OUString());
145 return aLocale;
148 //-----------------------------------------------
149 const Locale Locale::ES()
151 static Locale aLocale(
152 ::rtl::OUString::createFromAscii("es"),
153 ::rtl::OUString());
154 return aLocale;
157 //-----------------------------------------------
158 const Locale Locale::FI()
160 static Locale aLocale(
161 ::rtl::OUString::createFromAscii("fi"),
162 ::rtl::OUString());
163 return aLocale;
166 //-----------------------------------------------
167 const Locale Locale::FR()
169 static Locale aLocale(
170 ::rtl::OUString::createFromAscii("fr"),
171 ::rtl::OUString());
172 return aLocale;
175 //-----------------------------------------------
176 const Locale Locale::HE()
178 static Locale aLocale(
179 ::rtl::OUString::createFromAscii("he"),
180 ::rtl::OUString());
181 return aLocale;
184 //-----------------------------------------------
185 const Locale Locale::HI_IN()
187 static Locale aLocale(
188 ::rtl::OUString::createFromAscii("hi"),
189 ::rtl::OUString::createFromAscii("IN"));
190 return aLocale;
193 //-----------------------------------------------
194 const Locale Locale::HU()
196 static Locale aLocale(
197 ::rtl::OUString::createFromAscii("hu"),
198 ::rtl::OUString());
199 return aLocale;
202 //-----------------------------------------------
203 const Locale Locale::IT()
205 static Locale aLocale(
206 ::rtl::OUString::createFromAscii("it"),
207 ::rtl::OUString());
208 return aLocale;
211 //-----------------------------------------------
212 const Locale Locale::JA()
214 static Locale aLocale(
215 ::rtl::OUString::createFromAscii("ja"),
216 ::rtl::OUString());
217 return aLocale;
220 //-----------------------------------------------
221 const Locale Locale::KO()
223 static Locale aLocale(
224 ::rtl::OUString::createFromAscii("ko"),
225 ::rtl::OUString());
226 return aLocale;
229 //-----------------------------------------------
230 const Locale Locale::NL()
232 static Locale aLocale(
233 ::rtl::OUString::createFromAscii("nl"),
234 ::rtl::OUString());
235 return aLocale;
238 //-----------------------------------------------
239 const Locale Locale::PL()
241 static Locale aLocale(
242 ::rtl::OUString::createFromAscii("pl"),
243 ::rtl::OUString());
244 return aLocale;
247 //-----------------------------------------------
248 const Locale Locale::PT()
250 static Locale aLocale(
251 ::rtl::OUString::createFromAscii("pt"),
252 ::rtl::OUString());
253 return aLocale;
256 //-----------------------------------------------
257 const Locale Locale::PT_BR()
259 static Locale aLocale(
260 ::rtl::OUString::createFromAscii("pt"),
261 ::rtl::OUString::createFromAscii("BR"));
262 return aLocale;
265 //-----------------------------------------------
266 const Locale Locale::RU()
268 static Locale aLocale(
269 ::rtl::OUString::createFromAscii("ru"),
270 ::rtl::OUString());
271 return aLocale;
274 //-----------------------------------------------
275 const Locale Locale::SK()
277 static Locale aLocale(
278 ::rtl::OUString::createFromAscii("sk"),
279 ::rtl::OUString());
280 return aLocale;
283 //-----------------------------------------------
284 const Locale Locale::SL()
286 static Locale aLocale(
287 ::rtl::OUString::createFromAscii("sl"),
288 ::rtl::OUString());
289 return aLocale;
292 //-----------------------------------------------
293 const Locale Locale::SV()
295 static Locale aLocale(
296 ::rtl::OUString::createFromAscii("sv"),
297 ::rtl::OUString());
298 return aLocale;
301 //-----------------------------------------------
302 const Locale Locale::TH()
304 static Locale aLocale(
305 ::rtl::OUString::createFromAscii("th"),
306 ::rtl::OUString());
307 return aLocale;
310 //-----------------------------------------------
311 const Locale Locale::TR()
313 static Locale aLocale(
314 ::rtl::OUString::createFromAscii("tr"),
315 ::rtl::OUString());
316 return aLocale;
319 //-----------------------------------------------
320 const Locale Locale::X_COMMENT()
322 static Locale aLocale(
323 ::rtl::OUString::createFromAscii("x"),
324 ::rtl::OUString::createFromAscii("comment"));
325 return aLocale;
328 //-----------------------------------------------
329 const Locale Locale::X_TRANSLATE()
331 static Locale aLocale(
332 ::rtl::OUString::createFromAscii("x"),
333 ::rtl::OUString::createFromAscii("translate"));
334 return aLocale;
337 //-----------------------------------------------
338 const Locale Locale::X_NOTRANSLATE()
340 static Locale aLocale(
341 ::rtl::OUString::createFromAscii("x"),
342 ::rtl::OUString::createFromAscii("notranslate"));
343 return aLocale;
346 //-----------------------------------------------
347 const Locale Locale::ZH_CN()
349 static Locale aLocale(
350 ::rtl::OUString::createFromAscii("zh"),
351 ::rtl::OUString::createFromAscii("CN"));
352 return aLocale;
355 //-----------------------------------------------
356 const Locale Locale::ZH_TW()
358 static Locale aLocale(
359 ::rtl::OUString::createFromAscii("zh"),
360 ::rtl::OUString::createFromAscii("TW"));
361 return aLocale;
364 //-----------------------------------------------
365 Locale::Locale(const ::rtl::OUString& sISO)
366 throw(Locale::MalFormedLocaleException)
368 fromISO(sISO);
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 //-----------------------------------------------
383 Locale::Locale()
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
399 return m_sLanguage;
402 //-----------------------------------------------
403 ::rtl::OUString Locale::getCountry() const
405 return m_sCountry;
408 //-----------------------------------------------
409 ::rtl::OUString Locale::getVariant() const
411 return m_sVariant;
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
436 automaticly ...
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);
446 sParser.trim();
448 sal_Int32 nStart = 0;
449 sal_Int32 nEnd = 0;
451 // extract language part
452 nEnd = sParser.indexOf(SEPERATOR_LC, nStart);
453 if (nEnd<0)
455 setLanguage(sParser);
456 return;
458 setLanguage(sParser.copy(nStart, nEnd-nStart));
459 nStart = nEnd+1;
461 // extract country
462 nEnd = sParser.indexOf(SEPERATOR_CV, nStart);
463 if (nEnd<0)
464 nEnd = sParser.indexOf(SEPERATOR_CV_LINUX, nStart);
465 if (nEnd<0)
467 setCountry(sParser.copy(nStart, sParser.getLength()-nStart));
468 return;
470 nStart = nEnd+1;
472 // extract variant
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
500 return (
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() ;
537 ++pIt )
539 Locale aCheck(*pIt);
540 // found Locale, which match with 100% => return it
541 if (aCheck.equals(aReference))
542 return pIt;
544 // found similar Locale => safe it as possible fallback
545 if (
546 (pSimilar == lISOList.end()) &&
547 (aCheck.similar(aReference))
550 pSimilar = pIt;
552 else
553 // found en-US => safe it as fallback
554 if (
555 (pEN_US == lISOList.end()) &&
556 (aCheck.equals(EN_US()) )
559 pEN_US = pIt;
561 else
562 // found en[-XX] => safe it as fallback
563 if (
564 (pEN == lISOList.end() ) &&
565 (aCheck.similar(EN_US()))
568 pEN = pIt;
570 else
571 // found an explicit default value(!) => safe it as fallback
572 if (
573 (pXDefault == lISOList.end()) &&
574 (aCheck.equals(X_DEFAULT()) )
577 pXDefault = pIt;
579 else
580 // found an implicit default value(!) => safe it as fallback
581 if (
582 (pXNoTranslate == lISOList.end()) &&
583 (aCheck.equals(X_NOTRANSLATE()) )
586 pXNoTranslate = pIt;
588 else
589 // safe the first locale, which isn't an explicit fallback
590 // as "last possible fallback"
591 if (pAny == lISOList.end())
592 pAny = pIt;
595 if (pSimilar != lISOList.end())
596 return pSimilar;
598 if (pEN_US != lISOList.end())
599 return pEN_US;
601 if (pEN != lISOList.end())
602 return pEN;
604 if (pXDefault != lISOList.end())
605 return pXDefault;
607 if (pXNoTranslate != lISOList.end())
608 return pXNoTranslate;
610 if (pAny != lISOList.end())
611 return pAny;
613 return lISOList.end();
616 //-----------------------------------------------
617 sal_Bool Locale::getFallback(Locale& aLocale)
619 // a)
620 // this was our last fallback!
621 // break any further calls to this method ...
622 if (aLocale.equals(X_NOTRANSLATE()))
623 return sal_False;
625 // b)
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();
631 return sal_True;
634 // c)
635 // switch from EN to X_DEFAULT
636 // next time we will go to b)
637 if (aLocale.equals(EN()))
639 aLocale = X_DEFAULT();
640 return sal_True;
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());
648 return sal_True;
651 // e) "en-US" possible?
652 if (!aLocale.equals(EN_US()))
654 aLocale = EN_US();
655 return sal_True;
658 // f) no more fallbacks
659 return sal_False;
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