diff --git a/components/fpspreadsheet/source/common/fpstypes.pas b/components/fpspreadsheet/source/common/fpstypes.pas index 77287f76a..5bcef293f 100644 --- a/components/fpspreadsheet/source/common/fpstypes.pas +++ b/components/fpspreadsheet/source/common/fpstypes.pas @@ -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 diff --git a/components/fpspreadsheet/source/visual/fpspreadsheetctrls.pas b/components/fpspreadsheet/source/visual/fpspreadsheetctrls.pas index 686e16742..89a87185b 100644 --- a/components/fpspreadsheet/source/visual/fpspreadsheetctrls.pas +++ b/components/fpspreadsheet/source/visual/fpspreadsheetctrls.pas @@ -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; diff --git a/components/fpspreadsheet/source/visual/fpspreadsheetgrid.pas b/components/fpspreadsheet/source/visual/fpspreadsheetgrid.pas index dfc9ef923..08bb551a7 100644 --- a/components/fpspreadsheet/source/visual/fpspreadsheetgrid.pas +++ b/components/fpspreadsheet/source/visual/fpspreadsheetgrid.pas @@ -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;