Code:
/ 4.0 / 4.0 / untmp / 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.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ColorAnimationUsingKeyFrames.cs
- FieldAccessException.cs
- ContextProperty.cs
- Matrix.cs
- DataControlFieldCell.cs
- DSACryptoServiceProvider.cs
- TraceSection.cs
- QueryCacheEntry.cs
- CheckBox.cs
- StringValidatorAttribute.cs
- TextProperties.cs
- FastEncoder.cs
- RadioButton.cs
- UshortList2.cs
- ImageMapEventArgs.cs
- EarlyBoundInfo.cs
- RangeValueProviderWrapper.cs
- EdmScalarPropertyAttribute.cs
- DataGridViewComponentPropertyGridSite.cs
- SharedHttpTransportManager.cs
- KeyedCollection.cs
- HostedHttpRequestAsyncResult.cs
- Wildcard.cs
- SQLResource.cs
- Listbox.cs
- InitializerFacet.cs
- DBSchemaRow.cs
- SiteMapNodeCollection.cs
- RootProfilePropertySettingsCollection.cs
- ParserContext.cs
- prompt.cs
- ExplicitDiscriminatorMap.cs
- EditingCoordinator.cs
- XmlEntityReference.cs
- PeerTransportListenAddressValidator.cs
- SQLBoolean.cs
- Duration.cs
- DataTableTypeConverter.cs
- QilTypeChecker.cs
- PointAnimationBase.cs
- Symbol.cs
- DropSource.cs
- WindowsTreeView.cs
- Missing.cs
- ElementsClipboardData.cs
- Rfc2898DeriveBytes.cs
- MeasurementDCInfo.cs
- QilIterator.cs
- DataGridClipboardCellContent.cs
- EndEvent.cs
- TracingConnectionListener.cs
- OrderedDictionary.cs
- PageStatePersister.cs
- objectresult_tresulttype.cs
- RegexTypeEditor.cs
- CompoundFileDeflateTransform.cs
- AutomationProperty.cs
- FamilyMapCollection.cs
- DragSelectionMessageFilter.cs
- BevelBitmapEffect.cs
- AssertFilter.cs
- webbrowsersite.cs
- EventsTab.cs
- LazyTextWriterCreator.cs
- recordstatescratchpad.cs
- httpserverutility.cs
- WebBrowserDocumentCompletedEventHandler.cs
- MenuAutomationPeer.cs
- VirtualDirectoryMapping.cs
- TextModifier.cs
- DesignBindingPicker.cs
- PermissionSet.cs
- DeferrableContentConverter.cs
- CodeIterationStatement.cs
- XslAstAnalyzer.cs
- HashCodeCombiner.cs
- SoapTypeAttribute.cs
- SystemBrushes.cs
- XmlObjectSerializerWriteContext.cs
- SerialPinChanges.cs
- DataSourceHelper.cs
- ParseNumbers.cs
- HttpServerUtilityWrapper.cs
- UniqueEventHelper.cs
- SolidColorBrush.cs
- Array.cs
- Point3DConverter.cs
- ReferenceCountedObject.cs
- HttpListenerException.cs
- FixedDocument.cs
- XmlDataSource.cs
- OuterGlowBitmapEffect.cs
- PolyQuadraticBezierSegment.cs
- LinkedResourceCollection.cs
- TreeViewBindingsEditor.cs
- ComboBoxRenderer.cs
- Timeline.cs
- ItemsPanelTemplate.cs
- ResourceDictionaryCollection.cs
- ObjectItemAssemblyLoader.cs