Example #1
0
        /// <summary>Called by the control's OnDoubleClick()</summary>
        /// <param name="e">A DiagramPointEventArgs that contains event data.</param>
        public override void OnDoubleClick(DiagramPointEventArgs e)
        {
            base.OnDoubleClick(e);

            if (OpenCodeFile != null)
            {
                ModelClass modelClass = (ModelClass)ModelElement;

                if (OpenCodeFile(modelClass))
                {
                    return;
                }

                if (!modelClass.GenerateCode)
                {
                    ErrorDisplay.Show(Store, $"{modelClass.Name} has its GenerateCode property set to false. No file available to open.");

                    return;
                }

                if (ExecCodeGeneration != null && BooleanQuestionDisplay.Show(Store, $"Can't open generated file for {modelClass.Name}. It may not have been generated yet. Do you want to generate the code now?") == true)
                {
                    ExecCodeGeneration();

                    if (OpenCodeFile(modelClass))
                    {
                        return;
                    }
                }

                ErrorDisplay.Show(Store, $"Can't open generated file for {modelClass.Name}");
            }
        }
Example #2
0
        //private void ObjectModelBrowser_OnNodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        //{
        //            // select element in tree
        //   if (PrimarySelection != null && PrimarySelection is ModelElement element)
        //   {
        //      using (Transaction t = element.Store.TransactionManager.BeginTransaction("TreeSelectionChanged"))
        //      {
        //         Diagram diagram = element.GetActiveDiagramView()?.Diagram;

        //         switch (PrimarySelection)
        //         {
        //            case ModelDiagramData modelDiagramData:
        //               // user selected a diagram. Open it.
        //               EFModelDocData docData = (EFModelDocData)TreeContainer.ModelingDocData;
        //               docData.OpenView(Constants.LogicalView, new Mexedge.VisualStudio.Modeling.ViewContext(modelDiagramData.Name, typeof(EFModelDiagram), docData.RootElement));

        //               break;

        //            case ModelClass modelClass:
        //               // user selected a class. If it's in the current diagram, find it, center it and make it visible
        //               ShapeElement primaryShapeElement = PresentationViewsSubject.GetPresentation(modelClass)
        //                                                                          .OfType<ShapeElement>()
        //                                                                          .FirstOrDefault(s => s.Diagram == diagram);

        //               if (primaryShapeElement == null || !primaryShapeElement.IsVisible)
        //                  break;

        //               modelClass.LocateInDiagram(true);

        //               // then fix up the compartments since they might need it
        //               ModelElement[] classElements = {modelClass};
        //               CompartmentItemAddRule.UpdateCompartments(classElements, typeof(ClassShape), "AttributesCompartment", false);
        //               CompartmentItemAddRule.UpdateCompartments(classElements, typeof(ClassShape), "AssociationsCompartment", false);
        //               CompartmentItemAddRule.UpdateCompartments(classElements, typeof(ClassShape), "SourcesCompartment", false);

        //               // any associations to visible classes on this diagram need to be visible as well
        //               foreach (NavigationProperty navigationProperty in modelClass.LocalNavigationProperties())
        //               {
        //                  ModelClass other = navigationProperty.AssociationObject.Dependent == modelClass
        //                                           ? navigationProperty.AssociationObject.Principal
        //                                           : navigationProperty.AssociationObject.Dependent;

        //                  ShapeElement shapeElement = PresentationViewsSubject.GetPresentation(other)
        //                                                                      .OfType<ShapeElement>()
        //                                                                      .FirstOrDefault(s => s.Diagram == diagram);

        //                  if (shapeElement != null && shapeElement.IsVisible)
        //                  {
        //                     ShapeElement connectorElement = PresentationViewsSubject.GetPresentation(navigationProperty.AssociationObject)
        //                                                                             .OfType<AssociationConnector>()
        //                                                                             .FirstOrDefault(s => s.Diagram == diagram);
        //                     connectorElement?.Show();
        //                  }
        //               }

        //               FixUpAllDiagrams.FixUp(diagram, modelClass.ModelRoot, modelClass);

        //               break;

        //            case ModelEnum modelEnum:
        //               // user selected an enum. Find it in the current diagram, center it and make it visible
        //               modelEnum.LocateInDiagram(true);

        //               // then fix up the compartment since it might need it
        //               ModelElement[] enumElements = {modelEnum};
        //               CompartmentItemAddRule.UpdateCompartments(enumElements, typeof(EnumShape), "ValuesCompartment", false);
        //               FixUpAllDiagrams.FixUp(diagram, modelEnum.ModelRoot, modelEnum);

        //               break;
        //         }

        //         t.Commit();
        //      }
        //   }

        //}

        /// <summary>Virtual method to process the menu Delete operation</summary>
        protected override void ProcessOnMenuDeleteCommand()
        {
            if (SelectedElement is ModelDiagramData diagramData)
            {
                if (BooleanQuestionDisplay.Show($"About to permanently delete diagram named {diagramData.Name} - are you sure?") == true)
                {
                    base.ProcessOnMenuDeleteCommand();
                    ObjectModelBrowser.SelectedNode = null;
                }
            }
            else if (SelectedElement is ModelEnum modelEnum)
            {
                if (!ModelEnum.IsUsed(modelEnum) ||
                    BooleanQuestionDisplay.Show($"{modelEnum.FullName} is used as an entity property. Deleting the enumeration will remove those properties. Are you sure?") == true)

                {
                    base.ProcessOnMenuDeleteCommand();
                    ObjectModelBrowser.SelectedNode = null;
                }
            }
            else
            {
                base.ProcessOnMenuDeleteCommand();
                ObjectModelBrowser.SelectedNode = null;
            }
        }
Example #3
0
        /// <summary>Called by the control's OnDoubleClick()</summary>
        /// <param name="e">A DiagramPointEventArgs that contains event data.</param>
        public override void OnDoubleClick(DiagramPointEventArgs e)
        {
            base.OnDoubleClick(e);

            if (OpenCodeFile != null)
            {
                ModelEnum modelEnum = (ModelEnum)ModelElement;

                if (OpenCodeFile(modelEnum))
                {
                    return;
                }

                if (ExecCodeGeneration != null && BooleanQuestionDisplay.Show($"Can't open generated file for {modelEnum.Name}. It may not have been generated yet. Do you want to generate the code now?") == true)
                {
                    ExecCodeGeneration();

                    if (OpenCodeFile(modelEnum))
                    {
                        return;
                    }
                }

                ErrorDisplay.Show($"Can't open generated file for {modelEnum.Name}");
            }
        }
Example #4
0
        public override void ElementDeleting(ElementDeletingEventArgs e)
        {
            base.ElementDeleting(e);

            ModelClass  element = (ModelClass)e.ModelElement;
            Store       store   = element.Store;
            Transaction current = store.TransactionManager.CurrentTransaction;

            if (current.IsSerializing || ModelRoot.BatchUpdating)
            {
                return;
            }

            foreach (ModelAttribute attribute in element.Attributes)
            {
                attribute.SetLocks(Locks.None);
            }

            List <Generalization> generalizations = store.GetAll <Generalization>().Where(g => g.Superclass == element).ToList();

            if (generalizations.Any())
            {
                string question = generalizations.Count == 1
                                 ? $"Push {element.Name} attributes and associations down its to its subclass?"
                                 : $"Push {element.Name} attributes and associations down its to {generalizations.Count} subclasses?";

                if (BooleanQuestionDisplay.Show(store, question) == true)
                {
                    foreach (ModelClass subclass in generalizations.Select(g => g.Subclass))
                    {
                        element.MoveContents(subclass);
                    }
                }
            }
        }
        /// <inheritdoc />
        public override void ElementDeleting(ElementDeletingEventArgs e)
        {
            base.ElementDeleting(e);

            ModelDiagramData element = (ModelDiagramData)e.ModelElement;
            Store            store   = element.Store;
            Transaction      current = store.TransactionManager.CurrentTransaction;

            if (current.IsSerializing || ModelRoot.BatchUpdating)
            {
                return;
            }

            if (BooleanQuestionDisplay.Show($"About to permanently delete diagram named {element.Name} - are you sure?") != true)
            {
                current.Rollback();

                return;
            }

            EFModelDiagram diagram = element.GetDiagram();

            ModelDiagramData.CloseDiagram?.Invoke(diagram);
            diagram.Delete();
        }
      private bool TryParse(string assemblyPath, ref List<ModelElement> newElements, string parserPath, string outputFilename, string logFilename, Dictionary<string, bool> contexts)
      {
         string contextName = contexts.Any(kv => contexts[kv.Key])
                                 ? contexts.First(kv => contexts[kv.Key]).Key
                                 : null;

         if (contexts.Any() && string.IsNullOrEmpty(contextName))
            return false;

         int parseResult = TryParseAssembly(assemblyPath, parserPath, outputFilename, contextName);

         if (parseResult == 0)
            return DoProcessing(outputFilename, out newElements);

         if (!contexts.Any())
         {
            string dupeContextTag = "Found more than one class derived from DbContext:";
            string dupeContextLogEntry = File.ReadAllLines(logFilename).FirstOrDefault(logEntry => logEntry.Contains(dupeContextTag));

            if (dupeContextLogEntry != null)
            {
               IEnumerable<string> contextNames = dupeContextLogEntry.Substring(dupeContextLogEntry.IndexOf(dupeContextTag, StringComparison.InvariantCulture) + dupeContextTag.Length).Split(',')
                                                                     .Select(s => s.Trim().Split('.').Last());

               foreach (string context in contextNames)
                  contexts.Add(context, BooleanQuestionDisplay.Show(Store, $"Found multiple DbContext classes. Process {context}?") == true);

               return TryParse(assemblyPath, ref newElements, parserPath, outputFilename, logFilename, contexts);
            }
         }

         return false;
      }
        /// <inheritdoc />
        public override void ElementDeleting(ElementDeletingEventArgs e)
        {
            base.ElementDeleting(e);

            Generalization element = (Generalization)e.ModelElement;
            Store          store   = element.Store;
            Transaction    current = store.TransactionManager.CurrentTransaction;

            if (current.IsSerializing || ModelRoot.BatchUpdating)
            {
                return;
            }

            if (element.Superclass.IsDeleting)
            {
                return;
            }

            ModelClass         superclass   = element.Superclass;
            ModelClass         subclass     = element.Subclass;
            List <Association> associations = store.Get <Association>().Where(a => a.Source == superclass || a.Target == superclass).ToList();

            if (!superclass.AllAttributes.Any() && !associations.Any())
            {
                return;
            }

            if (!subclass.IsDeleting && BooleanQuestionDisplay.Show($"Push {superclass.Name} attributes and associations down to {subclass.Name}?") == true)
            {
                superclass.PushDown(subclass);
            }
        }
Example #8
0
        /// <summary>Virtual method to process the menu Delete operation</summary>
        protected override void ProcessOnMenuDeleteCommand()
        {
            foreach (EnumShape enumShape in CurrentSelection.OfType <EnumShape>())
            {
                if (enumShape.ModelElement is ModelEnum modelEnum &&
                    ModelEnum.IsUsed(modelEnum) &&
                    BooleanQuestionDisplay.Show($"{modelEnum.FullName} is used as an entity property. Deleting the enumeration will remove those properties. Are you sure?") != true)
                {
                    return;
                }
            }

            base.ProcessOnMenuDeleteCommand();
        }
Example #9
0
        /// <summary>Virtual method to process the menu Delete operation</summary>
        protected override void ProcessOnMenuDeleteCommand()
        {
            switch (SelectedElement)
            {
            case ModelDiagramData diagramData when BooleanQuestionDisplay.Show($"About to permanently delete diagram named {diagramData.Name} - are you sure?") == true:
            {
                base.ProcessOnMenuDeleteCommand();

                break;
            }

            case ModelEnum modelEnum when !ModelEnum.IsUsed(modelEnum) ||
                BooleanQuestionDisplay.Show($"{modelEnum.FullName} is used as an entity property. Deleting the enumeration will remove those properties. Are you sure?") == true:
            {
                base.ProcessOnMenuDeleteCommand();

                break;
            }
            }
        }
Example #10
0
        /// <summary>Virtual method to process the menu Delete operation</summary>
        protected override void ProcessOnMenuDeleteCommand()
        {
            TreeNode diagramRoot = ObjectModelBrowser.SelectedNode?.Parent;

            switch (SelectedElement)
            {
            case ModelDiagramData diagramData:
            {
                if (BooleanQuestionDisplay.Show(diagramData.Store, $"About to permanently delete diagram named {diagramData.Name} - are you sure?") == true)
                {
                    base.ProcessOnMenuDeleteCommand();
                    ObjectModelBrowser.SelectedNode = null;
                }

                break;
            }

            case ModelEnum modelEnum:
            {
                string fullName = modelEnum.FullName.Split('.').Last();

                if (!ModelEnum.IsUsed(modelEnum) ||
                    BooleanQuestionDisplay.Show(modelEnum.Store, $"{fullName} is used as an entity property. Deleting the enumeration will remove those properties. Are you sure?") == true)
                {
                    base.ProcessOnMenuDeleteCommand();
                    ObjectModelBrowser.SelectedNode = null;
                }

                break;
            }

            default:
                base.ProcessOnMenuDeleteCommand();
                ObjectModelBrowser.SelectedNode = null;

                break;
            }

            diagramRoot?.Expand();
        }
Example #11
0
        /// <inheritdoc />
        public override void ElementDeleting(ElementDeletingEventArgs e)
        {
            base.ElementDeleting(e);

            Generalization element = (Generalization)e.ModelElement;
            Store          store   = element.Store;
            Transaction    current = store.TransactionManager.CurrentTransaction;

            if (current.IsSerializing || ModelRoot.BatchUpdating)
            {
                return;
            }

            if (element.Superclass.IsDeleting)
            {
                return;
            }

            ModelClass subclass   = element.Subclass;
            ModelClass superclass = element.Superclass;

            List <Association> associations = superclass.AllNavigationProperties()
                                              .Select(n => n.AssociationObject)
                                              .Distinct()
                                              .ToList();

            if (!superclass.AllAttributes.Any() && !associations.Any())
            {
                return;
            }

            if (!subclass.IsDeleting && BooleanQuestionDisplay.Show(store, $"Push {superclass.Name} attributes and associations down to {subclass.Name}?") == true)
            {
                superclass.PushDown(subclass);
            }
        }
Example #12
0
        private ModelClass ProcessClass([NotNull] ClassDeclarationSyntax classDecl, List <ModelElement> newElements, NamespaceDeclarationSyntax namespaceDecl = null)
        {
            ModelClass result;

            if (classDecl == null)
            {
                throw new ArgumentNullException(nameof(classDecl));
            }

            ModelRoot modelRoot = Store.ModelRoot();
            string    className = classDecl.Identifier.Text.Split(':').LastOrDefault();

            if (!ValidateInput())
            {
                return(null);
            }

            Transaction tx = Store.TransactionManager.CurrentTransaction == null
                             ? Store.TransactionManager.BeginTransaction()
                             : null;

            List <string> customInterfaces = new List <string>();

            try
            {
                result = Store.GetAll <ModelClass>().FirstOrDefault(c => c.Name == className);

                if (result == null)
                {
                    result = new ModelClass(Store
                                            , new PropertyAssignment(ModelClass.NameDomainPropertyId, className)
                                            , new PropertyAssignment(ModelClass.NamespaceDomainPropertyId, namespaceDecl?.Name.ToString() ?? modelRoot.Namespace)
                                            , new PropertyAssignment(ModelClass.IsAbstractDomainPropertyId, classDecl.DescendantNodes().Any(n => n.Kind() == SyntaxKind.AbstractKeyword)));

                    newElements.Add(result);
                    modelRoot.Classes.Add(result);
                }

                ModelClass superClass = FindSuperClass();

                if (superClass != null)
                {
                    result.Superclass = superClass;
                }

                if (result.CustomInterfaces != null)
                {
                    customInterfaces.AddRange(result.CustomInterfaces
                                              .Split(',')
                                              .Where(i => !string.IsNullOrEmpty(i))
                                              .Select(i => i.Trim()));
                }

                if (customInterfaces.Contains("INotifyPropertyChanged"))
                {
                    result.ImplementNotify = true;
                    customInterfaces.Remove("INotifyPropertyChanged");
                }

                if (result.Superclass != null && customInterfaces.Contains(result.Superclass.Name))
                {
                    customInterfaces.Remove(result.Superclass.Name);
                }

                result.CustomInterfaces = customInterfaces.Any()
                                         ? string.Join(",", customInterfaces.Distinct())
                                         : null;

                AttributeSyntax tableAttribute = classDecl.GetAttribute("Table");

                if (tableAttribute != null)
                {
                    result.TableName = tableAttribute.GetAttributeArguments().First().Expression.ToString().Trim('"');

                    string schemaName = tableAttribute.GetNamedArgumentValue("Schema");
                    if (schemaName != null)
                    {
                        result.DatabaseSchema = schemaName;
                    }
                }

                XMLDocumentation xmlDocumentation = new XMLDocumentation(classDecl);
                result.Summary     = xmlDocumentation.Summary;
                result.Description = xmlDocumentation.Description;
                tx?.Commit();
            }
            catch
            {
                tx?.Rollback();
                throw;
            }

            return(result);

            ModelClass FindSuperClass()
            {
                ModelClass superClass = null;

                // Base classes and interfaces
                // Check these first. If we need to add new models, we want the base class already in the store
                IEnumerable <BaseTypeSyntax> baseTypes = (classDecl.BaseList?.Types ?? Enumerable.Empty <BaseTypeSyntax>());

                foreach (string baseName in baseTypes.Select(type => type.ToString().Split(':').Last()))
                {
                    // Do we know this is an interface?
                    if (KnownInterfaces.Contains(baseName) || superClass != null || result.Superclass != null)
                    {
                        customInterfaces.Add(baseName);

                        if (!KnownInterfaces.Contains(baseName))
                        {
                            KnownInterfaces.Add(baseName);
                        }

                        continue;
                    }

                    // is it inheritance or an interface?
                    superClass = modelRoot.Classes.FirstOrDefault(c => c.Name == baseName);

                    // if it's not in the model, we just don't know. Ask the user
                    if (superClass == null && (KnownClasses.Contains(baseName) || BooleanQuestionDisplay.Show(Store, $"For class {className}, is {baseName} the base class?") == true))
                    {
                        string[] nameparts = baseName.Split('.');

                        superClass = nameparts.Length == 1
                                  ? new ModelClass(Store, new PropertyAssignment(ModelClass.NameDomainPropertyId, nameparts.Last()))
                                  : new ModelClass(Store
                                                   , new PropertyAssignment(ModelClass.NameDomainPropertyId, nameparts.Last())
                                                   , new PropertyAssignment(ModelClass.NamespaceDomainPropertyId, string.Join(".", nameparts.Take(nameparts.Length - 1))));

                        modelRoot.Classes.Add(superClass);
                    }
                    else
                    {
                        customInterfaces.Add(baseName);
                        KnownInterfaces.Add(baseName);
                    }
                }

                return(superClass);
            }

            bool ValidateInput()
            {
                if (className == null)
                {
                    ErrorDisplay.Show(Store, "Can't find class name");

                    return(false);
                }

                if (namespaceDecl == null && classDecl.Parent is NamespaceDeclarationSyntax classDeclParent)
                {
                    namespaceDecl = classDeclParent;
                }

                if (Store.GetAll <ModelEnum>().Any(c => c.Name == className))
                {
                    ErrorDisplay.Show(Store, $"'{className}' already exists in model as an Enum.");

                    return(false);
                }

                if (classDecl.TypeParameterList != null)
                {
                    ErrorDisplay.Show(Store, $"Can't add generic class '{className}'.");

                    return(false);
                }

                return(true);
            }
        }
        public override void ElementPropertyChanged(ElementPropertyChangedEventArgs e)
        {
            base.ElementPropertyChanged(e);

            ModelRoot   element = (ModelRoot)e.ModelElement;
            Store       store   = element.Store;
            Transaction current = store.TransactionManager.CurrentTransaction;

            if (current.IsSerializing || ModelRoot.BatchUpdating)
            {
                return;
            }

            if (Equals(e.NewValue, e.OldValue))
            {
                return;
            }

            List <string> errorMessages = EFCoreValidator.GetErrors(element).ToList();
            bool          redraw        = false;

            switch (e.DomainProperty.Name)
            {
            case "ConnectionString":

                if (e.NewValue != null)
                {
                    element.ConnectionStringName = null;
                }

                break;

            case "ConnectionStringName":

                if (e.NewValue != null)
                {
                    element.ConnectionString = null;
                }

                break;

            case "EntityFrameworkVersion":
                element.EntityFrameworkPackageVersion = "Latest";

                if (element.EntityFrameworkVersion == EFVersion.EFCore)
                {
                    element.InheritanceStrategy = CodeStrategy.TablePerHierarchy;
                }

                if (element.EntityFrameworkVersion == EFVersion.EF6)
                {
                    List <Association> associations = store.ElementDirectory
                                                      .AllElements
                                                      .OfType <Association>()
                                                      .Where(a => !string.IsNullOrEmpty(a.FKPropertyName) && a.SourceMultiplicity != Multiplicity.ZeroMany && a.TargetMultiplicity != Multiplicity.ZeroMany)
                                                      .ToList();

                    string message = $"This will remove declared foreign key properties from {associations.Count} association{(associations.Count == 1 ? "" : "s")}. Are you sure?";

                    if (associations.Any() && BooleanQuestionDisplay.Show(store, message) == true)
                    {
                        foreach (Association association in associations)
                        {
                            association.FKPropertyName = null;
                            AssociationChangedRules.FixupForeignKeys(association);
                        }
                    }
                }

                ModelRoot.ExecuteValidator?.Invoke();

                break;

            case "EntityOutputDirectory":

                if (string.IsNullOrEmpty(element.EnumOutputDirectory) || element.EnumOutputDirectory == (string)e.OldValue)
                {
                    element.EnumOutputDirectory = (string)e.NewValue;
                }

                if (string.IsNullOrEmpty(element.StructOutputDirectory) || element.StructOutputDirectory == (string)e.OldValue)
                {
                    element.StructOutputDirectory = (string)e.NewValue;
                }

                break;

            case "EnumOutputDirectory":

                if (string.IsNullOrEmpty((string)e.NewValue) && !string.IsNullOrEmpty(element.EntityOutputDirectory))
                {
                    element.EnumOutputDirectory = element.EntityOutputDirectory;
                }

                break;

            case "ExposeForeignKeys":
                if (!element.ExposeForeignKeys)
                {
                    foreach (Association association in element.Store.GetAll <Association>()
                             .Where(a => (a.SourceRole == EndpointRole.Dependent || a.TargetRole == EndpointRole.Dependent) &&
                                    !string.IsNullOrWhiteSpace(a.FKPropertyName)))
                    {
                        association.FKPropertyName = null;
                        AssociationChangedRules.FixupForeignKeys(association);
                    }
                }

                break;

            case "FileNameMarker":
                string newFileNameMarker = (string)e.NewValue;

                if (!Regex.Match($"a.{newFileNameMarker}.cs",
                                 @"^(?!^(PRN|AUX|CLOCK\$|NUL|CON|COM\d|LPT\d|\..*)(\..+)?$)[^\x00-\x1f\\?*:\"";|/]+$")
                    .Success)
                {
                    errorMessages.Add("Invalid value to make part of file name");
                }

                break;

            case "GridColor":
                foreach (EFModelDiagram diagram in element.GetDiagrams())
                {
                    diagram.GridColor = (Color)e.NewValue;
                }

                redraw = true;

                break;

            case "InheritanceStrategy":

                if ((element.EntityFrameworkVersion == EFVersion.EFCore) && (element.NuGetPackageVersion.MajorMinorVersionNum < 2.1))
                {
                    element.InheritanceStrategy = CodeStrategy.TablePerHierarchy;
                }

                break;

            case "Namespace":
                errorMessages.Add(CommonRules.ValidateNamespace((string)e.NewValue, CodeGenerator.IsValidLanguageIndependentIdentifier));

                break;

            case "ShowCascadeDeletes":
                // Normally you'd think that we should be able to register this in a AssociateValueWith call
                // in AssociationConnector, but that doesn't appear to work. So call the update method here.
                foreach (Association association in store.ElementDirectory.FindElements <Association>())
                {
                    PresentationHelper.UpdateAssociationDisplay(association);
                }

                redraw = true;

                break;

            case "ShowGrid":
                foreach (EFModelDiagram diagram in element.GetDiagrams())
                {
                    diagram.ShowGrid = (bool)e.NewValue;
                }

                redraw = true;

                break;

            case "ShowWarningsInDesigner":
                redraw = true;

                if ((bool)e.NewValue)
                {
                    ModelRoot.ExecuteValidator?.Invoke();
                }

                break;

            case "SnapToGrid":
                foreach (EFModelDiagram diagram in element.GetDiagrams())
                {
                    diagram.SnapToGrid = (bool)e.NewValue;
                }

                redraw = true;

                break;

            case "StructOutputDirectory":

                if (string.IsNullOrEmpty((string)e.NewValue) && !string.IsNullOrEmpty(element.EntityOutputDirectory))
                {
                    element.StructOutputDirectory = element.EntityOutputDirectory;
                }

                break;

            case "WarnOnMissingDocumentation":

                if (element.ShowWarningsInDesigner)
                {
                    redraw = true;
                }

                ModelRoot.ExecuteValidator?.Invoke();

                break;
            }

            errorMessages = errorMessages.Where(m => m != null).ToList();

            if (errorMessages.Any())
            {
                current.Rollback();
                ErrorDisplay.Show(store, string.Join("\n", errorMessages));
            }

            if (redraw)
            {
                foreach (EFModelDiagram diagram in element.GetDiagrams().Where(d => d.ActiveDiagramView != null))
                {
                    diagram.Invalidate(true);
                }
            }
        }
Example #14
0
        public override void OnDragDrop(DiagramDragEventArgs diagramDragEventArgs)
        {
            // came from model explorer?
            ModelElement element = (diagramDragEventArgs.Data.GetData("Sawczyn.EFDesigner.EFModel.ModelClass") as ModelElement)
                                   ?? (diagramDragEventArgs.Data.GetData("Sawczyn.EFDesigner.EFModel.ModelEnum") as ModelElement);

            if (element != null)
            {
                ShapeElement newShape = AddExistingModelElement(this, element);

                if (newShape != null)
                {
                    using (Transaction t = element.Store.TransactionManager.BeginTransaction("Moving pasted shapes"))
                    {
                        if (newShape is NodeShape nodeShape)
                        {
                            nodeShape.Location = diagramDragEventArgs.MousePosition;
                        }

                        t.Commit();
                    }
                }
            }
            else
            {
                if (IsDroppingExternal)
                {
                    DisableDiagramRules();
                    Cursor prev = Cursor.Current;
                    Cursor.Current = Cursors.WaitCursor;

                    List <ModelElement> newElements = null;

                    try
                    {
                        try
                        {
                            // add to the model
                            string[] filenames;

                            if (diagramDragEventArgs.Data.GetData("Text") is string concatenatedFilenames)
                            {
                                filenames = concatenatedFilenames.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
                            }
                            else if (diagramDragEventArgs.Data.GetData("FileDrop") is string[] droppedFilenames)
                            {
                                filenames = droppedFilenames;
                            }
                            else
                            {
                                ErrorDisplay.Show(Store, "Unexpected error dropping files. Please create an issue in Github.");

                                return;
                            }

                            string[] existingFiles = filenames.Where(File.Exists).ToArray();
                            newElements = FileDropHelper.HandleMultiDrop(Store, existingFiles).ToList();

                            string[] missingFiles = filenames.Except(existingFiles).ToArray();

                            if (missingFiles.Any())
                            {
                                if (missingFiles.Length > 1)
                                {
                                    missingFiles[missingFiles.Length - 1] = "and " + missingFiles[missingFiles.Length - 1];
                                }

                                ErrorDisplay.Show(Store, $"Can't find files {string.Join(", ", missingFiles)}");
                            }
                        }
                        finally
                        {
                            if (newElements?.Count > 0)
                            {
                                string message = $"Created {newElements.Count} new elements that have been added to the Model Explorer. "
                                                 + $"Do you want these added to the current diagram as well? It could take a while.";

                                if (BooleanQuestionDisplay.Show(Store, message) == true)
                                {
                                    AddElementsToActiveDiagram(newElements);
                                }
                            }

                            //string message = $"{newElements.Count} have been added to the Model Explorer. You can add them to this or any other diagram by dragging them from the Model Explorer and dropping them onto the design surface.";
                            //MessageDisplay.Show(message);

                            IsDroppingExternal = false;
                        }
                    }
                    finally
                    {
                        EnableDiagramRules();
                        Cursor.Current = prev;

                        MessageDisplay.Show(newElements == null || !newElements.Any()
                                         ? "Import dropped files: no new elements added"
                                         : BuildMessage(newElements));

                        StatusDisplay.Show("Ready");
                    }
                }
                else
                {
                    try
                    {
                        base.OnDragDrop(diagramDragEventArgs);
                    }
                    catch (ArgumentException)
                    {
                        // ignore. byproduct of multiple diagrams
                    }
                }
            }

            StatusDisplay.Show("Ready");
            Invalidate();

            string BuildMessage(List <ModelElement> newElements)
            {
                int           classCount    = newElements.OfType <ModelClass>().Count();
                int           propertyCount = newElements.OfType <ModelClass>().SelectMany(c => c.Attributes).Count();
                int           enumCount     = newElements.OfType <ModelEnum>().Count();
                List <string> messageParts  = new List <string>();

                if (classCount > 0)
                {
                    messageParts.Add($"{classCount} classes");
                }

                if (propertyCount > 0)
                {
                    messageParts.Add($"{propertyCount} properties");
                }

                if (enumCount > 0)
                {
                    messageParts.Add($"{enumCount} enums");
                }

                return($"Import dropped files: added {(messageParts.Count > 1 ? string.Join(", ", messageParts.Take(messageParts.Count - 1)) + " and " + messageParts.Last() : messageParts.First())}");
            }
        }