Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / Tools / System.Activities.Presentation / System / Activities / Presentation / UndoEngine.cs / 1305376 / UndoEngine.cs
//---------------------------------------------------------------- // Copyright (c) Microsoft Corporation. All rights reserved. //--------------------------------------------------------------- namespace System.Activities.Presentation { using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Runtime; [Fx.Tag.XamlVisible(false)] public class UndoEngine : IUndoEngineOperations { const int capacity = 100; ListundoBuffer; List redoBuffer; EditingContext context; Bookmark bookmark; //interface which contains actual implementation of AddUndoUnit, Undo and Redo operations IUndoEngineOperations undoEngineImpl = null; public event EventHandler UndoUnitAdded; public event EventHandler UndoUnitDiscarded; internal event EventHandler ExecuteUndo; public event EventHandler UndoRedoBufferChanged; public UndoEngine(EditingContext context) { this.context = context; undoBuffer = new List (capacity); redoBuffer = new List (capacity); this.undoEngineImpl = this; } //CreateBookmark - creates a new UndoUnit which gatters all edits in its //undo unit list. all changes in bookmark appear as a one change and can be //undoned or redoned as a one set. internal Bookmark CreateBookmark(string bookmarkName) { //only one bookmark is supported if (null == this.bookmark) { //create bookmark undo unit, and give it a description BookmarkUndoUnit unit = new BookmarkUndoUnit(this.context) { Description = bookmarkName ?? string.Format(CultureInfo.InvariantCulture, "Bookmark {0}", Guid.NewGuid()), }; //create bookmark, and pass bookmark undo unit to it. this.bookmark = new Bookmark(this, unit); //switch implementation of AddUndoUnit, Undo, Redo to be delegated through bookmark this.undoEngineImpl = bookmark; return this.bookmark; } throw FxTrace.Exception.AsError(new NotSupportedException(SR.UndoEngine_NestedBookmarksException)); } public IEnumerable GetUndoActions() { return this.undoBuffer.Select(p => p.Description); } public IEnumerable GetRedoActions() { return this.redoBuffer.Select(p => p.Description); } void NotifyChange() { if (null != this.UndoRedoBufferChanged) { this.UndoRedoBufferChanged(this, EventArgs.Empty); } } public void AddUndoUnit(UndoUnit unit) { if (unit == null) { throw FxTrace.Exception.ArgumentNull("unit"); } this.undoEngineImpl.AddUndoUnitCore(unit); this.NotifyChange(); } public bool Undo() { this.IsUndoRedoInProgress = true; bool succeeded = this.undoEngineImpl.UndoCore(); this.IsUndoRedoInProgress = false; if (succeeded) { this.NotifyChange(); } return succeeded; } public bool Redo() { this.IsUndoRedoInProgress = true; bool succeeded = this.undoEngineImpl.RedoCore(); this.IsUndoRedoInProgress = false; if (succeeded) { this.NotifyChange(); } return succeeded; } public bool IsUndoRedoInProgress { get; private set; } void IUndoEngineOperations.AddUndoUnitCore(UndoUnit unit) { undoBuffer.Add(unit); RaiseUndoUnitAdded(unit); if (undoBuffer.Count > capacity) { undoBuffer.RemoveAt(0); RaiseUndoUnitDiscarded(); } redoBuffer.Clear(); } bool IUndoEngineOperations.UndoCore() { bool succeeded = false; if (undoBuffer.Count > 0) { UndoUnit unitToUndo = undoBuffer.Last(); undoBuffer.RemoveAt(undoBuffer.Count - 1); unitToUndo.Undo(); redoBuffer.Add(unitToUndo); RaiseExecuteUndo(unitToUndo); succeeded = true; } return succeeded; } bool IUndoEngineOperations.RedoCore() { bool succeeded = false; if (redoBuffer.Count > 0) { UndoUnit unitToRedo = redoBuffer.Last(); redoBuffer.RemoveAt(redoBuffer.Count - 1); unitToRedo.Redo(); undoBuffer.Add(unitToRedo); succeeded = true; } return succeeded; } void RaiseUndoUnitAdded(UndoUnit unit) { if (this.UndoUnitAdded != null) { this.UndoUnitAdded(this, new UndoUnitEventArgs() { UndoUnit = unit }); } } void RaiseUndoUnitDiscarded() { if (this.UndoUnitDiscarded != null) { this.UndoUnitDiscarded(this, null); } } void RaiseExecuteUndo(UndoUnit unitToUndo) { if (this.ExecuteUndo != null) { this.ExecuteUndo(this, new UndoUnitEventArgs() { UndoUnit = unitToUndo }); } } //Bookmark implmeentation - implements core UndoEngine operations + IDisposable - //default bookmark behaviour is to Rollback changes, unless commited explicitly. //usage of IDisposable enables usage of pattern: // using (Bookmark b = new Bookmark()).... internal sealed class Bookmark : IDisposable, IUndoEngineOperations { BookmarkUndoUnit containerUndoUnit; UndoEngine undoEngine; bool isCommited = false; bool isRolledBack = false; bool isDisposed = false; internal Bookmark(UndoEngine undoEngine, BookmarkUndoUnit undoUnit) { this.undoEngine = undoEngine; this.containerUndoUnit = undoUnit; } public void CommitBookmark() { //cannot commit more than once... if (this.isDisposed) { throw FxTrace.Exception.AsError(new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, SR.UndoEngine_OperationNotAllowed, "CommitBookmark"))); } this.isCommited = true; //restore original undo engine implementation this.undoEngine.undoEngineImpl = this.undoEngine; //get rid of the bookmark this.undoEngine.bookmark = null; //check if bookmark has any changes if (this.containerUndoUnit.DoList.Count != 0 || this.containerUndoUnit.RedoList.Count != 0) { //add all changes in bookmark into a undo list as a one element this.undoEngine.AddUndoUnit(this.containerUndoUnit); } //dispose bookmark this.Dispose(); } public void RollbackBookmark() { //cannot rollback more than once if (this.isDisposed) { throw FxTrace.Exception.AsError(new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, SR.UndoEngine_OperationNotAllowed, "RollbackBookmark"))); } this.isRolledBack = true; //get through the list of all accumulated changes and reverse each of them foreach (UndoUnit unit in this.containerUndoUnit.DoList.Reverse ()) { unit.Undo(); } //clear the lists this.containerUndoUnit.DoList.Clear(); this.containerUndoUnit.RedoList.Clear(); //restore original undo engine implementation this.undoEngine.undoEngineImpl = this.undoEngine; //get rid of the bookmark this.undoEngine.bookmark = null; //dispose bookmark this.Dispose(); } public void Dispose() { if (!this.isDisposed) { GC.SuppressFinalize(this); DisposeInternal(); } } void DisposeInternal() { if (!this.isDisposed) { //if not commited or rolled back - rollback by default if (!this.isCommited && !this.isRolledBack) { this.RollbackBookmark(); } this.isDisposed = true; } } void IUndoEngineOperations.AddUndoUnitCore(UndoUnit unit) { //add element to Undo list this.containerUndoUnit.DoList.Add(unit); //clear redo list this.containerUndoUnit.RedoList.Clear(); } bool IUndoEngineOperations.UndoCore() { //if there is anything to undo bool succeeded = false; if (this.containerUndoUnit.DoList.Count > 0) { //get the last element done UndoUnit unitToUndo = this.containerUndoUnit.DoList.Last(); //remove it this.containerUndoUnit.DoList.RemoveAt(this.containerUndoUnit.DoList.Count - 1); //undo it unitToUndo.Undo(); //and insert to the head of redo list this.containerUndoUnit.RedoList.Insert(0, unitToUndo); succeeded = true; } return succeeded; } bool IUndoEngineOperations.RedoCore() { //if there is anything to redo bool succeeded = false; if (this.containerUndoUnit.RedoList.Count > 0) { //get first element to redo UndoUnit unitToRedo = this.containerUndoUnit.RedoList.First(); //remove it this.containerUndoUnit.RedoList.RemoveAt(0); //redo it unitToRedo.Redo(); //add it to the end of undo list this.containerUndoUnit.DoList.Add(unitToRedo); succeeded = true; } return succeeded; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //---------------------------------------------------------------- // Copyright (c) Microsoft Corporation. All rights reserved. //--------------------------------------------------------------- namespace System.Activities.Presentation { using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Runtime; [Fx.Tag.XamlVisible(false)] public class UndoEngine : IUndoEngineOperations { const int capacity = 100; List undoBuffer; List redoBuffer; EditingContext context; Bookmark bookmark; //interface which contains actual implementation of AddUndoUnit, Undo and Redo operations IUndoEngineOperations undoEngineImpl = null; public event EventHandler UndoUnitAdded; public event EventHandler UndoUnitDiscarded; internal event EventHandler ExecuteUndo; public event EventHandler UndoRedoBufferChanged; public UndoEngine(EditingContext context) { this.context = context; undoBuffer = new List (capacity); redoBuffer = new List (capacity); this.undoEngineImpl = this; } //CreateBookmark - creates a new UndoUnit which gatters all edits in its //undo unit list. all changes in bookmark appear as a one change and can be //undoned or redoned as a one set. internal Bookmark CreateBookmark(string bookmarkName) { //only one bookmark is supported if (null == this.bookmark) { //create bookmark undo unit, and give it a description BookmarkUndoUnit unit = new BookmarkUndoUnit(this.context) { Description = bookmarkName ?? string.Format(CultureInfo.InvariantCulture, "Bookmark {0}", Guid.NewGuid()), }; //create bookmark, and pass bookmark undo unit to it. this.bookmark = new Bookmark(this, unit); //switch implementation of AddUndoUnit, Undo, Redo to be delegated through bookmark this.undoEngineImpl = bookmark; return this.bookmark; } throw FxTrace.Exception.AsError(new NotSupportedException(SR.UndoEngine_NestedBookmarksException)); } public IEnumerable GetUndoActions() { return this.undoBuffer.Select(p => p.Description); } public IEnumerable GetRedoActions() { return this.redoBuffer.Select(p => p.Description); } void NotifyChange() { if (null != this.UndoRedoBufferChanged) { this.UndoRedoBufferChanged(this, EventArgs.Empty); } } public void AddUndoUnit(UndoUnit unit) { if (unit == null) { throw FxTrace.Exception.ArgumentNull("unit"); } this.undoEngineImpl.AddUndoUnitCore(unit); this.NotifyChange(); } public bool Undo() { this.IsUndoRedoInProgress = true; bool succeeded = this.undoEngineImpl.UndoCore(); this.IsUndoRedoInProgress = false; if (succeeded) { this.NotifyChange(); } return succeeded; } public bool Redo() { this.IsUndoRedoInProgress = true; bool succeeded = this.undoEngineImpl.RedoCore(); this.IsUndoRedoInProgress = false; if (succeeded) { this.NotifyChange(); } return succeeded; } public bool IsUndoRedoInProgress { get; private set; } void IUndoEngineOperations.AddUndoUnitCore(UndoUnit unit) { undoBuffer.Add(unit); RaiseUndoUnitAdded(unit); if (undoBuffer.Count > capacity) { undoBuffer.RemoveAt(0); RaiseUndoUnitDiscarded(); } redoBuffer.Clear(); } bool IUndoEngineOperations.UndoCore() { bool succeeded = false; if (undoBuffer.Count > 0) { UndoUnit unitToUndo = undoBuffer.Last(); undoBuffer.RemoveAt(undoBuffer.Count - 1); unitToUndo.Undo(); redoBuffer.Add(unitToUndo); RaiseExecuteUndo(unitToUndo); succeeded = true; } return succeeded; } bool IUndoEngineOperations.RedoCore() { bool succeeded = false; if (redoBuffer.Count > 0) { UndoUnit unitToRedo = redoBuffer.Last(); redoBuffer.RemoveAt(redoBuffer.Count - 1); unitToRedo.Redo(); undoBuffer.Add(unitToRedo); succeeded = true; } return succeeded; } void RaiseUndoUnitAdded(UndoUnit unit) { if (this.UndoUnitAdded != null) { this.UndoUnitAdded(this, new UndoUnitEventArgs() { UndoUnit = unit }); } } void RaiseUndoUnitDiscarded() { if (this.UndoUnitDiscarded != null) { this.UndoUnitDiscarded(this, null); } } void RaiseExecuteUndo(UndoUnit unitToUndo) { if (this.ExecuteUndo != null) { this.ExecuteUndo(this, new UndoUnitEventArgs() { UndoUnit = unitToUndo }); } } //Bookmark implmeentation - implements core UndoEngine operations + IDisposable - //default bookmark behaviour is to Rollback changes, unless commited explicitly. //usage of IDisposable enables usage of pattern: // using (Bookmark b = new Bookmark()).... internal sealed class Bookmark : IDisposable, IUndoEngineOperations { BookmarkUndoUnit containerUndoUnit; UndoEngine undoEngine; bool isCommited = false; bool isRolledBack = false; bool isDisposed = false; internal Bookmark(UndoEngine undoEngine, BookmarkUndoUnit undoUnit) { this.undoEngine = undoEngine; this.containerUndoUnit = undoUnit; } public void CommitBookmark() { //cannot commit more than once... if (this.isDisposed) { throw FxTrace.Exception.AsError(new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, SR.UndoEngine_OperationNotAllowed, "CommitBookmark"))); } this.isCommited = true; //restore original undo engine implementation this.undoEngine.undoEngineImpl = this.undoEngine; //get rid of the bookmark this.undoEngine.bookmark = null; //check if bookmark has any changes if (this.containerUndoUnit.DoList.Count != 0 || this.containerUndoUnit.RedoList.Count != 0) { //add all changes in bookmark into a undo list as a one element this.undoEngine.AddUndoUnit(this.containerUndoUnit); } //dispose bookmark this.Dispose(); } public void RollbackBookmark() { //cannot rollback more than once if (this.isDisposed) { throw FxTrace.Exception.AsError(new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, SR.UndoEngine_OperationNotAllowed, "RollbackBookmark"))); } this.isRolledBack = true; //get through the list of all accumulated changes and reverse each of them foreach (UndoUnit unit in this.containerUndoUnit.DoList.Reverse ()) { unit.Undo(); } //clear the lists this.containerUndoUnit.DoList.Clear(); this.containerUndoUnit.RedoList.Clear(); //restore original undo engine implementation this.undoEngine.undoEngineImpl = this.undoEngine; //get rid of the bookmark this.undoEngine.bookmark = null; //dispose bookmark this.Dispose(); } public void Dispose() { if (!this.isDisposed) { GC.SuppressFinalize(this); DisposeInternal(); } } void DisposeInternal() { if (!this.isDisposed) { //if not commited or rolled back - rollback by default if (!this.isCommited && !this.isRolledBack) { this.RollbackBookmark(); } this.isDisposed = true; } } void IUndoEngineOperations.AddUndoUnitCore(UndoUnit unit) { //add element to Undo list this.containerUndoUnit.DoList.Add(unit); //clear redo list this.containerUndoUnit.RedoList.Clear(); } bool IUndoEngineOperations.UndoCore() { //if there is anything to undo bool succeeded = false; if (this.containerUndoUnit.DoList.Count > 0) { //get the last element done UndoUnit unitToUndo = this.containerUndoUnit.DoList.Last(); //remove it this.containerUndoUnit.DoList.RemoveAt(this.containerUndoUnit.DoList.Count - 1); //undo it unitToUndo.Undo(); //and insert to the head of redo list this.containerUndoUnit.RedoList.Insert(0, unitToUndo); succeeded = true; } return succeeded; } bool IUndoEngineOperations.RedoCore() { //if there is anything to redo bool succeeded = false; if (this.containerUndoUnit.RedoList.Count > 0) { //get first element to redo UndoUnit unitToRedo = this.containerUndoUnit.RedoList.First(); //remove it this.containerUndoUnit.RedoList.RemoveAt(0); //redo it unitToRedo.Redo(); //add it to the end of undo list this.containerUndoUnit.DoList.Add(unitToRedo); succeeded = true; } return succeeded; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ASCIIEncoding.cs
- GradientBrush.cs
- Int32AnimationBase.cs
- WebPartHeaderCloseVerb.cs
- BaseCollection.cs
- TextTreeText.cs
- CharacterString.cs
- Light.cs
- XmlComplianceUtil.cs
- AnnotationAuthorChangedEventArgs.cs
- ColumnCollection.cs
- HorizontalAlignConverter.cs
- Marshal.cs
- PageParser.cs
- EmbeddedObject.cs
- TextElementEditingBehaviorAttribute.cs
- QueryGeneratorBase.cs
- ColumnWidthChangingEvent.cs
- XmlCharCheckingReader.cs
- recordstate.cs
- WaitHandleCannotBeOpenedException.cs
- EntityObject.cs
- FormViewDesigner.cs
- DBSqlParser.cs
- ClientData.cs
- Vector3DCollectionConverter.cs
- InternalBufferManager.cs
- GridViewColumnCollectionChangedEventArgs.cs
- handlecollector.cs
- ItemsControl.cs
- X509AsymmetricSecurityKey.cs
- AddingNewEventArgs.cs
- TdsParserHelperClasses.cs
- QueueTransferProtocol.cs
- ConstructorBuilder.cs
- System.Data.OracleClient_BID.cs
- DetailsViewRow.cs
- TableColumn.cs
- UnlockCardRequest.cs
- DrawListViewSubItemEventArgs.cs
- CompareValidator.cs
- ContractListAdapter.cs
- EventQueueState.cs
- SystemWebExtensionsSectionGroup.cs
- AttachedAnnotationChangedEventArgs.cs
- UpDownEvent.cs
- ValidationHelper.cs
- ConvertEvent.cs
- IncomingWebRequestContext.cs
- ApplicationTrust.cs
- SafeMILHandle.cs
- IdnElement.cs
- WebPartConnection.cs
- SinglePageViewer.cs
- DefaultAsyncDataDispatcher.cs
- ParameterModifier.cs
- StrongNameKeyPair.cs
- Mapping.cs
- DataGridCellAutomationPeer.cs
- WorkflowApplicationException.cs
- TextBoxAutoCompleteSourceConverter.cs
- LiteralControl.cs
- TreeViewImageIndexConverter.cs
- NullableIntMinMaxAggregationOperator.cs
- TimeStampChecker.cs
- ApplicationSecurityInfo.cs
- SchemaName.cs
- QilName.cs
- ComplexBindingPropertiesAttribute.cs
- AppDomainProtocolHandler.cs
- MonthChangedEventArgs.cs
- AdornerHitTestResult.cs
- UriParserTemplates.cs
- ReadWriteObjectLock.cs
- DataControlImageButton.cs
- coordinatorscratchpad.cs
- XmlStreamNodeWriter.cs
- WasAdminWrapper.cs
- StateDesigner.CommentLayoutGlyph.cs
- HwndSourceParameters.cs
- DateTimeConverter.cs
- SystemPens.cs
- ExpanderAutomationPeer.cs
- PropertyKey.cs
- PrefixHandle.cs
- AutomationElementIdentifiers.cs
- DictionarySectionHandler.cs
- ServicePointManager.cs
- EntryPointNotFoundException.cs
- _AutoWebProxyScriptWrapper.cs
- AssemblyCollection.cs
- StubHelpers.cs
- FrugalList.cs
- ContainerControl.cs
- Style.cs
- WindowsSpinner.cs
- SequenceQuery.cs
- ToolStripItemDesigner.cs
- InvalidFilterCriteriaException.cs
- SecurityUtils.cs