Kaydet (Commit) da5adead authored tarafından Eike Rathke's avatar Eike Rathke

DescriptionInfoset with LanguageTag

Change-Id: I7957a4a773b2ea8e69c30a1152b90ce5623a26dc
üst e7207202
...@@ -49,6 +49,7 @@ $(eval $(call gb_Library_use_libraries,deployment,\ ...@@ -49,6 +49,7 @@ $(eval $(call gb_Library_use_libraries,deployment,\
ucbhelper \ ucbhelper \
utl \ utl \
xmlscript \ xmlscript \
i18nisolang1 \
$(gb_UWINAPI) \ $(gb_UWINAPI) \
)) ))
......
...@@ -31,7 +31,6 @@ ...@@ -31,7 +31,6 @@
/// @HTML /// @HTML
namespace com { namespace sun { namespace star { namespace com { namespace sun { namespace star {
namespace lang { struct Locale; }
namespace uno { class XComponentContext; } namespace uno { class XComponentContext; }
namespace xml { namespace xml {
namespace dom { namespace dom {
...@@ -230,16 +229,9 @@ private: ...@@ -230,16 +229,9 @@ private:
SAL_DLLPRIVATE ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode > SAL_DLLPRIVATE ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode >
getLocalizedChild( ::rtl::OUString const & sParent) const; getLocalizedChild( ::rtl::OUString const & sParent) const;
SAL_DLLPRIVATE ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode> SAL_DLLPRIVATE ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode>
matchFullLocale(::com::sun::star::uno::Reference< matchLanguageTag(
::com::sun::star::xml::dom::XNode > const & xParent, ::rtl::OUString const & sLocale) const;
SAL_DLLPRIVATE ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode>
matchCountryAndLanguage(::com::sun::star::uno::Reference<
::com::sun::star::xml::dom::XNode > const & xParent,
::com::sun::star::lang::Locale const & officeLocale) const;
SAL_DLLPRIVATE ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode>
matchLanguage(
::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode > const & xParent, ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode > const & xParent,
::com::sun::star::lang::Locale const & officeLocale) const; OUString const & rTag) const;
/** If there is no child element with a locale matching the office locale, then we use /** If there is no child element with a locale matching the office locale, then we use
the first child. In the case of the simple-license we also use the former default locale, which the first child. In the case of the simple-license we also use the former default locale, which
...@@ -258,9 +250,6 @@ private: ...@@ -258,9 +250,6 @@ private:
SAL_DLLPRIVATE ::rtl::OUString getLocalizedHREFAttrFromChild( SAL_DLLPRIVATE ::rtl::OUString getLocalizedHREFAttrFromChild(
::rtl::OUString const & sXPathParent, bool * out_bParentExists) const; ::rtl::OUString const & sXPathParent, bool * out_bParentExists) const;
static SAL_DLLPRIVATE ::rtl::OUString
localeToString(::com::sun::star::lang::Locale const & locale);
/** Gets the node value for a given expression. The expression is used in /** Gets the node value for a given expression. The expression is used in
m_xpath-selectSingleNode. The value of the returned node is return value m_xpath-selectSingleNode. The value of the returned node is return value
of this function. of this function.
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#include "tools/string.hxx" #include "tools/string.hxx"
#include "tools/resid.hxx" #include "tools/resid.hxx"
#include "com/sun/star/lang/Locale.hpp" #include <i18npool/languagetag.hxx>
#include "dp_misc.h" #include "dp_misc.h"
#include <memory> #include <memory>
#include "dp_misc_api.hxx" #include "dp_misc_api.hxx"
...@@ -43,15 +43,7 @@ struct StaticResourceString : ...@@ -43,15 +43,7 @@ struct StaticResourceString :
//============================================================================== //==============================================================================
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
::com::sun::star::lang::Locale toLocale( ::rtl::OUString const & slang ); const LanguageTag & getOfficeLanguageTag();
//==============================================================================
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
::com::sun::star::lang::Locale getOfficeLocale();
//==============================================================================
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
::rtl::OUString getOfficeLocaleString();
} }
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#include "com/sun/star/beans/XPropertySet.hpp" #include "com/sun/star/beans/XPropertySet.hpp"
#include "com/sun/star/io/SequenceInputStream.hpp" #include "com/sun/star/io/SequenceInputStream.hpp"
#include "com/sun/star/lang/XMultiComponentFactory.hpp" #include "com/sun/star/lang/XMultiComponentFactory.hpp"
#include "com/sun/star/lang/Locale.hpp"
#include "com/sun/star/uno/Reference.hxx" #include "com/sun/star/uno/Reference.hxx"
#include "com/sun/star/uno/RuntimeException.hpp" #include "com/sun/star/uno/RuntimeException.hpp"
#include "com/sun/star/uno/Sequence.hxx" #include "com/sun/star/uno/Sequence.hxx"
...@@ -725,20 +724,24 @@ DescriptionInfoset::getLocalizedChild( const ::rtl::OUString & sParent) const ...@@ -725,20 +724,24 @@ DescriptionInfoset::getLocalizedChild( const ::rtl::OUString & sParent) const
css::uno::Reference<css::xml::dom::XNode> nodeMatch; css::uno::Reference<css::xml::dom::XNode> nodeMatch;
if (xParent.is()) if (xParent.is())
{ {
const ::rtl::OUString sLocale = getOfficeLocaleString(); nodeMatch = matchLanguageTag(xParent, getOfficeLanguageTag().getBcp47());
nodeMatch = matchFullLocale(xParent, sLocale);
//office: en-DE, en, en-DE-altmark //office: en-DE, en, en-DE-altmark
if (! nodeMatch.is()) if (! nodeMatch.is())
{ {
const css::lang::Locale officeLocale = getOfficeLocale(); const ::std::vector< OUString > aFallbacks = getOfficeLanguageTag().getFallbackStrings();
nodeMatch = matchCountryAndLanguage(xParent, officeLocale); // Already tried full tag, continue with first fallback.
if ( ! nodeMatch.is()) ::std::vector< OUString >::const_iterator it( aFallbacks.begin());
if (it != aFallbacks.end())
++it;
for ( ; it != aFallbacks.end(); ++it)
{ {
nodeMatch = matchLanguage(xParent, officeLocale); nodeMatch = matchLanguageTag(xParent, *it);
if (! nodeMatch.is()) if (nodeMatch.is())
nodeMatch = getChildWithDefaultLocale(xParent); break;
} }
if (! nodeMatch.is())
nodeMatch = getChildWithDefaultLocale(xParent);
} }
} }
...@@ -746,79 +749,26 @@ DescriptionInfoset::getLocalizedChild( const ::rtl::OUString & sParent) const ...@@ -746,79 +749,26 @@ DescriptionInfoset::getLocalizedChild( const ::rtl::OUString & sParent) const
} }
css::uno::Reference<css::xml::dom::XNode> css::uno::Reference<css::xml::dom::XNode>
DescriptionInfoset::matchFullLocale(css::uno::Reference< css::xml::dom::XNode > DescriptionInfoset::matchLanguageTag(
const & xParent, ::rtl::OUString const & sLocale) const css::uno::Reference< css::xml::dom::XNode > const & xParent, OUString const & rTag) const
{
OSL_ASSERT(xParent.is());
const ::rtl::OUString exp1("*[@lang=\"" + sLocale + "\"]");
try {
return m_xpath->selectSingleNode(xParent, exp1);
} catch (const css::xml::xpath::XPathException &) {
// ignore
return 0;
}
}
css::uno::Reference<css::xml::dom::XNode>
DescriptionInfoset::matchCountryAndLanguage(
css::uno::Reference< css::xml::dom::XNode > const & xParent, css::lang::Locale const & officeLocale) const
{
OSL_ASSERT(xParent.is());
css::uno::Reference<css::xml::dom::XNode> nodeMatch;
if (!officeLocale.Country.isEmpty())
{
const ::rtl::OUString sLangCountry(officeLocale.Language +
"-" + officeLocale.Country);
//first try exact match for lang-country
const ::rtl::OUString exp1(
"*[@lang=\"" + sLangCountry +"\"]");
try {
nodeMatch = m_xpath->selectSingleNode(xParent, exp1);
} catch (const css::xml::xpath::XPathException &) {
// ignore
}
//try to match in strings that also have a variant, for example en-US matches in
//en-US-montana
if (!nodeMatch.is())
{
const ::rtl::OUString exp2(
"*[starts-with(@lang,\"" + sLangCountry + "-\")]");
try {
nodeMatch = m_xpath->selectSingleNode(xParent, exp2);
} catch (const css::xml::xpath::XPathException &) {
// ignore
}
}
}
return nodeMatch;
}
css::uno::Reference<css::xml::dom::XNode>
DescriptionInfoset::matchLanguage(
css::uno::Reference< css::xml::dom::XNode > const & xParent, css::lang::Locale const & officeLocale) const
{ {
OSL_ASSERT(xParent.is()); OSL_ASSERT(xParent.is());
css::uno::Reference<css::xml::dom::XNode> nodeMatch; css::uno::Reference<css::xml::dom::XNode> nodeMatch;
//first try exact match for lang //first try exact match for lang
const ::rtl::OUString exp1("*[@lang=\"" + officeLocale.Language const ::rtl::OUString exp1("*[@lang=\"" + rTag + "\"]");
+ "\"]");
try { try {
nodeMatch = m_xpath->selectSingleNode(xParent, exp1); nodeMatch = m_xpath->selectSingleNode(xParent, exp1);
} catch (const css::xml::xpath::XPathException &) { } catch (const css::xml::xpath::XPathException &) {
// ignore // ignore
} }
//try to match in strings that also have a country and/orvariant, for example en matches in //try to match in strings that also have a country and/or variant, for
//en-US-montana, en-US, en-montana //example en matches in en-US-montana, en-US, en-montana
if (!nodeMatch.is()) if (!nodeMatch.is())
{ {
const ::rtl::OUString exp2( const ::rtl::OUString exp2(
"*[starts-with(@lang,\"" + officeLocale.Language + "-\")]"); "*[starts-with(@lang,\"" + rTag + "-\")]");
try { try {
nodeMatch = m_xpath->selectSingleNode(xParent, exp2); nodeMatch = m_xpath->selectSingleNode(xParent, exp2);
} catch (const css::xml::xpath::XPathException &) { } catch (const css::xml::xpath::XPathException &) {
......
...@@ -37,21 +37,21 @@ namespace dp_misc { ...@@ -37,21 +37,21 @@ namespace dp_misc {
namespace { namespace {
struct OfficeLocale : struct OfficeLocale :
public rtl::StaticWithInit<OUString, OfficeLocale> { public rtl::StaticWithInit<LanguageTag, OfficeLocale> {
const OUString operator () () { const LanguageTag operator () () {
OUString slang(utl::ConfigManager::getLocale()); OUString slang(utl::ConfigManager::getLocale());
//fallback, the locale is currently only set when the user starts the //fallback, the locale is currently only set when the user starts the
//office for the first time. //office for the first time.
if (slang.isEmpty()) if (slang.isEmpty())
slang = "en-US"; slang = "en-US";
return slang; return LanguageTag( slang);
} }
}; };
struct DeploymentResMgr : public rtl::StaticWithInit< struct DeploymentResMgr : public rtl::StaticWithInit<
ResMgr *, DeploymentResMgr> { ResMgr *, DeploymentResMgr> {
ResMgr * operator () () { ResMgr * operator () () {
return ResMgr::CreateResMgr( "deployment", LanguageTag( OfficeLocale::get()) ); return ResMgr::CreateResMgr( "deployment", OfficeLocale::get() );
} }
}; };
...@@ -76,19 +76,8 @@ String getResourceString( sal_uInt16 id ) ...@@ -76,19 +76,8 @@ String getResourceString( sal_uInt16 id )
return ret; return ret;
} }
//=============================================================================
::com::sun::star::lang::Locale toLocale( ::rtl::OUString const & slang )
{
return LanguageTag( slang).getLocale();
}
//============================================================================== //==============================================================================
lang::Locale getOfficeLocale() const LanguageTag & getOfficeLanguageTag()
{
return toLocale(OfficeLocale::get());
}
::rtl::OUString getOfficeLocaleString()
{ {
return OfficeLocale::get(); return OfficeLocale::get();
} }
......
...@@ -1419,9 +1419,11 @@ void BackendImpl::PackageImpl::scanBundle( ...@@ -1419,9 +1419,11 @@ void BackendImpl::PackageImpl::scanBundle(
} }
const lang::Locale officeLocale = getOfficeLocale(); const LanguageTag& officeLocale = getOfficeLanguageTag();
const ::std::vector< OUString > officeFallbacks( officeLocale.getFallbackStrings());
const size_t nPenaltyMax = ::std::numeric_limits<size_t>::max();
size_t descrPenalty = nPenaltyMax;
OUString descrFile; OUString descrFile;
lang::Locale descrFileLocale;
const Reference<XComponentContext> xContext( const Reference<XComponentContext> xContext(
getMyBackend()->getComponentContext() ); getMyBackend()->getComponentContext() );
...@@ -1469,18 +1471,33 @@ void BackendImpl::PackageImpl::scanBundle( ...@@ -1469,18 +1471,33 @@ void BackendImpl::PackageImpl::scanBundle(
} }
else { else {
// match best locale: // match best locale:
lang::Locale locale( toLocale(param->m_sValue) ); LanguageTag descrTag( param->m_sValue);
if (locale.Language == officeLocale.Language) if (officeLocale.getLanguage() == descrTag.getLanguage())
{ {
if (descrFileLocale.Country == officeLocale.Country size_t nPenalty = nPenaltyMax;
&& locale.Country != officeLocale.Country) const ::std::vector< OUString > descrFallbacks( descrTag.getFallbackStrings());
continue; for (size_t o=0; o < officeFallbacks.size() && nPenalty == nPenaltyMax; ++o)
if (descrFileLocale.Variant == officeLocale.Variant {
&& locale.Variant != officeLocale.Variant) for (size_t d=0; d < descrFallbacks.size() && nPenalty == nPenaltyMax; ++d)
continue; {
descrFile = url; if (officeFallbacks[o] == descrFallbacks[d])
descrFileLocale = locale; {
// The last fallbacks are always language-only
// fallbacks, so we _will_ have _some_ match if
// we ever entered the overall if() condition.
nPenalty = o * 1000 + d;
if (descrPenalty > nPenalty)
{
descrPenalty = nPenalty;
descrFile = url;
}
}
}
}
} }
// TODO: we could break here if descrPenalty==0 for an exact
// match of officeLocale, but the previous code didn't; are
// there side effects?
} }
continue; continue;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment