• 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 com.android.inputmethod.keyboard.Keyboard;
20 import com.android.inputmethod.latin.Utils.RingCharBuffer;
21 
22 import android.util.Log;
23 
24 public class TextEntryState {
25     private static final String TAG = TextEntryState.class.getSimpleName();
26     private static final boolean DEBUG = false;
27 
28     private static final int UNKNOWN = 0;
29     private static final int START = 1;
30     private static final int IN_WORD = 2;
31     private static final int ACCEPTED_DEFAULT = 3;
32     private static final int PICKED_SUGGESTION = 4;
33     private static final int PUNCTUATION_AFTER_WORD = 5;
34     private static final int PUNCTUATION_AFTER_ACCEPTED = 6;
35     private static final int SPACE_AFTER_ACCEPTED = 7;
36     private static final int SPACE_AFTER_PICKED = 8;
37     private static final int UNDO_COMMIT = 9;
38     private static final int RECORRECTING = 10;
39     private static final int PICKED_RECORRECTION = 11;
40 
41     private static int sState = UNKNOWN;
42     private static int sPreviousState = UNKNOWN;
43 
setState(final int newState)44     private static void setState(final int newState) {
45         sPreviousState = sState;
46         sState = newState;
47     }
48 
acceptedDefault(CharSequence typedWord, CharSequence actualWord, int separatorCode)49     public static void acceptedDefault(CharSequence typedWord, CharSequence actualWord,
50             int separatorCode) {
51         if (typedWord == null) return;
52         setState(ACCEPTED_DEFAULT);
53         LatinImeLogger.logOnAutoCorrection(
54                 typedWord.toString(), actualWord.toString(), separatorCode);
55         if (DEBUG)
56             displayState("acceptedDefault", "typedWord", typedWord, "actualWord", actualWord);
57     }
58 
59     // State.ACCEPTED_DEFAULT will be changed to other sub-states
60     // (see "case ACCEPTED_DEFAULT" in typedCharacter() below),
61     // and should be restored back to State.ACCEPTED_DEFAULT after processing for each sub-state.
backToAcceptedDefault(CharSequence typedWord)62     public static void backToAcceptedDefault(CharSequence typedWord) {
63         if (typedWord == null) return;
64         switch (sState) {
65         case SPACE_AFTER_ACCEPTED:
66         case PUNCTUATION_AFTER_ACCEPTED:
67         case IN_WORD:
68             setState(ACCEPTED_DEFAULT);
69             break;
70         default:
71             break;
72         }
73         if (DEBUG) displayState("backToAcceptedDefault", "typedWord", typedWord);
74     }
75 
acceptedTyped(CharSequence typedWord)76     public static void acceptedTyped(CharSequence typedWord) {
77         setState(PICKED_SUGGESTION);
78         if (DEBUG) displayState("acceptedTyped", "typedWord", typedWord);
79     }
80 
acceptedSuggestion(CharSequence typedWord, CharSequence actualWord)81     public static void acceptedSuggestion(CharSequence typedWord, CharSequence actualWord) {
82         if (sState == RECORRECTING || sState == PICKED_RECORRECTION) {
83             setState(PICKED_RECORRECTION);
84         } else {
85             setState(PICKED_SUGGESTION);
86         }
87         if (DEBUG)
88             displayState("acceptedSuggestion", "typedWord", typedWord, "actualWord", actualWord);
89     }
90 
selectedForRecorrection()91     public static void selectedForRecorrection() {
92         setState(RECORRECTING);
93         if (DEBUG) displayState("selectedForRecorrection");
94     }
95 
onAbortRecorrection()96     public static void onAbortRecorrection() {
97         if (sState == RECORRECTING || sState == PICKED_RECORRECTION) {
98             setState(START);
99         }
100         if (DEBUG) displayState("onAbortRecorrection");
101     }
102 
typedCharacter(char c, boolean isSeparator, int x, int y)103     public static void typedCharacter(char c, boolean isSeparator, int x, int y) {
104         final boolean isSpace = (c == Keyboard.CODE_SPACE);
105         switch (sState) {
106         case IN_WORD:
107             if (isSpace || isSeparator) {
108                 setState(START);
109             } else {
110                 // State hasn't changed.
111             }
112             break;
113         case ACCEPTED_DEFAULT:
114         case SPACE_AFTER_PICKED:
115         case PUNCTUATION_AFTER_ACCEPTED:
116             if (isSpace) {
117                 setState(SPACE_AFTER_ACCEPTED);
118             } else if (isSeparator) {
119                 // Swap
120                 setState(PUNCTUATION_AFTER_ACCEPTED);
121             } else {
122                 setState(IN_WORD);
123             }
124             break;
125         case PICKED_SUGGESTION:
126         case PICKED_RECORRECTION:
127             if (isSpace) {
128                 setState(SPACE_AFTER_PICKED);
129             } else if (isSeparator) {
130                 // Swap
131                 setState(PUNCTUATION_AFTER_ACCEPTED);
132             } else {
133                 setState(IN_WORD);
134             }
135             break;
136         case START:
137         case UNKNOWN:
138         case SPACE_AFTER_ACCEPTED:
139         case PUNCTUATION_AFTER_WORD:
140             if (!isSpace && !isSeparator) {
141                 setState(IN_WORD);
142             } else {
143                 setState(START);
144             }
145             break;
146         case UNDO_COMMIT:
147             if (isSpace || isSeparator) {
148                 setState(START);
149             } else {
150                 setState(IN_WORD);
151             }
152             break;
153         case RECORRECTING:
154             setState(START);
155             break;
156         }
157         RingCharBuffer.getInstance().push(c, x, y);
158         if (isSeparator) {
159             LatinImeLogger.logOnInputSeparator();
160         } else {
161             LatinImeLogger.logOnInputChar();
162         }
163         if (DEBUG) displayState("typedCharacter", "char", c, "isSeparator", isSeparator);
164     }
165 
backspace()166     public static void backspace() {
167         if (sState == ACCEPTED_DEFAULT) {
168             setState(UNDO_COMMIT);
169             LatinImeLogger.logOnAutoCorrectionCancelled();
170         } else if (sState == UNDO_COMMIT) {
171             setState(IN_WORD);
172         }
173         if (DEBUG) displayState("backspace");
174     }
175 
reset()176     public static void reset() {
177         setState(START);
178         if (DEBUG) displayState("reset");
179     }
180 
isAcceptedDefault()181     public static boolean isAcceptedDefault() {
182         return sState == ACCEPTED_DEFAULT;
183     }
184 
isSpaceAfterPicked()185     public static boolean isSpaceAfterPicked() {
186         return sState == SPACE_AFTER_PICKED;
187     }
188 
isUndoCommit()189     public static boolean isUndoCommit() {
190         return sState == UNDO_COMMIT;
191     }
192 
isPunctuationAfterAccepted()193     public static boolean isPunctuationAfterAccepted() {
194         return sState == PUNCTUATION_AFTER_ACCEPTED;
195     }
196 
isRecorrecting()197     public static boolean isRecorrecting() {
198         return sState == RECORRECTING || sState == PICKED_RECORRECTION;
199     }
200 
getState()201     public static String getState() {
202         return stateName(sState);
203     }
204 
stateName(int state)205     private static String stateName(int state) {
206         switch (state) {
207         case START: return "START";
208         case IN_WORD: return "IN_WORD";
209         case ACCEPTED_DEFAULT: return "ACCEPTED_DEFAULT";
210         case PICKED_SUGGESTION: return "PICKED_SUGGESTION";
211         case PUNCTUATION_AFTER_WORD: return "PUNCTUATION_AFTER_WORD";
212         case PUNCTUATION_AFTER_ACCEPTED: return "PUNCTUATION_AFTER_ACCEPTED";
213         case SPACE_AFTER_ACCEPTED: return "SPACE_AFTER_ACCEPTED";
214         case SPACE_AFTER_PICKED: return "SPACE_AFTER_PICKED";
215         case UNDO_COMMIT: return "UNDO_COMMIT";
216         case RECORRECTING: return "RECORRECTING";
217         case PICKED_RECORRECTION: return "PICKED_RECORRECTION";
218         default: return "UNKNOWN";
219         }
220     }
221 
displayState(String title, Object ... args)222     private static void displayState(String title, Object ... args) {
223         final StringBuilder sb = new StringBuilder(title);
224         sb.append(':');
225         for (int i = 0; i < args.length; i += 2) {
226             sb.append(' ');
227             sb.append(args[i]);
228             sb.append('=');
229             sb.append(args[i+1].toString());
230         }
231         sb.append(" state=");
232         sb.append(stateName(sState));
233         sb.append(" previous=");
234         sb.append(stateName(sPreviousState));
235         Log.d(TAG, sb.toString());
236     }
237 }
238