PageRenderTime 19ms CodeModel.GetById 1ms app.highlight 15ms RepoModel.GetById 1ms app.codeStats 0ms

/ime/latinime/src/com/googlecode/eyesfree/inputmethod/latin/TextEntryState.java

http://eyes-free.googlecode.com/
Java | 278 lines | 220 code | 35 blank | 23 comment | 48 complexity | 1b183993b22e8274da16ee5e15951613 MD5 | raw file
  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
 17package com.googlecode.eyesfree.inputmethod.latin;
 18
 19import android.content.Context;
 20import android.inputmethodservice.Keyboard.Key;
 21import android.text.format.DateFormat;
 22import android.util.Log;
 23
 24import java.io.FileOutputStream;
 25import java.io.IOException;
 26import java.util.Calendar;
 27
 28public class TextEntryState {
 29    
 30    private static final boolean DBG = false;
 31
 32    private static final String TAG = "TextEntryState";
 33
 34    private static boolean LOGGING = false;
 35
 36    private static int sBackspaceCount = 0;
 37    
 38    private static int sAutoSuggestCount = 0;
 39    
 40    private static int sAutoSuggestUndoneCount = 0;
 41    
 42    private static int sManualSuggestCount = 0;
 43    
 44    private static int sWordNotInDictionaryCount = 0;
 45    
 46    private static int sSessionCount = 0;
 47    
 48    private static int sTypedChars;
 49
 50    private static int sActualChars;
 51
 52    public enum State {
 53        UNKNOWN,
 54        START,
 55        IN_WORD,
 56        ACCEPTED_DEFAULT,
 57        PICKED_SUGGESTION,
 58        PUNCTUATION_AFTER_WORD,
 59        PUNCTUATION_AFTER_ACCEPTED,
 60        SPACE_AFTER_ACCEPTED,
 61        SPACE_AFTER_PICKED,
 62        UNDO_COMMIT,
 63        CORRECTING,
 64        PICKED_CORRECTION;
 65    }
 66
 67    private static State sState = State.UNKNOWN;
 68
 69    private static FileOutputStream sKeyLocationFile;
 70    private static FileOutputStream sUserActionFile;
 71    
 72    public static void newSession(Context context) {
 73        sSessionCount++;
 74        sAutoSuggestCount = 0;
 75        sBackspaceCount = 0;
 76        sAutoSuggestUndoneCount = 0;
 77        sManualSuggestCount = 0;
 78        sWordNotInDictionaryCount = 0;
 79        sTypedChars = 0;
 80        sActualChars = 0;
 81        sState = State.START;
 82        
 83        if (LOGGING) {
 84            try {
 85                sKeyLocationFile = context.openFileOutput("key.txt", Context.MODE_APPEND);
 86                sUserActionFile = context.openFileOutput("action.txt", Context.MODE_APPEND);
 87            } catch (IOException ioe) {
 88                Log.e("TextEntryState", "Couldn't open file for output: " + ioe);
 89            }
 90        }
 91    }
 92    
 93    public static void endSession() {
 94        if (sKeyLocationFile == null) {
 95            return;
 96        }
 97        try {
 98            sKeyLocationFile.close();
 99            // Write to log file            
100            // Write timestamp, settings,
101            String out = DateFormat.format("MM:dd hh:mm:ss", Calendar.getInstance().getTime())
102                    .toString()
103                    + " BS: " + sBackspaceCount
104                    + " auto: " + sAutoSuggestCount
105                    + " manual: " + sManualSuggestCount
106                    + " typed: " + sWordNotInDictionaryCount
107                    + " undone: " + sAutoSuggestUndoneCount
108                    + " saved: " + ((float) (sActualChars - sTypedChars) / sActualChars)
109                    + "\n";
110            sUserActionFile.write(out.getBytes());
111            sUserActionFile.close();
112            sKeyLocationFile = null;
113            sUserActionFile = null;
114        } catch (IOException ioe) {
115            
116        }
117    }
118    
119    public static void acceptedDefault(CharSequence typedWord, CharSequence actualWord) {
120        if (typedWord == null) return;
121        if (!typedWord.equals(actualWord)) {
122            sAutoSuggestCount++;
123        }
124        sTypedChars += typedWord.length();
125        sActualChars += actualWord.length();
126        sState = State.ACCEPTED_DEFAULT;
127        LatinImeLogger.logOnAutoSuggestion(typedWord.toString(), actualWord.toString());
128        displayState();
129    }
130
131    // State.ACCEPTED_DEFAULT will be changed to other sub-states
132    // (see "case ACCEPTED_DEFAULT" in typedCharacter() below),
133    // and should be restored back to State.ACCEPTED_DEFAULT after processing for each sub-state.
134    public static void backToAcceptedDefault(CharSequence typedWord) {
135        if (typedWord == null) return;
136        switch (sState) {
137            case SPACE_AFTER_ACCEPTED:
138            case PUNCTUATION_AFTER_ACCEPTED:
139            case IN_WORD:
140                sState = State.ACCEPTED_DEFAULT;
141                break;
142        }
143        displayState();
144    }
145
146    public static void acceptedTyped(CharSequence typedWord) {
147        sWordNotInDictionaryCount++;
148        sState = State.PICKED_SUGGESTION;
149        displayState();
150    }
151
152    public static void acceptedSuggestion(CharSequence typedWord, CharSequence actualWord) {
153        sManualSuggestCount++;
154        State oldState = sState;
155        if (typedWord.equals(actualWord)) {
156            acceptedTyped(typedWord);
157        }
158        if (oldState == State.CORRECTING || oldState == State.PICKED_CORRECTION) {
159            sState = State.PICKED_CORRECTION;
160        } else {
161            sState = State.PICKED_SUGGESTION;
162        }
163        displayState();
164    }
165
166    public static void selectedForCorrection() {
167        sState = State.CORRECTING;
168        displayState();
169    }
170
171    public static void typedCharacter(char c, boolean isSeparator) {
172        boolean isSpace = c == ' ';
173        switch (sState) {
174            case IN_WORD:
175                if (isSpace || isSeparator) {
176                    sState = State.START;
177                } else {
178                    // State hasn't changed.
179                }
180                break;
181            case ACCEPTED_DEFAULT:
182            case SPACE_AFTER_PICKED:
183                if (isSpace) {
184                    sState = State.SPACE_AFTER_ACCEPTED;
185                } else if (isSeparator) {
186                    sState = State.PUNCTUATION_AFTER_ACCEPTED;
187                } else {
188                    sState = State.IN_WORD;
189                }
190                break;
191            case PICKED_SUGGESTION:
192            case PICKED_CORRECTION:
193                if (isSpace) {
194                    sState = State.SPACE_AFTER_PICKED;
195                } else if (isSeparator) {
196                    // Swap 
197                    sState = State.PUNCTUATION_AFTER_ACCEPTED;
198                } else {
199                    sState = State.IN_WORD;
200                }
201                break;
202            case START:
203            case UNKNOWN:
204            case SPACE_AFTER_ACCEPTED:
205            case PUNCTUATION_AFTER_ACCEPTED:
206            case PUNCTUATION_AFTER_WORD:
207                if (!isSpace && !isSeparator) {
208                    sState = State.IN_WORD;
209                } else {
210                    sState = State.START;
211                }
212                break;
213            case UNDO_COMMIT:
214                if (isSpace || isSeparator) {
215                    sState = State.ACCEPTED_DEFAULT;
216                } else {
217                    sState = State.IN_WORD;
218                }
219                break;
220            case CORRECTING:
221                sState = State.START;
222                break;
223        }
224        displayState();
225    }
226    
227    public static void backspace() {
228        if (sState == State.ACCEPTED_DEFAULT) {
229            sState = State.UNDO_COMMIT;
230            sAutoSuggestUndoneCount++;
231            LatinImeLogger.logOnAutoSuggestionCanceled();
232        } else if (sState == State.UNDO_COMMIT) {
233            sState = State.IN_WORD;
234        }
235        sBackspaceCount++;
236        displayState();
237    }
238
239    public static void reset() {
240        sState = State.START;
241        displayState();
242    }
243
244    public static State getState() {
245        if (DBG) {
246            Log.d(TAG, "Returning state = " + sState);
247        }
248        return sState;
249    }
250
251    public static boolean isCorrecting() {
252        return sState == State.CORRECTING || sState == State.PICKED_CORRECTION;
253    }
254
255    public static void keyPressedAt(Key key, int x, int y) {
256        if (LOGGING && sKeyLocationFile != null && key.codes[0] >= 32) {
257            String out = 
258                    "KEY: " + (char) key.codes[0] 
259                    + " X: " + x 
260                    + " Y: " + y
261                    + " MX: " + (key.x + key.width / 2)
262                    + " MY: " + (key.y + key.height / 2) 
263                    + "\n";
264            try {
265                sKeyLocationFile.write(out.getBytes());
266            } catch (IOException ioe) {
267                // TODO: May run out of space
268            }
269        }
270    }
271
272    private static void displayState() {
273        if (DBG) {
274            Log.d(TAG, "State = " + sState);
275        }
276    }
277}
278