diff options
Diffstat (limited to 'src/Text/Impl/StandaloneUndo')
6 files changed, 72 insertions, 47 deletions
diff --git a/src/Text/Impl/StandaloneUndo/AutoEnclose.cs b/src/Text/Impl/StandaloneUndo/AutoEnclose.cs index 42af7d4..ad92cd3 100644 --- a/src/Text/Impl/StandaloneUndo/AutoEnclose.cs +++ b/src/Text/Impl/StandaloneUndo/AutoEnclose.cs @@ -20,7 +20,9 @@ namespace Microsoft.VisualStudio.Text.Operations.Standalone this.end = end; } +#pragma warning disable CA1063 // Implement IDisposable Correctly public void Dispose() +#pragma warning restore CA1063 // Implement IDisposable Correctly { if (end != null) end(); GC.SuppressFinalize(this); diff --git a/src/Text/Impl/StandaloneUndo/CatchOperationsFromHistoryForDelegatedPrimitive.cs b/src/Text/Impl/StandaloneUndo/CatchOperationsFromHistoryForDelegatedPrimitive.cs index b39446d..ace7773 100644 --- a/src/Text/Impl/StandaloneUndo/CatchOperationsFromHistoryForDelegatedPrimitive.cs +++ b/src/Text/Impl/StandaloneUndo/CatchOperationsFromHistoryForDelegatedPrimitive.cs @@ -28,7 +28,9 @@ namespace Microsoft.VisualStudio.Text.Operations.Standalone history.ForwardToUndoOperation(primitive); } +#pragma warning disable CA1063 // Implement IDisposable Correctly public void Dispose() +#pragma warning restore CA1063 // Implement IDisposable Correctly { history.EndForwardToUndoOperation(primitive); primitive.State = DelegatedUndoPrimitiveState.Inactive; diff --git a/src/Text/Impl/StandaloneUndo/DelegatedUndoPrimitiveImpl.cs b/src/Text/Impl/StandaloneUndo/DelegatedUndoPrimitiveImpl.cs index 87c83f9..3e678f9 100644 --- a/src/Text/Impl/StandaloneUndo/DelegatedUndoPrimitiveImpl.cs +++ b/src/Text/Impl/StandaloneUndo/DelegatedUndoPrimitiveImpl.cs @@ -110,10 +110,12 @@ namespace Microsoft.VisualStudio.Text.Operations.Standalone } } +#pragma warning disable CA1822 // Mark members as static public bool MergeWithPreviousOnly { get { return true; } } +#pragma warning restore CA1822 // Mark members as static public bool CanMerge(ITextUndoPrimitive primitive) { @@ -125,4 +127,4 @@ namespace Microsoft.VisualStudio.Text.Operations.Standalone throw new InvalidOperationException("Strings.DelegatedUndoPrimitiveCannotMerge"); } } -}
\ No newline at end of file +} diff --git a/src/Text/Impl/StandaloneUndo/UndoHistoryImpl.cs b/src/Text/Impl/StandaloneUndo/UndoHistoryImpl.cs index 9f5bac5..47fec01 100644 --- a/src/Text/Impl/StandaloneUndo/UndoHistoryImpl.cs +++ b/src/Text/Impl/StandaloneUndo/UndoHistoryImpl.cs @@ -8,13 +8,11 @@ using System; using System.Collections.Generic; using System.Globalization; -using System.Collections.ObjectModel; -using System.ComponentModel.Composition; using Microsoft.VisualStudio.Utilities; namespace Microsoft.VisualStudio.Text.Operations.Standalone { - internal class UndoHistoryImpl : ITextUndoHistory + internal class UndoHistoryImpl : ITextUndoHistory2 { public event EventHandler<TextUndoRedoEventArgs> UndoRedoHappened; public event EventHandler<TextUndoTransactionCompletedEventArgs> UndoTransactionCompleted; @@ -25,7 +23,7 @@ namespace Microsoft.VisualStudio.Text.Operations.Standalone private Stack<ITextUndoTransaction> undoStack; private Stack<ITextUndoTransaction> redoStack; private DelegatedUndoPrimitiveImpl activeUndoOperationPrimitive; - private TextUndoHistoryState state; + internal TextUndoHistoryState state; private PropertyCollection properties; #endregion @@ -188,6 +186,13 @@ namespace Microsoft.VisualStudio.Text.Operations.Standalone get { return this.state; } } + public ITextUndoTransaction CreateInvisibleTransaction(string description) + { + // Standalone undo doesn't support invisible transactions so simply return + // a normal transaction. + return this.CreateTransaction(description); + } + /// <summary> /// Creates a new transaction, nests it in the previously current transaction, and marks it current. /// If there is a redo stack, it gets cleared. @@ -198,9 +203,9 @@ namespace Microsoft.VisualStudio.Text.Operations.Standalone /// <returns></returns> public ITextUndoTransaction CreateTransaction(string description) { - if (String.IsNullOrEmpty(description)) + if (string.IsNullOrEmpty(description)) { - throw new ArgumentNullException("description", String.Format(CultureInfo.CurrentUICulture, "Strings.ArgumentCannotBeNull", "CreateTransaction", "description")); + throw new ArgumentNullException(nameof(description)); } // If there is a pending transaction that has already been completed, we should not be permitted @@ -244,12 +249,12 @@ namespace Microsoft.VisualStudio.Text.Operations.Standalone { if (count <= 0) { - throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, "Strings.RedoAndUndoAcceptOnlyPositiveCounts", "Undo", count), "count"); + throw new ArgumentOutOfRangeException(nameof(count)); } if (!IsThereEnoughVisibleTransactions(this.undoStack, count)) { - throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, "Strings.CannotUndoMoreTransactionsThanExist", "undo", count)); + throw new InvalidOperationException("Cannot undo more transactions than exist"); } TextUndoHistoryState originalState = this.state; @@ -321,12 +326,12 @@ namespace Microsoft.VisualStudio.Text.Operations.Standalone { if (count <= 0) { - throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, "Strings.RedoAndUndoAcceptOnlyPositiveCounts", "Redo", count), "count"); + throw new ArgumentOutOfRangeException(nameof(count)); } if (!IsThereEnoughVisibleTransactions(this.redoStack, count)) { - throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, "Strings.CannotUndoMoreTransactionsThanExist", "redo", count)); + throw new InvalidOperationException("Cannot redo more transactions than exist"); } TextUndoHistoryState originalState = this.state; @@ -424,15 +429,19 @@ namespace Microsoft.VisualStudio.Text.Operations.Standalone throw new InvalidOperationException("Strings.EndTransactionOutOfOrder"); } + // Note that the VS undo history actually "pops" the nested undo stack on the Complete/Cancel + // (instead of in the Dispose). This shouldn't affect anything but we should consider adapting + // this code to follow the model in VS undo. + this.currentTransaction = (UndoTransactionImpl)(transaction.Parent); + // only add completed transactions to their parents (or the stack) - if (this.currentTransaction.State == UndoTransactionState.Completed) + if (transaction.State == UndoTransactionState.Completed) { - if (this.currentTransaction.Parent == null) // stack bottomed out! + if (transaction.Parent == null) // stack bottomed out! { - MergeOrPushToUndoStack(this.currentTransaction); + MergeOrPushToUndoStack((UndoTransactionImpl)transaction); } } - this.currentTransaction = this.currentTransaction.Parent as UndoTransactionImpl; } /// <summary> @@ -471,7 +480,7 @@ namespace Microsoft.VisualStudio.Text.Operations.Standalone transactionAdded = transaction; transactionResult = TextUndoTransactionCompletionResult.TransactionAdded; } - RaiseUndoTransactionCompleted(transactionAdded, transactionResult); + RaiseUndoTransactionCompleted(transactionAdded, transactionResult); } public bool ValidTransactionForMarkers(ITextUndoTransaction transaction) diff --git a/src/Text/Impl/StandaloneUndo/UndoHistoryRegistryImpl.cs b/src/Text/Impl/StandaloneUndo/UndoHistoryRegistryImpl.cs index 2e4742d..5aef378 100644 --- a/src/Text/Impl/StandaloneUndo/UndoHistoryRegistryImpl.cs +++ b/src/Text/Impl/StandaloneUndo/UndoHistoryRegistryImpl.cs @@ -18,7 +18,7 @@ namespace Microsoft.VisualStudio.Text.Operations.Standalone internal class UndoHistoryRegistryImpl : ITextUndoHistoryRegistry { #region Private Fields - private Dictionary<ITextUndoHistory, int> histories; + internal Dictionary<ITextUndoHistory, int> histories; private Dictionary<WeakReferenceForDictionaryKey, ITextUndoHistory> weakContextMapping; private Dictionary<object, ITextUndoHistory> strongContextMapping; #endregion // Private Fields @@ -50,7 +50,7 @@ namespace Microsoft.VisualStudio.Text.Operations.Standalone { if (context == null) { - throw new ArgumentNullException("context", String.Format(CultureInfo.CurrentCulture, "Strings.ArgumentCannotBeNull", "RegisterHistory", "context")); + throw new ArgumentNullException(nameof(context)); } return RegisterHistory(context, false); @@ -66,7 +66,7 @@ namespace Microsoft.VisualStudio.Text.Operations.Standalone { if (context == null) { - throw new ArgumentNullException("context", String.Format(CultureInfo.CurrentCulture, "Strings.ArgumentCannotBeNull", "RegisterHistory", "context")); + throw new ArgumentNullException(nameof(context)); } ITextUndoHistory result; @@ -118,7 +118,7 @@ namespace Microsoft.VisualStudio.Text.Operations.Standalone { if (context == null) { - throw new ArgumentNullException("context", String.Format(CultureInfo.CurrentCulture, "Strings.ArgumentCannotBeNull", "GetHistory", "context")); + throw new ArgumentNullException(nameof(context)); } ITextUndoHistory result; @@ -149,7 +149,7 @@ namespace Microsoft.VisualStudio.Text.Operations.Standalone { if (context == null) { - throw new ArgumentNullException("context", String.Format(CultureInfo.CurrentCulture, "Strings.ArgumentCannotBeNull", "TryGetHistory", "context")); + throw new ArgumentNullException(nameof(context)); } ITextUndoHistory result = null; @@ -176,12 +176,12 @@ namespace Microsoft.VisualStudio.Text.Operations.Standalone { if (context == null) { - throw new ArgumentNullException("context", String.Format(CultureInfo.CurrentCulture, "Strings.ArgumentCannotBeNull", "AttachHistory", "context")); + throw new ArgumentNullException(nameof(context)); } if (history == null) { - throw new ArgumentNullException("context", String.Format(CultureInfo.CurrentCulture, "Strings.ArgumentCannotBeNull", "AttachHistory", "history")); + throw new ArgumentNullException(nameof(history)); } AttachHistory(context, history, false); @@ -197,12 +197,12 @@ namespace Microsoft.VisualStudio.Text.Operations.Standalone { if (context == null) { - throw new ArgumentNullException("context", String.Format(CultureInfo.CurrentCulture, "Strings.ArgumentCannotBeNull", "AttachHistory", "context")); + throw new ArgumentNullException(nameof(context)); } if (history == null) { - throw new ArgumentNullException("context", String.Format(CultureInfo.CurrentCulture, "Strings.ArgumentCannotBeNull", "AttachHistory", "history")); + throw new ArgumentNullException(nameof(history)); } if (strongContextMapping.ContainsKey(context) || weakContextMapping.ContainsKey(new WeakReferenceForDictionaryKey(context))) @@ -237,7 +237,7 @@ namespace Microsoft.VisualStudio.Text.Operations.Standalone { if (history == null) { - throw new ArgumentNullException("context", String.Format(CultureInfo.CurrentCulture, "Strings.ArgumentCannotBeNull", "RemoveHistory", "history")); + throw new ArgumentNullException(nameof(history)); } if (!histories.ContainsKey(history)) diff --git a/src/Text/Impl/StandaloneUndo/UndoTransactionImpl.cs b/src/Text/Impl/StandaloneUndo/UndoTransactionImpl.cs index aae1d06..7bc7db8 100644 --- a/src/Text/Impl/StandaloneUndo/UndoTransactionImpl.cs +++ b/src/Text/Impl/StandaloneUndo/UndoTransactionImpl.cs @@ -17,13 +17,14 @@ namespace Microsoft.VisualStudio.Text.Operations.Standalone { #region Private Fields - private readonly UndoHistoryImpl history; + private UndoHistoryImpl history; private readonly UndoTransactionImpl parent; private string description; private UndoTransactionState state; private List<ITextUndoPrimitive> primitives; private IMergeTextUndoTransactionPolicy mergePolicy; + internal bool _isDisposed = false; #endregion @@ -31,12 +32,12 @@ namespace Microsoft.VisualStudio.Text.Operations.Standalone { if (history == null) { - throw new ArgumentNullException("history", String.Format(CultureInfo.CurrentUICulture, "Strings.ArgumentCannotBeNull", "UndoTransactionImpl", "history")); + throw new ArgumentNullException(nameof(history)); } - if (String.IsNullOrEmpty(description)) + if (string.IsNullOrEmpty(description)) { - throw new ArgumentNullException("description", String.Format(CultureInfo.CurrentUICulture, "Strings.ArgumentCannotBeNull", "UndoTransactionImpl", "description")); + throw new ArgumentNullException(nameof(description)); } this.history = history as UndoHistoryImpl; @@ -363,35 +364,44 @@ namespace Microsoft.VisualStudio.Text.Operations.Standalone { if (value == null) { - throw new ArgumentNullException("value"); + throw new ArgumentNullException(nameof(value)); } this.mergePolicy = value; } } - /// <summary> - /// Closes a transaction and disposes it. - /// </summary> +#pragma warning disable CA1063 // Implement IDisposable Correctly + /// <summary> + /// Closes a transaction and disposes it. + /// </summary> public void Dispose() +#pragma warning restore CA1063 // Implement IDisposable Correctly { - GC.SuppressFinalize(this); - switch (this.State) + if (!_isDisposed) { - case UndoTransactionState.Open: - Cancel(); - break; + _isDisposed = true; - case UndoTransactionState.Canceled: - case UndoTransactionState.Completed: - break; + GC.SuppressFinalize(this); + switch (this.State) + { + case UndoTransactionState.Open: + Cancel(); + break; + + case UndoTransactionState.Canceled: + case UndoTransactionState.Completed: + break; + + case UndoTransactionState.Redoing: + case UndoTransactionState.Undoing: + case UndoTransactionState.Undone: + throw new InvalidOperationException("Strings.ClosingAnOpenTransactionThatAppearsToBeUndoneOrUndoing"); + } - case UndoTransactionState.Redoing: - case UndoTransactionState.Undoing: - case UndoTransactionState.Undone: - throw new InvalidOperationException("Strings.ClosingAnOpenTransactionThatAppearsToBeUndoneOrUndoing"); + this.history.EndTransaction(this); } - history.EndTransaction(this); } + } } |