summaryrefslogtreecommitdiff
path: root/comphelper/source/misc/locale.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'comphelper/source/misc/locale.cxx')
-rw-r--r--comphelper/source/misc/locale.cxx683
1 files changed, 683 insertions, 0 deletions
diff --git a/comphelper/source/misc/locale.cxx b/comphelper/source/misc/locale.cxx
new file mode 100644
index 000000000000..53c53f1c3c48
--- /dev/null
+++ b/comphelper/source/misc/locale.cxx
@@ -0,0 +1,683 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_comphelper.hxx"
+#include <comphelper/locale.hxx>
+
+//_______________________________________________
+// includes
+#include <rtl/ustrbuf.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace comphelper{
+
+//-----------------------------------------------
+const sal_Unicode Locale::SEPERATOR_LC = (sal_Unicode)'-';
+const sal_Unicode Locale::SEPERATOR_CV = (sal_Unicode)'_';
+const sal_Unicode Locale::SEPERATOR_CV_LINUX = (sal_Unicode)'.';
+
+//-----------------------------------------------
+const Locale Locale::X_DEFAULT()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("x"),
+ ::rtl::OUString::createFromAscii("default"));
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::EN()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("en"),
+ ::rtl::OUString());
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::EN_US()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("en"),
+ ::rtl::OUString::createFromAscii("US"));
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::DE_DE()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("de"),
+ ::rtl::OUString::createFromAscii("DE"));
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::DE_CH()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("de"),
+ ::rtl::OUString::createFromAscii("CH"));
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::DE_AT()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("de"),
+ ::rtl::OUString::createFromAscii("AT"));
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::AR()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("ar"),
+ ::rtl::OUString());
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::CA()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("ca"),
+ ::rtl::OUString());
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::CS()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("cs"),
+ ::rtl::OUString());
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::DA()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("da"),
+ ::rtl::OUString());
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::EL()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("el"),
+ ::rtl::OUString());
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::ES()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("es"),
+ ::rtl::OUString());
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::FI()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("fi"),
+ ::rtl::OUString());
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::FR()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("fr"),
+ ::rtl::OUString());
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::HE()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("he"),
+ ::rtl::OUString());
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::HI_IN()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("hi"),
+ ::rtl::OUString::createFromAscii("IN"));
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::HU()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("hu"),
+ ::rtl::OUString());
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::IT()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("it"),
+ ::rtl::OUString());
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::JA()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("ja"),
+ ::rtl::OUString());
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::KO()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("ko"),
+ ::rtl::OUString());
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::NL()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("nl"),
+ ::rtl::OUString());
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::PL()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("pl"),
+ ::rtl::OUString());
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::PT()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("pt"),
+ ::rtl::OUString());
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::PT_BR()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("pt"),
+ ::rtl::OUString::createFromAscii("BR"));
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::RU()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("ru"),
+ ::rtl::OUString());
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::SK()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("sk"),
+ ::rtl::OUString());
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::SL()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("sl"),
+ ::rtl::OUString());
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::SV()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("sv"),
+ ::rtl::OUString());
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::TH()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("th"),
+ ::rtl::OUString());
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::TR()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("tr"),
+ ::rtl::OUString());
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::X_COMMENT()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("x"),
+ ::rtl::OUString::createFromAscii("comment"));
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::X_TRANSLATE()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("x"),
+ ::rtl::OUString::createFromAscii("translate"));
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::X_NOTRANSLATE()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("x"),
+ ::rtl::OUString::createFromAscii("notranslate"));
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::ZH_CN()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("zh"),
+ ::rtl::OUString::createFromAscii("CN"));
+ return aLocale;
+}
+
+//-----------------------------------------------
+const Locale Locale::ZH_TW()
+{
+ static Locale aLocale(
+ ::rtl::OUString::createFromAscii("zh"),
+ ::rtl::OUString::createFromAscii("TW"));
+ return aLocale;
+}
+
+//-----------------------------------------------
+Locale::Locale(const ::rtl::OUString& sISO)
+ throw(Locale::MalFormedLocaleException)
+{
+ fromISO(sISO);
+}
+
+//-----------------------------------------------
+Locale::Locale(const ::rtl::OUString& sLanguage,
+ const ::rtl::OUString& sCountry ,
+ const ::rtl::OUString& sVariant )
+{
+ // Use set methods to check values too!
+ setLanguage(sLanguage);
+ setCountry (sCountry );
+ setVariant (sVariant );
+}
+
+//-----------------------------------------------
+Locale::Locale()
+{
+ // Initialize instance ... otherwhise user will
+ // may be get exceptions if he e.g. copy this instance ...
+ (*this) = X_NOTRANSLATE();
+}
+
+//-----------------------------------------------
+Locale::Locale(const Locale& aCopy)
+{
+ (*this) = aCopy; // recycle assign operator
+}
+
+//-----------------------------------------------
+::rtl::OUString Locale::getLanguage() const
+{
+ return m_sLanguage;
+}
+
+//-----------------------------------------------
+::rtl::OUString Locale::getCountry() const
+{
+ return m_sCountry;
+}
+
+//-----------------------------------------------
+::rtl::OUString Locale::getVariant() const
+{
+ return m_sVariant;
+}
+
+//-----------------------------------------------
+void Locale::setLanguage(const ::rtl::OUString& sLanguage)
+{
+ m_sLanguage = sLanguage;
+}
+
+//-----------------------------------------------
+void Locale::setCountry(const ::rtl::OUString& sCountry)
+{
+ m_sCountry = sCountry;
+}
+
+//-----------------------------------------------
+void Locale::setVariant(const ::rtl::OUString& sVariant)
+{
+ m_sVariant = sVariant;
+}
+
+//-----------------------------------------------
+/* Attention: Use own interface methods to set the
+ different parts of this locale. Because the
+ check the incoming value and throw an exception
+ automaticly ...
+ */
+void Locale::fromISO(const ::rtl::OUString& sISO)
+ throw(Locale::MalFormedLocaleException)
+{
+ m_sLanguage = ::rtl::OUString();
+ m_sCountry = ::rtl::OUString();
+ m_sVariant = ::rtl::OUString();
+
+ ::rtl::OUString sParser(sISO);
+ sParser.trim();
+
+ sal_Int32 nStart = 0;
+ sal_Int32 nEnd = 0;
+
+ // extract language part
+ nEnd = sParser.indexOf(SEPERATOR_LC, nStart);
+ if (nEnd<0)
+ {
+ setLanguage(sParser);
+ return;
+ }
+ setLanguage(sParser.copy(nStart, nEnd-nStart));
+ nStart = nEnd+1;
+
+ // extract country
+ nEnd = sParser.indexOf(SEPERATOR_CV, nStart);
+ if (nEnd<0)
+ nEnd = sParser.indexOf(SEPERATOR_CV_LINUX, nStart);
+ if (nEnd<0)
+ {
+ setCountry(sParser.copy(nStart, sParser.getLength()-nStart));
+ return;
+ }
+ nStart = nEnd+1;
+
+ // extract variant
+ setVariant(sParser.copy(nStart, sParser.getLength()-nStart));
+}
+
+//-----------------------------------------------
+::rtl::OUString Locale::toISO() const
+{
+ ::rtl::OUStringBuffer sISO(64);
+
+ sISO.append(m_sLanguage);
+ if (m_sCountry.getLength())
+ {
+ sISO.append(SEPERATOR_LC);
+ sISO.append(m_sCountry);
+
+ if (m_sVariant.getLength())
+ {
+ sISO.append(SEPERATOR_CV);
+ sISO.append(m_sVariant);
+ }
+ }
+
+ return sISO.makeStringAndClear();
+}
+
+//-----------------------------------------------
+sal_Bool Locale::equals(const Locale& aComparable) const
+{
+ return (
+ m_sLanguage.equals(aComparable.m_sLanguage) &&
+ m_sCountry.equals (aComparable.m_sCountry ) &&
+ m_sVariant.equals (aComparable.m_sVariant )
+ );
+}
+
+//-----------------------------------------------
+sal_Bool Locale::similar(const Locale& aComparable) const
+{
+ return (m_sLanguage.equals(aComparable.m_sLanguage));
+}
+
+//-----------------------------------------------
+::std::vector< ::rtl::OUString >::const_iterator Locale::getFallback(const ::std::vector< ::rtl::OUString >& lISOList ,
+ const ::rtl::OUString& sReferenceISO)
+ throw(Locale::MalFormedLocaleException)
+{
+ Locale aReference(sReferenceISO);
+
+ // Note: The same language or "en"/"en-US" should be preferred as fallback.
+ // On the other side some localized variables doesnt use localzation in real.
+ // May be the use a "fix" value only ... marked as X-DEFAULT or X-NOTRANSLATE.
+ // At least it can be discussed, if any language is a valid fallback ...
+ // But in case some office functionality depends on that (that means real functionality instead
+ // of pure UI descriptions) we should do anything, so it can work.
+
+ ::std::vector< ::rtl::OUString >::const_iterator pSimilar = lISOList.end();
+ ::std::vector< ::rtl::OUString >::const_iterator pEN_US = lISOList.end();
+ ::std::vector< ::rtl::OUString >::const_iterator pEN = lISOList.end();
+ ::std::vector< ::rtl::OUString >::const_iterator pXDefault = lISOList.end();
+ ::std::vector< ::rtl::OUString >::const_iterator pXNoTranslate = lISOList.end();
+ ::std::vector< ::rtl::OUString >::const_iterator pAny = lISOList.end();
+
+ ::std::vector< ::rtl::OUString >::const_iterator pIt;
+ for ( pIt = lISOList.begin();
+ pIt != lISOList.end() ;
+ ++pIt )
+ {
+ Locale aCheck(*pIt);
+ // found Locale, which match with 100% => return it
+ if (aCheck.equals(aReference))
+ return pIt;
+
+ // found similar Locale => safe it as possible fallback
+ if (
+ (pSimilar == lISOList.end()) &&
+ (aCheck.similar(aReference))
+ )
+ {
+ pSimilar = pIt;
+ }
+ else
+ // found en-US => safe it as fallback
+ if (
+ (pEN_US == lISOList.end()) &&
+ (aCheck.equals(EN_US()) )
+ )
+ {
+ pEN_US = pIt;
+ }
+ else
+ // found en[-XX] => safe it as fallback
+ if (
+ (pEN == lISOList.end() ) &&
+ (aCheck.similar(EN_US()))
+ )
+ {
+ pEN = pIt;
+ }
+ else
+ // found an explicit default value(!) => safe it as fallback
+ if (
+ (pXDefault == lISOList.end()) &&
+ (aCheck.equals(X_DEFAULT()) )
+ )
+ {
+ pXDefault = pIt;
+ }
+ else
+ // found an implicit default value(!) => safe it as fallback
+ if (
+ (pXNoTranslate == lISOList.end()) &&
+ (aCheck.equals(X_NOTRANSLATE()) )
+ )
+ {
+ pXNoTranslate = pIt;
+ }
+ else
+ // safe the first locale, which isn't an explicit fallback
+ // as "last possible fallback"
+ if (pAny == lISOList.end())
+ pAny = pIt;
+ }
+
+ if (pSimilar != lISOList.end())
+ return pSimilar;
+
+ if (pEN_US != lISOList.end())
+ return pEN_US;
+
+ if (pEN != lISOList.end())
+ return pEN;
+
+ if (pXDefault != lISOList.end())
+ return pXDefault;
+
+ if (pXNoTranslate != lISOList.end())
+ return pXNoTranslate;
+
+ if (pAny != lISOList.end())
+ return pAny;
+
+ return lISOList.end();
+}
+
+//-----------------------------------------------
+sal_Bool Locale::getFallback(Locale& aLocale)
+{
+ // a)
+ // this was our last fallback!
+ // break any further calls to this method ...
+ if (aLocale.equals(X_NOTRANSLATE()))
+ return sal_False;
+
+ // b)
+ // switch from X_DEFAULT to X_NOTRANSLATE
+ // next time we will go to a)
+ if (aLocale.equals(X_DEFAULT()))
+ {
+ aLocale = X_NOTRANSLATE();
+ return sal_True;
+ }
+
+ // c)
+ // switch from EN to X_DEFAULT
+ // next time we will go to b)
+ if (aLocale.equals(EN()))
+ {
+ aLocale = X_DEFAULT();
+ return sal_True;
+ }
+
+ // d) remove country from incoming locale
+ // e.g. "de-DE" => "de" or "en-US" => "en"!
+ if (aLocale.getCountry().getLength())
+ {
+ aLocale.setCountry(::rtl::OUString());
+ return sal_True;
+ }
+
+ // e) "en-US" possible?
+ if (!aLocale.equals(EN_US()))
+ {
+ aLocale = EN_US();
+ return sal_True;
+ }
+
+ // f) no more fallbacks
+ return sal_False;
+}
+
+//-----------------------------------------------
+void Locale::operator=(const Locale& rCopy)
+{
+ // Take over these values without checking ...
+ // They was already checked if the copy was constructed
+ // and must be valid now!
+ m_sLanguage = rCopy.m_sLanguage;
+ m_sCountry = rCopy.m_sCountry;
+ m_sVariant = rCopy.m_sVariant;
+}
+
+//-----------------------------------------------
+sal_Bool Locale::operator==(const Locale& aComparable) const
+{
+ return equals(aComparable);
+}
+
+//-----------------------------------------------
+sal_Bool Locale::operator!=(const Locale& aComparable) const
+{
+ return !equals(aComparable);
+}
+
+} // namespace comphelper
+