Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Framework / MS / Internal / documents / ParentUndoUnit.cs / 1 / ParentUndoUnit.cs
//---------------------------------------------------------------------------- // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: // // See spec at http://avalon/uis/Stock%20Services/Undo%20spec.htm // // History: // 07/21/2003 : psarrett ported to WCP tree // 03/21/2004 : eveselov - code style cleaned // //--------------------------------------------------------------------------- using System; using System.Windows; using System.Collections; using MS.Utility; namespace MS.Internal.Documents { ////// ParentUndoUnit /// internal class ParentUndoUnit : IParentUndoUnit { //----------------------------------------------------- // // Constructors // //----------------------------------------------------- #region Constructors ////// Constructor /// /// /// Text description of the undo unit /// public ParentUndoUnit(string description) : base() { Init(description); } #endregion Constructors //------------------------------------------------------ // // Public Methods // //----------------------------------------------------- #region Public Methods ////// Opens a new parent undo unit. /// /// /// IParentUndoUnit to open /// ////// Thrown if passed unit is null. /// public virtual void Open(IParentUndoUnit newUnit) { IParentUndoUnit deepestOpen; if (newUnit == null) { throw new ArgumentNullException("newUnit"); } deepestOpen = DeepestOpenUnit; if (deepestOpen == null) { if (IsInParentUnitChain(newUnit)) { throw new InvalidOperationException(SR.Get(SRID.UndoUnitCantBeOpenedTwice)); } _openedUnit = newUnit; if (newUnit != null) { newUnit.Container = this; } } else { if (newUnit != null) { newUnit.Container = deepestOpen; } deepestOpen.Open(newUnit); } } ////// Closes the current open unit, adding it to the containing unit's undo stack if committed. /// public virtual void Close(UndoCloseAction closeAction) { Close(OpenedUnit, closeAction); } ////// Closes an open child parent unit, adding it to the containing unit's undo stack if committed. /// /// /// IParentUndoUnit to close. If NULL, this unit's OpenedUnit is closed. /// /// /// ////// Thrown if no undo unit is currently open /// ////// Thrown if unit is null /// public virtual void Close(IParentUndoUnit unit, UndoCloseAction closeAction) { UndoManager undoManager; if (unit == null) { throw new ArgumentNullException("unit"); } if (OpenedUnit == null) { throw new InvalidOperationException(SR.Get(SRID.UndoNoOpenUnit)); } // find the parent of the given unit if (OpenedUnit != unit) { IParentUndoUnit closeParent; closeParent = this; while (closeParent.OpenedUnit != null && closeParent.OpenedUnit != unit) { closeParent = closeParent.OpenedUnit; } if (closeParent.OpenedUnit == null) { throw new ArgumentException(SR.Get(SRID.UndoUnitNotFound), "unit"); } if (closeParent != this) { closeParent.Close(closeAction); return; } } // // Close our open unit // // Get the undo manager undoManager = TopContainer as UndoManager; if (closeAction != UndoCloseAction.Commit) { // discard unit if (undoManager != null) { undoManager.IsEnabled = false; } if (OpenedUnit.OpenedUnit != null) { OpenedUnit.Close(closeAction); } if (closeAction == UndoCloseAction.Rollback) { ((IParentUndoUnit)OpenedUnit).Do(); } _openedUnit = null; // unlock previous unit(s) if (TopContainer is UndoManager) { ((UndoManager)TopContainer).OnNextDiscard(); } else { ((IParentUndoUnit)TopContainer).OnNextDiscard(); } if (undoManager != null) { undoManager.IsEnabled = true; } } else { // commit unit if (OpenedUnit.OpenedUnit != null) { OpenedUnit.Close(UndoCloseAction.Commit); } IParentUndoUnit openedUnit = OpenedUnit; _openedUnit = null; Add(openedUnit); SetLastUnit(openedUnit); } } ////// Adds an undo unit to the deepest open parent unit's collection. /// /// /// IUndoUnit to add /// ////// TRUE if unit successfully added, FALSE otherwise /// ////// Thrown if unit is null /// ////// Thrown if: /// unit being added is already open /// unit being added to is locked /// public virtual void Add(IUndoUnit unit) { IParentUndoUnit parentUndoUnit; if (unit == null) { throw new ArgumentNullException("unit"); } parentUndoUnit = DeepestOpenUnit; // If we have an open unit, call Add on it if (parentUndoUnit != null) { parentUndoUnit.Add(unit); return; } if (IsInParentUnitChain(unit)) { throw new InvalidOperationException(SR.Get(SRID.UndoUnitCantBeAddedTwice)); } if (Locked) { throw new InvalidOperationException(SR.Get(SRID.UndoUnitLocked)); } if (!Merge(unit)) { _units.Push(unit); if (LastUnit is IParentUndoUnit) { ((IParentUndoUnit)LastUnit).OnNextAdd(); } SetLastUnit(unit); } } ////// Clear all undo units. /// ////// Thrown if unit is locked /// public virtual void Clear() { if (Locked) { throw new InvalidOperationException(SR.Get(SRID.UndoUnitLocked)); } _units.Clear(); SetOpenedUnit(null); SetLastUnit(null); } ////// Notifies the last parent undo unit in the collection that a new unit has been added /// to the collection. The undo manager or containing parent undo unit calls this /// function on its most recently added parent undo unit to notify it that the context /// has changed and no further modifications should be made to it. /// public virtual void OnNextAdd() { _locked = true; foreach (IUndoUnit unit in _units) { if (unit is IParentUndoUnit) { ((IParentUndoUnit)unit).OnNextAdd(); } } } ////// Inverse of OnNextAdd(). Called when a unit previously added after this one gets discarded. /// public virtual void OnNextDiscard() { _locked = false; IParentUndoUnit lastParent = this; foreach (IUndoUnit unit in _units) { if (unit is IParentUndoUnit) { lastParent = unit as IParentUndoUnit; } } if (lastParent != this) { lastParent.OnNextDiscard(); } } ////// Implements IUndoUnit::Do(). For IParentUndoUnit, this means iterating through /// all contained units and calling their Do(). /// public virtual void Do() { IParentUndoUnit redo; UndoManager topContainer; // Create the parent redo unit redo = CreateParentUndoUnitForSelf(); topContainer = TopContainer as UndoManager; if (topContainer != null) { if (topContainer.IsEnabled) { topContainer.Open(redo); } } while (_units.Count > 0) { IUndoUnit unit; unit = _units.Pop() as IUndoUnit; unit.Do(); } if (topContainer != null) { if (topContainer.IsEnabled) { topContainer.Close(redo, UndoCloseAction.Commit); } } } ////// Iterates through all child units, attempting to merge the given unit into that unit. /// Only simple undo units are merged-- parent undo units are not. /// /// /// IUndoUnit to merge /// ////// true if unit was merged, false otherwise /// public virtual bool Merge(IUndoUnit unit) { Invariant.Assert(unit != null); return false; } #endregion Public Methods //------------------------------------------------------ // // Public Properties // //------------------------------------------------------ #region Public Properties ////// text description of this unit /// public string Description { get { return _description; } set { if (value == null) { value = String.Empty; } _description = value; } } ////// Returns the most recent child parent unit /// public IParentUndoUnit OpenedUnit { get { return _openedUnit; } } ////// Readonly access to the last unit added to the IParentUndoUnit /// public IUndoUnit LastUnit { get { return _lastUnit; } } ////// Whether or not the unit can accept new changes /// public virtual bool Locked { get { return _locked; } protected set { _locked = value; } } ////// The IParentUndoUnit or UndoManager this parent unit is contained by. /// public object Container { get { return _container; } set { if (!(value is IParentUndoUnit || value is UndoManager)) { throw new Exception(SR.Get(SRID.UndoContainerTypeMismatch)); } _container = value; } } #endregion Public Properties //----------------------------------------------------- // // Public Events // //------------------------------------------------------ //----------------------------------------------------- // // Protected Methods // //----------------------------------------------------- #region Protected Methods ////// Initialization common to all constructors /// /// /// String describing the undo unit /// protected void Init(string description) { if (description == null) { description = String.Empty; } _description = description; _locked = false; _openedUnit = null; _units = new Stack(2); _container = null; } ////// current opened unit /// /// /// IParentUndoUnit to which OpenedUnit is to be set /// protected void SetOpenedUnit(IParentUndoUnit value) { _openedUnit = value; } ////// Set LastUnit /// /// /// IUndoUnit to which LastUnit is to be set /// protected void SetLastUnit(IUndoUnit value) { _lastUnit = value; } ////// Callback from Do method allowing derived subclass to /// provide its own ParentUndoUnit. By default general /// ParentUndoUnit is created. /// ///protected virtual IParentUndoUnit CreateParentUndoUnitForSelf() { return new ParentUndoUnit(Description); } #endregion Protected Methods //----------------------------------------------------- // // Protected Properties // //------------------------------------------------------ #region Protected Properties /// /// Returns the deepest open parent undo unit contained within this one. /// protected IParentUndoUnit DeepestOpenUnit { get { IParentUndoUnit openedUnit; openedUnit = _openedUnit; if (openedUnit != null) { while (openedUnit.OpenedUnit != null) { openedUnit = openedUnit.OpenedUnit; } } return openedUnit; } } ////// Returns the outermost container of this unit. /// protected object TopContainer { get { object container; container = this; while (container is IParentUndoUnit && ((IParentUndoUnit)container).Container != null) { container = ((IParentUndoUnit)container).Container; } return container; } } protected Stack Units { get { return _units; } } #endregion Protected Properties //----------------------------------------------------- // // Private Methods // //------------------------------------------------------ #region Private Methods ////// Walk up the parent undo unit chain and make sure none of the parent units /// in that chain are the same as the given unit. /// /// /// Unit to search for in the parent chain /// ////// true if the unit is already in the parent chain, false otherwise /// bool IsInParentUnitChain(IUndoUnit unit) { if (unit is IParentUndoUnit) { IParentUndoUnit parent; parent = this; do { if (parent == unit) { return true; } parent = parent.Container as IParentUndoUnit; } while (parent != null); } return false; } #endregion Private methods //------------------------------------------------------ // // Private Properties // //----------------------------------------------------- //------------------------------------------------------ // // Private Fields // //----------------------------------------------------- #region Private Fields private string _description; private bool _locked; private IParentUndoUnit _openedUnit; private IUndoUnit _lastUnit; private Stack _units; private object _container; #endregion Private Fields } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //---------------------------------------------------------------------------- // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: // // See spec at http://avalon/uis/Stock%20Services/Undo%20spec.htm // // History: // 07/21/2003 : psarrett ported to WCP tree // 03/21/2004 : eveselov - code style cleaned // //--------------------------------------------------------------------------- using System; using System.Windows; using System.Collections; using MS.Utility; namespace MS.Internal.Documents { ////// ParentUndoUnit /// internal class ParentUndoUnit : IParentUndoUnit { //----------------------------------------------------- // // Constructors // //----------------------------------------------------- #region Constructors ////// Constructor /// /// /// Text description of the undo unit /// public ParentUndoUnit(string description) : base() { Init(description); } #endregion Constructors //------------------------------------------------------ // // Public Methods // //----------------------------------------------------- #region Public Methods ////// Opens a new parent undo unit. /// /// /// IParentUndoUnit to open /// ////// Thrown if passed unit is null. /// public virtual void Open(IParentUndoUnit newUnit) { IParentUndoUnit deepestOpen; if (newUnit == null) { throw new ArgumentNullException("newUnit"); } deepestOpen = DeepestOpenUnit; if (deepestOpen == null) { if (IsInParentUnitChain(newUnit)) { throw new InvalidOperationException(SR.Get(SRID.UndoUnitCantBeOpenedTwice)); } _openedUnit = newUnit; if (newUnit != null) { newUnit.Container = this; } } else { if (newUnit != null) { newUnit.Container = deepestOpen; } deepestOpen.Open(newUnit); } } ////// Closes the current open unit, adding it to the containing unit's undo stack if committed. /// public virtual void Close(UndoCloseAction closeAction) { Close(OpenedUnit, closeAction); } ////// Closes an open child parent unit, adding it to the containing unit's undo stack if committed. /// /// /// IParentUndoUnit to close. If NULL, this unit's OpenedUnit is closed. /// /// /// ////// Thrown if no undo unit is currently open /// ////// Thrown if unit is null /// public virtual void Close(IParentUndoUnit unit, UndoCloseAction closeAction) { UndoManager undoManager; if (unit == null) { throw new ArgumentNullException("unit"); } if (OpenedUnit == null) { throw new InvalidOperationException(SR.Get(SRID.UndoNoOpenUnit)); } // find the parent of the given unit if (OpenedUnit != unit) { IParentUndoUnit closeParent; closeParent = this; while (closeParent.OpenedUnit != null && closeParent.OpenedUnit != unit) { closeParent = closeParent.OpenedUnit; } if (closeParent.OpenedUnit == null) { throw new ArgumentException(SR.Get(SRID.UndoUnitNotFound), "unit"); } if (closeParent != this) { closeParent.Close(closeAction); return; } } // // Close our open unit // // Get the undo manager undoManager = TopContainer as UndoManager; if (closeAction != UndoCloseAction.Commit) { // discard unit if (undoManager != null) { undoManager.IsEnabled = false; } if (OpenedUnit.OpenedUnit != null) { OpenedUnit.Close(closeAction); } if (closeAction == UndoCloseAction.Rollback) { ((IParentUndoUnit)OpenedUnit).Do(); } _openedUnit = null; // unlock previous unit(s) if (TopContainer is UndoManager) { ((UndoManager)TopContainer).OnNextDiscard(); } else { ((IParentUndoUnit)TopContainer).OnNextDiscard(); } if (undoManager != null) { undoManager.IsEnabled = true; } } else { // commit unit if (OpenedUnit.OpenedUnit != null) { OpenedUnit.Close(UndoCloseAction.Commit); } IParentUndoUnit openedUnit = OpenedUnit; _openedUnit = null; Add(openedUnit); SetLastUnit(openedUnit); } } ////// Adds an undo unit to the deepest open parent unit's collection. /// /// /// IUndoUnit to add /// ////// TRUE if unit successfully added, FALSE otherwise /// ////// Thrown if unit is null /// ////// Thrown if: /// unit being added is already open /// unit being added to is locked /// public virtual void Add(IUndoUnit unit) { IParentUndoUnit parentUndoUnit; if (unit == null) { throw new ArgumentNullException("unit"); } parentUndoUnit = DeepestOpenUnit; // If we have an open unit, call Add on it if (parentUndoUnit != null) { parentUndoUnit.Add(unit); return; } if (IsInParentUnitChain(unit)) { throw new InvalidOperationException(SR.Get(SRID.UndoUnitCantBeAddedTwice)); } if (Locked) { throw new InvalidOperationException(SR.Get(SRID.UndoUnitLocked)); } if (!Merge(unit)) { _units.Push(unit); if (LastUnit is IParentUndoUnit) { ((IParentUndoUnit)LastUnit).OnNextAdd(); } SetLastUnit(unit); } } ////// Clear all undo units. /// ////// Thrown if unit is locked /// public virtual void Clear() { if (Locked) { throw new InvalidOperationException(SR.Get(SRID.UndoUnitLocked)); } _units.Clear(); SetOpenedUnit(null); SetLastUnit(null); } ////// Notifies the last parent undo unit in the collection that a new unit has been added /// to the collection. The undo manager or containing parent undo unit calls this /// function on its most recently added parent undo unit to notify it that the context /// has changed and no further modifications should be made to it. /// public virtual void OnNextAdd() { _locked = true; foreach (IUndoUnit unit in _units) { if (unit is IParentUndoUnit) { ((IParentUndoUnit)unit).OnNextAdd(); } } } ////// Inverse of OnNextAdd(). Called when a unit previously added after this one gets discarded. /// public virtual void OnNextDiscard() { _locked = false; IParentUndoUnit lastParent = this; foreach (IUndoUnit unit in _units) { if (unit is IParentUndoUnit) { lastParent = unit as IParentUndoUnit; } } if (lastParent != this) { lastParent.OnNextDiscard(); } } ////// Implements IUndoUnit::Do(). For IParentUndoUnit, this means iterating through /// all contained units and calling their Do(). /// public virtual void Do() { IParentUndoUnit redo; UndoManager topContainer; // Create the parent redo unit redo = CreateParentUndoUnitForSelf(); topContainer = TopContainer as UndoManager; if (topContainer != null) { if (topContainer.IsEnabled) { topContainer.Open(redo); } } while (_units.Count > 0) { IUndoUnit unit; unit = _units.Pop() as IUndoUnit; unit.Do(); } if (topContainer != null) { if (topContainer.IsEnabled) { topContainer.Close(redo, UndoCloseAction.Commit); } } } ////// Iterates through all child units, attempting to merge the given unit into that unit. /// Only simple undo units are merged-- parent undo units are not. /// /// /// IUndoUnit to merge /// ////// true if unit was merged, false otherwise /// public virtual bool Merge(IUndoUnit unit) { Invariant.Assert(unit != null); return false; } #endregion Public Methods //------------------------------------------------------ // // Public Properties // //------------------------------------------------------ #region Public Properties ////// text description of this unit /// public string Description { get { return _description; } set { if (value == null) { value = String.Empty; } _description = value; } } ////// Returns the most recent child parent unit /// public IParentUndoUnit OpenedUnit { get { return _openedUnit; } } ////// Readonly access to the last unit added to the IParentUndoUnit /// public IUndoUnit LastUnit { get { return _lastUnit; } } ////// Whether or not the unit can accept new changes /// public virtual bool Locked { get { return _locked; } protected set { _locked = value; } } ////// The IParentUndoUnit or UndoManager this parent unit is contained by. /// public object Container { get { return _container; } set { if (!(value is IParentUndoUnit || value is UndoManager)) { throw new Exception(SR.Get(SRID.UndoContainerTypeMismatch)); } _container = value; } } #endregion Public Properties //----------------------------------------------------- // // Public Events // //------------------------------------------------------ //----------------------------------------------------- // // Protected Methods // //----------------------------------------------------- #region Protected Methods ////// Initialization common to all constructors /// /// /// String describing the undo unit /// protected void Init(string description) { if (description == null) { description = String.Empty; } _description = description; _locked = false; _openedUnit = null; _units = new Stack(2); _container = null; } ////// current opened unit /// /// /// IParentUndoUnit to which OpenedUnit is to be set /// protected void SetOpenedUnit(IParentUndoUnit value) { _openedUnit = value; } ////// Set LastUnit /// /// /// IUndoUnit to which LastUnit is to be set /// protected void SetLastUnit(IUndoUnit value) { _lastUnit = value; } ////// Callback from Do method allowing derived subclass to /// provide its own ParentUndoUnit. By default general /// ParentUndoUnit is created. /// ///protected virtual IParentUndoUnit CreateParentUndoUnitForSelf() { return new ParentUndoUnit(Description); } #endregion Protected Methods //----------------------------------------------------- // // Protected Properties // //------------------------------------------------------ #region Protected Properties /// /// Returns the deepest open parent undo unit contained within this one. /// protected IParentUndoUnit DeepestOpenUnit { get { IParentUndoUnit openedUnit; openedUnit = _openedUnit; if (openedUnit != null) { while (openedUnit.OpenedUnit != null) { openedUnit = openedUnit.OpenedUnit; } } return openedUnit; } } ////// Returns the outermost container of this unit. /// protected object TopContainer { get { object container; container = this; while (container is IParentUndoUnit && ((IParentUndoUnit)container).Container != null) { container = ((IParentUndoUnit)container).Container; } return container; } } protected Stack Units { get { return _units; } } #endregion Protected Properties //----------------------------------------------------- // // Private Methods // //------------------------------------------------------ #region Private Methods ////// Walk up the parent undo unit chain and make sure none of the parent units /// in that chain are the same as the given unit. /// /// /// Unit to search for in the parent chain /// ////// true if the unit is already in the parent chain, false otherwise /// bool IsInParentUnitChain(IUndoUnit unit) { if (unit is IParentUndoUnit) { IParentUndoUnit parent; parent = this; do { if (parent == unit) { return true; } parent = parent.Container as IParentUndoUnit; } while (parent != null); } return false; } #endregion Private methods //------------------------------------------------------ // // Private Properties // //----------------------------------------------------- //------------------------------------------------------ // // Private Fields // //----------------------------------------------------- #region Private Fields private string _description; private bool _locked; private IParentUndoUnit _openedUnit; private IUndoUnit _lastUnit; private Stack _units; private object _container; #endregion Private Fields } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- MdiWindowListStrip.cs
- DllNotFoundException.cs
- EventMap.cs
- XPathParser.cs
- RegexFCD.cs
- UncommonField.cs
- DesignerDataColumn.cs
- RSAPKCS1KeyExchangeFormatter.cs
- TabControl.cs
- GeometryCombineModeValidation.cs
- ShaderRenderModeValidation.cs
- ObjectDataSourceStatusEventArgs.cs
- NullableDecimalSumAggregationOperator.cs
- LoadRetryAsyncResult.cs
- BindingExpression.cs
- ActivityBuilderXamlWriter.cs
- ComponentConverter.cs
- DockProviderWrapper.cs
- FrameworkContextData.cs
- LockedBorderGlyph.cs
- XmlEntity.cs
- PropertyIdentifier.cs
- Cursors.cs
- UrlAuthorizationModule.cs
- XmlDocumentSurrogate.cs
- NavigatorOutput.cs
- ContextMenuService.cs
- DoubleLinkList.cs
- PathData.cs
- TypefaceCollection.cs
- TableLayoutSettingsTypeConverter.cs
- TailCallAnalyzer.cs
- ObjectFactoryCodeDomTreeGenerator.cs
- DatePickerDateValidationErrorEventArgs.cs
- _SingleItemRequestCache.cs
- ConfigurationPropertyAttribute.cs
- PeerApplicationLaunchInfo.cs
- PerfProviderCollection.cs
- DateTimeFormatInfo.cs
- TemplateAction.cs
- ReliableChannelBinder.cs
- EntityParameter.cs
- InfoCardRSAOAEPKeyExchangeFormatter.cs
- OleDbException.cs
- DateTimeUtil.cs
- EntitySqlQueryBuilder.cs
- HandleTable.cs
- AddingNewEventArgs.cs
- SystemInfo.cs
- TcpAppDomainProtocolHandler.cs
- DeflateEmulationStream.cs
- ISO2022Encoding.cs
- FrameDimension.cs
- OnOperation.cs
- SqlRowUpdatingEvent.cs
- ResourceSet.cs
- RegexFCD.cs
- SubMenuStyleCollectionEditor.cs
- WebSysDisplayNameAttribute.cs
- QilReference.cs
- TextTreeNode.cs
- XmlDesignerDataSourceView.cs
- TextParagraphView.cs
- OleDbConnection.cs
- OutputCacheProfileCollection.cs
- XamlToRtfParser.cs
- DebugView.cs
- CompoundFileDeflateTransform.cs
- LabelDesigner.cs
- Columns.cs
- TypeDefinition.cs
- RadioButton.cs
- ZipIOCentralDirectoryBlock.cs
- MiniAssembly.cs
- ReflectPropertyDescriptor.cs
- SamlNameIdentifierClaimResource.cs
- DelayedRegex.cs
- BackgroundWorker.cs
- DataBinder.cs
- PenContext.cs
- PropertiesTab.cs
- Light.cs
- CalendarAutoFormat.cs
- Animatable.cs
- TreeViewCancelEvent.cs
- ContentDesigner.cs
- FlowDocumentPage.cs
- ChtmlPhoneCallAdapter.cs
- OciEnlistContext.cs
- DataServiceClientException.cs
- ServicePointManagerElement.cs
- Button.cs
- RepeaterItem.cs
- ConstraintConverter.cs
- ApplicationException.cs
- RuleConditionDialog.cs
- SchemaEntity.cs
- IPipelineRuntime.cs
- validationstate.cs
- XamlSerializer.cs