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
- DesignerTransaction.cs
- ToolStripProgressBar.cs
- ScriptControlDescriptor.cs
- DriveInfo.cs
- XmlSchemaComplexType.cs
- SoundPlayer.cs
- CAGDesigner.cs
- ValueOfAction.cs
- DataGridSortCommandEventArgs.cs
- Random.cs
- SchemaImporterExtensionElementCollection.cs
- JulianCalendar.cs
- TransformerTypeCollection.cs
- ListItemCollection.cs
- NavigationCommands.cs
- ExtractorMetadata.cs
- ValidatorCollection.cs
- TextDpi.cs
- WindowsAltTab.cs
- NotifyIcon.cs
- StdValidatorsAndConverters.cs
- Popup.cs
- MenuItemStyle.cs
- RMPermissions.cs
- OracleParameter.cs
- Size.cs
- SimpleMailWebEventProvider.cs
- SQLConvert.cs
- AttributeInfo.cs
- AuthStoreRoleProvider.cs
- MemberRestriction.cs
- ToolStripMenuItemDesigner.cs
- ToolStripMenuItemCodeDomSerializer.cs
- BamlResourceDeserializer.cs
- PerformanceCountersElement.cs
- BuildProviderUtils.cs
- ByteBufferPool.cs
- GuidelineSet.cs
- TlsSspiNegotiation.cs
- EventArgs.cs
- IsolatedStorageFileStream.cs
- TextServicesProperty.cs
- COM2ComponentEditor.cs
- HMACSHA1.cs
- RoutedEventConverter.cs
- LinqDataSourceView.cs
- Logging.cs
- Calendar.cs
- WebPartPersonalization.cs
- ListControl.cs
- WindowsHyperlink.cs
- CopyAction.cs
- FlowPosition.cs
- BamlLocalizationDictionary.cs
- ExceptionValidationRule.cs
- ColumnTypeConverter.cs
- BitmapEffectrendercontext.cs
- TransportSecurityBindingElement.cs
- EdmFunctionAttribute.cs
- AxHostDesigner.cs
- XmlCharCheckingReader.cs
- DependencyPropertyKind.cs
- BoolExpressionVisitors.cs
- DesignerValidatorAdapter.cs
- MessagePropertyFilter.cs
- EnvelopedPkcs7.cs
- BrowserCapabilitiesFactoryBase.cs
- oledbconnectionstring.cs
- StateDesigner.Layouts.cs
- PasswordTextContainer.cs
- ThemeDirectoryCompiler.cs
- FormatVersion.cs
- SqlBuilder.cs
- XmlHierarchicalDataSourceView.cs
- SpeechRecognizer.cs
- UserPreferenceChangingEventArgs.cs
- UIElement.cs
- ObjectFullSpanRewriter.cs
- HtmlWindow.cs
- SystemColorTracker.cs
- OdbcConnectionHandle.cs
- Command.cs
- HttpRuntime.cs
- RewritingProcessor.cs
- WinFormsSecurity.cs
- SQLInt32Storage.cs
- StateBag.cs
- IPHostEntry.cs
- Parameter.cs
- ValidationError.cs
- Paragraph.cs
- IdentifierCreationService.cs
- HashHelpers.cs
- WriterOutput.cs
- TextElementEnumerator.cs
- TextServicesLoader.cs
- HwndPanningFeedback.cs
- ItemDragEvent.cs
- WCFModelStrings.Designer.cs
- TreeViewImageKeyConverter.cs