From 4e9bdee0bbef65d2419f36e504292e3341a81004 Mon Sep 17 00:00:00 2001 From: Eike Rathke Date: Thu, 15 Nov 2012 22:13:19 +0100 Subject: [PATCH] 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 --- i18npool/inc/i18npool/languagetag.hxx | 63 ++++++++-- i18npool/source/languagetag/languagetag.cxx | 124 +++++++++++--------- 2 files changed, 123 insertions(+), 64 deletions(-) diff --git a/i18npool/inc/i18npool/languagetag.hxx b/i18npool/inc/i18npool/languagetag.hxx index 7475cf06c679..abc7ed1bf17c 100644 --- a/i18npool/inc/i18npool/languagetag.hxx +++ b/i18npool/inc/i18npool/languagetag.hxx @@ -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; diff --git a/i18npool/source/languagetag/languagetag.cxx b/i18npool/source/languagetag/languagetag.cxx index 0a7e8933b65f..2b3dbc404a9c 100644 --- a/i18npool/source/languagetag/languagetag.cxx +++ b/i18npool/source/languagetag/languagetag.cxx @@ -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: */