void OnPencilDisposed(Pencil pencil, TextDataChangedEventArgs args) { Debug.Assert(pencil == this.activePencil, "Disposing a pencil that isn't the active one."); if (args != null) { if (this.LastChange != null) { this.LastChange.NextChange = args.Change; } TextChange finalChange = args.Change; while (finalChange.NextChange != null) { finalChange = finalChange.NextChange; } this.TextData = finalChange.NewTextData; this.LastChange = finalChange; var handler = this.TextDataChanged; if (handler != null) { handler(this, args); } if (pencil.UndoUnit != null) { var now = DateTime.Now; bool merged = false; if (((now - this.timeOfLastEdit).TotalMilliseconds < MinimumMillisecondsTimeBetweenUndoUnits) && (this.undoStack.Count > 0)) { // If possible, merge this unit with the one on the stack. TextUndoUnit existingUnit = this.undoStack.Peek(); TextUndoUnit incomingUnit = pencil.UndoUnit; if (incomingUnit.Metadata != null && incomingUnit.Metadata.TryMerge(existingUnit.Metadata)) { // Successful merge existingUnit.Metadata = incomingUnit.Metadata; existingUnit.Merge(pencil.UndoUnit); merged = true; } } if (!merged) { this.undoStack.Push(pencil.UndoUnit); } this.redoStack.Clear(); this.timeOfLastEdit = now; } } this.activePencil = null; this.pencilEvent.Set(); }
void NotifyAfterUndoRedo(TextUndoUnit unit, object instigator, bool isUndo) { foreach (var observer in this.undoObservers) { observer.OnAfterUndoRedoUnit(unit, instigator, isUndo); } }
internal void Merge(TextUndoUnit incomingUnit) { if (this.changes == null) { this.changes = incomingUnit.changes; } else if (incomingUnit.changes != null) { this.changes.AddRange(incomingUnit.changes); } }
public Pencil(TextBuffer buffer, bool forUndoRedo) { this.buffer = buffer; this.firstChange = null; this.lastChange = null; if (!forUndoRedo) { this.undoUnit = new TextUndoUnit(); } }
internal void Merge(TextUndoUnit incomingUnit) { if (this.changes == null) { this.changes = incomingUnit.changes; } else if (incomingUnit.changes != null) { this.changes.AddRange(incomingUnit.changes); } }
public void Redo(object instigator) { TextUndoUnit unit = null; using (var pencil = GetPencil(forUndoRedo: true)) { if (this.redoStack.Count > 0) { unit = this.redoStack.Pop(); NotifyBeforeUndoRedo(unit, instigator, isUndo: false); unit.Redo(pencil); this.undoStack.Push(unit); } } if (unit != null) { NotifyAfterUndoRedo(unit, instigator, isUndo: false); } }
void ITextUndoObserver.OnAfterUndoRedoUnit(TextUndoUnit unit, object instigator, bool isUndo) { if (object.ReferenceEquals(instigator, this)) { var meta = unit.Metadata as SelectionUndoMetadata; if (meta != null) { var selection = isUndo ? meta.OldSelection : meta.NewSelection; if (selection.IsEmpty) { MoveCaret(selection.Span.Start, false); } else if (selection.AnchoredAtTop) { this.SelectionAnchor = selection.Span.Start; MoveCaret(selection.Span.End, true); } else { this.SelectionAnchor = selection.Span.End; MoveCaret(selection.Span.Start, true); } } this.inUndoRedo = false; } }
void ITextUndoObserver.OnBeforeUndoRedoUnit(TextUndoUnit unit, object instigator, bool isUndo) { if (object.ReferenceEquals(instigator, this)) { this.inUndoRedo = true; } }
public Pencil(TextBuffer buffer, bool forUndoRedo) { this.buffer = buffer; this.firstChange = null; this.lastChange = null; if (!forUndoRedo) { this.undoUnit = new TextUndoUnit(); } }
void NotifyAfterUndoRedo(TextUndoUnit unit, object instigator, bool isUndo) { foreach (var observer in this.undoObservers) { observer.OnAfterUndoRedoUnit(unit, instigator, isUndo); } }