fpspreadsheet: Fix grid behavior when navigating to another cell and the currenly edited cell contains a formula with error.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@6503 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2018-06-17 21:53:40 +00:00
parent 53e2ca7944
commit 92a061388c

View File

@@ -246,6 +246,7 @@ type
function CanEditShow: boolean; override; function CanEditShow: boolean; override;
function CellOverflow(ACol, ARow: Integer; AState: TGridDrawState; function CellOverflow(ACol, ARow: Integer; AState: TGridDrawState;
out ACol1, ACol2: Integer; var ARect: TRect): Boolean; out ACol1, ACol2: Integer; var ARect: TRect): Boolean;
procedure CheckFormula(ACol, ARow: Integer; AExpression: String);
procedure ColRowMoved(IsColumn: Boolean; FromIndex,ToIndex: Integer); override; procedure ColRowMoved(IsColumn: Boolean; FromIndex,ToIndex: Integer); override;
procedure CreateHandle; override; procedure CreateHandle; override;
procedure CreateNewWorkbook; procedure CreateNewWorkbook;
@@ -832,8 +833,8 @@ implementation
uses uses
Types, LCLType, LCLIntf, LCLProc, LazUTF8, Math, StrUtils, Types, LCLType, LCLIntf, LCLProc, LazUTF8, Math, StrUtils,
fpCanvas, {%H-}fpsPatches, fpCanvas, {%H-}fpsPatches, fpsStrings, fpsUtils, fpsVisualUtils, fpsHTMLUtils,
fpsStrings, fpsUtils, fpsVisualUtils, fpsHTMLUtils, fpsImages, fpsNumFormat; fpsImages, fpsNumFormat, fpsExprParser;
const const
{@@ Interval how long the mouse buttons has to be held down on a {@@ Interval how long the mouse buttons has to be held down on a
@@ -1905,6 +1906,23 @@ begin
UpdateRowHeights(AGridRow); UpdateRowHeights(AGridRow);
end; end;
procedure TsCustomWorksheetGrid.CheckFormula(ACol, ARow: Integer;
AExpression: String);
var
parser: TsSpreadsheetParser;
begin
if Assigned(Worksheet) and
(AExpression <> '') and (AExpression[1] = '=') then
begin
parser := TsSpreadsheetParser.Create(Worksheet);
try
parser.Expression := AExpression;
finally
parser.Free;
end;
end;
end;
procedure TsCustomWorksheetGrid.ColRowMoved(IsColumn: Boolean; procedure TsCustomWorksheetGrid.ColRowMoved(IsColumn: Boolean;
FromIndex,ToIndex: Integer); FromIndex,ToIndex: Integer);
begin begin
@@ -3256,9 +3274,14 @@ begin
cell := Worksheet.GetCell(GetWorksheetRow(Row), GetWorksheetCol(Col)); cell := Worksheet.GetCell(GetWorksheetRow(Row), GetWorksheetCol(Col));
if Worksheet.IsMerged(cell) then if Worksheet.IsMerged(cell) then
cell := Worksheet.FindMergeBase(cell); cell := Worksheet.FindMergeBase(cell);
if (FEditText <> '') and (FEditText[1] = '=') then if (FEditText <> '') and (FEditText[1] = '=') then begin
Worksheet.WriteFormula(cell, Copy(FEditText, 2, Length(FEditText)), true) // try
else Worksheet.WriteFormula(cell, Copy(FEditText, 2, Length(FEditText)), true)
// except
// on E: Exception do
// cell := nil;
// end;
end else
Worksheet.WriteCellValueAsString(cell, FEditText); Worksheet.WriteCellValueAsString(cell, FEditText);
FEditText := ''; FEditText := '';
FOldEditorText := ''; FOldEditorText := '';
@@ -4637,6 +4660,12 @@ procedure TsCustomWorksheetGrid.KeyDown(var Key : Word; Shift : TShiftState);
var var
R: TRect; R: TRect;
begin begin
// Check validity for formula before navigating to another cell.
case Key of
VK_TAB, VK_LEFT, VK_RIGHT, VK_UP, VK_DOWN, VK_PRIOR, VK_NEXT, VK_END, VK_HOME:
if EditorMode then CheckFormula(Col, Row, FEditText);
end;
case Key of case Key of
VK_RIGHT: VK_RIGHT:
if (aeNavigation in FAutoExpand) and (Col = ColCount-1) then if (aeNavigation in FAutoExpand) and (Col = ColCount-1) then
@@ -5016,6 +5045,9 @@ begin
if Worksheet = nil then if Worksheet = nil then
exit; exit;
mouseCell := MouseToCell(Point(X, Y));
if EditorMode then CheckFormula(mouseCell.X, mouseCell.Y, FEditText);
if FAllowDragAndDrop and if FAllowDragAndDrop and
(not Assigned(DragManager) or not DragManager.IsDragging) and (not Assigned(DragManager) or not DragManager.IsDragging) and
(ssLeft in Shift) and (ssLeft in Shift) and
@@ -5037,7 +5069,6 @@ begin
begin begin
{ Prepare processing of the hyperlink: triggers a timer, the hyperlink is { Prepare processing of the hyperlink: triggers a timer, the hyperlink is
executed when the timer has expired (see HyperlinkTimerElapsed). } executed when the timer has expired (see HyperlinkTimerElapsed). }
mouseCell := MouseToCell(Point(X, Y));
r := GetWorksheetRow(mouseCell.Y); r := GetWorksheetRow(mouseCell.Y);
c := GetWorksheetCol(mouseCell.X); c := GetWorksheetCol(mouseCell.X);
cell := Worksheet.FindCell(r, c); cell := Worksheet.FindCell(r, c);
@@ -5064,7 +5095,7 @@ end;
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
procedure TsCustomWorksheetGrid.MouseMove(Shift: TShiftState; X, Y: Integer); procedure TsCustomWorksheetGrid.MouseMove(Shift: TShiftState; X, Y: Integer);
{ {
--- wp: removed this for testing: why does the entire grid be repainted when the --- wp: removed this for testing: why is the entire grid repainted when the
mouse moved to another cell? mouse moved to another cell?
var var
prevMouseCell: TPoint; prevMouseCell: TPoint;
@@ -5337,8 +5368,31 @@ function TsCustomWorksheetGrid.SelectCell(ACol, ARow: Integer): Boolean;
var var
cell: PCell; cell: PCell;
cp: TsCellprotections; cp: TsCellprotections;
parser: TsSpreadsheetParser;
begin begin
// Checking validity of formula in current cell
if Assigned(Worksheet) and EditorMode then begin
if (FEditText <> '') and (FEditText[1] = '=') then begin
parser := TsSpreadsheetParser.Create(Worksheet);
try
try
parser.LocalizedExpression[Workbook.FormatSettings] := FEditText;
except
on E:Exception do begin
FGridState := gsNormal;
MessageDlg(E.Message, mtError, [mbOK], 0);
Result := false;
exit;
end;
end;
finally
parser.Free;
end;
end;
end;
Result := inherited; Result := inherited;
if Result and Assigned(Worksheet) and Worksheet.IsProtected then if Result and Assigned(Worksheet) and Worksheet.IsProtected then
begin begin
cell := Worksheet.FindCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol)); cell := Worksheet.FindCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));