Skip to content

Spec: Copy/Paste Between Files

Overview

Enable copying circuit fragments (components, wires, annotations, groups) from one circuit file and pasting them into another, enabling component reuse and design composition across documents.

Motivation

Designers frequently want to reuse sub-circuits across projects without creating formal macros. Copy/paste between files is the simplest and most intuitive way to share circuit fragments. Combined with tabbed multi-document, this becomes a natural workflow.

Requirements

Functional Requirements

  1. Cross-Document Copy: Copy selected elements from one circuit and paste into a different open circuit.
  2. Clipboard Format: Use a structured clipboard format that preserves component types, positions, connections, and properties.
  3. Wire Preservation: Wires connecting copied components are preserved; wires to non-copied components are trimmed.
  4. Relative Positioning: Pasted elements maintain their relative positions, placed at the cursor or canvas center.
  5. GUID Regeneration: Pasted elements receive new GUIDs to avoid conflicts with existing elements.
  6. Property Preservation: All component properties (propagation delay, label, configuration) are preserved.
  7. Group Preservation: If a group is fully selected, it pastes as a group.
  8. Duplicate Detection: Warn if pasting a component that already exists in the target (same label/position).
  9. External Paste: Support paste from system clipboard (serialized circuit fragment format).
  10. Cut Operation: Cut removes from source after copying to clipboard.
  11. Paste History: Optional paste history showing recent clipboard entries (Ctrl+Shift+V).

Non-Functional Requirements

  • Copy/paste handles up to 500 elements without noticeable delay.
  • Clipboard data is compact (serialized, not full canvas bitmaps).
  • Works across application instances (via system clipboard).

Design

Clipboard Data Format

csharp
public class CircuitClipboardData
{
    public string Version { get; set; }
    public List<ComponentData> Components { get; set; }
    public List<WireData> Wires { get; set; }
    public List<AnnotationData> Annotations { get; set; }
    public List<GroupData> Groups { get; set; }
    public Point ReferencePoint { get; set; }  // anchor for relative positioning
}

Serialized as JSON and placed on the system clipboard with a custom format identifier (e.g., DigitalWorks.CircuitFragment).

Paste Logic

1. Deserialize clipboard data.
2. Generate new GUIDs for all elements (maintain internal cross-references).
3. Remap wire endpoints to new component GUIDs.
4. Calculate offset from reference point to paste target.
5. Add elements to target circuit.
6. Select pasted elements for immediate repositioning.

Wire Handling

  • Wires where both endpoints are in the copied set → preserved.
  • Wires where one endpoint is outside the set → wire is trimmed (dangling end left open).
  • Junction points on trimmed wires are preserved.

Implementation Tasks

  1. Define CircuitClipboardData serialization format (JSON).
  2. Implement selection serialization (components + wires + annotations → clipboard data).
  3. Implement GUID regeneration with internal reference remapping.
  4. Implement paste logic with relative positioning.
  5. Implement wire trimming for partial selections.
  6. Register custom clipboard format with the system clipboard.
  7. Enable cross-instance paste (system clipboard serialization).
  8. Integrate with undo/redo (paste is one undoable action).
  9. Add paste preview ghost rendering before confirming position.
  10. Implement paste history (recent clipboard entries).

Risks & Open Questions

  • How to handle pasting components that reference macros not available in the target circuit?
  • Should paste auto-connect to nearby compatible pins?
  • System clipboard size limit for very large selections?
  • Should there be a "Paste Special" option (paste without wires, paste as macro)?

Priority

Medium — Natural complement to tabbed multi-document; enhances reuse workflows.