/// <summary>
 /// Clear all the input state (autotext, autocap, multitap, undo)
 /// from the specified Editable, going beyond Editable.clear(), which
 /// just clears the text but not the input state.
 /// </summary>
 /// <remarks>
 /// Clear all the input state (autotext, autocap, multitap, undo)
 /// from the specified Editable, going beyond Editable.clear(), which
 /// just clears the text but not the input state.
 /// </remarks>
 /// <param name="e">the buffer whose text and state are to be cleared.</param>
 public static void clear(android.text.Editable e)
 {
     e.clear();
     e.removeSpan(ACTIVE);
     e.removeSpan(CAPPED);
     e.removeSpan(INHIBIT_REPLACEMENT);
     e.removeSpan(LAST_TYPED);
     android.text.method.QwertyKeyListener.Replaced[] repl = e.getSpans <android.text.method.QwertyKeyListener
                                                                         .Replaced>(0, e.Length);
     int count = repl.Length;
     {
         for (int i = 0; i < count; i++)
         {
             e.removeSpan(repl[i]);
         }
     }
 }
Exemple #2
0
        private void createMisspelledSuggestionSpan(android.text.Editable editable, android.view.textservice.SuggestionsInfo
                                                    suggestionsInfo, android.text.style.SpellCheckSpan spellCheckSpan)
        {
            int start = editable.getSpanStart(spellCheckSpan);
            int end   = editable.getSpanEnd(spellCheckSpan);

            // Other suggestion spans may exist on that region, with identical suggestions, filter
            // them out to avoid duplicates. First, filter suggestion spans on that exact region.
            android.text.style.SuggestionSpan[] suggestionSpans = editable.getSpans <android.text.style.SuggestionSpan
                                                                                     >(start, end);
            int length = suggestionSpans.Length;
            {
                for (int i = 0; i < length; i++)
                {
                    int spanStart = editable.getSpanStart(suggestionSpans[i]);
                    int spanEnd   = editable.getSpanEnd(suggestionSpans[i]);
                    if (spanStart != start || spanEnd != end)
                    {
                        suggestionSpans[i] = null;
                        break;
                    }
                }
            }
            int suggestionsCount = suggestionsInfo.getSuggestionsCount();

            string[] suggestions;
            if (suggestionsCount <= 0)
            {
                // A negative suggestion count is possible
                suggestions = new string[0];
            }
            else
            {
                int numberOfSuggestions = 0;
                suggestions = new string[suggestionsCount];
                {
                    for (int i_1 = 0; i_1 < suggestionsCount; i_1++)
                    {
                        string spellSuggestion = suggestionsInfo.getSuggestionAt(i_1);
                        if (spellSuggestion == null)
                        {
                            break;
                        }
                        bool suggestionFound = false;
                        {
                            for (int j = 0; j < length && !suggestionFound; j++)
                            {
                                if (suggestionSpans[j] == null)
                                {
                                    break;
                                }
                                string[] suggests = suggestionSpans[j].getSuggestions();
                                {
                                    for (int k = 0; k < suggests.Length; k++)
                                    {
                                        if (spellSuggestion.Equals(suggests[k]))
                                        {
                                            // The suggestion is already provided by an other SuggestionSpan
                                            suggestionFound = true;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                        if (!suggestionFound)
                        {
                            suggestions[numberOfSuggestions++] = spellSuggestion;
                        }
                    }
                }
                if (numberOfSuggestions != suggestionsCount)
                {
                    string[] newSuggestions = new string[numberOfSuggestions];
                    System.Array.Copy(suggestions, 0, newSuggestions, 0, numberOfSuggestions);
                    suggestions = newSuggestions;
                }
            }
            android.text.style.SuggestionSpan suggestionSpan = new android.text.style.SuggestionSpan
                                                                   (mTextView.getContext(), suggestions, android.text.style.SuggestionSpan.FLAG_EASY_CORRECT
                                                                   | android.text.style.SuggestionSpan.FLAG_MISSPELLED);
            editable.setSpan(suggestionSpan, start, end, android.text.SpannedClass.SPAN_EXCLUSIVE_EXCLUSIVE
                             );
            // TODO limit to the word rectangle region
            mTextView.invalidate();
        }
Exemple #3
0
            public virtual void parse()
            {
                android.text.Editable editable = (android.text.Editable) this._enclosing.mTextView
                                                 .getText();
                // Iterate over the newly added text and schedule new SpellCheckSpans
                int start = editable.getSpanStart(this.mRange);
                int end   = editable.getSpanEnd(this.mRange);

                this.mWordIterator.setCharSequence(editable, start, end);
                // Move back to the beginning of the current word, if any
                int wordStart = this.mWordIterator.preceding(start);
                int wordEnd;

                if (wordStart == java.text.BreakIterator.DONE)
                {
                    wordEnd = this.mWordIterator.following(start);
                    if (wordEnd != java.text.BreakIterator.DONE)
                    {
                        wordStart = this.mWordIterator.getBeginning(wordEnd);
                    }
                }
                else
                {
                    wordEnd = this.mWordIterator.getEnd(wordStart);
                }
                if (wordEnd == java.text.BreakIterator.DONE)
                {
                    editable.removeSpan(this.mRange);
                    return;
                }
                // We need to expand by one character because we want to include the spans that
                // end/start at position start/end respectively.
                android.text.style.SpellCheckSpan[] spellCheckSpans = editable.getSpans <android.text.style.SpellCheckSpan
                                                                                         >(start - 1, end + 1);
                android.text.style.SuggestionSpan[] suggestionSpans = editable.getSpans <android.text.style.SuggestionSpan
                                                                                         >(start - 1, end + 1);
                int  nbWordsChecked          = 0;
                bool scheduleOtherSpellCheck = false;

                while (wordStart <= end)
                {
                    if (wordEnd >= start && wordEnd > wordStart)
                    {
                        // A new word has been created across the interval boundaries with this edit.
                        // Previous spans (ended on start / started on end) removed, not valid anymore
                        if (wordStart < start && wordEnd > start)
                        {
                            this.removeSpansAt(editable, start, spellCheckSpans);
                            this.removeSpansAt(editable, start, suggestionSpans);
                        }
                        if (wordStart < end && wordEnd > end)
                        {
                            this.removeSpansAt(editable, end, spellCheckSpans);
                            this.removeSpansAt(editable, end, suggestionSpans);
                        }
                        // Do not create new boundary spans if they already exist
                        bool createSpellCheckSpan = true;
                        if (wordEnd == start)
                        {
                            {
                                for (int i = 0; i < spellCheckSpans.Length; i++)
                                {
                                    int spanEnd = editable.getSpanEnd(spellCheckSpans[i]);
                                    if (spanEnd == start)
                                    {
                                        createSpellCheckSpan = false;
                                        break;
                                    }
                                }
                            }
                        }
                        if (wordStart == end)
                        {
                            {
                                for (int i = 0; i < spellCheckSpans.Length; i++)
                                {
                                    int spanStart = editable.getSpanStart(spellCheckSpans[i]);
                                    if (spanStart == end)
                                    {
                                        createSpellCheckSpan = false;
                                        break;
                                    }
                                }
                            }
                        }
                        if (createSpellCheckSpan)
                        {
                            if (nbWordsChecked == android.widget.SpellChecker.MAX_SPELL_BATCH_SIZE)
                            {
                                scheduleOtherSpellCheck = true;
                                break;
                            }
                            this._enclosing.addSpellCheckSpan(editable, wordStart, wordEnd);
                            nbWordsChecked++;
                        }
                    }
                    // iterate word by word
                    wordEnd = this.mWordIterator.following(wordEnd);
                    if (wordEnd == java.text.BreakIterator.DONE)
                    {
                        break;
                    }
                    wordStart = this.mWordIterator.getBeginning(wordEnd);
                    if (wordStart == java.text.BreakIterator.DONE)
                    {
                        break;
                    }
                }
                if (scheduleOtherSpellCheck)
                {
                    editable.setSpan(this.mRange, wordStart, end, android.text.SpannedClass.SPAN_EXCLUSIVE_EXCLUSIVE
                                     );
                }
                else
                {
                    editable.removeSpan(this.mRange);
                }
                this._enclosing.spellCheck();
            }
Exemple #4
0
        public override bool onKeyDown(android.view.View view, android.text.Editable content
                                       , int keyCode, android.view.KeyEvent @event)
        {
            int selStart;
            int selEnd;
            int pref = 0;

            if (view != null)
            {
                pref = android.text.method.TextKeyListener.getInstance().getPrefs(view.getContext
                                                                                      ());
            }
            {
                int a = android.text.Selection.getSelectionStart(content);
                int b = android.text.Selection.getSelectionEnd(content);
                selStart = System.Math.Min(a, b);
                selEnd   = System.Math.Max(a, b);
                if (selStart < 0 || selEnd < 0)
                {
                    selStart = selEnd = 0;
                    android.text.Selection.setSelection(content, 0, 0);
                }
            }
            int activeStart = content.getSpanStart(android.text.method.TextKeyListener.ACTIVE
                                                   );
            int activeEnd = content.getSpanEnd(android.text.method.TextKeyListener.ACTIVE);
            // QWERTY keyboard normal case
            int i = @event.getUnicodeChar(@event.getMetaState() | getMetaState(content));

            if (!mFullKeyboard)
            {
                int count = @event.getRepeatCount();
                if (count > 0 && selStart == selEnd && selStart > 0)
                {
                    char c = content[selStart - 1];
                    if (c == i || c == Sharpen.CharHelper.ToUpper(i) && view != null)
                    {
                        if (showCharacterPicker(view, content, c, false, count))
                        {
                            resetMetaState(content);
                            return(true);
                        }
                    }
                }
            }
            if (i == android.view.KeyCharacterMap.PICKER_DIALOG_INPUT)
            {
                if (view != null)
                {
                    showCharacterPicker(view, content, android.view.KeyCharacterMap.PICKER_DIALOG_INPUT
                                        , true, 1);
                }
                resetMetaState(content);
                return(true);
            }
            if (i == android.view.KeyCharacterMap.HEX_INPUT)
            {
                int start;
                if (selStart == selEnd)
                {
                    start = selEnd;
                    while (start > 0 && selEnd - start < 4 && Sharpen.CharHelper.Digit(content[start
                                                                                               - 1], 16) >= 0)
                    {
                        start--;
                    }
                }
                else
                {
                    start = selStart;
                }
                int ch = -1;
                try
                {
                    string hex = android.text.TextUtils.substring(content, start, selEnd);
                    ch = System.Convert.ToInt32(hex, 16);
                }
                catch (System.ArgumentException)
                {
                }
                if (ch >= 0)
                {
                    selStart = start;
                    android.text.Selection.setSelection(content, selStart, selEnd);
                    i = ch;
                }
                else
                {
                    i = 0;
                }
            }
            if (i != 0)
            {
                bool dead = false;
                if ((i & android.view.KeyCharacterMap.COMBINING_ACCENT) != 0)
                {
                    dead = true;
                    i    = i & android.view.KeyCharacterMap.COMBINING_ACCENT_MASK;
                }
                if (activeStart == selStart && activeEnd == selEnd)
                {
                    bool replace = false;
                    if (selEnd - selStart - 1 == 0)
                    {
                        char accent   = content[selStart];
                        int  composed = android.view.KeyEvent.getDeadChar(accent, i);
                        if (composed != 0)
                        {
                            i       = composed;
                            replace = true;
                        }
                    }
                    if (!replace)
                    {
                        android.text.Selection.setSelection(content, selEnd);
                        content.removeSpan(android.text.method.TextKeyListener.ACTIVE);
                        selStart = selEnd;
                    }
                }
                if ((pref & android.text.method.TextKeyListener.AUTO_CAP) != 0 && Sharpen.CharHelper.IsLower
                        (i) && android.text.method.TextKeyListener.shouldCap(mAutoCap, content, selStart
                                                                             ))
                {
                    int where = content.getSpanEnd(android.text.method.TextKeyListener.CAPPED);
                    int flags = content.getSpanFlags(android.text.method.TextKeyListener.CAPPED);
                    if (where == selStart && (((flags >> 16) & unchecked ((int)(0xFFFF))) == i))
                    {
                        content.removeSpan(android.text.method.TextKeyListener.CAPPED);
                    }
                    else
                    {
                        flags = i << 16;
                        i     = Sharpen.CharHelper.ToUpper(i);
                        if (selStart == 0)
                        {
                            content.setSpan(android.text.method.TextKeyListener.CAPPED, 0, 0, android.text.SpannedClass.SPAN_MARK_MARK
                                            | flags);
                        }
                        else
                        {
                            content.setSpan(android.text.method.TextKeyListener.CAPPED, selStart - 1, selStart
                                            , android.text.SpannedClass.SPAN_EXCLUSIVE_EXCLUSIVE | flags);
                        }
                    }
                }
                if (selStart != selEnd)
                {
                    android.text.Selection.setSelection(content, selEnd);
                }
                content.setSpan(OLD_SEL_START, selStart, selStart, android.text.SpannedClass.SPAN_MARK_MARK
                                );
                content.replace(selStart, selEnd, java.lang.CharSequenceProxy.Wrap(((char)i).ToString
                                                                                       ()));
                int oldStart = content.getSpanStart(OLD_SEL_START);
                selEnd = android.text.Selection.getSelectionEnd(content);
                if (oldStart < selEnd)
                {
                    content.setSpan(android.text.method.TextKeyListener.LAST_TYPED, oldStart, selEnd,
                                    android.text.SpannedClass.SPAN_EXCLUSIVE_EXCLUSIVE);
                    if (dead)
                    {
                        android.text.Selection.setSelection(content, oldStart, selEnd);
                        content.setSpan(android.text.method.TextKeyListener.ACTIVE, oldStart, selEnd, android.text.SpannedClass.SPAN_EXCLUSIVE_EXCLUSIVE
                                        );
                    }
                }
                adjustMetaAfterKeypress(content);
                // potentially do autotext replacement if the character
                // that was typed was an autotext terminator
                if ((pref & android.text.method.TextKeyListener.AUTO_TEXT) != 0 && mAutoText && (
                        i == ' ' || i == '\t' || i == '\n' || i == ',' || i == '.' || i == '!' || i == '?' ||
                        i == '"' || Sharpen.CharHelper.GetType(i) == Sharpen.CharHelper.END_PUNCTUATION
                        ) && content.getSpanEnd(android.text.method.TextKeyListener.INHIBIT_REPLACEMENT)
                    != oldStart)
                {
                    int x;
                    for (x = oldStart; x > 0; x--)
                    {
                        char c = content[x - 1];
                        if (c != '\'' && !System.Char.IsLetter(c))
                        {
                            break;
                        }
                    }
                    string rep = getReplacement(content, x, oldStart, view);
                    if (rep != null)
                    {
                        android.text.method.QwertyKeyListener.Replaced[] repl = content.getSpans <android.text.method.QwertyKeyListener
                                                                                                  .Replaced>(0, content.Length);
                        {
                            for (int a = 0; a < repl.Length; a++)
                            {
                                content.removeSpan(repl[a]);
                            }
                        }
                        char[] orig = new char[oldStart - x];
                        android.text.TextUtils.getChars(content, x, oldStart, orig, 0);
                        content.setSpan(new android.text.method.QwertyKeyListener.Replaced(orig), x, oldStart
                                        , android.text.SpannedClass.SPAN_EXCLUSIVE_EXCLUSIVE);
                        content.replace(x, oldStart, java.lang.CharSequenceProxy.Wrap(rep));
                    }
                }
                // Replace two spaces by a period and a space.
                if ((pref & android.text.method.TextKeyListener.AUTO_PERIOD) != 0 && mAutoText)
                {
                    selEnd = android.text.Selection.getSelectionEnd(content);
                    if (selEnd - 3 >= 0)
                    {
                        if (content[selEnd - 1] == ' ' && content[selEnd - 2] == ' ')
                        {
                            char c = content[selEnd - 3];
                            {
                                for (int j = selEnd - 3; j > 0; j--)
                                {
                                    if (c == '"' || Sharpen.CharHelper.GetType(c) == Sharpen.CharHelper.END_PUNCTUATION)
                                    {
                                        c = content[j - 1];
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                            }
                            if (System.Char.IsLetter(c) || System.Char.IsDigit(c))
                            {
                                content.replace(selEnd - 2, selEnd - 1, java.lang.CharSequenceProxy.Wrap("."));
                            }
                        }
                    }
                }
                return(true);
            }
            else
            {
                if (keyCode == android.view.KeyEvent.KEYCODE_DEL && (@event.hasNoModifiers() || @event
                                                                     .hasModifiers(android.view.KeyEvent.META_ALT_ON)) && selStart == selEnd)
                {
                    // special backspace case for undoing autotext
                    int consider = 1;
                    // if backspacing over the last typed character,
                    // it undoes the autotext prior to that character
                    // (unless the character typed was newline, in which
                    // case this behavior would be confusing)
                    if (content.getSpanEnd(android.text.method.TextKeyListener.LAST_TYPED) == selStart)
                    {
                        if (content[selStart - 1] != '\n')
                        {
                            consider = 2;
                        }
                    }
                    android.text.method.QwertyKeyListener.Replaced[] repl = content.getSpans <android.text.method.QwertyKeyListener
                                                                                              .Replaced>(selStart - consider, selStart);
                    if (repl.Length > 0)
                    {
                        int    st  = content.getSpanStart(repl[0]);
                        int    en  = content.getSpanEnd(repl[0]);
                        string old = new string(repl[0].mText);
                        content.removeSpan(repl[0]);
                        // only cancel the autocomplete if the cursor is at the end of
                        // the replaced span (or after it, because the user is
                        // backspacing over the space after the word, not the word
                        // itself).
                        if (selStart >= en)
                        {
                            content.setSpan(android.text.method.TextKeyListener.INHIBIT_REPLACEMENT, en, en,
                                            android.text.SpannedClass.SPAN_POINT_POINT);
                            content.replace(st, en, java.lang.CharSequenceProxy.Wrap(old));
                            en = content.getSpanStart(android.text.method.TextKeyListener.INHIBIT_REPLACEMENT
                                                      );
                            if (en - 1 >= 0)
                            {
                                content.setSpan(android.text.method.TextKeyListener.INHIBIT_REPLACEMENT, en - 1,
                                                en, android.text.SpannedClass.SPAN_EXCLUSIVE_EXCLUSIVE);
                            }
                            else
                            {
                                content.removeSpan(android.text.method.TextKeyListener.INHIBIT_REPLACEMENT);
                            }
                            adjustMetaAfterKeypress(content);
                        }
                        else
                        {
                            adjustMetaAfterKeypress(content);
                            return(base.onKeyDown(view, content, keyCode, @event));
                        }
                        return(true);
                    }
                }
            }
            return(base.onKeyDown(view, content, keyCode, @event));
        }