diff --git a/components/fpspreadsheet/source/common/fpsconditionalformat.pas b/components/fpspreadsheet/source/common/fpsconditionalformat.pas index c6e3a6ed8..039b8f865 100644 --- a/components/fpspreadsheet/source/common/fpsconditionalformat.pas +++ b/components/fpspreadsheet/source/common/fpsconditionalformat.pas @@ -84,6 +84,8 @@ type end; TsConditionalFormatList = class(TFPObjectList) + private + FWorksheet: TsBasicWorksheet; protected function AddRule(ARange: TsCellRange; ARule: TsCFRule): Integer; public @@ -95,12 +97,16 @@ type AParam1, AParam2: Variant; ACellFormatIndex: Integer): Integer; overload; procedure AddColorRangeRule(ARange: TsCellRange); procedure AddDataBarRule(ARange: TsCellRange); + procedure Delete(AIndex: Integer); function Find(ARange: TsCellRange): Integer; end; implementation +uses + fpSpreadsheet; + procedure TsCFCellRule.Assign(ASource: TsCFRule); begin if ASource is TsCFCellRule then @@ -265,6 +271,34 @@ begin end; +{@@ ---------------------------------------------------------------------------- + Deletes the conditional format at the given index from the list. + Iterates also through all cell in the range of the CF and removess the + format index from the cell's ConditionalFormatIndex array. +-------------------------------------------------------------------------------} +procedure TsConditionalFormatList.Delete(AIndex: Integer); +var + CF: TsConditionalFormat; + r, c: Cardinal; + i: Integer; + cell: PCell; +begin + CF := TsConditionalFormat(Items[AIndex]); + for r := CF.CellRange.Row1 to CF.CellRange.Row2 do + for c := CF.CellRange.Col1 to CF.CellRange.Col2 do + begin + cell := TsWorksheet(FWorksheet).FindCell(r, c); + if Assigned(cell) and (Length(cell^.ConditionalFormatIndex) > 0) then begin + for i := AIndex+1 to High(cell^.ConditionalFormatIndex) do + cell^.ConditionalFormatIndex[i-1] := cell^.ConditionalFormatIndex[i]; + SetLength(cell^.ConditionalFormatIndex, Length(cell^.ConditionalFormatIndex)-1); + end; + end; + + inherited Delete(AIndex); +end; + + {@@ ---------------------------------------------------------------------------- The conditional format list must be unique regarding cell ranges. This function searches all format item whether a given cell ranges is diff --git a/components/fpspreadsheet/source/common/fpspreadsheet_cf.inc b/components/fpspreadsheet/source/common/fpspreadsheet_cf.inc index 0e94f9bfe..3bf378248 100644 --- a/components/fpspreadsheet/source/common/fpspreadsheet_cf.inc +++ b/components/fpspreadsheet/source/common/fpspreadsheet_cf.inc @@ -15,33 +15,61 @@ begin Result := TsConditionalFormat(FConditionalFormats[AIndex]); end; +procedure StoreCFIndexInCells(AWorksheet: TsWorksheet; AIndex: Integer; + ARange: TsCellRange); +var + r, c: Cardinal; + n: Integer; + cell: PCell; +begin + for r := ARange.Row1 to ARange.Row2 do + for c := ARange.Col1 to ARange.Col2 do + begin + cell := AWorksheet.GetCell(r, c); + n := Length(cell^.ConditionalFormatIndex); + SetLength(cell^.ConditionalFormatIndex, n+1); + cell^.ConditionalFormatIndex[n] := AIndex; + end; +end; + {@@ ---------------------------------------------------------------------------- Creates a conditional format item for the cells given by ARange. - The condition specified must not require parameters, e.g. cfcEmpty + The condition specified here must not require parameters, e.g. cfcEmpty + The format is primarily stored in the worksheet's ConditionalFormats list, + but the format index is also stored in the cell's ConditionalFormatIndex list. + Returns the index of the conditional format in the workbook's CF list. -------------------------------------------------------------------------------} function TsWorksheet.WriteConditionalCellFormat(ARange: TsCellRange; ACondition: TsCFCondition; ACellFormatIndex: Integer): Integer; begin Result := FConditionalFormats.AddCellRule(ARange, ACondition, ACellFormatIndex); + StoreCFIndexInCells(self, Result, ARange); end; {@@ ---------------------------------------------------------------------------- Creates a conditional format item for the cells given by ARange. The condition specified must require one parameter, e.g. cfcEqual, and the parameter must be specified as AParam. + The format is primarily stored in the worksheet's ConditionalFormats list, + but the format index is also stored in the cell's ConditionalFormatIndex list. + Returns the index of the conditional format in the workbook's CF list. -------------------------------------------------------------------------------} function TsWorksheet.WriteConditionalCellFormat(ARange: TsCellRange; ACondition: TsCFCondition; AParam: Variant; ACellFormatIndex: Integer): Integer; begin Result := FConditionalFormats.AddCellRule(ARange, ACondition, AParam, ACellFormatIndex); + StoreCFIndexInCells(self, Result, ARange); end; {@@ ---------------------------------------------------------------------------- Creates a conditional format item for the cells given by ARange. The condition specified must requored two parameters, e.g. cfcBetween, and the parameters must be specified as AParam1 and AParam2. + The format is primarily stored in the worksheet's ConditionalFormats list, + but the format index is also stored in the cell's ConditionalFormatIndex list. + Returns the index of the conditional format in the workbook's CF list. -------------------------------------------------------------------------------} function TsWorksheet.WriteConditionalCellFormat(ARange: TsCellRange; ACondition: TsCFCondition; AParam1, AParam2: Variant; @@ -49,5 +77,6 @@ function TsWorksheet.WriteConditionalCellFormat(ARange: TsCellRange; begin Result := FConditionalFormats.AddCellRule(ARange, ACondition, AParam1, AParam2, ACellFormatIndex); + StoreCFIndexInCells(self, Result, ARange); end; diff --git a/components/fpspreadsheet/source/common/fpstypes.pas b/components/fpspreadsheet/source/common/fpstypes.pas index d8f00cfc1..3a83a6a1d 100644 --- a/components/fpspreadsheet/source/common/fpstypes.pas +++ b/components/fpspreadsheet/source/common/fpstypes.pas @@ -750,6 +750,8 @@ type Flags: TsCellFlags; { Index of format record in the workbook's CellFormatList } FormatIndex: Integer; + { Indexes to worksheet's ConditionalFormats list needed for conditional formatting } + ConditionalFormatIndex: array of Integer; { Cell content } UTF8StringValue: String; // Strings cannot be part of a variant record RichTextParams: TsRichTextParams; // Formatting of individual text ranges