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

View File

@@ -241,6 +241,9 @@ type
function GetWorksheet: TsWorksheet; function GetWorksheet: TsWorksheet;
procedure SetWorkbookSource(AValue: TsWorkbookSource); procedure SetWorkbookSource(AValue: TsWorkbookSource);
protected 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 KeyDown(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;
@@ -1856,6 +1859,36 @@ begin
inherited Destroy; inherited Destroy;
end; 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, 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 or the TAB key which removes focus from the control, or clicks somewhere else
@@ -2051,8 +2084,7 @@ begin
FOldText := Lines.Text; FOldText := Lines.Text;
ReadOnly := Worksheet.IsProtected and (spCells in Worksheet.Protection) and ReadOnly := not CanEditCell(ACell);
(cpLockCell in Worksheet.ReadCellProtection(ACell));
end; end;

View File

@@ -261,6 +261,7 @@ type
procedure PrepareCanvasFont; procedure PrepareCanvasFont;
function RelaxAutoExpand: TsAutoExpandModes; function RelaxAutoExpand: TsAutoExpandModes;
procedure RestoreAutoExpand(AValue: TsAutoExpandModes); procedure RestoreAutoExpand(AValue: TsAutoExpandModes);
function SelectCell(ACol, ARow: Integer): Boolean; override;
procedure SelPenChangeHandler(Sender: TObject); procedure SelPenChangeHandler(Sender: TObject);
procedure SetEditText(ACol, ARow: Longint; const AValue: string); override; procedure SetEditText(ACol, ARow: Longint; const AValue: string); override;
procedure Setup; procedure Setup;
@@ -4831,8 +4832,32 @@ begin
GetWorkbookSource.SelectWorksheet(Workbook.GetWorksheetByIndex(AIndex)); GetWorkbookSource.SelectWorksheet(Workbook.GetWorksheetByIndex(AIndex));
end; 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. } {@@ Event handler which fires when an element of the SelectionPen changes. }
procedure TsCustomWOrksheetGrid.SelPenChangeHandler(Sender: TObject); procedure TsCustomWorksheetGrid.SelPenChangeHandler(Sender: TObject);
begin begin
InvalidateGrid; InvalidateGrid;
end; end;