diff --git a/components/fpspreadsheet/laz_fpspreadsheet.lpk b/components/fpspreadsheet/laz_fpspreadsheet.lpk index 92ca967ba..fd90c6773 100644 --- a/components/fpspreadsheet/laz_fpspreadsheet.lpk +++ b/components/fpspreadsheet/laz_fpspreadsheet.lpk @@ -34,252 +34,256 @@ This package is all you need if you don't want graphical components (like grids and charts)."/> - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + + + + + - - + + - - + + - + diff --git a/components/fpspreadsheet/source/common/fpspreadsheet.pas b/components/fpspreadsheet/source/common/fpspreadsheet.pas index d3c4f0276..267d61a1a 100644 --- a/components/fpspreadsheet/source/common/fpspreadsheet.pas +++ b/components/fpspreadsheet/source/common/fpspreadsheet.pas @@ -6189,1092 +6189,6 @@ begin ChangedCell(ACell^.Row, ACell^.Col); end; -{@@ ---------------------------------------------------------------------------- - Adds font specification to the formatting of a cell. Looks in the workbook's - FontList and creates an new entry if the font is not used so far. Returns the - index of the font in the font list. - - @param ARow The row of the cell - @param ACol The column of the cell - @param AFontName Name of the font - @param AFontSize Size of the font, in points - @param AFontStyle Set with font style attributes - (don't use those of unit "graphics" !) - @param AFontColor RGB value of the font's color - @param APosition Specifies sub- or superscript text - @return Index of the font in the workbook's font list. --------------------------------------------------------------------------------} -function TsWorksheet.WriteFont(ARow, ACol: Cardinal; const AFontName: String; - AFontSize: Single; AFontStyle: TsFontStyles; AFontColor: TsColor; - APosition: TsFontPosition = fpNormal): Integer; -begin - Result := WriteFont(GetCell(ARow, ACol), AFontName, AFontSize, AFontStyle, - AFontColor, APosition); -end; - -{@@ ---------------------------------------------------------------------------- - Adds font specification to the formatting of a cell. Looks in the workbook's - FontList and creates an new entry if the font is not used so far. Returns the - index of the font in the font list. - - @param ACell Pointer to the cell considered - @param AFontName Name of the font - @param AFontSize Size of the font, in points - @param AFontStyle Set with font style attributes - (don't use those of unit "graphics" !) - @param AFontColor RGB value of the font's color - @param APosition Specified subscript or superscript text. - @return Index of the font in the workbook's font list. --------------------------------------------------------------------------------} -function TsWorksheet.WriteFont(ACell: PCell; const AFontName: String; - AFontSize: Single; AFontStyle: TsFontStyles; AFontColor: TsColor; - APosition: TsFontPosition = fpNormal): Integer; -var - fmt: TsCellFormat; -begin - if ACell = nil then - begin - Result := -1; - Exit; - end; - - Result := FWorkbook.FindFont(AFontName, AFontSize, AFontStyle, AFontColor, APosition); - if Result = -1 then - result := FWorkbook.AddFont(AFontName, AFontSize, AFontStyle, AFontColor, APosition); - - fmt := Workbook.GetCellFormat(ACell^.FormatIndex); - Include(fmt.UsedFormattingFields, uffFont); - fmt.FontIndex := Result; - ACell^.FormatIndex := Workbook.AddCellFormat(fmt); - - ChangedFont(ACell^.Row, ACell^.Col); -end; - -{@@ ---------------------------------------------------------------------------- - Applies a font to the formatting of a cell. The font is determined by its - index in the workbook's font list: - - @param ARow The row of the cell - @param ACol The column of the cell - @param AFontIndex Index of the font in the workbook's font list - @return Pointer to the cell --------------------------------------------------------------------------------} -function TsWorksheet.WriteFont(ARow, ACol: Cardinal; AFontIndex: Integer): PCell; -begin - Result := GetCell(ARow, ACol); - WriteFont(Result, AFontIndex); -end; - -{@@ ---------------------------------------------------------------------------- - Applies a font to the formatting of a cell. The font is determined by its - index in the workbook's font list: - - @param ACell Pointer to the cell considered - @param AFontIndex Index of the font in the workbook's font list --------------------------------------------------------------------------------} -procedure TsWorksheet.WriteFont(ACell: PCell; AFontIndex: Integer); -var - fmt: TsCellFormat; -begin - if ACell = nil then - exit; - - if (AFontIndex < 0) or (AFontIndex >= Workbook.GetFontCount) then - raise EFPSpreadsheet.Create(rsInvalidFontIndex); - - fmt := Workbook.GetCellFormat(ACell^.FormatIndex); - Include(fmt.UsedFormattingFields, uffFont); - fmt.FontIndex := AFontIndex; - ACell^.FormatIndex := Workbook.AddCellFormat(fmt); - - ChangedFont(ACell^.Row, ACell^.Col); -end; - -{@@ ---------------------------------------------------------------------------- - Replaces the text color used in formatting of a cell. Looks in the workbook's - font list if this modified font has already been used. If not a new font entry - is created. Returns the index of this font in the font list. - - @param ARow The row of the cell - @param ACol The column of the cell - @param AFontColor RGB value of the new text color - @return Index of the font in the workbook's font list. --------------------------------------------------------------------------------} -function TsWorksheet.WriteFontColor(ARow, ACol: Cardinal; AFontColor: TsColor): Integer; -begin - Result := WriteFontColor(GetCell(ARow, ACol), AFontColor); -end; - -{@@ ---------------------------------------------------------------------------- - Replaces the text color used in formatting of a cell. Looks in the workbook's - font list if this modified font has already been used. If not a new font entry - is created. Returns the index of this font in the font list. - - @param ACell Pointer to the cell - @param AFontColor RGB value of the new text color - @return Index of the font in the workbook's font list. --------------------------------------------------------------------------------} -function TsWorksheet.WriteFontColor(ACell: PCell; AFontColor: TsColor): Integer; -var - fnt: TsFont; -begin - if ACell = nil then begin - Result := 0; - exit; - end; - fnt := ReadCellFont(ACell); - Result := WriteFont(ACell, fnt.FontName, fnt.Size, fnt.Style, AFontColor); -end; - -{@@ ---------------------------------------------------------------------------- - Replaces the font used in formatting of a cell considering only the font face - and leaving font size, style and color unchanged. Looks in the workbook's - font list if this modified font has already been used. If not a new font entry - is created. Returns the index of this font in the font list. - - @param ARow The row of the cell - @param ACol The column of the cell - @param AFontName Name of the new font to be used - @return Index of the font in the workbook's font list. --------------------------------------------------------------------------------} -function TsWorksheet.WriteFontName(ARow, ACol: Cardinal; AFontName: String): Integer; -begin - result := WriteFontName(GetCell(ARow, ACol), AFontName); -end; - -{@@ ---------------------------------------------------------------------------- - Replaces the font used in formatting of a cell considering only the font face - and leaving font size, style and color unchanged. Looks in the workbook's - font list if this modified font has already been used. If not a new font entry - is created. Returns the index of this font in the font list. - - @param ACell Pointer to the cell - @param AFontName Name of the new font to be used - @return Index of the font in the workbook's font list. --------------------------------------------------------------------------------} -function TsWorksheet.WriteFontName(ACell: PCell; AFontName: String): Integer; -var - fnt: TsFont; -begin - if ACell = nil then begin - Result := 0; - exit; - end; - fnt := ReadCellFont(ACell); - result := WriteFont(ACell, AFontName, fnt.Size, fnt.Style, fnt.Color); -end; - -{@@ ---------------------------------------------------------------------------- - Replaces the font size in formatting of a cell. Looks in the workbook's - font list if this modified font has already been used. If not a new font entry - is created. Returns the index of this font in the font list. - - @param ARow The row of the cell - @param ACol The column of the cell - @param ASize Size of the font to be used (in points). - @return Index of the font in the workbook's font list. --------------------------------------------------------------------------------} -function TsWorksheet.WriteFontSize(ARow, ACol: Cardinal; ASize: Single): Integer; -begin - Result := WriteFontSize(GetCell(ARow, ACol), ASize); -end; - -{@@ ---------------------------------------------------------------------------- - Replaces the font size in formatting of a cell. Looks in the workbook's - font list if this modified font has already been used. If not a new font entry - is created. Returns the index of this font in the font list. - - @param ACell Pointer to the cell - @param ASize Size of the font to be used (in points). - @return Index of the font in the workbook's font list. --------------------------------------------------------------------------------} -function TsWorksheet.WriteFontSize(ACell: PCell; ASize: Single): Integer; -var - fnt: TsFont; -begin - if ACell = nil then begin - Result := 0; - exit; - end; - fnt := ReadCellFont(ACell); - Result := WriteFont(ACell, fnt.FontName, ASize, fnt.Style, fnt.Color); -end; - -{@@ ---------------------------------------------------------------------------- - Replaces the font style (bold, italic, etc) in formatting of a cell. - Looks in the workbook's font list if this modified font has already been used. - If not a new font entry is created. - Returns the index of this font in the font list. - - @param ARow The row of the cell - @param ACol The column of the cell - @param AStyle New font style to be used - @return Index of the font in the workbook's font list. - - @see TsFontStyle --------------------------------------------------------------------------------} -function TsWorksheet.WriteFontStyle(ARow, ACol: Cardinal; - AStyle: TsFontStyles): Integer; -begin - Result := WriteFontStyle(GetCell(ARow, ACol), AStyle); -end; - -{@@ ---------------------------------------------------------------------------- - Replaces the font style (bold, italic, etc) in formatting of a cell. - Looks in the workbook's font list if this modified font has already been used. - If not a new font entry is created. - Returns the index of this font in the font list. - - @param ACell Pointer to the cell considered - @param AStyle New font style to be used - @return Index of the font in the workbook's font list. - - @see TsFontStyle --------------------------------------------------------------------------------} -function TsWorksheet.WriteFontStyle(ACell: PCell; AStyle: TsFontStyles): Integer; -var - fnt: TsFont; -begin - if ACell = nil then begin - Result := -1; - exit; - end; - fnt := ReadCellFont(ACell); - Result := WriteFont(ACell, fnt.FontName, fnt.Size, AStyle, fnt.Color); -end; - -{@@ ---------------------------------------------------------------------------- - Adds text rotation to the formatting of a cell - - @param ARow The row of the cell - @param ACol The column of the cell - @param ARotation How to rotate the text - @return Pointer to cell - - @see TsTextRotation --------------------------------------------------------------------------------} -function TsWorksheet.WriteTextRotation(ARow, ACol: Cardinal; - ARotation: TsTextRotation): PCell; -begin - Result := GetCell(ARow, ACol); - WriteTextRotation(Result, ARotation); -end; - -{@@ ---------------------------------------------------------------------------- - Adds text rotation to the formatting of a cell - - @param ACell Pointer to the cell - @param ARotation How to rotate the text - - @see TsTextRotation --------------------------------------------------------------------------------} -procedure TsWorksheet.WriteTextRotation(ACell: PCell; ARotation: TsTextRotation); -var - fmt: TsCellFormat; -begin - if ACell = nil then - exit; - - fmt := Workbook.GetCellFormat(ACell^.FormatIndex); - Include(fmt.UsedFormattingFields, uffTextRotation); - fmt.TextRotation := ARotation; - ACell^.FormatIndex := Workbook.AddCellFormat(fmt); - - ChangedFont(ACell^.Row, ACell^.Col); -end; - -{@@ ---------------------------------------------------------------------------- - Directly modifies the used formatting fields of a cell. - Only formatting corresponding to items included in this set is executed. - - @param ARow The row of the cell - @param ACol The column of the cell - @param AUsedFormatting set of the used formatting fields - @return Pointer to the (existing or created) cell - - @see TsUsedFormattingFields - @see TCell --------------------------------------------------------------------------------} -function TsWorksheet.WriteUsedFormatting(ARow, ACol: Cardinal; - AUsedFormatting: TsUsedFormattingFields): PCell; -begin - Result := GetCell(ARow, ACol); - WriteUsedFormatting(Result, AUsedFormatting); -end; - -{@@ ---------------------------------------------------------------------------- - Directly modifies the used formatting fields of an existing cell. - Only formatting corresponding to items included in this set is executed. - - @param ACell Pointer to the cell to be modified - @param AUsedFormatting set of the used formatting fields - - @see TsUsedFormattingFields - @see TCell --------------------------------------------------------------------------------} -procedure TsWorksheet.WriteUsedFormatting(ACell: PCell; - AUsedFormatting: TsUsedFormattingFields); -var - fmt: TsCellFormat; -begin - if ACell = nil then - exit; - fmt := FWorkbook.GetCellFormat(ACell^.FormatIndex); - fmt.UsedFormattingFields := AUsedFormatting; - ACell^.FormatIndex := Workbook.AddCellFormat(fmt); - ChangedCell(ACell^.Row, ACell^.Col); -end; - -{@@ ---------------------------------------------------------------------------- - Modifies the background parameters of the format record stored at the - specified index. - - @param AFormatIndex Index of the format record to be changed - @param AStyle Fill style ("pattern") to be used - see TsFillStyle - @param APatternColor RGB value of the pattern color - @param ABackgroundColor RGB value of the background color - - @return Index of the new format record. - - @NOTE When AStyle is fsSolidFill the color is defined by APatternColor, - ABackgroundColor is ignored unless the APatternColor is not - used (scTransparent). --------------------------------------------------------------------------------} -function TsWorksheet.ChangeBackground(AFormatIndex: Integer; AStyle: TsFillStyle; - APatternColor: TsColor = scTransparent; - ABackgroundColor: TsColor = scTransparent): Integer; -var - fmt: TsCellFormat; -begin - fmt := Workbook.GetCellFormat(AFormatIndex); - if (AStyle = fsNoFill) or - ((APatternColor = scTransparent) and (ABackgroundColor = scTransparent)) - then - Exclude(fmt.UsedFormattingFields, uffBackground) - else - begin - Include(fmt.UsedFormattingFields, uffBackground); - fmt.Background.Style := AStyle; - fmt.Background.FgColor := APatternColor; - if (AStyle = fsSolidFill) and (APatternColor = scTransparent) then - fmt.Background.FgColor := ABackgroundColor - else - fmt.Background.BgColor := ABackgroundColor; - { - if (AStyle = fsSolidFill) and (ABackgroundColor = scTransparent) then - fmt.Background.BgColor := APatternColor - else - fmt.Background.BgColor := ABackgroundColor; - } - end; - Result := Workbook.AddCellFormat(fmt); -end; - -{@@ ---------------------------------------------------------------------------- - Defines a background pattern for a cell - - @param ARow Row index of the cell - @param ACol Column index of the cell - @param AFillStyle Fill style to be used - see TsFillStyle - @param APatternColor RGB value of the pattern color - @param ABackgroundColor RGB value of the background color - @return Pointer to cell - - @NOTE When AStyle is fsSolidFill the color is defined by APatternColor, - ABackgroundColor is ignored unless the APatternColor is not - used (scTransparent). - - @NOTE Is replaced by uniform fill if WriteBackgroundColor is called later. --------------------------------------------------------------------------------} -function TsWorksheet.WriteBackground(ARow, ACol: Cardinal; AStyle: TsFillStyle; - APatternColor, ABackgroundColor: TsColor): PCell; -begin - Result := GetCell(ARow, ACol); - WriteBackground(Result, AStyle, APatternColor, ABackgroundColor); -end; - -{@@ ---------------------------------------------------------------------------- - Defines a background pattern for a cell - - @param ACell Pointer to the cell - @param AStyle Fill style ("pattern") to be used - see TsFillStyle - @param APatternColor RGB value of the pattern color - @param ABackgroundColor RGB value of the background color - - @NOTE When AStyle is fsSolidFill the color is defined by APatternColor, - ABackgroundColor is ignored unless the APatternColor is not - used (scTransparent). - - @NOTE Is replaced by uniform fill if WriteBackgroundColor is called later. --------------------------------------------------------------------------------} -procedure TsWorksheet.WriteBackground(ACell: PCell; AStyle: TsFillStyle; - APatternColor: TsColor = scTransparent; ABackgroundColor: TsColor = scTransparent); -var - idx: Integer; -begin - if ACell <> nil then begin - idx := ACell^.FormatIndex; - ACell^.FormatIndex := ChangeBackground(idx, AStyle, APatternColor, ABackgroundColor); - ChangedCell(ACell^.Row, ACell^.Col); - end; -end; - -{@@ ---------------------------------------------------------------------------- - Sets a uniform background color of a cell. - - @param ARow Row index of the cell - @param ACol Column index of the cell - @param AColor RGB value of the new background color. - Use the value "scTransparent" to clear an existing - background color. - @return Pointer to cell --------------------------------------------------------------------------------} -function TsWorksheet.WriteBackgroundColor(ARow, ACol: Cardinal; - AColor: TsColor): PCell; -begin - Result := GetCell(ARow, ACol); - WriteBackgroundColor(Result, AColor); -end; - -{@@ ---------------------------------------------------------------------------- - Sets a uniform background color of a cell. - - @param ACell Pointer to cell - @param AColor RGB value of the new background color. - Use the value "scTransparent" to clear an existing - background color. --------------------------------------------------------------------------------} -procedure TsWorksheet.WriteBackgroundColor(ACell: PCell; AColor: TsColor); -begin - if ACell <> nil then begin - if AColor = scTransparent then - WriteBackground(ACell, fsNoFill) - else - WriteBackground(ACell, fsSolidFill, AColor, AColor); - end; -end; - -{@@ ---------------------------------------------------------------------------- - Sets the color of a cell border line. - Note: the border must be included in Borders set in order to be shown! - - @param ARow Row index of the cell - @param ACol Column index of the cell - @param ABorder Indicates to which border (left/top etc) this color is - to be applied - @param AColor RGB value of the new border color - @return Pointer to cell --------------------------------------------------------------------------------} -function TsWorksheet.WriteBorderColor(ARow, ACol: Cardinal; - ABorder: TsCellBorder; AColor: TsColor): PCell; -begin - Result := GetCell(ARow, ACol); - WriteBorderColor(Result, ABorder, AColor); -end; - -{@@ ---------------------------------------------------------------------------- - Sets the color of a cell border line. - Note: the border must be included in Borders set in order to be shown! - - @param ACell Pointer to cell - @param ABorder Indicates to which border (left/top etc) this color is - to be applied - @param AColor RGB value of the new border color --------------------------------------------------------------------------------} -procedure TsWorksheet.WriteBorderColor(ACell: PCell; ABorder: TsCellBorder; - AColor: TsColor); -var - fmt: TsCellFormat; -begin - if ACell <> nil then begin - fmt := Workbook.GetCellFormat(ACell^.FormatIndex); - fmt.BorderStyles[ABorder].Color := AColor; - ACell^.FormatIndex := Workbook.AddCellFormat(fmt); - ChangedCell(ACell^.Row, ACell^.Col); - end; -end; - -{@@ ---------------------------------------------------------------------------- - Sets the linestyle of a cell border. - Note: the border must be included in the "Borders" set in order to be shown! - - @param ARow Row index of the cell - @param ACol Column index of the cell - @param ABorder Indicates to which border (left/top etc) this color is - to be applied - @param ALineStyle Identifier of the new line style to be applied. - @return Pointer to cell - - @see TsLineStyle --------------------------------------------------------------------------------} -function TsWorksheet.WriteBorderLineStyle(ARow, ACol: Cardinal; - ABorder: TsCellBorder; ALineStyle: TsLineStyle): PCell; -begin - Result := GetCell(ARow, ACol); - WriteBorderLineStyle(Result, ABorder, ALineStyle); -end; - -{@@ ---------------------------------------------------------------------------- - Sets the linestyle of a cell border. - Note: the border must be included in the "Borders" set in order to be shown! - - @param ACell Pointer to cell - @param ABorder Indicates to which border (left/top etc) this color is - to be applied - @param ALineStyle Identifier of the new line style to be applied. - - @see TsLineStyle --------------------------------------------------------------------------------} -procedure TsWorksheet.WriteBorderLineStyle(ACell: PCell; - ABorder: TsCellBorder; ALineStyle: TsLineStyle); -var - fmt: TsCellFormat; -begin - if ACell <> nil then begin - fmt := Workbook.GetCellFormat(ACell^.FormatIndex); - fmt.BorderStyles[ABorder].LineStyle := ALineStyle; - ACell^.FormatIndex := Workbook.AddCellFormat(fmt); - ChangedCell(ACell^.Row, ACell^.Col); - end; -end; - -{@@ ---------------------------------------------------------------------------- - Shows the cell borders included in the set ABorders. No border lines are drawn - for those not included. - - The borders are drawn using the "BorderStyles" assigned to the cell. - - @param ARow Row index of the cell - @param ACol Column index of the cell - @param ABorders Set with elements to identify the border(s) to will be shown - @return Pointer to cell - @see TsCellBorder --------------------------------------------------------------------------------} -function TsWorksheet.WriteBorders(ARow, ACol: Cardinal; ABorders: TsCellBorders): PCell; -begin - Result := GetCell(ARow, ACol); - WriteBorders(Result, ABorders); -end; - -{@@ ---------------------------------------------------------------------------- - Shows the cell borders included in the set ABorders. No border lines are drawn - for those not included. - - The borders are drawn using the "BorderStyles" assigned to the cell. - - @param ACell Pointer to cell - @param ABorders Set with elements to identify the border(s) to will be shown - @see TsCellBorder --------------------------------------------------------------------------------} -procedure TsWorksheet.WriteBorders(ACell: PCell; ABorders: TsCellBorders); -var - fmt: TsCellFormat; -begin - if ACell <> nil then begin - fmt := Workbook.GetCellFormat(ACell^.FormatIndex); - if ABorders = [] then - Exclude(fmt.UsedFormattingFields, uffBorder) - else - Include(fmt.UsedFormattingFields, uffBorder); - fmt.Border := ABorders; - ACell^.FormatIndex := Workbook.AddCellFormat(fmt); - ChangedCell(ACell^.Row, ACell^.Col); - end; -end; - { -procedure TsWorksheet.WriteBorders(ALeft, ATop, ARight, ABottom: Integer; - ABorders: TsCellBorders; ALeftStyle, ATopStyle, ARightStyle, ABottomStyle, - AInnerHorStyle, AInnerVertStyle: TsCellBorderStyle); - - function BorderVisible(const AStyle: TsCellBorderStyle): Boolean; - begin - Result := (AStyle.Color <> scNotDefined) and (AStyle.Color <> scTransparent); - end; - - procedure SetNeighborBorder(NewRow, NewCol: Cardinal; - ANewBorder: TsCellBorder; const ANewBorderStyle: TsCellBorderStyle; - AInclude: Boolean); - var - neighbor: PCell; - border: TsCellBorders; - begin - neighbor := FindCell(NewRow, NewCol); - if neighbor <> nil then - begin - border := ReadCelLBorders(neighbor); - if AInclude then - begin - Include(border, ANewBorder); - WriteBorderStyle(NewRow, NewCol, ANewBorder, ANewBorderStyle); - end else - Exclude(border, ANewBorder); - WriteBorders(NewRow, NewCol, border); - end; - end; - - procedure FixNeighborCellBorders(ACell: PCell); - var - fmt: PsCellFormat; - begin - if (ACell = nil) then - exit; - - fmt := GetPointerToEffectiveCellFormat(ACell); - with ACell^ do - begin - if Col > 0 then - SetNeighborBorder(Row, Col-1, cbEast, fmt^.BorderStyles[cbWest], cbWest in fmt^.Border); - SetNeighborBorder(Row, Col+1, cbWest, fmt^.BorderStyles[cbEast], cbEast in fmt^.Border); - if Row > 0 then - SetNeighborBorder(Row-1, Col, cbSouth, fmt^.BorderStyles[cbNorth], cbNorth in fmt^.Border); - SetNeighborBorder(Row+1, Col, cbNorth, fmt^.BorderStyles[cbSouth], cbSouth in fmt^.Border); - end; - end; - - procedure ProcessBorder(ARow, ACol: Cardinal; ABorder: TsCellBorder; - const AStyle: TsCellBorderStyle); - var - cb: TsCellBorders = []; - cell: PCell; - begin - cell := FindCell(ARow, ACol); - if cell <> nil then - cb := ReadCellBorders(cell); - if BorderVisible(AStyle) then - begin - Include(cb, ABorder); - cell := WriteBorders(ARow, ACol, cb); - WriteBorderStyle(cell, ABorder, AStyle); - end else - if cb <> [] then - begin - Exclude(cb, ABorder); - cell := WriteBorders(ARow, ACol, cb); - end; - FixNeighborCellBorders(cell); - end; - - procedure ShowCellBorders(ALeft, ATop, ARight, ABottom: Integer; - ALeftOuterStyle, ATopOuterStyle, ARightOuterStyle, ABottomOuterStyle, - AHorInnerStyle, AVertInnerStyle: TsCellBorderStyle); - var - r, c, r1, c1, r2, c2: Cardinal; - begin - // Preparations - EnsureOrder(ALeft, ARight); - EnsureOrder(ATop, ABottom); - - // Top outer border - for c := ALeft to ARight do - ProcessBorder(r1, c, cbNorth, ATopOuterStyle); - // Bottom outer border - for c := ALeft to ARight do - ProcessBorder(r2, c, cbSouth, ABottomOuterStyle); - // Left outer border - for r := ATop to ABottom do - ProcessBorder(r, c1, cbWest, ALeftOuterStyle); - // Right outer border - for r := ATop to ABottom do - ProcessBorder(r, c2, cbEast, ARightOuterStyle); - // Horizontal inner border - if ATop <> ABottom then - for r := ATop to ABottom-1 do - for c := ALeft to ARight do - ProcessBorder(r, c, cbSouth, AHorInnerStyle); - // Vertical inner border - if ALeft <> ARight then - for r := ATop to ABottom do - for c := ALeft to ARight-1 do - ProcessBorder(r, c, cbEast, AVertInnerStyle); - end; - - procedure SetCellBorders(ACol, ARow: Integer); - var - cell: PCell; - r1, c1, r2, c2: Cardinal; - styles, saved_styles: TsCellBorderStyles; - begin - cell := GetCell(ARow, ACol); - - if IsMergeBase(cell) then - begin - styles := ReadCellBorderStyles(cell); - saved_styles := styles; - if not (cbEast in ABorders) then styles[cbEast] := NO_CELL_BORDER; - if not (cbWest in ABorders) then styles[cbWest] := NO_CELL_BORDER; - if not (cbNorth in ABorders) then styles[cbNorth] := NO_CELL_BORDER; - if not (cbSouth in ABorders) then styles[cbSouth] := NO_CELL_BORDER; - FindMergedRange(cell, r1, c1, r2, c2); - // Set border flags and styles for all outer cells of the merged block - // Note: This overwrites the styles of the base ... - ShowCellBorders(r1,c1, r2,c2, styles[cbWest], styles[cbNorth], - styles[cbEast], styles[cbSouth], NO_CELL_BORDER, NO_CELL_BORDER); - // ... Restores base border style overwritten in prev instruction - WriteBorderStyles(cell, saved_styles); - WriteBorders(cell, ABorders); - end else - begin - WriteBorders(cell, ABorders); - FixNeighborCellBorders(cell); - end; - end; - -var - r, c: Cardinal; -begin - EnsureOrder(ALeft, ARight); - EnsureOrder(ATop, ABottom); - Workbook.DisableNotifications; - try - for c := ALeft to ARight do - for r := ATop to ABottom do - SetCellBorders(c, r); - finally - Workbook.EnableNotifications; - ChangedCell(ALeft, ATop); - end; -end; -} - -{@@ ---------------------------------------------------------------------------- - Sets the style of a cell border, i.e. line style and line color. - Note: the border must be included in the "Borders" set in order to be shown! - - @param ARow Row index of the cell considered - @param ACol Column index of the cell considered - @param ABorder Identifies the border to be modified (left/top/right/bottom) - @param AStyle record of parameters controlling how the border line is drawn - (line style, line color) - @result Pointer to cell --------------------------------------------------------------------------------} -function TsWorksheet.WriteBorderStyle(ARow, ACol: Cardinal; - ABorder: TsCellBorder; AStyle: TsCellBorderStyle): PCell; -begin - Result := GetCell(ARow, ACol); - WriteBorderStyle(Result, ABorder, AStyle); -end; - -{@@ ---------------------------------------------------------------------------- - Sets the style of a cell border, i.e. line style and line color. - Note: the border must be included in the "Borders" set in order to be shown! - - @param ACell Pointer to cell - @param ABorder Identifies the border to be modified (left/top/right/bottom) - @param AStyle record of parameters controlling how the border line is drawn - (line style, line color) --------------------------------------------------------------------------------} -procedure TsWorksheet.WriteBorderStyle(ACell: PCell; ABorder: TsCellBorder; - AStyle: TsCellBorderStyle); -var - fmt: TsCellFormat; -begin - if ACell <> nil then begin - fmt := Workbook.GetCellFormat(ACell^.FormatIndex); - fmt.BorderStyles[ABorder] := AStyle; - ACell^.FormatIndex := Workbook.AddCellFormat(fmt); - ChangedCell(ACell^.Row, ACell^.Col); - end; -end; - -{@@ ---------------------------------------------------------------------------- - Sets line style and line color of a cell border. - Note: the border must be included in the "Borders" set in order to be shown! - - @param ARow Row index of the considered cell - @param ACol Column index of the considered cell - @param ABorder Identifier of the border to be modified - @param ALineStyle Identifier for the new line style of the border - @param AColor RGB value of the border line color - @return Pointer to cell - - @see WriteBorderStyles --------------------------------------------------------------------------------} -function TsWorksheet.WriteBorderStyle(ARow, ACol: Cardinal; - ABorder: TsCellBorder; ALineStyle: TsLineStyle; AColor: TsColor): PCell; -begin - Result := GetCell(ARow, ACol); - WriteBorderStyle(Result, ABorder, ALineStyle, AColor); -end; - -{@@ ---------------------------------------------------------------------------- - Sets line style and line color of a cell border. - Note: the border must be included in the "Borders" set in order to be shown! - - @param ACell Pointer to cell - @param ABorder Identifier of the border to be modified - @param ALineStyle Identifier for the new line style of the border - @param AColor RGB value of the color of the border line - - @see WriteBorderStyles --------------------------------------------------------------------------------} -procedure TsWorksheet.WriteBorderStyle(ACell: PCell; ABorder: TsCellBorder; - ALineStyle: TsLineStyle; AColor: TsColor); -var - fmt: TsCellFormat; -begin - if ACell <> nil then begin - fmt := Workbook.GetCellFormat(ACell^.FormatIndex); - fmt.BorderStyles[ABorder].LineStyle := ALineStyle; - fmt.BorderStyles[ABorder].Color := AColor; - ACell^.FormatIndex := Workbook.AddCellFormat(fmt); - ChangedCell(ACell^.Row, ACell^.Col); - end; -end; - -{@@ ---------------------------------------------------------------------------- - Sets the style of all cell border of a cell, i.e. line style and line color. - Note: Only those borders included in the "Borders" set are shown! - - @param ARow Row index of the considered cell - @param ACol Column index of the considered cell - @param AStyles Array of CellBorderStyles for each cell border. - @return Pointer to cell - - @see WriteBorderStyle --------------------------------------------------------------------------------} -function TsWorksheet.WriteBorderStyles(ARow, ACol: Cardinal; - const AStyles: TsCellBorderStyles): PCell; -begin - Result := GetCell(ARow, ACol); - WriteBorderStyles(Result, AStyles); -end; - -{@@ ---------------------------------------------------------------------------- - Sets the style of all cell border of a cell, i.e. line style and line color. - Note: Only those borders included in the "Borders" set are shown! - - @param ACell Pointer to cell - @param ACol Column index of the considered cell - @param AStyles Array of CellBorderStyles for each cell border. - - @see WriteBorderStyle --------------------------------------------------------------------------------} -procedure TsWorksheet.WriteBorderStyles(ACell: PCell; - const AStyles: TsCellBorderStyles); -var - b: TsCellBorder; - fmt: TsCellFormat; -begin - if Assigned(ACell) then begin - fmt := Workbook.GetCellFormat(ACell^.FormatIndex); - for b in TsCellBorder do fmt.BorderStyles[b] := AStyles[b]; - ACell^.FormatIndex := Workbook.AddCellFormat(fmt); - ChangedCell(ACell^.Row, ACell^.Col); - end; -end; - -{@@ ---------------------------------------------------------------------------- - Assigns a complete cell format record to a cell - - @param ACell Pointer to the cell to be modified - @param ACellFormat Cell format record to be used by the cell - - @see TsCellFormat --------------------------------------------------------------------------------} -procedure TsWorksheet.WriteCellFormat(ACell: PCell; - const ACellFormat: TsCellFormat); -var - idx: Integer; -begin - idx := Workbook.AddCellFormat(ACellFormat); - WriteCellFormatIndex(ACell, idx); -end; - -{@@ ---------------------------------------------------------------------------- - Formats a cell to the cell format stored at the specified index in the - workbook's cell format list. - - @param ACell Pointer to the cell to be formatted - @param AIndex Index of the cell format record to be used by the cell - - @see TsCellFormat --------------------------------------------------------------------------------} -procedure TsWorksheet.WriteCellFormatIndex(ACell: PCell; AIndex: Integer); -begin - if AIndex >= Workbook.GetNumCellFormats then - raise EFpSpreadsheet.Create('[Worksheet.WriteCellFormat] Invalid cell format index.'); - - // The default format index is 0, but it could also be refered to by -1 - if AIndex < 0 then AIndex := 0; - if Assigned(ACell) then begin - ACell^.FormatIndex := AIndex; - ChangedCell(ACell^.Row, ACell^.Col); - end; -end; - -{@@ ---------------------------------------------------------------------------- - Defines the horizontal alignment of text in a cell. - - @param ARow Row index of the cell considered - @param ACol Column index of the cell considered - @param AValue Parameter for horizontal text alignment - (haDefault, vaLeft, haCenter, haRight) - By default, texts are left-aligned, numbers and dates are - right-aligned. - @return Pointer to cell --------------------------------------------------------------------------------} -function TsWorksheet.WriteHorAlignment(ARow, ACol: Cardinal; AValue: TsHorAlignment): PCell; -begin - Result := GetCell(ARow, ACol); - WriteHorAlignment(Result, AValue); -end; - -{@@ ---------------------------------------------------------------------------- - Defines the horizontal alignment of text in a cell. - - @param ACell Pointer to the cell considered - @param AValue Parameter for horizontal text alignment - (haDefault, vaLeft, haCenter, haRight) - By default, texts are left-aligned, numbers and dates are - right-aligned. --------------------------------------------------------------------------------} -procedure TsWorksheet.WriteHorAlignment(ACell: PCell; AValue: TsHorAlignment); -var - fmt: TsCellFormat; -begin - if ACell = nil then - exit; - fmt := Workbook.GetCellFormat(ACell^.FormatIndex); - if AValue = haDefault then - Exclude(fmt.UsedFormattingFields, uffHorAlign) - else - Include(fmt.UsedFormattingFields, uffHorAlign); - fmt.HorAlignment := AValue; - ACell^.FormatIndex := Workbook.AddCellFormat(fmt); - ChangedCell(ACell^.Row, ACell^.Col); -end; - -{@@ ---------------------------------------------------------------------------- - Defines the vertical alignment of text in a cell. - - @param ARow Row index of the cell considered - @param ACol Column index of the cell considered - @param AValue Parameter for vertical text alignment - (vaDefault, vaTop, vaCenter, vaBottom) - By default, texts are bottom-aligned. - @return Pointer to cell --------------------------------------------------------------------------------} -function TsWorksheet.WriteVertAlignment(ARow, ACol: Cardinal; - AValue: TsVertAlignment): PCell; -begin - Result := GetCell(ARow, ACol); - WriteVertAlignment(Result, AValue); -end; - -{@@ ---------------------------------------------------------------------------- - Defines the vertical alignment of text in a cell. - - @param ACell Poiner to the cell considered - @param AValue Parameter for vertical text alignment - (vaDefault, vaTop, vaCenter, vaBottom) - By default, texts are bottom-aligned. --------------------------------------------------------------------------------} -procedure TsWorksheet.WriteVertAlignment(ACell: PCell; AValue: TsVertAlignment); -var - fmt: TsCellFormat; -begin - if ACell = nil then - exit; - fmt := Workbook.GetCellFormat(ACell^.FormatIndex); - if AValue = vaDefault then - Exclude(fmt.UsedFormattingFields, uffVertAlign) - else - Include(fmt.UsedFormattingFields, uffVertAlign); - fmt.VertAlignment := AValue; - ACell^.FormatIndex := Workbook.AddCellFormat(fmt); - ChangedCell(ACell^.Row, ACell^.Col); -end; - -{@@ ---------------------------------------------------------------------------- - Enables or disables the word-wrapping feature for a cell. - - @param ARow Row index of the cell considered - @param ACol Column index of the cell considered - @param AValue true = word-wrapping enabled, false = disabled. - @return Pointer to cell --------------------------------------------------------------------------------} -function TsWorksheet.WriteWordwrap(ARow, ACol: Cardinal; AValue: boolean): PCell; -begin - Result := GetCell(ARow, ACol); - WriteWordWrap(Result, AValue); -end; - -{@@ ---------------------------------------------------------------------------- - Enables or disables the word-wrapping feature for a cell. - - @param ACel Pointer to the cell considered - @param AValue true = word-wrapping enabled, false = disabled. --------------------------------------------------------------------------------} -procedure TsWorksheet.WriteWordwrap(ACell: PCell; AValue: boolean); -var - fmt: TsCellFormat; -begin - if ACell = nil then - exit; - fmt := Workbook.GetCellFormat(ACell^.FormatIndex); - if AValue then - Include(fmt.UsedFormattingFields, uffWordwrap) - else - Exclude(fmt.UsedFormattingFields, uffWordwrap); - ACell^.FormatIndex := Workbook.AddCellFormat(fmt); - ChangedCell(ACell^.Row, ACell^.Col); -end; - -function TsWorksheet.WriteBiDiMode(ARow, ACol: Cardinal; AValue: TsBiDiMode): PCell; -begin - Result := GetCell(ARow, ACol); - WriteBiDiMode(Result, AValue); -end; - -procedure TsWorksheet.WriteBiDiMode(ACell: PCell; AValue: TsBiDiMode); -var - fmt: TsCellFormat; -begin - if ACell = nil then - exit; - fmt := Workbook.GetCellFormat(ACell^.FormatIndex); - fmt.BiDiMode := AValue; - if AValue <> bdDefault then - Include(fmt.UsedFormattingFields, uffBiDi) - else - Exclude(fmt.UsedFormattingFields, uffBiDi); - ACell^.FormatIndex := Workbook.AddCellFormat(fmt); - ChangedCell(ACell^.Row, ACell^.Col); -end; - -{@@ ---------------------------------------------------------------------------- - Defines how the cell at the specified row and column is protected: lock - cell modification and/or hide formulas. Note that this is activated only after - enabling worksheet protection (worksheet.Protect(true)). - - NOTE: - FPSpreadsheet does not enforce these actions. They are only written - to the file for the Office application. --------------------------------------------------------------------------------} -function TsWorksheet.WriteCellProtection(ARow, ACol: Cardinal; - AValue: TsCellProtections): PCell; -begin - Result := GetCell(ARow, ACol); - WriteCellProtection(Result, AValue); -end; - -procedure TsWorksheet.WriteCellProtection(ACell: PCell; - AValue: TsCellProtections); -var - fmt: TsCellFormat; -begin - if ACell = nil then - exit; - fmt := Workbook.GetCellFormat(ACell^.FormatIndex); - fmt.Protection := AValue; - if AValue <> DEFAULT_CELL_PROTECTION then - Include(fmt.UsedFormattingFields, uffProtection) - else - Exclude(fmt.UsedFormattingFields, uffProtection); - ACell^.FormatIndex := Workbook.AddCellFormat(fmt); - ChangedCell(ACell^.Row, ACell^.Col); -end; - function TsWorksheet.GetFormatSettings: TFormatSettings; begin Result := FWorkbook.FormatSettings; @@ -8503,7 +7417,8 @@ begin end; end; -{$include fpspreadsheet_CF.inc} // conditional formatting +{$include fpspreadsheet_fmt.inc} // cell formatting +{$include fpspreadsheet_cf.inc} // conditional formatting {==============================================================================} diff --git a/components/fpspreadsheet/source/common/fpspreadsheet_fmt.inc b/components/fpspreadsheet/source/common/fpspreadsheet_fmt.inc new file mode 100644 index 000000000..5ca909df8 --- /dev/null +++ b/components/fpspreadsheet/source/common/fpspreadsheet_fmt.inc @@ -0,0 +1,929 @@ +{ Included by fpspreadsheet.pas } +{ Contains code for cell formatting } + +{@@ ---------------------------------------------------------------------------- + Modifies the background parameters of the format record stored at the + specified index. + + @param AFormatIndex Index of the format record to be changed + @param AStyle Fill style ("pattern") to be used - see TsFillStyle + @param APatternColor RGB value of the pattern color + @param ABackgroundColor RGB value of the background color + + @return Index of the new format record. + + @NOTE When AStyle is fsSolidFill the color is defined by APatternColor, + ABackgroundColor is ignored unless the APatternColor is not + used (scTransparent). +-------------------------------------------------------------------------------} +function TsWorksheet.ChangeBackground(AFormatIndex: Integer; AStyle: TsFillStyle; + APatternColor: TsColor = scTransparent; + ABackgroundColor: TsColor = scTransparent): Integer; +var + fmt: TsCellFormat; +begin + fmt := Workbook.GetCellFormat(AFormatIndex); + if (AStyle = fsNoFill) or + ((APatternColor = scTransparent) and (ABackgroundColor = scTransparent)) + then + Exclude(fmt.UsedFormattingFields, uffBackground) + else + begin + Include(fmt.UsedFormattingFields, uffBackground); + fmt.Background.Style := AStyle; + fmt.Background.FgColor := APatternColor; + if (AStyle = fsSolidFill) and (APatternColor = scTransparent) then + fmt.Background.FgColor := ABackgroundColor + else + fmt.Background.BgColor := ABackgroundColor; + end; + Result := Workbook.AddCellFormat(fmt); +end; + +{@@ ---------------------------------------------------------------------------- + Defines a background pattern for a cell + + @param ARow Row index of the cell + @param ACol Column index of the cell + @param AFillStyle Fill style to be used - see TsFillStyle + @param APatternColor RGB value of the pattern color + @param ABackgroundColor RGB value of the background color + @return Pointer to cell + + @NOTE When AStyle is fsSolidFill the color is defined by APatternColor, + ABackgroundColor is ignored unless the APatternColor is not + used (scTransparent). + + @NOTE Is replaced by uniform fill if WriteBackgroundColor is called later. +-------------------------------------------------------------------------------} +function TsWorksheet.WriteBackground(ARow, ACol: Cardinal; AStyle: TsFillStyle; + APatternColor, ABackgroundColor: TsColor): PCell; +begin + Result := GetCell(ARow, ACol); + WriteBackground(Result, AStyle, APatternColor, ABackgroundColor); +end; + +{@@ ---------------------------------------------------------------------------- + Defines a background pattern for a cell + + @param ACell Pointer to the cell + @param AStyle Fill style ("pattern") to be used - see TsFillStyle + @param APatternColor RGB value of the pattern color + @param ABackgroundColor RGB value of the background color + + @NOTE When AStyle is fsSolidFill the color is defined by APatternColor, + ABackgroundColor is ignored unless the APatternColor is not + used (scTransparent). + + @NOTE Is replaced by uniform fill if WriteBackgroundColor is called later. +-------------------------------------------------------------------------------} +procedure TsWorksheet.WriteBackground(ACell: PCell; AStyle: TsFillStyle; + APatternColor: TsColor = scTransparent; ABackgroundColor: TsColor = scTransparent); +var + idx: Integer; +begin + if ACell <> nil then begin + idx := ACell^.FormatIndex; + ACell^.FormatIndex := ChangeBackground(idx, AStyle, APatternColor, ABackgroundColor); + ChangedCell(ACell^.Row, ACell^.Col); + end; +end; + +{@@ ---------------------------------------------------------------------------- + Sets a uniform background color of a cell. + + @param ARow Row index of the cell + @param ACol Column index of the cell + @param AColor RGB value of the new background color. + Use the value "scTransparent" to clear an existing + background color. + @return Pointer to cell +-------------------------------------------------------------------------------} +function TsWorksheet.WriteBackgroundColor(ARow, ACol: Cardinal; + AColor: TsColor): PCell; +begin + Result := GetCell(ARow, ACol); + WriteBackgroundColor(Result, AColor); +end; + +{@@ ---------------------------------------------------------------------------- + Sets a uniform background color of a cell. + + @param ACell Pointer to cell + @param AColor RGB value of the new background color. + Use the value "scTransparent" to clear an existing + background color. +-------------------------------------------------------------------------------} +procedure TsWorksheet.WriteBackgroundColor(ACell: PCell; AColor: TsColor); +begin + if ACell <> nil then begin + if AColor = scTransparent then + WriteBackground(ACell, fsNoFill) + else + WriteBackground(ACell, fsSolidFill, AColor, AColor); + end; +end; + +function TsWorksheet.WriteBiDiMode(ARow, ACol: Cardinal; AValue: TsBiDiMode): PCell; +begin + Result := GetCell(ARow, ACol); + WriteBiDiMode(Result, AValue); +end; + +procedure TsWorksheet.WriteBiDiMode(ACell: PCell; AValue: TsBiDiMode); +var + fmt: TsCellFormat; +begin + if ACell = nil then + exit; + fmt := Workbook.GetCellFormat(ACell^.FormatIndex); + fmt.BiDiMode := AValue; + if AValue <> bdDefault then + Include(fmt.UsedFormattingFields, uffBiDi) + else + Exclude(fmt.UsedFormattingFields, uffBiDi); + ACell^.FormatIndex := Workbook.AddCellFormat(fmt); + ChangedCell(ACell^.Row, ACell^.Col); +end; + +{@@ ---------------------------------------------------------------------------- + Sets the color of a cell border line. + Note: the border must be included in Borders set in order to be shown! + + @param ARow Row index of the cell + @param ACol Column index of the cell + @param ABorder Indicates to which border (left/top etc) this color is + to be applied + @param AColor RGB value of the new border color + @return Pointer to cell +-------------------------------------------------------------------------------} +function TsWorksheet.WriteBorderColor(ARow, ACol: Cardinal; + ABorder: TsCellBorder; AColor: TsColor): PCell; +begin + Result := GetCell(ARow, ACol); + WriteBorderColor(Result, ABorder, AColor); +end; + +{@@ ---------------------------------------------------------------------------- + Sets the color of a cell border line. + Note: the border must be included in Borders set in order to be shown! + + @param ACell Pointer to cell + @param ABorder Indicates to which border (left/top etc) this color is + to be applied + @param AColor RGB value of the new border color +-------------------------------------------------------------------------------} +procedure TsWorksheet.WriteBorderColor(ACell: PCell; ABorder: TsCellBorder; + AColor: TsColor); +var + fmt: TsCellFormat; +begin + if ACell <> nil then begin + fmt := Workbook.GetCellFormat(ACell^.FormatIndex); + fmt.BorderStyles[ABorder].Color := AColor; + ACell^.FormatIndex := Workbook.AddCellFormat(fmt); + ChangedCell(ACell^.Row, ACell^.Col); + end; +end; + +{@@ ---------------------------------------------------------------------------- + Sets the linestyle of a cell border. + Note: the border must be included in the "Borders" set in order to be shown! + + @param ARow Row index of the cell + @param ACol Column index of the cell + @param ABorder Indicates to which border (left/top etc) this color is + to be applied + @param ALineStyle Identifier of the new line style to be applied. + @return Pointer to cell + + @see TsLineStyle +-------------------------------------------------------------------------------} +function TsWorksheet.WriteBorderLineStyle(ARow, ACol: Cardinal; + ABorder: TsCellBorder; ALineStyle: TsLineStyle): PCell; +begin + Result := GetCell(ARow, ACol); + WriteBorderLineStyle(Result, ABorder, ALineStyle); +end; + +{@@ ---------------------------------------------------------------------------- + Sets the linestyle of a cell border. + Note: the border must be included in the "Borders" set in order to be shown! + + @param ACell Pointer to cell + @param ABorder Indicates to which border (left/top etc) this color is + to be applied + @param ALineStyle Identifier of the new line style to be applied. + + @see TsLineStyle +-------------------------------------------------------------------------------} +procedure TsWorksheet.WriteBorderLineStyle(ACell: PCell; + ABorder: TsCellBorder; ALineStyle: TsLineStyle); +var + fmt: TsCellFormat; +begin + if ACell <> nil then begin + fmt := Workbook.GetCellFormat(ACell^.FormatIndex); + fmt.BorderStyles[ABorder].LineStyle := ALineStyle; + ACell^.FormatIndex := Workbook.AddCellFormat(fmt); + ChangedCell(ACell^.Row, ACell^.Col); + end; +end; + +{@@ ---------------------------------------------------------------------------- + Shows the cell borders included in the set ABorders. No border lines are drawn + for those not included. + + The borders are drawn using the "BorderStyles" assigned to the cell. + + @param ARow Row index of the cell + @param ACol Column index of the cell + @param ABorders Set with elements to identify the border(s) to will be shown + @return Pointer to cell + @see TsCellBorder +-------------------------------------------------------------------------------} +function TsWorksheet.WriteBorders(ARow, ACol: Cardinal; ABorders: TsCellBorders): PCell; +begin + Result := GetCell(ARow, ACol); + WriteBorders(Result, ABorders); +end; + +{@@ ---------------------------------------------------------------------------- + Shows the cell borders included in the set ABorders. No border lines are drawn + for those not included. + + The borders are drawn using the "BorderStyles" assigned to the cell. + + @param ACell Pointer to cell + @param ABorders Set with elements to identify the border(s) to will be shown + @see TsCellBorder +-------------------------------------------------------------------------------} +procedure TsWorksheet.WriteBorders(ACell: PCell; ABorders: TsCellBorders); +var + fmt: TsCellFormat; +begin + if ACell <> nil then begin + fmt := Workbook.GetCellFormat(ACell^.FormatIndex); + if ABorders = [] then + Exclude(fmt.UsedFormattingFields, uffBorder) + else + Include(fmt.UsedFormattingFields, uffBorder); + fmt.Border := ABorders; + ACell^.FormatIndex := Workbook.AddCellFormat(fmt); + ChangedCell(ACell^.Row, ACell^.Col); + end; +end; + +{@@ ---------------------------------------------------------------------------- + Sets the style of a cell border, i.e. line style and line color. + Note: the border must be included in the "Borders" set in order to be shown! + + @param ARow Row index of the cell considered + @param ACol Column index of the cell considered + @param ABorder Identifies the border to be modified (left/top/right/bottom) + @param AStyle record of parameters controlling how the border line is drawn + (line style, line color) + @result Pointer to cell +-------------------------------------------------------------------------------} +function TsWorksheet.WriteBorderStyle(ARow, ACol: Cardinal; + ABorder: TsCellBorder; AStyle: TsCellBorderStyle): PCell; +begin + Result := GetCell(ARow, ACol); + WriteBorderStyle(Result, ABorder, AStyle); +end; + +{@@ ---------------------------------------------------------------------------- + Sets the style of a cell border, i.e. line style and line color. + Note: the border must be included in the "Borders" set in order to be shown! + + @param ACell Pointer to cell + @param ABorder Identifies the border to be modified (left/top/right/bottom) + @param AStyle record of parameters controlling how the border line is drawn + (line style, line color) +-------------------------------------------------------------------------------} +procedure TsWorksheet.WriteBorderStyle(ACell: PCell; ABorder: TsCellBorder; + AStyle: TsCellBorderStyle); +var + fmt: TsCellFormat; +begin + if ACell <> nil then begin + fmt := Workbook.GetCellFormat(ACell^.FormatIndex); + fmt.BorderStyles[ABorder] := AStyle; + ACell^.FormatIndex := Workbook.AddCellFormat(fmt); + ChangedCell(ACell^.Row, ACell^.Col); + end; +end; + +{@@ ---------------------------------------------------------------------------- + Sets line style and line color of a cell border. + Note: the border must be included in the "Borders" set in order to be shown! + + @param ARow Row index of the considered cell + @param ACol Column index of the considered cell + @param ABorder Identifier of the border to be modified + @param ALineStyle Identifier for the new line style of the border + @param AColor RGB value of the border line color + @return Pointer to cell + + @see WriteBorderStyles +-------------------------------------------------------------------------------} +function TsWorksheet.WriteBorderStyle(ARow, ACol: Cardinal; + ABorder: TsCellBorder; ALineStyle: TsLineStyle; AColor: TsColor): PCell; +begin + Result := GetCell(ARow, ACol); + WriteBorderStyle(Result, ABorder, ALineStyle, AColor); +end; + +{@@ ---------------------------------------------------------------------------- + Sets line style and line color of a cell border. + Note: the border must be included in the "Borders" set in order to be shown! + + @param ACell Pointer to cell + @param ABorder Identifier of the border to be modified + @param ALineStyle Identifier for the new line style of the border + @param AColor RGB value of the color of the border line + + @see WriteBorderStyles +-------------------------------------------------------------------------------} +procedure TsWorksheet.WriteBorderStyle(ACell: PCell; ABorder: TsCellBorder; + ALineStyle: TsLineStyle; AColor: TsColor); +var + fmt: TsCellFormat; +begin + if ACell <> nil then begin + fmt := Workbook.GetCellFormat(ACell^.FormatIndex); + fmt.BorderStyles[ABorder].LineStyle := ALineStyle; + fmt.BorderStyles[ABorder].Color := AColor; + ACell^.FormatIndex := Workbook.AddCellFormat(fmt); + ChangedCell(ACell^.Row, ACell^.Col); + end; +end; + +{@@ ---------------------------------------------------------------------------- + Sets the style of all cell border of a cell, i.e. line style and line color. + Note: Only those borders included in the "Borders" set are shown! + + @param ARow Row index of the considered cell + @param ACol Column index of the considered cell + @param AStyles Array of CellBorderStyles for each cell border. + @return Pointer to cell + + @see WriteBorderStyle +-------------------------------------------------------------------------------} +function TsWorksheet.WriteBorderStyles(ARow, ACol: Cardinal; + const AStyles: TsCellBorderStyles): PCell; +begin + Result := GetCell(ARow, ACol); + WriteBorderStyles(Result, AStyles); +end; + +{@@ ---------------------------------------------------------------------------- + Sets the style of all cell border of a cell, i.e. line style and line color. + Note: Only those borders included in the "Borders" set are shown! + + @param ACell Pointer to cell + @param ACol Column index of the considered cell + @param AStyles Array of CellBorderStyles for each cell border. + + @see WriteBorderStyle +-------------------------------------------------------------------------------} +procedure TsWorksheet.WriteBorderStyles(ACell: PCell; + const AStyles: TsCellBorderStyles); +var + b: TsCellBorder; + fmt: TsCellFormat; +begin + if Assigned(ACell) then begin + fmt := Workbook.GetCellFormat(ACell^.FormatIndex); + for b in TsCellBorder do fmt.BorderStyles[b] := AStyles[b]; + ACell^.FormatIndex := Workbook.AddCellFormat(fmt); + ChangedCell(ACell^.Row, ACell^.Col); + end; +end; + +{@@ ---------------------------------------------------------------------------- + Assigns a complete cell format record to a cell + + @param ACell Pointer to the cell to be modified + @param ACellFormat Cell format record to be used by the cell + + @see TsCellFormat +-------------------------------------------------------------------------------} +procedure TsWorksheet.WriteCellFormat(ACell: PCell; + const ACellFormat: TsCellFormat); +var + idx: Integer; +begin + idx := Workbook.AddCellFormat(ACellFormat); + WriteCellFormatIndex(ACell, idx); +end; + +{@@ ---------------------------------------------------------------------------- + Formats a cell to the cell format stored at the specified index in the + workbook's cell format list. + + @param ACell Pointer to the cell to be formatted + @param AIndex Index of the cell format record to be used by the cell + + @see TsCellFormat +-------------------------------------------------------------------------------} +procedure TsWorksheet.WriteCellFormatIndex(ACell: PCell; AIndex: Integer); +begin + if AIndex >= Workbook.GetNumCellFormats then + raise EFpSpreadsheet.Create('[Worksheet.WriteCellFormat] Invalid cell format index.'); + + // The default format index is 0, but it could also be refered to by -1 + if AIndex < 0 then AIndex := 0; + if Assigned(ACell) then begin + ACell^.FormatIndex := AIndex; + ChangedCell(ACell^.Row, ACell^.Col); + end; +end; + +{@@ ---------------------------------------------------------------------------- + Defines how the cell at the specified row and column is protected: lock + cell modification and/or hide formulas. Note that this is activated only after + enabling worksheet protection (worksheet.Protect(true)). + + NOTE: + FPSpreadsheet does not enforce these actions. They are only written + to the file for the Office application. +-------------------------------------------------------------------------------} +function TsWorksheet.WriteCellProtection(ARow, ACol: Cardinal; + AValue: TsCellProtections): PCell; +begin + Result := GetCell(ARow, ACol); + WriteCellProtection(Result, AValue); +end; + +procedure TsWorksheet.WriteCellProtection(ACell: PCell; + AValue: TsCellProtections); +var + fmt: TsCellFormat; +begin + if ACell = nil then + exit; + fmt := Workbook.GetCellFormat(ACell^.FormatIndex); + fmt.Protection := AValue; + if AValue <> DEFAULT_CELL_PROTECTION then + Include(fmt.UsedFormattingFields, uffProtection) + else + Exclude(fmt.UsedFormattingFields, uffProtection); + ACell^.FormatIndex := Workbook.AddCellFormat(fmt); + ChangedCell(ACell^.Row, ACell^.Col); +end; + +{@@ ---------------------------------------------------------------------------- + Adds font specification to the formatting of a cell. Looks in the workbook's + FontList and creates an new entry if the font is not used so far. Returns the + index of the font in the font list. + + @param ARow The row of the cell + @param ACol The column of the cell + @param AFontName Name of the font + @param AFontSize Size of the font, in points + @param AFontStyle Set with font style attributes + (don't use those of unit "graphics" !) + @param AFontColor RGB value of the font's color + @param APosition Specifies sub- or superscript text + @return Index of the font in the workbook's font list. +-------------------------------------------------------------------------------} +function TsWorksheet.WriteFont(ARow, ACol: Cardinal; const AFontName: String; + AFontSize: Single; AFontStyle: TsFontStyles; AFontColor: TsColor; + APosition: TsFontPosition = fpNormal): Integer; +begin + Result := WriteFont(GetCell(ARow, ACol), AFontName, AFontSize, AFontStyle, + AFontColor, APosition); +end; + +{@@ ---------------------------------------------------------------------------- + Adds font specification to the formatting of a cell. Looks in the workbook's + FontList and creates an new entry if the font is not used so far. Returns the + index of the font in the font list. + + @param ACell Pointer to the cell considered + @param AFontName Name of the font + @param AFontSize Size of the font, in points + @param AFontStyle Set with font style attributes + (don't use those of unit "graphics" !) + @param AFontColor RGB value of the font's color + @param APosition Specified subscript or superscript text. + @return Index of the font in the workbook's font list. +-------------------------------------------------------------------------------} +function TsWorksheet.WriteFont(ACell: PCell; const AFontName: String; + AFontSize: Single; AFontStyle: TsFontStyles; AFontColor: TsColor; + APosition: TsFontPosition = fpNormal): Integer; +var + fmt: TsCellFormat; +begin + if ACell = nil then + begin + Result := -1; + Exit; + end; + + Result := FWorkbook.FindFont(AFontName, AFontSize, AFontStyle, AFontColor, APosition); + if Result = -1 then + result := FWorkbook.AddFont(AFontName, AFontSize, AFontStyle, AFontColor, APosition); + + fmt := Workbook.GetCellFormat(ACell^.FormatIndex); + Include(fmt.UsedFormattingFields, uffFont); + fmt.FontIndex := Result; + ACell^.FormatIndex := Workbook.AddCellFormat(fmt); + + ChangedFont(ACell^.Row, ACell^.Col); +end; + +{@@ ---------------------------------------------------------------------------- + Applies a font to the formatting of a cell. The font is determined by its + index in the workbook's font list: + + @param ARow The row of the cell + @param ACol The column of the cell + @param AFontIndex Index of the font in the workbook's font list + @return Pointer to the cell +-------------------------------------------------------------------------------} +function TsWorksheet.WriteFont(ARow, ACol: Cardinal; AFontIndex: Integer): PCell; +begin + Result := GetCell(ARow, ACol); + WriteFont(Result, AFontIndex); +end; + +{@@ ---------------------------------------------------------------------------- + Applies a font to the formatting of a cell. The font is determined by its + index in the workbook's font list: + + @param ACell Pointer to the cell considered + @param AFontIndex Index of the font in the workbook's font list +-------------------------------------------------------------------------------} +procedure TsWorksheet.WriteFont(ACell: PCell; AFontIndex: Integer); +var + fmt: TsCellFormat; +begin + if ACell = nil then + exit; + + if (AFontIndex < 0) or (AFontIndex >= Workbook.GetFontCount) then + raise EFPSpreadsheet.Create(rsInvalidFontIndex); + + fmt := Workbook.GetCellFormat(ACell^.FormatIndex); + Include(fmt.UsedFormattingFields, uffFont); + fmt.FontIndex := AFontIndex; + ACell^.FormatIndex := Workbook.AddCellFormat(fmt); + + ChangedFont(ACell^.Row, ACell^.Col); +end; + +{@@ ---------------------------------------------------------------------------- + Replaces the text color used in formatting of a cell. Looks in the workbook's + font list if this modified font has already been used. If not a new font entry + is created. Returns the index of this font in the font list. + + @param ARow The row of the cell + @param ACol The column of the cell + @param AFontColor RGB value of the new text color + @return Index of the font in the workbook's font list. +-------------------------------------------------------------------------------} +function TsWorksheet.WriteFontColor(ARow, ACol: Cardinal; AFontColor: TsColor): Integer; +begin + Result := WriteFontColor(GetCell(ARow, ACol), AFontColor); +end; + +{@@ ---------------------------------------------------------------------------- + Replaces the text color used in formatting of a cell. Looks in the workbook's + font list if this modified font has already been used. If not a new font entry + is created. Returns the index of this font in the font list. + + @param ACell Pointer to the cell + @param AFontColor RGB value of the new text color + @return Index of the font in the workbook's font list. +-------------------------------------------------------------------------------} +function TsWorksheet.WriteFontColor(ACell: PCell; AFontColor: TsColor): Integer; +var + fnt: TsFont; +begin + if ACell = nil then begin + Result := 0; + exit; + end; + fnt := ReadCellFont(ACell); + Result := WriteFont(ACell, fnt.FontName, fnt.Size, fnt.Style, AFontColor); +end; + +{@@ ---------------------------------------------------------------------------- + Replaces the font used in formatting of a cell considering only the font face + and leaving font size, style and color unchanged. Looks in the workbook's + font list if this modified font has already been used. If not a new font entry + is created. Returns the index of this font in the font list. + + @param ARow The row of the cell + @param ACol The column of the cell + @param AFontName Name of the new font to be used + @return Index of the font in the workbook's font list. +-------------------------------------------------------------------------------} +function TsWorksheet.WriteFontName(ARow, ACol: Cardinal; AFontName: String): Integer; +begin + result := WriteFontName(GetCell(ARow, ACol), AFontName); +end; + +{@@ ---------------------------------------------------------------------------- + Replaces the font used in formatting of a cell considering only the font face + and leaving font size, style and color unchanged. Looks in the workbook's + font list if this modified font has already been used. If not a new font entry + is created. Returns the index of this font in the font list. + + @param ACell Pointer to the cell + @param AFontName Name of the new font to be used + @return Index of the font in the workbook's font list. +-------------------------------------------------------------------------------} +function TsWorksheet.WriteFontName(ACell: PCell; AFontName: String): Integer; +var + fnt: TsFont; +begin + if ACell = nil then begin + Result := 0; + exit; + end; + fnt := ReadCellFont(ACell); + result := WriteFont(ACell, AFontName, fnt.Size, fnt.Style, fnt.Color); +end; + +{@@ ---------------------------------------------------------------------------- + Replaces the font size in formatting of a cell. Looks in the workbook's + font list if this modified font has already been used. If not a new font entry + is created. Returns the index of this font in the font list. + + @param ARow The row of the cell + @param ACol The column of the cell + @param ASize Size of the font to be used (in points). + @return Index of the font in the workbook's font list. +-------------------------------------------------------------------------------} +function TsWorksheet.WriteFontSize(ARow, ACol: Cardinal; ASize: Single): Integer; +begin + Result := WriteFontSize(GetCell(ARow, ACol), ASize); +end; + +{@@ ---------------------------------------------------------------------------- + Replaces the font size in formatting of a cell. Looks in the workbook's + font list if this modified font has already been used. If not a new font entry + is created. Returns the index of this font in the font list. + + @param ACell Pointer to the cell + @param ASize Size of the font to be used (in points). + @return Index of the font in the workbook's font list. +-------------------------------------------------------------------------------} +function TsWorksheet.WriteFontSize(ACell: PCell; ASize: Single): Integer; +var + fnt: TsFont; +begin + if ACell = nil then begin + Result := 0; + exit; + end; + fnt := ReadCellFont(ACell); + Result := WriteFont(ACell, fnt.FontName, ASize, fnt.Style, fnt.Color); +end; + +{@@ ---------------------------------------------------------------------------- + Replaces the font style (bold, italic, etc) in formatting of a cell. + Looks in the workbook's font list if this modified font has already been used. + If not a new font entry is created. + Returns the index of this font in the font list. + + @param ARow The row of the cell + @param ACol The column of the cell + @param AStyle New font style to be used + @return Index of the font in the workbook's font list. + + @see TsFontStyle +-------------------------------------------------------------------------------} +function TsWorksheet.WriteFontStyle(ARow, ACol: Cardinal; + AStyle: TsFontStyles): Integer; +begin + Result := WriteFontStyle(GetCell(ARow, ACol), AStyle); +end; + +{@@ ---------------------------------------------------------------------------- + Replaces the font style (bold, italic, etc) in formatting of a cell. + Looks in the workbook's font list if this modified font has already been used. + If not a new font entry is created. + Returns the index of this font in the font list. + + @param ACell Pointer to the cell considered + @param AStyle New font style to be used + @return Index of the font in the workbook's font list. + + @see TsFontStyle +-------------------------------------------------------------------------------} +function TsWorksheet.WriteFontStyle(ACell: PCell; AStyle: TsFontStyles): Integer; +var + fnt: TsFont; +begin + if ACell = nil then begin + Result := -1; + exit; + end; + fnt := ReadCellFont(ACell); + Result := WriteFont(ACell, fnt.FontName, fnt.Size, AStyle, fnt.Color); +end; + +{@@ ---------------------------------------------------------------------------- + Defines the horizontal alignment of text in a cell. + + @param ARow Row index of the cell considered + @param ACol Column index of the cell considered + @param AValue Parameter for horizontal text alignment + (haDefault, vaLeft, haCenter, haRight) + By default, texts are left-aligned, numbers and dates are + right-aligned. + @return Pointer to cell +-------------------------------------------------------------------------------} +function TsWorksheet.WriteHorAlignment(ARow, ACol: Cardinal; AValue: TsHorAlignment): PCell; +begin + Result := GetCell(ARow, ACol); + WriteHorAlignment(Result, AValue); +end; + +{@@ ---------------------------------------------------------------------------- + Defines the horizontal alignment of text in a cell. + + @param ACell Pointer to the cell considered + @param AValue Parameter for horizontal text alignment + (haDefault, vaLeft, haCenter, haRight) + By default, texts are left-aligned, numbers and dates are + right-aligned. +-------------------------------------------------------------------------------} +procedure TsWorksheet.WriteHorAlignment(ACell: PCell; AValue: TsHorAlignment); +var + fmt: TsCellFormat; +begin + if ACell = nil then + exit; + fmt := Workbook.GetCellFormat(ACell^.FormatIndex); + if AValue = haDefault then + Exclude(fmt.UsedFormattingFields, uffHorAlign) + else + Include(fmt.UsedFormattingFields, uffHorAlign); + fmt.HorAlignment := AValue; + ACell^.FormatIndex := Workbook.AddCellFormat(fmt); + ChangedCell(ACell^.Row, ACell^.Col); +end; + +{@@ ---------------------------------------------------------------------------- + Adds text rotation to the formatting of a cell + + @param ARow The row of the cell + @param ACol The column of the cell + @param ARotation How to rotate the text + @return Pointer to cell + + @see TsTextRotation +-------------------------------------------------------------------------------} +function TsWorksheet.WriteTextRotation(ARow, ACol: Cardinal; + ARotation: TsTextRotation): PCell; +begin + Result := GetCell(ARow, ACol); + WriteTextRotation(Result, ARotation); +end; + +{@@ ---------------------------------------------------------------------------- + Adds text rotation to the formatting of a cell + + @param ACell Pointer to the cell + @param ARotation How to rotate the text + + @see TsTextRotation +-------------------------------------------------------------------------------} +procedure TsWorksheet.WriteTextRotation(ACell: PCell; ARotation: TsTextRotation); +var + fmt: TsCellFormat; +begin + if ACell = nil then + exit; + + fmt := Workbook.GetCellFormat(ACell^.FormatIndex); + Include(fmt.UsedFormattingFields, uffTextRotation); + fmt.TextRotation := ARotation; + ACell^.FormatIndex := Workbook.AddCellFormat(fmt); + + ChangedFont(ACell^.Row, ACell^.Col); +end; + +{@@ ---------------------------------------------------------------------------- + Directly modifies the used formatting fields of a cell. + Only formatting corresponding to items included in this set is executed. + + @param ARow The row of the cell + @param ACol The column of the cell + @param AUsedFormatting set of the used formatting fields + @return Pointer to the (existing or created) cell + + @see TsUsedFormattingFields + @see TCell +-------------------------------------------------------------------------------} +function TsWorksheet.WriteUsedFormatting(ARow, ACol: Cardinal; + AUsedFormatting: TsUsedFormattingFields): PCell; +begin + Result := GetCell(ARow, ACol); + WriteUsedFormatting(Result, AUsedFormatting); +end; + +{@@ ---------------------------------------------------------------------------- + Directly modifies the used formatting fields of an existing cell. + Only formatting corresponding to items included in this set is executed. + + @param ACell Pointer to the cell to be modified + @param AUsedFormatting set of the used formatting fields + + @see TsUsedFormattingFields + @see TCell +-------------------------------------------------------------------------------} +procedure TsWorksheet.WriteUsedFormatting(ACell: PCell; + AUsedFormatting: TsUsedFormattingFields); +var + fmt: TsCellFormat; +begin + if ACell = nil then + exit; + fmt := FWorkbook.GetCellFormat(ACell^.FormatIndex); + fmt.UsedFormattingFields := AUsedFormatting; + ACell^.FormatIndex := Workbook.AddCellFormat(fmt); + ChangedCell(ACell^.Row, ACell^.Col); +end; + +{@@ ---------------------------------------------------------------------------- + Defines the vertical alignment of text in a cell. + + @param ARow Row index of the cell considered + @param ACol Column index of the cell considered + @param AValue Parameter for vertical text alignment + (vaDefault, vaTop, vaCenter, vaBottom) + By default, texts are bottom-aligned. + @return Pointer to cell +-------------------------------------------------------------------------------} +function TsWorksheet.WriteVertAlignment(ARow, ACol: Cardinal; + AValue: TsVertAlignment): PCell; +begin + Result := GetCell(ARow, ACol); + WriteVertAlignment(Result, AValue); +end; + +{@@ ---------------------------------------------------------------------------- + Defines the vertical alignment of text in a cell. + + @param ACell Poiner to the cell considered + @param AValue Parameter for vertical text alignment + (vaDefault, vaTop, vaCenter, vaBottom) + By default, texts are bottom-aligned. +-------------------------------------------------------------------------------} +procedure TsWorksheet.WriteVertAlignment(ACell: PCell; AValue: TsVertAlignment); +var + fmt: TsCellFormat; +begin + if ACell = nil then + exit; + fmt := Workbook.GetCellFormat(ACell^.FormatIndex); + if AValue = vaDefault then + Exclude(fmt.UsedFormattingFields, uffVertAlign) + else + Include(fmt.UsedFormattingFields, uffVertAlign); + fmt.VertAlignment := AValue; + ACell^.FormatIndex := Workbook.AddCellFormat(fmt); + ChangedCell(ACell^.Row, ACell^.Col); +end; + +{@@ ---------------------------------------------------------------------------- + Enables or disables the word-wrapping feature for a cell. + + @param ARow Row index of the cell considered + @param ACol Column index of the cell considered + @param AValue true = word-wrapping enabled, false = disabled. + @return Pointer to cell +-------------------------------------------------------------------------------} +function TsWorksheet.WriteWordwrap(ARow, ACol: Cardinal; AValue: boolean): PCell; +begin + Result := GetCell(ARow, ACol); + WriteWordWrap(Result, AValue); +end; + +{@@ ---------------------------------------------------------------------------- + Enables or disables the word-wrapping feature for a cell. + + @param ACel Pointer to the cell considered + @param AValue true = word-wrapping enabled, false = disabled. +-------------------------------------------------------------------------------} +procedure TsWorksheet.WriteWordwrap(ACell: PCell; AValue: boolean); +var + fmt: TsCellFormat; +begin + if ACell = nil then + exit; + fmt := Workbook.GetCellFormat(ACell^.FormatIndex); + if AValue then + Include(fmt.UsedFormattingFields, uffWordwrap) + else + Exclude(fmt.UsedFormattingFields, uffWordwrap); + ACell^.FormatIndex := Workbook.AddCellFormat(fmt); + ChangedCell(ACell^.Row, ACell^.Col); +end; +