LanguageTag getters with optional bResolveSystem parameter

Added bResolveSystem=true parameter to getBcp47(), getLocale() and
getLanguageType(). Other get...() and is...() methods now always resolve
to system locale.

Change-Id: I2d9718b8bd36aac5e047afd6921d462e52c6a235
This commit is contained in:
Eike Rathke 2012-11-15 22:13:19 +01:00
parent cc0c8e5643
commit 4e9bdee0bb
2 changed files with 123 additions and 64 deletions

View file

@ -61,8 +61,14 @@ public:
~LanguageTag();
LanguageTag& operator=( const LanguageTag & rLanguageTag );
/** Obtain BCP 47 language tag. */
rtl::OUString getBcp47() const;
/** Obtain BCP 47 language tag.
@param bResolveSystem
If TRUE, resolve an empty language tag denoting the system
locale to the real locale used.
If FALSE, return an empty OUString for such a tag.
*/
rtl::OUString getBcp47( bool bResolveSystem = true ) const;
/** Obtain language tag as Locale.
@ -72,40 +78,67 @@ public:
the entire BCP 47 language tag in the Variant field. The Country field
contains the corresponding ISO 3166 country code _if_ there is one, or
otherwise is empty.
@param bResolveSystem
If TRUE, resolve an empty language tag denoting the system
locale to the real locale used.
If FALSE, return an empty Locale for such a tag.
*/
com::sun::star::lang::Locale getLocale() const;
com::sun::star::lang::Locale getLocale( bool bResolveSystem = true ) const;
/** Obtain mapping to MS-LangID. */
LanguageType getLanguageType() const;
/** Obtain mapping to MS-LangID.
/** Get ISO 639 language code, or BCP 47 language. */
@param bResolveSystem
If TRUE, resolve an empty language tag denoting the system
locale to the real locale used.
If FALSE, return LANGUAGE_SYSTEM for such a tag.
*/
LanguageType getLanguageType( bool bResolveSystem = true ) const;
/** Get ISO 639 language code, or BCP 47 language.
Always resolves an empty tag to the system locale.
*/
rtl::OUString getLanguage() const;
/** Get ISO 15924 script code, if not the default script according to
BCP 47. For default script an empty string is returned.
Always resolves an empty tag to the system locale.
*/
rtl::OUString getScript() const;
/** Get combined language and script code, separated by '-' if
non-default script, if default script only language.
Always resolves an empty tag to the system locale.
*/
rtl::OUString getLanguageAndScript() const;
/** Get ISO 3166 country alpha code. Empty if the BCP 47 tags denote a
region not expressable as 2 character country code.
Always resolves an empty tag to the system locale.
*/
rtl::OUString getCountry() const;
/** Get BCP 47 region tag, which may be an ISO 3166 country alpha code or
any other BCP 47 region tag.
Always resolves an empty tag to the system locale.
*/
rtl::OUString getRegion() const;
/** If language tag is a locale that can be expressed using only ISO 639
language codes and ISO 3166 country codes, thus is convertible to a
conforming Locale struct without using extension mechanisms. Note that
an empty language tag or empty Locale::Language field or LanguageType
LANGUAGE_SYSTEM is treated as a valid ISO locale.
conforming Locale struct without using extension mechanisms.
Note that an empty language tag or empty Locale::Language field or
LanguageType LANGUAGE_SYSTEM could be treated as a valid ISO locale in
some context, but here is not. If you want that ask for
aTag.isSystemLocale() || aTag.isIsoLocale()
Always resolves an empty tag to the system locale.
*/
bool isIsoLocale() const;
@ -114,12 +147,21 @@ public:
thus can be stored in an ODF document using only fo:language, fo:script
and fo:country attributes. If this is FALSE, the locale must be stored
as a <*:rfc-language-tag> element.
Always resolves an empty tag to the system locale.
*/
bool isIsoODF() const;
/** If this is a valid BCP 47 language tag. */
/** If this is a valid BCP 47 language tag.
Always resolves an empty tag to the system locale.
*/
bool isValidBcp47() const;
/** If this tag was contructed as an empty tag denoting the system locale.
*/
bool isSystemLocale() const;
private:
enum Decision
@ -139,6 +181,7 @@ private:
mutable Decision meIsValid;
mutable Decision meIsIsoLocale;
mutable Decision meIsIsoODF;
bool mbSystemLocale : 1;
mutable bool mbInitializedBcp47 : 1;
mutable bool mbInitializedLocale : 1;
mutable bool mbInitializedLangID : 1;

View file

@ -146,7 +146,8 @@ LanguageTag::LanguageTag( const rtl::OUString & rBcp47LanguageTag, bool bCanonic
meIsValid( DECISION_DONTKNOW),
meIsIsoLocale( DECISION_DONTKNOW),
meIsIsoODF( DECISION_DONTKNOW),
mbInitializedBcp47( true),
mbSystemLocale( rBcp47LanguageTag.isEmpty()),
mbInitializedBcp47( !mbSystemLocale),
mbInitializedLocale( false),
mbInitializedLangID( false),
mbCachedLanguage( false),
@ -168,8 +169,9 @@ LanguageTag::LanguageTag( const com::sun::star::lang::Locale & rLocale )
meIsValid( DECISION_DONTKNOW),
meIsIsoLocale( DECISION_DONTKNOW),
meIsIsoODF( DECISION_DONTKNOW),
mbSystemLocale( rLocale.Language.isEmpty()),
mbInitializedBcp47( false),
mbInitializedLocale( true),
mbInitializedLocale( !mbSystemLocale),
mbInitializedLangID( false),
mbCachedLanguage( false),
mbCachedScript( false),
@ -186,9 +188,10 @@ LanguageTag::LanguageTag( LanguageType nLanguage )
meIsValid( DECISION_DONTKNOW),
meIsIsoLocale( DECISION_DONTKNOW),
meIsIsoODF( DECISION_DONTKNOW),
mbSystemLocale( nLanguage == LANGUAGE_SYSTEM),
mbInitializedBcp47( false),
mbInitializedLocale( false),
mbInitializedLangID( true),
mbInitializedLangID( !mbSystemLocale),
mbCachedLanguage( false),
mbCachedScript( false),
mbCachedCountry( false)
@ -205,8 +208,9 @@ LanguageTag::LanguageTag( const rtl::OUString& rLanguage, const rtl::OUString& r
meIsValid( DECISION_DONTKNOW),
meIsIsoLocale( DECISION_DONTKNOW),
meIsIsoODF( DECISION_DONTKNOW),
mbSystemLocale( rLanguage.isEmpty()),
mbInitializedBcp47( false),
mbInitializedLocale( true),
mbInitializedLocale( !mbSystemLocale),
mbInitializedLangID( false),
mbCachedLanguage( false),
mbCachedScript( false),
@ -229,6 +233,7 @@ LanguageTag::LanguageTag( const LanguageTag & rLanguageTag )
meIsValid( rLanguageTag.meIsValid),
meIsIsoLocale( rLanguageTag.meIsIsoLocale),
meIsIsoODF( rLanguageTag.meIsIsoODF),
mbSystemLocale( rLanguageTag.mbSystemLocale),
mbInitializedBcp47( rLanguageTag.mbInitializedBcp47),
mbInitializedLocale( rLanguageTag.mbInitializedLocale),
mbInitializedLangID( rLanguageTag.mbInitializedLangID),
@ -254,6 +259,7 @@ LanguageTag& LanguageTag::operator=( const LanguageTag & rLanguageTag )
meIsValid = rLanguageTag.meIsValid;
meIsIsoLocale = rLanguageTag.meIsIsoLocale;
meIsIsoODF = rLanguageTag.meIsIsoODF;
mbSystemLocale = rLanguageTag.mbSystemLocale;
mbInitializedBcp47 = rLanguageTag.mbInitializedBcp47;
mbInitializedLocale = rLanguageTag.mbInitializedLocale;
mbInitializedLangID = rLanguageTag.mbInitializedLangID;
@ -285,16 +291,7 @@ bool LanguageTag::canonicalize() const
dumper aDumper( &mpImplLangtag);
#endif
getBcp47(); // side effect: have maBcp47 in any case
// Checking empty for system locale before having allocated mpImplLangtag
// may result in multiple calls of this method because that serves as flag
// whether this was canonicalized, but that's better than allocating
// lt_tag_t for all those system locales.
if (maBcp47.isEmpty())
{
meIsValid = DECISION_YES;
return true;
}
getBcp47( true ); // side effect: have maBcp47 in any case, resolved system
if (!mpImplLangtag)
mpImplLangtag = lt_tag_new();
@ -342,13 +339,10 @@ bool LanguageTag::canonicalize() const
void LanguageTag::convertLocaleToBcp47()
{
if (maLocale.Language.isEmpty())
{
// Special case system locale.
maBcp47 = OUString();
meIsIsoLocale = DECISION_YES;
}
else if (maLocale.Language == ISO639_LANGUAGE_TAG)
if (mbSystemLocale && !mbInitializedLocale)
convertLangToLocale();
if (maLocale.Language == ISO639_LANGUAGE_TAG)
{
maBcp47 = maLocale.Variant;
meIsIsoLocale = DECISION_NO;
@ -373,37 +367,35 @@ void LanguageTag::convertLocaleToBcp47()
void LanguageTag::convertLocaleToLang()
{
/* FIXME: this is temporary until code base is converted to not use
* MsLangId::convert...() anymore. After that, proper new method has to be
* implemented to allow ISO639_LANGUAGE_TAG and sript tag and such. */
mnLangID = MsLangId::convertLocaleToLanguage( maLocale);
if (mbSystemLocale)
{
mnLangID = MsLangId::getRealLanguage( LANGUAGE_SYSTEM);
}
else
{
/* FIXME: this is temporary until code base is converted to not use
* MsLangId::convert...() anymore. After that, proper new method has to
* be implemented to allow ISO639_LANGUAGE_TAG and sript tag and such. */
mnLangID = MsLangId::convertLocaleToLanguage( maLocale);
}
mbInitializedLangID = true;
}
void LanguageTag::convertBcp47ToLocale()
{
if (maBcp47.isEmpty())
bool bIso = isIsoLocale();
if (bIso)
{
// Special case system locale.
maLocale = lang::Locale();
meIsIsoLocale = DECISION_YES;
maLocale.Language = getLanguageFromLangtag();
maLocale.Country = getRegionFromLangtag();
maLocale.Variant = OUString();
}
else
{
bool bIso = isIsoLocale();
if (bIso)
{
maLocale.Language = getLanguageFromLangtag();
maLocale.Country = getRegionFromLangtag();
maLocale.Variant = OUString();
}
else
{
maLocale.Language = ISO639_LANGUAGE_TAG;
maLocale.Country = getCountry();
maLocale.Variant = maBcp47;
}
maLocale.Language = ISO639_LANGUAGE_TAG;
maLocale.Country = getCountry();
maLocale.Variant = maBcp47;
}
mbInitializedLocale = true;
}
@ -411,23 +403,35 @@ void LanguageTag::convertBcp47ToLocale()
void LanguageTag::convertBcp47ToLang()
{
/* FIXME: this is temporary. If we support locales that consist not only of
* language and country, e.g. added script, this probably needs to be
* adapted. */
if (!mbInitializedLocale)
convertBcp47ToLocale();
convertLocaleToLang();
if (mbSystemLocale)
{
mnLangID = MsLangId::getRealLanguage( LANGUAGE_SYSTEM);
}
else
{
/* FIXME: this is temporary. If we support locales that consist not
* only of language and country, e.g. added script, this probably needs
* to be adapted. */
if (!mbInitializedLocale)
convertBcp47ToLocale();
convertLocaleToLang();
}
mbInitializedLangID = true;
}
void LanguageTag::convertLangToLocale()
{
if (mbSystemLocale && !mbInitializedLangID)
{
mnLangID = MsLangId::getRealLanguage( LANGUAGE_SYSTEM);
mbInitializedLangID = true;
}
/* FIXME: this is temporary until code base is converted to not use
* MsLangId::convert...() anymore. After that, proper new method has to be
* implemented to allow ISO639_LANGUAGE_TAG and script tag and such. */
// Do not resolve system here!
maLocale = MsLangId::convertLanguageToLocale( mnLangID, false);
// Resolve system here!
maLocale = MsLangId::convertLanguageToLocale( mnLangID, true);
mbInitializedLocale = true;
}
@ -444,8 +448,10 @@ void LanguageTag::convertLangToBcp47()
}
rtl::OUString LanguageTag::getBcp47() const
rtl::OUString LanguageTag::getBcp47( bool bResolveSystem ) const
{
if (!bResolveSystem && mbSystemLocale)
return OUString();
if (!mbInitializedBcp47)
{
if (mbInitializedLocale)
@ -514,8 +520,10 @@ rtl::OUString LanguageTag::getRegionFromLangtag() const
}
com::sun::star::lang::Locale LanguageTag::getLocale() const
com::sun::star::lang::Locale LanguageTag::getLocale( bool bResolveSystem ) const
{
if (!bResolveSystem && mbSystemLocale)
return lang::Locale();
if (!mbInitializedLocale)
{
if (mbInitializedBcp47)
@ -527,8 +535,10 @@ com::sun::star::lang::Locale LanguageTag::getLocale() const
}
LanguageType LanguageTag::getLanguageType() const
LanguageType LanguageTag::getLanguageType( bool bResolveSystem ) const
{
if (!bResolveSystem && mbSystemLocale)
return LANGUAGE_SYSTEM;
if (!mbInitializedLangID)
{
if (mbInitializedBcp47)
@ -702,10 +712,16 @@ bool LanguageTag::isValidBcp47() const
if (!mpImplLangtag)
canonicalize();
SAL_WARN_IF( meIsValid == DECISION_DONTKNOW, "i18npool.langtag",
"LanguageTag::isValidBcp47: canonicalize() doesn't set meIsValid");
"LanguageTag::isValidBcp47: canonicalize() didn't set meIsValid");
}
return meIsValid == DECISION_YES;
}
bool LanguageTag::isSystemLocale() const
{
return mbSystemLocale;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */