/// <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); } }
/// <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)); } }
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); }
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); } } }
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); }
/// <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; } }