summaryrefslogtreecommitdiff
path: root/xmloff
diff options
context:
space:
mode:
authorLaurent BP <laurent.balland-poirier@laposte.net>2022-05-16 22:47:25 +0200
committerEike Rathke <erack@redhat.com>2022-07-12 18:01:58 +0200
commit56dff7b244fb0ef28951193a410dd5c4a3126590 (patch)
treecee5745a2f37f2ec2c5dc74bbed901726497745b /xmloff
parent2dde21ea74223ca68865ee87558baad0d3eb4e46 (diff)
tdf#96723 Number format: embedded text in decimal
Embedded text in decimal part is represented by negative position Use number:position as it is defined as integer in schema [1] Add Unit test to import XLSX file with embedded text in decimal and export to ODS [1] https://opengrok.libreoffice.org/xref/core/schema/odf1.3/OpenDocument-v1.3-schema.rng?r=7f3c9da5#7142 Change-Id: Ic68471a071ccbb1c3bec442bfcbe21d84f41ebd8 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135918 Tested-by: Jenkins Reviewed-by: Eike Rathke <erack@redhat.com>
Diffstat (limited to 'xmloff')
-rw-r--r--xmloff/source/style/xmlnumfe.cxx13
-rw-r--r--xmloff/source/style/xmlnumfi.cxx32
2 files changed, 27 insertions, 18 deletions
diff --git a/xmloff/source/style/xmlnumfe.cxx b/xmloff/source/style/xmlnumfe.cxx
index c4350c0db795..abf03285f818 100644
--- a/xmloff/source/style/xmlnumfe.cxx
+++ b/xmloff/source/style/xmlnumfe.cxx
@@ -603,6 +603,8 @@ void SvXMLNumFmtExport::WriteNumberElement_Impl(
const SvXMLEmbeddedTextEntry *const pObj = &rEmbeddedEntries[nEntry];
// position attribute
+ // position == 0 is between first integer digit and decimal separator
+ // position < 0 is inside decimal part
rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_POSITION,
OUString::number( pObj->nFormatPos ) );
SvXMLElementExport aChildElem( rExport, XML_NAMESPACE_NUMBER, XML_EMBEDDED_TEXT,
@@ -1389,6 +1391,10 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
if ( bAllowEmbedded )
{
sal_Int32 nDigitsPassed = 0;
+ sal_Int32 nEmbeddedPositionsMax = nIntegerSymbols;
+ // Enable embedded text in decimal part only if there's a decimal part
+ if ( nPrecision )
+ nEmbeddedPositionsMax += nPrecision + 1;
nPos = 0;
bEnd = false;
while (!bEnd)
@@ -1405,12 +1411,15 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
if ( pElemStr )
nDigitsPassed += pElemStr->getLength();
break;
+ case NF_SYMBOLTYPE_DECSEP:
+ nDigitsPassed++;
+ break;
case NF_SYMBOLTYPE_STRING:
case NF_SYMBOLTYPE_BLANK:
case NF_SYMBOLTYPE_PERCENT:
- if ( nDigitsPassed > 0 && nDigitsPassed < nIntegerSymbols && pElemStr )
+ if ( 0 < nDigitsPassed && nDigitsPassed < nEmbeddedPositionsMax && pElemStr )
{
- // text (literal or underscore) within the integer part of a number:number element
+ // text (literal or underscore) within the integer (>=0) or decimal (<0) part of a number:number element
OUString aEmbeddedStr;
if ( nElemType == NF_SYMBOLTYPE_STRING || nElemType == NF_SYMBOLTYPE_PERCENT )
diff --git a/xmloff/source/style/xmlnumfi.cxx b/xmloff/source/style/xmlnumfi.cxx
index 618232990c96..bedd13bebcf6 100644
--- a/xmloff/source/style/xmlnumfi.cxx
+++ b/xmloff/source/style/xmlnumfi.cxx
@@ -457,7 +457,7 @@ SvXMLNumFmtEmbeddedTextContext::SvXMLNumFmtEmbeddedTextContext( SvXMLImport& rIm
{
if ( aIter.getToken() == XML_ELEMENT(NUMBER, XML_POSITION) )
{
- if (::sax::Converter::convertNumber( nAttrVal, aIter.toView(), 0 ))
+ if (::sax::Converter::convertNumber( nAttrVal, aIter.toView() ))
nTextPosition = nAttrVal;
}
else
@@ -1707,8 +1707,8 @@ void SvXMLNumFormatContext::AddNumber( const SvXMLNumberInfo& rInfo )
bool bGrouping = rInfo.bGrouping;
size_t const nEmbeddedCount = rInfo.m_EmbeddedElements.size();
- if ( nEmbeddedCount )
- bGrouping = false; // grouping and embedded characters can't be used together
+ if ( nEmbeddedCount && rInfo.m_EmbeddedElements.rbegin()->first > 0 )
+ bGrouping = false; // grouping and embedded characters in integer part can't be used together
sal_uInt32 nStdIndex = pFormatter->GetStandardIndex( nFormatLang );
OUStringBuffer aNumStr(pFormatter->GenerateFormat( nStdIndex, nFormatLang,
@@ -1746,10 +1746,21 @@ void SvXMLNumFormatContext::AddNumber( const SvXMLNumberInfo& rInfo )
}
}
+ if ( ( rInfo.bDecReplace || rInfo.nMinDecimalDigits < rInfo.nDecimals ) && nPrec ) // add decimal replacement (dashes)
+ {
+ // add dashes for explicit decimal replacement, # or ? for variable decimals
+ sal_Unicode cAdd = rInfo.bDecReplace ? '-' : ( rInfo.bDecAlign ? '?': '#' );
+
+ if ( rInfo.nMinDecimalDigits == 0 )
+ aNumStr.append( pData->GetLocaleData( nFormatLang ).getNumDecimalSep() );
+ for ( sal_uInt16 i=rInfo.nMinDecimalDigits; i<nPrec; i++)
+ aNumStr.append( cAdd );
+ }
+
if ( nEmbeddedCount )
{
// insert embedded strings into number string
- // only the integer part is supported
+ // support integer (position >=0) and decimal (position <0) part
// nZeroPos is the string position where format position 0 is inserted
sal_Int32 nZeroPos = aNumStr.indexOf( pData->GetLocaleData( nFormatLang ).getNumDecimalSep() );
@@ -1778,7 +1789,7 @@ void SvXMLNumFormatContext::AddNumber( const SvXMLNumberInfo& rInfo )
{
sal_Int32 const nFormatPos = it.first;
sal_Int32 nInsertPos = nZeroPos - nFormatPos;
- if ( nFormatPos >= 0 && nInsertPos >= 0 )
+ if ( nInsertPos >= 0 )
{
// #107805# always quote embedded strings - even space would otherwise
// be recognized as thousands separator in French.
@@ -1792,17 +1803,6 @@ void SvXMLNumFormatContext::AddNumber( const SvXMLNumberInfo& rInfo )
aFormatCode.append( aNumStr );
- if ( ( rInfo.bDecReplace || rInfo.nMinDecimalDigits < rInfo.nDecimals ) && nPrec ) // add decimal replacement (dashes)
- {
- // add dashes for explicit decimal replacement, # or ? for variable decimals
- sal_Unicode cAdd = rInfo.bDecReplace ? '-' : ( rInfo.bDecAlign ? '?': '#' );
-
- if ( rInfo.nMinDecimalDigits == 0 )
- aFormatCode.append( pData->GetLocaleData( nFormatLang ).getNumDecimalSep() );
- for ( sal_uInt16 i=rInfo.nMinDecimalDigits; i<nPrec; i++)
- aFormatCode.append( cAdd );
- }
-
// add extra thousands separators for display factor
if (rInfo.fDisplayFactor == 1.0 || rInfo.fDisplayFactor <= 0.0)