public virtual void AddRootShapesForElement(DomainModelElement modelElement)//, bool bIgnoreVisualizationBehavior) { DiagramDomainDataDirectory data = modelElement.Store.DomainDataAdvDirectory.ResolveExtensionDirectory <DiagramDomainDataDirectory>(); IDomainModelServices topMost = modelElement.GetDomainModelServices().TopMostService; List <Guid> shapeIds = data.GetRootShapeTypesForElement(modelElement.GetDomainClassId()); if (shapeIds != null) { foreach (Guid shapeId in shapeIds) { ShapeClassInfo shapeInfo = data.ShapeClassInfos[shapeId]; ReadOnlyCollection <ModelElement> diagrams = modelElement.Store.ElementDirectory.FindElements(shapeInfo.DiagramClassType); if (diagrams.Count == 0) { continue; } foreach (Diagram d in diagrams) { if (d.IsVisible && d.CanHostShape(shapeId)) { if (!DiagramHelper.IsElementDisplayedOn(d, shapeId, modelElement.Id)) { NodeShape shape = topMost.ShapeProvider.CreateShapeForElement(shapeId, modelElement) as NodeShape; d.Children.Add(shape); DiagramsShapeStore.AddToStore(shape.Element.Id, shape.Id); shape.FixUpMissingLinkShapes(); } } } } } }
/// <summary> /// Verifies if the current shape can host a shape of a specific type. /// </summary> /// <param name="nodeShapeDomainClassId">Type of the shape specified by the domain class ID.</param> /// <returns>True if that specific type of shapes can be hosted by this shape. False otherwise.</returns> public virtual bool CanHostShape(Guid nodeShapeDomainClassId) { DiagramDomainDataDirectory data = this.Store.DomainDataAdvDirectory.ResolveExtensionDirectory <DiagramDomainDataDirectory>(); if (data == null) { throw new ArgumentNullException("DiagramDomainDataDirectory can not be null"); } List <Guid> vals = data.GetDiagramRootChildrenShapeTypes(this.GetDomainClass().Id); if (vals.Contains(nodeShapeDomainClassId)) { return(true); } foreach (Diagram d in this.IncludedDiagrams) { if (d.CanHostShape(nodeShapeDomainClassId)) { return(true); } } return(false); }
public virtual void AddRSShapesForElement(DomainModelLink modelElement) { if (modelElement == null) { return; } DiagramDomainDataDirectory data = modelElement.Store.DomainDataAdvDirectory.ResolveExtensionDirectory <DiagramDomainDataDirectory>(); if (data == null) { throw new ArgumentNullException("DiagramDomainDataDirectory"); } List <Guid> shapes = data.GetShapeTypesForElement(modelElement.GetDomainClassId()); if (shapes != null) { if (shapes.Count > 0) { DomainModelElement source = DomainRoleInfo.GetSourceRolePlayer(modelElement) as DomainModelElement; DomainModelElement target = DomainRoleInfo.GetTargetRolePlayer(modelElement) as DomainModelElement; foreach (Guid shape in shapes) { AddRSShapesForElement(source, target, modelElement, shape); } } } }
public void DeleteShapesForElement(DomainModelLink element) { if (element == null) { return; } DomainModelLink link = element; DiagramDomainDataDirectory data = link.Store.DomainDataAdvDirectory.ResolveExtensionDirectory <DiagramDomainDataDirectory>(); DomainModelElement m = DomainRoleInfo.GetSourceRolePlayer(link) as DomainModelElement; List <Guid> shapes = data.GetShapeTypesForElement(m.GetDomainClassId()); if (shapes == null) { return; } foreach (Guid g in shapes) { if (data.MappingRelationshipShapeInfos.ContainsKey(g)) { this.DeleteShapesForElement(m.Store, m.Id, g); return; } } }
/* * /// <summary> * /// Tries to find a free position on parent and update the location of the shape to that location. * /// </summary> * /// <returns> * /// Coordinates of a free position. * /// </returns> * /// <remarks> * /// Needs to be called within a modeling transaction. * /// </remarks> * public virtual void SetAtFreePositionOnParent() * { * IList<NodeShape> shapes; * if (this.Parent == null) * { * // free position on diagram * Diagram diagram = this.Diagram; * shapes = diagram.Children; * } * else * { * if (this.IsRelativeChildShape) * { * float width = (float)this.Bounds.Width; * float height = (float)this.Bounds.Height; * * float parentWidth = (float)this.Parent.Bounds.Width; * float parentHeight = (float)this.Parent.Bounds.Height; * * Dictionary<PortPlacement, int> dict = new Dictionary<PortPlacement, int>(); * dict.Add(PortPlacement.Left, 0); * dict.Add(PortPlacement.Top, 0); * dict.Add(PortPlacement.Bottom, 0); * dict.Add(PortPlacement.Right, 0); * for (int i = 0; i < this.Parent.RelativeChildren.Count; i++) * { * if (this.Parent.RelativeChildren[i] == this) * continue; * * dict[this.Parent.RelativeChildren[i].PlacementSide]++; * } * List<KeyValuePair<PortPlacement, int>> myList = new List<KeyValuePair<PortPlacement, int>>(dict); * myList.Sort((firstPair, nextPair) => * { * return firstPair.Value.CompareTo(nextPair.Value); * }); * * foreach (KeyValuePair<PortPlacement, int> p in myList) * { * RectangleF rectH; * switch (p.Key) * { * case PortPlacement.Left: * rectH = new RectangleF(-width / 2, 0, width, parentHeight); * break; * * case PortPlacement.Top: * rectH = new RectangleF(0, -height / 2, parentWidth, height); * break; * * case PortPlacement.Right: * rectH = new RectangleF(parentWidth - width / 2, 0, width, parentHeight); * break; * * case PortPlacement.Bottom: * rectH = new RectangleF(0, parentHeight - height / 2, parentWidth, height); * break; * * default: * throw new NotSupportedException(); * } * * if (SetPortAtFreePositionOnParent(p.Key, rectH)) * { * return; * } * } * * this.SetLocation(NodeShape.CorrectPortLocation(this.Parent, this, new PointD(0, 0))); * return; * } * * // free position on parent shape * shapes = this.Parent.NestedChildren; * } * * // trivial algo.. TODO: find something good * RectangleF rect = new RectangleF(0, 0, (float)this.Size.Width, (float)this.Size.Height); * * // find area that is already filled * RectangleF completeBounds = new RectangleF(0, 0, 0, 0); * for (int i = 0; i < shapes.Count; i++) * { * if (shapes[i] == this) * continue; * * if (i == 0) * completeBounds = shapes[i].Bounds.ToRectangleF(); * else * { * RectangleF f = shapes[i].Bounds.ToRectangleF(); * if (completeBounds.X > f.X) * completeBounds.X = f.X; * if (completeBounds.Y > f.Y) * completeBounds.Y = f.Y; * * if (completeBounds.Right < f.Right) * completeBounds.Width = f.Right - completeBounds.X; * * if (completeBounds.Bottom < f.Bottom) * completeBounds.Height = f.Bottom - completeBounds.Y; * } * } * * /* * // see if we can insert shape somewhere in that area * // if not, add shape right at the edge of that area * for (int i = 0; i < shapes.Count; i++) * { * if (shapes[i] == this) * continue; * * // TODO ... (not necessaraly required) * } * * // could not add shape in the completeBounds are, so add it outside of it */ /* * if( completeBounds.Width < completeBounds.Height ) * this.SetLocation(new PointD(completeBounds.Right + 5, 5)); * else * this.SetLocation(new PointD(5, completeBounds.Bottom + 5)); * this.UpdateAbsoluteLocation(); * } * * private bool SetPortAtFreePositionOnParent(PortPlacement side, RectangleF freeRectangle) * { * List<RectangleF> freeRectangles = new List<RectangleF>(); * freeRectangles.Add(freeRectangle); * * for (int i = 0; i < this.Parent.RelativeChildren.Count; i++) * { * if (this.Parent.RelativeChildren[i] == this) * continue; * * if (this.Parent.RelativeChildren[i].PlacementSide != side) * continue; * * RectangleF s = this.Parent.RelativeChildren[i].Bounds.ToRectangleF(); * for (int y = freeRectangles.Count - 1; y >= 0; y--) * { * RectangleF r = freeRectangles[y]; * RectangleF t = r; * r.Intersect(s); * * if (!r.IsEmpty) * { * // remove r from freeRectangley[y] --> yields <=2 rects * // add 2 rects to freeRectangles * freeRectangles.RemoveAt(y); * * switch (side) * { * case PortPlacement.Left: * case PortPlacement.Right: * if (t.Y < r.Y) * { * // first r * RectangleF r1 = new RectangleF(t.X, t.Y, t.Width, r.Y - t.Y); * freeRectangles.Add(r1); * } * * if (r.Bottom < t.Bottom) * { * // second r * RectangleF r2 = new RectangleF(t.X, r.Bottom, t.Width, t.Bottom - r.Bottom); * freeRectangles.Add(r2); * } * break; * * case PortPlacement.Top: * case PortPlacement.Bottom: * if (t.X < r.X) * { * // first r * RectangleF r1 = new RectangleF(t.X, t.Y, r.X-t.X, t.Height); * freeRectangles.Add(r1); * } * * if (r.Right < t.Right) * { * // second r * RectangleF r2 = new RectangleF(r.Right, t.Y, t.Right-r.Right, t.Height); * freeRectangles.Add(r2); * } * break; * } * * } * } * } * * // try to place at a fitting free rectangle * foreach (RectangleF r in freeRectangles) * { * if (r.Width >= this.Bounds.Width && r.Height >= this.Bounds.Height) * { * this.Location = new PointD(r.X, r.Y); * this.PlacementSide = side; * this.UpdateAbsoluteLocation(); * return true; * } * } * * return false; * } */ /// <summary> /// Create missing shapes. /// </summary> public virtual void FixUpMissingShapes() { if (this.Element == null) { return; } DomainModelElement e = this.Element as DomainModelElement; IDomainModelServices topMost = e.GetDomainModelServices().TopMostService; DiagramDomainDataDirectory data = this.Store.DomainDataAdvDirectory.ResolveExtensionDirectory <DiagramDomainDataDirectory>(); List <EmbeddingRelationshipAdvancedInfo> infos = this.Store.DomainDataAdvDirectory.FindDomainClassSourceEmbeddings(e.GetDomainClassId()); if (infos != null) { foreach (EmbeddingRelationshipAdvancedInfo info in infos) { List <Guid> shapes = data.GetShapeTypesForElement(info.TargetElementDomainClassId); if (shapes == null) { continue; } if (shapes.Count == 0) { continue; } ReadOnlyCollection <ElementLink> instances = DomainRoleInfo.GetElementLinks <ElementLink>(this.Element, info.SourceRoleId); foreach (ElementLink link in instances) { DomainModelElement child = DomainRoleInfo.GetTargetRolePlayer(link) as DomainModelElement; if (child == null) { continue; } // see if we need to add shape foreach (Guid elementShapeId in data.GetShapeTypesForElement(child.GetDomainClassId(), this.GetDomainClassId())) { if (!DiagramHelper.IsElementDisplayedOn(this, elementShapeId, child.Id)) { NodeShape shape = topMost.ShapeProvider.CreateShapeForElement(elementShapeId, child) as NodeShape; if (shape.IsRelativeChildShape) { this.AddRelativeChild(shape); } else { this.AddNestedChild(shape); } shape.FixUpMissingShapes(); } } } } } }
public void DeleteShapesForElement(DomainModelLink element) { if (element == null) { return; } DomainModelLink link = element; DiagramDomainDataDirectory data = link.Store.DomainDataAdvDirectory.ResolveExtensionDirectory <DiagramDomainDataDirectory>(); if (data.HasShapeForElement(link.GetDomainClassId())) { this.DeleteShapesForElement(link.Store, link.Id); } }
public virtual void AddMappingRSShapesForElement(DomainModelElement modelElement) { if (modelElement == null) { return; } DiagramDomainDataDirectory data = modelElement.Store.DomainDataAdvDirectory.ResolveExtensionDirectory <DiagramDomainDataDirectory>(); if (data == null) { throw new ArgumentNullException("DiagramDomainDataDirectory"); } List <Guid> shapes = data.GetShapeTypesForElement(modelElement.GetDomainClassId()); if (shapes == null) { return; } foreach (Guid g in shapes) { if (data.MappingRelationshipShapeInfos.ContainsKey(g)) { MappingRelationshipShapeInfo info = data.MappingRelationshipShapeInfos[g]; // see if the required relationships exist ReadOnlyCollection <ElementLink> colSource = DomainRoleInfo.GetElementLinks <ElementLink>(modelElement, info.SourceDomainRole); if (colSource.Count != 1) { return; } ReadOnlyCollection <ElementLink> colTarget = DomainRoleInfo.GetElementLinks <ElementLink>(modelElement, info.TargetDomainRole); if (colTarget.Count != 1) { return; } DomainModelElement source = DomainRoleInfo.GetTargetRolePlayer(colSource[0]) as DomainModelElement; DomainModelElement target = DomainRoleInfo.GetTargetRolePlayer(colTarget[0]) as DomainModelElement; AddRSShapesForElement(source, target, modelElement, g); } } }
/// <summary> /// Adds shapes for a given element. /// </summary> /// <param name="parent">Model element.</param> /// <param name="child"></param> internal void AddShapesForElement(DomainModelElement parent, DomainModelElement child) { if (parent == null || child == null) { return; } DiagramDomainDataDirectory data = child.Store.DomainDataAdvDirectory.ResolveExtensionDirectory <DiagramDomainDataDirectory>(); IDomainModelServices topMost = child.GetDomainModelServices().TopMostService; // find parent shapes List <Guid> shapeIds = DiagramsShapeStore.GetFromStore(parent.Id); if (shapeIds != null) { foreach (Guid shapeId in shapeIds) { // see if each parent shape has a child shape already added to it NodeShape parentShape = child.Store.ElementDirectory.FindElement(shapeId) as NodeShape; if (parentShape == null) { continue; } foreach (Guid elementShapeId in data.GetShapeTypesForElement(child.GetDomainClassId(), parentShape.GetDomainClassId())) { if (!DiagramHelper.IsElementDisplayedOn(parentShape, elementShapeId, child.Id)) { NodeShape shape = topMost.ShapeProvider.CreateShapeForElement(elementShapeId, child) as NodeShape; if (shape.IsRelativeChildShape) { parentShape.AddRelativeChild(shape); } else { parentShape.AddNestedChild(shape); } shape.SetAtFreePositionOnParent(); } } } } //AddRootShapesForElement(child, false); AddRootShapesForElement(child); }
/// <summary> /// Creates missing links for the added shape. /// </summary> /// <param name="shapeAdded">Shape added.</param> public virtual void FixUpMissingLinkShapes(NodeShape shapeAdded) { DiagramDomainDataDirectory data = this.Store.DomainDataAdvDirectory.ResolveExtensionDirectory <DiagramDomainDataDirectory>(); if (data == null) { throw new ArgumentNullException("DiagramDomainDataDirectory can not be null"); } ShapeClassInfo info; data.ShapeClassInfos.TryGetValue(shapeAdded.GetDomainClass().Id, out info); if (info == null) { return; } ModelLinkAddRuleForRSShapes.RSShapesFactoryHelper factory = this.GetRSShapesFactoryHelper(); ModelLinkAddRuleForMappingRSShapes.RSShapesFactoryHelper factoryMapping = this.GetMappingRSShapesFactoryHelper(); if (factory != null) { if (info.RelationshipSourceRoleTypes.Count > 0) { foreach (Guid rel in info.RelationshipSourceRoleTypes) { ReadOnlyCollection <DomainModelLink> links = DomainRoleInfo.GetElementLinks <DomainModelLink>(shapeAdded.Element, rel); foreach (DomainModelLink link in links) { factory.AddRSShapesForElement(link); } } } if (info.RelationshipTargetRoleTypes.Count > 0) { foreach (Guid rel in info.RelationshipTargetRoleTypes) { ReadOnlyCollection <DomainModelLink> links = DomainRoleInfo.GetElementLinks <DomainModelLink>(shapeAdded.Element, rel); foreach (DomainModelLink link in links) { factory.AddRSShapesForElement(link); } } } } if (factoryMapping != null) { if (info.MappingRelationshipSourceRoleTypes.Count > 0) { foreach (Guid rel in info.MappingRelationshipSourceRoleTypes) { ReadOnlyCollection <DomainModelLink> links = DomainRoleInfo.GetElementLinks <DomainModelLink>(shapeAdded.Element, rel); foreach (DomainModelLink link in links) { factoryMapping.AddRSShapesForElement(link); } } } if (info.MappingRelationshipTargetRoleTypes.Count > 0) { foreach (Guid rel in info.MappingRelationshipTargetRoleTypes) { ReadOnlyCollection <DomainModelLink> links = DomainRoleInfo.GetElementLinks <DomainModelLink>(shapeAdded.Element, rel); foreach (DomainModelLink link in links) { factoryMapping.AddRSShapesForElement(link); } } } } foreach (Diagram d in this.IncludedDiagrams) { d.FixUpMissingLinkShapes(shapeAdded); } foreach (NodeShape s in shapeAdded.Children) { s.FixUpMissingLinkShapes(); } }
/// <summary> /// Merges the current directory with an additional directory. /// </summary> /// <param name="data">Directory</param> public void Merge(IDomainDataExtensionDirectory data) { if (!(data is DiagramDomainDataDirectory)) { throw new InvalidOperationException("Can not merge with " + data.ToString()); } DiagramDomainDataDirectory domainData = data as DiagramDomainDataDirectory; foreach (KeyValuePair <Guid, Guid> pair in domainData.ClassShapesDependenciesMapping) { ClassShapesDependenciesMapping.Add(pair.Key, pair.Value); } foreach (KeyValuePair <Guid, List <Guid> > pair in domainData.ParentChildrenShapesMapping) { ParentChildrenShapesMapping.Add(pair.Key, pair.Value); } foreach (KeyValuePair <Guid, List <Guid> > pair in domainData.DiagramChildrenShapesMapping) { DiagramChildrenShapesMapping.Add(pair.Key, pair.Value); } foreach (KeyValuePair <Guid, List <Guid> > pair in domainData.DiagramRootChildrenShapesMapping) { DiagramRootChildrenShapesMapping.Add(pair.Key, pair.Value); } foreach (KeyValuePair <Guid, List <Guid> > pair in domainData.DiagramRSChildren) { DiagramRSChildren.Add(pair.Key, pair.Value); } foreach (KeyValuePair <Guid, List <Guid> > pair in domainData.DiagramMappingRSChildren) { DiagramMappingRSChildren.Add(pair.Key, pair.Value); } // class shape mappings foreach (KeyValuePair <Guid, List <Guid> > pair in domainData.ClassShapesMapping) { if (ClassShapesMapping.ContainsKey(pair.Key)) { ClassShapesMapping[pair.Key].AddRange(pair.Value); } else { ClassShapesMapping.Add(pair.Key, pair.Value); } } foreach (KeyValuePair <Guid, DiagramClassInfo> pair in domainData.DiagramClassInfos) { DiagramClassInfos.Add(pair.Key, pair.Value); } foreach (KeyValuePair <Guid, ShapeClassInfo> pair in domainData.ShapeClassInfos) { ShapeClassInfos.Add(pair.Key, pair.Value); } foreach (KeyValuePair <Guid, RelationshipShapeInfo> pair in domainData.RelationshipShapeInfos) { RelationshipShapeInfos.Add(pair.Key, pair.Value); } foreach (KeyValuePair <Guid, MappingRelationshipShapeInfo> pair in domainData.MappingRelationshipShapeInfos) { MappingRelationshipShapeInfos.Add(pair.Key, pair.Value); } }