Home | History | Annotate | Download | only in latin
      1 /*
      2  * Copyright (C) 2008-2009 Google Inc.
      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 import java.util.List;
     21 
     22 /**
     23  * A place to store the currently composing word with information such as adjacent key codes as well
     24  */
     25 public class WordComposer {
     26     /**
     27      * The list of unicode values for each keystroke (including surrounding keys)
     28      */
     29     private ArrayList<int[]> mCodes;
     30 
     31     /**
     32      * The word chosen from the candidate list, until it is committed.
     33      */
     34     private String mPreferredWord;
     35 
     36     private StringBuilder mTypedWord;
     37 
     38     private int mCapsCount;
     39 
     40     private boolean mAutoCapitalized;
     41 
     42     /**
     43      * Whether the user chose to capitalize the word.
     44      */
     45     private boolean mIsCapitalized;
     46 
     47     WordComposer() {
     48         mCodes = new ArrayList<int[]>(12);
     49         mTypedWord = new StringBuilder(20);
     50     }
     51 
     52     /**
     53      * Clear out the keys registered so far.
     54      */
     55     public void reset() {
     56         mCodes.clear();
     57         mIsCapitalized = false;
     58         mPreferredWord = null;
     59         mTypedWord.setLength(0);
     60         mCapsCount = 0;
     61     }
     62 
     63     /**
     64      * Number of keystrokes in the composing word.
     65      * @return the number of keystrokes
     66      */
     67     public int size() {
     68         return mCodes.size();
     69     }
     70 
     71     /**
     72      * Returns the codes at a particular position in the word.
     73      * @param index the position in the word
     74      * @return the unicode for the pressed and surrounding keys
     75      */
     76     public int[] getCodesAt(int index) {
     77         return mCodes.get(index);
     78     }
     79 
     80     /**
     81      * Add a new keystroke, with codes[0] containing the pressed key's unicode and the rest of
     82      * the array containing unicode for adjacent keys, sorted by reducing probability/proximity.
     83      * @param codes the array of unicode values
     84      */
     85     public void add(int primaryCode, int[] codes) {
     86         mTypedWord.append((char) primaryCode);
     87         correctPrimaryJuxtapos(primaryCode, codes);
     88         mCodes.add(codes);
     89         if (Character.isUpperCase((char) primaryCode)) mCapsCount++;
     90     }
     91 
     92     /**
     93      * Swaps the first and second values in the codes array if the primary code is not the first
     94      * value in the array but the second. This happens when the preferred key is not the key that
     95      * the user released the finger on.
     96      * @param primaryCode the preferred character
     97      * @param codes array of codes based on distance from touch point
     98      */
     99     private void correctPrimaryJuxtapos(int primaryCode, int[] codes) {
    100         if (codes.length < 2) return;
    101         if (codes[0] > 0 && codes[1] > 0 && codes[0] != primaryCode && codes[1] == primaryCode) {
    102             codes[1] = codes[0];
    103             codes[0] = primaryCode;
    104         }
    105     }
    106 
    107     /**
    108      * Delete the last keystroke as a result of hitting backspace.
    109      */
    110     public void deleteLast() {
    111         mCodes.remove(mCodes.size() - 1);
    112         final int lastPos = mTypedWord.length() - 1;
    113         char last = mTypedWord.charAt(lastPos);
    114         mTypedWord.deleteCharAt(lastPos);
    115         if (Character.isUpperCase(last)) mCapsCount--;
    116     }
    117 
    118     /**
    119      * Returns the word as it was typed, without any correction applied.
    120      * @return the word that was typed so far
    121      */
    122     public CharSequence getTypedWord() {
    123         int wordSize = mCodes.size();
    124         if (wordSize == 0) {
    125             return null;
    126         }
    127 //        StringBuffer sb = new StringBuffer(wordSize);
    128 //        for (int i = 0; i < wordSize; i++) {
    129 //            char c = (char) mCodes.get(i)[0];
    130 //            if (i == 0 && mIsCapitalized) {
    131 //                c = Character.toUpperCase(c);
    132 //            }
    133 //            sb.append(c);
    134 //        }
    135 //        return sb;
    136         return mTypedWord;
    137     }
    138 
    139     public void setCapitalized(boolean capitalized) {
    140         mIsCapitalized = capitalized;
    141     }
    142 
    143     /**
    144      * Whether or not the user typed a capital letter as the first letter in the word
    145      * @return capitalization preference
    146      */
    147     public boolean isCapitalized() {
    148         return mIsCapitalized;
    149     }
    150 
    151     /**
    152      * Stores the user's selected word, before it is actually committed to the text field.
    153      * @param preferred
    154      */
    155     public void setPreferredWord(String preferred) {
    156         mPreferredWord = preferred;
    157     }
    158 
    159     /**
    160      * Return the word chosen by the user, or the typed word if no other word was chosen.
    161      * @return the preferred word
    162      */
    163     public CharSequence getPreferredWord() {
    164         return mPreferredWord != null ? mPreferredWord : getTypedWord();
    165     }
    166 
    167     /**
    168      * Returns true if more than one character is upper case, otherwise returns false.
    169      */
    170     public boolean isMostlyCaps() {
    171         return mCapsCount > 1;
    172     }
    173 
    174     /**
    175      * Saves the reason why the word is capitalized - whether it was automatic or
    176      * due to the user hitting shift in the middle of a sentence.
    177      * @param auto whether it was an automatic capitalization due to start of sentence
    178      */
    179     public void setAutoCapitalized(boolean auto) {
    180         mAutoCapitalized = auto;
    181     }
    182 
    183     /**
    184      * Returns whether the word was automatically capitalized.
    185      * @return whether the word was automatically capitalized
    186      */
    187     public boolean isAutoCapitalized() {
    188         return mAutoCapitalized;
    189     }
    190 }
    191