Ejemplo n.º 1
0
 private static void Trace(ISubordinateTextEdit subedit, string operation)
 {
     if (BufferGroup.tracing)
     {
         Trace(subedit.TextBuffer, operation);
         Debug.WriteLine(subedit.ToString());
     }
 }
Ejemplo n.º 2
0
        public void PerformMasterEdit(ITextBuffer buffer, ISubordinateTextEdit xedit, EditOptions options, object editTag)
        {
            Debug.Assert(this.MembersContains(buffer));
            if (this.masterBuffer != null)
            {
                // internal error
                throw new InvalidOperationException("Master edit already in progress");
            }

            try
            {
                this.masterBuffer  = (BaseBuffer)buffer;
                this.masterOptions = options;
                this.masterEditTag = editTag;

                this.buffer2EditMap = new Dictionary <ITextBuffer, ISubordinateTextEdit>();
                this.buffer2EditMap.Add(buffer, xedit);

                this.pendingIndependentBuffers = new HashSet <BaseProjectionBuffer>();

                BuildGraph();

                Trace(buffer, "Master");

                Stack <ISubordinateTextEdit> appliedSubordinateEdits = new Stack <ISubordinateTextEdit>();
                while (this.buffer2EditMap.Count > 0)
                {
                    // Pick an edit that has no possibility of further impact from target projection buffers.
                    ISubordinateTextEdit subedit = PickEdit();
                    Trace(subedit, "Pre Apply");
                    PopulateSourceEdits(subedit.TextBuffer);
                    subedit.PreApply();                           // this may add more edits to buffer2EditMap
                    appliedSubordinateEdits.Push(subedit);
                }

                Action cancelAction = () =>
                {
                    foreach (var edit in appliedSubordinateEdits)
                    {
                        edit.CancelApplication();
                    }

                    Debug.Assert(this.pendingIndependentBuffers.Count == 0);
                    Debug.Assert(this.depth == 0);

                    this.graph                     = null;
                    this.buffer2EditMap            = null;
                    this.masterBuffer              = null;
                    this.pendingIndependentBuffers = null;
                };

                foreach (var edit in appliedSubordinateEdits)
                {
                    if (!edit.CheckForCancellation(cancelAction))
                    {
                        Debug.Assert(this.graph == null);
                        Debug.Assert(this.buffer2EditMap == null);
                        Debug.Assert(this.masterBuffer == null);
                        Debug.Assert(this.pendingIndependentBuffers == null);
                        Debug.Assert(this.eventQueue.Count == 0);
                        Debug.Assert(this.depth == 0);
                        Debug.Assert(!this.eventingInProgress);
                        return;
                    }
                }

                // pendingIndependentBuffers currently do not get a voice in cancelation.

                // now interpret events in the reverse order
                while (appliedSubordinateEdits.Count > 0)
                {
                    ISubordinateTextEdit subedit = appliedSubordinateEdits.Pop();
                    Trace(subedit.TextBuffer, "Final Apply");
                    subedit.FinalApply(); // this creates the snapshot and queues/raises events...TODO: make it return raisers
                }

                // move on to independent edits
                while (this.pendingIndependentBuffers.Count > 0)
                {
                    BaseProjectionBuffer projectionBuffer = PickIndependentBuffer();
                    Trace(projectionBuffer, "Propagate");
                    BaseBuffer.ITextEventRaiser raiser = projectionBuffer.PropagateSourceChanges(options, editTag);
                    this.eventQueue.Enqueue(new Tuple <BaseBuffer.ITextEventRaiser, BaseBuffer>(raiser, projectionBuffer));
                }

                this.graph                     = null;
                this.buffer2EditMap            = null;
                this.masterBuffer              = null;
                this.pendingIndependentBuffers = null;
            }
            catch (Exception e)
            {
                BufferGroup.LastMasterEditException           = e;
                BufferGroup.LastMasterEditExceptionStackTrace = e.StackTrace;
                throw;
            }
        }