You've already forked lazarus-ccr
fpspreadsheet: Improved formula validation by TsWorksheetGrid and TsCellEdit
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@6524 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -27,9 +27,13 @@ unit fpspreadsheetctrls;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
|
LMessages, LResources, LCLVersion,
|
||||||
Classes, Graphics, SysUtils, Controls, StdCtrls, ComCtrls, ValEdit, ActnList,
|
Classes, Graphics, SysUtils, Controls, StdCtrls, ComCtrls, ValEdit, ActnList,
|
||||||
LResources, LCLVersion,
|
fpstypes, fpspreadsheet;
|
||||||
fpstypes, fpspreadsheet; //, {%H-}fpsAllFormats;
|
|
||||||
|
const
|
||||||
|
{@@ User-defined message for input validation }
|
||||||
|
UM_VALIDATEINPUT = LM_USER + 100;
|
||||||
|
|
||||||
type
|
type
|
||||||
{@@ Event handler procedure for displaying a message if an error or
|
{@@ Event handler procedure for displaying a message if an error or
|
||||||
@ -236,16 +240,25 @@ type
|
|||||||
FWorkbookSource: TsWorkbookSource;
|
FWorkbookSource: TsWorkbookSource;
|
||||||
FShowHTMLText: Boolean;
|
FShowHTMLText: Boolean;
|
||||||
FOldText: String;
|
FOldText: String;
|
||||||
|
FFormulaError: Boolean;
|
||||||
|
FRefocusing: TObject;
|
||||||
|
FRefocusingCol, FRefocusingRow: Cardinal;
|
||||||
function GetSelectedCell: PCell;
|
function GetSelectedCell: PCell;
|
||||||
function GetWorkbook: TsWorkbook;
|
function GetWorkbook: TsWorkbook;
|
||||||
function GetWorksheet: TsWorksheet;
|
function GetWorksheet: TsWorksheet;
|
||||||
procedure SetWorkbookSource(AValue: TsWorkbookSource);
|
procedure SetWorkbookSource(AValue: TsWorkbookSource);
|
||||||
|
procedure ValidateInput(var Msg: TLMessage); message UM_VALIDATEINPUT;
|
||||||
|
procedure WMKillFocus(var AMessage: TLMKillFocus); message LM_KILLFOCUS;
|
||||||
protected
|
protected
|
||||||
|
FEditText: String;
|
||||||
function CanEditCell(ACell: PCell): Boolean; overload;
|
function CanEditCell(ACell: PCell): Boolean; overload;
|
||||||
function CanEditCell(ARow, ACol: Cardinal): Boolean; overload;
|
function CanEditCell(ARow, ACol: Cardinal): Boolean; overload;
|
||||||
procedure CheckFormula;
|
|
||||||
procedure DoEnter; override;
|
procedure DoEnter; override;
|
||||||
procedure KeyDown(var Key : Word; Shift : TShiftState); override;
|
procedure DoExit; override;
|
||||||
|
function DoValidText(const AText: String): Boolean; virtual;
|
||||||
|
function ValidFormula(AFormula: String; out AErrMsg: String): Boolean;
|
||||||
|
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
|
||||||
|
procedure KeyUp(var Key: Word; Shift: TShiftState); override;
|
||||||
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
||||||
procedure ShowCell(ACell: PCell); virtual;
|
procedure ShowCell(ACell: PCell); virtual;
|
||||||
public
|
public
|
||||||
@ -1886,21 +1899,6 @@ begin
|
|||||||
Result := CanEditCell(cell);
|
Result := CanEditCell(cell);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsCellEdit.CheckFormula;
|
|
||||||
var
|
|
||||||
parser: TsSpreadsheetParser;
|
|
||||||
begin
|
|
||||||
if Assigned(Worksheet) and (Text <> '') and (Text[1] = '=') then
|
|
||||||
begin
|
|
||||||
parser := TsSpreadsheetParser.Create(Worksheet);
|
|
||||||
try
|
|
||||||
parser.LocalizedExpression[Workbook.FormatSettings] := Text;
|
|
||||||
finally
|
|
||||||
parser.Free;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TsCellEdit.DoEnter;
|
procedure TsCellEdit.DoEnter;
|
||||||
begin
|
begin
|
||||||
if Worksheet = nil then
|
if Worksheet = nil then
|
||||||
@ -1913,31 +1911,70 @@ begin
|
|||||||
Abort;
|
Abort;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
if FRefocusing = self then
|
||||||
|
FRefocusing := nil;
|
||||||
|
|
||||||
inherited;
|
inherited;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
EditingDone is called when the user presses the RETURN key to finish editing,
|
DoExit is called when the edit has lost focus. Posts a message to the end of
|
||||||
or the TAB key which removes focus from the control, or clicks somewhere else
|
the message queue in order to complete the focus change operation and to
|
||||||
The edited text is written to the worksheet which tries to figure out the
|
trigger validation of the edit afterwards (which will restore the edit as
|
||||||
data type. In particular, if the text begins with an equal sign ("=") then
|
focused control if validation fails.
|
||||||
the text is assumed to be a formula.
|
|
||||||
|
Source of the idea:
|
||||||
|
https://community.embarcadero.com/article/technical-articles/149-tools/12766-validating-input-in-tedit-components
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
procedure TsCellEdit.DoExit;
|
||||||
|
begin
|
||||||
|
if FRefocusing = nil then begin
|
||||||
|
// Remember current text in editor...
|
||||||
|
FEditText := Text;
|
||||||
|
// ... as well as currently selected cell.
|
||||||
|
FRefocusingRow := Worksheet.ActiveCellRow;
|
||||||
|
FRefocusingCol := Worksheet.ActiveCellCol;
|
||||||
|
// Initiate validation of current input
|
||||||
|
PostMessage(Handle, UM_VALIDATEINPUT, 0, LParam(Self));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Validation function for the current text in the edit control called by the
|
||||||
|
handler of the message posted in DoExit. Checks whether a formula is valid.
|
||||||
|
If not, the currently selected cell and the edit's Text are restored, and an
|
||||||
|
error message is displayed.
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
function TsCellEdit.DoValidText(const AText: String): Boolean;
|
||||||
|
var
|
||||||
|
err: String;
|
||||||
|
begin
|
||||||
|
Result := ValidFormula(AText, err);
|
||||||
|
if not Result then begin
|
||||||
|
Worksheet.SelectCell(FRefocusingRow, FRefocusingCol);
|
||||||
|
Text := AText; // restore orig text lost by interaction with grid
|
||||||
|
SelectAll;
|
||||||
|
MessageDlg(err, mtError, [mbOK], 0);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
EditingDone is called when the user presses the RETURN key to finish editing.
|
||||||
|
If the current Text is an invalid formula an error message is displayed and
|
||||||
|
nothing else happens. Otherwise, however, the edited text is written to the
|
||||||
|
worksheet which tries to figure out the data type.
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure TsCellEdit.EditingDone;
|
procedure TsCellEdit.EditingDone;
|
||||||
var
|
var
|
||||||
s: String;
|
s: String;
|
||||||
cell: PCell;
|
cell: PCell;
|
||||||
begin
|
begin
|
||||||
if Worksheet = nil then
|
if (Worksheet = nil) then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
try
|
if not ValidFormula(Text, s) then begin
|
||||||
Checkformula;
|
MessageDlg(s, mtError, [mbOK], 0);
|
||||||
except
|
exit;
|
||||||
on E:Exception do begin
|
|
||||||
MessageDlg(E.Message, mtError, [mbOk], 0);
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
cell := Worksheet.GetCell(Worksheet.ActiveCellRow, Worksheet.ActiveCellCol);
|
cell := Worksheet.GetCell(Worksheet.ActiveCellRow, Worksheet.ActiveCellCol);
|
||||||
@ -1994,16 +2031,35 @@ end;
|
|||||||
procedure TsCellEdit.KeyDown(var Key: Word; Shift : TShiftState);
|
procedure TsCellEdit.KeyDown(var Key: Word; Shift : TShiftState);
|
||||||
var
|
var
|
||||||
selpos: Integer;
|
selpos: Integer;
|
||||||
|
errMsg: String;
|
||||||
begin
|
begin
|
||||||
if Key = VK_ESCAPE then begin
|
FFormulaError := false;
|
||||||
selpos := SelStart;
|
case Key of
|
||||||
Lines.Text := FOldText;
|
VK_RETURN:
|
||||||
SelStart := selpos;
|
if not ValidFormula(Text, errMsg) then begin
|
||||||
exit;
|
Key := 0;
|
||||||
|
FFormulaError := true;
|
||||||
|
MessageDlg(errMsg, mtError, [mbOK], 0);
|
||||||
|
end;
|
||||||
|
VK_ESCAPE:
|
||||||
|
begin
|
||||||
|
Key := 0;
|
||||||
|
selpos := SelStart;
|
||||||
|
Lines.Text := FOldText;
|
||||||
|
SelStart := selpos;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
inherited;
|
inherited;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TsCellEdit.KeyUp(var Key: Word; Shift : TShiftState);
|
||||||
|
begin
|
||||||
|
if FFormulaError and (Key = VK_RETURN) then
|
||||||
|
Key := 0;
|
||||||
|
inherited;
|
||||||
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Notification message received from the WorkbookSource telling which item
|
Notification message received from the WorkbookSource telling which item
|
||||||
of the spreadsheet has changed.
|
of the spreadsheet has changed.
|
||||||
@ -2019,7 +2075,7 @@ procedure TsCellEdit.ListenerNotification(
|
|||||||
var
|
var
|
||||||
cell: PCell;
|
cell: PCell;
|
||||||
begin
|
begin
|
||||||
if (FWorkbookSource = nil) then
|
if (FWorkbookSource = nil) or (FRefocusing = self) then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
if (lniSelection in AChangedItems) or
|
if (lniSelection in AChangedItems) or
|
||||||
@ -2124,6 +2180,62 @@ begin
|
|||||||
ReadOnly := not CanEditCell(ACell);
|
ReadOnly := not CanEditCell(ACell);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Validation routine of current input initiated when the edit lost focus.
|
||||||
|
If input is not correct (DoValidText) then state before focus change is
|
||||||
|
re-established.
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
procedure TsCellEdit.ValidateInput(var Msg: TLMessage);
|
||||||
|
var
|
||||||
|
s: String;
|
||||||
|
begin
|
||||||
|
if TControl(Msg.lParam) is TsCellEdit then begin
|
||||||
|
s := TsCellEdit(Msg.lParam).FEditText;
|
||||||
|
if not DoValidText(s) then begin
|
||||||
|
FRefocusing := TControl(Msg.lParam); // Avoid an endless loop
|
||||||
|
TWinControl(Msg.lParam).SetFocus; // Set focus back
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Checks valididty of the provided formula and creates a corresponding
|
||||||
|
error message.
|
||||||
|
|
||||||
|
Returns TRUE if the provided string is a valid formula or no formula, FALSE
|
||||||
|
otherwise. In the latter case an error message string is returned as well.
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
function TsCellEdit.ValidFormula(AFormula: String; out AErrMsg: String): Boolean;
|
||||||
|
var
|
||||||
|
parser: TsSpreadsheetParser;
|
||||||
|
begin
|
||||||
|
Result := true;
|
||||||
|
AErrMsg := '';
|
||||||
|
|
||||||
|
if Assigned(Worksheet) and (AFormula <> '') and (AFormula[1] = '=') then
|
||||||
|
begin
|
||||||
|
parser := TsSpreadsheetParser.Create(Worksheet);
|
||||||
|
try
|
||||||
|
try
|
||||||
|
parser.LocalizedExpression[Workbook.FormatSettings] := AFormula;
|
||||||
|
except
|
||||||
|
on E: Exception do begin
|
||||||
|
AErrMsg := E.Message;
|
||||||
|
Result := false;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
parser.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TsCellEdit.WMKillFocus(var AMessage: TLMKillFocus);
|
||||||
|
begin
|
||||||
|
// Override inherited behavior because we don't want to call EditingDone
|
||||||
|
// here.
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{------------------------------------------------------------------------------}
|
{------------------------------------------------------------------------------}
|
||||||
{ TsCellIndicator }
|
{ TsCellIndicator }
|
||||||
|
@ -61,24 +61,46 @@ type
|
|||||||
property JoinStyle default pjsMiter;
|
property JoinStyle default pjsMiter;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TMultilineStringCellEditor = class(TMemo)
|
(*
|
||||||
|
TsSingleLineStringCellEditor = class(TEdit)
|
||||||
private
|
private
|
||||||
FGrid: TsCustomWorksheetGrid;
|
FGrid: TsCustomWorksheetGrid;
|
||||||
FCol,FRow:Integer;
|
FCol, FRow:Integer;
|
||||||
|
// procedure WMKillFocus(var AMessage: TLMKillFocus); message LM_KILLFOCUS;
|
||||||
protected
|
protected
|
||||||
procedure WndProc(var TheMessage : TLMessage); override;
|
|
||||||
procedure Change; override;
|
procedure Change; override;
|
||||||
procedure KeyDown(var Key : Word; Shift : TShiftState); override;
|
procedure KeyDown(var AKey: Word; AShift : TShiftState); override;
|
||||||
procedure msg_SetValue(var Msg: TGridMessage); message GM_SETVALUE;
|
procedure msg_GetGrid(var AMsg: TGridMessage); message GM_GETGRID;
|
||||||
procedure msg_GetValue(var Msg: TGridMessage); message GM_GETVALUE;
|
procedure msg_GetValue(var AMsg: TGridMessage); message GM_GETVALUE;
|
||||||
procedure msg_SetGrid(var Msg: TGridMessage); message GM_SETGRID;
|
procedure msg_SelectAll(var AMsg: TGridMessage); message GM_SELECTALL;
|
||||||
procedure msg_SelectAll(var Msg: TGridMessage); message GM_SELECTALL;
|
procedure msg_SetGrid(var AMsg: TGridMessage); message GM_SETGRID;
|
||||||
procedure msg_SetPos(var Msg: TGridMessage); message GM_SETPOS;
|
procedure msg_SetPos(var AMsg: TGridMessage); message GM_SETPOS;
|
||||||
procedure msg_GetGrid(var Msg: TGridMessage); message GM_GETGRID;
|
procedure msg_SetValue(var AMsg: TGridMessage); message GM_SETVALUE;
|
||||||
|
procedure WndProc(var AMsg: TLMessage); override;
|
||||||
public
|
public
|
||||||
constructor Create(Aowner : TComponent); override;
|
constructor Create(AOwner: TComponent); override;
|
||||||
|
procedure EditingDone; override;
|
||||||
|
property OnEditingDone;
|
||||||
|
end;
|
||||||
|
*)
|
||||||
|
|
||||||
|
TsMultilineStringCellEditor = class(TMemo)
|
||||||
|
private
|
||||||
|
FGrid: TsCustomWorksheetGrid;
|
||||||
|
FCol, FRow: Integer;
|
||||||
|
protected
|
||||||
|
procedure Change; override;
|
||||||
|
procedure KeyDown(var AKey: Word; AShift: TShiftState); override;
|
||||||
|
procedure msg_SetValue(var AMsg: TGridMessage); message GM_SETVALUE;
|
||||||
|
procedure msg_GetValue(var AMsg: TGridMessage); message GM_GETVALUE;
|
||||||
|
procedure msg_SetGrid(var AMsg: TGridMessage); message GM_SETGRID;
|
||||||
|
procedure msg_SelectAll(var AMsg: TGridMessage); message GM_SELECTALL;
|
||||||
|
procedure msg_SetPos(var AMsg: TGridMessage); message GM_SETPOS;
|
||||||
|
procedure msg_GetGrid(var AMsg: TGridMessage); message GM_GETGRID;
|
||||||
|
procedure WndProc(var AMsg: TLMessage); override;
|
||||||
|
public
|
||||||
|
constructor Create(AOwner: TComponent); override;
|
||||||
procedure EditingDone; override;
|
procedure EditingDone; override;
|
||||||
// property EditText;
|
|
||||||
property OnEditingDone;
|
property OnEditingDone;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -119,7 +141,8 @@ type
|
|||||||
FReadOnly: Boolean;
|
FReadOnly: Boolean;
|
||||||
FOnClickHyperlink: TsHyperlinkClickEvent;
|
FOnClickHyperlink: TsHyperlinkClickEvent;
|
||||||
FOldEditorText: String;
|
FOldEditorText: String;
|
||||||
FMultiLineStringEditor: TMultilineStringCellEditor;
|
// FSingleLineStringEditor: TsSingleLineStringCellEditor;
|
||||||
|
FMultiLineStringEditor: TsMultilineStringCellEditor;
|
||||||
FLineMode: TsEditorLineMode;
|
FLineMode: TsEditorLineMode;
|
||||||
FAllowDragAndDrop: Boolean;
|
FAllowDragAndDrop: Boolean;
|
||||||
FDragStartCol, FDragStartRow: Integer;
|
FDragStartCol, FDragStartRow: Integer;
|
||||||
@ -127,6 +150,7 @@ type
|
|||||||
FDragSelection: TGridRect;
|
FDragSelection: TGridRect;
|
||||||
FGetRowHeaderText: TsGetCellTextEvent;
|
FGetRowHeaderText: TsGetCellTextEvent;
|
||||||
FGetColHeaderText: TsGetCellTextEvent;
|
FGetColHeaderText: TsGetCellTextEvent;
|
||||||
|
FRefocusing: TObject;
|
||||||
function CalcAutoRowHeight(ARow: Integer): Integer;
|
function CalcAutoRowHeight(ARow: Integer): Integer;
|
||||||
function CalcColWidthFromSheet(AWidth: Single): Integer;
|
function CalcColWidthFromSheet(AWidth: Single): Integer;
|
||||||
function CalcRowHeightFromSheet(AHeight: Single): Integer;
|
function CalcRowHeightFromSheet(AHeight: Single): Integer;
|
||||||
@ -255,6 +279,8 @@ type
|
|||||||
procedure DoCutToClipboard; override;
|
procedure DoCutToClipboard; override;
|
||||||
procedure DoEditorHide; override;
|
procedure DoEditorHide; override;
|
||||||
procedure DoEditorShow; override;
|
procedure DoEditorShow; override;
|
||||||
|
procedure DoEnter; override;
|
||||||
|
procedure DoExit; override;
|
||||||
procedure DoPasteFromClipboard; override;
|
procedure DoPasteFromClipboard; override;
|
||||||
procedure DoOnResize; override;
|
procedure DoOnResize; override;
|
||||||
procedure DoPrepareCanvas(ACol, ARow: Integer; AState: TGridDrawState); override;
|
procedure DoPrepareCanvas(ACol, ARow: Integer; AState: TGridDrawState); override;
|
||||||
@ -314,6 +340,7 @@ type
|
|||||||
function ToPixels(AValue: Double): Integer;
|
function ToPixels(AValue: Double): Integer;
|
||||||
procedure TopLeftChanged; override;
|
procedure TopLeftChanged; override;
|
||||||
function TrimToCell(ACell: PCell): String;
|
function TrimToCell(ACell: PCell): String;
|
||||||
|
procedure ValidateInput(var Msg: TLMessage); message UM_VALIDATEINPUT;
|
||||||
function ValidFormula({ACol, ARow: Integer; }AExpression: String;
|
function ValidFormula({ACol, ARow: Integer; }AExpression: String;
|
||||||
out AErrMsg: String): Boolean;
|
out AErrMsg: String): Boolean;
|
||||||
procedure WMHScroll(var message: TLMHScroll); message LM_HSCROLL;
|
procedure WMHScroll(var message: TLMHScroll); message LM_HSCROLL;
|
||||||
@ -1105,56 +1132,80 @@ end;
|
|||||||
|
|
||||||
|
|
||||||
{*******************************************************************************
|
{*******************************************************************************
|
||||||
* TMultilineStringCellEditor *
|
* TsSingleLineStringCellEditor *
|
||||||
*******************************************************************************}
|
*******************************************************************************}
|
||||||
|
(*
|
||||||
constructor TMultilineStringCellEditor.Create(Aowner: TComponent);
|
constructor TsSingleLineStringCellEditor.Create(AOwner: TComponent);
|
||||||
begin
|
begin
|
||||||
inherited Create(AOwner);
|
inherited Create(AOwner);
|
||||||
AutoSize := false;
|
AutoSize := false;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMultilineStringCellEditor.Change;
|
procedure TsSingleLineStringCellEditor.Change;
|
||||||
begin
|
begin
|
||||||
inherited Change;
|
inherited Change;
|
||||||
if (FGrid <> nil) and Visible then
|
if (FGrid <> nil) and Visible then begin
|
||||||
FGrid.EditorTextChanged(FCol, FRow, Text);
|
FGrid.EditorTextChanged(FCol, FRow, Text);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
{
|
||||||
procedure TMultilineStringCellEditor.EditingDone;
|
function TsSingleLineStringCellEditor.DoValidText(const AText: String): Boolean;
|
||||||
|
var
|
||||||
|
err: String;
|
||||||
|
begin
|
||||||
|
Result := FGrid.ValidFormula(AText, err);
|
||||||
|
if not Result then
|
||||||
|
MessageDlg(err, mtError, [mbOK], 0);
|
||||||
|
end;
|
||||||
|
}
|
||||||
|
procedure TsSingleLineStringCellEditor.EditingDone;
|
||||||
begin
|
begin
|
||||||
inherited EditingDone;
|
inherited EditingDone;
|
||||||
if FGrid <> nil then
|
if FGrid <> nil then
|
||||||
FGrid.EditingDone;
|
FGrid.EditingDone;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMultilineStringCellEditor.KeyDown(var Key: Word; Shift: TShiftState);
|
procedure TsSingleLineStringCellEditor.msg_GetGrid(var AMsg: TGridMessage);
|
||||||
|
begin
|
||||||
|
AMsg.Grid := FGrid;
|
||||||
|
AMsg.Options:= EO_IMPLEMENTED;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TsSingleLineStringCellEditor.msg_GetValue(var AMsg: TGridMessage);
|
||||||
|
begin
|
||||||
|
AMsg.Col := FCol;
|
||||||
|
AMsg.Row := FRow;
|
||||||
|
AMsg.Value := Text;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TsSingleLineStringCellEditor.KeyDown(var AKey: Word;
|
||||||
|
AShift: TShiftState);
|
||||||
|
|
||||||
function AllSelected: boolean;
|
function AllSelected: boolean;
|
||||||
begin
|
begin
|
||||||
result := (SelLength > 0) and (SelLength = UTF8Length(Text));
|
Result := (SelLength > 0) and (SelLength = UTF8Length(Text));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function AtStart: Boolean;
|
function AtStart: Boolean;
|
||||||
begin
|
begin
|
||||||
Result:= (SelStart = 0);
|
Result := (SelStart = 0);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function AtEnd: Boolean;
|
function AtEnd: Boolean;
|
||||||
begin
|
begin
|
||||||
result := ((SelStart + 1) > UTF8Length(Text)) or AllSelected;
|
Result := ((SelStart + 1) > UTF8Length(Text)) or AllSelected;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure doEditorKeyDown;
|
procedure DoEditorKeyDown;
|
||||||
begin
|
begin
|
||||||
if FGrid <> nil then
|
if FGrid <> nil then
|
||||||
FGrid.EditorkeyDown(Self, key, shift);
|
FGrid.EditorkeyDown(Self, AKey, AShift);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure doGridKeyDown;
|
procedure DoGridKeyDown;
|
||||||
begin
|
begin
|
||||||
if FGrid <> nil then
|
if FGrid <> nil then
|
||||||
FGrid.KeyDown(Key, shift);
|
FGrid.KeyDown(AKey, AShift);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function GetFastEntry: boolean;
|
function GetFastEntry: boolean;
|
||||||
@ -1168,15 +1219,179 @@ procedure TMultilineStringCellEditor.KeyDown(var Key: Word; Shift: TShiftState);
|
|||||||
procedure CheckEditingKey;
|
procedure CheckEditingKey;
|
||||||
begin
|
begin
|
||||||
if (FGrid = nil) or FGrid.EditorIsReadOnly then
|
if (FGrid = nil) or FGrid.EditorIsReadOnly then
|
||||||
Key := 0;
|
AKey := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
IntSel: boolean;
|
||||||
|
begin
|
||||||
|
inherited KeyDown(AKey, AShift);
|
||||||
|
case AKey of
|
||||||
|
VK_F2:
|
||||||
|
if AllSelected then begin
|
||||||
|
SelLength := 0;
|
||||||
|
SelStart := Length(Text);
|
||||||
|
end;
|
||||||
|
VK_DELETE, VK_BACK:
|
||||||
|
CheckEditingKey;
|
||||||
|
VK_UP, VK_DOWN:
|
||||||
|
DoGridKeyDown;
|
||||||
|
VK_LEFT, VK_RIGHT:
|
||||||
|
if GetFastEntry then
|
||||||
|
begin
|
||||||
|
IntSel:=
|
||||||
|
((AKey = VK_LEFT) and not AtStart) or
|
||||||
|
((AKey = VK_RIGHT) and not AtEnd);
|
||||||
|
if not IntSel then begin
|
||||||
|
DoGridKeyDown;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
VK_END, VK_HOME:
|
||||||
|
;
|
||||||
|
VK_ESCAPE:
|
||||||
|
begin
|
||||||
|
doGridKeyDown;
|
||||||
|
if AKey <> 0 then begin
|
||||||
|
Text := FGrid.FOldEditorText;
|
||||||
|
FGrid.EditorHide;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
DoEditorKeyDown;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TsSingleLineStringCellEditor.msg_SelectAll(var AMsg: TGridMessage);
|
||||||
|
begin
|
||||||
|
Unused(AMsg);
|
||||||
|
SelectAll;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TsSingleLineStringCellEditor.msg_SetGrid(var AMsg: TGridMessage);
|
||||||
|
begin
|
||||||
|
FGrid := AMsg.Grid as TsCustomWorksheetGrid;
|
||||||
|
AMsg.Options := EO_AUTOSIZE or EO_SELECTALL or EO_HOOKKEYPRESS or EO_HOOKKEYUP;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{
|
||||||
|
procedure TsSingleLineStringCellEditor.msg_SetMask(var AMsg: TGridMessage);
|
||||||
|
begin
|
||||||
|
EditMask := AMsg.Value;
|
||||||
|
end;
|
||||||
|
}
|
||||||
|
procedure TsSingleLineStringCellEditor.msg_SetPos(var AMsg: TGridMessage);
|
||||||
|
begin
|
||||||
|
FCol := AMsg.Col;
|
||||||
|
FRow := AMsg.Row;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TsSingleLineStringCellEditor.msg_SetValue(var AMsg: TGridMessage);
|
||||||
|
begin
|
||||||
|
Text := AMsg.Value;
|
||||||
|
SelStart := UTF8Length(Text);
|
||||||
|
end;
|
||||||
|
{
|
||||||
|
procedure TsSingleLineStringCellEditor.WMKillFocus(var AMessage: TLMKillFocus);
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
}
|
||||||
|
|
||||||
|
procedure TsSingleLineStringCellEditor.WndProc(var AMsg: TLMessage);
|
||||||
|
begin
|
||||||
|
if FGrid <> nil then
|
||||||
|
case AMsg.Msg of
|
||||||
|
LM_CLEAR, LM_CUT, LM_PASTE:
|
||||||
|
begin
|
||||||
|
if FGrid.EditorIsReadOnly then
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
inherited WndProc(AMsg);
|
||||||
|
end;
|
||||||
|
*)
|
||||||
|
|
||||||
|
{*******************************************************************************
|
||||||
|
* TsMultiLineStringCellEditor *
|
||||||
|
*******************************************************************************}
|
||||||
|
|
||||||
|
constructor TsMultilineStringCellEditor.Create(AOwner: TComponent);
|
||||||
|
begin
|
||||||
|
inherited Create(AOwner);
|
||||||
|
AutoSize := false;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TsMultilineStringCellEditor.Change;
|
||||||
|
begin
|
||||||
|
inherited Change;
|
||||||
|
if (FGrid <> nil) and Visible then
|
||||||
|
FGrid.EditorTextChanged(FCol, FRow, Text);
|
||||||
|
end;
|
||||||
|
(*
|
||||||
|
function TsMultiLineStringCellEditor.DoValidText(const AText: String): Boolean;
|
||||||
|
var
|
||||||
|
err: String;
|
||||||
|
begin
|
||||||
|
Result := FGrid.ValidFormula(AText, err);
|
||||||
|
if not Result then
|
||||||
|
MessageDlg(err, mtError, [mbOK], 0);
|
||||||
|
end; *)
|
||||||
|
|
||||||
|
procedure TsMultilineStringCellEditor.EditingDone;
|
||||||
|
begin
|
||||||
|
inherited EditingDone;
|
||||||
|
if FGrid <> nil then
|
||||||
|
FGrid.EditingDone;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TsMultilineStringCellEditor.KeyDown(var AKey: Word; AShift: TShiftState);
|
||||||
|
|
||||||
|
function AllSelected: boolean;
|
||||||
|
begin
|
||||||
|
Result := (SelLength > 0) and (SelLength = UTF8Length(Text));
|
||||||
|
end;
|
||||||
|
|
||||||
|
function AtStart: Boolean;
|
||||||
|
begin
|
||||||
|
Result:= (SelStart = 0);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function AtEnd: Boolean;
|
||||||
|
begin
|
||||||
|
Result := ((SelStart + 1) > UTF8Length(Text)) or AllSelected;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure DoEditorKeyDown;
|
||||||
|
begin
|
||||||
|
if FGrid <> nil then
|
||||||
|
FGrid.EditorkeyDown(Self, AKey, AShift);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure DoGridKeyDown;
|
||||||
|
begin
|
||||||
|
if FGrid <> nil then
|
||||||
|
FGrid.KeyDown(AKey, AShift);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GetFastEntry: boolean;
|
||||||
|
begin
|
||||||
|
if FGrid <> nil then
|
||||||
|
Result := FGrid.FastEditing
|
||||||
|
else
|
||||||
|
Result := False;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure CheckEditingKey;
|
||||||
|
begin
|
||||||
|
if (FGrid = nil) or FGrid.EditorIsReadOnly then
|
||||||
|
AKey := 0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
IntSel: boolean;
|
IntSel: boolean;
|
||||||
msg: String;
|
msg: String;
|
||||||
begin
|
begin
|
||||||
inherited KeyDown(Key,Shift);
|
inherited KeyDown(AKey, AShift);
|
||||||
case Key of
|
case AKey of
|
||||||
VK_F2:
|
VK_F2:
|
||||||
if AllSelected then begin
|
if AllSelected then begin
|
||||||
SelLength := 0;
|
SelLength := 0;
|
||||||
@ -1189,9 +1404,9 @@ begin
|
|||||||
VK_LEFT, VK_RIGHT:
|
VK_LEFT, VK_RIGHT:
|
||||||
if GetFastEntry then begin
|
if GetFastEntry then begin
|
||||||
IntSel:=
|
IntSel:=
|
||||||
((Key=VK_LEFT) and not AtStart) or
|
((AKey = VK_LEFT) and not AtStart) or
|
||||||
((Key=VK_RIGHT) and not AtEnd);
|
((AKey = VK_RIGHT) and not AtEnd);
|
||||||
if not IntSel then begin
|
if not IntSel then begin
|
||||||
doGridKeyDown;
|
doGridKeyDown;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -1200,64 +1415,66 @@ begin
|
|||||||
VK_ESCAPE:
|
VK_ESCAPE:
|
||||||
begin
|
begin
|
||||||
doGridKeyDown;
|
doGridKeyDown;
|
||||||
if key<>0 then begin
|
if AKey <> 0 then begin
|
||||||
Text := FGrid.FOldEditorText;
|
Text := FGrid.FOldEditorText;
|
||||||
// Lines.Text := ''; // FIXME: FGrid.FEditorOldvalue;
|
|
||||||
// SetEditText(FGrid.FEditorOldValue);
|
|
||||||
FGrid.EditorHide;
|
FGrid.EditorHide;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
else
|
else
|
||||||
doEditorKeyDown;
|
DoEditorKeyDown;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMultilineStringCellEditor.msg_GetGrid(var Msg: TGridMessage);
|
procedure TsMultilineStringCellEditor.msg_GetGrid(var AMsg: TGridMessage);
|
||||||
begin
|
begin
|
||||||
Msg.Grid := FGrid;
|
AMsg.Grid := FGrid;
|
||||||
Msg.Options:= EO_IMPLEMENTED;
|
AMsg.Options:= EO_IMPLEMENTED;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMultilineStringCellEditor.msg_GetValue(var Msg: TGridMessage);
|
procedure TsMultilineStringCellEditor.msg_GetValue(var AMsg: TGridMessage);
|
||||||
begin
|
begin
|
||||||
Msg.Col := FCol;
|
AMsg.Col := FCol;
|
||||||
Msg.Row := FRow;
|
AMsg.Row := FRow;
|
||||||
Msg.Value := Text;
|
AMsg.Value := Text;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMultilineStringCellEditor.msg_SelectAll(var Msg: TGridMessage);
|
procedure TsMultilineStringCellEditor.msg_SelectAll(var AMsg: TGridMessage);
|
||||||
begin
|
begin
|
||||||
Unused(Msg);
|
Unused(AMsg);
|
||||||
SelectAll;
|
SelectAll;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMultilineStringCellEditor.msg_SetGrid(var Msg: TGridMessage);
|
procedure TsMultilineStringCellEditor.msg_SetGrid(var AMsg: TGridMessage);
|
||||||
begin
|
begin
|
||||||
FGrid := Msg.Grid as TsCustomWorksheetGrid;
|
FGrid := AMsg.Grid as TsCustomWorksheetGrid;
|
||||||
Msg.Options := EO_AUTOSIZE or EO_SELECTALL or EO_HOOKKEYPRESS or EO_HOOKKEYUP;
|
AMsg.Options := EO_AUTOSIZE or EO_SELECTALL or EO_HOOKKEYPRESS or EO_HOOKKEYUP;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMultilineStringCellEditor.msg_SetPos(var Msg: TGridMessage);
|
procedure TsMultilineStringCellEditor.msg_SetPos(var AMsg: TGridMessage);
|
||||||
begin
|
begin
|
||||||
FCol := Msg.Col;
|
FCol := AMsg.Col;
|
||||||
FRow := Msg.Row;
|
FRow := AMsg.Row;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMultilineStringCellEditor.msg_SetValue(var Msg: TGridMessage);
|
procedure TsMultilineStringCellEditor.msg_SetValue(var AMsg: TGridMessage);
|
||||||
begin
|
begin
|
||||||
Text := Msg.Value;
|
Text := AMsg.Value;
|
||||||
SelStart := UTF8Length(Text);
|
SelStart := UTF8Length(Text);
|
||||||
end;
|
end;
|
||||||
|
(*
|
||||||
|
procedure TsMultiLineStringCellEditor.WMKillFocus(var AMessage: TLMKillFocus);
|
||||||
|
begin
|
||||||
|
end; *)
|
||||||
|
|
||||||
procedure TMultilineStringCellEditor.WndProc(var TheMessage: TLMessage);
|
procedure TsMultilineStringCellEditor.WndProc(var AMsg: TLMessage);
|
||||||
begin
|
begin
|
||||||
if FGrid <> nil then
|
if FGrid <> nil then
|
||||||
case TheMessage.Msg of
|
case AMsg.Msg of
|
||||||
LM_CLEAR, LM_CUT, LM_PASTE:
|
LM_CLEAR, LM_CUT, LM_PASTE:
|
||||||
if FGrid.EditorIsReadOnly then exit;
|
if FGrid.EditorIsReadOnly then exit;
|
||||||
end;
|
end;
|
||||||
inherited WndProc(TheMessage);
|
inherited WndProc(AMsg);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -1314,6 +1531,13 @@ begin
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
FAllowDragAndDrop := true;
|
FAllowDragAndDrop := true;
|
||||||
|
(*
|
||||||
|
FSingleLineStringEditor := TsSingleLineStringCellEditor.Create(self);
|
||||||
|
FSingleLineStringEditor.name :='SingleLineStringEditor';
|
||||||
|
FSingleLineStringEditor.Text := '';
|
||||||
|
FSingleLineStringEditor.Visible := False;
|
||||||
|
FSingleLineStringEditor.Align := alNone;
|
||||||
|
FSingleLineStringEditor.BorderStyle := bsNone; *)
|
||||||
|
|
||||||
dec(FRowHeightLock);
|
dec(FRowHeightLock);
|
||||||
UpdateRowHeights;
|
UpdateRowHeights;
|
||||||
@ -1330,7 +1554,8 @@ begin
|
|||||||
FreeAndNil(FCellFont);
|
FreeAndNil(FCellFont);
|
||||||
FreeAndNil(FSelPen);
|
FreeAndNil(FSelPen);
|
||||||
FreeAndNil(FFrozenBorderPen);
|
FreeAndNil(FFrozenBorderPen);
|
||||||
FreeAndNil(FMultilineStringEditor);
|
// FreeAndNil(FSingleLineStringEditor);
|
||||||
|
FreeAndNil(FMultiLineStringEditor);
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2002,13 +2227,15 @@ var
|
|||||||
msg: String;
|
msg: String;
|
||||||
begin
|
begin
|
||||||
inherited;
|
inherited;
|
||||||
|
{
|
||||||
// The following code is reached when an error is found in the cell formula
|
// The following code is reached when an error is found in the cell formula
|
||||||
// being edited and another control is selected.
|
// being edited and another control is selected.
|
||||||
if (FEditText <> '') then
|
if (FEditText <> '') then begin
|
||||||
if not ValidFormula(FEditText, msg) then begin
|
if not lula(FEditText, msg) then
|
||||||
MessageDlg(msg, mtError, [mbOK], 0);
|
MessageDlg(msg, mtError, [mbOK], 0);
|
||||||
FEditText := '';
|
FEditText := '';
|
||||||
end;
|
end;
|
||||||
|
}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Make the cell editor the same size as the edited cell, in particular for
|
{ Make the cell editor the same size as the edited cell, in particular for
|
||||||
@ -2040,6 +2267,22 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TsCustomWorksheetGrid.DoEnter;
|
||||||
|
begin
|
||||||
|
if FRefocusing = self then
|
||||||
|
FRefocusing := nil;
|
||||||
|
inherited;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TsCustomWorksheetGrid.DoExit;
|
||||||
|
begin
|
||||||
|
{ Post a message to myself which indicates it's time to validate the input.
|
||||||
|
Pass the grid instance (Self) as the message lParam. }
|
||||||
|
if FRefocusing = nil then
|
||||||
|
PostMessage(Handle, um_ValidateInput, 0, LParam(Self));
|
||||||
|
FGridState := gsNormal;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TsCustomWorksheetGrid.DoOnResize;
|
procedure TsCustomWorksheetGrid.DoOnResize;
|
||||||
begin
|
begin
|
||||||
if (csDesigning in ComponentState) and (Worksheet = nil) then
|
if (csDesigning in ComponentState) and (Worksheet = nil) then
|
||||||
@ -3296,6 +3539,13 @@ end;
|
|||||||
|
|
||||||
function TsCustomWorksheetGrid.EditorByStyle(Style: TColumnButtonStyle): TWinControl;
|
function TsCustomWorksheetGrid.EditorByStyle(Style: TColumnButtonStyle): TWinControl;
|
||||||
begin
|
begin
|
||||||
|
(*
|
||||||
|
if (Style = cbsAuto) then
|
||||||
|
case FLineMode of
|
||||||
|
elmSingleLine : Result := FSingleLineStringEditor;
|
||||||
|
elmMultiLine : Result := FMultiLineStringEditor ;
|
||||||
|
end
|
||||||
|
*)
|
||||||
if (Style = cbsAuto) and (FLineMode = elmMultiLine) then
|
if (Style = cbsAuto) and (FLineMode = elmMultiLine) then
|
||||||
Result := FMultiLineStringEditor
|
Result := FMultiLineStringEditor
|
||||||
else
|
else
|
||||||
@ -4676,7 +4926,6 @@ begin
|
|||||||
Key := 0;
|
Key := 0;
|
||||||
end;
|
end;
|
||||||
end;
|
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
|
||||||
@ -5386,6 +5635,7 @@ var
|
|||||||
err: String;
|
err: String;
|
||||||
begin
|
begin
|
||||||
// Checking validity of formula in current cell
|
// Checking validity of formula in current cell
|
||||||
|
|
||||||
if Assigned(Worksheet) and EditorMode then begin
|
if Assigned(Worksheet) and EditorMode then begin
|
||||||
if not ValidFormula(FEditText, err) then begin
|
if not ValidFormula(FEditText, err) then begin
|
||||||
FGridState := gsNormal;
|
FGridState := gsNormal;
|
||||||
@ -5395,6 +5645,7 @@ begin
|
|||||||
end;
|
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
|
||||||
@ -5464,22 +5715,6 @@ begin
|
|||||||
maxRowCount := IfThen(aeDefault in FAutoExpand, DEFAULT_ROW_COUNT, 1);
|
maxRowCount := IfThen(aeDefault in FAutoExpand, DEFAULT_ROW_COUNT, 1);
|
||||||
ColCount := Max(GetGridCol(Worksheet.GetLastColIndex) + 1, maxColCount);
|
ColCount := Max(GetGridCol(Worksheet.GetLastColIndex) + 1, maxColCount);
|
||||||
RowCount := Max(GetGridRow(Worksheet.GetLastRowIndex) + 1, maxRowCount);
|
RowCount := Max(GetGridRow(Worksheet.GetLastRowIndex) + 1, maxRowCount);
|
||||||
(*
|
|
||||||
if aeDefault in FAutoExpand then begin
|
|
||||||
ColCount := Max(GetGridCol(Worksheet.GetLastColIndex)+1, DEFAULT_COL_COUNT); // + FHeaderCount;
|
|
||||||
RowCount := Max(GetGridRow(Worksheet.GetLastRowIndex)+1, DEFAULT_ROW_COUNT); // + FHeaderCount;
|
|
||||||
end else begin
|
|
||||||
|
|
||||||
// wp: next lines replaced by the following ones because of
|
|
||||||
// http://forum.lazarus.freepascal.org/index.php/topic,36770.msg246192.html#msg246192
|
|
||||||
// NOTE: VERY SENSITIVE LOCATION !!!
|
|
||||||
|
|
||||||
// ColCount := Max(GetGridCol(WorkSheet.GetLastColIndex), 1) + FHeaderCount;
|
|
||||||
// RowCount := Max(GetGridCol(Worksheet.GetLastRowIndex), 1) + FHeaderCount;
|
|
||||||
ColCount := Max(GetGridCol(WorkSheet.GetLastColIndex)+1, 1); // + FHeaderCount;
|
|
||||||
RowCount := Max(GetGridCol(Worksheet.GetLastRowIndex)+1, 1); // + FHeaderCount;
|
|
||||||
end;
|
|
||||||
*)
|
|
||||||
FixedCols := FFrozenCols + FHeaderCount;
|
FixedCols := FFrozenCols + FHeaderCount;
|
||||||
FixedRows := FFrozenRows + FHeaderCount;
|
FixedRows := FFrozenRows + FHeaderCount;
|
||||||
if ShowHeaders then begin
|
if ShowHeaders then begin
|
||||||
@ -6765,11 +7000,11 @@ begin
|
|||||||
FLineMode := AValue;
|
FLineMode := AValue;
|
||||||
if (FLineMode = elmMultiline) and (FMultilineStringEditor = nil) then
|
if (FLineMode = elmMultiline) and (FMultilineStringEditor = nil) then
|
||||||
begin
|
begin
|
||||||
FMultilineStringEditor := TMultilineStringCellEditor.Create(nil);
|
FMultilineStringEditor := TsMultilineStringCellEditor.Create(nil);
|
||||||
FMultilineStringEditor.name :='StringEditor';
|
FMultilineStringEditor.name := 'MultilineStringEditor';
|
||||||
FMultilineStringEditor.Text:='';
|
FMultilineStringEditor.Text := '';
|
||||||
FMultilineStringEditor.Visible:=False;
|
FMultilineStringEditor.Visible := False;
|
||||||
FMultilineStringEditor.Align:=alNone;
|
FMultilineStringEditor.Align := alNone;
|
||||||
FMultilineStringEditor.BorderStyle := bsNone;
|
FMultilineStringEditor.BorderStyle := bsNone;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -7053,15 +7288,29 @@ begin
|
|||||||
BeginUpdate;
|
BeginUpdate;
|
||||||
try
|
try
|
||||||
Worksheet.ZoomFactor := abs(AValue);
|
Worksheet.ZoomFactor := abs(AValue);
|
||||||
// AdaptToZoomFactor;
|
|
||||||
finally
|
finally
|
||||||
EndUpdate;
|
EndUpdate;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TsCustomWorksheetGrid.ValidFormula(//ACol, ARow: Integer;
|
procedure TsCustomWorksheetGrid.ValidateInput(var Msg: TLMessage);
|
||||||
AExpression: String; out AErrMsg: String): Boolean;
|
var
|
||||||
|
grid: TsCustomWorksheetGrid;
|
||||||
|
errmsg: String;
|
||||||
|
begin
|
||||||
|
if TObject(Msg.lParam) is TsCustomWorksheetGrid then begin
|
||||||
|
grid := TsCustomWorksheetGrid(Msg.lParam);
|
||||||
|
if not ValidFormula(FEditText, errmsg) then begin
|
||||||
|
MessageDlg(errmsg, mtError, [mbOK], 0);
|
||||||
|
FRefocusing := grid; // Avoid an endless loop
|
||||||
|
grid.SetFocus; // Set focus back
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TsCustomWorksheetGrid.ValidFormula(AExpression: String;
|
||||||
|
out AErrMsg: String): Boolean;
|
||||||
var
|
var
|
||||||
parser: TsSpreadsheetParser;
|
parser: TsSpreadsheetParser;
|
||||||
begin
|
begin
|
||||||
|
Reference in New Issue
Block a user