// Token: 0x06007312 RID: 29458 RVA: 0x00210104 File Offset: 0x0020E304 internal static void AttachUndoManager(DependencyObject scope, UndoManager undoManager) { if (scope == null) { throw new ArgumentNullException("scope"); } if (undoManager == null) { throw new ArgumentNullException("undoManager"); } if (undoManager != null && undoManager._scope != null) { throw new InvalidOperationException(SR.Get("UndoManagerAlreadyAttached")); } UndoManager.DetachUndoManager(scope); scope.SetValue(UndoManager.UndoManagerInstanceProperty, undoManager); if (undoManager != null) { undoManager._scope = scope; } undoManager.IsEnabled = true; }
// Called after raising public events. // // If the application interrupted events, this method will temporarily rollback // the application changes to safely finalize the composition, then restore // the application changes. // // If the application did not interrupt events, restores the original view // of the document last seen by IMEs. private void SetFinalDocumentState(UndoManager undoManager, Stack imeChangeStack, int appChangeCount, int imeSelectionAnchorOffset, int imeSelectionMovingOffset, int appSelectionAnchorOffset, int appSelectionMovingOffset) { this.TextSelection.BeginChangeNoUndo(); try { bool textChanged = _compositionModifiedByEventListener; // // Undo app changes. // UndoQuietly(appChangeCount); // // Redo IME changes. // Stack appRedoStack = undoManager.SetRedoStack(imeChangeStack); int imeChangeCount = imeChangeStack.Count; RedoQuietly(imeChangeCount); // At this point the document should be exactly where the IME left it. Invariant.Assert(_netCharCount == this.TextContainer.IMECharCount); if (textChanged) { // // We need to complete the composition before continuing. // int completeUnitCount = undoManager.UndoCount; if (_isComposing) { TextParentUndoUnit completeUndoUnit = OpenTextParentUndoUnit(); try { CompleteComposition(); } finally { CloseTextParentUndoUnit(completeUndoUnit, (completeUndoUnit.LastUnit != null) ? UndoCloseAction.Commit : UndoCloseAction.Discard); } } completeUnitCount = (undoManager.UndoCount - completeUnitCount); // Set a flag that informs the event listeners they need // to pass along change notifications to the IMEs. _compositionEventState = CompositionEventState.ApplyingApplicationChange; try { // // Undo the composition complete, if any. // UndoQuietly(completeUnitCount); // // Undo the remaining IME changes. // UndoQuietly(imeChangeCount); // // Restore application changes. // undoManager.SetRedoStack(appRedoStack); RedoQuietly(appChangeCount); // The IME should have received the app change events from preceeding RedoQuietly. Invariant.Assert(_netCharCount == this.TextContainer.IMECharCount); // we can't rely on Redo fixing up the selection. // If the app only modified the selection appChangeCount == 0. ITextPointer anchor = this.TextContainer.CreatePointerAtOffset(appSelectionAnchorOffset, LogicalDirection.Forward); ITextPointer moving = this.TextContainer.CreatePointerAtOffset(appSelectionMovingOffset, LogicalDirection.Forward); this.TextSelection.Select(anchor, moving); // // We may have a filtering related composition undo unit on the top // of the stack and if that's the case we want to merge it with all // other composition undo units (if present). // MergeCompositionUndoUnits(); } finally { // Reset CompositionEventState after Redo operation _compositionEventState = CompositionEventState.RaisingEvents; } } else { // Restore the selection. ITextPointer anchor = this.TextContainer.CreatePointerAtOffset(imeSelectionAnchorOffset, LogicalDirection.Backward); ITextPointer moving = this.TextContainer.CreatePointerAtOffset(imeSelectionMovingOffset, LogicalDirection.Backward); this.TextSelection.Select(anchor, moving); // Since we just had a composition accepted, we need to merge all // of its individual units now. MergeCompositionUndoUnits(); } } finally { this.TextSelection.EndChange(false /* disableScroll */, true /* skipEvents */); } }
//------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ #region Internal Methods /// <summary> /// Defines a given FrameworkElement as a scope for undo service. /// New instance of UndoManager created and attached to this element. /// </summary> /// <param name="scope"> /// FrameworkElement to which new instance of UndoManager is attached. /// </param> /// <param name="undoManager"> /// </param> internal static void AttachUndoManager(DependencyObject scope, UndoManager undoManager) { if (scope == null) { throw new ArgumentNullException("scope"); } if (undoManager == null) { throw new ArgumentNullException("undoManager"); } if (undoManager is UndoManager && ((UndoManager)undoManager)._scope != null) { throw new InvalidOperationException(SR.Get(SRID.UndoManagerAlreadyAttached)); } // Detach existing instance of undo manager if any DetachUndoManager(scope); // Attach the service to the scope via private dependency property scope.SetValue(UndoManager.UndoManagerInstanceProperty, undoManager); if (undoManager is UndoManager) { Debug.Assert(((UndoManager)undoManager)._scope == null); ((UndoManager)undoManager)._scope = scope; } undoManager.IsEnabled = true; }
// Token: 0x060071A6 RID: 29094 RVA: 0x00207A9C File Offset: 0x00205C9C public virtual void Close(IParentUndoUnit unit, UndoCloseAction closeAction) { if (unit == null) { throw new ArgumentNullException("unit"); } if (this.OpenedUnit == null) { throw new InvalidOperationException(SR.Get("UndoNoOpenUnit")); } if (this.OpenedUnit != unit) { IParentUndoUnit parentUndoUnit = this; while (parentUndoUnit.OpenedUnit != null && parentUndoUnit.OpenedUnit != unit) { parentUndoUnit = parentUndoUnit.OpenedUnit; } if (parentUndoUnit.OpenedUnit == null) { throw new ArgumentException(SR.Get("UndoUnitNotFound"), "unit"); } if (parentUndoUnit != this) { parentUndoUnit.Close(closeAction); return; } } UndoManager undoManager = this.TopContainer as UndoManager; if (closeAction != UndoCloseAction.Commit) { if (undoManager != null) { undoManager.IsEnabled = false; } if (this.OpenedUnit.OpenedUnit != null) { this.OpenedUnit.Close(closeAction); } if (closeAction == UndoCloseAction.Rollback) { this.OpenedUnit.Do(); } this._openedUnit = null; if (this.TopContainer is UndoManager) { ((UndoManager)this.TopContainer).OnNextDiscard(); } else { ((IParentUndoUnit)this.TopContainer).OnNextDiscard(); } if (undoManager != null) { undoManager.IsEnabled = true; return; } } else { if (this.OpenedUnit.OpenedUnit != null) { this.OpenedUnit.Close(UndoCloseAction.Commit); } IParentUndoUnit openedUnit = this.OpenedUnit; this._openedUnit = null; this.Add(openedUnit); this.SetLastUnit(openedUnit); } }
//------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ #region Internal Methods // Allocates an UndoManager for this instance. // This method should only be called once, but by controls // that also creates TextEditors and want undo. internal void EnableUndo(FrameworkElement uiScope) { Invariant.Assert(_undoManager == null, SR.Get(SRID.TextContainer_UndoManagerCreatedMoreThanOnce)); _undoManager = new UndoManager(); MS.Internal.Documents.UndoManager.AttachUndoManager(uiScope, _undoManager); }