blob: 42d8492ab2b8bbf77bbb52960f5cd71813271111 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the 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.isEmpty() )
{
sISO.append(SEPERATOR_LC);
sISO.append(m_sCountry);
if ( !m_sVariant.isEmpty() )
{
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().isEmpty())
{
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