示例#1
0
        /// <summary>
        /// This method gets called when the IBus CommitText event is raised and indicates that
        /// the composition is ending. The temporarily inserted composition string will be
        /// replaced with <paramref name="ibusText"/>.
        /// It's in the discretion of the IBus 'keyboard' to decide when it calls OnCommitText.
        /// Typically this is done when the user selects a string in the pop-up composition
        /// window, or when he types a character that isn't part of the previous composition
        /// sequence.
        /// </summary>
        public void OnCommitText(object ibusText)
        {
            if (AssociatedSimpleRootSite.InvokeRequired)
            {
                AssociatedSimpleRootSite.InvokeAsync(() => OnCommitText(ibusText));
                return;
            }

            OnCommitText(((IBusText)ibusText).Text, true);
        }
示例#2
0
        /// <summary>
        /// Called when the IBus DeleteSurroundingText is raised to delete surrounding
        /// characters.
        /// </summary>
        /// <param name="offset">The character offset from the cursor position of the text to be
        /// deleted. A negative value indicates a position before the cursor.</param>
        /// <param name="nChars">The number of characters to be deleted.</param>
        public void OnDeleteSurroundingText(int offset, int nChars)
        {
            if (AssociatedSimpleRootSite.InvokeRequired)
            {
                AssociatedSimpleRootSite.InvokeAsync(() => OnDeleteSurroundingText(offset, nChars));
                return;
            }

            var selHelper = SetupForTypingEventHandler(true, false);

            if (selHelper == null || nChars <= 0)
            {
                return;
            }

            try
            {
                var selectionStart = selHelper.GetIch(SelectionHelper.SelLimitType.Top);
                var startIndex     = selectionStart + offset;
                if (startIndex + nChars <= 0)
                {
                    return;
                }

                var selectionProps = GetSelectionProps(selHelper);

                startIndex          = Math.Max(startIndex, 0);
                selHelper.IchAnchor = startIndex;
                selHelper.IchEnd    = startIndex + nChars;
                selHelper.SetSelection(true);

                ITsString str = CreateTsStringUsingSelectionProps(string.Empty, selectionProps, true);
                selHelper.Selection.ReplaceWithTsString(str);

                if (startIndex < selectionStart)
                {
                    selectionStart = Math.Max(selectionStart - nChars, 0);
                }

                selHelper.IchAnchor = selectionStart;
                selHelper.IchEnd    = selectionStart;

                // make the selection visible
                var selection = selHelper.SetSelection(true);
                selection.SetSelectionProps(selectionProps.Length, selectionProps);
            }
            finally
            {
                if (m_ActionHandler != null)
                {
                    m_ActionHandler.EndUndoTask();
                    m_ActionHandler = null;
                }
            }
        }
示例#3
0
        /// <summary>
        /// Called when the IBus HidePreeditText event is raised to cancel/remove the composition,
        /// e.g. after the user pressed the ESC key or the application lost focus.
        /// </summary>
        public void OnHidePreeditText()
        {
            if (AssociatedSimpleRootSite.InvokeRequired)
            {
                AssociatedSimpleRootSite.InvokeAsync(OnHidePreeditText);
                return;
            }

            if (!AssociatedSimpleRootSite.Focused || AssociatedSimpleRootSite.ReadOnlyView)
            {
                return;
            }

            Reset(true);
        }
示例#4
0
        /// <summary>
        /// Called when the IBus ForwardKeyEvent is raised, i.e. when IBus wants the application
        /// to process a key event. One example is when IBus raises the ForwardKeyEvent and
        /// passes backspace to delete the character to the left of the cursor so that it can be
        /// replaced with a new modified character.
        /// </summary>
        /// <param name="keySym">Key symbol.</param>
        /// <param name="scanCode">Scan code.</param>
        /// <param name="index">Index of the KeyCode vector. This more or less tells the state of
        /// the modifier keys: 0=unshifted, 1=shifted (the other values I don't know and are irrelevant).
        /// </param>
        public void OnIbusKeyPress(int keySym, int scanCode, int index)
        {
            if (AssociatedSimpleRootSite.InvokeRequired)
            {
                AssociatedSimpleRootSite.InvokeAsync(() => OnIbusKeyPress(keySym, scanCode, index));
                return;
            }
            if (!AssociatedSimpleRootSite.Focused || AssociatedSimpleRootSite.ReadOnlyView)
            {
                return;
            }

            var inChar = (char)(0x00FF & keySym);

            OnCommitText(inChar.ToString(), true);
        }
示例#5
0
        /// <summary>
        /// Called when the IBus UpdatePreeditText event is raised to update the composition.
        /// </summary>
        /// <param name="obj">New composition string that will replace the existing
        /// composition (sub-)string.</param>
        /// <param name="cursorPos">0-based position where the cursor should be put after
        /// updating the composition (pre-edit window). This position is relative to the
        /// composition/preedit text.</param>
        public void OnUpdatePreeditText(object obj, int cursorPos)
        {
            if (AssociatedSimpleRootSite.InvokeRequired)
            {
                AssociatedSimpleRootSite.InvokeAsync(() => OnUpdatePreeditText(obj, cursorPos));
                return;
            }

            var selHelper = SetupForTypingEventHandler(true, false);

            if (selHelper == null)
            {
                return;
            }

            if (m_InitialSelection == null)
            {
                // Create a new, independent selection helper for m_InitialSelHelper - we want
                // to remember the current selection
                m_InitialSelection = new SelectionWrapper(AssociatedSimpleRootSite);
                OnPreeditOpened();
            }

            var ibusText        = obj as IBusText;
            var compositionText = ibusText.Text;

            CheckAttributesForCommittingKeyboard(ibusText);

            // Make the correct selection
            if (m_EndOfPreedit != null)
            {
                selHelper = m_EndOfPreedit;
            }

            var selectionProps = GetSelectionProps(selHelper);

            // Replace any previous pre-edit text.
            if (m_InitialSelection.SelectionHelper.Selection.EndBeforeAnchor)
            {
                // If we have a backwards selection we insert the pre-edit before the selected
                // text. selHelper points to the originally selected text (which got moved because
                // we inserted the pre-edit before it). The top of m_InitialSelection is the
                // start of the pre-edit, the top of selHelper is the position before the
                // originally selected text
                Debug.Assert(m_InitialSelection.SelectionHelper.IsRange);
                selHelper.IchEnd    = selHelper.GetIch(SelectionHelper.SelLimitType.End);
                selHelper.IchAnchor = m_InitialSelection.SelectionHelper.GetIch(SelectionHelper.SelLimitType.Top);
            }
            else
            {
                // selHelper points to the position after inserting the previous pre-edit text,
                // so it will be the end of our range selection. The bottom of m_InitialSelection
                // is the position at the end of the initial range selection, so it will be part
                // of the anchor.
                selHelper.IchEnd    = selHelper.GetIch(SelectionHelper.SelLimitType.Bottom);
                selHelper.IchAnchor = m_InitialSelection.SelectionHelper.GetIch(SelectionHelper.SelLimitType.Bottom);
            }
            selHelper.SetSelection(true);

            // Update the pre-edit text
            ITsString str = CreateTsStringUsingSelectionProps(compositionText, selectionProps, true);

            selHelper.Selection.ReplaceWithTsString(str);

            m_EndOfPreedit = new SelectionHelper(
                AssociatedSimpleRootSite.EditingHelper.CurrentSelection);

            if (m_InitialSelection.SelectionHelper.IsRange)
            {
                // keep the range selection
                if (m_InitialSelection.SelectionHelper.Selection.EndBeforeAnchor)
                {
                    // we inserted before the original selection but we want to keep the original
                    // text selected, so we have to adjust
                    selHelper            = new SelectionHelper(m_InitialSelection.SelectionHelper);
                    selHelper.IchAnchor += str.Length;
                    selHelper.IchEnd    += str.Length;
                }
                else
                {
                    selHelper = m_InitialSelection.SelectionHelper;
                }
            }
            else
            {
                // Set the IP to the position IBus told us. This is tricky because compositionText
                // might be in NFC but we have converted it to NFD, so the position needs to
                // change. To simplify this we expect for now that IBus sets the cursor always
                // either at the start or the end of the composition string.
                selHelper           = new SelectionHelper(AssociatedSimpleRootSite.EditingHelper.CurrentSelection);
                selHelper.IchAnchor = m_InitialSelection.SelectionHelper.GetIch(SelectionHelper.SelLimitType.Bottom);
                if (compositionText.Length == cursorPos)
                {
                    selHelper.IchAnchor += str.Length;
                }
                else
                {
                    Debug.Assert(cursorPos == 0,
                                 "IBus told us a cursor position that changed because of nfc->nfd normalization");
                    selHelper.IchAnchor += cursorPos;
                }
                selHelper.IchEnd = selHelper.IchAnchor;
            }

            // make the selection visible
            selHelper.SetSelection(true);
        }