So the problem this problem is already solved (you helped me earlier with it).
I know. Just wanted to document that your observation was correct. All the demos had been working correctly with Laz 1.8.2/fpc 3.0.2, but did not compile with 1.8.4/fpc3.0.4. This has been fixed in the current fpspreadsheet revision.
The problem I have now is with the lines:
swDest.Workbook.GetWorksheetByIndex(0).CryptoInfo.Algorithm:= caExcel;
swDest.Workbook.GetWorksheetByIndex(0).CryptoInfo.PasswordHash:=psw;
(311,57) Error: Argument cannot be assigned to
swDest.Workbook.GetWorksheetByIndex(0).Protection: = [spDeleteRows, spInsertRows, spSort];
(313,57) Error: Illegal expression
This is because CryptoInfo is a record, and the worksheet only has a getter/setter for the entire record, not for its individual elements. Create a local variable "c: TsCryptoInfo", assign the individual record elements, and then assign the entire record to the CryptoInfo of the worksheet.
I don't see anything wrong with the instruction "...Protection := [...]"
Here is a tested example with cell and sheet protection:
program demo_protection;
{$mode objfpc}{$H+}
uses
Classes, SysUtils,
fpstypes, fpspreadsheet, fpsallformats, fpsutils, fpscrypto;
const
PASSWORD = 'lazarus';
var
book: TsWorkbook;
sheet: TsWorksheet;
cell: PCell;
c: TsCryptoInfo;
begin
book := TsWorkbook.Create;
try
sheet := book.AddWorksheet('Sheet1');
// Add an unprotected cell
cell := sheet.WriteText(0, 0, 'Unprotected cell');
sheet.WriteCellProtection(cell, []);
// Add a protected cell
sheet.WriteText(1, 0, 'Protected cell');
// Activate worksheet protection such that a password is required to
// change the protection state
InitCryptoInfo(c);
c.Algorithm := caExcel;
c.PasswordHash := Format('%.4x', [ExcelPasswordHash(PASSWORD)]);
sheet.CryptoInfo := c;
sheet.Protection := [spDeleteRows, spDeleteColumns, spInsertRows, spInsertColumns];
sheet.Protect(true);
book.WriteToFile('protected.xls', sfExcel8, true);
book.WriteToFile('protected.xlsx', sfOOXML, true);
// Note ODS does not write the excel password correctly, yet. --> protection cannot be removed.
book.WriteToFile('protected.ods', sfOpenDocument, true);
finally
book.Free;
end;
WriteLn('Open the files "protected.*" in your spreadsheet application.');
WriteLn('Only cell A1 can be modifed.');
WriteLn('Press [ENTER] to quit...');
ReadLn;
end.
Note that protecting the protection settings by a password does not work for ODS files because I did not yet sort out how the stored password hash is created from the Excel hash or password. Ideas are welcome.