fpspreadsheet: Fix incorrect cell background painting of text-overflown cells in TsWorksheetGrid.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3604 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2014-09-25 10:36:17 +00:00
parent dcbbb0c0a1
commit 19281ec8af

View File

@ -50,6 +50,7 @@ type
FTextOverflow: Boolean; FTextOverflow: Boolean;
FReadFormulas: Boolean; FReadFormulas: Boolean;
FDrawingCell: PCell; FDrawingCell: PCell;
FTextOverflowing: Boolean;
function CalcAutoRowHeight(ARow: Integer): Integer; function CalcAutoRowHeight(ARow: Integer): Integer;
function CalcColWidth(AWidth: Single): Integer; function CalcColWidth(AWidth: Single): Integer;
function CalcRowHeight(AHeight: Single): Integer; function CalcRowHeight(AHeight: Single): Integer;
@ -816,6 +817,16 @@ end;
to show the complete text. to show the complete text.
Ony for non-wordwrapped label cells and for horizontal orientation. Ony for non-wordwrapped label cells and for horizontal orientation.
Function returns false if text overflow needs not to be considered. Function returns false if text overflow needs not to be considered.
@param ACol, ARow Column and row indexes (in grid coordinates) of the cell
to be drawn
@param AState GridDrawState of the cell (normal, fixed, selected etc)
@param ACol1,ACol2 (output) Index of the first and last column covered by the
overflowing text
@param ARect (output) Pixel rectangle enclosing the cell and its neighbors
affected
@return TRUE if text overflow into neighbor cells is to be considered,
FALSE if not.
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
function TsCustomWorksheetGrid.CellOverflow(ACol, ARow: Integer; function TsCustomWorksheetGrid.CellOverflow(ACol, ARow: Integer;
AState: TGridDrawState; out ACol1, ACol2: Integer; var ARect: TRect): Boolean; AState: TGridDrawState; out ACol1, ACol2: Integer; var ARect: TRect): Boolean;
@ -829,11 +840,13 @@ var
begin begin
Result := false; Result := false;
cell := FDrawingCell; cell := FDrawingCell;
if (cell = nil) or (cell^.ContentType <> cctUTF8String) then // non-label cells do not overflow!
// Nothing to do in these cases (like in Excel):
if (cell = nil) or (cell^.ContentType <> cctUTF8String) then // ... non-label cells
exit; exit;
if (uffWordWrap in cell^.UsedFormattingFields) then if (uffWordWrap in cell^.UsedFormattingFields) then // ... word-wrap
exit; exit;
if (uffTextRotation in cell^.UsedFormattingFields) and if (uffTextRotation in cell^.UsedFormattingFields) and // ... vertical text
(cell^.TextRotation <> trHorizontal) (cell^.TextRotation <> trHorizontal)
then then
exit; exit;
@ -1418,9 +1431,7 @@ end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
This procedure is responsible for painting the focus rectangle. We don't want This procedure is responsible for painting the focus rectangle. We don't want
the red dashed rectangle here, but prefer the thick Excel-like black border the red dashed rectangle here, but prefer the thick Excel-like black border
line. line. This new focus rectangle is drawn by the method DrawSelection.
This new focus rectangle is drawn by the method DrawSelection. To turn off the
red dashed rectangle DrawFocusRect is just empty.
@param ACol Grid column index of the focused cell @param ACol Grid column index of the focused cell
@param ARow Grid row index of the focused cell @param ARow Grid row index of the focused cell
@ -1457,15 +1468,18 @@ end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
Draws a complete row of cells. Is mostly duplicated from Grids.pas, but adds Draws a complete row of cells. Is mostly duplicated from Grids.pas, but adds
code for merged cells and overflow text. code for merged cells and overflow text, the section on drawing the default
focus rectangle is removed.
@param ARow Index of the row to be drawn (index in grid coordinates)
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
procedure TsCustomWorksheetGrid.DrawRow(ARow: Integer); procedure TsCustomWorksheetGrid.DrawRow(ARow: Integer);
var var
gds: TGridDrawState; gds: TGridDrawState;
sr, sc, sr1,sc1,sr2,sc2: Cardinal; // sheet row/column sr, sc, sr1,sc1,sr2,sc2: Cardinal; // sheet row/column
gr, gc, gcNext, gcLast, gc1, gc2, gcLastUsed: Integer; // grid row/column gr, gc, gcNext, gcLast, gc1, gc2, gcLastUsed: Integer; // grid row/column
Rs: Boolean; i: Integer;
rct, saved_rct: TRect; rct, saved_rct, temp_rct: TRect;
clipArea: Trect; clipArea: Trect;
cell: PCell; cell: PCell;
tmp: Integer; tmp: Integer;
@ -1486,7 +1500,7 @@ var
result := (aRect.Left < bRect.Right) and (aRect.Right > bRect.Left); result := (aRect.Left < bRect.Right) and (aRect.Right > bRect.Left);
end; end;
procedure DoDrawCell(_col, _row: Integer); procedure DoDrawCell(_col, _row: Integer; _clipRect, _cellRect: TRect);
var var
Rgn: HRGN; Rgn: HRGN;
begin begin
@ -1501,9 +1515,9 @@ var
end; end;
Canvas.SaveHandleState; Canvas.SaveHandleState;
try try
Rgn := CreateRectRgn(rct.Left, rct.Top, rct.Right, rct.Bottom); Rgn := CreateRectRgn(_clipRect.Left, _clipRect.Top, _clipRect.Right, _clipRect.Bottom);
SelectClipRgn(Canvas.Handle, Rgn); SelectClipRgn(Canvas.Handle, Rgn);
DrawCell(_col, _row, rct, gds); DrawCell(_col, _row, _cellRect, gds);
DeleteObject(Rgn); DeleteObject(Rgn);
finally finally
Canvas.RestoreHandleState; Canvas.RestoreHandleState;
@ -1597,14 +1611,40 @@ begin
begin begin
// single cell // single cell
FDrawingCell := cell; FDrawingCell := cell;
// Special treatment of overflowing cells
if FTextOverflow then if FTextOverflow then
begin begin
gds := GetGridDrawState(gc, gr); gds := GetGridDrawState(gc, gr);
ColRowToOffset(true, true, gc, rct.Left, rct.Right); ColRowToOffset(true, true, gc, rct.Left, rct.Right);
if CellOverflow(gc, gr, gds, gc1, gc2, rct) then if CellOverflow(gc, gr, gds, gc1, gc2, rct) then
begin begin
gc := gc1; // Draw individual cells of the overflown range
gcNext := gc + (gc2 - gc1) + 1; ColRowToOffset(true, true, gc1, rct.Left, tmp); // rct is the clip rect
ColRowToOffset(true, true, gc2, tmp, rct.Right);
FDrawingCell := nil;
temp_rct := rct;
for i := gc1 to gc2 do begin
ColRowToOffset(true, true, i, temp_rct.Left, temp_rct.Right);
if HorizontalIntersect(temp_rct, clipArea) and (i <> gc) then
begin
gds := GetGridDrawState(i, gr);
DoDrawCell(i, gr, rct, temp_rct);
end;
end;
// Repaint the base cell text (it was partly overwritten before)
FDrawingCell := cell;
FTextOverflowing := true;
ColRowToOffset(true, true, gc, temp_rct.Left, temp_rct.Right);
if HorizontalIntersect(temp_rct, clipArea) then
begin
gds := GetGridDrawState(gc, gr);
DoDrawCell(gc, gr, rct, temp_rct);
end;
FTextOverflowing := false;
gcNext := gc2 + 1;
gc := gcNext;
continue;
end; end;
end; end;
end end
@ -1626,29 +1666,13 @@ begin
if (rct.Left < rct.Right) and HorizontalIntersect(rct, clipArea) then if (rct.Left < rct.Right) and HorizontalIntersect(rct, clipArea) then
begin begin
Rs := (goRowSelect in Options);
gds := GetGridDrawState(gc, gr); gds := GetGridDrawState(gc, gr);
DoDrawCell(gc, gr); DoDrawCell(gc, gr, rct, rct);
end; end;
gc := gcNext; gc := gcNext;
end; end;
end; // with GCache.VisibleGrid ...
// Draw the focus Rect
if FocusRectVisible and (ARow = Row) and
(( Rs and (ARow >= Top) and (ARow <= Bottom)) or IsCellVisible(Col, ARow))
then begin
if EditorMode then begin
//if EditorAlwaysShown and (FEditor<>nil) and FEditor.Visible then begin
//DebugLn('No Draw Focus Rect');
end else begin
ColRowToOffset(true, true, Col, rct.Left, rct.Right);
// is this column within the ClipRect?
if HorizontalIntersect(rct, clipArea) then
DrawFocusRect(Col, Row, rct);
end;
end;
end;
// Draw Fixed Columns // Draw Fixed Columns
gr := ARow; gr := ARow;
@ -1662,7 +1686,7 @@ begin
FDrawingCell := FWorksheet.FindCell(GetWorksheetRow(gr), GetWorksheetCol(gc)) FDrawingCell := FWorksheet.FindCell(GetWorksheetRow(gr), GetWorksheetCol(gc))
else else
FDrawingCell := nil; FDrawingCell := nil;
DoDrawCell(gc, gr); DoDrawCell(gc, gr, rct, rct);
end; end;
end; end;
end; end;
@ -1726,14 +1750,7 @@ begin
lCell := nil lCell := nil
else else
lCell := FDrawingCell; lCell := FDrawingCell;
{
c := ACol - FHeaderCount;
r := ARow - FHeaderCount;
if (r >= 0) and (c >= 0) then
lCell := FWorksheet.FindCell(r, c)
else
lCell := nil;
}
// Header // Header
if lCell = nil then if lCell = nil then
begin begin
@ -2631,6 +2648,7 @@ begin
Canvas.Font.Orientation := 0; Canvas.Font.Orientation := 0;
ts := Canvas.TextStyle; ts := Canvas.TextStyle;
ts.Opaque := false; ts.Opaque := false;
ts.Clipping := not FTextOverflowing;
if wrapped then begin if wrapped then begin
ts.Wordbreak := true; ts.Wordbreak := true;
ts.SingleLine := false; ts.SingleLine := false;