WordComposer.java revision 1c551251106e506c70fad7ba0cb8b1e2a7dff3a9
1923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project/*
2923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Copyright (C) 2008-2009 Google Inc.
3923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project *
4923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * use this file except in compliance with the License. You may obtain a copy of
6923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * the License at
7923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project *
8923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0
9923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project *
10923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * License for the specific language governing permissions and limitations under
14923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * the License.
15923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */
16923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
17923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectpackage com.android.inputmethod.latin;
18923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
19923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport java.util.ArrayList;
20923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport java.util.List;
21923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
22923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project/**
23923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * A place to store the currently composing word with information such as adjacent key codes as well
24923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */
25923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectpublic class WordComposer {
26923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    /**
27923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     * The list of unicode values for each keystroke (including surrounding keys)
28923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     */
293263841911dc3dbbf4ffe26d2f046e38a1896f72Amith Yamasani    private ArrayList<int[]> mCodes;
30923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
31923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    /**
32923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     * The word chosen from the candidate list, until it is committed.
33923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     */
34923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private String mPreferredWord;
35923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
36923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private StringBuilder mTypedWord;
374a7ff90d513f8b6cbf39688c08be0828a57e311bAmith Yamasani
384a7ff90d513f8b6cbf39688c08be0828a57e311bAmith Yamasani    private int mCapsCount;
391c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani
401c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani    private boolean mAutoCapitalized;
41923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
42923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    /**
43923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     * Whether the user chose to capitalize the word.
44923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     */
45923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private boolean mIsCapitalized;
46923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
47923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    WordComposer() {
48923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mCodes = new ArrayList<int[]>(12);
49923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mTypedWord = new StringBuilder(20);
50923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
51923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
52923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    /**
53923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     * Clear out the keys registered so far.
54923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     */
55923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public void reset() {
56923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mCodes.clear();
57923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mIsCapitalized = false;
58923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mPreferredWord = null;
59923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mTypedWord.setLength(0);
604a7ff90d513f8b6cbf39688c08be0828a57e311bAmith Yamasani        mCapsCount = 0;
61923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
62923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
63923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    /**
64923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     * Number of keystrokes in the composing word.
65923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     * @return the number of keystrokes
66923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     */
67923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public int size() {
68923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        return mCodes.size();
69923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
70923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
71923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    /**
72923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     * Returns the codes at a particular position in the word.
73923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     * @param index the position in the word
74923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     * @return the unicode for the pressed and surrounding keys
75923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     */
76923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public int[] getCodesAt(int index) {
77923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        return mCodes.get(index);
78923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
79923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
80923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    /**
81923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     * Add a new keystroke, with codes[0] containing the pressed key's unicode and the rest of
82923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     * the array containing unicode for adjacent keys, sorted by reducing probability/proximity.
83923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     * @param codes the array of unicode values
84923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     */
85923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public void add(int primaryCode, int[] codes) {
86923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mTypedWord.append((char) primaryCode);
87923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mCodes.add(codes);
884a7ff90d513f8b6cbf39688c08be0828a57e311bAmith Yamasani        if (Character.isUpperCase((char) primaryCode)) mCapsCount++;
89923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
90923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
91923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    /**
92923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     * Delete the last keystroke as a result of hitting backspace.
93923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     */
94923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public void deleteLast() {
95923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mCodes.remove(mCodes.size() - 1);
964a7ff90d513f8b6cbf39688c08be0828a57e311bAmith Yamasani        final int lastPos = mTypedWord.length() - 1;
974a7ff90d513f8b6cbf39688c08be0828a57e311bAmith Yamasani        char last = mTypedWord.charAt(lastPos);
984a7ff90d513f8b6cbf39688c08be0828a57e311bAmith Yamasani        mTypedWord.deleteCharAt(lastPos);
994a7ff90d513f8b6cbf39688c08be0828a57e311bAmith Yamasani        if (Character.isUpperCase(last)) mCapsCount--;
100923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
101923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
102923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    /**
103923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     * Returns the word as it was typed, without any correction applied.
104923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     * @return the word that was typed so far
105923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     */
106923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public CharSequence getTypedWord() {
107923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        int wordSize = mCodes.size();
108923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        if (wordSize == 0) {
109923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            return null;
110923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        }
111923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project//        StringBuffer sb = new StringBuffer(wordSize);
112923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project//        for (int i = 0; i < wordSize; i++) {
113923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project//            char c = (char) mCodes.get(i)[0];
114923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project//            if (i == 0 && mIsCapitalized) {
115923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project//                c = Character.toUpperCase(c);
116923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project//            }
117923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project//            sb.append(c);
118923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project//        }
119923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project//        return sb;
120923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        return mTypedWord;
121923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
122923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
123923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public void setCapitalized(boolean capitalized) {
124923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mIsCapitalized = capitalized;
125923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
126923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
127923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    /**
128923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     * Whether or not the user typed a capital letter as the first letter in the word
129923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     * @return capitalization preference
130923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     */
131923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public boolean isCapitalized() {
132923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        return mIsCapitalized;
133923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
134923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
135923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    /**
136923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     * Stores the user's selected word, before it is actually committed to the text field.
137923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     * @param preferred
138923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     */
139923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public void setPreferredWord(String preferred) {
140923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mPreferredWord = preferred;
141923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
142923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
143923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    /**
144923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     * Return the word chosen by the user, or the typed word if no other word was chosen.
145923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     * @return the preferred word
146923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     */
147923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public CharSequence getPreferredWord() {
148923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        return mPreferredWord != null ? mPreferredWord : getTypedWord();
149923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
1504a7ff90d513f8b6cbf39688c08be0828a57e311bAmith Yamasani
1514a7ff90d513f8b6cbf39688c08be0828a57e311bAmith Yamasani    /**
1524a7ff90d513f8b6cbf39688c08be0828a57e311bAmith Yamasani     * Returns true if more than one character is upper case, otherwise returns false.
1534a7ff90d513f8b6cbf39688c08be0828a57e311bAmith Yamasani     */
1544a7ff90d513f8b6cbf39688c08be0828a57e311bAmith Yamasani    public boolean isMostlyCaps() {
1554a7ff90d513f8b6cbf39688c08be0828a57e311bAmith Yamasani        return mCapsCount > 1;
1564a7ff90d513f8b6cbf39688c08be0828a57e311bAmith Yamasani    }
1571c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani
1581c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani    /**
1591c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani     * Saves the reason why the word is capitalized - whether it was automatic or
1601c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani     * due to the user hitting shift in the middle of a sentence.
1611c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani     * @param auto whether it was an automatic capitalization due to start of sentence
1621c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani     */
1631c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani    public void setAutoCapitalized(boolean auto) {
1641c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani        mAutoCapitalized = auto;
1651c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani    }
1661c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani
1671c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani    /**
1681c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani     * Returns whether the word was automatically capitalized.
1691c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani     * @return whether the word was automatically capitalized
1701c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani     */
1711c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani    public boolean isAutoCapitalized() {
1721c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani        return mAutoCapitalized;
1731c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani    }
174923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project}
175