You've already forked lazarus-ccr
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:
@ -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,
|
||||||
|
@ -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));
|
||||||
|
@ -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>
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
Reference in New Issue
Block a user