fpspreadsheet: Complete ods writer for cell/sheet/document protection -- but ods has a so-far unsupported option to hide cell content, not just formulas ("hidden-and-protected")...
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@5797 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
parent
dfc01330c2
commit
d81738d19c
@ -204,6 +204,7 @@ type
|
|||||||
function WriteBackgroundColorStyleXMLAsString(const AFormat: TsCellFormat): String;
|
function WriteBackgroundColorStyleXMLAsString(const AFormat: TsCellFormat): String;
|
||||||
function WriteBiDiModeStyleXMLAsString(const AFormat: TsCellFormat): String;
|
function WriteBiDiModeStyleXMLAsString(const AFormat: TsCellFormat): String;
|
||||||
function WriteBorderStyleXMLAsString(const AFormat: TsCellFormat): String;
|
function WriteBorderStyleXMLAsString(const AFormat: TsCellFormat): String;
|
||||||
|
function WriteCellProtectionStyleXMLAsString(const AFormat: TsCellFormat): String;
|
||||||
function WriteCommentXMLAsString(AComment: String): String;
|
function WriteCommentXMLAsString(AComment: String): String;
|
||||||
function WriteDefaultFontXMLAsString: String;
|
function WriteDefaultFontXMLAsString: String;
|
||||||
function WriteDefaultGraphicStyleXMLAsString: String; overload;
|
function WriteDefaultGraphicStyleXMLAsString: String; overload;
|
||||||
@ -212,8 +213,10 @@ type
|
|||||||
function WriteFontStyleXMLAsString(AFont: TsFont): String; overload;
|
function WriteFontStyleXMLAsString(AFont: TsFont): String; overload;
|
||||||
function WriteHeaderFooterFontXMLAsString(AFont: TsHeaderFooterFont): String;
|
function WriteHeaderFooterFontXMLAsString(AFont: TsHeaderFooterFont): String;
|
||||||
function WriteHorAlignmentStyleXMLAsString(const AFormat: TsCellFormat): String;
|
function WriteHorAlignmentStyleXMLAsString(const AFormat: TsCellFormat): String;
|
||||||
function WritePageLayoutAsXMLString(AStyleName: String; const APageLayout: TsPageLayout): String;
|
function WritePageLayoutXMLAsString(AStyleName: String; const APageLayout: TsPageLayout): String;
|
||||||
function WritePrintRangesAsXMLString(ASheet: TsWorksheet): String;
|
function WritePrintRangesXMLAsString(ASheet: TsWorksheet): String;
|
||||||
|
function WriteSheetProtectionXMLAsString(ASheet: TsWorksheet): String;
|
||||||
|
function WriteSheetProtectionDetailsXMLAsString(ASheet: TsWorksheet): String;
|
||||||
function WriteTextRotationStyleXMLAsString(const AFormat: TsCellFormat): String;
|
function WriteTextRotationStyleXMLAsString(const AFormat: TsCellFormat): String;
|
||||||
function WriteVertAlignmentStyleXMLAsString(const AFormat: TsCellFormat): String;
|
function WriteVertAlignmentStyleXMLAsString(const AFormat: TsCellFormat): String;
|
||||||
function WriteWordwrapStyleXMLAsString(const AFormat: TsCellFormat): String;
|
function WriteWordwrapStyleXMLAsString(const AFormat: TsCellFormat): String;
|
||||||
@ -3934,7 +3937,9 @@ begin
|
|||||||
s := GetAttrValue(childnode, 'loext:select-unprotected-cells');
|
s := GetAttrValue(childnode, 'loext:select-unprotected-cells');
|
||||||
if s='true' then Exclude(sp, spSelectUnlockedCells)
|
if s='true' then Exclude(sp, spSelectUnlockedCells)
|
||||||
else Include(sp, spSelectUnlockedCells);
|
else Include(sp, spSelectUnlockedCells);
|
||||||
if s='false' then Exclude(sp, spSelectLockedCells)
|
|
||||||
|
s := GetAttrValue(childnode, 'loext:select-protected-cells');
|
||||||
|
if s='true' then Exclude(sp, spSelectLockedCells)
|
||||||
else Include(sp, spSelectLockedCells);
|
else Include(sp, spSelectLockedCells);
|
||||||
end;
|
end;
|
||||||
childNode := childNode.NextSibling;
|
childNode := childNode.NextSibling;
|
||||||
@ -4796,7 +4801,7 @@ begin
|
|||||||
for i:=0 to FWorkbook.GetWorksheetCount-1 do begin
|
for i:=0 to FWorkbook.GetWorksheetCount-1 do begin
|
||||||
sheet := FWorkbook.GetWorksheetByIndex(i);
|
sheet := FWorkbook.GetWorksheetByIndex(i);
|
||||||
AppendToStream(AStream,
|
AppendToStream(AStream,
|
||||||
WritePageLayoutAsXMLString('Mpm' + IntToStr(3+i), sheet.PageLayout));
|
WritePageLayoutXMLAsString('Mpm' + IntToStr(3+i), sheet.PageLayout));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
for i:=0 to FHeaderFooterFontList.Count-1 do
|
for i:=0 to FHeaderFooterFontList.Count-1 do
|
||||||
@ -5116,8 +5121,12 @@ begin
|
|||||||
|
|
||||||
// Header
|
// Header
|
||||||
AppendToStream(AStream, Format(
|
AppendToStream(AStream, Format(
|
||||||
'<table:table table:name="%s" table:style-name="ta%d" %s>', [
|
'<table:table table:name="%s" table:style-name="ta%d"%s%s>%s', [
|
||||||
UTF8TextToXMLText(FWorkSheet.Name), ASheetIndex+1, WritePrintRangesAsXMLString(FWorksheet)
|
UTF8TextToXMLText(FWorkSheet.Name),
|
||||||
|
ASheetIndex+1,
|
||||||
|
WriteSheetProtectionXMLAsString(FWorksheet),
|
||||||
|
WritePrintRangesXMLAsString(FWorksheet),
|
||||||
|
WriteSheetProtectionDetailsXMLAsString(FWorksheet)
|
||||||
]));
|
]));
|
||||||
|
|
||||||
// shapes
|
// shapes
|
||||||
@ -5196,7 +5205,8 @@ begin
|
|||||||
WriteBackgroundColorStyleXMLAsString(fmt) +
|
WriteBackgroundColorStyleXMLAsString(fmt) +
|
||||||
WriteWordwrapStyleXMLAsString(fmt) +
|
WriteWordwrapStyleXMLAsString(fmt) +
|
||||||
WriteTextRotationStyleXMLAsString(fmt) +
|
WriteTextRotationStyleXMLAsString(fmt) +
|
||||||
WriteVertAlignmentStyleXMLAsString(fmt);
|
WriteVertAlignmentStyleXMLAsString(fmt) +
|
||||||
|
WriteCellProtectionStyleXMLAsString(fmt);
|
||||||
if s <> '' then
|
if s <> '' then
|
||||||
AppendToStream(AStream,
|
AppendToStream(AStream,
|
||||||
'<style:table-cell-properties ' + s + '/>');
|
'<style:table-cell-properties ' + s + '/>');
|
||||||
@ -5336,6 +5346,21 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TsSpreadOpenDocWriter.WriteCellProtectionStyleXMLAsString(
|
||||||
|
const AFormat: TsCellFormat): String;
|
||||||
|
// style:cell-protect="protected formula-hidden"
|
||||||
|
begin
|
||||||
|
if AFormat.Protection * [cpLockCell, cpHideFormulas] = [] then
|
||||||
|
Result := 'none'
|
||||||
|
else if (AFormat.Protection * [cpLockCell, cpHideFormulas] = [cpLockCell]) then
|
||||||
|
Result := 'protected'
|
||||||
|
else if (AFormat.Protection *[cpLockCell, cpHideFormulas] = [cpHideFormulas]) then
|
||||||
|
Result := 'formula-hidden'
|
||||||
|
else
|
||||||
|
Result := 'hidden-and-protected'; // or: 'protected formula-hidden'
|
||||||
|
Result := ' style:cell-protect="' + Result + '"';
|
||||||
|
end;
|
||||||
|
|
||||||
function TsSpreadOpenDocWriter.WriteCommentXMLAsString(AComment: String): String;
|
function TsSpreadOpenDocWriter.WriteCommentXMLAsString(AComment: String): String;
|
||||||
var
|
var
|
||||||
L: TStringList;
|
L: TStringList;
|
||||||
@ -6340,7 +6365,7 @@ begin
|
|||||||
spannedStr := '';
|
spannedStr := '';
|
||||||
|
|
||||||
fmt := FWorkbook.GetCellFormat(ACell^.FormatIndex);
|
fmt := FWorkbook.GetCellFormat(ACell^.FormatIndex);
|
||||||
if fmt.UsedFormattingFields <> [] then
|
if (fmt.UsedFormattingFields <> []) or (fmt.Protection <> [cpLockCell]) then
|
||||||
AppendToStream(AStream, Format(
|
AppendToStream(AStream, Format(
|
||||||
'<table:table-cell table:style-name="ce%d"%s>', [ACell^.FormatIndex, spannedStr]),
|
'<table:table-cell table:style-name="ce%d"%s>', [ACell^.FormatIndex, spannedStr]),
|
||||||
comment,
|
comment,
|
||||||
@ -6373,7 +6398,7 @@ begin
|
|||||||
valType := 'boolean';
|
valType := 'boolean';
|
||||||
|
|
||||||
fmt := FWorkbook.GetCellFormat(ACell^.FormatIndex);
|
fmt := FWorkbook.GetCellFormat(ACell^.FormatIndex);
|
||||||
if fmt.UsedFormattingFields <> [] then
|
if (fmt.UsedFormattingFields <> []) or (fmt.Protection <> [cpLockCell]) then
|
||||||
lStyle := ' table:style-name="ce' + IntToStr(ACell^.FormatIndex) + '" '
|
lStyle := ' table:style-name="ce' + IntToStr(ACell^.FormatIndex) + '" '
|
||||||
else
|
else
|
||||||
lStyle := '';
|
lStyle := '';
|
||||||
@ -6598,7 +6623,6 @@ var
|
|||||||
begin
|
begin
|
||||||
if bpLockStructure in Workbook.Protection then
|
if bpLockStructure in Workbook.Protection then
|
||||||
begin
|
begin
|
||||||
Result := ' table:structure-protected="true"';
|
|
||||||
cinfo := Workbook.CryptoInfo;
|
cinfo := Workbook.CryptoInfo;
|
||||||
if cinfo.PasswordHash <> '' then
|
if cinfo.PasswordHash <> '' then
|
||||||
pwd := Format(' table:protection-key="%s"', [cinfo.PasswordHash])
|
pwd := Format(' table:protection-key="%s"', [cinfo.PasswordHash])
|
||||||
@ -6609,11 +6633,12 @@ begin
|
|||||||
[AlgorithmToStr(cinfo.Algorithm, auOpenDocument)])
|
[AlgorithmToStr(cinfo.Algorithm, auOpenDocument)])
|
||||||
else
|
else
|
||||||
algo := '';
|
algo := '';
|
||||||
Result := Result + pwd + algo;
|
Result := ' table:structure-protected="true"' + pwd + algo;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
Result := '';
|
Result := '';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadOpenDocWriter.WriteError(AStream: TStream;
|
procedure TsSpreadOpenDocWriter.WriteError(AStream: TStream;
|
||||||
const ARow, ACol: Cardinal; const AValue: TsErrorValue; ACell: PCell);
|
const ARow, ACol: Cardinal; const AValue: TsErrorValue; ACell: PCell);
|
||||||
var
|
var
|
||||||
@ -6628,7 +6653,7 @@ begin
|
|||||||
Unused(ARow, ACol, AValue);
|
Unused(ARow, ACol, AValue);
|
||||||
|
|
||||||
fmt := FWorkbook.GetPointerToCellFormat(ACell^.FormatIndex);
|
fmt := FWorkbook.GetPointerToCellFormat(ACell^.FormatIndex);
|
||||||
if fmt^.UsedFormattingFields <> [] then
|
if (fmt^.UsedFormattingFields <> []) or (fmt^.Protection <> [cpLockCell]) then
|
||||||
lStyle := ' table:style-name="ce' + IntToStr(ACell^.FormatIndex) + '" '
|
lStyle := ' table:style-name="ce' + IntToStr(ACell^.FormatIndex) + '" '
|
||||||
else
|
else
|
||||||
lStyle := '';
|
lStyle := '';
|
||||||
@ -6787,7 +6812,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TsSpreadOpenDocWriter.WritePageLayoutAsXMLString(AStyleName: String;
|
function TsSpreadOpenDocWriter.WritePageLayoutXMLAsString(AStyleName: String;
|
||||||
const APageLayout: TsPageLayout): String;
|
const APageLayout: TsPageLayout): String;
|
||||||
|
|
||||||
function CalcPageLayoutPropStr: String;
|
function CalcPageLayoutPropStr: String;
|
||||||
@ -6902,12 +6927,13 @@ begin
|
|||||||
'</style:page-layout>';
|
'</style:page-layout>';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TsSpreadOpenDocWriter.WritePrintRangesAsXMLString(ASheet: TsWorksheet): String;
|
function TsSpreadOpenDocWriter.WritePrintRangesXMLAsString(ASheet: TsWorksheet): String;
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
rng: TsCellRange;
|
rng: TsCellRange;
|
||||||
sheetName: String;
|
sheetName: String;
|
||||||
begin
|
begin
|
||||||
|
Result := '';
|
||||||
if ASheet.PageLayout.NumPrintRanges > 0 then
|
if ASheet.PageLayout.NumPrintRanges > 0 then
|
||||||
begin
|
begin
|
||||||
for i := 0 to ASheet.PageLayout.NumPrintRanges - 1 do
|
for i := 0 to ASheet.PageLayout.NumPrintRanges - 1 do
|
||||||
@ -6924,10 +6950,44 @@ begin
|
|||||||
if Result <> '' then
|
if Result <> '' then
|
||||||
begin
|
begin
|
||||||
Delete(Result, 1, 1);
|
Delete(Result, 1, 1);
|
||||||
Result := 'table:print-ranges="' + Result + '"';
|
Result := ' table:print-ranges="' + Result + '"';
|
||||||
end;
|
end;
|
||||||
end else
|
end;
|
||||||
Result := '';
|
end;
|
||||||
|
|
||||||
|
function TsSpreadOpenDocWriter.WriteSheetProtectionXMLAsString(
|
||||||
|
ASheet: TsWorksheet): String;
|
||||||
|
{table:protected="true" table:protection-key="h/jtkVcSX/xNqeBqe4ARrYClP+E=" table:protection-key-digest-algorithm="http://www.w3.org/2000/09/xmldsig#sha1"}
|
||||||
|
var
|
||||||
|
pwd: String;
|
||||||
|
algo: String;
|
||||||
|
begin
|
||||||
|
Result := '';
|
||||||
|
if ASheet.IsProtected then
|
||||||
|
begin
|
||||||
|
if ASheet.CryptoInfo.PasswordHash <> '' then
|
||||||
|
pwd := ' table:protection-key="' + ASheet.CryptoInfo.PasswordHash + '"' else
|
||||||
|
pwd := '';
|
||||||
|
algo := AlgorithmToStr(ASheet.CryptoInfo.Algorithm, auOpenDocument);
|
||||||
|
if algo <> '' then
|
||||||
|
algo := ' table:protection-key-digest-algorithm="%s"';
|
||||||
|
Result := ' table:protected="true"' + pwd + algo;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TsSpreadOpenDocWriter.WriteSheetProtectionDetailsXMLAsString(
|
||||||
|
ASheet: TsWorksheet): String;
|
||||||
|
// <loext:table-protection loext:select-unprotected-cells="true" />
|
||||||
|
begin
|
||||||
|
Result := '';
|
||||||
|
if ASheet.IsProtected then
|
||||||
|
begin
|
||||||
|
if not (spSelectUnlockedCells in ASheet.Protection) then
|
||||||
|
Result := Result + ' loext:select-unprotected-cells="true"';
|
||||||
|
if not (spSelectLockedCells in ASheet.Protection) then
|
||||||
|
Result := Result + ' loext:select-protected-cells="true"';
|
||||||
|
Result := '<loext:table-protection' + Result + '/>';
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadOpenDocWriter.WriteShapes(AStream: TStream;
|
procedure TsSpreadOpenDocWriter.WriteShapes(AStream: TStream;
|
||||||
@ -7357,7 +7417,7 @@ begin
|
|||||||
|
|
||||||
// Style
|
// Style
|
||||||
fmt := FWorkbook.GetCellFormat(ACell^.FormatIndex);
|
fmt := FWorkbook.GetCellFormat(ACell^.FormatIndex);
|
||||||
if fmt.UsedFormattingFields <> [] then
|
if (fmt.UsedFormattingFields <> []) or (fmt.Protection <> [cpLockCell]) then
|
||||||
lStyle := ' table:style-name="ce' + IntToStr(ACell^.FormatIndex) + '" '
|
lStyle := ' table:style-name="ce' + IntToStr(ACell^.FormatIndex) + '" '
|
||||||
else
|
else
|
||||||
lStyle := '';
|
lStyle := '';
|
||||||
@ -7527,7 +7587,7 @@ begin
|
|||||||
|
|
||||||
// Style
|
// Style
|
||||||
fmt := FWorkbook.GetCellFormat(ACell^.FormatIndex);
|
fmt := FWorkbook.GetCellFormat(ACell^.FormatIndex);
|
||||||
if fmt.UsedFormattingFields <> [] then
|
if (fmt.UsedFormattingFields <> []) or (fmt.Protection <> [cpLockCell]) then
|
||||||
lStyle := ' table:style-name="ce' + IntToStr(ACell^.FormatIndex) + '"'
|
lStyle := ' table:style-name="ce' + IntToStr(ACell^.FormatIndex) + '"'
|
||||||
else
|
else
|
||||||
lStyle := '';
|
lStyle := '';
|
||||||
@ -7683,7 +7743,7 @@ begin
|
|||||||
|
|
||||||
valType := 'float';
|
valType := 'float';
|
||||||
fmt := FWorkbook.GetCellFormat(ACell^.FormatIndex);
|
fmt := FWorkbook.GetCellFormat(ACell^.FormatIndex);
|
||||||
if fmt.UsedFormattingFields <> [] then
|
if (fmt.UsedFormattingFields <> []) or (fmt.Protection <> [cpLockCell]) then
|
||||||
begin
|
begin
|
||||||
numFmt := FWorkbook.GetNumberFormat(fmt.NumberFormatIndex);
|
numFmt := FWorkbook.GetNumberFormat(fmt.NumberFormatIndex);
|
||||||
if (numFmt <> nil) then begin
|
if (numFmt <> nil) then begin
|
||||||
@ -7778,7 +7838,7 @@ begin
|
|||||||
|
|
||||||
fmt := FWorkbook.GetCellFormat(ACell^.FormatIndex);
|
fmt := FWorkbook.GetCellFormat(ACell^.FormatIndex);
|
||||||
numFmtParams := FWorkbook.GetNumberFormat(fmt.NumberFormatIndex);
|
numFmtParams := FWorkbook.GetNumberFormat(fmt.NumberFormatIndex);
|
||||||
if fmt.UsedFormattingFields <> [] then
|
if (fmt.UsedFormattingFields <> []) or (fmt.Protection <> [cpLockCell]) then
|
||||||
lStyle := Format(' table:style-name="ce%d"', [ACell^.FormatIndex])
|
lStyle := Format(' table:style-name="ce%d"', [ACell^.FormatIndex])
|
||||||
else
|
else
|
||||||
lStyle := '';
|
lStyle := '';
|
||||||
|
@ -97,6 +97,12 @@ type
|
|||||||
//procedure TestWriteRead_ODS_WorkbookProtection_Win;
|
//procedure TestWriteRead_ODS_WorkbookProtection_Win;
|
||||||
//procedure TestWriteRead_ODS_WorkbookProtection_StructWin;
|
//procedure TestWriteRead_ODS_WorkbookProtection_StructWin;
|
||||||
|
|
||||||
|
procedure TestWriteRead_ODS_WorksheetProtection_Default;
|
||||||
|
procedure TestWriteRead_ODS_WorksheetProtection_SelectLockedCells;
|
||||||
|
procedure TestWriteRead_ODS_WorksheetProtection_SelectUnlockedCells;
|
||||||
|
|
||||||
|
procedure TestWriteRead_ODS_CellProtection;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
@ -596,6 +602,25 @@ begin
|
|||||||
TestWriteRead_WorkbookProtection(sfOpenDocument, 3);
|
TestWriteRead_WorkbookProtection(sfOpenDocument, 3);
|
||||||
end;}
|
end;}
|
||||||
|
|
||||||
|
procedure TSpreadWriteReadProtectionTests.TestWriteRead_ODS_WorksheetProtection_Default;
|
||||||
|
begin
|
||||||
|
TestWriteRead_WorksheetProtection(sfOpenDocument, 0);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSpreadWriteReadProtectionTests.TestWriteRead_ODS_WorksheetProtection_SelectLockedCells;
|
||||||
|
begin
|
||||||
|
TestWriteRead_WorksheetProtection(sfOpenDocument, 10);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSpreadWriteReadProtectionTests.TestWriteRead_ODS_WorksheetProtection_SelectUnlockedCells;
|
||||||
|
begin
|
||||||
|
TestWriteRead_WorksheetProtection(sfOpenDocument, 11);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSpreadWriteReadProtectionTests.TestWriteRead_ODS_CellProtection;
|
||||||
|
begin
|
||||||
|
TestWriteRead_CellProtection(sfOpenDocument);
|
||||||
|
end;
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
RegisterTest(TSpreadWriteReadProtectionTests);
|
RegisterTest(TSpreadWriteReadProtectionTests);
|
||||||
|
Loading…
Reference in New Issue
Block a user