Ejemplo n.º 1
0
        public override void TextAppendLine(string text, int textColumnIndex)
        {
            // Special consideration is taken if it is the first line being appended. Then it begins on index 0 (obviously).
            var newLine = new TextLine(this.TextLength > 0 ? this.TextLength + 1 : 0, text);

            this.Lines.Add(newLine);

            this.DispatchTextSegmentAlter(new AlterTextSegmentArgs(newLine, this.Lines.Count - 1, newLine.GetLength(textColumnIndex) + 1, textColumnIndex));

            foreach (var textView in this.GetTextViews())
            {
                this.TextSegmentStyledManager.SearchAndApplyTo(textView, newLine, 0, newLine.GetLength(textColumnIndex), textColumnIndex);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="textView"></param>
        /// <param name="textLine"></param>
        /// <param name="relativeIndex">Relative index is the index before the new character, so text[relativeIndex] is the <see cref="c"/>.</param>
        /// <param name="c"></param>
        /// <param name="alterTextStyleIndexes"></param>
        /// <param name="length"></param>
        /// <param name="textColumnIndex"></param>
        private void ModifyStyledTextSegments(ITextView textView, TextLine textLine, int relativeIndex, char c, bool alterTextStyleIndexes, int length, int textColumnIndex)
        {
            var isErase = c == '\0' && length <= 0;

            if (isErase)
            {
                length *= -1;
            }

            IEnumerable <ITextSegmentStyled> befores = null;
            IEnumerable <ITextSegmentStyled> afters  = null;

            var startSearch = Math.Max(0, relativeIndex - 1);

            const bool foundMatch = false;

            if (alterTextStyleIndexes)
            {
                var offsetCount = 0;
                for (var n = 0; n < textLine.StyledTextSegments.Count - offsetCount; n++)
                {
                    if (textLine.StyledTextSegments[n].Index > textLine.GetLength(textColumnIndex))
                    {
                        // The style starts after the end of the line, which is silly and should be filtered out.
                        textLine.StyledTextSegments[n].TextLine = null;
                        n--;
                    }
                    else if (isErase && textLine.StyledTextSegments[n].Style.Type == TextStyleType.Automatic && textLine.StyledTextSegments[n].Index >= relativeIndex && textLine.StyledTextSegments[n].Index + textLine.StyledTextSegments[n].GetLength(textColumnIndex) <= relativeIndex + length)
                    {
                        // The whole styled text segment was inside the removed range of text.
                        // It does not exist anymore and is automatically eligible for removing.
                        textLine.StyledTextSegments[n].TextLine = null;
                        n--;
                    }
                    else if (textLine.StyledTextSegments[n].Style.Type == TextStyleType.Automatic && textLine.StyledTextSegments[n].Contains(relativeIndex, length, isErase, true))
                    {
                        if (befores == null)
                        {
                            // This will search from the character before the change, the character before a new addition,
                            // or the character before the character that was removed.
                            befores = this.FindStyles(textView, textLine, startSearch, textColumnIndex);

                            // If a new addition, we search from the character after the change (so "pol<new space>ice" will search on "i" and not <new space>).
                            // When removing we only need to search from where the removal took place.
                            var afterSearchIdx = isErase == false?Math.Min(textLine.GetLength(textColumnIndex), startSearch + 2) : startSearch + 1;

                            afters = this.FindStyles(textView, textLine, afterSearchIdx, textColumnIndex);
                        }

                        var current = textLine.StyledTextSegments[n];

                        if (befores != null || afters != null)
                        {
                            ITextSegmentStyled before = null;
                            ITextSegmentStyled after  = null;

                            if (befores != null)
                            {
                                foreach (var b in befores)
                                {
                                    if (b.Style.NameKey == current.Style.NameKey)
                                    {
                                        before = b;
                                        break;
                                    }
                                }
                            }

                            if (afters != null)
                            {
                                foreach (var a in afters)
                                {
                                    if (a.Style.NameKey == current.Style.NameKey)
                                    {
                                        after = a;
                                        break;
                                    }
                                }
                            }

                            if (before == null)
                            {
                                if (after == null)
                                {
                                    // The styled text segment is no more since it is no longer found.
                                    current.TextLine = null;
                                    n--;
                                    continue;
                                }

                                before = after;
                                after  = null;
                            }
                            else if (after != null && before.Object != null && before.Object.Equals(after.Object))
                            {
                                after = null;
                            }

                            if (before.Index == current.Index && before.GetLength(textColumnIndex) == current.GetLength(textColumnIndex) &&
                                ((before.Object != null && before.Object.Equals(current.Object)) || before.Object == null && current.Object == null))
                            {
                                continue; // No change was done. Just don't do any changes.
                            }

                            //foundMatch = true;

                            if (before.Contains(current.Index, current.GetLength(textColumnIndex), true, true))
                            {
                                current.TextLine = null;
                                n--;
                            }

                            ((TextAnchor)before).TextLine = textLine;
                            offsetCount++;

                            if (after != null)
                            {
                                ((TextAnchor)after).TextLine = textLine;
                                offsetCount++;
                            }
                        }
                        else
                        {
                            // The styled text segment is no more since it is no longer found.
                            current.TextLine = null;
                            n--;
                        }
                    }
                    else if (textLine.StyledTextSegments[n].Index > relativeIndex)
                    {
                        if (isErase)
                        {
                            textLine.StyledTextSegments[n].Index -= length;
                        }
                        else
                        {
                            textLine.StyledTextSegments[n].Index += length;
                        }
                    }
                }
            }

            if (foundMatch == false)
            {
#if DEBUG
                var foundOne =
#endif
                this.TextSegmentStyledManager.SearchAndApplyTo(textView, textLine, startSearch, 1, CharacterIsFinalizer(c), textColumnIndex);
            }
        }