Welcome to mirror list, hosted at ThFree Co, Russian Federation.

DelegatedUndoPrimitiveImpl.cs « StandaloneUndo « Impl « Text « src - github.com/microsoft/vs-editor-api.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 3e678f94462d2bb0d0f2b4d73e649a0888f74955 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//
//  Copyright (c) Microsoft Corporation. All rights reserved.
//  Licensed under the MIT License. See License.txt in the project root for license information.
//
// This file contain implementations details that are subject to change without notice.
// Use at your own risk.
//
using System;
using System.Collections.Generic;

namespace Microsoft.VisualStudio.Text.Operations.Standalone
{
    /// <summary>
    /// This is the implementation of a primitive to support inverse operations, where the user does not supply their own
    /// primitives. Rather, the user calls "AddUndo" on the history and we build the primitive for them.
    /// </summary>
    internal class DelegatedUndoPrimitiveImpl : ITextUndoPrimitive
    {
        private Stack<UndoableOperationCurried> redoOperations;
        private Stack<UndoableOperationCurried> undoOperations;
        private UndoTransactionImpl parent;
        private readonly UndoHistoryImpl history;
        private DelegatedUndoPrimitiveState state;

        public DelegatedUndoPrimitiveState State
        {
            get { return state; }
            set { state = value; }
        }

        public DelegatedUndoPrimitiveImpl(UndoHistoryImpl history, UndoTransactionImpl parent, UndoableOperationCurried operationCurried)
        {
            redoOperations = new Stack<UndoableOperationCurried>();
            undoOperations = new Stack<UndoableOperationCurried>();

            this.parent = parent;
            this.history = history;
            this.state = DelegatedUndoPrimitiveState.Inactive;

            undoOperations.Push(operationCurried);
        }

        public bool CanRedo
        {
            get { return redoOperations.Count > 0; }
        }

        public bool CanUndo
        {
            get { return undoOperations.Count > 0; }
        }


        /// <summary>
        /// Here, we undo everything in the list of undo operations, and then clear the list. While this is happening, the
        /// History will collect new operations for the redo list and pass them on to us.
        /// </summary>
        public void Undo()
        {
            using (new CatchOperationsFromHistoryForDelegatedPrimitive(history, this, DelegatedUndoPrimitiveState.Undoing))
            {
                while (undoOperations.Count > 0)
                {
                    undoOperations.Pop()();
                }
            }
        }

        /// <summary>
        /// This is only called for "Redo," not for the original "Do." The action is to redo everything in the list of
        /// redo operations, and then clear the list. While this is happening, the History will collect new operations
        /// for the undo list and pass them on to us.
        /// </summary>
        public void Do()
        {
            using (new CatchOperationsFromHistoryForDelegatedPrimitive(history, this, DelegatedUndoPrimitiveState.Redoing))
            {
                while (redoOperations.Count > 0)
                {
                    redoOperations.Pop()();
                }
            }
        }

        public ITextUndoTransaction Parent
        {
            get { return this.parent; }
            set { this.parent = value as UndoTransactionImpl; }
        }

        /// <summary>
        /// This is called by the UndoHistory implementation when we are mid-undo/mid-redo and
        /// the history receives a new UndoableOperation. The action is then to add that operation
        /// to the inverse list.
        /// </summary>
        /// <param name="operation"></param>
        public void AddOperation(UndoableOperationCurried operation)
        {
            if (this.state == DelegatedUndoPrimitiveState.Redoing)
            {
                undoOperations.Push(operation);
            }
            else if (this.state == DelegatedUndoPrimitiveState.Undoing)
            {
                redoOperations.Push(operation);
            }
            else
            {
                throw new InvalidOperationException("Strings.DelegatedUndoPrimitiveStateDoesNotAllowAdd");
            }
        }

#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)
        {
            return false;
        }

        public ITextUndoPrimitive Merge(ITextUndoPrimitive primitive)
        {
            throw new InvalidOperationException("Strings.DelegatedUndoPrimitiveCannotMerge");
        }
    }
}