/// <summary> /// Adds a new changeset to the undo history. The change set will be added to the existing batch, if in a batch. /// </summary> /// <param name="changeSet">The ChangeSet to add.</param> public void AddChange(ChangeSet changeSet) { // System.Diagnostics.Debug.WriteLine("Starting AddChange: " + description); // We don't want to add additional changes representing the operations that happen when undoing or redoing a change. if (_isUndoingOrRedoing) return; // If batched, add to the current ChangeSet, otherwise add a new ChangeSet. if (IsInBatch) { foreach (var chg in changeSet.Changes) { _currentBatchChangeSet.AddChange(chg); //System.Diagnostics.Debug.WriteLine("AddChange: BATCHED " + description); } } else { _undoStack.Push(changeSet); OnUndoStackChanged(); //System.Diagnostics.Debug.WriteLine("AddChange: " + description); } // Prune the RedoStack _redoStack.Clear(); OnRedoStackChanged(); }
/// <summary> /// Tells the UndoRoot that it can stop collecting Changes into a single ChangeSet. /// </summary> public void EndChangeSetBatch() { _isInBatchCounter--; if (_isInBatchCounter < 0) _isInBatchCounter = 0; if (_isInBatchCounter == 0) { _consolidateChangesForSameInstance = false; _currentBatchChangeSet = null; } }
/// <summary> /// Redo ChangeSets up to and including the lastChangeToRedo. /// </summary> public void Redo(ChangeSet lastChangeToRedo) { if (IsInBatch) throw new InvalidOperationException("Cannot perform a Redo when the Undo Service is collecting a batch of changes. The batch must be completed first."); if (!_redoStack.Contains(lastChangeToRedo)) throw new InvalidOperationException("The specified change does not exist in the list of redoable changes. Perhaps it has already been redone."); System.Diagnostics.Debug.WriteLine("Starting REDO: " + lastChangeToRedo.Description); bool done = false; _isUndoingOrRedoing = true; try { do { var changeSet = _redoStack.Pop(); OnRedoStackChanged(); if (changeSet == lastChangeToRedo || _redoStack.Count == 0) done = true; changeSet.Redo(); _undoStack.Push(changeSet); OnUndoStackChanged(); } while (!done); } finally { _isUndoingOrRedoing = false; } }
/// <summary> /// Tells the UndoRoot that all subsequent changes should be part of a single ChangeSet. /// </summary> public void BeginChangeSetBatch(string batchDescription, bool consolidateChangesForSameInstance) { // We don't want to add additional changes representing the operations that happen when undoing or redoing a change. if (_isUndoingOrRedoing) return; _isInBatchCounter++; if (_isInBatchCounter == 1) { _consolidateChangesForSameInstance = consolidateChangesForSameInstance; _currentBatchChangeSet = new ChangeSet(this, batchDescription, null); _undoStack.Push(_currentBatchChangeSet); OnUndoStackChanged(); } }