fpspreadsheet: Fix some UTF8-related bugs in connection with currency formats

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3696 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2014-10-25 23:05:26 +00:00
parent c0f91c703d
commit ba40d180c4
6 changed files with 32 additions and 25 deletions

View File

@ -2489,6 +2489,9 @@ function TsWorksheet.ReadAsUTF8Text(ACell: PCell;
else else
if (ANumberFormat = nfPercentage) then if (ANumberFormat = nfPercentage) then
Result := FormatFloat(ANumberFormatStr, AValue*100, AFormatSettings) Result := FormatFloat(ANumberFormatStr, AValue*100, AFormatSettings)
else
if IsCurrencyFormat(ANumberFormat) then
Result := FormatCurr(ANumberFormatStr, AValue, AFormatSettings)
else else
Result := FormatFloat(ANumberFormatStr, AValue, AFormatSettings) Result := FormatFloat(ANumberFormatStr, AValue, AFormatSettings)
end; end;
@ -3933,7 +3936,7 @@ begin
if ANegCurrFormat = -1 then if ANegCurrFormat = -1 then
ANegCurrFormat := Workbook.FormatSettings.NegCurrFormat; ANegCurrFormat := Workbook.FormatSettings.NegCurrFormat;
if ACurrencySymbol = '?' then if ACurrencySymbol = '?' then
ACurrencySymbol := AnsiToUTF8(Workbook.FormatSettings.CurrencyString); ACurrencySymbol := Workbook.FormatSettings.CurrencyString;
fmt := BuildCurrencyFormatString( fmt := BuildCurrencyFormatString(
nfdDefault, nfdDefault,

View File

@ -22,10 +22,10 @@ uses
var var
// Norm to test against - list of strings that should occur in spreadsheet // Norm to test against - list of strings that should occur in spreadsheet
SollNumberStrings: array[0..6, 0..7] of string; SollNumberStrings: array[0..6, 0..9] of string;
SollNumbers: array[0..6] of Double; SollNumbers: array[0..6] of Double;
SollNumberFormats: array[0..7] of TsNumberFormat; SollNumberFormats: array[0..9] of TsNumberFormat;
SollNumberDecimals: array[0..7] of word; SollNumberDecimals: array[0..9] of word;
SollDateTimeStrings: array[0..4, 0..9] of string; SollDateTimeStrings: array[0..4, 0..9] of string;
SollDateTimes: array[0..4] of TDateTime; SollDateTimes: array[0..4] of TDateTime;
@ -197,6 +197,10 @@ begin
SollNumberFormats[5] := nfExp; SollNumberDecimals[5] := 2; SollNumberFormats[5] := nfExp; SollNumberDecimals[5] := 2;
SollNumberFormats[6] := nfPercentage; SollNumberDecimals[6] := 0; SollNumberFormats[6] := nfPercentage; SollNumberDecimals[6] := 0;
SollNumberFormats[7] := nfPercentage; SollNumberDecimals[7] := 2; SollNumberFormats[7] := nfPercentage; SollNumberDecimals[7] := 2;
SollNumberFormats[8] := nfCurrency; SollNumberDecimals[8] := 1; // This should be 0, but there is a bug in fpc, issue #0026944)
SollNumberFormats[9] := nfCurrency; SollNumberDecimals[9] := 2;
SollNumberstrings[0, 0] := CurrToStrF(-1000.1, ffCurrency, 0, fs);
for i:=Low(SollNumbers) to High(SollNumbers) do for i:=Low(SollNumbers) to High(SollNumbers) do
begin begin
@ -208,6 +212,8 @@ begin
SollNumberStrings[i, 5] := FormatFloat('0.00E+00', SollNumbers[i], fs); SollNumberStrings[i, 5] := FormatFloat('0.00E+00', SollNumbers[i], fs);
SollNumberStrings[i, 6] := FormatFloat('0', SollNumbers[i]*100, fs) + '%'; SollNumberStrings[i, 6] := FormatFloat('0', SollNumbers[i]*100, fs) + '%';
SollNumberStrings[i, 7] := FormatFloat('0.00', SollNumbers[i]*100, fs) + '%'; SollNumberStrings[i, 7] := FormatFloat('0.00', SollNumbers[i]*100, fs) + '%';
SollNumberStrings[i, 8] := CurrToStrF(SollNumbers[i], ffCurrency, SollNumberDecimals[8], fs);
SollNumberStrings[i, 9] := CurrToStrF(SollNumbers[i], ffCurrency, SollNumberDecimals[9], fs);
end; end;
// Date/time values // Date/time values
@ -336,7 +342,10 @@ begin
for Row := Low(SollNumbers) to High(SollNumbers) do for Row := Low(SollNumbers) to High(SollNumbers) do
for Col := ord(Low(SollNumberFormats)) to ord(High(SollNumberFormats)) do for Col := ord(Low(SollNumberFormats)) to ord(High(SollNumberFormats)) do
begin begin
MyWorksheet.WriteNumber(Row, Col, SollNumbers[Row], SollNumberFormats[Col], SollNumberDecimals[Col]); if IsCurrencyFormat(SollNumberFormats[Col]) then
MyWorksheet.WriteCurrency(Row, Col, SollNumbers[Row], SollNumberFormats[Col], SollNumberDecimals[Col])
else
MyWorksheet.WriteNumber(Row, Col, SollNumbers[Row], SollNumberFormats[Col], SollNumberDecimals[Col]);
ActualString := MyWorksheet.ReadAsUTF8Text(Row, Col); ActualString := MyWorksheet.ReadAsUTF8Text(Row, Col);
CheckEquals(SollNumberStrings[Row, Col], ActualString, CheckEquals(SollNumberStrings[Row, Col], ActualString,
'Test unsaved string mismatch, cell ' + CellNotation(MyWorksheet,Row,Col)); 'Test unsaved string mismatch, cell ' + CellNotation(MyWorksheet,Row,Col));

View File

@ -48,7 +48,6 @@
<Unit1> <Unit1>
<Filename Value="datetests.pas"/> <Filename Value="datetests.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="datetests"/>
</Unit1> </Unit1>
<Unit2> <Unit2>
<Filename Value="stringtests.pas"/> <Filename Value="stringtests.pas"/>
@ -61,21 +60,19 @@
<Unit4> <Unit4>
<Filename Value="manualtests.pas"/> <Filename Value="manualtests.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="manualtests"/>
</Unit4> </Unit4>
<Unit5> <Unit5>
<Filename Value="testsutility.pas"/> <Filename Value="testsutility.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="testsutility"/>
</Unit5> </Unit5>
<Unit6> <Unit6>
<Filename Value="internaltests.pas"/> <Filename Value="internaltests.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="internaltests"/>
</Unit6> </Unit6>
<Unit7> <Unit7>
<Filename Value="formattests.pas"/> <Filename Value="formattests.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="formattests"/>
</Unit7> </Unit7>
<Unit8> <Unit8>
<Filename Value="colortests.pas"/> <Filename Value="colortests.pas"/>
@ -100,7 +97,6 @@
<Unit13> <Unit13>
<Filename Value="formulatests.pas"/> <Filename Value="formulatests.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="formulatests"/>
</Unit13> </Unit13>
<Unit14> <Unit14>
<Filename Value="emptycelltests.pas"/> <Filename Value="emptycelltests.pas"/>
@ -109,7 +105,6 @@
<Unit15> <Unit15>
<Filename Value="errortests.pas"/> <Filename Value="errortests.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="errortests"/>
</Unit15> </Unit15>
<Unit16> <Unit16>
<Filename Value="virtualmodetests.pas"/> <Filename Value="virtualmodetests.pas"/>
@ -118,7 +113,6 @@
<Unit17> <Unit17>
<Filename Value="insertdeletetests.pas"/> <Filename Value="insertdeletetests.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="insertdeletetests"/>
</Unit17> </Unit17>
<Unit18> <Unit18>
<Filename Value="celltypetests.pas"/> <Filename Value="celltypetests.pas"/>
@ -127,7 +121,6 @@
<Unit19> <Unit19>
<Filename Value="sortingtests.pas"/> <Filename Value="sortingtests.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="sortingtests"/>
</Unit19> </Unit19>
</Units> </Units>
</ProjectOptions> </ProjectOptions>

View File

@ -405,7 +405,6 @@ begin
len := Length(Boundsheets); len := Length(Boundsheets);
SetLength(Boundsheets, len + 1); SetLength(Boundsheets, len + 1);
Boundsheets[len] := WriteBoundsheet(AStream, Workbook.GetWorksheetByIndex(i).Name); Boundsheets[len] := WriteBoundsheet(AStream, Workbook.GetWorksheetByIndex(i).Name);
// BIFF8 does not support unicode --> Need UTF8ToAnsi !
end; end;
WriteEOF(AStream); WriteEOF(AStream);
@ -677,7 +676,7 @@ begin
if (AFormatData = nil) or (AFormatData.FormatString = '') then if (AFormatData = nil) or (AFormatData.FormatString = '') then
exit; exit;
s := NumFormatList.FormatStringForWriting(AListIndex); s := UTF8ToAnsi(NumFormatList.FormatStringForWriting(AListIndex));
len := Length(s); len := Length(s);
{ BIFF record header } { BIFF record header }
@ -1215,7 +1214,8 @@ end;
procedure TsSpreadBIFF5Reader.ReadBoundsheet(AStream: TStream); procedure TsSpreadBIFF5Reader.ReadBoundsheet(AStream: TStream);
var var
Len: Byte; Len: Byte;
Str: array[0..255] of Char; s: AnsiString;
sheetName: String;
begin begin
{ Absolute stream position of the BOF record of the sheet represented { Absolute stream position of the BOF record of the sheet represented
by this record } by this record }
@ -1230,11 +1230,11 @@ begin
{ Sheet name: Byte string, 8-bit length } { Sheet name: Byte string, 8-bit length }
Len := AStream.ReadByte(); Len := AStream.ReadByte();
Str[0] := #0; // to silence the compiler...
AStream.ReadBuffer(Str, Len);
Str[Len] := #0;
FWorksheetNames.Add(Str); SetLength(s, Len);
AStream.ReadBuffer(s[1], Len*SizeOf(AnsiChar));
sheetName := AnsiToUTF8(s);
FWorksheetNames.Add(sheetName);
end; end;
procedure TsSpreadBIFF5Reader.ReadRichString(AStream: TStream); procedure TsSpreadBIFF5Reader.ReadRichString(AStream: TStream);
@ -1565,7 +1565,7 @@ begin
AStream.ReadBuffer(fmtString[1], len); AStream.ReadBuffer(fmtString[1], len);
// Add to the list // Add to the list
NumFormatList.AnalyzeAndAdd(fmtIndex, fmtString); NumFormatList.AnalyzeAndAdd(fmtIndex, AnsiToUTF8(fmtString));
end; end;
procedure TsSpreadBIFF5Reader.ReadLabel(AStream: TStream); procedure TsSpreadBIFF5Reader.ReadLabel(AStream: TStream);

View File

@ -736,7 +736,8 @@ type
end; end;
var var
len: Integer; len: Integer;
s: widestring; s: String;
ws: widestring;
rec: TNumFormatRecord; rec: TNumFormatRecord;
buf: array of byte; buf: array of byte;
begin begin
@ -744,7 +745,8 @@ begin
exit; exit;
s := NumFormatList.FormatStringForWriting(AListIndex); s := NumFormatList.FormatStringForWriting(AListIndex);
len := Length(s); ws := UTF8Decode(s);
len := Length(ws);
{ BIFF record header } { BIFF record header }
rec.RecordID := WordToLE(INT_EXCEL_ID_FORMAT); rec.RecordID := WordToLE(INT_EXCEL_ID_FORMAT);
@ -761,7 +763,7 @@ begin
{ - Copy the text characters into a buffer immediately after rec } { - Copy the text characters into a buffer immediately after rec }
SetLength(buf, SizeOf(rec) + SizeOf(WideChar)*len); SetLength(buf, SizeOf(rec) + SizeOf(WideChar)*len);
Move(rec, buf[0], SizeOf(rec)); Move(rec, buf[0], SizeOf(rec));
Move(s[1], buf[SizeOf(rec)], len*SizeOf(WideChar)); Move(ws[1], buf[SizeOf(rec)], len*SizeOf(WideChar));
{ Write out } { Write out }
AStream.WriteBuffer(buf[0], SizeOf(rec) + SizeOf(WideChar)*len); AStream.WriteBuffer(buf[0], SizeOf(rec) + SizeOf(WideChar)*len);

View File

@ -561,7 +561,7 @@ var
cs: String; cs: String;
begin begin
fs := Workbook.FormatSettings; fs := Workbook.FormatSettings;
cs := AnsiToUTF8(Workbook.FormatSettings.CurrencyString); cs := Workbook.FormatSettings.CurrencyString;
AddFormat( 0, '', nfGeneral); AddFormat( 0, '', nfGeneral);
AddFormat( 1, '0', nfFixed); AddFormat( 1, '0', nfFixed);