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