From 2daa348262817bbad573c6092c439f1454df8aad Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Tue, 10 Jan 2023 21:54:55 +0000 Subject: [PATCH] fpspreadsheet: Adjust conditional format range when rows/cols are inserted or deleted. See https://forum.lazarus.freepascal.org/index.php/topic,61810.0.html git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@8672 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- .../demo_conditional_formatting.lpi | 5 ++ .../source/common/fpsconditionalformat.pas | 87 +++++++++++++++++++ .../source/common/fpspreadsheet.pas | 6 ++ 3 files changed, 98 insertions(+) diff --git a/components/fpspreadsheet/examples/other/conditional_formatting/demo_conditional_formatting.lpi b/components/fpspreadsheet/examples/other/conditional_formatting/demo_conditional_formatting.lpi index f9f511971..6505820bb 100644 --- a/components/fpspreadsheet/examples/other/conditional_formatting/demo_conditional_formatting.lpi +++ b/components/fpspreadsheet/examples/other/conditional_formatting/demo_conditional_formatting.lpi @@ -47,6 +47,11 @@ + + + + + diff --git a/components/fpspreadsheet/source/common/fpsconditionalformat.pas b/components/fpspreadsheet/source/common/fpsconditionalformat.pas index be747373a..6b13bcc23 100644 --- a/components/fpspreadsheet/source/common/fpsconditionalformat.pas +++ b/components/fpspreadsheet/source/common/fpsconditionalformat.pas @@ -129,6 +129,10 @@ type public constructor Create(AWorksheet: TsBasicWorksheet; ACellRange: TsCellRange); destructor Destroy; override; + procedure DeleteCol(ACol: Cardinal); + procedure DeleteRow(ARow: Cardinal); + procedure InsertCol(ACol: Cardinal); + procedure InsertRow(ARow: Cardinal); property CellRange: TsCellRange read FCellRange; property Rules[AIndex: Integer]: TsCFRule read GetRules; @@ -185,7 +189,9 @@ type AHideValue: Boolean = false; AReverse: Boolean = false): Integer; overload; procedure Delete(AIndex: Integer); + procedure DeleteRowOrCol(ASheet: TsBasicWorksheet; AIndex: Cardinal; IsRow: Boolean); function Find(ASheet: TsBasicWorksheet; ARange: TsCellRange): Integer; + procedure InsertRowOrCol(ASheet: TsBasicWorksheet; AIndex: Cardinal; IsRow: Boolean); end; function GetCFIconCount(AIconSet: TsCFIconSet): Integer; @@ -409,6 +415,22 @@ begin inherited; end; +procedure TsConditionalFormat.DeleteCol(ACol: Cardinal); +begin + if (ACol <= FCellRange.Col1) and (FCellRange.Col1 > 0) then + dec(FCellRange.Col1); + if (ACol <= FCellRange.Col2) and (FCellRange.Col2 > 0) then + dec(FCellRange.Col2); +end; + +procedure TsConditionalFormat.DeleteRow(ARow: Cardinal); +begin + if (ARow <= FCellRange.Row1) and (FCellRange.Row1 > 0) then + dec(FCellRange.Row1); + if (ARow <= FCellRange.Row2) and (FCellRange.Row2 > 0) then + dec(FCellRange.Row2); +end; + function TsConditionalFormat.GetRules(AIndex: Integer): TsCFRule; begin Result := FRules[AIndex]; @@ -419,6 +441,22 @@ begin Result := FRules.Count; end; +procedure TsConditionalFormat.InsertCol(ACol: Cardinal); +begin + if (ACol <= FCellRange.Col1) then + inc(FCellRange.Col1); + if (ACol <= FCellRange.Col2) then + inc(FCellRange.Col2); +end; + +procedure TsConditionalFormat.InsertRow(ARow: Cardinal); +begin + if (ARow <= FCellRange.Row1) then + inc(FCellRange.Row1); + if (ARow <= FCellRange.Row2) then + inc(FCellRange.Row2); +end; + { TsConditionalFormatList } @@ -708,6 +746,30 @@ begin end; +{@@ ---------------------------------------------------------------------------- + A row or column is deleted from the specified worksheet. Call this method to + update the range of the conditional formats. +-------------------------------------------------------------------------------} +procedure TsConditionalFormatList.DeleteRowOrCol(ASheet: TsBasicWorksheet; + AIndex: Cardinal; IsRow: Boolean); +var + CF: TsConditionalFormat; + i: Integer; +begin + for i := 0 to Count-1 do + begin + CF := TsConditionalFormat(Items[i]); + if CF.Worksheet = ASheet then + begin + if IsRow then + CF.DeleteRow(AIndex) + else + CF.DeleteCol(AIndex); + end; + end; +end; + + {@@ ---------------------------------------------------------------------------- The conditional format list must be unique regarding cell ranges. This function searches all format item whether a given cell ranges is @@ -737,5 +799,30 @@ begin Result := -1; end; + +{@@ ---------------------------------------------------------------------------- + A row or column is inserted in the specified worksheet. Call this method to + update the range of the conditional formats. +-------------------------------------------------------------------------------} +procedure TsConditionalFormatList.InsertRowOrCol(ASheet: TsBasicWorksheet; + AIndex: Cardinal; IsRow: Boolean); +var + CF: TsConditionalFormat; + i: Integer; +begin + for i := 0 to Count-1 do + begin + CF := TsConditionalFormat(Items[i]); + if CF.Worksheet = ASheet then + begin + if IsRow then + CF.InsertRow(AIndex) + else + CF.InsertCol(AIndex); + end; + end; +end; + + end. diff --git a/components/fpspreadsheet/source/common/fpspreadsheet.pas b/components/fpspreadsheet/source/common/fpspreadsheet.pas index 3a556872c..13836ca5b 100644 --- a/components/fpspreadsheet/source/common/fpspreadsheet.pas +++ b/components/fpspreadsheet/source/common/fpspreadsheet.pas @@ -5571,6 +5571,9 @@ begin // Fix hyperlinks FHyperlinks.DeleteRowOrCol(AIndex, IsRow); + // Fix conditional formats + FWorkbook.FConditionalFormatList.DeleteRowOrCol(Self, AIndex, IsRow); + // Fix formulas: // 1) Fix Row/Col index of in-sheet formulas FFormulas.DeleteRowOrCol(AIndex, IsRow); @@ -5670,6 +5673,9 @@ begin // Update row indexes of cell hyperlinks FHyperlinks.InsertRowOrCol(AIndex, IsRow); + // Update range of conditional formats + FWorkbook.FConditionalFormatList.InsertRowOrCol(Self, AIndex, IsRow); + // Fix formulas: // 1) Update Row/Col index of in-sheet formulas FFormulas.InsertRowOrCol(AIndex, IsRow);