/// <summary> /// Get the source object type or role after the /// base class sets the source shape /// </summary> /// <param name="e">MouseActionEventArgs</param> protected override void OnClicked(MouseActionEventArgs e) { base.OnClicked(e); if (mySourceObjectType == null && mySourceRole == null) { RoleBase roleBase = myLastMouseDownRole; if (roleBase != null) { Role role = roleBase.Role; mySourceRole = roleBase; FactTypeShape factShape; if (null != role.RolePlayer && null != (factShape = MouseDownHitShape as FactTypeShape)) { bool haveConnectorForRole = false; foreach (RolePlayerLink connector in MultiShapeUtility.GetEffectiveAttachedLinkShapesFrom <RolePlayerLink>(factShape)) { if (connector.AssociatedRolePlayerLink.PlayedRole == role) { haveConnectorForRole = true; break; } } mySourceRoleMissingConnector = !haveConnectorForRole; } } else { mySourceObjectType = ObjectTypeFromShape(MouseDownHitShape); } } }
/// <summary> /// RolePlayerChangeRule: typeof(Microsoft.VisualStudio.Modeling.Diagrams.LinkConnectsToNode) /// External constraint shapes can only be drawn if they show all of their /// links, so automatically remove them if a link is moved off the constraint /// shape. /// </summary> private static void VerifyConnectedShapeShapeRolePlayerChangedRule(RolePlayerChangedEventArgs e) { ShapeElement shape; if (e.DomainRole.Id == LinkConnectsToNode.NodesDomainRoleId && ((LinkConnectsToNode)e.ElementLink).Link is ExternalConstraintLink && null != (shape = e.OldRolePlayer as ShapeElement)) { ExternalConstraintShape constraintShape; FactTypeShape factTypeShape; if (null != (constraintShape = shape as ExternalConstraintShape)) { FrameworkDomainModel.DelayValidateElement(constraintShape, DelayValidateExternalConstraintShapeFullyConnected); } else if (null != (factTypeShape = MultiShapeUtility.ResolvePrimaryShape(shape) as FactTypeShape)) { FrameworkDomainModel.DelayValidateElement(factTypeShape, DelayValidateFactTypeShapeSize); if (null != (shape = e.NewRolePlayer as ShapeElement) && null != (factTypeShape = MultiShapeUtility.ResolvePrimaryShape(shape) as FactTypeShape)) { FrameworkDomainModel.DelayValidateElement(factTypeShape, DelayValidateFactTypeShapeSize); } } } }
/// <summary> /// ChangeRule: typeof(Microsoft.VisualStudio.Modeling.Diagrams.NodeShape), FireTime=TopLevelCommit, Priority=DiagramFixupConstants.AddConnectionRulePriority; /// </summary> private static void AbsoluteBoundsChangedRule(ElementPropertyChangedEventArgs e) { if (e.DomainProperty.Id == NodeShape.AbsoluteBoundsDomainPropertyId) { MultiShapeUtility.CheckLinksOnBoundsChange(e); } }
/// <summary> /// Calls <see cref="MultiShapeUtility.ShouldVisitOnDelete"/> to determine if the relationship should be visited /// and to reconfigure any links /// </summary> /// <param name="walker">The current <see cref="ElementWalker"/></param> /// <param name="sourceElement">The <see cref="ModelElement"/> being deleted</param> /// <param name="sourceRoleInfo">The role information</param> /// <param name="domainRelationshipInfo">The relationship information</param> /// <param name="targetRelationship">The other <see cref="ModelElement"/> in the relationship</param> /// <returns>Whether to visit the relationship</returns> public override VisitorFilterResult ShouldVisitRelationship(ElementWalker walker, ModelElement sourceElement, DomainRoleInfo sourceRoleInfo, DomainRelationshipInfo domainRelationshipInfo, ElementLink targetRelationship) { if (MultiShapeUtility.ShouldVisitOnDelete(walker, sourceElement, sourceRoleInfo, domainRelationshipInfo, targetRelationship)) { return(base.ShouldVisitRelationship(walker, sourceElement, sourceRoleInfo, domainRelationshipInfo, targetRelationship)); } else { return(VisitorFilterResult.Never); } }
/// <summary> /// Implements <see cref="IReconfigureableLink.Reconfigure"/> /// </summary> protected void Reconfigure(ShapeElement discludedShape) { SubtypeFact subtypeFact = AssociatedSubtypeFact; ObjectType subType = subtypeFact.Subtype; ObjectType superType = subtypeFact.Supertype; if (subType != null && superType != null) { FactType nestedSubFact = subType.NestedFactType; FactType nestedSuperFact = superType.NestedFactType; MultiShapeUtility.ReconfigureLink(this, (nestedSubFact == null) ? subType as ModelElement : nestedSubFact as ModelElement, (nestedSuperFact == null) ? superType as ModelElement : nestedSuperFact as ModelElement, discludedShape); } }
/// <summary> /// Implements <see cref="IConfigureAsChildShape.ConfiguringAsChildOf"/> /// </summary> protected new void ConfiguringAsChildOf(NodeShape parentShape, bool createdDuringViewFixup) { base.ConfiguringAsChildOf(parentShape, createdDuringViewFixup); // We have to make sure each shape is connected to its parent, // so we can't use the MultiShapeUtility. Diagram diagram = parentShape as Diagram; if (diagram == null) { return; } RoleHasValueConstraint modelLink = ModelElement as RoleHasValueConstraint; ModelElement factType = modelLink.Role.FactType; //connect the first unconnected constraint shape to its parent foreach (ValueConstraintShape shape in MultiShapeUtility.FindAllShapesForElement <ValueConstraintShape>(diagram, modelLink.ValueConstraint)) { bool connected = false; foreach (ShapeElement link in shape.ToRoleLinkShapes) { //check if the shape is already connected ValueRangeLink valueRangeLink; if ((valueRangeLink = link as ValueRangeLink) != null && valueRangeLink.FromShape.ModelElement == factType) { connected = true; break; } } FactTypeShape factTypeShape; if (connected || null == (factTypeShape = shape.ParentShape as FactTypeShape) || factTypeShape.DisplayAsObjectType) { continue; } Connect(factTypeShape, shape); return; } Delete(); }
/// <summary> /// DeletingRule: typeof(Microsoft.VisualStudio.Modeling.Diagrams.LinkConnectsToNode) /// External constraint shapes can only be drawn if they show all of their /// links, so automatically remove them if a connecting shape is removed. /// </summary> private static void VerifyConnectedShapeShapeDeletingRule(ElementDeletingEventArgs e) { LinkConnectsToNode connectLink = (LinkConnectsToNode)e.ModelElement; ExternalConstraintLink link; ModelElement linkMel; ModelElement shapeMel; if (null != (link = connectLink.Link as ExternalConstraintLink) && null != (linkMel = link.ModelElement) && !linkMel.IsDeleting) { NodeShape linkNode = connectLink.Nodes; ExternalConstraintShape constraintShape = linkNode as ExternalConstraintShape; NodeShape oppositeShape = null; // The ToShape (as opposed to FromShape) here needs to be in // sync with the code in ConfiguringAsChildOf if (constraintShape == null) { constraintShape = link.ToShape as ExternalConstraintShape; oppositeShape = linkNode; } else { oppositeShape = link.FromShape; } if (oppositeShape != null && constraintShape != null && null != (shapeMel = constraintShape.ModelElement) && !shapeMel.IsDeleting) { if (!constraintShape.IsDeleting) { FrameworkDomainModel.DelayValidateElement(constraintShape, DelayValidateExternalConstraintShapeFullyConnected); } // Delay, fact type shape size will not be accurate until deletion is completed. FactTypeShape factTypeShape = MultiShapeUtility.ResolvePrimaryShape(oppositeShape) as FactTypeShape; if (factTypeShape != null && !factTypeShape.IsDeleting) { FrameworkDomainModel.DelayValidateElement(factTypeShape, DelayValidateFactTypeShapeSize); } } } }
/// <summary> /// Implements <see cref="IReconfigureableLink.Reconfigure"/> /// </summary> protected void Reconfigure(ShapeElement discludedShape) { ModelElement element = ModelElement; // During the delete process for an external constrant, // the model element reference gets removed before checking ShouldVisitRelationship, // so we have to check the null case. if (element != null) { IFactConstraint factConstraint; ConstraintRoleSequenceHasRole constraintRole; FactType factType; if (null != (factConstraint = element as IFactConstraint)) { MultiShapeUtility.ReconfigureLink(this, factConstraint.FactType, factConstraint.Constraint as ModelElement, discludedShape); } else if (null != (constraintRole = element as ConstraintRoleSequenceHasRole) && null != (factType = constraintRole.Role.FactType)) { MultiShapeUtility.ReconfigureLink(this, factType, constraintRole.ConstraintRoleSequence, discludedShape); } } }
/// <summary> /// Add subtype links when possible /// </summary> /// <param name="element">An ModelHasFactType instance</param> /// <param name="store">The context store</param> /// <param name="notifyAdded">The listener to notify if elements are added during fixup</param> protected sealed override void ProcessElement(ModelHasFactType element, Store store, INotifyElementAdded notifyAdded) { SubtypeFact subTypeFact = element.FactType as SubtypeFact; ORMModel model; if (null != (subTypeFact = element.FactType as SubtypeFact) && !subTypeFact.IsDeleted && null != (model = subTypeFact.Model)) { ObjectType rolePlayer = subTypeFact.Subtype; FactType nestedFact = rolePlayer.NestedFactType; if (FactTypeShape.ShouldDrawObjectification(nestedFact)) { Diagram.FixUpDiagram(model, nestedFact); Diagram.FixUpDiagram(nestedFact, rolePlayer); } else { Diagram.FixUpDiagram(model, rolePlayer); } rolePlayer = subTypeFact.Supertype; nestedFact = rolePlayer.NestedFactType; if (FactTypeShape.ShouldDrawObjectification(nestedFact)) { Diagram.FixUpDiagram(model, nestedFact); Diagram.FixUpDiagram(nestedFact, rolePlayer); } else { Diagram.FixUpDiagram(model, rolePlayer); } object AllowMultipleShapes; Dictionary <object, object> topLevelContextInfo; bool containedAllowMultipleShapes; if (!(containedAllowMultipleShapes = (topLevelContextInfo = store.TransactionManager.CurrentTransaction.TopLevelTransaction.Context.ContextInfo).ContainsKey(AllowMultipleShapes = MultiShapeUtility.AllowMultipleShapes))) { topLevelContextInfo.Add(AllowMultipleShapes, null); } foreach (PresentationViewsSubject presentationViewsSubject in DomainRoleInfo.GetElementLinks <PresentationViewsSubject>(model, PresentationViewsSubject.SubjectDomainRoleId)) { ORMDiagram diagram; if ((diagram = presentationViewsSubject.Presentation as ORMDiagram) != null) { ObjectType subtype = subTypeFact.Subtype; // add a link shape for each object type shape on the diagram for the played role foreach (ObjectTypeShape shapeElement in MultiShapeUtility.FindAllShapesForElement <ObjectTypeShape>(diagram, subtype)) { diagram.FixUpLocalDiagram(subTypeFact); } FactType objectifiedFactType; if (null != (objectifiedFactType = subtype.NestedFactType)) { foreach (FactTypeShape shapeElement in MultiShapeUtility.FindAllShapesForElement <FactTypeShape>(diagram, objectifiedFactType)) { diagram.FixUpLocalDiagram(subTypeFact); } } } } if (!containedAllowMultipleShapes) { topLevelContextInfo.Remove(AllowMultipleShapes); } } }
/// <summary>See <see cref="ShapeElement.FixUpChildShapes"/>.</summary> public override ShapeElement FixUpChildShapes(ModelElement childElement) { return(MultiShapeUtility.FixUpChildShapes(this, childElement, null)); }
/// <summary> /// Implements <see cref="IModelErrorActivation.ActivateModelError"/> for /// the <see cref="ValueComparisonConstraintOperatorNotSpecifiedError"/> /// </summary> protected new bool ActivateModelError(ModelError error) { ValueComparisonConstraintOperatorNotSpecifiedError operatorError; ValueComparisonRolesNotComparableError comparabilityError; ValueComparisonConstraint constraint; Store store; bool retVal = true; if (null != (operatorError = error as ValueComparisonConstraintOperatorNotSpecifiedError)) { store = Store; constraint = operatorError.ValueComparisonConstraint; EditorUtility.ActivatePropertyEditor( (store as IORMToolServices).ServiceProvider, DomainTypeDescriptor.CreatePropertyDescriptor(constraint, ValueComparisonConstraint.OperatorDomainPropertyId), true); } else if (null != (comparabilityError = error as ValueComparisonRolesNotComparableError)) { constraint = comparabilityError.ValueComparisonConstraint; LinkedElementCollection <Role> constraintRoles = constraint.RoleCollection; Role role1; Role role2; ObjectTypePlaysRole rolePlayerLink1; ObjectTypePlaysRole rolePlayerLink2; ObjectType rolePlayer1 = null; ObjectType rolePlayer2 = null; Role[] valueRoles1 = null; Role[] valueRoles2 = null; // The default behavior is to activate the role sequence // for editing. However, if the problem is with a single // resolved value type, and the units are correct, then // we need to select the first directly detached object. if (constraintRoles.Count == 2 && null != (rolePlayerLink1 = ObjectTypePlaysRole.GetLinkToRolePlayer(role1 = constraintRoles[0])) && null != (rolePlayerLink2 = ObjectTypePlaysRole.GetLinkToRolePlayer(role2 = constraintRoles[1])) && (rolePlayerLink1.RolePlayer == rolePlayerLink2.RolePlayer || (null != (valueRoles1 = role1.GetValueRoles()) && null != (valueRoles2 = role2.GetValueRoles()) && DataType.IsComparableValueType(rolePlayer1 = valueRoles1[0].RolePlayer, rolePlayer2 = valueRoles2[0].RolePlayer, !constraint.IsDirectional)))) { bool verifiedReferenceMode = true; if (valueRoles1 != null) { ORMModel model = null; ReferenceMode referenceMode1 = (valueRoles1.Length > 1) ? ReferenceMode.FindReferenceModeFromEntityNameAndValueName(rolePlayer1.Name, valueRoles1[1].RolePlayer.Name, model = constraint.ResolvedModel) : null; ReferenceMode referenceMode2 = (valueRoles2.Length > 1) ? ReferenceMode.FindReferenceModeFromEntityNameAndValueName(rolePlayer2.Name, valueRoles2[1].RolePlayer.Name, model ?? constraint.ResolvedModel) : null; bool referenceMode1IsUnit = referenceMode1 != null && referenceMode1.Kind.ReferenceModeType == ReferenceModeType.UnitBased; bool referenceMode2IsUnit = referenceMode2 != null && referenceMode2.Kind.ReferenceModeType == ReferenceModeType.UnitBased; verifiedReferenceMode = referenceMode1IsUnit ? (referenceMode2IsUnit && referenceMode1 == referenceMode2) : !referenceMode2IsUnit; } if (verifiedReferenceMode) { // Find a connected role player foreach (ExternalConstraintLink constraintLink in MultiShapeUtility.GetEffectiveAttachedLinkShapes <ExternalConstraintLink>(this)) { FactTypeShape factTypeShape; if (constraintLink.AssociatedConstraintRole.Role == role1 && null != (factTypeShape = constraintLink.FromShape as FactTypeShape)) { foreach (RolePlayerLink rolePlayerLinkShape in MultiShapeUtility.GetEffectiveAttachedLinkShapes <RolePlayerLink>(factTypeShape)) { if (rolePlayerLinkShape.AssociatedRolePlayerLink == rolePlayerLink1) { Diagram.ActiveDiagramView.Selection.Set(new DiagramItem(rolePlayerLinkShape.ToShape)); return(true); } } } } } } ActivateNewRoleSequenceConnectAction(null); } else { retVal = base.ActivateModelError(error); } return(retVal); }
/// <summary> /// Implements <see cref="IReconfigureableLink.Reconfigure"/> /// </summary> protected void Reconfigure(ShapeElement discludedShape) { ModelNoteReferencesModelElement link = ModelElement as ModelNoteReferencesModelElement; MultiShapeUtility.ReconfigureLink(this, link.Note, link.Element, discludedShape); }