You've already forked lazarus-ccr
fpspreadsheet: Extend number format parser to accept the keyword "General" in custom formats
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4161 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -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:
|
||||
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;
|
||||
|
@ -626,6 +626,9 @@ begin
|
||||
nftCurrSymbol:
|
||||
Result := Result + '<number:currency-symbol>' + Elements[el].TextValue + '</number:currency-symbol>';
|
||||
|
||||
nftGeneral:
|
||||
Result := Result + '<number:number number:min-integer-digits="1" />';
|
||||
|
||||
nftIntTh:
|
||||
begin
|
||||
Result := Result + '<number:number number:min-integer-digits="1" number:grouping="true"';
|
||||
@ -2256,8 +2259,15 @@ procedure TsSpreadOpenDocReader.ReadNumFormats(AStylesNode: TDOMNode);
|
||||
if nodeName = 'number:number' then
|
||||
begin
|
||||
s := GetAttrValue(node, 'number:decimal-places');
|
||||
if s = '' then s := GetAttrValue(node, 'decimal-places');
|
||||
if s <> '' then decs := StrToInt(s) else decs := 0;
|
||||
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;
|
||||
@ -2271,6 +2281,7 @@ procedure TsSpreadOpenDocReader.ReadNumFormats(AStylesNode: TDOMNode);
|
||||
f := f / 1000;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end else
|
||||
if nodeName = 'number:fraction' then
|
||||
begin
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -440,7 +440,6 @@ end;*)
|
||||
procedure TsSpreadBIFF2Reader.ReadFormat(AStream: TStream);
|
||||
var
|
||||
len: byte;
|
||||
fmtIndex: Integer;
|
||||
fmtString: AnsiString;
|
||||
nfs: String;
|
||||
begin
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user