• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */
16 
17 package com.android.inputmethod.latin;
18 
19 import java.util.ArrayList;
20 
21 /**
22  * A place to store the currently composing word with information such as adjacent key codes as well
23  */
24 public class WordComposer {
25     /**
26      * The list of unicode values for each keystroke (including surrounding keys)
27      */
28     private final ArrayList<int[]> mCodes;
29 
30     /**
31      * The word chosen from the candidate list, until it is committed.
32      */
33     private String mPreferredWord;
34 
35     private final StringBuilder mTypedWord;
36 
37     private int mCapsCount;
38 
39     private boolean mAutoCapitalized;
40 
41     /**
42      * Whether the user chose to capitalize the first char of the word.
43      */
44     private boolean mIsFirstCharCapitalized;
45 
WordComposer()46     public WordComposer() {
47         mCodes = new ArrayList<int[]>(12);
48         mTypedWord = new StringBuilder(20);
49     }
50 
WordComposer(WordComposer copy)51     WordComposer(WordComposer copy) {
52         mCodes = new ArrayList<int[]>(copy.mCodes);
53         mPreferredWord = copy.mPreferredWord;
54         mTypedWord = new StringBuilder(copy.mTypedWord);
55         mCapsCount = copy.mCapsCount;
56         mAutoCapitalized = copy.mAutoCapitalized;
57         mIsFirstCharCapitalized = copy.mIsFirstCharCapitalized;
58     }
59 
60     /**
61      * Clear out the keys registered so far.
62      */
reset()63     public void reset() {
64         mCodes.clear();
65         mIsFirstCharCapitalized = false;
66         mPreferredWord = null;
67         mTypedWord.setLength(0);
68         mCapsCount = 0;
69     }
70 
71     /**
72      * Number of keystrokes in the composing word.
73      * @return the number of keystrokes
74      */
size()75     public int size() {
76         return mCodes.size();
77     }
78 
79     /**
80      * Returns the codes at a particular position in the word.
81      * @param index the position in the word
82      * @return the unicode for the pressed and surrounding keys
83      */
getCodesAt(int index)84     public int[] getCodesAt(int index) {
85         return mCodes.get(index);
86     }
87 
88     /**
89      * Add a new keystroke, with codes[0] containing the pressed key's unicode and the rest of
90      * the array containing unicode for adjacent keys, sorted by reducing probability/proximity.
91      * @param codes the array of unicode values
92      */
add(int primaryCode, int[] codes)93     public void add(int primaryCode, int[] codes) {
94         mTypedWord.append((char) primaryCode);
95         correctPrimaryJuxtapos(primaryCode, codes);
96         mCodes.add(codes);
97         if (Character.isUpperCase((char) primaryCode)) mCapsCount++;
98     }
99 
100     /**
101      * Swaps the first and second values in the codes array if the primary code is not the first
102      * value in the array but the second. This happens when the preferred key is not the key that
103      * the user released the finger on.
104      * @param primaryCode the preferred character
105      * @param codes array of codes based on distance from touch point
106      */
correctPrimaryJuxtapos(int primaryCode, int[] codes)107     private void correctPrimaryJuxtapos(int primaryCode, int[] codes) {
108         if (codes.length < 2) return;
109         if (codes[0] > 0 && codes[1] > 0 && codes[0] != primaryCode && codes[1] == primaryCode) {
110             codes[1] = codes[0];
111             codes[0] = primaryCode;
112         }
113     }
114 
115     /**
116      * Delete the last keystroke as a result of hitting backspace.
117      */
deleteLast()118     public void deleteLast() {
119         final int codesSize = mCodes.size();
120         if (codesSize > 0) {
121             mCodes.remove(codesSize - 1);
122             final int lastPos = mTypedWord.length() - 1;
123             char last = mTypedWord.charAt(lastPos);
124             mTypedWord.deleteCharAt(lastPos);
125             if (Character.isUpperCase(last)) mCapsCount--;
126         }
127     }
128 
129     /**
130      * Returns the word as it was typed, without any correction applied.
131      * @return the word that was typed so far
132      */
getTypedWord()133     public CharSequence getTypedWord() {
134         int wordSize = mCodes.size();
135         if (wordSize == 0) {
136             return null;
137         }
138         return mTypedWord;
139     }
140 
setFirstCharCapitalized(boolean capitalized)141     public void setFirstCharCapitalized(boolean capitalized) {
142         mIsFirstCharCapitalized = capitalized;
143     }
144 
145     /**
146      * Whether or not the user typed a capital letter as the first letter in the word
147      * @return capitalization preference
148      */
isFirstCharCapitalized()149     public boolean isFirstCharCapitalized() {
150         return mIsFirstCharCapitalized;
151     }
152 
153     /**
154      * Whether or not all of the user typed chars are upper case
155      * @return true if all user typed chars are upper case, false otherwise
156      */
isAllUpperCase()157     public boolean isAllUpperCase() {
158         return (mCapsCount > 0) && (mCapsCount == size());
159     }
160 
161     /**
162      * Stores the user's selected word, before it is actually committed to the text field.
163      * @param preferred
164      */
setPreferredWord(String preferred)165     public void setPreferredWord(String preferred) {
166         mPreferredWord = preferred;
167     }
168 
169     /**
170      * Return the word chosen by the user, or the typed word if no other word was chosen.
171      * @return the preferred word
172      */
getPreferredWord()173     public CharSequence getPreferredWord() {
174         return mPreferredWord != null ? mPreferredWord : getTypedWord();
175     }
176 
177     /**
178      * Returns true if more than one character is upper case, otherwise returns false.
179      */
isMostlyCaps()180     public boolean isMostlyCaps() {
181         return mCapsCount > 1;
182     }
183 
184     /**
185      * Saves the reason why the word is capitalized - whether it was automatic or
186      * due to the user hitting shift in the middle of a sentence.
187      * @param auto whether it was an automatic capitalization due to start of sentence
188      */
setAutoCapitalized(boolean auto)189     public void setAutoCapitalized(boolean auto) {
190         mAutoCapitalized = auto;
191     }
192 
193     /**
194      * Returns whether the word was automatically capitalized.
195      * @return whether the word was automatically capitalized
196      */
isAutoCapitalized()197     public boolean isAutoCapitalized() {
198         return mAutoCapitalized;
199     }
200 }
201