/// <summary> /// This predicate is true if it is permissible to connect a link to a given node/port. /// </summary> /// <param name="tonode"></param> /// <param name="toport"></param> /// <returns> /// False if the <paramref name="tonode"/> is in a <see cref="Layer"/> that does not <see cref="Layer.AllowLink"/>. /// False if <see cref="Node.GetLinkableTo"/> for the <paramref name="toport"/> is either false or null. /// False if the number of links connected to the <paramref name="toport"/> would exceed the <see cref="Node.GetLinkableMaximum"/> value. /// Otherwise true. /// </returns> public virtual bool IsValidTo(Node tonode, FrameworkElement toport) { if (tonode == null || toport == null) { var lmodel = this.Diagram.Model as ILinksModel; return (lmodel != null && lmodel.ValidUnconnectedLinks == ValidUnconnectedLinks.Allowed); } if (tonode.Layer != null && !tonode.Layer.AllowLink) return false; if (Node.GetLinkableTo(toport) != true) return false; // false or null value means not linkable int maxlinks = Node.GetLinkableMaximum(toport); if (maxlinks < int.MaxValue) { //??? wrong number, because RelinkingTool doesn't temporarily disconnect? if (this.OriginalLink != null && tonode == this.OriginalToNode && toport == this.OriginalToPort) return true; if (tonode.FindLinksConnectedWithPort(tonode.GetPortName(toport)).Count() >= maxlinks) return false; } return true; }
/// <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); } }
/// <summary> /// This predicate is true if it is permissible to connect a link from a given node/port. /// </summary> /// <param name="fromnode"></param> /// <param name="fromport"></param> /// <returns> /// False if the <paramref name="fromnode"/> is in a <see cref="Layer"/> that does not <see cref="Layer.AllowLink"/>. /// False if <see cref="Node.GetLinkableFrom"/> for the <paramref name="fromport"/> is either false or null. /// False if the number of links connected to the <paramref name="fromport"/> would exceed the <see cref="Node.GetLinkableMaximum"/> value. /// Otherwise true. /// </returns> public virtual bool IsValidFrom(Node fromnode, FrameworkElement fromport) { if (fromnode == null || fromport == null) return false; if (fromnode.Layer != null && !fromnode.Layer.AllowLink) return false; if (Node.GetLinkableFrom(fromport) != true) return false; // false or null value means not linkable int maxlinks = Node.GetLinkableMaximum(fromport); if (maxlinks < Int32.MaxValue) { //??? wrong number, because RelinkingTool doesn't temporarily disconnect? if (this.OriginalLink != null && fromnode == this.OriginalFromNode && fromport == this.OriginalFromPort) return true; if (fromnode.FindLinksConnectedWithPort(fromnode.GetPortName(fromport)).Count() >= maxlinks) return false; } return true; }