summaryrefslogtreecommitdiff
path: root/svl
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2018-05-29 23:40:44 +0200
committerAndras Timar <andras.timar@collabora.com>2018-06-01 20:47:10 +0200
commit940fc00c6a7f69e18b57eaead8840de576629e18 (patch)
tree24e5a903274be6bca327e50d1845f0aedb567774 /svl
parent8b7ede03c732eeb4da41faa810343a387f2d8c62 (diff)
Resolves: tdf#117819 append trailing '0' as needed before separator insertion
To insert separators, literal strings between digits and other, the formatter operates backwards on the string obtained from doubleToUString() cleaned of the decimal separator. The number of decimals returned by doubleToUString() may be less than the decimals of the number format as entered by the user, which lead to separators inserted at wrong positions. This wrong behavior was triggered respectively made more obvious by commit 0f6203edf74832f84d8263d7a544d679203a4efc CommitDate: Wed Jan 13 14:47:57 2016 +0100 tdf#96918 display accurate integer double values up to (2^53)-1 which for integer values returns at most 15 decimals ('0' in this case). Before operating on the decimals' part ensure that the number of decimals matches the digits requested, and if shorter append trailing '0' characters for the required amount so the separators (and other strings) are inserted at the correct positions. Change-Id: Ic02652699ea7d6fae3b2b3348f6f7d183319e043 Reviewed-on: https://gerrit.libreoffice.org/55039 Reviewed-by: Eike Rathke <erack@redhat.com> Tested-by: Eike Rathke <erack@redhat.com> (cherry picked from commit 8b43f58891d4b422a8934050d839b0c2c1e3a18a) Reviewed-on: https://gerrit.libreoffice.org/55060 Tested-by: Jenkins <ci@libreoffice.org> (cherry picked from commit 2e0c3c88865b64b04b6160f9f5955a3a9548d48c)
Diffstat (limited to 'svl')
-rw-r--r--svl/source/numbers/zformat.cxx31
1 files changed, 25 insertions, 6 deletions
diff --git a/svl/source/numbers/zformat.cxx b/svl/source/numbers/zformat.cxx
index 8614c412bfd5..ee42209f4363 100644
--- a/svl/source/numbers/zformat.cxx
+++ b/svl/source/numbers/zformat.cxx
@@ -2523,6 +2523,7 @@ bool SvNumberformat::ImpGetScientificOutput(double fNumber,
OUStringBuffer ExpStr;
short nExpSign = 1;
sal_Int32 nExPos = sStr.indexOf('E');
+ sal_Int32 nDecPos = -1;
if ( nExPos >= 0 )
{
@@ -2581,6 +2582,8 @@ bool SvNumberformat::ImpGetScientificOutput(double fNumber,
while((index = sStr.indexOf('.', index)) >= 0)
{
+ if (nDecPos < 0)
+ nDecPos = index;
sStr.remove(index, 1);
}
}
@@ -2630,7 +2633,7 @@ bool SvNumberformat::ImpGetScientificOutput(double fNumber,
}
else
{
- bRes |= ImpDecimalFill(sStr, fNumber, j, nIx, false);
+ bRes |= ImpDecimalFill(sStr, fNumber, nDecPos, j, nIx, false);
}
if (bSign)
@@ -4104,6 +4107,7 @@ bool SvNumberformat::ImpGetNumberOutput(double fNumber,
}
}
sal_uInt16 i, j;
+ sal_Int32 nDecPos = -1;
bool bInteger = false;
if ( rInfo.nThousand != FLAG_STANDARD_IN_FORMAT )
{
@@ -4155,17 +4159,17 @@ bool SvNumberformat::ImpGetNumberOutput(double fNumber,
sStr = ::rtl::math::doubleToUString( fNumber, rtl_math_StringFormat_F, 0, '.');
sStr.stripStart('0'); // Strip leading zeros
}
- sal_Int32 nPoint = sStr.indexOf('.' );
- if ( nPoint >= 0)
+ nDecPos = sStr.indexOf('.' );
+ if ( nDecPos >= 0)
{
- const sal_Unicode* p = sStr.getStr() + nPoint;
+ const sal_Unicode* p = sStr.getStr() + nDecPos;
while ( *++p == '0' )
;
if ( !*p )
{
bInteger = true;
}
- sStr.remove( nPoint, 1 ); // Remove .
+ sStr.remove( nDecPos, 1 ); // Remove .
}
if (bSign && (sStr.isEmpty() ||
comphelper::string::getTokenCount(sStr.toString(), '0') == sStr.getLength()+1)) // Only 00000
@@ -4177,7 +4181,7 @@ bool SvNumberformat::ImpGetNumberOutput(double fNumber,
// Edit backwards:
j = NumFor[nIx].GetCount()-1; // Last symbol
// Decimal places:
- bRes |= ImpDecimalFill( sStr, fNumber, j, nIx, bInteger );
+ bRes |= ImpDecimalFill( sStr, fNumber, nDecPos, j, nIx, bInteger );
if (bSign)
{
sStr.insert(0, '-');
@@ -4188,6 +4192,7 @@ bool SvNumberformat::ImpGetNumberOutput(double fNumber,
bool SvNumberformat::ImpDecimalFill( OUStringBuffer& sStr, // number string
double& rNumber, // number
+ sal_Int32 nDecPos, // decimals start
sal_uInt16 j, // symbol index within format code
sal_uInt16 nIx, // subformat index
bool bInteger) // is integer
@@ -4232,6 +4237,20 @@ bool SvNumberformat::ImpDecimalFill( OUStringBuffer& sStr, // number string
const OUString& rStr = rInfo.sStrArray[j];
const sal_Unicode* p1 = rStr.getStr();
const sal_Unicode* p = p1 + rStr.getLength();
+ // In case the number of decimals passed are less than the
+ // "digits" given, append trailing '0' characters, which here
+ // means insert them because literal strings may have been
+ // appended already. If they weren't to be '0' characters
+ // they'll be changed below, as if decimals with trailing zeros
+ // were passed.
+ if (nDecPos >= 0 && nDecPos <= k)
+ {
+ sal_Int32 nAppend = rStr.getLength() - (k - nDecPos);
+ while (nAppend-- > 0)
+ {
+ sStr.insert( k++, '0');
+ }
+ }
while (k && p1 < p--)
{
const sal_Unicode c = *p;