From 742c2fe0a256d33d06dc13f6d69c143b31e3ce93 Mon Sep 17 00:00:00 2001 From: Caolán McNamara Date: Mon, 23 May 2011 12:29:31 +0100 Subject: Resolves: fdo#33638 add extra level of language tag matching --- configmgr/source/childaccess.cxx | 82 +++++++++++++++++++++++++++------------- 1 file changed, 56 insertions(+), 26 deletions(-) (limited to 'configmgr') diff --git a/configmgr/source/childaccess.cxx b/configmgr/source/childaccess.cxx index 3d9c40bc072b..fc8e1ca4395c 100644 --- a/configmgr/source/childaccess.cxx +++ b/configmgr/source/childaccess.cxx @@ -271,6 +271,17 @@ void ChildAccess::setProperty( localModifications->add(getRelativePath()); } +namespace +{ + rtl::OUString lcl_StripSegment(const rtl::OUString &rLocale) + { + sal_Int32 i = rLocale.getLength() ? rLocale.getLength() - 1 : 0; + while (i > 0 && rLocale[i] != '-' && rLocale[i] != '_') + --i; + return rLocale.copy(0, i); + } +} + css::uno::Any ChildAccess::asValue() { if (changedValue_.get() != 0) { return *changedValue_; @@ -281,43 +292,62 @@ css::uno::Any ChildAccess::asValue() { getComponents()); case Node::KIND_LOCALIZED_PROPERTY: { - rtl::OUString locale(getRootAccess()->getLocale()); - if (!Components::allLocales(locale)) { - // Find best match using an adaption of RFC 4647 lookup matching - // rules, removing "-" or "_" delimited segments from the end; - // defaults are the "en-US" locale, the "en" locale, the empty - // string locale, the first child (if any), or a nil value (even - // though it may be illegal for the given property), in that - // order: + rtl::OUString sLocale(getRootAccess()->getLocale()); + if (!Components::allLocales(sLocale)) + { rtl::Reference< ChildAccess > child; - for (;;) { - child = getChild(locale); - if (child.is() || locale.getLength() == 0) { + // Find best match using an adaption of RFC 4647 lookup matching + // rules, removing "-" or "_" delimited segments from the end + while (1) + { + child = getChild(sLocale); + if (child.is()) break; - } - sal_Int32 i = locale.getLength() - 1; - while (i > 0 && locale[i] != '-' && locale[i] != '_') { - --i; - } - if (i == 0) { + rtl::OUString sTmpLocale = lcl_StripSegment(sLocale); + if (!sTmpLocale.getLength()) break; + sLocale = sTmpLocale; + } + + //Resolves: fdo#33638 Look for the first entry with the same + //first segment as the requested language tag, before falling + //back to en-US, etc. + typedef std::vector< rtl::Reference< ChildAccess > > ChildVector; + if (!child.is()) + { + const ChildVector &rAllChildren = getAllChildren(); + for (ChildVector::const_iterator aI = rAllChildren.begin(), + aEnd = rAllChildren.end(); aI != aEnd; ++aI) + { + rtl::OUString sLanguage = lcl_StripSegment((*aI)->getNameInternal()); + if (sLocale == sLanguage) + { + child = *aI; + break; + } } - locale = locale.copy(0, i); } - if (!child.is()) { + + // defaults are the "en-US" locale, the "en" locale, the empty + // string locale, the first child (if any), or a nil value (even + // though it may be illegal for the given property), in that + // order: + if (!child.is()) + { child = getChild( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en-US"))); - if (!child.is()) { + if (!child.is()) + { child = getChild( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en"))); - if (!child.is()) { + if (!child.is()) + { child = getChild(rtl::OUString()); - if (!child.is()) { - std::vector< rtl::Reference< ChildAccess > > - all(getAllChildren()); - if (!all.empty()) { + if (!child.is()) + { + ChildVector all(getAllChildren()); + if (!all.empty()) child = all.front(); - } } } } -- cgit