You've already forked lazarus-ccr
fpspreadsheet: Add reading of cell/sheet/workbook protection for xls biff8.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@5789 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@@ -368,6 +368,9 @@ const
|
|||||||
{ XF CELL BACKGROUND PATTERN }
|
{ XF CELL BACKGROUND PATTERN }
|
||||||
MASK_XF_BACKGROUND_PATTERN = $FC000000;
|
MASK_XF_BACKGROUND_PATTERN = $FC000000;
|
||||||
|
|
||||||
|
{ XP CELL PROTECTION }
|
||||||
|
MASK_XF_PROTECTION = $0007;
|
||||||
|
|
||||||
{ HLINK FLAGS }
|
{ HLINK FLAGS }
|
||||||
MASK_HLINK_LINK = $00000001;
|
MASK_HLINK_LINK = $00000001;
|
||||||
MASK_HLINK_ABSOLUTE = $00000002;
|
MASK_HLINK_ABSOLUTE = $00000002;
|
||||||
@@ -799,16 +802,19 @@ begin
|
|||||||
case RecordType of
|
case RecordType of
|
||||||
INT_EXCEL_ID_BOF : ;
|
INT_EXCEL_ID_BOF : ;
|
||||||
INT_EXCEL_ID_BOUNDSHEET : ReadBoundSheet(AStream);
|
INT_EXCEL_ID_BOUNDSHEET : ReadBoundSheet(AStream);
|
||||||
|
INT_EXCEL_ID_CODEPAGE : ReadCodepage(AStream);
|
||||||
|
INT_EXCEL_ID_DATEMODE : ReadDateMode(AStream);
|
||||||
INT_EXCEL_ID_DEFINEDNAME : ReadDEFINEDNAME(AStream);
|
INT_EXCEL_ID_DEFINEDNAME : ReadDEFINEDNAME(AStream);
|
||||||
INT_EXCEL_ID_EOF : SectionEOF := True;
|
INT_EXCEL_ID_EOF : SectionEOF := True;
|
||||||
INT_EXCEL_ID_EXTERNSHEET : ReadEXTERNSHEET(AStream);
|
INT_EXCEL_ID_EXTERNSHEET : ReadEXTERNSHEET(AStream);
|
||||||
INT_EXCEL_ID_SST : ReadSST(AStream);
|
|
||||||
INT_EXCEL_ID_CODEPAGE : ReadCodepage(AStream);
|
|
||||||
INT_EXCEL_ID_FONT : ReadFont(AStream);
|
INT_EXCEL_ID_FONT : ReadFont(AStream);
|
||||||
INT_EXCEL_ID_FORMAT : ReadFormat(AStream);
|
INT_EXCEL_ID_FORMAT : ReadFormat(AStream);
|
||||||
INT_EXCEL_ID_XF : ReadXF(AStream);
|
|
||||||
INT_EXCEL_ID_DATEMODE : ReadDateMode(AStream);
|
|
||||||
INT_EXCEL_ID_PALETTE : ReadPalette(AStream);
|
INT_EXCEL_ID_PALETTE : ReadPalette(AStream);
|
||||||
|
INT_EXCEL_ID_PASSWORD : ReadPASSWORD(AStream);
|
||||||
|
INT_EXCEL_ID_PROTECT : ReadPROTECT(AStream);
|
||||||
|
INT_EXCEL_ID_SST : ReadSST(AStream);
|
||||||
|
INT_EXCEL_ID_WINDOWPROTECT : ReadWindowProtect(AStream);
|
||||||
|
INT_EXCEL_ID_XF : ReadXF(AStream);
|
||||||
else
|
else
|
||||||
// nothing
|
// nothing
|
||||||
end;
|
end;
|
||||||
@@ -874,6 +880,8 @@ begin
|
|||||||
INT_EXCEL_ID_OBJ : ReadOBJ(AStream);
|
INT_EXCEL_ID_OBJ : ReadOBJ(AStream);
|
||||||
INT_EXCEL_ID_PAGESETUP : ReadPageSetup(AStream);
|
INT_EXCEL_ID_PAGESETUP : ReadPageSetup(AStream);
|
||||||
INT_EXCEL_ID_PANE : ReadPane(AStream);
|
INT_EXCEL_ID_PANE : ReadPane(AStream);
|
||||||
|
INT_EXCEL_ID_PASSWORD : ReadPASSWORD(AStream, FWorksheet);
|
||||||
|
INT_EXCEL_ID_PROTECT : ReadPROTECT(AStream, FWorksheet);
|
||||||
INT_EXCEL_ID_PRINTGRID : ReadPrintGridLines(AStream);
|
INT_EXCEL_ID_PRINTGRID : ReadPrintGridLines(AStream);
|
||||||
INT_EXCEL_ID_PRINTHEADERS : ReadPrintHeaders(AStream);
|
INT_EXCEL_ID_PRINTHEADERS : ReadPrintHeaders(AStream);
|
||||||
INT_EXCEL_ID_RIGHTMARGIN : ReadMargin(AStream, 1);
|
INT_EXCEL_ID_RIGHTMARGIN : ReadMargin(AStream, 1);
|
||||||
@@ -1678,6 +1686,14 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// Protection
|
||||||
|
case WordLEToN(rec.XFType_Prot_ParentXF) and MASK_XF_PROTECTION of
|
||||||
|
0: fmt.Protection := [];
|
||||||
|
1: fmt.Protection := [cpLockCell];
|
||||||
|
2: fmt.Protection := [cpHideFormulas];
|
||||||
|
3: fmt.Protection := [cpLockCell, cpHideFormulas];
|
||||||
|
end;
|
||||||
|
|
||||||
// Add the XF to the internal cell format list
|
// Add the XF to the internal cell format list
|
||||||
FCellFormatList.Add(fmt);
|
FCellFormatList.Add(fmt);
|
||||||
end;
|
end;
|
||||||
|
@@ -17,9 +17,12 @@ uses
|
|||||||
const
|
const
|
||||||
{ RECORD IDs which didn't change across versions 2-8 }
|
{ RECORD IDs which didn't change across versions 2-8 }
|
||||||
INT_EXCEL_ID_EOF = $000A;
|
INT_EXCEL_ID_EOF = $000A;
|
||||||
|
INT_EXCEL_ID_PROTECT = $0012;
|
||||||
|
INT_EXCEL_ID_PASSWORD = $0013;
|
||||||
INT_EXCEL_ID_HEADER = $0014;
|
INT_EXCEL_ID_HEADER = $0014;
|
||||||
INT_EXCEL_ID_FOOTER = $0015;
|
INT_EXCEL_ID_FOOTER = $0015;
|
||||||
INT_EXCEL_ID_EXTERNSHEET = $0017;
|
INT_EXCEL_ID_EXTERNSHEET = $0017;
|
||||||
|
INT_EXCEL_ID_WINDOWPROTECT = $0019;
|
||||||
INT_EXCEL_ID_NOTE = $001C;
|
INT_EXCEL_ID_NOTE = $001C;
|
||||||
INT_EXCEL_ID_SELECTION = $001D;
|
INT_EXCEL_ID_SELECTION = $001D;
|
||||||
INT_EXCEL_ID_DATEMODE = $0022;
|
INT_EXCEL_ID_DATEMODE = $0022;
|
||||||
@@ -451,8 +454,12 @@ type
|
|||||||
procedure ReadPageSetup(AStream: TStream);
|
procedure ReadPageSetup(AStream: TStream);
|
||||||
// Read PANE record
|
// Read PANE record
|
||||||
procedure ReadPane(AStream: TStream);
|
procedure ReadPane(AStream: TStream);
|
||||||
|
// Read PASSWORD record
|
||||||
|
procedure ReadPASSWORD(AStream: TStream; AWorksheet: TsWorksheet = nil);
|
||||||
procedure ReadPrintGridLines(AStream: TStream);
|
procedure ReadPrintGridLines(AStream: TStream);
|
||||||
procedure ReadPrintHeaders(AStream: TStream);
|
procedure ReadPrintHeaders(AStream: TStream);
|
||||||
|
// Reads whether the workbook or worksheet is protected
|
||||||
|
procedure ReadPROTECT(AStream: TStream; AWorksheet: TsWorksheet = nil);
|
||||||
// Read an RK value cell
|
// Read an RK value cell
|
||||||
procedure ReadRKValue(AStream: TStream);
|
procedure ReadRKValue(AStream: TStream);
|
||||||
// Read the row, column, and XF index at the current stream position
|
// Read the row, column, and XF index at the current stream position
|
||||||
@@ -491,6 +498,8 @@ type
|
|||||||
procedure ReadVCENTER(AStream: TStream);
|
procedure ReadVCENTER(AStream: TStream);
|
||||||
// Read WINDOW2 record (gridlines, sheet headers)
|
// Read WINDOW2 record (gridlines, sheet headers)
|
||||||
procedure ReadWindow2(AStream: TStream); virtual;
|
procedure ReadWindow2(AStream: TStream); virtual;
|
||||||
|
// Read WINDOWPROTECT record
|
||||||
|
procedure ReadWindowProtect(AStream: TStream);
|
||||||
procedure ReadWorkbookGlobals(AStream: TStream); virtual;
|
procedure ReadWorkbookGlobals(AStream: TStream); virtual;
|
||||||
procedure ReadWorksheet(AStream: TStream); virtual;
|
procedure ReadWorksheet(AStream: TStream); virtual;
|
||||||
|
|
||||||
@@ -2017,6 +2026,35 @@ begin
|
|||||||
// If BIFF5-BIFF8 there is 1 more byte which is not used here.
|
// If BIFF5-BIFF8 there is 1 more byte which is not used here.
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Reads the PASSWORD record containing the encrypted password
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
procedure TsSpreadBIFFReader.ReadPASSWORD(AStream: TStream;
|
||||||
|
AWorksheet: TsWorksheet = nil);
|
||||||
|
var
|
||||||
|
hash: Word;
|
||||||
|
cinfo: TsCryptoInfo;
|
||||||
|
begin
|
||||||
|
hash := WordLEToN(AStream.ReadWord);
|
||||||
|
if hash = 0 then
|
||||||
|
exit; // no password
|
||||||
|
|
||||||
|
if AWorksheet = nil then begin
|
||||||
|
// Password for workbook protection
|
||||||
|
cinfo := FWorkbook.CryptoInfo;
|
||||||
|
cinfo.PasswordHash := Format('%.4x', [hash]);
|
||||||
|
cinfo.Algorithm := caExcel;
|
||||||
|
FWorkbook.CryptoInfo := cinfo;
|
||||||
|
end else
|
||||||
|
begin
|
||||||
|
// Password for worksheet protection
|
||||||
|
cinfo := AWorksheet.CryptoInfo;
|
||||||
|
cinfo.PasswordHash := Format('%.4x', [hash]);
|
||||||
|
cinfo.Algorithm := caExcel;
|
||||||
|
AWorksheet.CryptoInfo := cinfo;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Reads whether the gridlines are printed or not
|
Reads whether the gridlines are printed or not
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
@@ -2043,6 +2081,28 @@ begin
|
|||||||
Options := Options + [poPrintHeaders];
|
Options := Options + [poPrintHeaders];
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Determines whether the workbook or worksheet is protected
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
procedure TsSpreadBIFFReader.ReadPROTECT(AStream: TStream;
|
||||||
|
AWorksheet: TsWorksheet = nil);
|
||||||
|
var
|
||||||
|
p: Word;
|
||||||
|
begin
|
||||||
|
p := WordLEToN(AStream.ReadWord);
|
||||||
|
if p = 0 then // not protected
|
||||||
|
exit;
|
||||||
|
|
||||||
|
if AWorksheet = nil then
|
||||||
|
// Workbook protection
|
||||||
|
FWorkbook.Protection := FWorkbook.Protection + [bpLockStructure]
|
||||||
|
else begin
|
||||||
|
// Worksheet protection
|
||||||
|
AWorksheet.Protection := FWorksheet.Protection + [spCells];
|
||||||
|
AWorksheet.Protect(true);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Reads the row, column and xf index
|
Reads the row, column and xf index
|
||||||
NOT VALID for BIFF2
|
NOT VALID for BIFF2
|
||||||
@@ -2875,6 +2935,17 @@ begin
|
|||||||
Unused(AStream);
|
Unused(AStream);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TsSpreadBIFFReader.ReadWindowProtect(AStream: TStream);
|
||||||
|
var
|
||||||
|
p: Word;
|
||||||
|
begin
|
||||||
|
p := WordLEToN(AStream.ReadWord);
|
||||||
|
if p = 0 then // Workbook not protected
|
||||||
|
FWorkbook.Protection := FWorkbook.Protection - [bpLockWindows]
|
||||||
|
else // Workbook protection
|
||||||
|
FWorkbook.Protection := FWorkbook.Protection + [bpLockWindows];
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TsSpreadBIFFReader.ReadWorksheet(AStream: TStream);
|
procedure TsSpreadBIFFReader.ReadWorksheet(AStream: TStream);
|
||||||
begin
|
begin
|
||||||
// To be overridden by BIFF5 and BIFF8
|
// To be overridden by BIFF5 and BIFF8
|
||||||
|
Reference in New Issue
Block a user