summaryrefslogtreecommitdiff
path: root/xmloff
diff options
context:
space:
mode:
Diffstat (limited to 'xmloff')
-rw-r--r--xmloff/source/core/xmltoken.cxx1
-rw-r--r--xmloff/source/style/xmlnumfe.cxx101
-rw-r--r--xmloff/source/style/xmlnumfi.cxx29
-rw-r--r--xmloff/source/token/tokens.txt1
4 files changed, 82 insertions, 50 deletions
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index d1d2047a50b9..78ef34951013 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -3450,6 +3450,7 @@ namespace xmloff::token {
TOKEN( "zeros-numerator-digits", XML_ZEROS_NUMERATOR_DIGITS ),
TOKEN( "zeros-denominator-digits", XML_ZEROS_DENOMINATOR_DIGITS ),
TOKEN( "integer-fraction-delimiter", XML_INTEGER_FRACTION_DELIMITER ),
+ TOKEN( "max-blank-integer-digits", XML_MAX_BLANK_INTEGER_DIGITS ),
// for optional language-dependent reference formats
TOKEN( "reference-language", XML_REFERENCE_LANGUAGE ),
diff --git a/xmloff/source/style/xmlnumfe.cxx b/xmloff/source/style/xmlnumfe.cxx
index 01367fe12e55..7d44f43342ef 100644
--- a/xmloff/source/style/xmlnumfe.cxx
+++ b/xmloff/source/style/xmlnumfe.cxx
@@ -532,9 +532,32 @@ void SvXMLNumFmtExport::WriteAMPMElement_Impl()
// numbers
+void SvXMLNumFmtExport::WriteIntegerElement_Impl(
+ sal_Int32 nInteger, sal_Int32 nBlankInteger, bool bGrouping )
+{
+ // integer digits: '0' and '?'
+ if ( nInteger >= 0 ) // negative = automatic
+ {
+ rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_MIN_INTEGER_DIGITS,
+ OUString::number( nInteger ) );
+ }
+ SvtSaveOptions::ODFSaneDefaultVersion eVersion = rExport.getSaneDefaultVersion();
+ // blank integer digits: '?'
+ if ( nBlankInteger > 0 && ( (eVersion & SvtSaveOptions::ODFSVER_EXTENDED) != 0 ) )
+ {
+ rExport.AddAttribute( XML_NAMESPACE_LO_EXT, XML_MAX_BLANK_INTEGER_DIGITS,
+ OUString::number( nBlankInteger ) );
+ }
+ // (automatic) grouping separator
+ if ( bGrouping )
+ {
+ rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_GROUPING, XML_TRUE );
+ }
+}
+
void SvXMLNumFmtExport::WriteNumberElement_Impl(
sal_Int32 nDecimals, sal_Int32 nMinDecimals,
- sal_Int32 nInteger, const OUString& rDashStr,
+ sal_Int32 nInteger, sal_Int32 nBlankInteger, const OUString& rDashStr,
bool bGrouping, sal_Int32 nTrailingThousands,
const SvXMLEmbeddedTextEntryArr& rEmbeddedEntries )
{
@@ -547,10 +570,10 @@ void SvXMLNumFmtExport::WriteNumberElement_Impl(
OUString::number( nDecimals ) );
}
+ SvtSaveOptions::ODFSaneDefaultVersion eVersion = rExport.getSaneDefaultVersion();
if ( nMinDecimals >= 0 ) // negative = automatic
{
// Export only for 1.2 with extensions or 1.3 and later.
- SvtSaveOptions::ODFSaneDefaultVersion eVersion = rExport.getSaneDefaultVersion();
if (eVersion > SvtSaveOptions::ODFSVER_012)
{
// OFFICE-3860 For 1.2+ use loext namespace, for 1.3 use number namespace.
@@ -560,14 +583,6 @@ void SvXMLNumFmtExport::WriteNumberElement_Impl(
OUString::number( nMinDecimals ) );
}
}
-
- // integer digits
- if ( nInteger >= 0 ) // negative = automatic
- {
- rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_MIN_INTEGER_DIGITS,
- OUString::number( nInteger ) );
- }
-
// decimal replacement (dashes) or variable decimals (#)
if ( !rDashStr.isEmpty() || nMinDecimals < nDecimals )
{
@@ -576,11 +591,7 @@ void SvXMLNumFmtExport::WriteNumberElement_Impl(
rDashStr );
}
- // (automatic) grouping separator
- if ( bGrouping )
- {
- rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_GROUPING, XML_TRUE );
- }
+ WriteIntegerElement_Impl( nInteger, nBlankInteger, bGrouping );
// display-factor if there are trailing thousands separators
if ( nTrailingThousands )
@@ -626,7 +637,7 @@ void SvXMLNumFmtExport::WriteNumberElement_Impl(
}
void SvXMLNumFmtExport::WriteScientificElement_Impl(
- sal_Int32 nDecimals, sal_Int32 nMinDecimals, sal_Int32 nInteger,
+ sal_Int32 nDecimals, sal_Int32 nMinDecimals, sal_Int32 nInteger, sal_Int32 nBlankInteger,
bool bGrouping, sal_Int32 nExp, sal_Int32 nExpInterval, bool bExpSign )
{
FinishTextElement_Impl();
@@ -652,18 +663,7 @@ void SvXMLNumFmtExport::WriteScientificElement_Impl(
}
}
- // integer digits
- if ( nInteger >= 0 ) // negative = automatic
- {
- rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_MIN_INTEGER_DIGITS,
- OUString::number( nInteger ) );
- }
-
- // (automatic) grouping separator
- if ( bGrouping )
- {
- rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_GROUPING, XML_TRUE );
- }
+ WriteIntegerElement_Impl( nInteger, nBlankInteger, bGrouping );
// exponent digits
if ( nExp >= 0 )
@@ -702,10 +702,12 @@ void SvXMLNumFmtExport::WriteScientificElement_Impl(
}
void SvXMLNumFmtExport::WriteFractionElement_Impl(
- sal_Int32 nInteger, bool bGrouping,
+ sal_Int32 nInteger, sal_Int32 nBlankInteger, bool bGrouping,
const SvNumberformat& rFormat, sal_uInt16 nPart )
{
FinishTextElement_Impl();
+ WriteIntegerElement_Impl( nInteger, nBlankInteger, bGrouping );
+
const OUString aNumeratorString = rFormat.GetNumeratorString( nPart );
const OUString aDenominatorString = rFormat.GetDenominatorString( nPart );
const OUString aIntegerFractionDelimiterString = rFormat.GetIntegerFractionDelimiterString( nPart );
@@ -734,21 +736,9 @@ void SvXMLNumFmtExport::WriteFractionElement_Impl(
nZerosDenominatorDigits = 0;
sal_Int32 nDenominator = aDenominatorString.toInt32();
- // integer digits
- if ( nInteger >= 0 ) // negative = default (no integer part)
- {
- rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_MIN_INTEGER_DIGITS,
- OUString::number( nInteger ) );
- }
-
- // (automatic) grouping separator
- if ( bGrouping )
- {
- rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_GROUPING, XML_TRUE );
- }
+ SvtSaveOptions::ODFSaneDefaultVersion eVersion = rExport.getSaneDefaultVersion();
// integer/fraction delimiter
- SvtSaveOptions::ODFSaneDefaultVersion eVersion = rExport.getSaneDefaultVersion();
if ( !aIntegerFractionDelimiterString.isEmpty() && aIntegerFractionDelimiterString != " "
&& ((eVersion & SvtSaveOptions::ODFSVER_EXTENDED) != 0) )
{ // Export only for 1.2/1.3 with extensions.
@@ -1249,7 +1239,7 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
if ( eBuiltIn == NF_NUMBER_STANDARD )
{
// default number format contains just one number element
- WriteNumberElement_Impl( -1, -1, 1, OUString(), false, 0, aEmbeddedEntries );
+ WriteNumberElement_Impl( -1, -1, 1, -1, OUString(), false, 0, aEmbeddedEntries );
bAnyContent = true;
}
else if ( eBuiltIn == NF_BOOLEAN )
@@ -1303,6 +1293,7 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
sal_Int32 nIntegerSymbols = 0; // for embedded-text, including "#"
sal_Int32 nTrailingThousands = 0; // thousands-separators after all digits
sal_Int32 nMinDecimals = nPrecision;
+ sal_Int32 nBlankInteger = 0;
OUString sCurrExt;
OUString aCalendar;
bool bImplicitOtherCalendar = false;
@@ -1327,7 +1318,7 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
bDecDashes = true;
nMinDecimals = 0;
}
- else if ( !bInInteger && pElemStr )
+ else if ( nFmtType != SvNumFormatType::FRACTION && !bInInteger && pElemStr )
{
for ( sal_Int32 i = pElemStr->getLength()-1; i >= 0 ; i-- )
{
@@ -1343,9 +1334,17 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
}
}
if ( bInInteger && pElemStr )
+ {
nIntegerSymbols += pElemStr->getLength();
+ for ( sal_Int32 i = pElemStr->getLength()-1; i >= 0 ; i-- )
+ {
+ if ( (*pElemStr)[i] == '?' )
+ nBlankInteger ++;
+ }
+ }
nTrailingThousands = 0;
break;
+ case NF_SYMBOLTYPE_FRACBLANK:
case NF_SYMBOLTYPE_DECSEP:
bInInteger = false;
break;
@@ -1507,7 +1506,7 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
}
break;
case NF_KEY_GENERAL :
- WriteNumberElement_Impl( -1, -1, 1, OUString(), false, 0, aEmbeddedEntries );
+ WriteNumberElement_Impl( -1, -1, 1, -1, OUString(), false, 0, aEmbeddedEntries );
bAnyContent = true;
break;
case NF_KEY_CCC:
@@ -1566,7 +1565,10 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
// only one built-in format has automatic integer digits
sal_Int32 nInteger = nLeading;
if ( eBuiltIn == NF_NUMBER_SYSTEM )
+ {
nInteger = -1;
+ nBlankInteger = -1;
+ }
// string for decimal replacement
// has to be taken from nPrecision
@@ -1578,16 +1580,16 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
if (bDecAlign && nPrecision > 0)
sDashStr = " ";
- WriteNumberElement_Impl(nDecimals, nMinDecimals, nInteger, sDashStr.makeStringAndClear(),
+ WriteNumberElement_Impl(nDecimals, nMinDecimals, nInteger, nBlankInteger, sDashStr.makeStringAndClear(),
bThousand, nTrailingThousands, aEmbeddedEntries);
bAnyContent = true;
}
break;
case SvNumFormatType::SCIENTIFIC:
- // #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
// nIntegerSymbols represents exponent interval (for engineering notation)
- WriteScientificElement_Impl( nPrecision, nMinDecimals, nLeading, bThousand, nExpDigits, nIntegerSymbols, bExpSign );
+ WriteScientificElement_Impl( nPrecision, nMinDecimals, nLeading, nBlankInteger, bThousand, nExpDigits, nIntegerSymbols, bExpSign );
bAnyContent = true;
break;
case SvNumFormatType::FRACTION:
@@ -1599,8 +1601,9 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
// the fraction doesn't have an integer part, and no
// min-integer-digits attribute must be written.
nInteger = -1;
+ nBlankInteger = -1;
}
- WriteFractionElement_Impl( nInteger, bThousand, rFormat, nPart );
+ WriteFractionElement_Impl( nInteger, nBlankInteger, bThousand, rFormat, nPart );
bAnyContent = true;
}
break;
diff --git a/xmloff/source/style/xmlnumfi.cxx b/xmloff/source/style/xmlnumfi.cxx
index 370af2bde369..7cb1b7d679ef 100644
--- a/xmloff/source/style/xmlnumfi.cxx
+++ b/xmloff/source/style/xmlnumfi.cxx
@@ -88,7 +88,8 @@ public:
struct SvXMLNumberInfo
{
sal_Int32 nDecimals = -1;
- sal_Int32 nInteger = -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 nExpInterval = -1;
sal_Int32 nMinNumerDigits = -1;
@@ -675,6 +676,11 @@ SvXMLNumFmtElementContext::SvXMLNumFmtElementContext( SvXMLImport& rImport,
if (::sax::Converter::convertNumber( nAttrVal, aIter.toView(), 0 ))
aNumInfo.nInteger = nAttrVal;
break;
+ case XML_ELEMENT(LO_EXT, XML_MAX_BLANK_INTEGER_DIGITS):
+ case XML_ELEMENT(NUMBER, XML_MAX_BLANK_INTEGER_DIGITS):
+ if (::sax::Converter::convertNumber( nAttrVal, aIter.toView(), 0 ))
+ aNumInfo.nBlankInteger = nAttrVal;
+ break;
case XML_ELEMENT(NUMBER, XML_GROUPING):
if (::sax::Converter::convertBool( bAttrBool, aIter.toView() ))
aNumInfo.bGrouping = bAttrBool;
@@ -776,6 +782,8 @@ SvXMLNumFmtElementContext::SvXMLNumFmtElementContext( SvXMLImport& rImport,
XMLOFF_WARN_UNKNOWN("xmloff", aIter);
}
}
+ if ( aNumInfo.nBlankInteger > aNumInfo.nInteger )
+ aNumInfo.nInteger = aNumInfo.nBlankInteger;
if ( aNumInfo.nMinDecimalDigits == -1)
{
if ( bVarDecimals || aNumInfo.bDecReplace )
@@ -1722,6 +1730,25 @@ void SvXMLNumFormatContext::AddNumber( const SvXMLNumberInfo& rInfo )
aNumStr.stripStart('#');
}
+ if ( rInfo.nBlankInteger > 0 )
+ {
+ // Replace nBlankInteger '0' by '?'
+ sal_Int32 nIndex = 0;
+ sal_Int32 nBlanks = rInfo.nBlankInteger;
+ sal_Int32 nIntegerEnd = aNumStr.indexOf( pFormatter->GetNumDecimalSep() );
+ if ( nIntegerEnd < 0 )
+ nIntegerEnd = aNumStr.getLength();
+ while ( nIndex < nIntegerEnd && nBlanks > 0 )
+ {
+ if ( aNumStr[nIndex] == '0' )
+ {
+ aNumStr[nIndex] = '?';
+ nBlanks--;
+ }
+ nIndex++;
+ }
+ }
+
if ( bGrouping && rInfo.nExpInterval > rInfo.nInteger )
{
sal_Int32 nIndex = 0;
diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt
index e4a0a5fe7c36..74a725d91b30 100644
--- a/xmloff/source/token/tokens.txt
+++ b/xmloff/source/token/tokens.txt
@@ -3206,6 +3206,7 @@ max-numerator-digits
zeros-numerator-digits
zeros-denominator-digits
integer-fraction-delimiter
+max-blank-integer-digits
reference-language
newline
creator-initials