Kaydet (Commit) 4fee05e6 authored tarafından Laurent Balland-Poirier's avatar Laurent Balland-Poirier Kaydeden (comit) Eike Rathke

tdf#90133 Extend ODF: variable decimal in scientific format

Variable decimal is only saved in ODF for number, and do not consider
partial variable decimal: 0.0## is saved as 0.000
This patch extend ODF with loext:min-decimal-digit for number format and
scientific format

Change-Id: I5022458da47bbd33c3e195c280e75c43faca5f8d
Reviewed-on: https://gerrit.libreoffice.org/15135Reviewed-by: 's avatarEike Rathke <erack@redhat.com>
Tested-by: 's avatarEike Rathke <erack@redhat.com>
üst 38992b41
......@@ -62,11 +62,11 @@ private:
SAL_DLLPRIVATE void FinishTextElement_Impl(bool bUseExtensionNS = false);
SAL_DLLPRIVATE void WriteColorElement_Impl( const Color& rColor );
SAL_DLLPRIVATE void WriteNumberElement_Impl( sal_Int32 nDecimals, sal_Int32 nInteger,
const OUString& rDashStr, bool bVarDecimals,
SAL_DLLPRIVATE void WriteNumberElement_Impl( sal_Int32 nDecimals, sal_Int32 nMinDecimals,
sal_Int32 nInteger, const OUString& rDashStr,
bool bGrouping, sal_Int32 nTrailingThousands,
const SvXMLEmbeddedTextEntryArr& rEmbeddedEntries );
SAL_DLLPRIVATE void WriteScientificElement_Impl( sal_Int32 nDecimals, sal_Int32 nInteger,
SAL_DLLPRIVATE void WriteScientificElement_Impl( sal_Int32 nDecimals, sal_Int32 nMinDecimals, sal_Int32 nInteger,
bool bGrouping, sal_Int32 nExp, sal_Int32 nExpInterval, bool bExpSign );
SAL_DLLPRIVATE void WriteFractionElement_Impl( sal_Int32 nInteger, bool bGrouping,
sal_Int32 nNumeratorDigits, sal_Int32 nDenominatorDigits, sal_Int32 nDenominator );
......
......@@ -3251,6 +3251,7 @@ namespace xmloff { namespace token {
XML_EXPONENT_INTERVAL,
XML_EXPONENT_SIGN,
XML_MIN_DECIMAL_DIGITS,
XML_TOKEN_END
};
......
......@@ -3249,6 +3249,7 @@ namespace xmloff { namespace token {
TOKEN( "exponent-interval", XML_EXPONENT_INTERVAL ),
TOKEN( "exponent-sign", XML_EXPONENT_SIGN ),
TOKEN( "min-decimal-digits", XML_MIN_DECIMAL_DIGITS ),
#if OSL_DEBUG_LEVEL > 0
{ 0, NULL, NULL, XML_TOKEN_END }
......
......@@ -556,8 +556,8 @@ void SvXMLNumFmtExport::WriteAMPMElement_Impl()
// numbers
void SvXMLNumFmtExport::WriteNumberElement_Impl(
sal_Int32 nDecimals, sal_Int32 nInteger,
const OUString& rDashStr, bool bVarDecimals,
sal_Int32 nDecimals, sal_Int32 nMinDecimals,
sal_Int32 nInteger, const OUString& rDashStr,
bool bGrouping, sal_Int32 nTrailingThousands,
const SvXMLEmbeddedTextEntryArr& rEmbeddedEntries )
{
......@@ -570,6 +570,12 @@ void SvXMLNumFmtExport::WriteNumberElement_Impl(
OUString::number( nDecimals ) );
}
if ( nMinDecimals >= 0 ) // negative = automatic
{
rExport.AddAttribute( XML_NAMESPACE_LO_EXT, XML_MIN_DECIMAL_DIGITS,
OUString::number( nMinDecimals ) );
}
// integer digits
if ( nInteger >= 0 ) // negative = automatic
{
......@@ -578,9 +584,9 @@ void SvXMLNumFmtExport::WriteNumberElement_Impl(
}
// decimal replacement (dashes) or variable decimals (#)
if ( !rDashStr.isEmpty() || bVarDecimals )
if ( !rDashStr.isEmpty() || nMinDecimals < nDecimals )
{
// variable decimals means an empty replacement string
// full variable decimals means an empty replacement string
rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_DECIMAL_REPLACEMENT,
rDashStr );
}
......@@ -633,7 +639,7 @@ void SvXMLNumFmtExport::WriteNumberElement_Impl(
}
void SvXMLNumFmtExport::WriteScientificElement_Impl(
sal_Int32 nDecimals, sal_Int32 nInteger,
sal_Int32 nDecimals, sal_Int32 nMinDecimals, sal_Int32 nInteger,
bool bGrouping, sal_Int32 nExp, sal_Int32 nExpInterval, bool bExpSign )
{
FinishTextElement_Impl();
......@@ -645,6 +651,12 @@ void SvXMLNumFmtExport::WriteScientificElement_Impl(
OUString::number( nDecimals ) );
}
if ( nMinDecimals >= 0 ) // negative = automatic
{
rExport.AddAttribute( XML_NAMESPACE_LO_EXT, XML_MIN_DECIMAL_DIGITS,
OUString::number( nMinDecimals ) );
}
// integer digits
if ( nInteger >= 0 ) // negative = automatic
{
......@@ -1154,7 +1166,7 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
if ( eBuiltIn == NF_NUMBER_STANDARD )
{
// default number format contains just one number element
WriteNumberElement_Impl( -1, 1, OUString(), false, false, 0, aEmbeddedEntries );
WriteNumberElement_Impl( -1, -1, 1, OUString(), false, 0, aEmbeddedEntries );
bAnyContent = true;
}
else if ( eBuiltIn == NF_BOOLEAN )
......@@ -1168,7 +1180,6 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
// first loop to collect attributes
bool bDecDashes = false;
bool bVarDecimals = false;
bool bExpFound = false;
bool bCurrFound = false;
bool bInInteger = true;
......@@ -1176,6 +1187,7 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
sal_Int32 nExpDigits = 0;
sal_Int32 nIntegerSymbols = 0; // for embedded-text, including "#"
sal_Int32 nTrailingThousands = 0; // thousands-separators after all digits
sal_Int32 nMinDecimals = nPrecision;
OUString sCurrExt;
OUString aCalendar;
sal_uInt16 nPos = 0;
......@@ -1195,11 +1207,12 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
nExpDigits += pElemStr->getLength();
else if ( !bDecDashes && pElemStr && (*pElemStr)[0] == '-' )
bDecDashes = true;
else if ( !bVarDecimals && !bInInteger && pElemStr && (*pElemStr)[0] == '#' )
else if ( !bInInteger && pElemStr )
{
// If the decimal digits string starts with a '#', variable
// decimals is assumed (for 0.###, but not 0.0##).
bVarDecimals = true;
for ( sal_Int32 i = pElemStr->getLength()-1; i >= 0 && (*pElemStr)[i] == '#'; i-- )
{
nMinDecimals --;
}
}
if ( bInInteger && pElemStr )
nIntegerSymbols += pElemStr->getLength();
......@@ -1352,7 +1365,7 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
}
break;
case NF_KEY_GENERAL :
WriteNumberElement_Impl( -1, 1, OUString(), false, false, 0, aEmbeddedEntries );
WriteNumberElement_Impl( -1, -1, 1, OUString(), false, 0, aEmbeddedEntries );
break;
case NF_KEY_CCC:
if (pElemStr)
......@@ -1419,8 +1432,8 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
if (bDecDashes && nPrecision > 0)
comphelper::string::padToLength(sDashStr, nPrecision, '-');
WriteNumberElement_Impl(nDecimals, nInteger, sDashStr.makeStringAndClear(),
bVarDecimals, bThousand, nTrailingThousands, aEmbeddedEntries);
WriteNumberElement_Impl(nDecimals, nMinDecimals, nInteger, sDashStr.makeStringAndClear(),
bThousand, nTrailingThousands, aEmbeddedEntries);
bAnyContent = true;
}
break;
......@@ -1428,7 +1441,7 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
// #i43959# for scientific numbers, count all integer symbols ("0" and "#")
// as integer digits: use nIntegerSymbols instead of nLeading
// nIntegerSymbols represents exponent interval (for engineering notation)
WriteScientificElement_Impl( nPrecision, nLeading, bThousand, nExpDigits, nIntegerSymbols, bExpSign );
WriteScientificElement_Impl( nPrecision, nMinDecimals, nLeading, bThousand, nExpDigits, nIntegerSymbols, bExpSign );
bAnyContent = true;
break;
case css::util::NumberFormat::FRACTION:
......
......@@ -114,17 +114,18 @@ struct SvXMLNumberInfo
sal_Int32 nNumerDigits;
sal_Int32 nDenomDigits;
sal_Int32 nFracDenominator;
sal_Int32 nMinDecimalDigits;
bool bGrouping;
bool bDecReplace;
bool bVarDecimals;
bool bExpSign;
double fDisplayFactor;
SvXMLEmbeddedElementArr aEmbeddedElements;
SvXMLNumberInfo()
{
nDecimals = nInteger = nExpDigits = nExpInterval = nNumerDigits = nDenomDigits = nFracDenominator = -1;
bGrouping = bDecReplace = bVarDecimals = false;
nDecimals = nInteger = nExpDigits = nExpInterval = nNumerDigits = nDenomDigits =
nFracDenominator = nMinDecimalDigits = -1;
bGrouping = bDecReplace = false;
bExpSign = true;
fDisplayFactor = 1.0;
}
......@@ -273,6 +274,7 @@ enum SvXMLStyleAttrTokens
enum SvXMLStyleElemAttrTokens
{
XML_TOK_ELEM_ATTR_DECIMAL_PLACES,
XML_TOK_ELEM_ATTR_MIN_DECIMAL_DIGITS,
XML_TOK_ELEM_ATTR_MIN_INTEGER_DIGITS,
XML_TOK_ELEM_ATTR_GROUPING,
XML_TOK_ELEM_ATTR_DISPLAY_FACTOR,
......@@ -570,6 +572,7 @@ const SvXMLTokenMap& SvXMLNumImpData::GetStyleElemAttrTokenMap()
{
// attributes for an element within a style
{ XML_NAMESPACE_NUMBER, XML_DECIMAL_PLACES, XML_TOK_ELEM_ATTR_DECIMAL_PLACES },
{ XML_NAMESPACE_LO_EXT, XML_MIN_DECIMAL_DIGITS, XML_TOK_ELEM_ATTR_MIN_DECIMAL_DIGITS },
{ XML_NAMESPACE_NUMBER, XML_MIN_INTEGER_DIGITS, XML_TOK_ELEM_ATTR_MIN_INTEGER_DIGITS },
{ XML_NAMESPACE_NUMBER, XML_GROUPING, XML_TOK_ELEM_ATTR_GROUPING },
{ XML_NAMESPACE_NUMBER, XML_DISPLAY_FACTOR, XML_TOK_ELEM_ATTR_DISPLAY_FACTOR },
......@@ -924,6 +927,7 @@ SvXMLNumFmtElementContext::SvXMLNumFmtElementContext( SvXMLImport& rImport,
LanguageTagODF aLanguageTagODF;
sal_Int32 nAttrVal;
bool bAttrBool(false);
bool bVarDecimals = false;
sal_uInt16 nAttrEnum;
double fAttrDouble;
......@@ -944,6 +948,10 @@ SvXMLNumFmtElementContext::SvXMLNumFmtElementContext( SvXMLImport& rImport,
if (::sax::Converter::convertNumber( nAttrVal, sValue, 0 ))
aNumInfo.nDecimals = std::min<sal_Int32>(nAttrVal, MAX_SECOND_DIGITS);
break;
case XML_TOK_ELEM_ATTR_MIN_DECIMAL_DIGITS:
if (::sax::Converter::convertNumber( nAttrVal, sValue, 0 ))
aNumInfo.nMinDecimalDigits = nAttrVal;
break;
case XML_TOK_ELEM_ATTR_MIN_INTEGER_DIGITS:
if (::sax::Converter::convertNumber( nAttrVal, sValue, 0 ))
aNumInfo.nInteger = nAttrVal;
......@@ -960,7 +968,7 @@ SvXMLNumFmtElementContext::SvXMLNumFmtElementContext( SvXMLImport& rImport,
if ( !sValue.isEmpty() )
aNumInfo.bDecReplace = true; // only a default string is supported
else
aNumInfo.bVarDecimals = true; // empty replacement string: variable decimals
bVarDecimals = true; // empty replacement string: variable decimals
break;
case XML_TOK_ELEM_ATTR_MIN_EXPONENT_DIGITS:
if (::sax::Converter::convertNumber( nAttrVal, sValue, 0 ))
......@@ -1011,6 +1019,13 @@ SvXMLNumFmtElementContext::SvXMLNumFmtElementContext( SvXMLImport& rImport,
break;
}
}
if ( aNumInfo.nMinDecimalDigits == -1)
{
if ( bVarDecimals )
aNumInfo.nMinDecimalDigits = 0;
else
aNumInfo.nMinDecimalDigits = aNumInfo.nDecimals;
}
if ( !aLanguageTagODF.isEmpty() )
{
......@@ -1799,7 +1814,9 @@ void SvXMLNumFormatContext::AddNumber( const SvXMLNumberInfo& rInfo )
}
sal_uInt16 nGenPrec = nPrec;
if ( rInfo.bDecReplace || rInfo.bVarDecimals )
if ( rInfo.nMinDecimalDigits >= 0 )
nGenPrec = rInfo.nMinDecimalDigits;
if ( rInfo.bDecReplace )
nGenPrec = 0; // generate format without decimals...
bool bGrouping = rInfo.bGrouping;
......@@ -1892,13 +1909,14 @@ void SvXMLNumFormatContext::AddNumber( const SvXMLNumberInfo& rInfo )
aFormatCode.append( aNumStr.makeStringAndClear() );
if ( ( rInfo.bDecReplace || rInfo.bVarDecimals ) && nPrec ) // add decimal replacement (dashes)
if ( ( rInfo.bDecReplace || rInfo.nMinDecimalDigits < rInfo.nDecimals ) && nPrec ) // add decimal replacement (dashes)
{
// add dashes for explicit decimal replacement, # for variable decimals
sal_Unicode cAdd = rInfo.bDecReplace ? '-' : '#';
if ( rInfo.nMinDecimalDigits == 0 )
aFormatCode.append( pData->GetLocaleData( nFormatLang ).getNumDecimalSep() );
for ( sal_uInt16 i=0; i<nPrec; i++)
for ( sal_uInt16 i=rInfo.nMinDecimalDigits; i<nPrec; i++)
aFormatCode.append( cAdd );
}
......
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