/// <summary> /// Do the following when a new Association is created: /// - Initialize the "End1" and "End2" properties (displayed on the connector decorators) /// - Set the "Name" property to a sensible default /// - Update the navigation property of the Source and Target entities /// </summary> public override void ElementAdded(ElementAddedEventArgs e) { base.ElementAdded(e); var addedAssociation = e.ModelElement as Association; Debug.Assert(addedAssociation != null); Debug.Assert(addedAssociation.SourceEntityType != null); Debug.Assert(addedAssociation.TargetEntityType != null); Debug.Assert(addedAssociation.SourceEntityType.EntityDesignerViewModel != null); if (addedAssociation != null && addedAssociation.SourceEntityType != null && addedAssociation.TargetEntityType != null && addedAssociation.SourceEntityType.EntityDesignerViewModel != null) { var tx = ModelUtils.GetCurrentTx(e.ModelElement.Store); Debug.Assert(tx != null); if (tx != null && !tx.IsSerializing) { // create the new association ViewModelChangeContext.GetNewOrExistingContext(tx).ViewModelChanges.Add(new AssociationAdd(addedAssociation)); } } }
/// <summary> /// Do the following when a new EntityType shape is created: /// - Add the new EntityType to the model /// </summary> /// <param name="e"></param> public override void ElementAdded(ElementAddedEventArgs e) { base.ElementAdded(e); var addedEntity = e.ModelElement as EntityType; Debug.Assert(addedEntity != null); Debug.Assert(addedEntity.EntityDesignerViewModel != null); if ((addedEntity != null) && (addedEntity.EntityDesignerViewModel != null)) { var viewModel = addedEntity.EntityDesignerViewModel; Debug.Assert(viewModel != null); var tx = ModelUtils.GetCurrentTx(e.ModelElement.Store); Debug.Assert(tx != null, "Make sure we have a Current Active Tx"); if (tx != null && !tx.IsSerializing) { // Remove the added DSL EntityType. // When Escher model is updated, there will be a code that will create the EntityType back viewModel.EntityTypes.Remove(addedEntity); addedEntity.Delete(); // create the model change and add it to the current transaction changelist ViewModelChangeContext.GetNewOrExistingContext(tx).ViewModelChanges.Add(new EntityTypeAdd()); } } }
public override void ElementPropertyChanged(ElementPropertyChangedEventArgs e) { var inheritanceConnector = e.ModelElement as InheritanceConnector; Debug.Assert(inheritanceConnector != null); if (inheritanceConnector != null) { // for some reason when deleting connector, DSL invokes ChangeRule, so just return if it's deleted if (inheritanceConnector.IsDeleted) { return; } var tx = ModelUtils.GetCurrentTx(e.ModelElement.Store); Debug.Assert(tx != null); if (tx != null && !tx.IsSerializing) { if (e.DomainProperty.Id == LinkShape.EdgePointsDomainPropertyId || e.DomainProperty.Id == LinkShape.ManuallyRoutedDomainPropertyId) { ViewModelChangeContext.GetNewOrExistingContext(tx) .ViewModelChanges.Add(new InheritanceConnectorChange(inheritanceConnector, e.DomainProperty.Id)); } } } }
public override void ElementDeleted(ElementDeletedEventArgs e) { base.ElementDeleted(e); var inheritance = e.ModelElement as Inheritance; if (inheritance != null) { if (inheritance.TargetEntityType != null) { // We need to invalidate the target entitytypeshape element; so base type name will be updated correctly. foreach (var pe in PresentationViewsSubject.GetPresentation(inheritance.TargetEntityType)) { var entityShape = pe as EntityTypeShape; if (entityShape != null) { entityShape.Invalidate(); } } } var tx = ModelUtils.GetCurrentTx(inheritance.Store); Debug.Assert(tx != null); if (tx != null && !tx.IsSerializing) { ViewModelChangeContext.GetNewOrExistingContext(tx).ViewModelChanges.Add(new InheritanceDelete(inheritance)); } } }
protected override void OnDeleting() { base.OnDeleting(); if (EntityType != null && EntityType.EntityDesignerViewModel != null && EntityType.EntityDesignerViewModel.Reloading == false) { var viewModel = EntityType.EntityDesignerViewModel; var tx = ModelUtils.GetCurrentTx(Store); Debug.Assert(tx != null); if (tx != null && !tx.IsSerializing) { // deleting the property would select the Diagram, select parent Entity instead var diagram = viewModel.GetDiagram(); if (diagram != null && diagram.ActiveDiagramView != null) { var shape = diagram.FindShape(EntityType); if (shape != null) { diagram.ActiveDiagramView.Selection.Set(new DiagramItem(shape)); } } ViewModelChangeContext.GetNewOrExistingContext(tx).ViewModelChanges.Add(new NavigationPropertyDelete(this)); } } }
public override void ElementPropertyChanged(ElementPropertyChangedEventArgs e) { var entityShape = e.ModelElement as EntityTypeShape; Debug.Assert(entityShape != null); var tx = ModelUtils.GetCurrentTx(entityShape.Store); Debug.Assert(tx != null); if (tx != null && !tx.IsSerializing) { if (e.DomainProperty.Id == NodeShape.AbsoluteBoundsDomainPropertyId) { var oldAbsoluteBounds = (RectangleD)e.OldValue; var newAbsoluteBounds = (RectangleD)e.NewValue; // If only the height changed then we don't need to change anything in the model. // Also check an edge case where the first entity shape added to the diagram is added at a location that is within the NestedShapeMargin // in the top left corner. In this scenario, the ViewModel EntityShape is by default added to the top left of diagram at the NestedShapeMargin // value (i.e. (0.5,0.5)). This means that if the user tries add a shape at a point less than (0.5,0.5), i.e. if they drop/right-click in the // top left corner, it will not change the location of the shape because any point smaller than (0.5,0.5) will be rounded off to (0.5,0.5) // because of the NestedShapeMargin. This means that the old and new value of the absolute bounds will not change after the drop point // is applied to the new ViewModel shape's default location. Normally this would not be a problem, but when we create the EntityTypeShape in // the model we initally assign it a random (x,y) value (see CreateEntityTypeShapeCommand.cs) and we're relying on the EntityTypeShapeChange // command issued by this rule to update the model x,y values so that the correct co-ords are persisted in the *.diagram file. // Therefore there is an extra check in the IF statement below to catch the case where the user adds their first shape in the diagram at the // top left corner inside the NestedShapeMargin as this is the easiest edge case to hit. Note that this will not protect against edge cases // from subsequent updates where the user drops a new shape exactly on the same point as the initial location of the new ViewModel shape // (the initial co-ords cascade from top-left down to the bottom-right as more shapes are added). If our users are dextrous enough to hit the // edge cases for new entities and it's causing issues it would probably be best to remove this check entirely and always return an // EntityTypeShapeChange (and forgo the optimization). if (oldAbsoluteBounds.X == newAbsoluteBounds.X && oldAbsoluteBounds.Y == newAbsoluteBounds.Y && oldAbsoluteBounds.Width == newAbsoluteBounds.Width && (newAbsoluteBounds.X > entityShape.Diagram.NestedShapesMargin.Width || newAbsoluteBounds.Y > entityShape.Diagram.NestedShapesMargin.Height)) { return; } } if (e.DomainProperty.Id == NodeShape.AbsoluteBoundsDomainPropertyId || e.DomainProperty.Id == NodeShape.IsExpandedDomainPropertyId) { foreach (var link in entityShape.Link) { link.ManuallyRouted = false; } ViewModelChangeContext.GetNewOrExistingContext(tx) .ViewModelChanges.Add(new EntityTypeShapeChange(entityShape, e.DomainProperty.Id)); } } }
/// <summary> /// Do the following when an EntityType changes: /// - Update roles in related Associations /// </summary> /// <param name="e"></param> public override void ElementPropertyChanged(ElementPropertyChangedEventArgs e) { base.ElementPropertyChanged(e); // if the element is deleted or about to be deleted, this rule will get fired. // Just return immediately here because we don't care if the entity-type's property has changed. if (e.ModelElement.IsDeleted || e.ModelElement.IsDeleting) { return; } var changedEntity = e.ModelElement as EntityType; Debug.Assert(changedEntity != null); Debug.Assert(changedEntity.EntityDesignerViewModel != null); if (changedEntity != null && changedEntity.EntityDesignerViewModel != null) { var viewModel = changedEntity.EntityDesignerViewModel; var tx = ModelUtils.GetCurrentTx(e.ModelElement.Store); Debug.Assert(tx != null); // don't do the auto update stuff if we are in the middle of deserialization if (tx != null && !tx.IsSerializing) { // are they changing the name? if (e.DomainProperty.Id == NameableItem.NameDomainPropertyId) { // if we are creating this Entity, there is no 'change' to do if (viewModel.ModelXRef.GetExisting(changedEntity) == null) { return; } if (!EscherAttributeContentValidator.IsValidCsdlEntityTypeName(changedEntity.Name)) { throw new InvalidOperationException( String.Format(CultureInfo.CurrentCulture, Resources.Error_EntityNameInvalid, changedEntity.Name)); } if (ModelUtils.IsUniqueName(changedEntity, changedEntity.Name, viewModel.EditingContext) == false) { throw new InvalidOperationException( String.Format(CultureInfo.CurrentCulture, Resources.Error_EntityNameDuplicate, changedEntity.Name)); } ViewModelChangeContext.GetNewOrExistingContext(tx).ViewModelChanges.Add(new EntityTypeChange(changedEntity)); } } } }
public override void ElementPropertyChanged(ElementPropertyChangedEventArgs e) { base.ElementPropertyChanged(e); var changedProperty = e.ModelElement as ScalarProperty; Debug.Assert(changedProperty != null); // this rule will fire if a PropertyRef gets deleted (this happens if a keyed property that has a sibling keyed property is deleted), // in which case we ignore this change. if (changedProperty.IsDeleted) { return; } Debug.Assert(changedProperty.EntityType != null && changedProperty.EntityType.EntityDesignerViewModel != null); if (changedProperty != null && changedProperty.EntityType != null && changedProperty.EntityType.EntityDesignerViewModel != null) { var diagram = changedProperty.EntityType.EntityDesignerViewModel.GetDiagram(); Debug.Assert(diagram != null, "EntityDesignerDiagram is null"); // if EntityKey property changed, we need to invalidate properties compartment for this property to refresh the icon if (e.DomainProperty.Id == ScalarProperty.EntityKeyDomainPropertyId) { foreach (var pe in PresentationViewsSubject.GetPresentation(changedProperty.EntityType)) { var entityShape = pe as EntityTypeShape; if (entityShape != null) { entityShape.PropertiesCompartment.Invalidate(true); } } } var tx = ModelUtils.GetCurrentTx(e.ModelElement.Store); Debug.Assert(tx != null); // don't do the auto update stuff if we are in the middle of deserialization if (tx != null && !tx.IsSerializing) { if (e.DomainProperty.Id == ScalarProperty.EntityKeyDomainPropertyId) { ViewModelChangeContext.GetNewOrExistingContext(tx) .ViewModelChanges.Add(new ScalarPropertyKeyChange(changedProperty)); } } } }
/// <summary> /// Do the following when a new Inheritance is created: /// - Display a warning and proceed per user choice /// - Remove any keys defined in the derived entity (and their derived entities down the hierarchy) /// </summary> /// <param name="e"></param> public override void ElementAdded(ElementAddedEventArgs e) { base.ElementAdded(e); var addedInheritance = e.ModelElement as Inheritance; Debug.Assert(addedInheritance != null); Debug.Assert(addedInheritance.SourceEntityType != null); Debug.Assert(addedInheritance.SourceEntityType.EntityDesignerViewModel != null); Debug.Assert(addedInheritance.TargetEntityType != null); if (addedInheritance != null && addedInheritance.SourceEntityType != null && addedInheritance.SourceEntityType.EntityDesignerViewModel != null && addedInheritance.TargetEntityType != null) { // We need to invalidate the target entitytypeshape element; so base type name will be updated correctly. foreach (var pe in PresentationViewsSubject.GetPresentation(addedInheritance.TargetEntityType)) { var entityShape = pe as EntityTypeShape; if (entityShape != null) { entityShape.Invalidate(); } } var tx = ModelUtils.GetCurrentTx(e.ModelElement.Store); Debug.Assert(tx != null); if (tx != null && !tx.IsSerializing) { var source = addedInheritance.SourceEntityType; var viewModel = source.EntityDesignerViewModel; var b = viewModel.ModelXRef.GetExisting(addedInheritance.SourceEntityType) as EntityType; var d = viewModel.ModelXRef.GetExisting(addedInheritance.TargetEntityType) as EntityType; var baseEntity = b as ConceptualEntityType; var derivedEntity = d as ConceptualEntityType; Debug.Assert(b != null ? baseEntity != null : true, "EntityType is not ConceptualEntityType"); Debug.Assert(d != null ? derivedEntity != null : true, "EntityType is not ConceptualEntityType"); Debug.Assert(baseEntity != null && derivedEntity != null); ViewModelChangeContext.GetNewOrExistingContext(tx) .ViewModelChanges.Add(new InheritanceAdd(addedInheritance, baseEntity, derivedEntity)); } } }
public override void ElementAdded(ElementAddedEventArgs e) { var inheritanceConnector = e.ModelElement as InheritanceConnector; Debug.Assert(inheritanceConnector != null); var tx = ModelUtils.GetCurrentTx(inheritanceConnector.Store); Debug.Assert(tx != null); if (tx != null && !tx.IsSerializing) { ViewModelChangeContext.GetNewOrExistingContext(tx).ViewModelChanges.Add(new InheritanceConnectorAdd(inheritanceConnector)); } }
public override void ElementAdded(ElementAddedEventArgs e) { var entityShape = e.ModelElement as EntityTypeShape; Debug.Assert(entityShape != null); var tx = ModelUtils.GetCurrentTx(entityShape.Store); Debug.Assert(tx != null); if (tx != null && !tx.IsSerializing) { ViewModelChangeContext.GetNewOrExistingContext(tx).ViewModelChanges.Add(new EntityTypeShapeAdd(entityShape)); } }
protected override void OnDeleting() { base.OnDeleting(); if (EntityDesignerViewModel != null && EntityDesignerViewModel.Reloading == false) { var tx = ModelUtils.GetCurrentTx(Store); Debug.Assert(tx != null); if (tx != null && !tx.IsSerializing) { ViewModelChangeContext.GetNewOrExistingContext(tx).ViewModelChanges.Add(new EntityTypeDelete(this)); } } }
public override void ElementDeleted(ElementDeletedEventArgs e) { base.ElementDeleted(e); var associationConnector = e.ModelElement as AssociationConnector; if (associationConnector != null) { var tx = ModelUtils.GetCurrentTx(associationConnector.Store); Debug.Assert(tx != null); if (tx != null && !tx.IsSerializing) { ViewModelChangeContext.GetNewOrExistingContext(tx) .ViewModelChanges.Add(new AssociationConnectorDelete(associationConnector)); } } }
/// <summary> /// Do the following when an Entity changes: /// - Update roles in related Associations /// </summary> /// <param name="e"></param> public override void ElementAdded(ElementAddedEventArgs e) { base.ElementAdded(e); var addedProperty = e.ModelElement as Property; Debug.Assert(addedProperty != null); Debug.Assert(addedProperty.EntityType != null && addedProperty.EntityType.EntityDesignerViewModel != null); if (addedProperty != null && addedProperty.EntityType != null && addedProperty.EntityType.EntityDesignerViewModel != null) { var tx = ModelUtils.GetCurrentTx(e.ModelElement.Store); Debug.Assert(tx != null); if (tx != null && !tx.IsSerializing) { ViewModelChangeContext.GetNewOrExistingContext(tx).ViewModelChanges.Add(new PropertyAdd(addedProperty)); } } }
/// <summary> /// Do the following when an Entity changes: /// - Update roles in related Associations /// </summary> /// <param name="e"></param> public override void ElementPropertyChanged(ElementPropertyChangedEventArgs e) { base.ElementPropertyChanged(e); var changedNavigationProperty = e.ModelElement as NavigationProperty; Debug.Assert(changedNavigationProperty != null); Debug.Assert( changedNavigationProperty.EntityType != null && changedNavigationProperty.EntityType.EntityDesignerViewModel != null); if ((changedNavigationProperty != null) && (changedNavigationProperty.EntityType != null) && (changedNavigationProperty.EntityType.EntityDesignerViewModel != null)) { var tx = ModelUtils.GetCurrentTx(e.ModelElement.Store); Debug.Assert(tx != null); // don't do the auto update stuff if we are in the middle of deserialization if (tx != null && !tx.IsSerializing) { var viewModel = changedNavigationProperty.EntityType.EntityDesignerViewModel; if (e.DomainProperty.Id == NameableItem.NameDomainPropertyId) { // if we are creating this, the old name will be empty so there is no 'change' to do if (String.IsNullOrEmpty((string)e.OldValue)) { return; } if (!EscherAttributeContentValidator.IsValidCsdlNavigationPropertyName(changedNavigationProperty.Name)) { throw new InvalidOperationException( String.Format( CultureInfo.CurrentCulture, Resources.Error_NavigationPropertyNameInvalid, changedNavigationProperty.Name)); } var modelEntityType = viewModel.ModelXRef.GetExisting(changedNavigationProperty.EntityType) as Model.Entity.EntityType; Debug.Assert(modelEntityType != null, "modelEntityType is null"); // ensure name is unique if (modelEntityType.LocalName.Value.Equals(changedNavigationProperty.Name, StringComparison.Ordinal)) { var msg = string.Format( CultureInfo.CurrentCulture, Model.Resources.Error_MemberNameSameAsParent, changedNavigationProperty.Name, modelEntityType.LocalName.Value); throw new InvalidOperationException(msg); } else if (!EDMModelUtils.IsUniquePropertyName(modelEntityType, changedNavigationProperty.Name, true)) { var msg = string.Format( CultureInfo.CurrentCulture, Model.Resources.Error_MemberNameNotUnique, changedNavigationProperty.Name, modelEntityType.LocalName.Value); throw new InvalidOperationException(msg); } ViewModelChangeContext.GetNewOrExistingContext(tx) .ViewModelChanges.Add(new NavigationPropertyChange(changedNavigationProperty)); } } } }
/// <summary> /// Do the following when an Entity changes: /// - Update roles in related Associations /// </summary> /// <param name="e"></param> public override void ElementPropertyChanged(ElementPropertyChangedEventArgs e) { base.ElementPropertyChanged(e); var changedProperty = e.ModelElement as Property; Debug.Assert(changedProperty != null); // this rule will fire if a PropertyRef gets deleted (this happens if a keyed property that has a sibling keyed property is deleted), // in which case we ignore this change. if (changedProperty.IsDeleted) { return; } Debug.Assert(changedProperty.EntityType != null && changedProperty.EntityType.EntityDesignerViewModel != null); if (changedProperty != null && changedProperty.EntityType != null && changedProperty.EntityType.EntityDesignerViewModel != null) { var diagram = changedProperty.EntityType.EntityDesignerViewModel.GetDiagram(); Debug.Assert(diagram != null, "EntityDesignerDiagram is null"); // if EntityType property was changed and EntityDesignerDiagram's DisplayNameAndType flag is set to true, we need to refresh the entity shape diagram. if (e.DomainProperty.Id == Property.TypeDomainPropertyId && null != diagram && diagram.DisplayNameAndType) { foreach (var pe in PresentationViewsSubject.GetPresentation(changedProperty.EntityType)) { var entityShape = pe as EntityTypeShape; if (entityShape != null) { entityShape.PropertiesCompartment.Invalidate(true); } } } var tx = ModelUtils.GetCurrentTx(e.ModelElement.Store); Debug.Assert(tx != null); // don't do the auto update stuff if we are in the middle of deserialization if (tx != null && !tx.IsSerializing) { var viewModel = changedProperty.EntityType.EntityDesignerViewModel; // ensure name is unique and valid if the name has changed if (e.DomainProperty.Id == NameableItem.NameDomainPropertyId) { // if we are creating this, the old name will be empty so there is no 'change' to do if (String.IsNullOrEmpty((string)e.OldValue)) { return; } var modelProperty = viewModel.ModelXRef.GetExisting(changedProperty) as Model.Entity.Property; Debug.Assert(modelProperty != null, "modelProperty is null"); string errorMessage; if (!EDMModelUtils.ValidatePropertyName(modelProperty, changedProperty.Name, true, out errorMessage)) { throw new InvalidOperationException(errorMessage); } ViewModelChangeContext.GetNewOrExistingContext(tx).ViewModelChanges.Add(new PropertyChange(changedProperty)); } } } }