Code: Select all
procedure TRVClipboardTableRectangle.CopyFromTable(ATable: TRVTableItemInfo);
var
Row, Col, RowSpan, ColSpan: Integer;
begin
if ATable = nil then
raise Exception.Create('ATable=nil in TRVClipboardTableRectangle.CopyCells().');
if ATable.GetNormalizedSelectionBounds(True, Row, Col, ColSpan, RowSpan) then
begin
FStartRow := Row;
FStartCol := Col;
FRowCount := RowSpan;
FColCount := ColSpan;
ATable.SaveRectangleToStream(FStream, FStartRow, FStartCol, FRowCount, FColCount, True, True);
end;
end;
procedure TRVClipboardTableRectangle.PasteToTable(ATable: TRVTableItemInfo; AEdit: TCustomRichViewEdit);
var
TempTable: TRVTableItemInfo;
StartRow, StartCol, RowSpan, ColSpan: Integer;
r, c, new_r, new_c: Integer;
CellStream: TMemoryStream;
Color: TRVColor;
Dummy1, Dummy2: Pointer;
SourceCell, TargetCell: TRVTableCellData;
CurR, CurC: Integer;
MainR, MainC: Integer;
begin
if ATable = nil then
raise Exception.Create('ATable=nil in TRVClipboardTableRectangle.PasteCells().');
if AEdit = nil then
raise Exception.Create('AEdit=nil in TRVClipboardTableRectangle.PasteCells().');
if not Active then Exit;
{ identify the starting coordinates where the data will be inserted }
if not ATable.GetNormalizedSelectionBounds(True, StartRow, StartCol, ColSpan, RowSpan) then
begin
if ATable.GetEditedCell(CurR, CurC) <> nil then
begin
StartRow := CurR;
StartCol := CurC;
end
else
Exit; { caret is out of table... }
end;
Color := clNone;
Dummy1 := nil;
Dummy2 := nil;
TempTable := TRVTableItemInfo.CreateEx(0, 0, AEdit.RVData);
CellStream := TMemoryStream.Create;
try
{ load source table rectangle }
FStream.Position := 0;
TempTable.LoadFromStream(FStream);
if (TempTable.RowCount = 0) or (TempTable.ColCount = 0) then Exit;
for r := 0 to TempTable.RowCount - 1 do
for c := 0 to TempTable.ColCount - 1 do
begin
SourceCell := TempTable.Cells[r, c];
if Assigned(SourceCell) then
begin
new_r := r + StartRow;
new_c := c + StartCol;
{ are we within the target table range? }
if (new_r >= ATable.RowCount) or (new_c >= ATable.ColCount) then
Continue;
{ merge target cells if source cell has ColSpan or RowSpan > 1 }
if (SourceCell.ColSpan > 1) or (SourceCell.RowSpan > 1) then
begin
{ ensure merged area fits within target table bounds }
if (new_r + SourceCell.RowSpan <= ATable.RowCount) and
(new_c + SourceCell.ColSpan <= ATable.ColCount) then
begin
ATable.MergeCells(new_r, new_c, SourceCell.ColSpan, SourceCell.RowSpan, True);
end;
end;
ATable.Rows.GetMainCell(new_r, new_c, MainR, MainC);
if (MainR >= 0) and (MainC >= 0) and (new_r = MainR) and (new_c = MainC) then
begin
TargetCell := ATable.Cells[MainR, MainC];
if Assigned(TargetCell) then
begin
{ copy RVF data of the source cell }
CellStream.Clear;
SourceCell.SaveRVFToStream(CellStream, False, clNone, nil, nil);
{ insert RVF data to the target cell }
CellStream.Position := 0;
TargetCell.Clear;
TargetCell.InsertRVFFromStream(CellStream, 0, Color, Dummy1, Dummy2, True, nil, nil);
TargetCell.Normalize;
{ copy cell properties }
ATable.SetCellColor(SourceCell.Color, new_r, new_c);
ATable.SetCellOpacity(SourceCell.Opacity, new_r, new_c);
ATable.SetCellVAlign(SourceCell.VAlign, new_r, new_c);
ATable.SetCellBackgroundStyle(SourceCell.BackgroundStyle, new_r, new_c);
ATable.SetCellHint(SourceCell.Hint, new_r, new_c);
ATable.SetCellRotation(SourceCell.Rotation, new_r, new_c);
ATable.SetCellOptions(SourceCell.Options, new_r, new_c);
ATable.SetCellTag(SourceCell.Tag, new_r, new_c);
if Assigned(SourceCell.BackgroundImage) then
ATable.SetCellBackgroundImage(SourceCell.BackgroundImage, new_r, new_c);
end;
end;
end;
end;
finally
CellStream.Free;
TempTable.Free;
end;
ATable.Changed;
end;