Files
radzen-blazor/Radzen.Blazor/Spreadsheet/PasteCommand.cs
Atanas Korchev 40d0583987 Transfer the full cell state in spreadsheet paste, cut and autofill
Formats, quote prefixes and hyperlinks are now copied, empty source
cells blank their destinations and cut clears the source, matching
Excel. Entering a value over a formula cell replaces the formula, quote
prefixed entries store literal text and undo restores cells exactly as
captured, including after redo.

Breaking change: RangeSnapshotCommandBase snapshots cells as detached
clones (Dictionary<CellRef, Cell?>) instead of a value/formula/format
tuple.
2026-07-06 12:21:20 +03:00

83 lines
2.3 KiB
C#

using System.Collections.Generic;
using Radzen.Documents.Spreadsheet;
namespace Radzen.Blazor.Spreadsheet;
#nullable enable
// Snapshots overwritten destination cells (and, for a same-sheet cut, the cleared source cells)
// before the write, and captures the pasted result so redo can replay it without depending on
// the live clipboard. Batching comes from the UndoRedoStack.
class PasteCommand : RangeSnapshotCommandBase
{
private readonly SpreadsheetClipboard clipboard;
private readonly RangeRef destination;
private readonly string? text;
private readonly Dictionary<CellRef, Cell?> result = [];
private bool pasted;
public override SheetAction RequiredAction => SheetAction.EditCell;
public PasteCommand(SpreadsheetClipboard clipboard, Worksheet sheet, RangeRef destination, string? text)
: base(sheet)
{
this.clipboard = clipboard;
this.destination = destination;
this.text = text;
}
protected override bool DoExecute()
{
if (pasted)
{
// Redo: replay the captured result instead of re-running the (possibly consumed)
// clipboard. Execute cleared the snapshot, so re-capture it first or the next
// undo would have nothing to restore.
foreach (var cellRef in result.Keys)
{
Capture(cellRef);
}
Restore(result);
return true;
}
var destinationRange = clipboard.GetPasteRange(sheet, destination, text);
if (destinationRange == RangeRef.Invalid)
{
return false;
}
CaptureRange(destinationRange.GetCells());
if (clipboard.TryGetMoveSource(sheet, out var moveSource))
{
CaptureRange(moveSource.GetCells());
}
if (text is not null)
{
clipboard.Paste(sheet, destination, text);
}
else
{
clipboard.Paste(sheet, destination);
}
CaptureResult();
pasted = true;
return true;
}
public override void Unexecute() => RestoreSnapshot();
private void CaptureResult()
{
foreach (var cellRef in snapshot.Keys)
{
result[cellRef] = sheet.Cells.TryGet(cellRef.Row, cellRef.Column, out var cell) ? cell.Clone() : null;
}
}
}