1a81953a2b1818066ef5e44817f374ac288bab343Christine Chen/*
2a81953a2b1818066ef5e44817f374ac288bab343Christine Chen * Copyright (C) 2011 The Android Open Source Project
3a81953a2b1818066ef5e44817f374ac288bab343Christine Chen *
4a81953a2b1818066ef5e44817f374ac288bab343Christine Chen * Licensed under the Apache License, Version 2.0 (the "License");
5a81953a2b1818066ef5e44817f374ac288bab343Christine Chen * you may not use this file except in compliance with the License.
6a81953a2b1818066ef5e44817f374ac288bab343Christine Chen * You may obtain a copy of the License at
7a81953a2b1818066ef5e44817f374ac288bab343Christine Chen *
8a81953a2b1818066ef5e44817f374ac288bab343Christine Chen *      http://www.apache.org/licenses/LICENSE-2.0
9a81953a2b1818066ef5e44817f374ac288bab343Christine Chen *
10a81953a2b1818066ef5e44817f374ac288bab343Christine Chen * Unless required by applicable law or agreed to in writing, software
11a81953a2b1818066ef5e44817f374ac288bab343Christine Chen * distributed under the License is distributed on an "AS IS" BASIS,
12a81953a2b1818066ef5e44817f374ac288bab343Christine Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a81953a2b1818066ef5e44817f374ac288bab343Christine Chen * See the License for the specific language governing permissions and
14a81953a2b1818066ef5e44817f374ac288bab343Christine Chen * limitations under the License.
15a81953a2b1818066ef5e44817f374ac288bab343Christine Chen */
16a81953a2b1818066ef5e44817f374ac288bab343Christine Chen
17a81953a2b1818066ef5e44817f374ac288bab343Christine Chenpackage com.android.contacts.common.format;
18a81953a2b1818066ef5e44817f374ac288bab343Christine Chen
1942210256d3d584783ac2fb2742088ce57d9da766Yorke Leeimport android.graphics.Typeface;
20a81953a2b1818066ef5e44817f374ac288bab343Christine Chenimport android.text.SpannableString;
2142210256d3d584783ac2fb2742088ce57d9da766Yorke Leeimport android.text.style.CharacterStyle;
22a81953a2b1818066ef5e44817f374ac288bab343Christine Chenimport android.text.style.ForegroundColorSpan;
2342210256d3d584783ac2fb2742088ce57d9da766Yorke Leeimport android.text.style.StyleSpan;
24a81953a2b1818066ef5e44817f374ac288bab343Christine Chenimport android.widget.TextView;
25a81953a2b1818066ef5e44817f374ac288bab343Christine Chen
26a81953a2b1818066ef5e44817f374ac288bab343Christine Chenimport com.google.common.base.Preconditions;
27a81953a2b1818066ef5e44817f374ac288bab343Christine Chen
28a81953a2b1818066ef5e44817f374ac288bab343Christine Chen/**
29a81953a2b1818066ef5e44817f374ac288bab343Christine Chen * Highlights the text in a text field.
30a81953a2b1818066ef5e44817f374ac288bab343Christine Chen */
31a81953a2b1818066ef5e44817f374ac288bab343Christine Chenpublic class TextHighlighter {
32a81953a2b1818066ef5e44817f374ac288bab343Christine Chen    private final String TAG = TextHighlighter.class.getSimpleName();
33a81953a2b1818066ef5e44817f374ac288bab343Christine Chen    private final static boolean DEBUG = false;
34a81953a2b1818066ef5e44817f374ac288bab343Christine Chen
3542210256d3d584783ac2fb2742088ce57d9da766Yorke Lee    private int mTextStyle;
36a81953a2b1818066ef5e44817f374ac288bab343Christine Chen
3742210256d3d584783ac2fb2742088ce57d9da766Yorke Lee    private CharacterStyle mTextStyleSpan;
38a81953a2b1818066ef5e44817f374ac288bab343Christine Chen
3942210256d3d584783ac2fb2742088ce57d9da766Yorke Lee    public TextHighlighter(int textStyle) {
4042210256d3d584783ac2fb2742088ce57d9da766Yorke Lee        mTextStyle = textStyle;
4142210256d3d584783ac2fb2742088ce57d9da766Yorke Lee        mTextStyleSpan = getStyleSpan();
42a81953a2b1818066ef5e44817f374ac288bab343Christine Chen    }
43a81953a2b1818066ef5e44817f374ac288bab343Christine Chen
44a81953a2b1818066ef5e44817f374ac288bab343Christine Chen    /**
45a81953a2b1818066ef5e44817f374ac288bab343Christine Chen     * Sets the text on the given text view, highlighting the word that matches the given prefix.
46a81953a2b1818066ef5e44817f374ac288bab343Christine Chen     *
47a81953a2b1818066ef5e44817f374ac288bab343Christine Chen     * @param view the view on which to set the text
48a81953a2b1818066ef5e44817f374ac288bab343Christine Chen     * @param text the string to use as the text
49a81953a2b1818066ef5e44817f374ac288bab343Christine Chen     * @param prefix the prefix to look for
50a81953a2b1818066ef5e44817f374ac288bab343Christine Chen     */
51a81953a2b1818066ef5e44817f374ac288bab343Christine Chen    public void setPrefixText(TextView view, String text, String prefix) {
52a81953a2b1818066ef5e44817f374ac288bab343Christine Chen        view.setText(applyPrefixHighlight(text, prefix));
53a81953a2b1818066ef5e44817f374ac288bab343Christine Chen    }
54a81953a2b1818066ef5e44817f374ac288bab343Christine Chen
5542210256d3d584783ac2fb2742088ce57d9da766Yorke Lee    private CharacterStyle getStyleSpan() {
5642210256d3d584783ac2fb2742088ce57d9da766Yorke Lee        return new StyleSpan(mTextStyle);
5742210256d3d584783ac2fb2742088ce57d9da766Yorke Lee    }
5842210256d3d584783ac2fb2742088ce57d9da766Yorke Lee
59a81953a2b1818066ef5e44817f374ac288bab343Christine Chen    /**
60a81953a2b1818066ef5e44817f374ac288bab343Christine Chen     * Applies highlight span to the text.
61a81953a2b1818066ef5e44817f374ac288bab343Christine Chen     * @param text Text sequence to be highlighted.
62f99a990be713ed35afe64ba8133c5428816390c6Christine Chen     * @param start Start position of the highlight sequence.
63f99a990be713ed35afe64ba8133c5428816390c6Christine Chen     * @param end End position of the highlight sequence.
64a81953a2b1818066ef5e44817f374ac288bab343Christine Chen     */
65f99a990be713ed35afe64ba8133c5428816390c6Christine Chen    public void applyMaskingHighlight(SpannableString text, int start, int end) {
66a81953a2b1818066ef5e44817f374ac288bab343Christine Chen        /** Sets text color of the masked locations to be highlighted. */
6742210256d3d584783ac2fb2742088ce57d9da766Yorke Lee        text.setSpan(getStyleSpan(), start, end, 0);
68a81953a2b1818066ef5e44817f374ac288bab343Christine Chen    }
69a81953a2b1818066ef5e44817f374ac288bab343Christine Chen
70a81953a2b1818066ef5e44817f374ac288bab343Christine Chen    /**
71a81953a2b1818066ef5e44817f374ac288bab343Christine Chen     * Returns a CharSequence which highlights the given prefix if found in the given text.
72a81953a2b1818066ef5e44817f374ac288bab343Christine Chen     *
73a81953a2b1818066ef5e44817f374ac288bab343Christine Chen     * @param text the text to which to apply the highlight
74a81953a2b1818066ef5e44817f374ac288bab343Christine Chen     * @param prefix the prefix to look for
75a81953a2b1818066ef5e44817f374ac288bab343Christine Chen     */
76a81953a2b1818066ef5e44817f374ac288bab343Christine Chen    public CharSequence applyPrefixHighlight(CharSequence text, String prefix) {
77a81953a2b1818066ef5e44817f374ac288bab343Christine Chen        if (prefix == null) {
78a81953a2b1818066ef5e44817f374ac288bab343Christine Chen            return text;
79a81953a2b1818066ef5e44817f374ac288bab343Christine Chen        }
80a81953a2b1818066ef5e44817f374ac288bab343Christine Chen
81a81953a2b1818066ef5e44817f374ac288bab343Christine Chen        // Skip non-word characters at the beginning of prefix.
82a81953a2b1818066ef5e44817f374ac288bab343Christine Chen        int prefixStart = 0;
83a81953a2b1818066ef5e44817f374ac288bab343Christine Chen        while (prefixStart < prefix.length() &&
84a81953a2b1818066ef5e44817f374ac288bab343Christine Chen                !Character.isLetterOrDigit(prefix.charAt(prefixStart))) {
85a81953a2b1818066ef5e44817f374ac288bab343Christine Chen            prefixStart++;
86a81953a2b1818066ef5e44817f374ac288bab343Christine Chen        }
87a81953a2b1818066ef5e44817f374ac288bab343Christine Chen        final String trimmedPrefix = prefix.substring(prefixStart);
88a81953a2b1818066ef5e44817f374ac288bab343Christine Chen
89a81953a2b1818066ef5e44817f374ac288bab343Christine Chen        int index = FormatUtils.indexOfWordPrefix(text, trimmedPrefix);
90a81953a2b1818066ef5e44817f374ac288bab343Christine Chen        if (index != -1) {
91a81953a2b1818066ef5e44817f374ac288bab343Christine Chen            final SpannableString result = new SpannableString(text);
9242210256d3d584783ac2fb2742088ce57d9da766Yorke Lee            result.setSpan(mTextStyleSpan, index, index + trimmedPrefix.length(), 0 /* flags */);
93a81953a2b1818066ef5e44817f374ac288bab343Christine Chen            return result;
94a81953a2b1818066ef5e44817f374ac288bab343Christine Chen        } else {
95a81953a2b1818066ef5e44817f374ac288bab343Christine Chen            return text;
96a81953a2b1818066ef5e44817f374ac288bab343Christine Chen        }
97a81953a2b1818066ef5e44817f374ac288bab343Christine Chen    }
98a81953a2b1818066ef5e44817f374ac288bab343Christine Chen}
99