From 0a34c6314a47545b949711afe07be0dfdc352b35 Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Fri, 14 Nov 2014 21:18:16 +0000 Subject: [PATCH] fpspreadsheet: Improved increasing/decreasing of decimal count by means of action control. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3726 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- .../fpspreadsheet/examples/fpsctrls/main.lfm | 2 - components/fpspreadsheet/fpsactions.pas | 58 ++++++++++--------- components/fpspreadsheet/fpspreadsheet.pas | 48 +++++++++++++-- 3 files changed, 75 insertions(+), 33 deletions(-) diff --git a/components/fpspreadsheet/examples/fpsctrls/main.lfm b/components/fpspreadsheet/examples/fpsctrls/main.lfm index a42b42694..840b5b623 100644 --- a/components/fpspreadsheet/examples/fpsctrls/main.lfm +++ b/components/fpspreadsheet/examples/fpsctrls/main.lfm @@ -638,14 +638,12 @@ object Form1: TForm1 Category = 'FPSpreadsheet' WorkbookSource = WorkbookSource Caption = 'Decimals' - Hint = 'Decimal places' ImageIndex = 21 end object AcDecDecimals: TsDecimalsAction Category = 'FPSpreadsheet' WorkbookSource = WorkbookSource Caption = 'Decimals' - Hint = 'Decimal places' ImageIndex = 20 Delta = -1 end diff --git a/components/fpspreadsheet/fpsactions.pas b/components/fpspreadsheet/fpsactions.pas index c5717fa7b..fddb26616 100644 --- a/components/fpspreadsheet/fpsactions.pas +++ b/components/fpspreadsheet/fpsactions.pas @@ -232,18 +232,17 @@ type private FDecimals: Integer; FDelta: Integer; - procedure SetDecimals(AValue: Integer); procedure SetDelta(AValue: Integer); protected procedure ApplyFormatToCell(ACell: PCell); override; procedure ExtractFromCell(ACell: PCell); override; - property Decimals: Integer - read FDecimals write SetDecimals default 2; public constructor Create(AOwner: TComponent); override; published + property Caption stored false; property Delta: Integer read FDelta write SetDelta default +1; + property Hint stored false; end; @@ -321,6 +320,7 @@ end; procedure TsWorksheetAction.UpdateTarget(Target: TObject); begin + Unused(Target); Enabled := inherited Enabled and (Worksheet <> nil); end; @@ -460,6 +460,7 @@ end; specified cell. Must be overridden by descendants. } procedure TsCellFormatAction.ApplyFormatToCell(ACell: PCell); begin + Unused(ACell); end; procedure TsCellFormatAction.ExecuteTarget(Target: TObject); @@ -486,6 +487,7 @@ end; specified cell. Must be overridden by descendants. } procedure TsCellFormatAction.ExtractFromCell(ACell: PCell); begin + Unused(ACell); end; function TsCellFormatAction.HandlesTarget(Target: TObject): Boolean; @@ -497,6 +499,8 @@ procedure TsCellFormatAction.UpdateTarget(Target: TObject); var cell: PCell; begin + Unused(Target); + Enabled := inherited Enabled and (Worksheet <> nil) and (Length(GetSelection) > 0); if not Enabled then exit; @@ -531,7 +535,6 @@ end; procedure TsFontStyleAction.ExtractFromCell(ACell: PCell); var fnt: TsFont; - fs: TsFontStyles; begin if (ACell = nil) then Checked := false @@ -796,28 +799,26 @@ constructor TsDecimalsAction.Create(AOwner: TComponent); begin inherited Create(AOwner); Caption := 'Decimals'; - Hint := 'Decimal places'; - FDelta := +1; + Delta := +1; end; procedure TsDecimalsAction.ApplyFormatToCell(ACell: PCell); var decs: Integer; - currSym: String; begin - if not (uffNumberFormat in ACell^.UsedFormattingFields) or - (ACell^.NumberFormat = nfGeneral) - then - Worksheet.WriteNumberFormat(ACell, nfFixed, '0') - else if IsDateTimeFormat(ACell^.NumberFormat) then - exit + exit; + + if (ACell^.ContentType in [cctEmpty, cctNumber]) and ( + (not (uffNumberFormat in ACell^.UsedFormattingFields)) or + (ACell^.NumberFormat = nfGeneral) + ) then + decs := Worksheet.GetDisplayedDecimals(ACell) else - begin - decs := Decimals + FDelta; - if decs < 0 then decs := 0; - Worksheet.WriteDecimals(ACell, decs); - end; + decs := FDecimals; + inc(decs, FDelta); + if decs < 0 then decs := 0; + Worksheet.WriteDecimals(ACell, decs); end; procedure TsDecimalsAction.ExtractFromCell(ACell: PCell); @@ -825,16 +826,19 @@ var csym: String; decs: Byte; begin - decs := 2; - if (ACell <> nil) and (uffNumberFormat in ACell^.UsedFormattingFields) then - Worksheet.GetNumberFormatAttributes(ACell, decs, csym); - Decimals := decs -end; + if ACell = nil then begin + FDecimals := 2; + exit; + end; -procedure TsDecimalsAction.SetDecimals(AValue: Integer); -begin - FDecimals := AValue; - if FDecimals < 0 then FDecimals := 0; + if (ACell^.ContentType in [cctEmpty, cctNumber]) and ( + (not (uffNumberFormat in ACell^.UsedFormattingFields)) or + (ACell^.NumberFormat = nfGeneral) + ) then + decs := Worksheet.GetDisplayedDecimals(ACell) + else + Worksheet.GetNumberFormatAttributes(ACell, decs, csym); + FDecimals := decs; end; procedure TsDecimalsAction.SetDelta(AValue: Integer); diff --git a/components/fpspreadsheet/fpspreadsheet.pas b/components/fpspreadsheet/fpspreadsheet.pas index 9777b7e60..4a79859bf 100755 --- a/components/fpspreadsheet/fpspreadsheet.pas +++ b/components/fpspreadsheet/fpspreadsheet.pas @@ -607,6 +607,7 @@ type function ReadNumericValue(ACell: PCell; out AValue: Double): Boolean; { Reading of cell attributes } + function GetDisplayedDecimals(ACell: PCell): Byte; function GetNumberFormatAttributes(ACell: PCell; out ADecimals: Byte; out ACurrencySymbol: String): Boolean; function ReadUsedFormatting(ARow, ACol: Cardinal): TsUsedFormattingFields; overload; @@ -2210,6 +2211,32 @@ begin Result := FCells.Count; end; +{@@ ---------------------------------------------------------------------------- + Determines the number of decimals displayed for the number in the cell + + @param ACell Pointer to the cell under investigation + @return Number of decimals places used in the string display of the cell. +-------------------------------------------------------------------------------} +function TsWorksheet.GetDisplayedDecimals(ACell: PCell): Byte; +var + i, p: Integer; + s: String; +begin + Result := 0; + if (ACell <> nil) and (ACell^.ContentType = cctNumber) then + begin + s := ReadAsUTF8Text(ACell); + p := pos(Workbook.FormatSettings.DecimalSeparator, s); + if p > 0 then + begin + i := p+1; + while (i <= Length(s)) and (s[i] in ['0'..'9']) do inc(i); + Result := i - (p+1); + end; + end; +end; + + {@@ ---------------------------------------------------------------------------- Determines some number format attributes (decimal places, currency symbol) of a cell @@ -2234,9 +2261,15 @@ begin begin parser := TsNumFormatParser.Create(FWorkbook, ACell^.NumberFormatStr); try - if parser.Status = psOK then begin + if parser.Status = psOK then + begin nf := parser.NumFormat; - if (nf = nfGeneral) or IsDateTimeFormat(nf) then + if (nf = nfGeneral) and (ACell^.ContentType = cctNumber) then + begin + ADecimals := GetDisplayedDecimals(ACell); + ACurrencySymbol := ''; + end else + if IsDateTimeFormat(nf) then begin ADecimals := 2; ACurrencySymbol := '?'; @@ -4422,8 +4455,15 @@ procedure TsWorksheet.WriteDecimals(ACell: PCell; ADecimals: Byte); var parser: TsNumFormatParser; begin - if (ACell <> nil) and (ACell^.ContentType = cctNumber) and - (ACell^.NumberFormat <> nfCustom) then + if (ACell = nil) then //or (ACell^.ContentType <> cctNumber) then + exit; + + if (uffNumberFormat in ACell^.UsedFormattingFields) or (ACell^.NumberFormat = nfGeneral) + then begin + WriteNumberFormat(ACell, nfFixed, ADecimals); + ChangedCell(ACell^.Row, ACell^.Col); + end else + if (ACell^.NumberFormat <> nfCustom) then begin parser := TsNumFormatParser.Create(Workbook, ACell^.NumberFormatStr); try