Java Code Examples for android.text.style.SuggestionSpan

The following are top voted examples for showing how to use android.text.style.SuggestionSpan. These examples are extracted from open source projects. You can vote up the examples you like and your votes will be used in our system to generate more good examples.
Example 1
Project: AOSP-Kayboard-7.1.2   File: SpannableStringUtils.java   View source code 6 votes vote down vote up
/**
 * Copies the spans from the region <code>start...end</code> in
 * <code>source</code> to the region
 * <code>destoff...destoff+end-start</code> in <code>dest</code>.
 * Spans in <code>source</code> that begin before <code>start</code>
 * or end after <code>end</code> but overlap this range are trimmed
 * as if they began at <code>start</code> or ended at <code>end</code>.
 * Only SuggestionSpans that don't have the SPAN_PARAGRAPH span are copied.
 *
 * This code is almost entirely taken from {@link TextUtils#copySpansFrom}, except for the
 * kind of span that is copied.
 *
 * @throws IndexOutOfBoundsException if any of the copied spans
 * are out of range in <code>dest</code>.
 */
public static void copyNonParagraphSuggestionSpansFrom(Spanned source, int start, int end,
        Spannable dest, int destoff) {
    Object[] spans = source.getSpans(start, end, SuggestionSpan.class);

    for (int i = 0; i < spans.length; i++) {
        int fl = source.getSpanFlags(spans[i]);
        // We don't care about the PARAGRAPH flag in LatinIME code. However, if this flag
        // is set, Spannable#setSpan will throw an exception unless the span is on the edge
        // of a word. But the spans have been split into two by the getText{Before,After}Cursor
        // methods, so after concatenation they may end in the middle of a word.
        // Since we don't use them, we can just remove them and avoid crashing.
        fl &= ~Spanned.SPAN_PARAGRAPH;

        int st = source.getSpanStart(spans[i]);
        int en = source.getSpanEnd(spans[i]);

        if (st < start)
            st = start;
        if (en > end)
            en = end;

        dest.setSpan(spans[i], st - start + destoff, en - start + destoff,
                     fl);
    }
}
 
Example 2
Project: Tada   File: TextView.java   View source code 6 votes vote down vote up
/**
 * Removes the suggestion spans.
 */
CharSequence removeSuggestionSpans(CharSequence text) {
   if (text instanceof Spanned) {
       Spannable spannable;
       if (text instanceof Spannable) {
           spannable = (Spannable) text;
       } else {
           spannable = new SpannableString(text);
           text = spannable;
       }

       SuggestionSpan[] spans = spannable.getSpans(0, text.length(), SuggestionSpan.class);
       for (int i = 0; i < spans.length; i++) {
           spannable.removeSpan(spans[i]);
       }
   }
   return text;
}
 
Example 3
Project: Tada   File: TextView.java   View source code 6 votes vote down vote up
void removeAdjacentSuggestionSpans(final int pos) {
    if (!(mText instanceof Editable)) return;
    final Editable text = (Editable) mText;

    final SuggestionSpan[] spans = text.getSpans(pos, pos, SuggestionSpan.class);
    final int length = spans.length;
    for (int i = 0; i < length; i++) {
        final int spanStart = text.getSpanStart(spans[i]);
        final int spanEnd = text.getSpanEnd(spans[i]);
        if (spanEnd == pos || spanStart == pos) {
            if (SpellChecker.haveWordBoundariesChanged(text, pos, pos, spanStart, spanEnd)) {
                text.removeSpan(spans[i]);
            }
        }
    }
}
 
Example 4
Project: spanner   File: Spans.java   View source code 5 votes vote down vote up
/**
 * @see android.text.style.SuggestionSpan
 */
public static Span suggestion(@NonNull final Context context, @NonNull final String[] suggestions, final int flags) {
    return new Span(new SpanBuilder() {
        @Override
        public Object build() {
            return new SuggestionSpan(context, suggestions, flags);
        }
    });
}
 
Example 5
Project: spanner   File: Spans.java   View source code 5 votes vote down vote up
/**
 * @see android.text.style.SuggestionSpan
 */
public static Span suggestion(@NonNull final Locale locale, @NonNull final String[] suggestions, final int flags) {
    return new Span(new SpanBuilder() {
        @Override
        public Object build() {
            return new SuggestionSpan(locale, suggestions, flags);
        }
    });
}
 
Example 6
Project: spanner   File: Spans.java   View source code 5 votes vote down vote up
/**
 * @see android.text.style.SuggestionSpan
 */
public static Span suggestion(@NonNull final Context context, @NonNull final Locale locale, @NonNull final String[] suggestions, final int flags, @NonNull final Class<?> notificationTargetClass) {
    return new Span(new SpanBuilder() {
        @Override
        public Object build() {
            return new SuggestionSpan(context, locale, suggestions, flags, notificationTargetClass);
        }
    });
}
 
Example 7
Project: AOSP-Kayboard-7.1.2   File: SuggestionSpanUtils.java   View source code 5 votes vote down vote up
@UsedForTesting
public static CharSequence getTextWithAutoCorrectionIndicatorUnderline(
        final Context context, final String text, @Nonnull final Locale locale) {
    if (TextUtils.isEmpty(text) || OBJ_FLAG_AUTO_CORRECTION == null) {
        return text;
    }
    final Spannable spannable = new SpannableString(text);
    final SuggestionSpan suggestionSpan = new SuggestionSpan(context, locale,
            new String[] {} /* suggestions */, OBJ_FLAG_AUTO_CORRECTION, null);
    spannable.setSpan(suggestionSpan, 0, text.length(),
            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | Spanned.SPAN_COMPOSING);
    return spannable;
}
 
Example 8
Project: AOSP-Kayboard-7.1.2   File: SuggestionSpanUtils.java   View source code 5 votes vote down vote up
@UsedForTesting
public static CharSequence getTextWithSuggestionSpan(final Context context,
        final String pickedWord, final SuggestedWords suggestedWords, final Locale locale) {
    if (TextUtils.isEmpty(pickedWord) || suggestedWords.isEmpty()
            || suggestedWords.isPrediction() || suggestedWords.isPunctuationSuggestions()) {
        return pickedWord;
    }

    final ArrayList<String> suggestionsList = new ArrayList<>();
    for (int i = 0; i < suggestedWords.size(); ++i) {
        if (suggestionsList.size() >= SuggestionSpan.SUGGESTIONS_MAX_SIZE) {
            break;
        }
        final SuggestedWordInfo info = suggestedWords.getInfo(i);
        if (info.isKindOf(SuggestedWordInfo.KIND_PREDICTION)) {
            continue;
        }
        final String word = suggestedWords.getWord(i);
        if (!TextUtils.equals(pickedWord, word)) {
            suggestionsList.add(word.toString());
        }
    }
    final SuggestionSpan suggestionSpan = new SuggestionSpan(context, locale,
            suggestionsList.toArray(new String[suggestionsList.size()]), 0 /* flags */, null);
    final Spannable spannable = new SpannableString(pickedWord);
    spannable.setSpan(suggestionSpan, 0, pickedWord.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    return spannable;
}
 
Example 9
Project: AOSP-Kayboard-7.1.2   File: SuggestionSpanUtils.java   View source code 5 votes vote down vote up
/**
 * Returns first {@link Locale} found in the given array of {@link SuggestionSpan}.
 * @param suggestionSpans the array of {@link SuggestionSpan} to be examined.
 * @return the first {@link Locale} found in {@code suggestionSpans}. {@code null} when not
 * found.
 */
@UsedForTesting
@Nullable
public static Locale findFirstLocaleFromSuggestionSpans(
        final SuggestionSpan[] suggestionSpans) {
    for (final SuggestionSpan suggestionSpan : suggestionSpans) {
        final String localeString = suggestionSpan.getLocale();
        if (TextUtils.isEmpty(localeString)) {
            continue;
        }
        return LocaleUtils.constructLocaleFromString(localeString);
    }
    return null;
}
 
Example 10
Project: Tada   File: TextView.java   View source code 5 votes vote down vote up
void removeMisspelledSpans(Spannable spannable) {
    SuggestionSpan[] suggestionSpans = spannable.getSpans(0, spannable.length(),
            SuggestionSpan.class);
    for (int i = 0; i < suggestionSpans.length; i++) {
        int flags = suggestionSpans[i].getFlags();
        if ((flags & SuggestionSpan.FLAG_EASY_CORRECT) != 0
                && (flags & SuggestionSpan.FLAG_MISSPELLED) != 0) {
            spannable.removeSpan(suggestionSpans[i]);
        }
    }
}
 
Example 11
Project: Tada   File: TextView.java   View source code 5 votes vote down vote up
private void sendBeforeTextChanged(CharSequence text, int start, int before, int after) {
    if (mListeners != null) {
        final ArrayList<TextWatcher> list = mListeners;
        final int count = list.size();
        for (int i = 0; i < count; i++) {
            list.get(i).beforeTextChanged(text, start, before, after);
        }
    }

    // The spans that are inside or intersect the modified region no longer make sense
    removeIntersectingNonAdjacentSpans(start, start + before, SpellCheckSpan.class);
    removeIntersectingNonAdjacentSpans(start, start + before, SuggestionSpan.class);
}
 
Example 12
Project: android-kioskime   File: SuggestionSpanPickedNotificationReceiver.java   View source code 5 votes vote down vote up
@Override
public void onReceive(Context context, Intent intent) {
    if (SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(intent.getAction())) {
        if (DBG) {
            final String before = intent.getStringExtra(
                    SuggestionSpan.SUGGESTION_SPAN_PICKED_BEFORE);
            final String after = intent.getStringExtra(
                    SuggestionSpan.SUGGESTION_SPAN_PICKED_AFTER);
            Log.d(TAG, "Received notification picked: " + before + "," + after);
        }
    }
}
 
Example 13
Project: android-kioskime   File: SuggestionSpanUtils.java   View source code 5 votes vote down vote up
public static CharSequence getTextWithAutoCorrectionIndicatorUnderline(
        final Context context, final String text) {
    if (TextUtils.isEmpty(text) || OBJ_FLAG_AUTO_CORRECTION == null) {
        return text;
    }
    final Spannable spannable = new SpannableString(text);
    final SuggestionSpan suggestionSpan = new SuggestionSpan(context, null /* locale */,
            new String[] {} /* suggestions */, (int)OBJ_FLAG_AUTO_CORRECTION,
            SuggestionSpanPickedNotificationReceiver.class);
    spannable.setSpan(suggestionSpan, 0, text.length(),
            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | Spanned.SPAN_COMPOSING);
    return spannable;
}
 
Example 14
Project: android-kioskime   File: SuggestionSpanUtils.java   View source code 5 votes vote down vote up
public static CharSequence getTextWithSuggestionSpan(final Context context,
        final String pickedWord, final SuggestedWords suggestedWords,
        final boolean dictionaryAvailable) {
    if (!dictionaryAvailable || TextUtils.isEmpty(pickedWord) || suggestedWords.isEmpty()
            || suggestedWords.mIsPrediction || suggestedWords.mIsPunctuationSuggestions) {
        return pickedWord;
    }

    final Spannable spannable = new SpannableString(pickedWord);
    final ArrayList<String> suggestionsList = CollectionUtils.newArrayList();
    for (int i = 0; i < suggestedWords.size(); ++i) {
        if (suggestionsList.size() >= SuggestionSpan.SUGGESTIONS_MAX_SIZE) {
            break;
        }
        final String word = suggestedWords.getWord(i);
        if (!TextUtils.equals(pickedWord, word)) {
            suggestionsList.add(word.toString());
        }
    }

    // TODO: We should avoid adding suggestion span candidates that came from the bigram
    // prediction.
    final SuggestionSpan suggestionSpan = new SuggestionSpan(context, null /* locale */,
            suggestionsList.toArray(new String[suggestionsList.size()]), 0 /* flags */,
            SuggestionSpanPickedNotificationReceiver.class);
    spannable.setSpan(suggestionSpan, 0, pickedWord.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    return spannable;
}
 
Example 15
Project: AOSP-Kayboard-7.1.2   File: TextRange.java   View source code 4 votes vote down vote up
/**
 * Gets the suggestion spans that are put squarely on the word, with the exact start
 * and end of the span matching the boundaries of the word.
 * @return the list of spans.
 */
public SuggestionSpan[] getSuggestionSpansAtWord() {
    if (!(mTextAtCursor instanceof Spanned && mWord instanceof Spanned)) {
        return new SuggestionSpan[0];
    }
    final Spanned text = (Spanned)mTextAtCursor;
    // Note: it's fine to pass indices negative or greater than the length of the string
    // to the #getSpans() method. The reason we need to get from -1 to +1 is that, the
    // spans were cut at the cursor position, and #getSpans(start, end) does not return
    // spans that end at `start' or begin at `end'. Consider the following case:
    //              this| is          (The | symbolizes the cursor position
    //              ---- ---
    // In this case, the cursor is in position 4, so the 0~7 span has been split into
    // a 0~4 part and a 4~7 part.
    // If we called #getSpans(0, 4) in this case, we would only get the part from 0 to 4
    // of the span, and not the part from 4 to 7, so we would not realize the span actually
    // extends from 0 to 7. But if we call #getSpans(-1, 5) we'll get both the 0~4 and
    // the 4~7 spans and we can merge them accordingly.
    // Any span starting more than 1 char away from the word boundaries in any direction
    // does not touch the word, so we don't need to consider it. That's why requesting
    // -1 ~ +1 is enough.
    // Of course this is only relevant if the cursor is at one end of the word. If it's
    // in the middle, the -1 and +1 are not necessary, but they are harmless.
    final SuggestionSpan[] spans = text.getSpans(mWordAtCursorStartIndex - 1,
            mWordAtCursorEndIndex + 1, SuggestionSpan.class);
    int readIndex = 0;
    int writeIndex = 0;
    for (; readIndex < spans.length; ++readIndex) {
        final SuggestionSpan span = spans[readIndex];
        // The span may be null, as we null them when we find duplicates. Cf a few lines
        // down.
        if (null == span) continue;
        // Tentative span start and end. This may be modified later if we realize the
        // same span is also applied to other parts of the string.
        int spanStart = text.getSpanStart(span);
        int spanEnd = text.getSpanEnd(span);
        for (int i = readIndex + 1; i < spans.length; ++i) {
            if (span.equals(spans[i])) {
                // We found the same span somewhere else. Read the new extent of this
                // span, and adjust our values accordingly.
                spanStart = Math.min(spanStart, text.getSpanStart(spans[i]));
                spanEnd = Math.max(spanEnd, text.getSpanEnd(spans[i]));
                // ...and mark the span as processed.
                spans[i] = null;
            }
        }
        if (spanStart == mWordAtCursorStartIndex && spanEnd == mWordAtCursorEndIndex) {
            // If the span does not start and stop here, ignore it. It probably extends
            // past the start or end of the word, as happens in missing space correction
            // or EasyEditSpans put by voice input.
            spans[writeIndex++] = spans[readIndex];
        }
    }
    return writeIndex == readIndex ? spans : Arrays.copyOfRange(spans, 0, writeIndex);
}
 
Example 16
Project: android-kioskime   File: LatinIME.java   View source code 4 votes vote down vote up
/**
 * Check if the cursor is touching a word. If so, restart suggestions on this word, else
 * do nothing.
 */
private void restartSuggestionsOnWordTouchedByCursor() {
    // HACK: We may want to special-case some apps that exhibit bad behavior in case of
    // recorrection. This is a temporary, stopgap measure that will be removed later.
    // TODO: remove this.
    if (mAppWorkAroundsUtils.isBrokenByRecorrection()) return;
    // If the cursor is not touching a word, or if there is a selection, return right away.
    if (mLastSelectionStart != mLastSelectionEnd) return;
    // If we don't know the cursor location, return.
    if (mLastSelectionStart < 0) return;
    if (!mConnection.isCursorTouchingWord(mSettings.getCurrent())) return;
    final Range range = mConnection.getWordRangeAtCursor(mSettings.getWordSeparators(),
            0 /* additionalPrecedingWordsCount */);
    if (null == range) return; // Happens if we don't have an input connection at all
    // If for some strange reason (editor bug or so) we measure the text before the cursor as
    // longer than what the entire text is supposed to be, the safe thing to do is bail out.
    if (range.mCharsBefore > mLastSelectionStart) return;
    final ArrayList<SuggestedWordInfo> suggestions = CollectionUtils.newArrayList();
    final String typedWord = range.mWord.toString();
    if (range.mWord instanceof SpannableString) {
        final SpannableString spannableString = (SpannableString)range.mWord;
        int i = 0;
        for (Object object : spannableString.getSpans(0, spannableString.length(),
                SuggestionSpan.class)) {
            SuggestionSpan span = (SuggestionSpan)object;
            for (String s : span.getSuggestions()) {
                ++i;
                if (!TextUtils.equals(s, typedWord)) {
                    suggestions.add(new SuggestedWordInfo(s,
                            SuggestionStripView.MAX_SUGGESTIONS - i,
                            SuggestedWordInfo.KIND_RESUMED, Dictionary.TYPE_RESUMED));
                }
            }
        }
    }
    mWordComposer.setComposingWord(typedWord, mKeyboardSwitcher.getKeyboard());
    mWordComposer.setCursorPositionWithinWord(range.mCharsBefore);
    mConnection.setComposingRegion(mLastSelectionStart - range.mCharsBefore,
            mLastSelectionEnd + range.mCharsAfter);
    final SuggestedWords suggestedWords;
    if (suggestions.isEmpty()) {
        // We come here if there weren't any suggestion spans on this word. We will try to
        // compute suggestions for it instead.
        final SuggestedWords suggestedWordsIncludingTypedWord =
                getSuggestedWords(Suggest.SESSION_TYPING);
        if (suggestedWordsIncludingTypedWord.size() > 1) {
            // We were able to compute new suggestions for this word.
            // Remove the typed word, since we don't want to display it in this case.
            // The #getSuggestedWordsExcludingTypedWord() method sets willAutoCorrect to false.
            suggestedWords =
                    suggestedWordsIncludingTypedWord.getSuggestedWordsExcludingTypedWord();
        } else {
            // No saved suggestions, and we were unable to compute any good one either.
            // Rather than displaying an empty suggestion strip, we'll display the original
            // word alone in the middle.
            // Since there is only one word, willAutoCorrect is false.
            suggestedWords = suggestedWordsIncludingTypedWord;
        }
    } else {
        // We found suggestion spans in the word. We'll create the SuggestedWords out of
        // them, and make willAutoCorrect false.
        suggestedWords = new SuggestedWords(suggestions,
                true /* typedWordValid */, false /* willAutoCorrect */,
                false /* isPunctuationSuggestions */, false /* isObsoleteSuggestions */,
                false /* isPrediction */);
    }

    // Note that it's very important here that suggestedWords.mWillAutoCorrect is false.
    // We never want to auto-correct on a resumed suggestion. Please refer to the three
    // places above where suggestedWords is affected. We also need to reset
    // mIsAutoCorrectionIndicatorOn to avoid showSuggestionStrip touching the text to adapt it.
    // TODO: remove mIsAutoCorrectionIndicator on (see comment on definition)
    mIsAutoCorrectionIndicatorOn = false;
    showSuggestionStrip(suggestedWords, typedWord);
}