private bool LinkableToStationaryNode(Node n, Node stationary) { if (n == null) return false; if (n == stationary) return false; // shouldn't happen, but might as well check anyway var links = n.LinksOutOf.ToList(); if (links.Count > 1) return false; //?? multiple links: disallow Link relink = null; if (links.Count == 1) { // one link: relink if not connected with a dragged node relink = links.First(); Node other = relink.ToNode; // assume IsValidLink will check for relink valid if (other != null && other.IsSelected) return false; } // zero links: new link, assume IsValidLink will check for new link valid // ignore all nodes that are members of a selected Group if (this.Diagram.SelectedParts.OfType<Group>().Any(g => n.IsContainedBy(g))) return false; return IsValidLink(n, stationary, relink); }
/// <summary> /// This predicate should be true when it is logically valid to connect a link from /// one node/port to another node/port. /// </summary> /// <param name="fromnode">the "from" <see cref="Node"/></param> /// <param name="fromport">the "from" <c>FrameworkElement</c></param> /// <param name="tonode">the "to" <see cref="Node"/> (perhaps the same as <paramref name="fromnode"/>)</param> /// <param name="toport">the "to" <c>FrameworkElement</c> (perhaps the same as <paramref name="fromport"/>)</param> /// <returns> /// False if <see cref="IsValidFrom"/> is false for the <paramref name="fromnode"/> and <paramref name="fromport"/>. /// False if <see cref="IsValidTo"/> is false for the <paramref name="tonode"/> and <paramref name="toport"/>. /// False if <see cref="IsInSameNode"/> is true unless <see cref="Node.GetLinkableSelfNode"/> is true for both ports. /// False if <see cref="IsLinked"/> is true unless <see cref="Node.GetLinkableDuplicates"/> is true for both ports. /// False if trying to link to the link's own label node(s). /// False if <see cref="IDiagramModel.IsLinkValid"/> or one of the model-specific <c>IsRelinkValid</c> methods is false, /// depending on whether <see cref="OriginalLink"/> is null (a new link) or non-null (a relink). /// Otherwise true. /// </returns> public virtual bool IsValidLink(Node fromnode, FrameworkElement fromport, Node tonode, FrameworkElement toport) { if (this.Diagram == null || this.Diagram.PartManager == null) return false; //?? allow partly connected or unconnected links if (!IsValidFrom(fromnode, fromport)) return false; if (!IsValidTo(tonode, toport)) return false; if (fromport != null && toport != null) { if (!(Node.GetLinkableSelfNode(fromport) && Node.GetLinkableSelfNode(toport)) && IsInSameNode(fromport, toport)) return false; if (!(Node.GetLinkableDuplicates(fromport) && Node.GetLinkableDuplicates(toport)) && IsLinked(fromport, toport)) return false; } // disallow linking to the link's own label(s) if (this.OriginalLink != null) { if (fromnode != null && fromnode.IsContainedBy(this.OriginalLink)) return false; if (tonode != null && tonode.IsContainedBy(this.OriginalLink)) return false; } Object fromdata = (fromnode != null ? fromnode.Data : null); Object fromid = (fromnode != null ? fromnode.GetPortName(fromport) : null); Object todata = (tonode != null ? tonode.Data : null); Object toid = (tonode != null ? tonode.GetPortName(toport) : null); IDiagramModel model = this.Diagram.PartManager.FindCommonDataModel(fromdata, todata); if (model == null) { if (fromnode != null) model = fromnode.Model; else if (tonode != null) model = tonode.Model; var lmodel = model as ILinksModel; if (lmodel == null || lmodel.ValidUnconnectedLinks == ValidUnconnectedLinks.None) return false; // if the model allows unconnected links, it's OK } if (this.OriginalLink != null) { ILinksModel lmodel = model as ILinksModel; if (lmodel != null) return lmodel.IsRelinkValid(fromdata, fromid, todata, toid, this.OriginalLink.Data); IConnectedModel cmodel = model as IConnectedModel; if (cmodel != null) return cmodel.IsRelinkValid(fromdata, todata, this.OriginalLink.FromData, this.OriginalLink.ToData); ITreeModel tmodel = model as ITreeModel; if (tmodel != null) return tmodel.IsRelinkValid(fromdata, todata, this.OriginalLink.FromData, this.OriginalLink.ToData); return false; } else { return model.IsLinkValid(fromdata, fromid, todata, toid); } }
private bool LinkableFromStationaryNode(Node n, Dictionary<Part, Info> dragged, Node stationary) { if (n == null) return false; if (n == stationary) return false; // shouldn't happen, but might as well check anyway var links = n.LinksInto.ToList(); if (links.Count > 1) return false; //?? multiple links: disallow Link relink = null; if (links.Count == 1) { // one link: relink if not connected with a dragged node relink = links.First(); Node other = relink.FromNode; // assume IsValidLink will check for relink valid if (other != null && dragged.ContainsKey(other)) return false; } // zero links: new link, only need to check IsValidLink // ignore all nodes that are members of a dragged Group if (dragged.OfType<Group>().Any(g => n.IsContainedBy(g))) return false; return IsValidLink(stationary, n, relink); }