[Libreoffice-commits] core.git: include/svl sc/source svl/source
Eike Rathke (via logerrit)
logerrit at kemper.freedesktop.org
Wed Sep 1 20:54:29 UTC 2021
include/svl/zformat.hxx | 11 ++++++++---
sc/source/core/data/documen4.cxx | 17 +++++++++++++----
svl/source/numbers/zformat.cxx | 16 ++++++++++++++++
3 files changed, 37 insertions(+), 7 deletions(-)
New commits:
commit 71b003a12f8afdff42a25786ad0a12ddd6609d59
Author: Eike Rathke <erack at redhat.com>
AuthorDate: Wed Sep 1 15:35:11 2021 +0200
Commit: Eike Rathke <erack at redhat.com>
CommitDate: Wed Sep 1 22:53:55 2021 +0200
Resolves: tdf#144209 Handle General containing formats in RoundValueAsShown()
Calling SvNumberformat::GetThousandDivisorPrecision() for a
"AA "General
format resulted in 3000 as that was implemented for tdf#106253
without taking into account that ImpSvNumberformatInfo::nThousand
may be abused under some conditions, which here is having
FLAG_STANDARD_IN_FORMAT = 1000 as nThousand, multiplied by 3 gives
3000. Subtracted from the 0 precision gave -3000 decimals for
which of course the new rounding produced 0 where it previously
simply ignored the decimals and returned the original value.
Change-Id: I66afaf1e2d8b2654d9f7cc8cfb66389357fb742d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121447
Reviewed-by: Eike Rathke <erack at redhat.com>
Tested-by: Jenkins
diff --git a/include/svl/zformat.hxx b/include/svl/zformat.hxx
index 3fdee06d99dc..cd04f96ac8a1 100644
--- a/include/svl/zformat.hxx
+++ b/include/svl/zformat.hxx
@@ -272,10 +272,15 @@ public:
{ return NumFor[nIx].Info().nCntPre; }
/** Count of hidden integer digits with thousands divisor:
- * formats like "0," to show only thousands
+ formats like "0," to show only thousands.
+
+ Works only with SvNumFormatType::NUMBER and SvNumFormatType::CURRENCY,
+ returns 0 otherwise.
+
+ Returns SvNumberFormatter::UNLIMITED_PRECISION for formats that contain
+ the General keyword.
*/
- sal_uInt16 GetThousandDivisorPrecision( sal_uInt16 nIx = 0 ) const
- { return NumFor[nIx].Info().nThousand * 3; }
+ sal_uInt16 GetThousandDivisorPrecision( sal_uInt16 nIx = 0 ) const;
//! Read/write access on a special sal_uInt16 component, may only be used on the
//! standard format 0, 10000, ... and only by the number formatter!
diff --git a/sc/source/core/data/documen4.cxx b/sc/source/core/data/documen4.cxx
index 951a02700ec6..8f8bd3d43e98 100644
--- a/sc/source/core/data/documen4.cxx
+++ b/sc/source/core/data/documen4.cxx
@@ -641,8 +641,12 @@ double ScDocument::RoundValueAsShown( double fVal, sal_uInt32 nFormat, const ScI
SvNumFormatType nType = pFormat->GetMaskedType();
if (nType != SvNumFormatType::DATE && nType != SvNumFormatType::TIME && nType != SvNumFormatType::DATETIME )
{
- short nPrecision;
- if ((nFormat % SV_COUNTRY_LANGUAGE_OFFSET) != 0)
+ // MSVC doesn't recognize all paths init nPrecision and wails about
+ // "potentially uninitialized local variable 'nPrecision' used"
+ // so init to some random sensible value preserving all decimals.
+ short nPrecision = 20;
+ bool bStdPrecision = ((nFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0);
+ if (!bStdPrecision)
{
sal_uInt16 nIdx = pFormat->GetSubformatIndex( fVal );
nPrecision = static_cast<short>(pFormat->GetFormatPrecision( nIdx ));
@@ -679,13 +683,18 @@ double ScDocument::RoundValueAsShown( double fVal, sal_uInt32 nFormat, const ScI
case SvNumFormatType::NUMBER:
case SvNumFormatType::CURRENCY:
{ // tdf#106253 Thousands divisors for format "0,"
- nPrecision -= pFormat->GetThousandDivisorPrecision( nIdx );
+ const sal_uInt16 nTD = pFormat->GetThousandDivisorPrecision( nIdx );
+ if (nTD == SvNumberFormatter::UNLIMITED_PRECISION)
+ // Format contains General keyword, handled below.
+ bStdPrecision = true;
+ else
+ nPrecision -= nTD;
break;
}
default: break;
}
}
- else
+ if (bStdPrecision)
{
nPrecision = static_cast<short>(GetDocOptions().GetStdPrecision());
// #i115512# no rounding for automatic decimals
diff --git a/svl/source/numbers/zformat.cxx b/svl/source/numbers/zformat.cxx
index 6b68e79f1517..22a377a6cc69 100644
--- a/svl/source/numbers/zformat.cxx
+++ b/svl/source/numbers/zformat.cxx
@@ -5947,6 +5947,22 @@ OUString SvNumberformat::GetFormatStringForTimePrecision( int nPrecision ) const
return sString.makeStringAndClear();
}
+sal_uInt16 SvNumberformat::GetThousandDivisorPrecision( sal_uInt16 nIx ) const
+{
+ if (nIx >= 4)
+ return 0;
+
+ const ImpSvNumberformatInfo& rInfo = NumFor[nIx].Info();
+
+ if (rInfo.eScannedType != SvNumFormatType::NUMBER && rInfo.eScannedType != SvNumFormatType::CURRENCY)
+ return 0;
+
+ if (rInfo.nThousand == FLAG_STANDARD_IN_FORMAT)
+ return SvNumberFormatter::UNLIMITED_PRECISION;
+
+ return rInfo.nThousand * 3;
+}
+
const CharClass& SvNumberformat::rChrCls() const
{
return rScan.GetChrCls();
More information about the Libreoffice-commits
mailing list