Skip to content

Commit b5b77e5

Browse files
authored
DYN-10235: Allow copy/paste of pinned wire connections (DynamoDS#16944)
1 parent d51e3bd commit b5b77e5

File tree

2 files changed

+111
-11
lines changed

2 files changed

+111
-11
lines changed

src/DynamoCore/Models/DynamoModel.cs

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3186,6 +3186,15 @@ var el in
31863186

31873187
ClipBoard.AddRange(connectors);
31883188
}
3189+
3190+
var connectorPins = ClipBoard
3191+
.OfType<ConnectorModel>()
3192+
.SelectMany(connector => connector.ConnectorPinModels)
3193+
.Where(pin => !ClipBoard.Contains(pin))
3194+
.Cast<ModelBase>()
3195+
.ToList();
3196+
3197+
ClipBoard.AddRange(connectorPins);
31893198
}
31903199

31913200
/// <summary>
@@ -3235,6 +3244,7 @@ public void Paste(Point2D targetPoint, bool useOffset = true)
32353244

32363245
var nodes = ClipBoard.OfType<NodeModel>();
32373246
var connectors = ClipBoard.OfType<ConnectorModel>();
3247+
var connectorPins = ClipBoard.OfType<ConnectorPinModel>();
32383248
var notes = ClipBoard.OfType<NoteModel>();
32393249
// we only want to get groups that either has nested groups
32403250
// or does not belong to a group here.
@@ -3329,27 +3339,59 @@ public void Paste(Point2D targetPoint, bool useOffset = true)
33293339

33303340
ModelBase start;
33313341
ModelBase end;
3332-
var newConnectors =
3333-
from c in connectors
33343342

3335-
// If the guid is in nodeLookup, then we connect to the new pasted node. Otherwise we
3336-
// re-connect to the original.
3337-
let startNode =
3343+
var newConnectors = new List<ConnectorModel>();
3344+
var connectorLookup = new Dictionary<Guid, ConnectorModel>();
3345+
foreach (var c in connectors)
3346+
{
3347+
// If the guid is in nodeLookup, then we connect to the new pasted node. Otherwise we
3348+
// re-connect to the original.
3349+
var startNode =
33383350
modelLookup.TryGetValue(c.Start.Owner.GUID, out start)
33393351
? start as NodeModel
3340-
: CurrentWorkspace.Nodes.FirstOrDefault(x => x.GUID == c.Start.Owner.GUID)
3341-
let endNode =
3352+
: CurrentWorkspace.Nodes.FirstOrDefault(x => x.GUID == c.Start.Owner.GUID);
3353+
var endNode =
33423354
modelLookup.TryGetValue(c.End.Owner.GUID, out end)
33433355
? end as NodeModel
3344-
: CurrentWorkspace.Nodes.FirstOrDefault(x => x.GUID == c.End.Owner.GUID)
3356+
: CurrentWorkspace.Nodes.FirstOrDefault(x => x.GUID == c.End.Owner.GUID);
33453357

33463358
// Don't make a connector if either end is null.
3347-
where startNode != null && endNode != null
3348-
select
3349-
ConnectorModel.Make(startNode, endNode, c.Start.Index, c.End.Index);
3359+
if (startNode == null || endNode == null)
3360+
{
3361+
continue;
3362+
}
3363+
var newConnector = ConnectorModel.Make(startNode, endNode, c.Start.Index, c.End.Index);
3364+
if (newConnector != null)
3365+
{
3366+
newConnectors.Add(newConnector);
3367+
connectorLookup.Add(c.GUID, newConnector);
3368+
}
3369+
}
33503370

33513371
createdModels.AddRange(newConnectors);
33523372

3373+
var newConnectorPins = new List<ConnectorPinModel>();
3374+
foreach (var pin in connectorPins)
3375+
{
3376+
if (!connectorLookup.TryGetValue(pin.ConnectorId, out var connector))
3377+
{
3378+
continue;
3379+
}
3380+
3381+
var copiedPin = new ConnectorPinModel
3382+
(
3383+
pin.Position.X + shiftX + offset,
3384+
pin.Position.Y + shiftY + offset,
3385+
Guid.NewGuid(),
3386+
connector.GUID
3387+
);
3388+
3389+
connector.AddPin(copiedPin);
3390+
newConnectorPins.Add(copiedPin);
3391+
}
3392+
3393+
createdModels.AddRange(newConnectorPins);
3394+
33533395
//Grouping depends on the selected node models.
33543396
//so adding the group after nodes / notes are added to workspace.
33553397
//select only those nodes that are part of a group.
@@ -3399,6 +3441,12 @@ from c in connectors
33993441
AddToSelection(item);
34003442
}
34013443

3444+
// Keep connector pins selected together with the pasted graph chunk
3445+
foreach (var connectorPin in newConnectorPins)
3446+
{
3447+
AddToSelection(connectorPin);
3448+
}
3449+
34023450
DynamoSelection.Instance.ClearSelectionDisabled = false;
34033451

34043452
// Record models that are created as part of the command.

test/DynamoCoreTests/CoreTests.cs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,58 @@ public void CanCopyAndPaste2NodesWithRightOffset()
575575
Assert.AreEqual(27, CurrentDynamoModel.CurrentWorkspace.Nodes.ElementAt(3).Y);
576576
}
577577

578+
[Test]
579+
[Category("UnitTests")]
580+
public void CanCopyAndPasteConnectorPinsWithConnectors()
581+
{
582+
var numberNode = new DoubleInput();
583+
numberNode.Height = 2;
584+
numberNode.Width = 2;
585+
numberNode.CenterX = 100;
586+
numberNode.CenterY = 100;
587+
588+
var watchNode = new Watch();
589+
watchNode.Height = 2;
590+
watchNode.Width = 2;
591+
watchNode.CenterX = 350;
592+
watchNode.CenterY = 100;
593+
594+
CurrentDynamoModel.CurrentWorkspace.AddAndRegisterNode(numberNode, false);
595+
CurrentDynamoModel.CurrentWorkspace.AddAndRegisterNode(watchNode, false);
596+
597+
var connector = ConnectorModel.Make(numberNode, watchNode, 0, 0);
598+
Assert.IsNotNull(connector);
599+
600+
var originalPin = new ConnectorPinModel(225, 100, Guid.NewGuid(), connector.GUID);
601+
connector.ConnectorPinModels.Add(originalPin);
602+
603+
CurrentDynamoModel.AddToSelection(numberNode);
604+
CurrentDynamoModel.AddToSelection(watchNode);
605+
CurrentDynamoModel.AddToSelection(connector);
606+
CurrentDynamoModel.AddToSelection(originalPin);
607+
608+
CurrentDynamoModel.Copy();
609+
610+
Assert.AreEqual(1, CurrentDynamoModel.ClipBoard.OfType<ConnectorModel>().Count());
611+
Assert.AreEqual(1, CurrentDynamoModel.ClipBoard.OfType<ConnectorPinModel>().Count());
612+
613+
var originalConnectorCount = CurrentDynamoModel.CurrentWorkspace.Connectors.Count();
614+
615+
CurrentDynamoModel.Paste();
616+
617+
Assert.AreEqual(4, CurrentDynamoModel.CurrentWorkspace.Nodes.Count());
618+
Assert.AreEqual(originalConnectorCount + 1, CurrentDynamoModel.CurrentWorkspace.Connectors.Count());
619+
Assert.AreEqual(1, DynamoSelection.Instance.Selection.OfType<ConnectorPinModel>().Count());
620+
621+
var copiedConnector = CurrentDynamoModel.CurrentWorkspace.Connectors
622+
.First(c => c.GUID != connector.GUID);
623+
Assert.AreEqual(1, copiedConnector.ConnectorPinModels.Count);
624+
625+
var copiedPin = copiedConnector.ConnectorPinModels.Single();
626+
Assert.AreEqual(copiedConnector.GUID, copiedPin.ConnectorId);
627+
Assert.That(copiedPin.GUID, Is.Not.EqualTo(originalPin.GUID));
628+
}
629+
578630
[Test]
579631
[Category("UnitTests"), Category("Slow")]
580632
public void CanAdd100NodesToClipboardAndPaste3Times()

0 commit comments

Comments
 (0)