private static void SignificantFactTypeChangeDelayed(ModelElement element) { FactType factType; ORMModel model; if (!element.IsDeleted && !ORMElementGateway.IsElementExcluded(factType = (FactType)element) && null != (model = factType.Model)) { Objectification objectification = factType.Objectification; if (objectification != null) { LinkedElementCollection <FactType> impliedFactTypes = objectification.ImpliedFactTypeCollection; int impliedFactTypeCount = impliedFactTypes.Count; for (int i = 0; i < impliedFactTypeCount; ++i) { FactType impliedFactType = impliedFactTypes[i]; AddTransactedModelElement(impliedFactType, ModelElementModification.ORMElementChanged); } if (impliedFactTypeCount == 1) { AddTransactedModelElement(factType, ModelElementModification.ORMElementChanged); } } else { AddTransactedModelElement(factType, ModelElementModification.ORMElementChanged); } FrameworkDomainModel.DelayValidateElement(model, DelayValidateModel); } }
/// <summary> /// Implements <see cref="IAnswerSurveyQuestion{SurveyQuestionGlyph}.AskQuestion"/> /// </summary> protected int AskGlyphQuestion(object contextElement) { Objectification objectification = Objectification; if (objectification != null && !objectification.IsImplied) { return((int)SurveyQuestionGlyph.ObjectifiedFactType); } else { LinkedElementCollection <RoleBase> roles = RoleCollection; switch (roles.Count) { case 1: // This case should not get hit with unary binarization, but it isn't hurting anything return((int)SurveyQuestionGlyph.UnaryFactType); case 2: return(GetUnaryRoleIndex(roles).HasValue ? (int)SurveyQuestionGlyph.UnaryFactType : (int)SurveyQuestionGlyph.BinaryFactType); case 3: return((int)SurveyQuestionGlyph.TernaryFactType); default: return((int)SurveyQuestionGlyph.NaryFactType); } } }
/// <summary> /// This method ensures that the role in the related fact type is closest (spatially) to the related object shape. /// </summary> /// <param name="shape">The shape that was most recently placed on the diagram</param> protected override void PostShapePlacement(LayoutShape shape) { FactTypeShape factShape; LayoutShape parentShape; if (shape.Pinned || null == (parentShape = shape.Parent) || null == (factShape = shape.Shape as FactTypeShape)) { return; } NodeShape objectShape = parentShape.Shape; ModelElement objectElement = parentShape.Shape.ModelElement; FactType factElement; if (null != (factElement = objectElement as FactType)) { Objectification objectification = factElement.Objectification; if (objectification != null) { objectElement = objectification.NestingType; } } factElement = factShape.ModelElement as FactType; LinkedElementCollection <RoleBase> roles = factShape.DisplayedRoleOrder; // set the index at which the role will be closest to otherLayoutShape int targetIndex = 0; LayoutShape objectLayoutShape; PointD objectShapeLocation = myLayoutShapes.TryGetValue(objectShape, out objectLayoutShape) ? objectLayoutShape.TargetLocation : objectShape.Location; SizeD objectShapeSize = objectShape.Size; objectShapeLocation.Offset(objectShapeSize.Width / 2, objectShapeSize.Height / 2); if (objectShapeLocation.X > shape.TargetLocation.X + (factShape.Size.Width / 2)) { targetIndex = roles.Count - 1; } // find actual index bool haveEditableOrder = false; int roleCount = roles.Count; for (int i = 0; i < roleCount; ++i) { if (roles[i].Role.RolePlayer == objectElement) { if (i == targetIndex) { if (!haveEditableOrder) { haveEditableOrder = true; roles = factShape.GetEditableDisplayRoleOrder(); } roles.Move(i, targetIndex); break; } } } }
/// <summary>See <see cref="RolePlayerElementPropertyDescriptor.SetValue"/>.</summary> public override void SetValue(object component, object value) { ObjectType objectType; if (myIsReadOnly || null == (objectType = EditorUtility.ResolveContextInstance(component, false) as ObjectType)) { return; } IORMToolServices toolServices; AutomatedElementFilterCallback callback = null; Store store = objectType.Store; if (null != (toolServices = store as IORMToolServices)) { callback = delegate(ModelElement filterElement) { FactType factType; return(filterElement is ObjectType || (null != (factType = filterElement as FactType) && null == factType.ImpliedByObjectification) ? AutomatedElementDirective.NeverIgnore : AutomatedElementDirective.None); }; toolServices.AutomatedElementFilter += callback; } try { using (Transaction transaction = BeginTransaction(store)) { FactType factType = value as FactType; if (factType != null) { Objectification.CreateExplicitObjectification(factType, objectType); } else { objectType.NestedFactType = null; } if (transaction.HasPendingChanges) { transaction.Commit(); } } } finally { if (toolServices != null) { toolServices.AutomatedElementFilter -= callback; } } }
/// <summary> /// Returns a list of fact types that can be nested by an entity type. /// Currently nested fact types are filtered out, as well as fact types /// where the current object type is a role player. /// </summary> /// <param name="context">ITypeDescriptorContext. Used to retrieve the selected instance</param> /// <param name="value">The current value</param> /// <returns>A list of candidates</returns> protected sealed override IList GetContentList(ITypeDescriptorContext context, object value) { Debug.Assert(!(value is object[])); ObjectType instance = (ObjectType)EditorUtility.ResolveContextInstance(context.Instance, false); // false indicates this should not be called in multiselect mode. ReadOnlyCollection <FactType> candidates = instance.Store.ElementDirectory.FindElements <FactType>(); int count = candidates.Count; if (count > 0) { IComparer <FactType> comparer = ModelElementIdComparer <FactType> .Instance; LinkedElementCollection <Role> playedRoles = instance.PlayedRoleCollection; FactType[] playedFacts = new FactType[playedRoles.Count]; for (int i = 0; i < playedFacts.Length; ++i) { playedFacts[i] = playedRoles[i].FactType; } Array.Sort(playedFacts, comparer); List <FactType> types = new List <FactType>(count); // Always include the current value in the list if it is not null if (value != null) { types.Add(value as FactType); } foreach (FactType factType in candidates) { // SubtypeFacts and facts implied by an objectification can't be objectified if (factType is SubtypeFact || factType.ImpliedByObjectification != null) { continue; } Objectification objectification = factType.Objectification; if (objectification == null || objectification.IsImplied) { // Make sure that the nested fact does not parent a role with this // instance as a role player. // This is backed up in the metamodel rules and other pickers. if (Array.BinarySearch(playedFacts, factType, comparer) < 0) { types.Add(factType); } } } if (types.Count > 1) { types.Sort(NamedElementComparer <FactType> .CurrentCulture); } return(types); } return(candidates); }
/// <summary> /// Returns a list of role player candidates for a fact type. /// The nesting types of this fact type and of implied objectifications are filtered out of the list. /// </summary> /// <param name="context">ITypeDescriptorContext. Used to retrieve the selected instance</param> /// <param name="value">The current value</param> /// <returns>A list of candidates</returns> protected sealed override IList GetContentList(ITypeDescriptorContext context, object value) { Role instance = (Role)EditorUtility.ResolveContextInstance(context.Instance, true); ReadOnlyCollection <ObjectType> candidates = instance.Store.ElementDirectory.FindElements <ObjectType>(); int candidatesCount = candidates.Count; switch (candidatesCount) { case 0: break; case 1: { ObjectType objType = candidates[0]; Objectification objectification; if (objType.IsImplicitBooleanValue || (null != (objectification = objType.Objectification) && !objectification.IsImplied && objectification == instance.FactType.Objectification)) { return(new ObjectType[0]); } } break; default: { // Make sure we're sorted List <ObjectType> types = new List <ObjectType>(candidatesCount); Objectification thisObjectification = instance.FactType.Objectification; foreach (ObjectType objType in candidates) { Objectification objectification = objType.Objectification; if (!objType.IsImplicitBooleanValue && (null == (objectification = objType.Objectification) || (objectification != thisObjectification && !objectification.IsImplied))) { types.Add(objType); } } if (types.Count > 1) { types.Sort(NamedElementComparer <ObjectType> .CurrentCulture); } return(types); } } return(candidates); }
/// <summary> /// Ensure that the <see cref="ObjectType.IsValueType"/> property is read-only when /// <see cref="ObjectType.NestedFactType"/> is not <see langword="null"/>, /// <see cref="ObjectType.PreferredIdentifier"/> is not <see langword="null"/>, or /// <see cref="ObjectType.IsSubtypeOrSupertype"/> is <see langword="true"/>. /// Ensure that the <see cref="ObjectType.ValueRangeText"/> property is read-only when /// <see cref="ObjectType.IsValueType"/> is <see langword="false"/> and /// <see cref="ObjectType.HasReferenceMode"/> is <see langword="false"/>. /// Ensure that the <see cref="ObjectType.IsIndependent"/> property is read-only when /// when <see cref="ObjectType.Objectification"/> is not <see langword="null"/> and /// <see cref="Objectification.IsImplied"/> is <see langword="true"/>, or /// <see cref="ObjectType.AllowIsIndependent()"/> returns <see langword="false"/> /// Ensure that the <see cref="ObjectType.ReferenceModeDisplay"/> property is read-only /// when <see cref="ObjectType.Objectification"/> is not <see langword="null"/> and /// <see cref="Objectification.IsImplied"/> is <see langword="true"/>. /// </summary> protected override bool IsPropertyDescriptorReadOnly(ElementPropertyDescriptor propertyDescriptor) { ObjectType objectType = ModelElement; Guid propertyId = propertyDescriptor.DomainPropertyInfo.Id; if (objectType.IsImplicitBooleanValue) { return(true); } else if (propertyId == ObjectType.IsValueTypeDomainPropertyId) { return(objectType.NestedFactType != null || objectType.PreferredIdentifier != null || objectType.IsSubtypeOrSupertype); } else if (propertyId == ObjectType.ValueRangeTextDomainPropertyId) { return(!(objectType.IsValueType || objectType.HasReferenceMode)); } else if (propertyId == ObjectType.IsIndependentDomainPropertyId) { if (objectType.IsIndependent) { Objectification objectification = objectType.Objectification; return(objectification != null && objectification.IsImplied); } else { return(!objectType.AllowIsIndependent()); } } else if (propertyId == ObjectType.ReferenceModeDisplayDomainPropertyId) { Objectification objectification = objectType.Objectification; return(objectification != null && objectification.IsImplied); } else if (propertyId == ObjectType.TreatAsPersonalDomainPropertyId) { return(objectType.IsSupertypePersonal); } else { return(base.IsPropertyDescriptorReadOnly(propertyDescriptor)); } }
/// <summary> /// Show selected properties from the <see cref="FactType.NestingType"/> and the /// <see cref="Objectification.NestedFactType"/> for an objectified <see cref="FactType"/>, /// as well as expandable nodes for each of the underlying instances. /// </summary> public override PropertyDescriptorCollection GetProperties(Attribute[] attributes) { FactType factType = ModelElement; if (FactTypeShape.ShouldDrawObjectification(factType)) { FactTypeShape factTypeShape = PresentationElement; Objectification objectification = factType.Objectification; ObjectType nestingType = objectification.NestingType; bool nestingTypeHasRelatedTypes = nestingType.IsSubtypeOrSupertype; DomainDataDirectory domainDataDirectory = factType.Store.DomainDataDirectory; EnsureDomainAttributesInitialized(domainDataDirectory); PropertyDescriptorCollection retVal; if (factTypeShape.DisplayAsObjectType) { retVal = new PropertyDescriptorCollection(null); Type componentType = typeof(FactTypeShape); foreach (PropertyDescriptor nestingTypeDescriptor in TypeDescriptor.GetProperties(nestingType)) { if (nestingTypeDescriptor.Name == "NestedFactType") { continue; } retVal.Add(EditorUtility.RedirectPropertyDescriptor(nestingType, nestingTypeDescriptor, componentType)); } retVal.Add(CreatePropertyDescriptor(factTypeShape, domainDataDirectory.FindDomainProperty(FactTypeShape.DisplayAsObjectTypeDomainPropertyId), DisplayAsObjectTypeDomainPropertyAttributes)); retVal.Add(CreatePropertyDescriptor(factTypeShape, domainDataDirectory.FindDomainProperty(FactTypeShape.ExpandRefModeDomainPropertyId), ExpandRefModeDomainPropertyAttributes)); retVal.Add(new ObjectifyingEntityTypePropertyDescriptor(factType, domainDataDirectory.FindDomainRole(Objectification.NestingTypeDomainRoleId), NestedFactTypeDomainRoleAttributes)); retVal.Add(new ObjectifiedFactTypePropertyDescriptor(nestingType, domainDataDirectory.FindDomainRole(Objectification.NestedFactTypeDomainRoleId), NestingTypeDomainRoleAttributes)); if (nestingTypeHasRelatedTypes) { retVal.Add(CreatePropertyDescriptor(factTypeShape, domainDataDirectory.FindDomainProperty(FactTypeShape.DisplayRelatedTypesDomainPropertyId), DisplayRelatedTypesDomainPropertyAttributes)); } } else { PropertyDescriptor[] descriptors = new PropertyDescriptor[nestingTypeHasRelatedTypes ? 9 : 8]; descriptors[0] = CreatePropertyDescriptor(factTypeShape, domainDataDirectory.FindDomainProperty(FactTypeShape.ConstraintDisplayPositionDomainPropertyId), ConstraintDisplayPositionDomainPropertyAttributes); descriptors[1] = CreatePropertyDescriptor(factTypeShape, domainDataDirectory.FindDomainProperty(FactTypeShape.DisplayOrientationDomainPropertyId), DisplayOrientationDomainPropertyAttributes); descriptors[2] = CreatePropertyDescriptor(factTypeShape, domainDataDirectory.FindDomainProperty(FactTypeShape.DisplayRoleNamesDomainPropertyId), DisplayRoleNamesDomainPropertyAttributes); descriptors[3] = CreatePropertyDescriptor(factTypeShape, domainDataDirectory.FindDomainProperty(FactTypeShape.DisplayAsObjectTypeDomainPropertyId), DisplayAsObjectTypeDomainPropertyAttributes); descriptors[4] = CreatePropertyDescriptor(nestingType, domainDataDirectory.FindDomainProperty(ORMNamedElement.NameDomainPropertyId), NameDomainPropertyAttributes); descriptors[5] = CreatePropertyDescriptor(nestingType, domainDataDirectory.FindDomainProperty(ObjectType.IsIndependentDomainPropertyId), IsIndependentDomainPropertyAttributes); descriptors[6] = new ObjectifyingEntityTypePropertyDescriptor(factType, domainDataDirectory.FindDomainRole(Objectification.NestingTypeDomainRoleId), NestedFactTypeDomainRoleAttributes); descriptors[7] = new ObjectifiedFactTypePropertyDescriptor(nestingType, domainDataDirectory.FindDomainRole(Objectification.NestedFactTypeDomainRoleId), NestingTypeDomainRoleAttributes); if (nestingTypeHasRelatedTypes) { descriptors[8] = CreatePropertyDescriptor(factTypeShape, domainDataDirectory.FindDomainProperty(FactTypeShape.DisplayRelatedTypesDomainPropertyId), DisplayRelatedTypesDomainPropertyAttributes); } retVal = new PropertyDescriptorCollection(descriptors); } // This mockup of important properties means that extension providers cannot add properties // here by adding to the objecttype or facttype. Use an extension on the Objectification type // itself to add extension properties. ((IFrameworkServices)factType.Store).PropertyProviderService.GetProvidedProperties(objectification, retVal); return(retVal); } return(base.GetProperties(attributes)); }
/// <summary> /// Distinguish between objectified and non-objectified <see cref="FactType"/>s in the property grid display. /// </summary> public override string GetClassName() { Objectification objectification = ModelElement.Objectification; return((objectification == null || objectification.IsImplied) ? ResourceStrings.FactType : ResourceStrings.ObjectifiedFactType); }