/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * 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 .
*/
/* TODO-BCP47: this fiddling with Locale is quite ugly and fragile, especially * for the fo:script temporarily stored in Variant, it would be better to use * LanguageTagODF but we have that nasty UNO API requirement here.
* => make LanguageTagODF (unpublished) API? */
// For runtime performance, instead of converting back and forth between // css::Locale and LanguageTag to decide if script or tag are // needed, this code takes advantage of knowledge about the internal // representation of BCP 47 language tags in a Locale if present as done in a // LanguageTag.
XMLCharLanguageHdl::~XMLCharLanguageHdl()
{ // nothing to do
}
if (aLocale.Variant.isEmpty())
rStrExpValue = aLocale.Language; else
{
LanguageTag aLanguageTag( aLocale);
OUString aScript, aCountry;
aLanguageTag.getIsoLanguageScriptCountry( rStrExpValue, aScript, aCountry); // Do not write *:language='none' for a non-ISO language with // *:rfc-language-tag that is written if Variant is not empty. If there // is no match do not write this attribute at all. if (rStrExpValue.isEmpty()) returnfalse;
}
if( !IsXMLToken( rStrImpValue, XML_NONE ) )
{ // Import the script only if we don't have a full BCP 47 language tag // in Variant yet. if (aLocale.Variant.isEmpty())
{ if (aLocale.Language.isEmpty())
{
SAL_INFO( "xmloff.style", "XMLCharScriptHdl::importXML - script but no language yet"); // Temporarily store in Variant and hope the best (we will get // a language later, yes?)
aLocale.Variant = "-" + rStrImpValue;
} else
{
aLocale.Variant = aLocale.Language + "-" + rStrImpValue; if (!aLocale.Country.isEmpty())
aLocale.Variant += "-" + aLocale.Country;
aLocale.Language = I18NLANGTAG_QLT;
}
} elseif (aLocale.Variant[0] == '-')
{
SAL_WARN( "xmloff.style", "XMLCharScriptHdl::importXML - attempt to insert script twice: "
<< rStrImpValue << " -> " << aLocale.Variant);
} else
{ // Assume that if there already is a script or anything else BCP 47 // it was read by XMLCharRfcLanguageTagHdl() and takes precedence. // On the other hand, an *:rfc-language-tag without script and a // *:script ?!? #if OSL_DEBUG_LEVEL > 0 || defined(DBG_UTIL)
LanguageTag aLanguageTag( aLocale); if (!aLanguageTag.hasScript())
{
SAL_WARN( "xmloff.style", "XMLCharScriptHdl::importXML - attempt to insert script over bcp47: "
<< rStrImpValue << " -> " << aLanguageTag.getBcp47());
} #endif
}
}
LanguageTag aLanguageTag( aLocale); if (!aLanguageTag.hasScript()) returnfalse;
if (rUnitConv.getSaneDefaultVersion() < SvtSaveOptions::ODFSVER_012) returnfalse;
OUString aLanguage, aCountry;
aLanguageTag.getIsoLanguageScriptCountry( aLanguage, rStrExpValue, aCountry); // For non-ISO language it does not make sense to write *:script if // *:language is not written either, does it? It's all in // *:rfc-language-tag return !aLanguage.isEmpty() && !rStrExpValue.isEmpty();
}
XMLCharCountryHdl::~XMLCharCountryHdl()
{ // nothing to do
}
if( !IsXMLToken( rStrImpValue, XML_NONE ) )
{ if (aLocale.Country.isEmpty())
{
aLocale.Country = rStrImpValue; if (aLocale.Variant.getLength() >= 7 && aLocale.Language == I18NLANGTAG_QLT)
{ // already assembled language tag, at least ll-Ssss and not // ll-CC or lll-CC
sal_Int32 i = aLocale.Variant.indexOf('-'); // separator to script if (2 <= i && i < aLocale.Variant.getLength())
{
i = aLocale.Variant.indexOf( '-', i+1); if (i < 0) // no other separator
aLocale.Variant += "-" + rStrImpValue; // append country
}
}
}
}
if (aLocale.Variant.isEmpty())
rStrExpValue = aLocale.Country; else
{
LanguageTag aLanguageTag( aLocale);
OUString aLanguage, aScript;
aLanguageTag.getIsoLanguageScriptCountry( aLanguage, aScript, rStrExpValue); // Do not write *:country='none' for a non-ISO country with // *:rfc-language-tag that is written if Variant is not empty. If there // is no match do not write this attribute at all. if (rStrExpValue.isEmpty()) returnfalse;
}
if( !IsXMLToken( rStrImpValue, XML_NONE ) )
{ // Stored may be a *:rfc-language-tag in violation of ODF v1.3 // 19.516 style:rfc-language-tag "It shall only be used if its value // cannot be expressed as a valid combination of the fo:language // 19.871, fo:script 19.242 and fo:country 19.234 attributes". // That could override a more detailed fo:* and we also don't want an // unjustified I18NLANGTAG_QLT extended locale tag, but fetch the // values in case fo:* doesn't follow. // Rule out the obvious. if (rStrImpValue.getLength() < 7)
{
SAL_WARN("xmloff.style","rfc-language-tag too short: {" << rStrImpValue << "} Set: "
<< aLocale.Language <<","<< aLocale.Country <<","<< aLocale.Variant); // Ignore empty and keep Ssss or any earlier qlt already set. if (!rStrImpValue.isEmpty() && aLocale.Language != I18NLANGTAG_QLT)
{ // Shorter than ll-Ssss, so try ll-CC or lll-CC or ll or lll
sal_Int32 h = rStrImpValue.indexOf('-');
OUString aLang; if (2 <= h && h <= 3)
aLang = rStrImpValue.copy(0, h); elseif (h < 0 && 2 <= rStrImpValue.getLength() && rStrImpValue.getLength() <= 3)
aLang = rStrImpValue;
OUString aCoun; if (!aLang.isEmpty() && aLang.getLength() + 3 == rStrImpValue.getLength())
aCoun = rStrImpValue.copy( aLang.getLength() + 1); // Ignore identical value or less information. if ((!aLang.isEmpty() && aLang != aLocale.Language) ||
(!aCoun.isEmpty() && aCoun != aLocale.Country))
{ // Do not override existing values. if (aLocale.Language.isEmpty())
aLocale.Language = aLang; if (aLocale.Country.isEmpty())
aLocale.Country = aCoun; if (aLang != aLocale.Language || aCoun != aLocale.Country)
{ // No match, so we still need the qlt anyway. Whatever..
aLocale.Variant = rStrImpValue;
aLocale.Language = I18NLANGTAG_QLT;
}
} elseif (aLang.isEmpty() && aCoun.isEmpty())
{ // Both empty, some other tag.
aLocale.Variant = rStrImpValue;
aLocale.Language = I18NLANGTAG_QLT;
}
}
SAL_WARN("xmloff.style","rfc-language-tag too short: now set: "
<< aLocale.Language <<","<< aLocale.Country <<","<< aLocale.Variant);
} else
{
aLocale.Variant = rStrImpValue;
aLocale.Language = I18NLANGTAG_QLT;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.