fpspreadsheet: Make WorksheetGrid respect the spSelectLockedCells and spSelectUnlockedCells flags in the worksheet's Protection set. Like in Excel, TsCellEdit displays an error message box if the user tries to focus it in case of a locked cell.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@5815 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2017-03-20 11:10:02 +00:00
parent e3d40d489f
commit b736103903
3 changed files with 61 additions and 4 deletions

View File

@ -674,7 +674,7 @@ type
TsCellProtection = (cpLockCell, cpHideFormulas);
TsCellProtections = set of TsCellProtection;
const
const // all this actions are FORBIDDEN is included and ALLOWED of excluded!
ALL_SHEET_PROTECTIONS = [spFormatCells, spFormatColumns, spFormatRows,
spDeleteColumns, spDeleteRows, spInsertColumns, spInsertRows, spInsertHyperlinks,
spCells, spSort, spObjects, spSelectLockedCells, spSelectUnlockedCells

View File

@ -241,6 +241,9 @@ type
function GetWorksheet: TsWorksheet;
procedure SetWorkbookSource(AValue: TsWorkbookSource);
protected
function CanEditCell(ACell: PCell): Boolean; overload;
function CanEditCell(ARow, ACol: Cardinal): Boolean; overload;
procedure DoEnter; override;
procedure KeyDown(var Key : Word; Shift : TShiftState); override;
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
procedure ShowCell(ACell: PCell); virtual;
@ -1856,6 +1859,36 @@ begin
inherited Destroy;
end;
function TsCellEdit.CanEditCell(ACell: PCell): Boolean;
begin
if Worksheet.IsMerged(ACell) then
ACell := Worksheet.FindMergeBase(ACell);
Result := not (
Worksheet.IsProtected and
(spCells in Worksheet.Protection) and
((ACell = nil) or (cpLockcell in Worksheet.ReadCellProtection(ACell)))
);
end;
function TsCellEdit.CanEditCell(ARow, ACol: Cardinal): Boolean;
var
cell: PCell;
begin
cell := Worksheet.Findcell(Worksheet.ActiveCellRow, Worksheet.ActiveCellCol);
Result := CanEditCell(cell);
end;
procedure TsCellEdit.DoEnter;
begin
if not CanEditCell(Worksheet.ActiveCellRow, Worksheet.ActiveCellCol) then
begin
MessageDlg('This cell is protected from editing. Unlock worksheet protection '+
'before continuing.', mtInformation, [mbOK], 0);
Abort;
end;
inherited;
end;
{@@ ----------------------------------------------------------------------------
EditingDone is called when the user presses the RETURN key to finish editing,
or the TAB key which removes focus from the control, or clicks somewhere else
@ -2051,8 +2084,7 @@ begin
FOldText := Lines.Text;
ReadOnly := Worksheet.IsProtected and (spCells in Worksheet.Protection) and
(cpLockCell in Worksheet.ReadCellProtection(ACell));
ReadOnly := not CanEditCell(ACell);
end;

View File

@ -261,6 +261,7 @@ type
procedure PrepareCanvasFont;
function RelaxAutoExpand: TsAutoExpandModes;
procedure RestoreAutoExpand(AValue: TsAutoExpandModes);
function SelectCell(ACol, ARow: Integer): Boolean; override;
procedure SelPenChangeHandler(Sender: TObject);
procedure SetEditText(ACol, ARow: Longint; const AValue: string); override;
procedure Setup;
@ -4831,8 +4832,32 @@ begin
GetWorkbookSource.SelectWorksheet(Workbook.GetWorksheetByIndex(AIndex));
end;
{@@ ----------------------------------------------------------------------------
Standard method inherited from TCustomGrid. Is overridden to prevent
selection of cells in a protected worksheet. Details depend on whether
the elements spSelectLockedCells and/or spSelectUnlockedCells are included in
the worksheet's set of protections, and whether the cell to be selected is
locked or not.
-------------------------------------------------------------------------------}
function TsCustomWorksheetGrid.SelectCell(ACol, ARow: Integer): Boolean;
var
cell: PCell;
cp: TsCellprotections;
begin
Result := true;
if Worksheet.IsProtected then
begin
cell := Worksheet.FindCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
cp := Worksheet.ReadCellProtection(cell);
if (cpLockCell in cp) and (spSelectLockedCells in Worksheet.Protection) then
Result := false;
if not (cpLockCell in cp) and (spSelectUnlockedCells in Worksheet.Protection) then
Result := false;
end;
end;
{@@ Event handler which fires when an element of the SelectionPen changes. }
procedure TsCustomWOrksheetGrid.SelPenChangeHandler(Sender: TObject);
procedure TsCustomWorksheetGrid.SelPenChangeHandler(Sender: TObject);
begin
InvalidateGrid;
end;