Beispiel #1
0
        /// <summary> Inserts the given content into this instance. </summary>
        /// <param name="caret"> The caret which represents the point at which the content should be
        ///  inserted. </param>
        /// <param name="text"> The text that should be inserted into the text fragment </param>
        public TextCaret Insert(TextCaret caret, string text)
        {
            if (caret.Content != this)
            {
                throw new ArgumentException("Caret does not refer to this Content instance", nameof(caret));
            }
            if (text == null)
            {
                throw new ArgumentNullException(nameof(text));
            }

            // easy, it's empty
            if (text == "")
            {
                return(caret);
            }

            var originalNumGraphemes = _buffer.GraphemeLength;

            _buffer.InsertText(caret.Offset.CharOffset, text);
            var nowNumGraphemes = _buffer.GraphemeLength;

            NotifyChanged();

            return(TextCaret.FromOffset(this, caret.Offset.GraphemeOffset + nowNumGraphemes - originalNumGraphemes));
        }
Beispiel #2
0
        /// <summary> Retrieves a cursor that points at the given character. </summary>
        /// <exception cref="Exception"> Thrown when an exception error condition occurs. </exception>
        /// <param name="graphemeIndex"> The index of the grapheme to point at. </param>
        /// <returns> A TextBlockValueCursor that is pointing at the given grapheme. </returns>
        public TextCaret CursorFromGraphemeIndex(int graphemeIndex)
        {
            if (graphemeIndex < 0 || graphemeIndex > _buffer.GraphemeLength)
            {
                throw new ArgumentException($"Invalid index for cursor; index={graphemeIndex}; maximum={_buffer.GraphemeLength}", nameof(graphemeIndex));
            }

            return(TextCaret.FromOffset(this, graphemeIndex));
        }
Beispiel #3
0
        /// <summary> Inserts the given content into this instance. </summary>
        /// <param name="caret"> The caret which represents the point at which the content should be
        ///  inserted. </param>
        /// <param name="newContent"> The content to insert. </param>
        /// <param name="autoMerge"> (Optional) True to automatically merge similar fragments together. </param>
        public TextCaret Insert(TextCaret caret, TextBlockContent newContent, bool autoMerge = true)
        {
            if (newContent == this)
            {
                throw new ArgumentException("Content cannot be inserted into itself", nameof(newContent));
            }

            return(Insert(caret, newContent.GetText()));
        }
Beispiel #4
0
 /// <summary> Makes sure that <paramref name="caretStart"/> comes before <paramref name="caretEnd"/>. </summary>
 private void NormalizePositioning(ref TextCaret caretStart, ref TextCaret caretEnd)
 {
     if (caretStart.Offset.GraphemeOffset > caretEnd.Offset.GraphemeOffset)
     {
         var temp = caretStart;
         caretStart = caretEnd;
         caretEnd   = temp;
     }
 }
Beispiel #5
0
 private void VerifyExtractParameters(TextCaret caretStart,
                                      TextCaret caretEnd)
 {
     if (!caretStart.IsValid || caretStart.Content != this)
     {
         throw new ArgumentException("Start cursor is not pointing at this content", nameof(caretStart));
     }
     if (!caretEnd.IsValid || caretStart.Content != this)
     {
         throw new ArgumentException("End cursor is not pointing at this content", nameof(caretEnd));
     }
 }
Beispiel #6
0
        public TextBlockContent ExtractOrCloneContent(TextCaret caretStart, TextCaret caretEnd, bool shouldRemoveContent)
        {
            VerifyExtractParameters(caretStart, caretEnd);

            NormalizePositioning(ref caretStart, ref caretEnd);

            // zero-width; this check is needed, as the normalization process might shift the end to be
            // before the start when both are pointing at the end of a fragment (the start is normalized to
            // point at the beginning of the next fragment instead).
            if (caretStart == caretEnd)
            {
                return(new TextBlockContent());
            }

            var start = caretStart.Offset;
            var end   = caretEnd.Offset;

            if (start == end)
            {
                return(new TextBlockContent());
            }
            else if (caretStart.IsAtBlockStart && caretEnd.IsAtBlockEnd)
            {
                var newContent = new TextBlockContent(this);

                if (shouldRemoveContent)
                {
                    RemoveAll();
                }

                return(newContent);
            }
            else
            {
                var clone = new TextBlockContent(_buffer.GetText(start, end));

                if (shouldRemoveContent)
                {
                    _buffer.DeleteText(start, end);
                    NotifyChanged();
                }

                return(clone);
            }
        }
Beispiel #7
0
        /// <summary> Deletes text at the given position. </summary>
        public static TextCaret DeleteText(this TextCaret caret, int numberOfGraphemes)
        {
            var endCaret = caret;

            while (numberOfGraphemes > 0)
            {
                var next = endCaret.GetNextPosition();
                if (!next.IsValid)
                {
                    break;
                }

                endCaret = next;
                numberOfGraphemes--;
            }

            // TODO special case when we're deleting the entire fragment
            caret.Content.DeleteText(caret.Offset, endCaret.Offset);

            return(TextCaret.FromOffset(caret.Content, caret.Offset.GraphemeOffset));
        }
 public SerializedData(TextCaret caret)
 {
     _graphemeOffset = caret.Offset.GraphemeOffset;
     _pathToBlock    = caret.Block.GetBlockPath();
 }
Beispiel #9
0
 /// <summary> Gets a cursor that is looking at the end of this content. </summary>
 public TextCaret GetCaretAtEnd()
 => TextCaret.FromEnd(this);
Beispiel #10
0
 /// <summary> Gets a cursor that is looking at the beginning of this content. </summary>
 public TextCaret GetCaretAtStart()
 => TextCaret.FromBeginning(this);
Beispiel #11
0
 public TextBlockContent Clone()
 => CloneContent(TextCaret.FromBeginning(this), TextCaret.FromEnd(this));
Beispiel #12
0
 public TextBlockContent CloneContent(TextCaret start, TextCaret end)
 => ExtractOrCloneContent(start, end, shouldRemoveContent: false);
Beispiel #13
0
 /// <summary> Inserts text at the given location. </summary>
 public static TextCaret InsertText(this TextCaret original, string text)
 {
     return(original.Content.Insert(original, text));
 }