/// <summary> /// This API supports the Entity Framework infrastructure and is not intended to be used directly from your code. /// </summary> /// <param name="args">This API supports the Entity Framework infrastructure and is not intended to be used directly from your code.</param> protected virtual void OnUndoRedoCompleted(XmlTransactionEventArgs args) { if (UndoRedoCompleted != null) { UndoRedoCompleted(this, args); } }
/// <summary> /// This API supports the Entity Framework infrastructure and is not intended to be used directly from your code. /// </summary> /// <param name="args">This API supports the Entity Framework infrastructure and is not intended to be used directly from your code.</param> protected virtual void OnTransactionCompleted(XmlTransactionEventArgs args) { if (TransactionCompleted != null) { TransactionCompleted(this, args); } }
protected override void OnBeforeHandleXmlModelTransactionCompleted(object sender, XmlTransactionEventArgs args) { base.OnBeforeHandleXmlModelTransactionCompleted(sender, args); #if DEBUG var rDT = new RunningDocumentTable(PackageManager.Package); uint cookie = 0; rDT.FindDocument(Uri.LocalPath, out cookie); var info = rDT.GetDocumentInfo(cookie); Debug.Print( string.Format( CultureInfo.CurrentCulture, "There are now {0} Edit Locks, and {1} Read Locks.", info.EditLocks, info.ReadLocks)); #endif }
private void OnXmlModelUndoRedoCompleted(object senderId, XmlEditingScopeEventArgs e) { _xmlDesignerPackage.InvokeOnForeground( () => { var designerTx = ((senderId != null) && (senderId is XmlStore) && (senderId == _xmlStore)); XmlTransaction tx = GetTransaction(e.EditingScope); var args = new XmlTransactionEventArgs(tx, designerTx); OnUndoRedoCompleted(args); _txDictionary.Remove(e.EditingScope); }); }
protected override void OnAfterHandleXmlModelTransactionCompleted( object sender, XmlTransactionEventArgs xmlTransactionEventArgs, EfiChangeGroup changeGroup) { base.OnAfterHandleXmlModelTransactionCompleted(sender, xmlTransactionEventArgs, changeGroup); Debug.Assert(_layerManager != null, "LayerManager must not be null"); if (_layerManager != null) { var changes = from ixc in xmlTransactionEventArgs.Transaction.Changes() select new Tuple<XObject, XObjectChange>(ixc.Node, ixc.Action); _layerManager.OnAfterTransactionCommitted(changes); } }
private EfiChangeGroup ProcessUndoRedoChanges(XmlTransactionEventArgs xmlTransactionEventArgs) { using (var tx = new EfiTransaction(this, EfiTransactionOriginator.UndoRedoOriginatorId, xmlTransactionEventArgs.Transaction)) { var changeGroup = tx.ChangeGroup; var undoChanges = new List<ExternalXMLModelChange>(); var containersToRenormalize = new List<EFContainer>(); var bindingsForRebind = new List<ItemBinding>(); var namespaces = GetNamespaces(); // filter the changes received from XmlEditor and resolve changed EFObjects and their parents foreach (var xmlChange in xmlTransactionEventArgs.Transaction.Changes()) { // determine how to process this edit if (xmlChange.Node.NodeType == XmlNodeType.Element || xmlChange.Node.NodeType == XmlNodeType.Attribute || xmlChange.Node.NodeType == XmlNodeType.Document) { if (xmlChange.Node.NodeType == XmlNodeType.Element && xmlChange.Action == XObjectChange.Value) { var nodeValueChange = xmlChange as IXmlNodeValueChange; Debug.Assert( nodeValueChange != null && string.IsNullOrEmpty(nodeValueChange.OldValue) && string.IsNullOrEmpty(nodeValueChange.NewValue)); // in cases where we are undoing the addition of all children to an element A, the Xml Model // will forcibly add an empty string to the element A so that a "short" end tag "/>" is not created // in this case, the change we will receive is a set value change on an element; we ignore this } else { var emc = new ExternalXMLModelChange(xmlChange, ExpectEFObjectForXObject); if (emc.IsAnnotationChange(namespaces)) { continue; } undoChanges.Add(emc); } } } // go through the undo changes and make changes to the model foreach (var undoModelChange in undoChanges) { // Should ignore other artifact changes. if (undoModelChange.ChangedEFObject.Artifact != this) { continue; } if (undoModelChange.Action == XObjectChange.Remove) { ProcessExternalRemoveChange(changeGroup, bindingsForRebind, undoModelChange); } else { ProcessExternalAddOrUpdateChange(changeGroup, containersToRenormalize, undoModelChange); } } // because of the order in which elements were possibly added, certain ItemBindings were not resolved; // therefore we have to step through the normalized EFElements again and normalize/resolve so their child // ItemBindings will get resolved. foreach (var container in containersToRenormalize) { XmlModelHelper.NormalizeAndResolve(container); } XmlModelHelper.RebindItemBindings(bindingsForRebind); #if DEBUG var visitor = GetVerifyModelIntegrityVisitor(); visitor.Traverse(this); if (visitor.ErrorCount > 0) { Debug.WriteLine("Model Integrity Verifier found " + visitor.ErrorCount + " error(s):"); Debug.WriteLine(visitor.AllSerializedErrors); Debug.Assert( false, "Model Integrity Verifier found " + visitor.ErrorCount + " error(s). See the Debug console for details."); } #endif return changeGroup; } }
private static EfiChangeGroup ProcessDesignerChange(XmlTransactionEventArgs xmlTransactionEventArgs, EfiTransaction efiTransaction) { // if the transaction has one of our transactions in the UserState, then // this will not be null var changeGroup = efiTransaction.ChangeGroup; // Here, we need to call RecordModelChange for each change that occurred in the XmlTransaction // Since the XmlTransaction started in our model, the model already reflects these changes. foreach (var xmlChange in xmlTransactionEventArgs.Transaction.Changes()) { Debug.Assert(xmlChange.Node != null); if (xmlChange.Node.NodeType == XmlNodeType.Element || xmlChange.Node.NodeType == XmlNodeType.Attribute || xmlChange.Node.NodeType == XmlNodeType.Document) { var efObject = ModelItemAnnotation.GetModelItem(xmlChange.Node); if (efObject != null) { if (xmlChange.Node.NodeType == XmlNodeType.Element && xmlChange.Action == XObjectChange.Value) { var nodeValueChange = xmlChange as IXmlNodeValueChange; Debug.Assert( nodeValueChange != null && string.IsNullOrEmpty(nodeValueChange.OldValue) && string.IsNullOrEmpty(nodeValueChange.NewValue)); // at times (like when the last child is removed), the XLinq tree will // collapse whitespace nodes and we will get 'set value' on the // preceeding element, we can ignore these continue; } string oldValue = null; string newValue = null; string property = null; GetOldAndNewValues(xmlChange, out property, out oldValue, out newValue); changeGroup.RecordModelChange(GetChangeType(xmlChange), efObject, property, oldValue, newValue); } } } return changeGroup; }
protected virtual void OnAfterHandleXmlModelTransactionCompleted( object sender, XmlTransactionEventArgs xmlTransactionEventArgs, EfiChangeGroup changeGroup) { }
protected virtual void OnHandleXmlModelTransactionCompleted( object sender, XmlTransactionEventArgs xmlTransactionEventArgs, bool isUndoOrRedo, out EfiChangeGroup changeGroup) { // If this is an undo/redo XML transaction there is no EfiTransaction, thus the artifact will not // be made dirty as necessary. We will have to do it manually here. var efiTransaction = xmlTransactionEventArgs.Transaction.UserState as EfiTransaction; if (efiTransaction == null && isUndoOrRedo) { Artifact.IsDirty = true; } // When an XML transaction completes it could either be a normal, undo, or redo transaction. // In all cases we will need to clear the "validity" of the artifact so that any successive // validations will not short-circuit. // Ideally we can skip this in the event of any major error that causes the reloading // of the artifact but we'll be safe. SetValidityDirtyForErrorClass(ErrorClass.All, true); // the change group to send back to the caller changeGroup = null; // if the transaction is aborting, drop and reload if (xmlTransactionEventArgs.Transaction.Status == XmlTransactionStatus.Aborted) { ReloadArtifact(); return; } if (efiTransaction != null) { changeGroup = ProcessDesignerChange(xmlTransactionEventArgs, efiTransaction); if (changeGroup != null) { ModelManager.RecordChangeGroup(changeGroup); } } else { // TODO: when we want SxS again, we should handle these operations in addition to undo/redo if (isUndoOrRedo) { try { changeGroup = ProcessUndoRedoChanges(xmlTransactionEventArgs); if (changeGroup != null) { ModelManager.RecordChangeGroup(changeGroup); // we have to manually route the change groups here because we can't rely on ProcessUndoRedoChange to do it since nothing // gets updated in the Xml Model ModelManager.RouteChangeGroups(); } } catch (ChangeProcessingFailedException) { ReloadArtifact(); } catch (Exception e) { Debug.Fail("Unexpected exception caught while processing undo/redo", e.Message); ReloadArtifact(); } } } }
protected virtual void OnBeforeHandleXmlModelTransactionCompleted(object sender, XmlTransactionEventArgs xmlTransactionEventArgs) { }
private void HandleXmlModelUndoRedoCompleted(object sender, XmlTransactionEventArgs xmlTransactionEventArgs) { OnBeforeHandleXmlModelTransactionCompleted(sender, xmlTransactionEventArgs); EfiChangeGroup changeGroup; OnHandleXmlModelTransactionCompleted( sender, xmlTransactionEventArgs, true, // send 'true' since this is the undo handler out changeGroup); OnAfterHandleXmlModelTransactionCompleted(sender, xmlTransactionEventArgs, changeGroup); }
private void HandleXmlModelTransactionCompleted(object sender, XmlTransactionEventArgs xmlTransactionEventArgs) { OnBeforeHandleXmlModelTransactionCompleted(sender, xmlTransactionEventArgs); EfiChangeGroup changeGroup; OnHandleXmlModelTransactionCompleted( sender, xmlTransactionEventArgs, false, // send 'false' since this is the normal handler out changeGroup); OnAfterHandleXmlModelTransactionCompleted(sender, xmlTransactionEventArgs, changeGroup); }