related tdf#153993 Embedded text in scientific numbers
Embedded text was limited to number:number. But scientific notation may
require embedded text like
0.000" "000E+00
This change extend ODF format to support embedded text in
number:scientific-number also
Change-Id: I4e3220b06efbd9228d722bf518e137d7707ccf4f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/150804
Tested-by: Jenkins
Reviewed-by: Eike Rathke <erack@redhat.com>
diff --git a/include/xmloff/xmlnumfe.hxx b/include/xmloff/xmlnumfe.hxx
index fd0711b..43e1814 100644
--- a/include/xmloff/xmlnumfe.hxx
+++ b/include/xmloff/xmlnumfe.hxx
@@ -64,12 +64,14 @@ private:
SAL_DLLPRIVATE void WriteColorElement_Impl( const Color& rColor );
SAL_DLLPRIVATE void WriteIntegerElement_Impl( sal_Int32 nInteger, sal_Int32 nBlankInteger, bool bGrouping );
SAL_DLLPRIVATE void WriteEmbeddedEntries_Impl( const SvXMLEmbeddedTextEntryArr& rEmbeddedEntries );
SAL_DLLPRIVATE void WriteNumberElement_Impl( sal_Int32 nDecimals, sal_Int32 nMinDecimals,
sal_Int32 nInteger, sal_Int32 nBlankInteger, const OUString& rDashStr,
bool bGrouping, sal_Int32 nTrailingThousands,
const SvXMLEmbeddedTextEntryArr& rEmbeddedEntries );
SAL_DLLPRIVATE void 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,
const SvXMLEmbeddedTextEntryArr& rEmbeddedEntries );
SAL_DLLPRIVATE void WriteFractionElement_Impl( sal_Int32 nInteger, sal_Int32 nBlankInteger, bool bGrouping,
const SvNumberformat& rFormat, sal_uInt16 nPart );
SAL_DLLPRIVATE void WriteCurrencyElement_Impl( const OUString& rString,
diff --git a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
index f01e1c8..6bb2c69 100644
--- a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
+++ b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
@@ -1995,6 +1995,19 @@ xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.
</rng:element>
</rng:define>
<rng:define name="number-scientific-number">
<rng:element name="number:scientific-number">
<rng:ref name="number-scientific-number-attlist"/>
<rng:ref name="common-decimal-places-attlist"/>
<rng:ref name="common-number-attlist"/>
<!-- TODO no proposal -->
<rng:zeroOrMore>
<rng:ref name="number-embedded-text"/>
</rng:zeroOrMore>
<rng:empty/>
</rng:element>
</rng:define>
</rng:include>
<!-- TODO no proposal -->
diff --git a/xmloff/source/style/xmlnumfe.cxx b/xmloff/source/style/xmlnumfe.cxx
index 59e9f77..fb767dc 100644
--- a/xmloff/source/style/xmlnumfe.cxx
+++ b/xmloff/source/style/xmlnumfe.cxx
@@ -550,6 +550,35 @@ void SvXMLNumFmtExport::WriteIntegerElement_Impl(
}
}
void SvXMLNumFmtExport::WriteEmbeddedEntries_Impl( const SvXMLEmbeddedTextEntryArr& rEmbeddedEntries )
{
auto nEntryCount = rEmbeddedEntries.size();
for (decltype(nEntryCount) nEntry=0; nEntry < nEntryCount; ++nEntry)
{
const SvXMLEmbeddedTextEntry *const pObj = &rEmbeddedEntries[nEntry];
// position attribute
// position == 0 is between first integer digit and decimal separator
// position < 0 is inside decimal part
m_rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_POSITION,
OUString::number( pObj->nFormatPos ) );
SvXMLElementExport aChildElem( m_rExport, XML_NAMESPACE_NUMBER, XML_EMBEDDED_TEXT,
true, false );
// text as element content
OUStringBuffer aContent( pObj->aText );
while ( nEntry+1 < nEntryCount && rEmbeddedEntries[nEntry+1].nFormatPos == pObj->nFormatPos )
{
// The array can contain several elements for the same position in the number
// (for example, literal text and space from underscores). They must be merged
// into a single embedded-text element.
aContent.append(rEmbeddedEntries[nEntry+1].aText);
++nEntry;
}
m_rExport.Characters( aContent.makeStringAndClear() );
}
}
void SvXMLNumFmtExport::WriteNumberElement_Impl(
sal_Int32 nDecimals, sal_Int32 nMinDecimals,
sal_Int32 nInteger, sal_Int32 nBlankInteger, const OUString& rDashStr,
@@ -565,10 +594,10 @@ void SvXMLNumFmtExport::WriteNumberElement_Impl(
OUString::number( nDecimals ) );
}
SvtSaveOptions::ODFSaneDefaultVersion eVersion = m_rExport.getSaneDefaultVersion();
if ( nMinDecimals >= 0 ) // negative = automatic
{
// Export only for 1.2 with extensions or 1.3 and later.
SvtSaveOptions::ODFSaneDefaultVersion eVersion = m_rExport.getSaneDefaultVersion();
if (eVersion > SvtSaveOptions::ODFSVER_012)
{
// OFFICE-3860 For 1.2+ use loext namespace, for 1.3 use number namespace.
@@ -603,37 +632,13 @@ void SvXMLNumFmtExport::WriteNumberElement_Impl(
true, true );
// number:embedded-text as child elements
auto nEntryCount = rEmbeddedEntries.size();
for (decltype(nEntryCount) nEntry=0; nEntry < nEntryCount; ++nEntry)
{
const SvXMLEmbeddedTextEntry *const pObj = &rEmbeddedEntries[nEntry];
// position attribute
// position == 0 is between first integer digit and decimal separator
// position < 0 is inside decimal part
m_rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_POSITION,
OUString::number( pObj->nFormatPos ) );
SvXMLElementExport aChildElem( m_rExport, XML_NAMESPACE_NUMBER, XML_EMBEDDED_TEXT,
true, false );
// text as element content
OUStringBuffer aContent( pObj->aText );
while ( nEntry+1 < nEntryCount && rEmbeddedEntries[nEntry+1].nFormatPos == pObj->nFormatPos )
{
// The array can contain several elements for the same position in the number
// (for example, literal text and space from underscores). They must be merged
// into a single embedded-text element.
aContent.append(rEmbeddedEntries[nEntry+1].aText);
++nEntry;
}
m_rExport.Characters( aContent.makeStringAndClear() );
}
WriteEmbeddedEntries_Impl( rEmbeddedEntries );
}
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,
const SvXMLEmbeddedTextEntryArr& rEmbeddedEntries )
{
FinishTextElement_Impl();
@@ -694,6 +699,11 @@ void SvXMLNumFmtExport::WriteScientificElement_Impl(
SvXMLElementExport aElem( m_rExport,
XML_NAMESPACE_NUMBER, XML_SCIENTIFIC_NUMBER,
true, false );
// number:embedded-text as child elements
// Export only for 1.x with extensions
if (eVersion & SvtSaveOptions::ODFSVER_EXTENDED)
WriteEmbeddedEntries_Impl( rEmbeddedEntries );
}
void SvXMLNumFmtExport::WriteFractionElement_Impl(
@@ -1379,9 +1389,11 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
}
// collect strings for embedded-text (must be known before number element is written)
SvtSaveOptions::ODFSaneDefaultVersion eVersion = m_rExport.getSaneDefaultVersion();
bool bAllowEmbedded = ( nFmtType == SvNumFormatType::ALL || nFmtType == SvNumFormatType::NUMBER ||
nFmtType == SvNumFormatType::CURRENCY ||
// Export only for 1.x with extensions
( nFmtType == SvNumFormatType::SCIENTIFIC && (eVersion & SvtSaveOptions::ODFSVER_EXTENDED) )||
nFmtType == SvNumFormatType::PERCENT );
if ( bAllowEmbedded )
{
@@ -1586,7 +1598,8 @@ 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, nMinDecimals, nLeading, nBlankInteger, bThousand, nExpDigits, nIntegerSymbols, bExpSign );
WriteScientificElement_Impl( nPrecision, nMinDecimals, nLeading, nBlankInteger, bThousand, nExpDigits, nIntegerSymbols, bExpSign,
aEmbeddedEntries );
bAnyContent = true;
break;
case SvNumFormatType::FRACTION:
diff --git a/xmloff/source/style/xmlnumfi.cxx b/xmloff/source/style/xmlnumfi.cxx
index 2c6e589..e43e732 100644
--- a/xmloff/source/style/xmlnumfi.cxx
+++ b/xmloff/source/style/xmlnumfi.cxx
@@ -839,9 +839,9 @@ css::uno::Reference< css::xml::sax::XFastContextHandler > SvXMLNumFmtElementCont
sal_Int32 nElement,
const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
{
// only number:number supports number:embedded-text child element
// only number:number and number:scientific-number supports number:embedded-text child element
if ( nType == SvXMLStyleTokens::Number &&
if ( ( nType == SvXMLStyleTokens::Number || nType == SvXMLStyleTokens::ScientificNumber ) &&
nElement == XML_ELEMENT(NUMBER, XML_EMBEDDED_TEXT) )
{
return new SvXMLNumFmtEmbeddedTextContext( GetImport(), nElement, *this, xAttrList );