/// <summary> /// Unlink the node removing it from its origin linked nodes list and restore it to its /// original node class. /// </summary> public void UnlinkNode() { LinkedNodeViewModel linkedNode = (LinkedNodeViewModel)this; linkedNode.Origin.LinkedNodes.Remove(linkedNode); NestedConfigNode parent = (NestedConfigNode)linkedNode.m_parent; ConfigNodeViewModel unlinkedNode = getInstance(m_parentExperiment, parent, linkedNode.nodeDefinition, m_parentExperiment.AppName); // Keep the content of the former ogirin node if (!(linkedNode.Origin is ForkedNodeViewModel)) { unlinkedNode.content = linkedNode.Origin.content; } else { ForkedNodeViewModel forkedNode = (ForkedNodeViewModel)linkedNode.LinkedNode; int valueIndex = int.Parse(forkedNode.currentValueIndex.Substring(0, 1)) - 1; ForkValueViewModel value = (ForkValueViewModel)forkedNode.children[valueIndex]; unlinkedNode.content = value.configNode.content; } // For node substitution We don't need the index in the whole tree just // the index in the parent children list int index = parent.children.IndexOf(linkedNode); parent.children.Remove(linkedNode); parent.children.Insert(index, unlinkedNode); unlinkedNode.CanBeLinked = true; unlinkedNode.IsLinkable = false; }
/// <summary> /// Link nodes when experiment is loaded from a file. This has to be done once all nodes /// are loaded. /// </summary> private void LinkNodes() { var nodeStack = new Stack <ConfigNodeViewModel>(new[] { children[0] }); while (nodeStack.Any()) { ConfigNodeViewModel node = nodeStack.Pop(); if (node is LinkedNodeViewModel) { LinkedNodeViewModel linkedNode = (LinkedNodeViewModel)node; linkedNode.Origin = DepthFirstSearch(linkedNode.OriginName, linkedNode.OriginAlias); linkedNode.CreateLinkedNode(); linkedNode.LinkedNode.IsLinkable = false; linkedNode.LinkedNode.IsLinked = true; linkedNode.LinkedNode.IsNotLinked = false; // Add the node to origin linked nodes give the functionality to reflect content // changes of in all linked nodes linkedNode.Origin.LinkedNodes.Add(linkedNode.LinkedNode); if (linkedNode.Origin is ForkedNodeViewModel) { ForkedNodeViewModel forkedOrigin = (ForkedNodeViewModel)linkedNode.Origin; int len = forkedOrigin.children.Count; for (int i = 0; i < len; i++) { ForkedNodeViewModel linkedFork = (ForkedNodeViewModel)linkedNode.LinkedNode; ForkValueViewModel linkedForkValue = (ForkValueViewModel)linkedFork.children[i]; ((ForkValueViewModel)forkedOrigin.children[i]).configNode.LinkedNodes .Add(linkedForkValue.configNode); linkedForkValue.configNode.name = linkedNode.name; linkedForkValue.configNode.comment = linkedNode.comment; linkedForkValue.configNode.nodeDefinition = linkedNode.nodeDefinition; } } } WalkThroughBranch(ref nodeStack, node); } }
/// <summary> /// Actually perform the linking with the node. /// </summary> /// <param name="targetNode"></param> public void Link(ConfigNodeViewModel targetNode) { var linkedNode = new LinkedNodeViewModel(m_parentExperiment, m_parentExperiment.LinkOriginNode, targetNode); var node = m_parentExperiment.DepthFirstSearch(targetNode); NestedConfigNode parent = (NestedConfigNode)node.m_parent; // For node substitution we just need the index in the parent children list int index = parent.children.IndexOf(node); parent.children.Remove(node); parent.children.Insert(index, linkedNode); m_parentExperiment.LinkOriginNode.LinkedNodes.Add(linkedNode.LinkedNode); // If the origin is a ForkedNode we also need to link the fork values inside // this is for content changes reflection. if (m_parentExperiment.LinkOriginNode is ForkedNodeViewModel) { ForkedNodeViewModel forkedOrigin = (ForkedNodeViewModel)m_parentExperiment.LinkOriginNode; int len = forkedOrigin.children.Count; for (int i = 0; i < len; i++) { ForkedNodeViewModel linkedFork = (ForkedNodeViewModel)linkedNode.LinkedNode; ForkValueViewModel linkedForkValue = (ForkValueViewModel)linkedFork.children[i]; ((ForkValueViewModel)forkedOrigin.children[i]).configNode.LinkedNodes .Add(linkedForkValue.configNode); linkedForkValue.configNode.name = targetNode.name; linkedForkValue.configNode.comment = targetNode.comment; linkedForkValue.configNode.nodeDefinition = targetNode.nodeDefinition; } } linkedNode.LinkedNode.IsLinkable = false; linkedNode.LinkedNode.IsLinked = true; linkedNode.LinkedNode.IsNotLinked = false; }