/// <summary>
        ///     The implementation of VsShell.ISelectionContainer.GetObjects in
        ///     ModelingWindowPane calls either GetSelectedObjects() or GetAllObjects()
        ///     - base calls to ModelingWindowPane
        /// </summary>
        /// <returns></returns>
        protected override void GetSelectedObjects(uint count, object[] objects)
        {
            // call the base class version first; objects will be populated with a
            // collection of DSL ModelElements
            base.GetSelectedObjects(count, objects);

            if (IsArtifactDesignerSafe() == false)
            {
                if (EdmUtils.ShouldShowByRefDebugHelpers())
                {
                    if (Context != null)
                    {
                        var artifact = EditingContextManager.GetArtifact(Context) as EntityDesignArtifact;
                        if (artifact != null)
                        {
                            // Show at least the EFEntityModelDescriptor so we can see the by-reference property extensions
                            // for the hydrated model
                            var descriptor =
                                (ObjectDescriptor)TypeDescriptor.CreateInstance(null, typeof(EFEntityModelDescriptor), null, null);
                            descriptor.Initialize(artifact.ConceptualModel, Context, true);
                            objects[0] = descriptor;
                        }
                    }
                }
                else
                {
                    for (var i = 0; i < objects.Length; i++)
                    {
                        objects[i] = null;
                    }
                }
            }
            // only show properties for single selection
            else
            {
                // now change this into an array of our item descriptors.
                var selectedModelObjects = ConvertDslModelElementArrayToItemDescriptors(objects, false);

                // if there are more than 1 selected object, convert the item descriptors to linked-item-descriptors.
                // This is so that property update can be done in 1 transaction.
                if (selectedModelObjects.Count > 1)
                {
                    var tempSelectedModelObjects = new ArrayList();
                    var contextItem = new LinkedDescriptorContextItem();
                    foreach (var customTypeDescriptor in selectedModelObjects.ToArray().OfType <ICustomTypeDescriptor>())
                    {
                        tempSelectedModelObjects.Add(new LinkedPropertyTypeDescriptor(customTypeDescriptor, contextItem));
                    }
                    selectedModelObjects = tempSelectedModelObjects;
                }

                // if the lengths are not the same, then there are items (like compartments)
                // that are being selected, so don't change the object array
                if (objects.Length == selectedModelObjects.Count)
                {
                    selectedModelObjects.CopyTo(objects, 0);
                }
            }
        }
        private bool IsArtifactDesignerAndEditSafe()
        {
            var artifact = EditingContextManager.GetArtifact(Context) as EntityDesignArtifact;

            if (artifact != null)
            {
                return(IsArtifactDesignerSafe(artifact) && artifact.IsDesignerSafeAndEditSafe());
            }
            else
            {
                return(false);
            }
        }
        private bool IsArtifactDesignerSafe()
        {
            var artifact = EditingContextManager.GetArtifact(Context);

            // artifact may be null if the editing context has been disposed.
            if (artifact != null)
            {
                return(IsArtifactDesignerSafe(artifact));
            }
            else
            {
                // No artifact.  This should never be, but return false just to be safe.
                return(false);
            }
        }
Example #4
0
        /// <summary>
        ///     This method reads the .diagram file and makes sure that shapes exist for every item
        ///     in the .diagram file.
        /// </summary>
        internal static void ReloadDiagram(EntityDesignerViewModel viewModel)
        {
            var diagram = viewModel.GetDiagram();

            if (diagram == null)
            {
                // Empty DSL diagram
                return;
            }

            diagram.ResetWatermark(diagram.ActiveDiagramView);

            // get our artifact
            var artifact = EditingContextManager.GetArtifact(viewModel.EditingContext);

            Debug.Assert(artifact != null);
            if (!artifact.IsDesignerSafe)
            {
                return;
            }

            var diagramModel = viewModel.ModelXRef.GetExisting(diagram) as DesignerModel.Diagram;

            if (diagramModel != null)
            {
                // ensure that we still have all of the parts we need to re-translate from the Model
                EntityModelToDslModelTranslatorStrategy.TranslateDiagram(diagram, diagramModel);
            }
            else
            {
                // this path will usually only happen if an UMFDB extension has deleted the diagram node
                // since we don't have a diagram anymore, lay it all out and create a new one
                if (diagram.ModelElement.EntityTypes.Count < EntityDesignerDiagram.IMPLICIT_AUTO_LAYOUT_CEILING)
                {
                    diagram.AutoLayoutDiagram();
                }
                EntityModelToDslModelTranslatorStrategy.CreateDefaultDiagram(viewModel.EditingContext, diagram);
            }

            // remove "Select All" selection
            if (diagram.ActiveDiagramView != null)
            {
                diagram.ActiveDiagramView.Selection.Set(new DiagramItem(diagram));
            }
        }
Example #5
0
        protected override int LoadDocData(string fileName, bool isReload)
        {
            EntityDesignerViewModel.EntityShapeLocationSeed = 0;
            var ret = base.LoadDocData(fileName, isReload);

            if (UndoManager != null)
            {
                // Set the buffer's IOleUndoManager on XmlModelProvider, so each time a Tx Commits using XmlStore, an UndoUnit will be
                // pushed onto the stack.  This is currently neccessary if you want XmlEditor to fire UndoRedoCompleted Event.
                var artifact = EditingContextManager.GetArtifact(EditingContext);
                Debug.Assert(artifact != null, "artifact should not be null");
                if (artifact != null)
                {
                    var xmlModelProvider = artifact.XmlModelProvider as VSXmlModelProvider;
                    Debug.Assert(xmlModelProvider != null, "Unexpected xml model provider type is being used with VS implementation");
                    if (xmlModelProvider != null)
                    {
                        // Attempt to get the undo manager from the buffer and disable it.
                        // This is because this undo manager is different from the undo manager that is used by the Entity Designer (ParentUndoManager)
                        // In linked transactions this can cause a problem since there are two undo managers that are getting rolled back, and the
                        // XML Model ends up thinking the parse tree is out of sync with the buffer. We should not have to explicitly roll back the buffer
                        // since modifications from our undo manager wrap XML model parse tree modifications, which when rolled back will be committed
                        // to the buffer.
                        IOleUndoManager bufferUndoMgr;
                        var             hr = ((VSTextManagerInterop.IVsTextBuffer)VsBuffer).GetUndoManager(out bufferUndoMgr);

                        Debug.Assert(bufferUndoMgr != null, "Couldn't find the buffer undo manager. Undo/Redo will be disabled");
                        if (NativeMethods.Succeeded(hr) && bufferUndoMgr != null)
                        {
                            xmlModelProvider.UndoManager = new ParentUndoManager(VSUndoManager);
                            bufferUndoMgr.DiscardFrom(null);
                            bufferUndoMgr.Enable(0);
                        }

                        Store.UndoManager.UndoState = UndoState.Disabled;
                    }
                }
            }
            return(ret);
        }
Example #6
0
        internal override void SaveModelAndDiagram(
            SerializationResult serializationResult, EntityDesignerViewModel modelRoot, string modelFileName, EntityDesignerDiagram diagram,
            string diagramFileName, Encoding encoding, bool writeOptionalPropertiesWithDefaultValue)
        {
            // only save the model
            base.SaveModel(serializationResult, modelRoot, modelFileName, encoding, writeOptionalPropertiesWithDefaultValue);

            if (!serializationResult.Failed)
            {
                // flip our dirty bit (as long as we aren't trying to save the auto-recovery backup file)
                var artifact = EditingContextManager.GetArtifact(modelRoot.EditingContext);
                Debug.Assert(artifact != null, "Failed to get a valid EFArtifact from the context");

                IEntityDesignDocData docData = null;
                var fileName = String.Empty;
                if (artifact != null)
                {
                    fileName = artifact.Uri.LocalPath;
                }

                docData = VSHelpers.GetDocData(PackageManager.Package, fileName) as IEntityDesignDocData;
                Debug.Assert(docData != null, "Couldn't locate our DocData");
                if (artifact != null &&
                    docData != null &&
                    !string.Equals(docData.BackupFileName, modelFileName, StringComparison.OrdinalIgnoreCase))
                {
                    artifact.IsDirty = false;
                }

                // SaveDiagram file if the file exists
                // TODO: What happened if saving diagram file failed? Should we rollback the model file?
                var diagramDocData =
                    VSHelpers.GetDocData(PackageManager.Package, fileName + EntityDesignArtifact.ExtensionDiagram) as XmlModelDocData;
                if (diagramDocData != null)
                {
                    int saveIsCancelled;
                    diagramDocData.SaveDocData(VSSAVEFLAGS.VSSAVE_SilentSave, out diagramFileName, out saveIsCancelled);
                }
            }
        }
Example #7
0
        internal override MemoryStream InternalSaveModel(
            SerializationResult serializationResult, EntityDesignerViewModel modelRoot, string fileName, Encoding encoding,
            bool writeOptionalPropertiesWithDefaultValue)
        {
            IEntityDesignDocData docData = null;
            MemoryStream         stream  = null;

            Debug.Assert(modelRoot.EditingContext != null, "Designer model root has a null EditingContext");
            if (modelRoot.EditingContext != null)
            {
                // find our doc data; don't use the passed in fileName as this will be the new name
                // during a SaveAs operation
                var artifact = EditingContextManager.GetArtifact(modelRoot.EditingContext);
                if (artifact != null)
                {
                    docData = VSHelpers.GetDocData(PackageManager.Package, artifact.Uri.LocalPath) as IEntityDesignDocData;
                }

                Debug.Assert(docData != null, "Couldn't locate our DocData");
                if (docData != null)
                {
                    var text = docData.GetBufferTextForSaving();
                    if (!string.IsNullOrEmpty(text))
                    {
                        stream = FileUtils.StringToStream(text, encoding) as MemoryStream;
                    }
                }
            }

            // if we don't have a stream, then we couldn't serialize for some reason
            if (stream == null)
            {
                serializationResult.Failed = true;
            }

            return(stream);
        }
Example #8
0
        /// <summary>
        ///     This method loads the DSL view model with the items in the artifact's C-Model.
        /// </summary>
        internal void ReloadModel(EntityDesignerViewModel viewModel)
        {
            var diagram = viewModel.GetDiagram();

            if (diagram == null)
            {
                // empty DSL diagram
                return;
            }

            // get our artifact
            var artifact = EditingContextManager.GetArtifact(viewModel.EditingContext) as EntityDesignArtifact;

            Debug.Assert(artifact != null);

            var serializationResult = new SerializationResult();

            var serializationContext = new SerializationContext(GetDirectory(viewModel.Store), artifact.Uri.LocalPath, serializationResult);
            var transactionContext   = new TransactionContext();

            transactionContext.Add(SerializationContext.TransactionContextKey, serializationContext);

            var workaroundFixSerializationTransactionValue = false;

            if (viewModel.Store.PropertyBag.ContainsKey("WorkaroundFixSerializationTransaction"))
            {
                workaroundFixSerializationTransactionValue = (bool)viewModel.Store.PropertyBag["WorkaroundFixSerializationTransaction"];
            }

            try
            {
                // To fix performance issue during reload, we turn-off layout during "serialization".
                viewModel.Store.PropertyBag["WorkaroundFixSerializationTransaction"] = true;

                using (var t = viewModel.Store.TransactionManager.BeginTransaction("ReloadModel", true, transactionContext))
                {
                    if (artifact.ConceptualModel() == null)
                    {
                        return;
                    }

                    DesignerModel.Diagram diagramModel = null;

                    // If DiagramId is not string empty, try to get the diagram from the artifact.
                    // There is a situation where we could not find the diagram given an ID (for example: EDMX Model's Diagram that is created by VS before SQL 11;
                    // In that case, we assign temporary ID to the diagram and a new ID will be generated every time the model is reloaded.)
                    // We could safely choose the first diagram since multiple diagrams feature didn't exist in VS prior to SQL11 release.
                    if (!string.IsNullOrEmpty(diagram.DiagramId))
                    {
                        diagramModel = artifact.DesignerInfo.Diagrams.GetDiagram(diagram.DiagramId);
                    }

                    if (diagramModel == null)
                    {
                        diagramModel = artifact.DesignerInfo.Diagrams.FirstDiagram;
                    }

                    if (diagramModel != null)
                    {
                        // Re-establish the xref between Escher conceptual model and DSL root model.
                        // and between Escher Diagram model and DSL diagram model.

                        Debug.Assert(viewModel.ModelXRef != null, "Why ModelXRef is null?");
                        if (viewModel.ModelXRef != null)
                        {
                            viewModel.ModelXRef.Add(artifact.ConceptualModel(), viewModel, viewModel.EditingContext);
                            viewModel.ModelXRef.Add(diagramModel, diagram, viewModel.EditingContext);
                            ModelTranslatorContextItem.GetEntityModelTranslator(viewModel.EditingContext)
                            .TranslateModelToDslModel(diagramModel, viewModel.Partition);
                        }
                    }

                    if (t.IsActive)
                    {
                        t.Commit();
                    }
                }
            }
            finally
            {
                viewModel.Store.PropertyBag["WorkaroundFixSerializationTransaction"] = workaroundFixSerializationTransactionValue;
            }
        }