summaryrefslogtreecommitdiff
path: root/xmloff
diff options
context:
space:
mode:
authorLaurent Balland <laurent.balland@mailo.fr>2023-07-01 10:43:39 +0200
committerLaurent Balland <laurent.balland@mailo.fr>2023-11-01 09:10:19 +0100
commitcc721291cc4a53503398b82dd86baa521b2b13cc (patch)
treeab0e2bc3e9cd0d27adf98154e226270c56c18991 /xmloff
parente8228e0994610fed8af090ff30ffc08bfecb7261 (diff)
tdf#153993 Extend ODF: lowercase for exponent char
In scientific format, user may want to have clearer format such as: 0.000" "000" "e+" "0 This change - adds "exponent-lowercase" boolean attribute to scientific-number format to preserve "e" or "E" char - includes all positions up to exponent for embedded text of scientific number Add QA test Change-Id: Ie263f4ecf30a1a8dcd8046e1e048767020e54dc2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153824 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.cxx24
-rw-r--r--xmloff/source/style/xmlnumfi.cxx40
-rw-r--r--xmloff/source/token/tokens.txt1
4 files changed, 53 insertions, 13 deletions
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index fa439f9f367b..00234904e7b4 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -3472,6 +3472,7 @@ namespace xmloff::token {
TOKEN( "external-data", XML_EXTERNALDATA),
TOKEN( "exponent-interval", XML_EXPONENT_INTERVAL ),
+ TOKEN( "exponent-lowercase", XML_EXPONENT_LOWERCASE ),
TOKEN( "forced-exponent-sign", XML_FORCED_EXPONENT_SIGN ),
TOKEN( "min-decimal-places", XML_MIN_DECIMAL_PLACES ),
TOKEN( "max-denominator-value", XML_MAX_DENOMINATOR_VALUE ),
diff --git a/xmloff/source/style/xmlnumfe.cxx b/xmloff/source/style/xmlnumfe.cxx
index 67675cf22ab3..ee09dd0b39d8 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 bGrouping, sal_Int32 nExp, sal_Int32 nExpInterval, bool bExpSign, bool bExponentLowercase,
const SvXMLEmbeddedTextEntryArr& rEmbeddedEntries )
{
FinishTextElement_Impl();
@@ -753,6 +753,13 @@ void SvXMLNumFmtExport::WriteScientificElement_Impl(
XML_FORCED_EXPONENT_SIGN,
bExpSign? XML_TRUE : XML_FALSE );
}
+ // exponent string
+ // Export only for 1.x with extensions
+ if (eVersion & SvtSaveOptions::ODFSVER_EXTENDED)
+ {
+ if (bExponentLowercase)
+ m_rExport.AddAttribute( XML_NAMESPACE_LO_EXT, XML_EXPONENT_LOWERCASE, XML_TRUE );
+ }
SvXMLElementExport aElem( m_rExport,
XML_NAMESPACE_NUMBER, XML_SCIENTIFIC_NUMBER,
@@ -1351,6 +1358,7 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
bool bCurrFound = false;
bool bInInteger = true;
bool bExpSign = true;
+ bool bExponentLowercase = false; // 'e' or 'E' for scientific notation
bool bDecAlign = false; // decimal alignment with "?"
sal_Int32 nExpDigits = 0;
sal_Int32 nIntegerSymbols = 0; // for embedded-text, including "#"
@@ -1421,6 +1429,8 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
if ( pElemStr && ( pElemStr->getLength() == 1
|| ( pElemStr->getLength() == 2 && (*pElemStr)[1] == '-' ) ) )
bExpSign = false; // for 0.00E0 or 0.00E-00
+ if ( pElemStr && (*pElemStr)[0] == 'e' )
+ bExponentLowercase = true; // for 0.00e+00
break;
case NF_SYMBOLTYPE_CURRENCY:
bCurrFound = true;
@@ -1459,8 +1469,12 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
// Enable embedded text in decimal part only if there's a decimal part
if ( nPrecision )
nEmbeddedPositionsMax += nPrecision + 1;
+ // Enable embedded text in exponent in scientific number
+ if ( nFmtType == SvNumFormatType::SCIENTIFIC )
+ nEmbeddedPositionsMax += 1 + nExpDigits;
nPos = 0;
bEnd = false;
+ bExpFound = false;
while (!bEnd)
{
short nElemType = rFormat.GetNumForType( nPart, nPos );
@@ -1475,6 +1489,9 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
if ( pElemStr )
nDigitsPassed += pElemStr->getLength();
break;
+ case NF_SYMBOLTYPE_EXP:
+ bExpFound = true;
+ [[fallthrough]];
case NF_SYMBOLTYPE_DECSEP:
nDigitsPassed++;
break;
@@ -1505,6 +1522,9 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
aEmbeddedEntries.push_back(
SvXMLEmbeddedTextEntry( nPos, nEmbedPos, aEmbeddedStr, bSaveBlankWidthSymbol ));
+ // exponent sign is required with embedded text in exponent
+ if ( bExpFound && !bExpSign )
+ bExpSign = true;
}
break;
}
@@ -1662,7 +1682,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,
- aEmbeddedEntries );
+ bExponentLowercase, aEmbeddedEntries );
bAnyContent = true;
break;
case SvNumFormatType::FRACTION:
diff --git a/xmloff/source/style/xmlnumfi.cxx b/xmloff/source/style/xmlnumfi.cxx
index f9f9bce5f675..d72914937eb3 100644
--- a/xmloff/source/style/xmlnumfi.cxx
+++ b/xmloff/source/style/xmlnumfi.cxx
@@ -103,6 +103,7 @@ struct SvXMLNumberInfo
bool bGrouping = false;
bool bDecReplace = false;
bool bExpSign = true;
+ bool bExponentLowercase = false; /// Exponent is 'e' instead of 'E'
bool bDecAlign = false;
double fDisplayFactor = 1.0;
OUString aIntegerFractionDelimiter;
@@ -722,6 +723,11 @@ SvXMLNumFmtElementContext::SvXMLNumFmtElementContext( SvXMLImport& rImport,
if (::sax::Converter::convertBool( bAttrBool, aIter.toView() ))
aNumInfo.bExpSign = bAttrBool;
break;
+ case XML_ELEMENT(NUMBER, XML_EXPONENT_LOWERCASE):
+ case XML_ELEMENT(LO_EXT, XML_EXPONENT_LOWERCASE):
+ if (::sax::Converter::convertBool( bAttrBool, aIter.toView() ))
+ aNumInfo.bExponentLowercase = bAttrBool;
+ break;
case XML_ELEMENT(NUMBER, XML_MIN_NUMERATOR_DIGITS):
if (::sax::Converter::convertNumber( nAttrVal, aIter.toView(), 0 ))
aNumInfo.nMinNumerDigits = nAttrVal;
@@ -1173,16 +1179,7 @@ void SvXMLNumFmtElementContext::endFastElement(sal_Int32 )
rParent.AddToCode( '#' );
}
}
- rParent.AddNumber( aNumInfo ); // simple number
-
- if ( aNumInfo.bExpSign )
- rParent.AddToCode( u"E+" );
- else
- rParent.AddToCode( u"E" );
- for (sal_Int32 i=0; i<aNumInfo.nExpDigits; i++)
- {
- rParent.AddToCode( '0' );
- }
+ rParent.AddNumber( aNumInfo ); // number and exponent
}
break;
@@ -1868,6 +1865,23 @@ void SvXMLNumFormatContext::AddNumber( const SvXMLNumberInfo& rInfo )
aNumStr.append( cAdd );
}
+ // Scientific number
+ sal_Int32 nExpPos = -1;
+ if ( rInfo.nExpDigits > 0 )
+ {
+ nExpPos = aNumStr.getLength();
+ aNumStr.append( rInfo.bExponentLowercase ? u"e" : u"E" );
+ // exponent sign is required with embedded text in exponent
+ if ( rInfo.bExpSign || ( nEmbeddedCount && ( rInfo.nDecimals + 1 < -rInfo.m_EmbeddedElements.begin()->first ) ) )
+ {
+ aNumStr.append( u"+" );
+ }
+ for (sal_Int32 i=0; i<rInfo.nExpDigits; i++)
+ {
+ aNumStr.append( '0' );
+ }
+ }
+
if ( nEmbeddedCount )
{
// insert embedded strings into number string
@@ -1893,6 +1907,8 @@ void SvXMLNumFormatContext::AddNumber( const SvXMLNumberInfo& rInfo )
aNumStr.insert(0, '#');
}
nZeroPos = nZeroPos + nAddCount;
+ if ( nExpPos > 0 )
+ nExpPos = nExpPos + nAddCount;
}
// m_EmbeddedElements is sorted with ascending positions - loop is from right to left
@@ -1900,7 +1916,9 @@ void SvXMLNumFormatContext::AddNumber( const SvXMLNumberInfo& rInfo )
{
sal_Int32 const nFormatPos = it.first;
sal_Int32 nInsertPos = nZeroPos - nFormatPos;
- if ( nInsertPos >= 0 )
+ if ( nExpPos > 0 && nInsertPos > nExpPos )
+ nInsertPos ++;
+ if ( 0 <= nInsertPos && nInsertPos <= aNumStr.getLength() )
{
aNumStr.insert( nInsertPos, it.second );
}
diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt
index 85d947387e20..cdd387702531 100644
--- a/xmloff/source/token/tokens.txt
+++ b/xmloff/source/token/tokens.txt
@@ -3228,6 +3228,7 @@ display-units
display-units-built-in-unit
external-data
exponent-interval
+exponent-lowercase
forced-exponent-sign
min-decimal-places
max-denominator-value