// Helper for PasteTextFragment
        private static void PasteMergeableTextFragment(TextElement fragment, TextRange range, TextPointer insertionPosition)
        {
            TextPointer fragmentStart;
            TextPointer fragmentEnd;

            if (fragment is Span)
            {
                // Split structure at insertion point in target
                insertionPosition = TextRangeEdit.SplitFormattingElements(insertionPosition, /*keepEmptyFormatting:*/false);
                Invariant.Assert(insertionPosition.Parent is Paragraph, "insertionPosition must be in a scope of a Paragraph after splitting formatting elements");

                // Move the whole Span into the insertion point
                fragment.RepositionWithContent(insertionPosition);

                // Store edge positions of inserted content
                fragmentStart = fragment.ElementStart;
                fragmentEnd = fragment.ElementEnd;

                // Remove wrapper from a tree
                fragment.Reposition(null, null);
                ValidateMergingPositions(typeof(Inline), fragmentStart, fragmentEnd);

                // Transfer inheritable contextual properties
                ApplyContextualProperties(fragmentStart, fragmentEnd, fragment);
            }
            else
            {
                // Correct leading nested List elements in the fragment
                CorrectLeadingNestedLists((Section)fragment);

                // Split a paragraph at insertion position
                bool needFirstParagraphMerging = SplitParagraphForPasting(ref insertionPosition);

                // Move the whole Section into the insertion point
                fragment.RepositionWithContent(insertionPosition);

                // Store edge positions of inserted content
                fragmentStart = fragment.ElementStart;
                fragmentEnd = fragment.ElementEnd.GetPositionAtOffset(0, LogicalDirection.Forward); // need forward orientation to stick with the following content during merge at fragmentStart position

                // And unwrap the root Section
                fragment.Reposition(null, null);
                ValidateMergingPositions(typeof(Block), fragmentStart, fragmentEnd);

                // Transfer inheritable contextual properties
                ApplyContextualProperties(fragmentStart, fragmentEnd, fragment);

                // Merge paragraphs on fragment boundaries
                if (needFirstParagraphMerging)
                {
                    MergeParagraphsAtPosition(fragmentStart, /*mergingOnFragmentStart:*/true);
                }

                // Get an indication that we need to merge last paragraph
                if (!((Section)fragment).HasTrailingParagraphBreakOnPaste)
                {
                    MergeParagraphsAtPosition(fragmentEnd, /*mergingOnFragmentStart:*/false);
                }
            }

            // 

            // For paragraph pasting move range end to the following paragraph, because
            // it must include an ending paragraph break (in case of no-merging)
            if (fragment is Section && ((Section)fragment).HasTrailingParagraphBreakOnPaste)
            {
                fragmentEnd = fragmentEnd.GetInsertionPosition(LogicalDirection.Forward);
            }

            // Select pasted content
            range.Select(fragmentStart, fragmentEnd);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Inserts a TextElement at this TextPointer's position.
        /// </summary>
        /// <param name="textElement">
        /// ContentElement to insert.
        /// </param>
        /// <remarks>
        /// The LogicalDirection property specifies whether this TextPointer
        /// will be positioned before or after the TextElement.
        /// </remarks>
        /// <exception cref="ArgumentException">
        /// Throws ArgumentException is textElement is not valid
        /// according to flow schema.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// Throws InvalidOperationException if textElement cannot be inserted
        /// at this position because it belongs to another tree.
        /// </exception>
        internal void InsertTextElement(TextElement textElement)
        {
            Invariant.Assert(textElement != null);

            _tree.EmptyDeadPositionList();
            SyncToTreeGeneration();

            ValidationHelper.ValidateChild(this, textElement, "textElement");

            if (textElement.Parent != null)
            {
                throw new InvalidOperationException(SR.Get(SRID.TextPointer_CannotInsertTextElementBecauseItBelongsToAnotherTree));
            }
            textElement.RepositionWithContent(this);
        }