Exemplo n.º 1
0
        // See msdn's ITextStoreACP documentation for a full description.
        public void InsertTextAtSelection(UnsafeNativeMethods.InsertAtSelectionFlags flags, char[] text, int cch, out int startIndex, out int endIndex, out UnsafeNativeMethods.TS_TEXTCHANGE change)
        {
            ITextPointer startNavigator;
            ITextPointer endNavigator;
            int selectionStartIndex;
            int selectionEndIndex;

            startIndex = -1;
            endIndex = -1;

            change.start = 0;
            change.oldEnd = 0;
            change.newEnd = 0;

            if (IsReadOnly)
            {
                throw new COMException(SR.Get(SRID.TextStore_TS_E_READONLY), UnsafeNativeMethods.TS_E_READONLY);
            }

            //
            // 






            ITextRange range = new TextRange(this.TextSelection.AnchorPosition, this.TextSelection.MovingPosition);
            range.ApplyTypingHeuristics(false /* overType */);

            ITextPointer start;
            ITextPointer end;

            GetAdjustedSelection(range.Start, range.End, out start, out end);

            // Someone might change the default selection gravity, so use our
            // own TextPositions to track the insert.
            startNavigator = start.CreatePointer();
            startNavigator.SetLogicalDirection(LogicalDirection.Backward);
            endNavigator = end.CreatePointer();
            endNavigator.SetLogicalDirection(LogicalDirection.Forward);

            selectionStartIndex = startNavigator.CharOffset;
            selectionEndIndex = endNavigator.CharOffset;

            // Do the insert.
            if ((flags & UnsafeNativeMethods.InsertAtSelectionFlags.TS_IAS_QUERYONLY) == 0)
            {
                // Opene a composition undo unit for the composition undo.
                CompositionParentUndoUnit unit = OpenCompositionUndoUnit();
                UndoCloseAction undoCloseAction = UndoCloseAction.Rollback;

                try
                {
                    VerifyTextStoreConsistency();

                    change.oldEnd = selectionEndIndex;

                    string filteredText = FilterCompositionString(new string(text), range.Start.GetOffsetToPosition(range.End)); // does NOT filter MaxLength.
                    if (filteredText == null)
                    {
                        throw new COMException(SR.Get(SRID.TextStore_CompositionRejected), NativeMethods.E_FAIL);
                    }

                    // We still need to call ApplyTypingHeuristics, even though
                    // we already did the work above, because it might need
                    // to spring load formatting.
                    this.TextSelection.ApplyTypingHeuristics(false /* overType */);

                    //Invariant.Assert(this.TextSelection.Start.CompareTo(range.Start) == 0 && this.TextSelection.End.CompareTo(range.End) == 0);
                    // We cannot make this Assertion because TextRange will normalize
                    // differently around Floater/Inline edges.  This is probably
                    // not desired behavior.  To repro,
                    //
                    // <StackPanel xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
                    //  <RichTextBox FontSize="24" Height="150">
                    //      <FlowDocument>
                    //          <Paragraph>
                    //              <Run>para</Run>
                    //              <Floater HorizontalAlignment="Right" Width="100" Background="#FFFF0000">
                    //                  <Paragraph><Run>Floater</Run></Paragraph>
                    //              </Floater>
                    //              <Run> </Run>
                    //          </Paragraph>
                    //      </FlowDocument>
                    //  </RichTextBox>
                    // </StackPanel>
                    //
                    // 1. Put the caret before the Floater.
                    // 2. Shift-right to select the entire Floater.
                    // 3. Activate the chinese pinyin IME, and press 'a'.

                    // Avoid calling Select when the selection doesn't need a
                    // final reposition to preserve any spring loaded formatting
                    // from ApplyTypingHeuristics.
                    if (start.CompareTo(this.TextSelection.Start) != 0 ||
                        end.CompareTo(this.TextSelection.End) != 0)
                    {
                        this.TextSelection.Select(start, end);
                    }

                    if (!_isComposing && _previousCompositionStartOffset == -1)
                    {
                        // IMEs have the option (TF_IAS_NO_DEFAULT_COMPOSITION)
                        // of inserting text (via this method only) without first
                        // starting a composition.  If that happens, we need
                        // to remember where the composition started, from the
                        // point of view of the application listening to events
                        // we will raise in the future.
                        _previousCompositionStartOffset = this.TextSelection.Start.Offset;
                        _previousCompositionEndOffset = this.TextSelection.End.Offset;
                    }

                    this.TextEditor.SetSelectedText(filteredText, InputLanguageManager.Current.CurrentInputLanguage);

                    change.start = startNavigator.CharOffset;
                    change.newEnd = endNavigator.CharOffset;

                    ValidateChange(change);
                    VerifyTextStoreConsistency();

                    undoCloseAction = UndoCloseAction.Commit;
                }
                finally
                {
                    // Close a composition undo unit with commit to add the composition undo unit into the undo stack.
                    CloseTextParentUndoUnit(unit, undoCloseAction);
                }
            }

            // Report the location of the new text.
            if ((flags & UnsafeNativeMethods.InsertAtSelectionFlags.TS_IAS_NOQUERY) == 0)
            {
                startIndex = selectionStartIndex;
                endIndex = endNavigator.CharOffset;
            }
        }