You've already forked lazarus-ccr
fpspreadsheet: Fix merged cell borders in TWorksheet being drawn as defined by the merge base.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4467 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -1710,14 +1710,15 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Draws the borders of all cells. Calls DrawCellBorder for each individual cell.
|
Draws the borders of all cells. Calls DrawCellBorders for each individual cell.
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure TsCustomWorksheetGrid.DrawCellBorders;
|
procedure TsCustomWorksheetGrid.DrawCellBorders;
|
||||||
var
|
var
|
||||||
cell: PCell;
|
cell, base: PCell;
|
||||||
gc, gr: Integer;
|
gc, gr: Integer;
|
||||||
sr1, sc1, sr2, sc2: Cardinal;
|
sr1, sc1, sr2, sc2: Cardinal;
|
||||||
rect: TRect;
|
rect: TRect;
|
||||||
|
cellHasBorder: Boolean;
|
||||||
begin
|
begin
|
||||||
if Worksheet = nil then
|
if Worksheet = nil then
|
||||||
exit;
|
exit;
|
||||||
@ -1730,20 +1731,14 @@ begin
|
|||||||
if sc1 = UNASSIGNED_ROW_COL_INDEX then sc1 := 0;
|
if sc1 = UNASSIGNED_ROW_COL_INDEX then sc1 := 0;
|
||||||
|
|
||||||
for cell in Worksheet.Cells.GetRangeEnumerator(sr1, sc1, sr2, sc2) do
|
for cell in Worksheet.Cells.GetRangeEnumerator(sr1, sc1, sr2, sc2) do
|
||||||
if (uffBorder in Worksheet.ReadUsedFormatting(cell)) then
|
|
||||||
begin
|
begin
|
||||||
gc := GetGridCol(cell^.Col);
|
if Worksheet.IsMerged(cell) then
|
||||||
gr := GetGridRow(cell^.Row);
|
|
||||||
rect := CellRect(gc, gr);
|
|
||||||
DrawCellBorders(gc, gr, rect, cell);
|
|
||||||
end;
|
|
||||||
|
|
||||||
{
|
|
||||||
gr := TopLeft.Y;
|
|
||||||
gc := TopLeft.X;
|
|
||||||
for cell in Worksheet.Cells do
|
|
||||||
begin
|
begin
|
||||||
if (uffBorder in Worksheet.ReadUsedFormatting(cell)) then
|
base := Worksheet.FindMergeBase(cell);
|
||||||
|
cellHasBorder := uffBorder in Worksheet.ReadUsedFormatting(base);
|
||||||
|
end else
|
||||||
|
cellHasBorder := uffBorder in Worksheet.ReadUsedFormatting(cell);
|
||||||
|
if cellHasBorder then
|
||||||
begin
|
begin
|
||||||
gc := GetGridCol(cell^.Col);
|
gc := GetGridCol(cell^.Col);
|
||||||
gr := GetGridRow(cell^.Row);
|
gr := GetGridRow(cell^.Row);
|
||||||
@ -1751,7 +1746,6 @@ begin
|
|||||||
DrawCellBorders(gc, gr, rect, cell);
|
DrawCellBorders(gc, gr, rect, cell);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
}
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
@ -1892,23 +1886,12 @@ var
|
|||||||
fmt: PsCellFormat;
|
fmt: PsCellFormat;
|
||||||
begin
|
begin
|
||||||
if Assigned(Worksheet) then begin
|
if Assigned(Worksheet) then begin
|
||||||
if IsRightToLeft then
|
|
||||||
begin
|
|
||||||
// Left border
|
|
||||||
if GetBorderStyle(ACol, ARow, +1, 0, ACell, bs) then
|
|
||||||
DrawBorderLine(ARect.Left-1, ARect, drawVert, bs);
|
|
||||||
// Right border
|
|
||||||
if GetBorderStyle(ACol, ARow, -1, 0, ACell, bs) then
|
|
||||||
DrawBorderLine(ARect.Right-1, ARect, drawVert, bs);
|
|
||||||
end else
|
|
||||||
begin
|
|
||||||
// Left border
|
// Left border
|
||||||
if GetBorderStyle(ACol, ARow, -1, 0, ACell, bs) then
|
if GetBorderStyle(ACol, ARow, -1, 0, ACell, bs) then
|
||||||
DrawBorderLine(ARect.Left-1, ARect, drawVert, bs);
|
DrawBorderLine(ARect.Left-ord(not IsRightToLeft), ARect, drawVert, bs);
|
||||||
// Right border
|
// Right border
|
||||||
if GetBorderStyle(ACol, ARow, +1, 0, ACell, bs) then
|
if GetBorderStyle(ACol, ARow, +1, 0, ACell, bs) then
|
||||||
DrawBorderLine(ARect.Right-1, ARect, drawVert, bs);
|
DrawBorderLine(ARect.Right-ord(not IsRightToLeft), ARect, drawVert, bs);
|
||||||
end;
|
|
||||||
// Top border
|
// Top border
|
||||||
if GetBorderstyle(ACol, ARow, 0, -1, ACell, bs) then
|
if GetBorderstyle(ACol, ARow, 0, -1, ACell, bs) then
|
||||||
DrawBorderLine(ARect.Top-1, ARect, drawHor, bs);
|
DrawBorderLine(ARect.Top-1, ARect, drawHor, bs);
|
||||||
@ -2717,6 +2700,8 @@ end;
|
|||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Returns the cell borders which are drawn around a given cell.
|
Returns the cell borders which are drawn around a given cell.
|
||||||
|
If the cell is part of a merged block then the borders of the merge base
|
||||||
|
are applied to the location of the cell (no inner borders for merged cells).
|
||||||
|
|
||||||
@param ACol Grid column index of the cell
|
@param ACol Grid column index of the cell
|
||||||
@param ARow Grid row index of the cell
|
@param ARow Grid row index of the cell
|
||||||
@ -2725,11 +2710,32 @@ end;
|
|||||||
function TsCustomWorksheetGrid.GetCellBorder(ACol, ARow: Integer): TsCellBorders;
|
function TsCustomWorksheetGrid.GetCellBorder(ACol, ARow: Integer): TsCellBorders;
|
||||||
var
|
var
|
||||||
cell: PCell;
|
cell: PCell;
|
||||||
|
base: PCell;
|
||||||
|
r, c, r1, c1, r2, c2: Cardinal;
|
||||||
begin
|
begin
|
||||||
Result := [];
|
Result := [];
|
||||||
if Assigned(Worksheet) then
|
if Assigned(Worksheet) then
|
||||||
begin
|
begin
|
||||||
cell := Worksheet.FindCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
|
r := GetWorksheetRow(ARow);
|
||||||
|
c := GetWorksheetCol(ACol);
|
||||||
|
cell := Worksheet.FindCell(r, c);
|
||||||
|
if Worksheet.IsMerged(cell) then
|
||||||
|
begin
|
||||||
|
Worksheet.FindMergedRange(cell, r1, c1, r2, c2);
|
||||||
|
base := Worksheet.FindCell(r1, c1);
|
||||||
|
Result := Worksheet.ReadCellBorders(base);
|
||||||
|
if (cbNorth in Result) and (r > r1) then Exclude(Result, cbNorth);
|
||||||
|
if (cbSouth in Result) and (r < r2) then Exclude(Result, cbSouth);
|
||||||
|
if IsRightToLeft then
|
||||||
|
begin
|
||||||
|
if (cbEast in Result) and (c > c1) then Exclude(Result, cbEast);
|
||||||
|
if (cbWest in Result) and (c < c2) then Exclude(Result, cbWest);
|
||||||
|
end else
|
||||||
|
begin
|
||||||
|
if (cbWest in Result) and (c > c1) then Exclude(Result, cbWest);
|
||||||
|
if (cbEast in Result) and (c < c2) then Exclude(Result, cbEast);
|
||||||
|
end;
|
||||||
|
end else
|
||||||
Result := Worksheet.ReadCellBorders(cell);
|
Result := Worksheet.ReadCellBorders(cell);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -2771,6 +2777,9 @@ end;
|
|||||||
by the parameter ABorder of a cell. The style is defined by line style and
|
by the parameter ABorder of a cell. The style is defined by line style and
|
||||||
line color.
|
line color.
|
||||||
|
|
||||||
|
If the cell belongs to a merged block then the border styles of the merge
|
||||||
|
base are returned.
|
||||||
|
|
||||||
@param ACol Grid column index of the cell
|
@param ACol Grid column index of the cell
|
||||||
@param ARow Grid row index of the cell
|
@param ARow Grid row index of the cell
|
||||||
@param ABorder Identifier of the border at which the line will be drawn
|
@param ABorder Identifier of the border at which the line will be drawn
|
||||||
@ -2782,11 +2791,14 @@ function TsCustomWorksheetGrid.GetCellBorderStyle(ACol, ARow: Integer;
|
|||||||
ABorder: TsCellBorder): TsCellBorderStyle;
|
ABorder: TsCellBorder): TsCellBorderStyle;
|
||||||
var
|
var
|
||||||
cell: PCell;
|
cell: PCell;
|
||||||
|
base: PCell;
|
||||||
begin
|
begin
|
||||||
Result := DEFAULT_BORDERSTYLES[ABorder];
|
Result := DEFAULT_BORDERSTYLES[ABorder];
|
||||||
if Assigned(Worksheet) then
|
if Assigned(Worksheet) then
|
||||||
begin
|
begin
|
||||||
cell := Worksheet.FindCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
|
cell := Worksheet.FindCell(GetWorksheetRow(ARow), GetWorksheetCol(ACol));
|
||||||
|
if Worksheet.IsMerged(cell) then
|
||||||
|
cell := Worksheet.FindMergeBase(cell);
|
||||||
Result := Worksheet.ReadCellBorderStyle(cell, ABorder);
|
Result := Worksheet.ReadCellBorderStyle(cell, ABorder);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -3183,12 +3195,12 @@ end;
|
|||||||
function TsCustomWorksheetGrid.GetBorderStyle(ACol, ARow, ADeltaCol, ADeltaRow: Integer;
|
function TsCustomWorksheetGrid.GetBorderStyle(ACol, ARow, ADeltaCol, ADeltaRow: Integer;
|
||||||
ACell: PCell; out ABorderStyle: TsCellBorderStyle): Boolean;
|
ACell: PCell; out ABorderStyle: TsCellBorderStyle): Boolean;
|
||||||
var
|
var
|
||||||
//cell,
|
|
||||||
neighborcell: PCell;
|
neighborcell: PCell;
|
||||||
border, neighborborder: TsCellBorder;
|
border, neighborborder: TsCellBorder;
|
||||||
// r, c: Cardinal;
|
r, c: Cardinal;
|
||||||
begin
|
begin
|
||||||
Result := true;
|
Result := true;
|
||||||
|
|
||||||
if (ADeltaCol = -1) and (ADeltaRow = 0) then
|
if (ADeltaCol = -1) and (ADeltaRow = 0) then
|
||||||
begin
|
begin
|
||||||
border := cbWest;
|
border := cbWest;
|
||||||
@ -3211,13 +3223,15 @@ begin
|
|||||||
end else
|
end else
|
||||||
raise Exception.Create('[TsCustomWorksheetGrid] Incorrect col/row for GetBorderStyle.');
|
raise Exception.Create('[TsCustomWorksheetGrid] Incorrect col/row for GetBorderStyle.');
|
||||||
|
|
||||||
// r := GetWorksheetRow(ARow);
|
if IsRightToLeft then
|
||||||
// c := GetWorksheetCol(ACol);
|
ADeltaCol := -ADeltaCol;
|
||||||
//cell := Worksheet.FindCell(r, c);
|
|
||||||
if (ARow - FHeaderCount + ADeltaRow < 0) or (ACol - FHeaderCount + ADeltaCol < 0) then
|
r := GetWorksheetRow(ARow);
|
||||||
|
c := GetWorksheetCol(ACol);
|
||||||
|
if (r + ADeltaRow < 0) or (c + ADeltaCol < 0) then
|
||||||
neighborcell := nil
|
neighborcell := nil
|
||||||
else
|
else
|
||||||
neighborcell := Worksheet.FindCell(ARow - FHeaderCount + ADeltaRow, ACol - FHeaderCount + ADeltaCol);
|
neighborcell := Worksheet.FindCell(r + ADeltaRow, c + ADeltaCol);
|
||||||
|
|
||||||
// Only cell has border, but neighbor has not
|
// Only cell has border, but neighbor has not
|
||||||
if HasBorder(ACell, border) and not HasBorder(neighborCell, neighborBorder) then
|
if HasBorder(ACell, border) and not HasBorder(neighborCell, neighborBorder) then
|
||||||
@ -3225,7 +3239,7 @@ begin
|
|||||||
if Worksheet.InSameMergedRange(ACell, neighborcell) then
|
if Worksheet.InSameMergedRange(ACell, neighborcell) then
|
||||||
result := false
|
result := false
|
||||||
else
|
else
|
||||||
ABorderStyle := Worksheet.ReadCellBorderStyle(ACell, border)
|
ABorderStyle := GetCellBorderStyle(ACol, ARow, border);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
// Only neighbor has border, cell has not
|
// Only neighbor has border, cell has not
|
||||||
@ -3234,7 +3248,7 @@ begin
|
|||||||
if Worksheet.InSameMergedRange(ACell, neighborcell) then
|
if Worksheet.InSameMergedRange(ACell, neighborcell) then
|
||||||
result := false
|
result := false
|
||||||
else
|
else
|
||||||
ABorderStyle := Worksheet.ReadCellBorderStyle(neighborcell, neighborborder);
|
ABorderStyle := GetCellBorderStyle(ACol+ADeltaCol, ARow+ADeltaRow, neighborborder);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
// Both cells have shared border -> use top or left border
|
// Both cells have shared border -> use top or left border
|
||||||
@ -3244,9 +3258,9 @@ begin
|
|||||||
result := false
|
result := false
|
||||||
else
|
else
|
||||||
if (border in [cbNorth, cbWest]) then
|
if (border in [cbNorth, cbWest]) then
|
||||||
ABorderStyle := Worksheet.ReadCellBorderStyle(neighborcell, neighborborder)
|
ABorderStyle := GetCellBorderStyle(ACol+ADeltaCol, ARow+ADeltaRow, neighborborder)
|
||||||
else
|
else
|
||||||
ABorderStyle := Worksheet.ReadCellBorderStyle(ACell, border);
|
ABorderStyle := GetCellBorderStyle(ACol, ARow, border);
|
||||||
end else
|
end else
|
||||||
Result := false;
|
Result := false;
|
||||||
end;
|
end;
|
||||||
@ -3327,16 +3341,34 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Returns true if the cell has the given border.
|
Returns true if the cell has the given border. In case of merged cell the
|
||||||
|
borders of the merge base are checked. Inner merged cells don't have a border.
|
||||||
|
|
||||||
@param ACell Pointer to cell considered
|
@param ACell Pointer to cell considered
|
||||||
@param ABorder Indicator for border to be checked for visibility
|
@param ABorder Indicator for border to be checked for visibility
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
function TsCustomWorksheetGrid.HasBorder(ACell: PCell; ABorder: TsCellBorder): Boolean;
|
function TsCustomWorksheetGrid.HasBorder(ACell: PCell; ABorder: TsCellBorder): Boolean;
|
||||||
|
var
|
||||||
|
base: PCell;
|
||||||
|
r1, c1, r2, c2: Cardinal;
|
||||||
begin
|
begin
|
||||||
if Worksheet = nil then
|
if Worksheet = nil then
|
||||||
result := false
|
result := false
|
||||||
else
|
else
|
||||||
|
if Worksheet.IsMerged(ACell) then
|
||||||
|
begin
|
||||||
|
Worksheet.FindMergedRange(ACell, r1, c1, r2, c2);
|
||||||
|
base := Worksheet.FindCell(r1, c1);
|
||||||
|
Result := ABorder in Worksheet.ReadCellBorders(base);
|
||||||
|
case ABorder of
|
||||||
|
cbNorth : if ACell^.Row > r1 then Result := false;
|
||||||
|
cbSouth : if ACell^.Row < r2 then Result := false;
|
||||||
|
cbEast : if (IsRightToLeft and (ACell^.Col > c1)) or
|
||||||
|
(not IsRightToLeft and (ACell^.Col < c2)) then Result := false;
|
||||||
|
cbWest : if (IsRightToLeft and (ACell^.Col < c2)) or
|
||||||
|
(not IsRightToLeft and (ACell^.Col > c1)) then Result := false;
|
||||||
|
end;
|
||||||
|
end else
|
||||||
Result := ABorder in Worksheet.ReadCellBorders(ACell);
|
Result := ABorder in Worksheet.ReadCellBorders(ACell);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user