diff --git a/components/fpspreadsheet/fpsnumformatparser.pas b/components/fpspreadsheet/fpsnumformatparser.pas
index d562bd5d5..b0b416b18 100644
--- a/components/fpspreadsheet/fpsnumformatparser.pas
+++ b/components/fpspreadsheet/fpsnumformatparser.pas
@@ -23,7 +23,8 @@ const
psErrMultipleCurrSymbols = 9;
psErrMultipleFracSymbols = 10;
psErrMultipleExpChars = 11;
- psAmbiguousSymbol = 12;
+ psErrGeneralExpected = 12;
+ psAmbiguousSymbol = 13;
type
@@ -54,7 +55,7 @@ type
{ Administration while scanning }
procedure AddElement(AToken: TsNumFormatToken; AText: String); overload;
- procedure AddElement(AToken: TsNumFormatToken; AIntValue: Integer); overload;
+ procedure AddElement(AToken: TsNumFormatToken; AIntValue: Integer=0); overload;
procedure AddElement(AToken: TsNumFormatToken; AFloatValue: Double); overload;
procedure AddSection;
procedure DeleteElement(ASection, AIndex: Integer);
@@ -72,6 +73,7 @@ type
procedure ScanCurrSymbol;
procedure ScanDateTime;
procedure ScanFormat;
+ procedure ScanGeneral;
procedure ScanNumber;
procedure ScanQuotedText;
// Main scanner
@@ -190,7 +192,7 @@ begin
FSections[FCurrSection].Elements[n].TextValue := AText;
end;
-procedure TsNumFormatParser.AddElement(AToken: TsNumFormatToken; AIntValue: Integer);
+procedure TsNumFormatParser.AddElement(AToken: TsNumFormatToken; AIntValue: Integer=0);
var
n: Integer;
begin
@@ -359,7 +361,10 @@ begin
section^.Kind := section^.Kind + [nfkTimeInterval];
end;
nftColor:
- section^.Kind := section^.Kind + [nfkHasColor];
+ begin
+ section^.Kind := section^.Kind + [nfkHasColor];
+ section^.Color := section^.Elements[el].IntValue;
+ end;
nftIntTh:
section^.Kind := section^.Kind + [nfkHasThSep];
end;
@@ -932,8 +937,11 @@ begin
FStatus := psOK;
AddSection;
- if (AFormatString = '') or SameText(AFormatString, 'General') then
+ if (AFormatString = '') then
+ begin
+ AddElement(nftGeneral);
exit;
+ end;
FStart := @AFormatString[1];
FEnd := FStart + Length(AFormatString);
@@ -941,6 +949,7 @@ begin
FToken := FCurrent^;
while (FCurrent < FEnd) and (FStatus = psOK) do begin
case FToken of
+ 'G','g': ScanGeneral;
'[': ScanBrackets;
'"': ScanQuotedText;
':': AddElement(nftDateTimeSep, ':');
@@ -1264,6 +1273,8 @@ begin
ScanAMPM;
FToken := PrevToken;
end;
+ 'G', 'g':
+ ScanGeneral;
';': // End of the section. Important: Cursor must stay on ';'
begin
AddSection;
@@ -1276,6 +1287,26 @@ begin
end;
end;
+{ Scans for the word "General", it may be used like other tokens }
+procedure TsNumFormatParser.ScanGeneral;
+begin
+ FStatus := psErrGeneralExpected;
+ FToken := NextToken;
+ if not (FToken in ['e', 'E']) then exit;
+ FToken := NextToken;
+ if not (FToken in ['n', 'N']) then exit;
+ FToken := NextToken;
+ if not (FToken in ['e', 'E']) then exit;
+ FToken := NextToken;
+ if not (FToken in ['r', 'R']) then exit;
+ FToken := NextToken;
+ if not (FToken in ['a', 'A']) then exit;
+ FToken := NextToken;
+ if not (FToken in ['l', 'L']) then exit;
+ AddElement(nftGeneral);
+ FStatus := psOK;
+end;
+
{ Scans a floating point format. Procedure is left with the cursor at the last
character of the format. }
procedure TsNumFormatParser.ScanNumber;
@@ -1427,7 +1458,8 @@ begin
end;
end;
end;
-
+ 'G', 'g':
+ ScanGeneral;
else
FToken := PrevToken;
Exit;
diff --git a/components/fpspreadsheet/fpsopendocument.pas b/components/fpspreadsheet/fpsopendocument.pas
index a5c62f0b7..d6331ef8b 100755
--- a/components/fpspreadsheet/fpsopendocument.pas
+++ b/components/fpspreadsheet/fpsopendocument.pas
@@ -626,6 +626,9 @@ begin
nftCurrSymbol:
Result := Result + '' + Elements[el].TextValue + '';
+ nftGeneral:
+ Result := Result + '';
+
nftIntTh:
begin
Result := Result + ' '' then decs := StrToInt(s) else decs := 0;
- grouping := GetAttrValue(node, 'number:grouping') = 'true';
- s := GetAttrValue(node, 'number:display-factor');
- if s <> '' then f := StrToFloat(s, FPointSeparatorSettings) else f := 1.0;
- nf := IfThen(grouping, nfFixedTh, nfFixed);
- nfs := nfs + BuildNumberFormatString(nf, Workbook.FormatSettings, decs);
- if f <> 1.0 then begin
- nf := nfCustom;
- while (f > 1.0) do
- begin
- nfs := nfs + ',';
- f := f / 1000;
+ if s = '' then
+ s := GetAttrValue(node, 'decimal-places');
+ if s = '' then
+ begin
+ if nfs='' then nf := nfGeneral else nf := nfCustom;
+ nfs := nfs + 'General';
+ end else
+ begin
+ decs := StrToInt(s);
+ grouping := GetAttrValue(node, 'number:grouping') = 'true';
+ s := GetAttrValue(node, 'number:display-factor');
+ if s <> '' then f := StrToFloat(s, FPointSeparatorSettings) else f := 1.0;
+ nf := IfThen(grouping, nfFixedTh, nfFixed);
+ nfs := nfs + BuildNumberFormatString(nf, Workbook.FormatSettings, decs);
+ if f <> 1.0 then begin
+ nf := nfCustom;
+ while (f > 1.0) do
+ begin
+ nfs := nfs + ',';
+ f := f / 1000;
+ end;
end;
end;
end else
diff --git a/components/fpspreadsheet/fpstypes.pas b/components/fpspreadsheet/fpstypes.pas
index 03698ae2d..c838b016f 100644
--- a/components/fpspreadsheet/fpstypes.pas
+++ b/components/fpspreadsheet/fpstypes.pas
@@ -502,6 +502,7 @@ type
{@@ Tokens used by the elements of the number format parser }
TsNumFormatToken = (
+ nftGeneral, // token for "general" number format
nftText, // must be quoted, stored in TextValue
nftThSep, // ',', replaced by FormatSettings.ThousandSeparator
nftDecSep, // '.', replaced by FormatSettings.DecimalSeparator
@@ -970,6 +971,8 @@ begin
for i := 0 to High(ASection.Elements) do begin
element := ASection.Elements[i];
case element.Token of
+ nftGeneral:
+ Result := Result + 'General';
nftIntOptDigit, nftOptDecs, nftFracNumOptDigit, nftFracDenomOptDigit:
if element.IntValue > 0 then
Result := Result + DupeString('#', element.IntValue);
diff --git a/components/fpspreadsheet/fpsutils.pas b/components/fpspreadsheet/fpsutils.pas
index 3b5a3da7e..f5b278c77 100644
--- a/components/fpspreadsheet/fpsutils.pas
+++ b/components/fpspreadsheet/fpsutils.pas
@@ -2880,6 +2880,13 @@ begin
el := 0;
while (el < numEl) do begin
+ if section.Elements[el].Token = nftGeneral then
+ begin
+ s := FloatToStrF(AValue, ffGeneral, 20, 20, fs);
+ if (sidx=0) and isNeg then s := '-' + s;
+ Result := Result + s;
+ end
+ else
// Integer token: can be the start of a number, exp, or mixed fraction format
// Cases with thousand separator are handled here as well.
if section.Elements[el].Token in (INT_TOKENS + [nftIntTh]) then begin
diff --git a/components/fpspreadsheet/xlsbiff2.pas b/components/fpspreadsheet/xlsbiff2.pas
index 3d81a3249..0b380a121 100755
--- a/components/fpspreadsheet/xlsbiff2.pas
+++ b/components/fpspreadsheet/xlsbiff2.pas
@@ -440,7 +440,6 @@ end;*)
procedure TsSpreadBIFF2Reader.ReadFormat(AStream: TStream);
var
len: byte;
- fmtIndex: Integer;
fmtString: AnsiString;
nfs: String;
begin
diff --git a/components/fpspreadsheet/xlsbiff5.pas b/components/fpspreadsheet/xlsbiff5.pas
index 40dc84665..0a7409963 100755
--- a/components/fpspreadsheet/xlsbiff5.pas
+++ b/components/fpspreadsheet/xlsbiff5.pas
@@ -1200,7 +1200,6 @@ procedure TsSpreadBIFF5Writer.WriteFont(AStream: TStream; AFont: TsFont);
var
Len: Byte;
optn: Word;
- cidx: Integer;
begin
if AFont = nil then // this happens for FONT4 in case of BIFF
exit;