summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/svl/zformat.hxx1
-rw-r--r--include/xmloff/xmlnumfe.hxx2
-rw-r--r--include/xmloff/xmltoken.hxx2
-rw-r--r--svl/source/numbers/zformat.cxx26
-rw-r--r--xmloff/source/core/xmltoken.cxx2
-rw-r--r--xmloff/source/style/xmlnumfe.cxx51
-rw-r--r--xmloff/source/style/xmlnumfi.cxx72
7 files changed, 129 insertions, 27 deletions
diff --git a/include/svl/zformat.hxx b/include/svl/zformat.hxx
index 916a0d3004c8..b9c4101effb8 100644
--- a/include/svl/zformat.hxx
+++ b/include/svl/zformat.hxx
@@ -250,6 +250,7 @@ public:
short GetNumForType( sal_uInt16 nNumFor, sal_uInt16 nPos ) const;
OUString GetDenominatorString( sal_uInt16 nNumFor ) const;
+ OUString GetNumeratorString( sal_uInt16 nNumFor ) const;
/** If the count of string elements (substrings, ignoring [modifiers] and
so on) in a subformat code nNumFor (0..3) is equal to the given number.
Used by ImpSvNumberInputScan::IsNumberFormatMain() to detect a matched
diff --git a/include/xmloff/xmlnumfe.hxx b/include/xmloff/xmlnumfe.hxx
index 0f9d19a02331..8e47ff6dfbba 100644
--- a/include/xmloff/xmlnumfe.hxx
+++ b/include/xmloff/xmlnumfe.hxx
@@ -69,7 +69,7 @@ private:
SAL_DLLPRIVATE void WriteScientificElement_Impl( sal_Int32 nDecimals, sal_Int32 nMinDecimals, sal_Int32 nInteger,
bool bGrouping, sal_Int32 nExp, sal_Int32 nExpInterval, bool bExpSign );
SAL_DLLPRIVATE void WriteFractionElement_Impl( sal_Int32 nInteger, bool bGrouping,
- sal_Int32 nNumeratorDigits, sal_Int32 nDenominatorDigits, sal_Int32 nDenominator );
+ const OUString& aNumeratorString, const OUString& aDenominatorString );
SAL_DLLPRIVATE void WriteCurrencyElement_Impl( const OUString& rString,
const OUString& rExt );
SAL_DLLPRIVATE void WriteBooleanElement_Impl();
diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx
index ccbb8cf08e41..aaabbba53244 100644
--- a/include/xmloff/xmltoken.hxx
+++ b/include/xmloff/xmltoken.hxx
@@ -3259,6 +3259,8 @@ namespace xmloff { namespace token {
XML_EXPONENT_INTERVAL,
XML_FORCED_EXPONENT_SIGN,
XML_MIN_DECIMAL_PLACES,
+ XML_MAX_DENOMINATOR_VALUE,
+ XML_MAX_NUMERATOR_DIGITS,
XML_TOKEN_END
};
diff --git a/svl/source/numbers/zformat.cxx b/svl/source/numbers/zformat.cxx
index 0529f271979c..2f2d412ad114 100644
--- a/svl/source/numbers/zformat.cxx
+++ b/svl/source/numbers/zformat.cxx
@@ -2004,7 +2004,6 @@ void lcl_GetOutputStringScientific(double fNumber, sal_uInt16 nCharCount,
nPrec, rFormatter.GetNumDecimalSep()[0], true );
}
-
OUString lcl_GetDenominatorString(const ImpSvNumberformatInfo &rInfo, sal_uInt16 nAnz)
{
sal_uInt16 i;
@@ -2025,6 +2024,24 @@ OUString lcl_GetDenominatorString(const ImpSvNumberformatInfo &rInfo, sal_uInt16
return aDenominatorString.makeStringAndClear();
}
+OUString lcl_GetNumeratorString(const ImpSvNumberformatInfo &rInfo, sal_uInt16 nAnz)
+{
+ sal_Int16 i;
+ OUStringBuffer aNumeratorString;
+ for( i = 0; i < nAnz; i++ )
+ {
+ if( rInfo.nTypeArray[i] == NF_SYMBOLTYPE_FRAC )
+ {
+ for( i--; i >= 0 && rInfo.nTypeArray[i] == NF_SYMBOLTYPE_DIGIT ; i-- )
+ {
+ aNumeratorString.insert( 0, rInfo.sStrArray[i] );
+ }
+ i = nAnz;
+ }
+ }
+ return aNumeratorString.makeStringAndClear();
+}
+
// TODO: More optimizations?
void lcl_ForcedDenominator(sal_uLong &nFrac, sal_uLong &nDiv, sal_uLong nForcedDiv)
{
@@ -2051,6 +2068,13 @@ OUString SvNumberformat::GetDenominatorString( sal_uInt16 nNumFor ) const
return lcl_GetDenominatorString( rInfo, nAnz );
}
+OUString SvNumberformat::GetNumeratorString( sal_uInt16 nNumFor ) const
+{
+ const ImpSvNumberformatInfo& rInfo = NumFor[nNumFor].Info();
+ sal_uInt16 nAnz = NumFor[nNumFor].GetCount();
+ return lcl_GetNumeratorString( rInfo, nAnz );
+}
+
bool SvNumberformat::GetOutputString(double fNumber, sal_uInt16 nCharCount, OUString& rOutString) const
{
using namespace std;
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index 77ff93c7913b..847f61d9eecf 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -3255,6 +3255,8 @@ namespace xmloff { namespace token {
TOKEN( "exponent-interval", XML_EXPONENT_INTERVAL ),
TOKEN( "forced-exponent-sign", XML_FORCED_EXPONENT_SIGN ),
TOKEN( "min-decimal-places", XML_MIN_DECIMAL_PLACES ),
+ TOKEN( "max-denominator-value", XML_MAX_DENOMINATOR_VALUE ),
+ TOKEN( "max-numerator-digits", XML_MAX_NUMERATOR_DIGITS ),
#if OSL_DEBUG_LEVEL > 0
{ 0, nullptr, nullptr, XML_TOKEN_END }
diff --git a/xmloff/source/style/xmlnumfe.cxx b/xmloff/source/style/xmlnumfe.cxx
index 229237c2c309..235920df5fe8 100644
--- a/xmloff/source/style/xmlnumfe.cxx
+++ b/xmloff/source/style/xmlnumfe.cxx
@@ -721,9 +721,22 @@ void SvXMLNumFmtExport::WriteScientificElement_Impl(
void SvXMLNumFmtExport::WriteFractionElement_Impl(
sal_Int32 nInteger, bool bGrouping,
- sal_Int32 nNumeratorDigits, sal_Int32 nDenominatorDigits, sal_Int32 nDenominator )
+ const OUString& aNumeratorString , const OUString& aDenominatorString )
{
FinishTextElement_Impl();
+ sal_Int32 nMaxNumeratorDigits = aNumeratorString.getLength();
+ sal_Int32 nMinNumeratorDigits = aNumeratorString.indexOf('?');
+ if ( nMinNumeratorDigits >= 0 )
+ nMinNumeratorDigits = nMaxNumeratorDigits - nMinNumeratorDigits;
+ else
+ nMinNumeratorDigits = 0;
+ sal_Int32 nMaxDenominatorDigits = aDenominatorString.getLength();
+ sal_Int32 nMinDenominatorDigits = aDenominatorString.indexOf('?');
+ if ( nMinDenominatorDigits >= 0 )
+ nMinDenominatorDigits = nMaxDenominatorDigits - nMinDenominatorDigits;
+ else
+ nMinDenominatorDigits = 0;
+ sal_Int32 nDenominator = aDenominatorString.toInt32();
// integer digits
if ( nInteger >= 0 ) // negative = default (no integer part)
@@ -739,10 +752,17 @@ void SvXMLNumFmtExport::WriteFractionElement_Impl(
}
// numerator digits
- if ( nNumeratorDigits >= 0 )
+ if ( nMinNumeratorDigits == 0 ) // at least one digit to keep compatibility with previous versions
+ nMinNumeratorDigits++;
+ rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_MIN_NUMERATOR_DIGITS,
+ OUString::number( nMinNumeratorDigits ) );
+ // Export only for 1.2 with extensions or 1.3 and later.
+ SvtSaveOptions::ODFSaneDefaultVersion eVersion = rExport.getSaneDefaultVersion();
+ if ((eVersion & SvtSaveOptions::ODFSVER_EXTENDED) != 0)
{
- rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_MIN_NUMERATOR_DIGITS,
- OUString::number( nNumeratorDigits ) );
+ // For extended ODF use loext namespace
+ rExport.AddAttribute( XML_NAMESPACE_LO_EXT, XML_MAX_NUMERATOR_DIGITS,
+ OUString::number( nMaxNumeratorDigits ) );
}
if ( nDenominator )
@@ -750,12 +770,22 @@ void SvXMLNumFmtExport::WriteFractionElement_Impl(
rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_DENOMINATOR_VALUE,
OUString::number( nDenominator) );
}
- // I guess it's not necessary to export nDenominatorDigits
- // if we have a forced denominator ( remove ? )
- if ( nDenominatorDigits >= 0 )
+ // it's not necessary to export nDenominatorDigits
+ // if we have a forced denominator
+ else
{
+ if ( nMinDenominatorDigits == 0 ) // at least one digit to keep compatibility with previous versions
+ nMinDenominatorDigits++;
rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_MIN_DENOMINATOR_DIGITS,
- OUString::number( nDenominatorDigits ) );
+ OUString::number( nMinDenominatorDigits ) );
+ if (eVersion > SvtSaveOptions::ODFSVER_012)
+ {
+ // For 1.2+ use loext namespace, for 1.3 use number namespace.
+ rExport.AddAttribute(
+ ((eVersion < SvtSaveOptions::ODFSVER_013) ? XML_NAMESPACE_LO_EXT : XML_NAMESPACE_NUMBER),
+ XML_MAX_DENOMINATOR_VALUE,
+ OUString::number( pow ( 10.0, nMaxDenominatorDigits ) - 1 ) ); // 9, 99 or 999
+ }
}
SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_FRACTION,
@@ -1486,10 +1516,7 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
// min-integer-digits attribute must be written.
nInteger = -1;
}
- OUString aDenominatorString = rFormat.GetDenominatorString( nPart );
- sal_Int32 nDenominator = aDenominatorString.toInt32();
- sal_Int32 nDenominatorLength = aDenominatorString.getLength();
- WriteFractionElement_Impl( nInteger, bThousand, nPrecision, nDenominatorLength, nDenominator );
+ WriteFractionElement_Impl( nInteger, bThousand, rFormat.GetNumeratorString( nPart ), rFormat.GetDenominatorString( nPart ) );
bAnyContent = true;
}
break;
diff --git a/xmloff/source/style/xmlnumfi.cxx b/xmloff/source/style/xmlnumfi.cxx
index ddd925cc4f3f..b85bb1312e49 100644
--- a/xmloff/source/style/xmlnumfi.cxx
+++ b/xmloff/source/style/xmlnumfi.cxx
@@ -95,8 +95,10 @@ struct SvXMLNumberInfo
sal_Int32 nInteger;
sal_Int32 nExpDigits;
sal_Int32 nExpInterval;
- sal_Int32 nNumerDigits;
- sal_Int32 nDenomDigits;
+ sal_Int32 nMinNumerDigits;
+ sal_Int32 nMinDenomDigits;
+ sal_Int32 nMaxNumerDigits;
+ sal_Int32 nMaxDenomDigits;
sal_Int32 nFracDenominator;
sal_Int32 nMinDecimalDigits;
bool bGrouping;
@@ -108,7 +110,7 @@ struct SvXMLNumberInfo
SvXMLNumberInfo()
{
- nDecimals = nInteger = nExpDigits = nExpInterval = nNumerDigits = nDenomDigits =
+ nDecimals = nInteger = nExpDigits = nExpInterval = nMinNumerDigits = nMinDenomDigits = nMaxNumerDigits = nMaxDenomDigits =
nFracDenominator = nMinDecimalDigits = -1;
bGrouping = bDecReplace = bDecAlign = false;
bExpSign = true;
@@ -262,6 +264,8 @@ enum SvXMLStyleElemAttrTokens
XML_TOK_ELEM_ATTR_FORCED_EXPONENT_SIGN,
XML_TOK_ELEM_ATTR_MIN_NUMERATOR_DIGITS,
XML_TOK_ELEM_ATTR_MIN_DENOMINATOR_DIGITS,
+ XML_TOK_ELEM_ATTR_MAX_NUMERATOR_DIGITS,
+ XML_TOK_ELEM_ATTR_MAX_DENOMINATOR_VALUE,
XML_TOK_ELEM_ATTR_RFC_LANGUAGE_TAG,
XML_TOK_ELEM_ATTR_LANGUAGE,
XML_TOK_ELEM_ATTR_SCRIPT,
@@ -562,6 +566,9 @@ const SvXMLTokenMap& SvXMLNumImpData::GetStyleElemAttrTokenMap()
{ XML_NAMESPACE_NUMBER, XML_FORCED_EXPONENT_SIGN, XML_TOK_ELEM_ATTR_FORCED_EXPONENT_SIGN },
{ XML_NAMESPACE_NUMBER, XML_MIN_NUMERATOR_DIGITS, XML_TOK_ELEM_ATTR_MIN_NUMERATOR_DIGITS },
{ XML_NAMESPACE_NUMBER, XML_MIN_DENOMINATOR_DIGITS, XML_TOK_ELEM_ATTR_MIN_DENOMINATOR_DIGITS },
+ { XML_NAMESPACE_LO_EXT, XML_MAX_NUMERATOR_DIGITS, XML_TOK_ELEM_ATTR_MAX_NUMERATOR_DIGITS },
+ { XML_NAMESPACE_LO_EXT, XML_MAX_DENOMINATOR_VALUE, XML_TOK_ELEM_ATTR_MAX_DENOMINATOR_VALUE },
+ { XML_NAMESPACE_NUMBER, XML_MAX_DENOMINATOR_VALUE, XML_TOK_ELEM_ATTR_MAX_DENOMINATOR_VALUE },
{ XML_NAMESPACE_NUMBER, XML_RFC_LANGUAGE_TAG, XML_TOK_ELEM_ATTR_RFC_LANGUAGE_TAG },
{ XML_NAMESPACE_NUMBER, XML_LANGUAGE, XML_TOK_ELEM_ATTR_LANGUAGE },
{ XML_NAMESPACE_NUMBER, XML_SCRIPT, XML_TOK_ELEM_ATTR_SCRIPT },
@@ -906,6 +913,7 @@ SvXMLNumFmtElementContext::SvXMLNumFmtElementContext( SvXMLImport& rImport,
sal_Int32 nAttrVal;
bool bAttrBool(false);
bool bVarDecimals = false;
+ bool bIsMaxDenominator = false;
sal_uInt16 nAttrEnum;
double fAttrDouble;
@@ -967,17 +975,31 @@ SvXMLNumFmtElementContext::SvXMLNumFmtElementContext( SvXMLImport& rImport,
aNumInfo.bExpSign = bAttrBool;
break;
case XML_TOK_ELEM_ATTR_MIN_NUMERATOR_DIGITS:
- if (::sax::Converter::convertNumber( nAttrVal, sValue, 1 )) // at least one '?' (tdf#38097)
- aNumInfo.nNumerDigits = nAttrVal;
+ if (::sax::Converter::convertNumber( nAttrVal, sValue, 0 ))
+ aNumInfo.nMinNumerDigits = nAttrVal;
+ break;
+ case XML_TOK_ELEM_ATTR_MIN_DENOMINATOR_DIGITS:
+ if (::sax::Converter::convertNumber( nAttrVal, sValue, 0 ))
+ aNumInfo.nMinDenomDigits = nAttrVal;
break;
- case XML_TOK_ELEM_ATTR_MIN_DENOMINATOR_DIGITS: // while max-denominator-digits not treated (tdf#99661)
- if (::sax::Converter::convertNumber( nAttrVal, sValue, 1 )) // at least one '?' (tdf#38097)
- aNumInfo.nDenomDigits = nAttrVal;
+ case XML_TOK_ELEM_ATTR_MAX_NUMERATOR_DIGITS:
+ if (::sax::Converter::convertNumber( nAttrVal, sValue, 1 )) // at least one '#'
+ aNumInfo.nMaxNumerDigits = nAttrVal;
break;
case XML_TOK_ELEM_ATTR_DENOMINATOR_VALUE:
- if (::sax::Converter::convertNumber( nAttrVal, sValue, 0 ))
+ if (::sax::Converter::convertNumber( nAttrVal, sValue, 1 )) // 0 is not valid
+ {
aNumInfo.nFracDenominator = nAttrVal;
+ bIsMaxDenominator = false;
+ }
break;
+ case XML_TOK_ELEM_ATTR_MAX_DENOMINATOR_VALUE: // part of ODF 1.3
+ if (::sax::Converter::convertNumber( nAttrVal, sValue, 1 ) && aNumInfo.nFracDenominator <= 0)
+ { // if denominator value not yet defined
+ aNumInfo.nFracDenominator = nAttrVal;
+ bIsMaxDenominator = true;
+ }
+ break;
case XML_TOK_ELEM_ATTR_RFC_LANGUAGE_TAG:
aLanguageTagODF.maRfcLanguageTag = sValue;
break;
@@ -1010,6 +1032,24 @@ SvXMLNumFmtElementContext::SvXMLNumFmtElementContext( SvXMLImport& rImport,
else
aNumInfo.nMinDecimalDigits = aNumInfo.nDecimals;
}
+ if ( aNumInfo.nMinDenomDigits >= 0 )
+ if ( aNumInfo.nMaxDenomDigits < aNumInfo.nMinDenomDigits )
+ aNumInfo.nMaxDenomDigits = ( aNumInfo.nMinDenomDigits ? aNumInfo.nMinDenomDigits : 1 );
+ if ( aNumInfo.nMinNumerDigits >= 0 )
+ if ( aNumInfo.nMaxNumerDigits < aNumInfo.nMinNumerDigits )
+ aNumInfo.nMaxNumerDigits = ( aNumInfo.nMinNumerDigits ? aNumInfo.nMinNumerDigits : 1 );
+ if ( bIsMaxDenominator && aNumInfo.nFracDenominator > 0 )
+ {
+ aNumInfo.nMaxDenomDigits = floor( log10( aNumInfo.nFracDenominator ) ) + 1;
+ aNumInfo.nFracDenominator = -1; // Max denominator value only gives number of digits at denominator
+ }
+ if ( aNumInfo.nMaxDenomDigits > 0 )
+ {
+ if ( aNumInfo.nMinDenomDigits < 0 )
+ aNumInfo.nMinDenomDigits = 0;
+ else if ( aNumInfo.nMinDenomDigits > aNumInfo.nMaxDenomDigits )
+ aNumInfo.nMinDenomDigits = aNumInfo.nMaxDenomDigits;
+ }
if ( !aLanguageTagODF.isEmpty() )
{
@@ -1206,9 +1246,12 @@ void SvXMLNumFmtElementContext::EndElement()
//! build string and add at once
sal_Int32 i;
- for (i=0; i<aNumInfo.nNumerDigits; i++)
+ for (i=aNumInfo.nMaxNumerDigits; i > 0; i--)
{
- rParent.AddToCode( '?' );
+ if ( i > aNumInfo.nMinNumerDigits )
+ rParent.AddToCode( '#' );
+ else
+ rParent.AddToCode( '?' );
}
rParent.AddToCode( '/' );
if ( aNumInfo.nFracDenominator > 0 )
@@ -1217,9 +1260,12 @@ void SvXMLNumFmtElementContext::EndElement()
}
else
{
- for (i=0; i<aNumInfo.nDenomDigits; i++)
+ for (i=aNumInfo.nMaxDenomDigits; i > 0 ; i--)
{
- rParent.AddToCode( '?');
+ if ( i > aNumInfo.nMinDenomDigits )
+ rParent.AddToCode( '#' );
+ else
+ rParent.AddToCode( '?' );
}
}
}