mirror of
https://github.com/radzenhq/radzen-blazor.git
synced 2026-07-08 18:16:08 +00:00
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.
83 lines
2.3 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|