public override void ElementPropertyChanged(ElementPropertyChangedEventArgs e) { base.ElementPropertyChanged(e); ModelEnumValue element = (ModelEnumValue)e.ModelElement; if (element.IsDeleted) { return; } ModelEnum modelEnum = element.Enum; Store store = element.Store; Transaction current = store.TransactionManager.CurrentTransaction; if (current.IsSerializing || ModelRoot.BatchUpdating) { return; } if (Equals(e.NewValue, e.OldValue)) { return; } string errorMessage = null; switch (e.DomainProperty.Name) { case "Name": string newName = (string)e.NewValue; Match match = Regex.Match(newName, @"(.+)\s*=\s*(\d+)"); if (match != Match.Empty) { newName = match.Groups[1].Value; element.Value = match.Groups[2].Value; } if (string.IsNullOrWhiteSpace(newName) || !CodeGenerator.IsValidLanguageIndependentIdentifier(newName)) { errorMessage = $"{modelEnum.Name}.{newName}: Name must be a valid .NET identifier"; } else if (modelEnum.Values.Except(new[] { element }).Any(v => v.Name == newName)) { errorMessage = $"{modelEnum.Name}.{newName}: Name already in use"; } else if (!string.IsNullOrWhiteSpace((string)e.OldValue)) { // find ModelAttributes where the default value is this ModelEnumValue and change it to the new name string oldInitialValue = $"{modelEnum.Name}.{e.OldValue}"; string newInitialValue = $"{modelEnum.Name}.{e.NewValue}"; foreach (ModelAttribute modelAttribute in store.Get <ModelAttribute>().Where(a => a.InitialValue == oldInitialValue)) { modelAttribute.InitialValue = newInitialValue; } } break; case "Value": string newValue = (string)e.NewValue; //if (modelEnum.IsFlags) //{ // int index = modelEnum.Values.IndexOf(element); // int properValue = (int)Math.Pow(2, index); // if (newValue != properValue.ToString()) // current.Rollback(); // return; //} if (newValue != null) { bool badValue = false; switch (modelEnum.ValueType) { case EnumValueType.Int16: badValue = !short.TryParse(newValue, out short _); break; case EnumValueType.Int32: badValue = !int.TryParse(newValue, out int _); break; case EnumValueType.Int64: badValue = !long.TryParse(newValue, out long _); break; } if (badValue) { errorMessage = $"Invalid value for {modelEnum.Name}. Must be {modelEnum.ValueType}."; } else { bool hasDuplicates = modelEnum.Values.Any(x => x != element && x.Value == newValue); if (hasDuplicates) { errorMessage = $"Value {newValue} is already present in {modelEnum.Name}. Can't have duplicate values."; } } } break; } if (errorMessage != null) { current.Rollback(); ErrorDisplay.Show(errorMessage); } }
// ReSharper disable once UnusedMethodReturnValue.Local private static ModelEnum ProcessEnum([NotNull] Store store, [NotNull] EnumDeclarationSyntax enumDecl, NamespaceDeclarationSyntax namespaceDecl = null) { ModelEnum result = null; if (store == null) { throw new ArgumentNullException(nameof(store)); } if (enumDecl == null) { throw new ArgumentNullException(nameof(enumDecl)); } ModelRoot modelRoot = store.ElementDirectory.AllElements.OfType <ModelRoot>().FirstOrDefault(); string enumName = enumDecl.Identifier.Text; if (namespaceDecl == null && enumDecl.Parent is NamespaceDeclarationSyntax enumDeclParent) { namespaceDecl = enumDeclParent; } string namespaceName = namespaceDecl?.Name?.ToString() ?? modelRoot.Namespace; if (store.ElementDirectory.AllElements.OfType <ModelClass>().Any(c => c.Name == enumName) || store.ElementDirectory.AllElements.OfType <ModelEnum>().Any(c => c.Name == enumName)) { ErrorDisplay.Show($"'{enumName}' already exists in model."); // ReSharper disable once ExpressionIsAlwaysNull return(result); } Transaction tx = store.TransactionManager.CurrentTransaction == null ? store.TransactionManager.BeginTransaction() : null; try { result = new ModelEnum(store, new PropertyAssignment(ModelEnum.NameDomainPropertyId, enumName)) { Namespace = namespaceName, IsFlags = enumDecl.HasAttribute("Flags") }; SimpleBaseTypeSyntax baseTypeSyntax = enumDecl.DescendantNodes().OfType <SimpleBaseTypeSyntax>().FirstOrDefault(); if (baseTypeSyntax != null) { switch (baseTypeSyntax.Type.ToString()) { case "Int16": case "short": result.ValueType = EnumValueType.Int16; break; case "Int32": case "int": result.ValueType = EnumValueType.Int32; break; case "Int64": case "long": result.ValueType = EnumValueType.Int64; break; default: WarningDisplay.Show($"Could not resolve value type for '{enumName}'. The enum will default to an Int32 value type."); break; } } XMLDocumentation xmlDocumentation; foreach (EnumMemberDeclarationSyntax enumValueDecl in enumDecl.DescendantNodes().OfType <EnumMemberDeclarationSyntax>()) { ModelEnumValue enumValue = new ModelEnumValue(store, new PropertyAssignment(ModelEnumValue.NameDomainPropertyId, enumValueDecl.Identifier.ToString())); EqualsValueClauseSyntax valueDecl = enumValueDecl.DescendantNodes().OfType <EqualsValueClauseSyntax>().FirstOrDefault(); if (valueDecl != null) { enumValue.Value = valueDecl.Value.ToString(); } xmlDocumentation = new XMLDocumentation(enumValueDecl); enumValue.Summary = xmlDocumentation.Summary; enumValue.Description = xmlDocumentation.Description; result.Values.Add(enumValue); } xmlDocumentation = new XMLDocumentation(enumDecl); result.Summary = xmlDocumentation.Summary; result.Description = xmlDocumentation.Description; modelRoot.Enums.Add(result); } catch { tx = null; throw; } finally { tx?.Commit(); } return(result); }
/// <summary> /// User has released the mouse button. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Compartment_MouseUp(object sender, DiagramMouseEventArgs e) { dragStartElement = null; }
/// <summary> /// Remember which item the mouse was dragged from. /// We don't create an Action immediately, as this would inhibit the /// inline text editing feature. Instead, we just remember the details /// and will create an Action when/if the mouse moves off this list item. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Compartment_MouseDown(object sender, DiagramMouseEventArgs e) { dragStartElement = e.HitDiagramItem.RepresentedElements.OfType <ModelEnumValue>().FirstOrDefault(); compartmentBounds = e.HitDiagramItem.Shape.AbsoluteBoundingBox; }
/// <summary> /// Forget the source item if mouse up occurs outside the compartment. /// </summary> /// <param name="e"></param> public override void OnMouseUp(DiagramMouseEventArgs e) { base.OnMouseUp(e); dragStartElement = null; }
/// <summary> /// Get the embedding link to this element. /// Assumes there is no inheritance between embedding relationships. /// (If there is, you need to make sure you've got the relationship that is represented in the shape compartment.) /// </summary> /// <param name="child"></param> /// <returns></returns> private ElementLink GetEmbeddingLink(ModelEnumValue child) => child.GetDomainClass() .AllEmbeddedByDomainRoles .SelectMany(role => role.OppositeDomainRole.GetElementLinks(child)) .FirstOrDefault();