internal static UnsafeNativeMethods.ITfCompositionView GetCurrentCompositionView(UnsafeNativeMethods.ITfDocumentMgr documentMgr) { UnsafeNativeMethods.ITfContext tfContext; documentMgr.GetBase(out tfContext); UnsafeNativeMethods.ITfCompositionView composition = FrameworkTextComposition.GetComposition(tfContext); Marshal.ReleaseComObject(tfContext); return(composition); }
internal static void CompleteCurrentComposition(UnsafeNativeMethods.ITfDocumentMgr documentMgr) { UnsafeNativeMethods.ITfContext tfContext; documentMgr.GetBase(out tfContext); UnsafeNativeMethods.ITfCompositionView composition = FrameworkTextComposition.GetComposition(tfContext); if (composition != null) { UnsafeNativeMethods.ITfContextOwnerCompositionServices tfContextOwnerCompositionServices = tfContext as UnsafeNativeMethods.ITfContextOwnerCompositionServices; tfContextOwnerCompositionServices.TerminateComposition(composition); Marshal.ReleaseComObject(composition); } Marshal.ReleaseComObject(tfContext); }
internal static FrameworkTextComposition CreateComposition(TextEditor editor, object owner) { FrameworkTextComposition composition; // FrameworkRichTextComposition should be used for RichContent so TextRange is exposed for the application // to track the composition range. // FrameworkTextComposition should be used for non-RichContent and TextRange is not exposed. if (editor.AcceptsRichContent) { composition = new FrameworkRichTextComposition(InputManager.UnsecureCurrent, editor.UiScope, owner); } else { composition = new FrameworkTextComposition(InputManager.Current, editor.UiScope, owner); } return composition; }
/// <summary> /// Inserts composition text into the document. /// Raises public text, selection changed events. /// Called by default editor TextInputEvent handler. /// </summary> /// <param name="composition"></param> internal void UpdateCompositionText(FrameworkTextComposition composition) { if (_compositionModifiedByEventListener) { // If the app has modified the document since this event was raised // (by hooking a TextInput event), then we don't know what to do, // so do nothing. return; } _handledByTextStoreListener = true; bool isMaxLengthExceeded = false; string text; ITextRange range; if (composition._ResultStart != null) { // // If we're here it means composition is being finalized // range = new TextRange(composition._ResultStart, composition._ResultEnd, true /* ignoreTextUnitBoundaries */); text = this.TextEditor._FilterText(composition.Text, range); if (text.Length != composition.Text.Length) { isMaxLengthExceeded = true; } } else { range = new TextRange(composition._CompositionStart, composition._CompositionEnd, true /* ignoreTextUnitBoundaries */); text = this.TextEditor._FilterText(composition.CompositionText, range, /*filterMaxLength:*/false); // A change in length should not happen other than for MaxLength filtering during finalization since we cover those // cases and reject input if necessary when the IME edits the document in the first place. Invariant.Assert(text.Length == composition.CompositionText.Length); } // // Preparing to create new Composition undo unit and // set it as the last composition unit. // this is important for further call to MergeCompositionUndoUnits. // _nextUndoUnitIsFirstCompositionUnit = false; CompositionParentUndoUnit topUndoUnit = PeekCompositionParentUndoUnit(); if (null != topUndoUnit) { topUndoUnit.IsLastCompositionUnit = false; } CompositionParentUndoUnit compositionUndoUnit = OpenCompositionUndoUnit(range.Start, range.End); UndoCloseAction undoCloseAction = UndoCloseAction.Rollback; if (composition._ResultStart != null) { // If the composition is being finalized, this will be the last undo unit in this group. _nextUndoUnitIsFirstCompositionUnit = true; compositionUndoUnit.IsLastCompositionUnit = true; } this.TextSelection.BeginChange(); try { this.TextEditor.SetText(range, text, InputLanguageManager.Current.CurrentInputLanguage); // if (_interimSelection) { this.TextSelection.Select(range.Start, range.End); } else { this.TextSelection.SetCaretToPosition(range.End, LogicalDirection.Backward, /*allowStopAtLineEnd:*/true, /*allowStopNearSpace:*/true); } compositionUndoUnit.RecordRedoSelectionState(range.End, range.End); undoCloseAction = UndoCloseAction.Commit; } finally { // We're about to raise the public event. // Set a flag so we can detect app changes. _compositionModifiedByEventListener = isMaxLengthExceeded; // PUBLIC EVENT: this.TextSelection.EndChange(); CloseTextParentUndoUnit(compositionUndoUnit, undoCloseAction); } }
// Inserts composition text into the document. // Raises public text, selection changed events. // Returns the position of the inserted text. If includeResultText is // true, start/end will cover all the inserted text. Otherwise, text // from offset 0 to resultLength is omitted from start/end. internal void UpdateCompositionText(FrameworkTextComposition composition, int resultLength, bool includeResultText, out ITextPointer start, out ITextPointer end) { start = null; end = null; if (_compositionModifiedByEventListener) { // If the app has modified the document since this event was raised // (by hooking a TextInput event), then we don't know what to do, // so do nothing. return; } _handledByEditorListener = true; bool isTextFiltered = false; UndoCloseAction undoCloseAction = UndoCloseAction.Rollback; OpenCompositionUndoUnit(); try { _editor.Selection.BeginChange(); try { // ITextRange range; string text; if (composition._ResultStart != null) { // // If we're here it means composition is being finalized // range = new TextRange(composition._ResultStart, composition._ResultEnd); text = this._editor._FilterText(composition.Text, range); isTextFiltered = (text != composition.Text); if (isTextFiltered) { // If text was filtered we need to update the caret to point // past the updated text (_caretOffset == text.Length), but we should // also keep in mind that IMM's are free to have put caret in // any position so we're chosing minimum of both. _caretOffset = Math.Min(_caretOffset, text.Length); } } else { range = new TextRange(composition._CompositionStart, composition._CompositionEnd); text = composition.CompositionText; } _editor.SetText(range, text, InputLanguageManager.Current.CurrentInputLanguage); if (includeResultText) { start = range.Start; } else { start = range.Start.CreatePointer(resultLength, LogicalDirection.Forward); } end = range.End; ITextPointer caretPosition = _caretOffset >= 0 ? start.CreatePointer(_caretOffset, LogicalDirection.Forward) : end; _editor.Selection.Select(caretPosition, caretPosition); } finally { // We're about to raise the public event. // Set a flag so we can detect app changes. _compositionModifiedByEventListener = false; _editor.Selection.EndChange(); if (isTextFiltered) { _compositionModifiedByEventListener = true; } } undoCloseAction = UndoCloseAction.Commit; } finally { CloseCompositionUndoUnit(undoCloseAction, end); } }
// Inserts composition text into the document. // Raises public text, selection changed events. // Called by default editor TextInputEvent handler. internal void UpdateCompositionText(FrameworkTextComposition composition) { ITextPointer start; ITextPointer end; UpdateCompositionText(composition, 0, true /* includeResultText */ , out start, out end); }
private bool RaiseTextInputEvent(FrameworkTextComposition composition, string compositionString) { composition.Stage = TextCompositionStage.Started; composition.SetResultPositions(_startComposition, _endComposition, compositionString); _startComposition = null; _endComposition = null; UnregisterMouseListeners(); _handledByEditorListener = false; // PUBLIC event: TextCompositionManager.CompleteComposition(composition); _compositionUndoUnit = null; return (!_handledByEditorListener || composition.PendingComplete || _compositionModifiedByEventListener); }
private bool RaiseTextInputUpdateEvent(FrameworkTextComposition composition, int resultLength, string compositionString) { composition.Stage = TextCompositionStage.Started; composition.SetCompositionPositions(_startComposition, _endComposition, compositionString); // PUBLIC event: bool handled = TextCompositionManager.UpdateComposition(composition); if (handled || composition.PendingComplete || _compositionModifiedByEventListener) { return true; } // UpdateCompositionText raises a PUBLIC EVENT.... UpdateCompositionText(composition, resultLength, false /* includeResultText */, out _startComposition, out _endComposition); if (_compositionModifiedByEventListener) { return true; } return false; }
private bool RaiseTextInputStartEvent(FrameworkTextComposition composition, int resultLength, string compositionString) { composition.Stage = TextCompositionStage.None; composition.SetCompositionPositions(_editor.Selection.Start, _editor.Selection.End, compositionString); // PUBLIC event: bool handled = TextCompositionManager.StartComposition(composition); if (handled || composition.PendingComplete || _compositionModifiedByEventListener) { return true; } // UpdateCompositionText raises a PUBLIC EVENT.... UpdateCompositionText(composition, resultLength, true /* includeResultText */, out _startComposition, out _endComposition); if (_compositionModifiedByEventListener) { return true; } RegisterMouseListeners(); return false; }