summaryrefslogtreecommitdiff
path: root/xmloff
diff options
context:
space:
mode:
authorLaurent Balland <laurent.balland@mailo.fr>2023-07-26 17:58:00 +0200
committerLaurent Balland <laurent.balland@mailo.fr>2023-11-01 11:43:54 +0100
commit443027cd71aef3eb45bbf3631869ea63457f2c81 (patch)
tree4c8bcf044493e24de7077f48f0f77036fdd35a7a /xmloff
parent5d7d7eb55a3833ff12c61b1a03a296bb0bf4e640 (diff)
tdf#156449 Preserve '0' or '?' in exponent
Exponent in scientific number may use '?' as blank like in format "0.00E+?0" This change: - adds interpreatation of '0' and '?' in exponent - adds "blank-exponent-digits" attribute to scientific number for import and export to ODF - prevents using exponent with only '?'. There must be at least one '0' in exponent - adds QA test of such format and test import/export/import to ODF and OOXML - corrects one basic test Change-Id: If52edc632a161f842270bb2fd77af535e2b978d4 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154986 Tested-by: Jenkins Reviewed-by: Laurent Balland <laurent.balland@mailo.fr>
Diffstat (limited to 'xmloff')
-rw-r--r--xmloff/source/core/xmltoken.cxx1
-rw-r--r--xmloff/source/style/xmlnumfe.cxx20
-rw-r--r--xmloff/source/style/xmlnumfi.cxx16
-rw-r--r--xmloff/source/token/tokens.txt1
4 files changed, 33 insertions, 5 deletions
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index 00234904e7b4..6879f37db295 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -3474,6 +3474,7 @@ namespace xmloff::token {
TOKEN( "exponent-interval", XML_EXPONENT_INTERVAL ),
TOKEN( "exponent-lowercase", XML_EXPONENT_LOWERCASE ),
TOKEN( "forced-exponent-sign", XML_FORCED_EXPONENT_SIGN ),
+ TOKEN( "blank-exponent-digits", XML_BLANK_EXPONENT_DIGITS ),
TOKEN( "min-decimal-places", XML_MIN_DECIMAL_PLACES ),
TOKEN( "max-denominator-value", XML_MAX_DENOMINATOR_VALUE ),
TOKEN( "max-numerator-digits", XML_MAX_NUMERATOR_DIGITS ),
diff --git a/xmloff/source/style/xmlnumfe.cxx b/xmloff/source/style/xmlnumfe.cxx
index ee09dd0b39d8..406c22236a71 100644
--- a/xmloff/source/style/xmlnumfe.cxx
+++ b/xmloff/source/style/xmlnumfe.cxx
@@ -695,7 +695,7 @@ void SvXMLNumFmtExport::WriteNumberElement_Impl(
void SvXMLNumFmtExport::WriteScientificElement_Impl(
sal_Int32 nDecimals, sal_Int32 nMinDecimals, sal_Int32 nInteger, sal_Int32 nBlankInteger,
- bool bGrouping, sal_Int32 nExp, sal_Int32 nExpInterval, bool bExpSign, bool bExponentLowercase,
+ bool bGrouping, sal_Int32 nExp, sal_Int32 nExpInterval, bool bExpSign, bool bExponentLowercase, sal_Int32 nBlankExp,
const SvXMLEmbeddedTextEntryArr& rEmbeddedEntries )
{
FinishTextElement_Impl();
@@ -759,6 +759,12 @@ void SvXMLNumFmtExport::WriteScientificElement_Impl(
{
if (bExponentLowercase)
m_rExport.AddAttribute( XML_NAMESPACE_LO_EXT, XML_EXPONENT_LOWERCASE, XML_TRUE );
+ if (nBlankExp > 0)
+ {
+ if (nBlankExp >= nExp)
+ nBlankExp = nExp - 1; // preserve at least one '0' in exponent
+ m_rExport.AddAttribute( XML_NAMESPACE_LO_EXT, XML_BLANK_EXPONENT_DIGITS, OUString::number( nBlankExp ) );
+ }
}
SvXMLElementExport aElem( m_rExport,
@@ -1360,7 +1366,8 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
bool bExpSign = true;
bool bExponentLowercase = false; // 'e' or 'E' for scientific notation
bool bDecAlign = false; // decimal alignment with "?"
- sal_Int32 nExpDigits = 0;
+ sal_Int32 nExpDigits = 0; // '0' and '?' in exponent
+ sal_Int32 nBlankExp = 0; // only '?' in exponent
sal_Int32 nIntegerSymbols = 0; // for embedded-text, including "#"
sal_Int32 nTrailingThousands = 0; // thousands-separators after all digits
sal_Int32 nMinDecimals = nPrecision;
@@ -1383,7 +1390,14 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
break;
case NF_SYMBOLTYPE_DIGIT:
if ( bExpFound && pElemStr )
+ {
nExpDigits += pElemStr->getLength();
+ for ( sal_Int32 i = pElemStr->getLength()-1; i >= 0 ; i-- )
+ {
+ if ( (*pElemStr)[i] == '?' )
+ nBlankExp ++;
+ }
+ }
else if ( !bDecDashes && pElemStr && (*pElemStr)[0] == '-' )
{
bDecDashes = true;
@@ -1682,7 +1696,7 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
// as integer digits: use nIntegerSymbols instead of nLeading
// nIntegerSymbols represents exponent interval (for engineering notation)
WriteScientificElement_Impl( nPrecision, nMinDecimals, nLeading, nBlankInteger, bThousand, nExpDigits, nIntegerSymbols, bExpSign,
- bExponentLowercase, aEmbeddedEntries );
+ bExponentLowercase, nBlankExp, aEmbeddedEntries );
bAnyContent = true;
break;
case SvNumFormatType::FRACTION:
diff --git a/xmloff/source/style/xmlnumfi.cxx b/xmloff/source/style/xmlnumfi.cxx
index d72914937eb3..f6d05e94c1bf 100644
--- a/xmloff/source/style/xmlnumfi.cxx
+++ b/xmloff/source/style/xmlnumfi.cxx
@@ -90,7 +90,8 @@ struct SvXMLNumberInfo
sal_Int32 nDecimals = -1;
sal_Int32 nInteger = -1; /// Total min number of digits in integer part ('0' + '?')
sal_Int32 nBlankInteger = -1; /// Number of '?' in integer part
- sal_Int32 nExpDigits = -1;
+ sal_Int32 nExpDigits = -1; /// Number of '0' and '?' in exponent
+ sal_Int32 nBlankExp = -1; /// Number of '?' in exponent
sal_Int32 nExpInterval = -1;
sal_Int32 nMinNumerDigits = -1;
sal_Int32 nMinDenomDigits = -1;
@@ -713,6 +714,11 @@ SvXMLNumFmtElementContext::SvXMLNumFmtElementContext( SvXMLImport& rImport,
if (::sax::Converter::convertNumber( nAttrVal, aIter.toView(), 0 ))
aNumInfo.nExpDigits = std::min<sal_Int32>(nAttrVal, NF_MAX_FORMAT_SYMBOLS);
break;
+ case XML_ELEMENT(NUMBER, XML_BLANK_EXPONENT_DIGITS):
+ case XML_ELEMENT(LO_EXT, XML_BLANK_EXPONENT_DIGITS):
+ if (::sax::Converter::convertNumber( nAttrVal, aIter.toView(), 0 ))
+ aNumInfo.nBlankExp = std::min<sal_Int32>(nAttrVal, NF_MAX_FORMAT_SYMBOLS);
+ break;
case XML_ELEMENT(NUMBER, XML_EXPONENT_INTERVAL):
case XML_ELEMENT(LO_EXT, XML_EXPONENT_INTERVAL):
if (::sax::Converter::convertNumber( nAttrVal, aIter.toView(), 0 ))
@@ -808,6 +814,9 @@ SvXMLNumFmtElementContext::SvXMLNumFmtElementContext( SvXMLImport& rImport,
else
aNumInfo.nMinDecimalDigits = aNumInfo.nDecimals;
}
+ if ( aNumInfo.nExpDigits > 0 && aNumInfo.nBlankExp >= aNumInfo.nExpDigits )
+ aNumInfo.nBlankExp = aNumInfo.nExpDigits - 1; // at least one '0' in exponent
+
if ( aNumInfo.nZerosDenomDigits > 0 )
{ // nMin = count of '0' and '?'
if ( aNumInfo.nMinDenomDigits < aNumInfo.nZerosDenomDigits )
@@ -1878,7 +1887,10 @@ void SvXMLNumFormatContext::AddNumber( const SvXMLNumberInfo& rInfo )
}
for (sal_Int32 i=0; i<rInfo.nExpDigits; i++)
{
- aNumStr.append( '0' );
+ if ( i < rInfo.nBlankExp )
+ aNumStr.append( '?' );
+ else
+ aNumStr.append( '0' );
}
}
diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt
index cdd387702531..7eb09f6f2f9f 100644
--- a/xmloff/source/token/tokens.txt
+++ b/xmloff/source/token/tokens.txt
@@ -3230,6 +3230,7 @@ external-data
exponent-interval
exponent-lowercase
forced-exponent-sign
+blank-exponent-digits
min-decimal-places
max-denominator-value
max-numerator-digits