WordComposer.java revision 5c641a9f59735f0eaa772bde027993275b1bdfd7
1923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project/* 2443c360d0afdbab091994244f045f4756feaf2b4Jean-Baptiste Queru * Copyright (C) 2008 The Android Open Source Project 30fd625bcfdfac1c10e7bd7f9088bf425fec08989Jean Chalard * 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 70fd625bcfdfac1c10e7bd7f9088bf425fec08989Jean Chalard * 8923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 90fd625bcfdfac1c10e7bd7f9088bf425fec08989Jean Chalard * 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 196b1f500da451de56932a8b2a99c63857994ece85Jean Chalardimport com.android.inputmethod.keyboard.Key; 20887f11ee43ad621aa6ad93d535ab7f48dec73fc7Tadashi G. Takaokaimport com.android.inputmethod.keyboard.KeyDetector; 213708787fe91227083d2a1874fa41493d3bc9fe10Tadashi G. Takaokaimport com.android.inputmethod.keyboard.Keyboard; 22887f11ee43ad621aa6ad93d535ab7f48dec73fc7Tadashi G. Takaoka 23c83359f9746ca6f0269a1a7017b585c1a5cab9b8Jean Chalardimport java.util.Arrays; 24923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 25923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project/** 26923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * A place to store the currently composing word with information such as adjacent key codes as well 27923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */ 28923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectpublic class WordComposer { 298fbd55229243cb66c03d5ea1f79dfb39f596590dsatok 30887f11ee43ad621aa6ad93d535ab7f48dec73fc7Tadashi G. Takaoka public static final int NOT_A_CODE = KeyDetector.NOT_A_CODE; 318fbd55229243cb66c03d5ea1f79dfb39f596590dsatok public static final int NOT_A_COORDINATE = -1; 32887f11ee43ad621aa6ad93d535ab7f48dec73fc7Tadashi G. Takaoka 3301ab7c8b59a7f12862fbd95fb252e56719f1757fsatok private static final int N = BinaryDictionary.MAX_WORD_LENGTH; 348fbd55229243cb66c03d5ea1f79dfb39f596590dsatok 3501ab7c8b59a7f12862fbd95fb252e56719f1757fsatok private int[] mPrimaryKeyCodes; 3671538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka private final InputPointers mInputPointers = new InputPointers(); 37be79227dc99421ff7be62224c51c553b3fa73777Jean Chalard private StringBuilder mTypedWord; 38be79227dc99421ff7be62224c51c553b3fa73777Jean Chalard private CharSequence mAutoCorrection; 394b5b46bb66bf74ef5edd65c55e186b02f3c56e5dJean Chalard private boolean mIsResumed; 404a7ff90d513f8b6cbf39688c08be0828a57e311bAmith Yamasani 41be79227dc99421ff7be62224c51c553b3fa73777Jean Chalard // Cache these values for performance 424a7ff90d513f8b6cbf39688c08be0828a57e311bAmith Yamasani private int mCapsCount; 431c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani private boolean mAutoCapitalized; 44117fc18ed46496c81596f8207bba30a09c7317d1Jean Chalard private int mTrailingSingleQuotesCount; 4501ab7c8b59a7f12862fbd95fb252e56719f1757fsatok private int mCodePointSize; 46c83359f9746ca6f0269a1a7017b585c1a5cab9b8Jean Chalard 47923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project /** 480b4ae1f578e768eec4ada90aeb81d11acb10eb2eKen Wakasa * Whether the user chose to capitalize the first char of the word. 49923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */ 500b4ae1f578e768eec4ada90aeb81d11acb10eb2eKen Wakasa private boolean mIsFirstCharCapitalized; 51923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 52979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public WordComposer() { 5301ab7c8b59a7f12862fbd95fb252e56719f1757fsatok mPrimaryKeyCodes = new int[N]; 54be79227dc99421ff7be62224c51c553b3fa73777Jean Chalard mTypedWord = new StringBuilder(N); 55be79227dc99421ff7be62224c51c553b3fa73777Jean Chalard mAutoCorrection = null; 56117fc18ed46496c81596f8207bba30a09c7317d1Jean Chalard mTrailingSingleQuotesCount = 0; 574b5b46bb66bf74ef5edd65c55e186b02f3c56e5dJean Chalard mIsResumed = false; 5801ab7c8b59a7f12862fbd95fb252e56719f1757fsatok refreshSize(); 59923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 60923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 61f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok public WordComposer(WordComposer source) { 629fbfd5877305ed19a20663630b498b6b3fdae942satok init(source); 639fbfd5877305ed19a20663630b498b6b3fdae942satok } 649fbfd5877305ed19a20663630b498b6b3fdae942satok 659fbfd5877305ed19a20663630b498b6b3fdae942satok public void init(WordComposer source) { 6601ab7c8b59a7f12862fbd95fb252e56719f1757fsatok mPrimaryKeyCodes = Arrays.copyOf(source.mPrimaryKeyCodes, source.mPrimaryKeyCodes.length); 67be79227dc99421ff7be62224c51c553b3fa73777Jean Chalard mTypedWord = new StringBuilder(source.mTypedWord); 6871538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka mInputPointers.copy(source.mInputPointers); 69ea843f2a2404f4bc04fda494e475520162cfca27Tadashi G. Takaoka mCapsCount = source.mCapsCount; 70ea843f2a2404f4bc04fda494e475520162cfca27Tadashi G. Takaoka mIsFirstCharCapitalized = source.mIsFirstCharCapitalized; 71ea843f2a2404f4bc04fda494e475520162cfca27Tadashi G. Takaoka mAutoCapitalized = source.mAutoCapitalized; 72117fc18ed46496c81596f8207bba30a09c7317d1Jean Chalard mTrailingSingleQuotesCount = source.mTrailingSingleQuotesCount; 734b5b46bb66bf74ef5edd65c55e186b02f3c56e5dJean Chalard mIsResumed = source.mIsResumed; 7401ab7c8b59a7f12862fbd95fb252e56719f1757fsatok refreshSize(); 75979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 76979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 77923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project /** 78923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Clear out the keys registered so far. 79923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */ 80923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void reset() { 81be79227dc99421ff7be62224c51c553b3fa73777Jean Chalard mTypedWord.setLength(0); 82be79227dc99421ff7be62224c51c553b3fa73777Jean Chalard mAutoCorrection = null; 834a7ff90d513f8b6cbf39688c08be0828a57e311bAmith Yamasani mCapsCount = 0; 84ea843f2a2404f4bc04fda494e475520162cfca27Tadashi G. Takaoka mIsFirstCharCapitalized = false; 85117fc18ed46496c81596f8207bba30a09c7317d1Jean Chalard mTrailingSingleQuotesCount = 0; 864b5b46bb66bf74ef5edd65c55e186b02f3c56e5dJean Chalard mIsResumed = false; 8701ab7c8b59a7f12862fbd95fb252e56719f1757fsatok refreshSize(); 8801ab7c8b59a7f12862fbd95fb252e56719f1757fsatok } 8901ab7c8b59a7f12862fbd95fb252e56719f1757fsatok 90e55c23e4b0b8d9d66349a3b275d0fa1540d7450aKen Wakasa private final void refreshSize() { 9101ab7c8b59a7f12862fbd95fb252e56719f1757fsatok mCodePointSize = mTypedWord.codePointCount(0, mTypedWord.length()); 92923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 93923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 94923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project /** 95923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Number of keystrokes in the composing word. 96923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * @return the number of keystrokes 97923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */ 98ea843f2a2404f4bc04fda494e475520162cfca27Tadashi G. Takaoka public final int size() { 9901ab7c8b59a7f12862fbd95fb252e56719f1757fsatok return mCodePointSize; 100923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 101923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 102196d82cdd740580ed79d801483dbc282be85d076Jean Chalard public final boolean isComposingWord() { 10301ab7c8b59a7f12862fbd95fb252e56719f1757fsatok return size() > 0; 104196d82cdd740580ed79d801483dbc282be85d076Jean Chalard } 105196d82cdd740580ed79d801483dbc282be85d076Jean Chalard 1069611b281e18ac71d825ff5bc771a111423772cb3satok // TODO: make sure that the index should not exceed MAX_WORD_LENGTH 10701ab7c8b59a7f12862fbd95fb252e56719f1757fsatok public int getCodeAt(int index) { 1089611b281e18ac71d825ff5bc771a111423772cb3satok if (index >= BinaryDictionary.MAX_WORD_LENGTH) { 1099611b281e18ac71d825ff5bc771a111423772cb3satok return -1; 1109611b281e18ac71d825ff5bc771a111423772cb3satok } 11101ab7c8b59a7f12862fbd95fb252e56719f1757fsatok return mPrimaryKeyCodes[index]; 112923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 113923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 11471538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka public InputPointers getInputPointers() { 11571538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka return mInputPointers; 1168fbd55229243cb66c03d5ea1f79dfb39f596590dsatok } 1178fbd55229243cb66c03d5ea1f79dfb39f596590dsatok 118ea843f2a2404f4bc04fda494e475520162cfca27Tadashi G. Takaoka private static boolean isFirstCharCapitalized(int index, int codePoint, boolean previous) { 119ea843f2a2404f4bc04fda494e475520162cfca27Tadashi G. Takaoka if (index == 0) return Character.isUpperCase(codePoint); 120436a645ea837d36f7e0f81948d343fa6e166f33aTadashi G. Takaoka return previous && !Character.isUpperCase(codePoint); 121ea843f2a2404f4bc04fda494e475520162cfca27Tadashi G. Takaoka } 122ea843f2a2404f4bc04fda494e475520162cfca27Tadashi G. Takaoka 123923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project /** 124c61cd79229b1871d0f603a23389695d7f7751e66Tadashi G. Takaoka * Add a new keystroke, with the pressed key's code point with the touch point coordinates. 125923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */ 1265c641a9f59735f0eaa772bde027993275b1bdfd7Tadashi G. Takaoka public void add(int primaryCode, int keyX, int keyY) { 12701ab7c8b59a7f12862fbd95fb252e56719f1757fsatok final int newIndex = size(); 1289159b9953d857de83ae2f90a121fcd259f5ee01dJean Chalard mTypedWord.appendCodePoint(primaryCode); 12901ab7c8b59a7f12862fbd95fb252e56719f1757fsatok refreshSize(); 130ea843f2a2404f4bc04fda494e475520162cfca27Tadashi G. Takaoka if (newIndex < BinaryDictionary.MAX_WORD_LENGTH) { 13167094f5bdece00994f70c6f1fa9a6ff7b8f3c3c1satok mPrimaryKeyCodes[newIndex] = primaryCode >= Keyboard.CODE_SPACE 13267094f5bdece00994f70c6f1fa9a6ff7b8f3c3c1satok ? Character.toLowerCase(primaryCode) : primaryCode; 13371538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka // TODO: Set correct pointer id and time 13471538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka mInputPointers.addPointer(newIndex, keyX, keyY, 0, 0); 1358fbd55229243cb66c03d5ea1f79dfb39f596590dsatok } 136ea843f2a2404f4bc04fda494e475520162cfca27Tadashi G. Takaoka mIsFirstCharCapitalized = isFirstCharCapitalized( 137ea843f2a2404f4bc04fda494e475520162cfca27Tadashi G. Takaoka newIndex, primaryCode, mIsFirstCharCapitalized); 138ea843f2a2404f4bc04fda494e475520162cfca27Tadashi G. Takaoka if (Character.isUpperCase(primaryCode)) mCapsCount++; 139117fc18ed46496c81596f8207bba30a09c7317d1Jean Chalard if (Keyboard.CODE_SINGLE_QUOTE == primaryCode) { 140117fc18ed46496c81596f8207bba30a09c7317d1Jean Chalard ++mTrailingSingleQuotesCount; 141117fc18ed46496c81596f8207bba30a09c7317d1Jean Chalard } else { 142117fc18ed46496c81596f8207bba30a09c7317d1Jean Chalard mTrailingSingleQuotesCount = 0; 143117fc18ed46496c81596f8207bba30a09c7317d1Jean Chalard } 144be79227dc99421ff7be62224c51c553b3fa73777Jean Chalard mAutoCorrection = null; 145923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 146923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 147923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project /** 1486b1f500da451de56932a8b2a99c63857994ece85Jean Chalard * Internal method to retrieve reasonable proximity info for a character. 1496b1f500da451de56932a8b2a99c63857994ece85Jean Chalard */ 150a492790982c6d7df62f66344db30b31995800e1bJean Chalard private void addKeyInfo(final int codePoint, final Keyboard keyboard) { 1516b1f500da451de56932a8b2a99c63857994ece85Jean Chalard for (final Key key : keyboard.mKeys) { 1526b1f500da451de56932a8b2a99c63857994ece85Jean Chalard if (key.mCode == codePoint) { 1536b1f500da451de56932a8b2a99c63857994ece85Jean Chalard final int x = key.mX + key.mWidth / 2; 1546b1f500da451de56932a8b2a99c63857994ece85Jean Chalard final int y = key.mY + key.mHeight / 2; 1556ba8de2a608dfe4865b0b59a753f2d2abbedeeffsatok add(codePoint, x, y); 1566b1f500da451de56932a8b2a99c63857994ece85Jean Chalard return; 1576b1f500da451de56932a8b2a99c63857994ece85Jean Chalard } 1586b1f500da451de56932a8b2a99c63857994ece85Jean Chalard } 1596ba8de2a608dfe4865b0b59a753f2d2abbedeeffsatok add(codePoint, WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE); 1606b1f500da451de56932a8b2a99c63857994ece85Jean Chalard } 1616b1f500da451de56932a8b2a99c63857994ece85Jean Chalard 1626b1f500da451de56932a8b2a99c63857994ece85Jean Chalard /** 1636b1f500da451de56932a8b2a99c63857994ece85Jean Chalard * Set the currently composing word to the one passed as an argument. 1646b1f500da451de56932a8b2a99c63857994ece85Jean Chalard * This will register NOT_A_COORDINATE for X and Ys, and use the passed keyboard for proximity. 1656b1f500da451de56932a8b2a99c63857994ece85Jean Chalard */ 166a492790982c6d7df62f66344db30b31995800e1bJean Chalard public void setComposingWord(final CharSequence word, final Keyboard keyboard) { 1676b1f500da451de56932a8b2a99c63857994ece85Jean Chalard reset(); 1686b1f500da451de56932a8b2a99c63857994ece85Jean Chalard final int length = word.length(); 1699159b9953d857de83ae2f90a121fcd259f5ee01dJean Chalard for (int i = 0; i < length; i = Character.offsetByCodePoints(word, i, 1)) { 1709159b9953d857de83ae2f90a121fcd259f5ee01dJean Chalard int codePoint = Character.codePointAt(word, i); 171a492790982c6d7df62f66344db30b31995800e1bJean Chalard addKeyInfo(codePoint, keyboard); 1726b1f500da451de56932a8b2a99c63857994ece85Jean Chalard } 1734b5b46bb66bf74ef5edd65c55e186b02f3c56e5dJean Chalard mIsResumed = true; 1746b1f500da451de56932a8b2a99c63857994ece85Jean Chalard } 1756b1f500da451de56932a8b2a99c63857994ece85Jean Chalard 1766b1f500da451de56932a8b2a99c63857994ece85Jean Chalard /** 177923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Delete the last keystroke as a result of hitting backspace. 178923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */ 179923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void deleteLast() { 18001ab7c8b59a7f12862fbd95fb252e56719f1757fsatok final int size = size(); 181ea843f2a2404f4bc04fda494e475520162cfca27Tadashi G. Takaoka if (size > 0) { 1829159b9953d857de83ae2f90a121fcd259f5ee01dJean Chalard // Note: mTypedWord.length() and mCodes.length differ when there are surrogate pairs 1839159b9953d857de83ae2f90a121fcd259f5ee01dJean Chalard final int stringBuilderLength = mTypedWord.length(); 1849159b9953d857de83ae2f90a121fcd259f5ee01dJean Chalard if (stringBuilderLength < size) { 1859159b9953d857de83ae2f90a121fcd259f5ee01dJean Chalard throw new RuntimeException( 1869159b9953d857de83ae2f90a121fcd259f5ee01dJean Chalard "In WordComposer: mCodes and mTypedWords have non-matching lengths"); 1879159b9953d857de83ae2f90a121fcd259f5ee01dJean Chalard } 1889159b9953d857de83ae2f90a121fcd259f5ee01dJean Chalard final int lastChar = mTypedWord.codePointBefore(stringBuilderLength); 1899159b9953d857de83ae2f90a121fcd259f5ee01dJean Chalard if (Character.isSupplementaryCodePoint(lastChar)) { 1909159b9953d857de83ae2f90a121fcd259f5ee01dJean Chalard mTypedWord.delete(stringBuilderLength - 2, stringBuilderLength); 1919159b9953d857de83ae2f90a121fcd259f5ee01dJean Chalard } else { 1929159b9953d857de83ae2f90a121fcd259f5ee01dJean Chalard mTypedWord.deleteCharAt(stringBuilderLength - 1); 1939159b9953d857de83ae2f90a121fcd259f5ee01dJean Chalard } 194ea843f2a2404f4bc04fda494e475520162cfca27Tadashi G. Takaoka if (Character.isUpperCase(lastChar)) mCapsCount--; 19501ab7c8b59a7f12862fbd95fb252e56719f1757fsatok refreshSize(); 196d1a8e3088bb6267a31e3351d304796d1507e3af6Tadashi G. Takaoka } 1979159b9953d857de83ae2f90a121fcd259f5ee01dJean Chalard // We may have deleted the last one. 19801ab7c8b59a7f12862fbd95fb252e56719f1757fsatok if (0 == size()) { 199ea843f2a2404f4bc04fda494e475520162cfca27Tadashi G. Takaoka mIsFirstCharCapitalized = false; 200117fc18ed46496c81596f8207bba30a09c7317d1Jean Chalard } 201117fc18ed46496c81596f8207bba30a09c7317d1Jean Chalard if (mTrailingSingleQuotesCount > 0) { 202117fc18ed46496c81596f8207bba30a09c7317d1Jean Chalard --mTrailingSingleQuotesCount; 203c83359f9746ca6f0269a1a7017b585c1a5cab9b8Jean Chalard } else { 204825e2bbd910cce3055a4ca808d3744bc0b2ceddaJean Chalard int i = mTypedWord.length(); 205825e2bbd910cce3055a4ca808d3744bc0b2ceddaJean Chalard while (i > 0) { 206825e2bbd910cce3055a4ca808d3744bc0b2ceddaJean Chalard i = mTypedWord.offsetByCodePoints(i, -1); 207be79227dc99421ff7be62224c51c553b3fa73777Jean Chalard if (Keyboard.CODE_SINGLE_QUOTE != mTypedWord.codePointAt(i)) break; 208117fc18ed46496c81596f8207bba30a09c7317d1Jean Chalard ++mTrailingSingleQuotesCount; 209117fc18ed46496c81596f8207bba30a09c7317d1Jean Chalard } 2108fbd55229243cb66c03d5ea1f79dfb39f596590dsatok } 211be79227dc99421ff7be62224c51c553b3fa73777Jean Chalard mAutoCorrection = null; 212923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 213923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 214923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project /** 215923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Returns the word as it was typed, without any correction applied. 216117fc93f373cb86d4120c1261f9d0562c6529fecJean Chalard * @return the word that was typed so far. Never returns null. 217923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */ 2185c08151c227d98031abe27c3f0a8f43a7126ae9dJean Chalard public String getTypedWord() { 219be79227dc99421ff7be62224c51c553b3fa73777Jean Chalard return mTypedWord.toString(); 220923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 221923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 222923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project /** 223923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Whether or not the user typed a capital letter as the first letter in the word 224923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * @return capitalization preference 225923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */ 2260b4ae1f578e768eec4ada90aeb81d11acb10eb2eKen Wakasa public boolean isFirstCharCapitalized() { 2270b4ae1f578e768eec4ada90aeb81d11acb10eb2eKen Wakasa return mIsFirstCharCapitalized; 228923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2290b4ae1f578e768eec4ada90aeb81d11acb10eb2eKen Wakasa 230117fc18ed46496c81596f8207bba30a09c7317d1Jean Chalard public int trailingSingleQuotesCount() { 231117fc18ed46496c81596f8207bba30a09c7317d1Jean Chalard return mTrailingSingleQuotesCount; 232c83359f9746ca6f0269a1a7017b585c1a5cab9b8Jean Chalard } 233c83359f9746ca6f0269a1a7017b585c1a5cab9b8Jean Chalard 2340b4ae1f578e768eec4ada90aeb81d11acb10eb2eKen Wakasa /** 2350b4ae1f578e768eec4ada90aeb81d11acb10eb2eKen Wakasa * Whether or not all of the user typed chars are upper case 2360b4ae1f578e768eec4ada90aeb81d11acb10eb2eKen Wakasa * @return true if all user typed chars are upper case, false otherwise 2370b4ae1f578e768eec4ada90aeb81d11acb10eb2eKen Wakasa */ 2380b4ae1f578e768eec4ada90aeb81d11acb10eb2eKen Wakasa public boolean isAllUpperCase() { 2390b4ae1f578e768eec4ada90aeb81d11acb10eb2eKen Wakasa return (mCapsCount > 0) && (mCapsCount == size()); 2400b4ae1f578e768eec4ada90aeb81d11acb10eb2eKen Wakasa } 2410b4ae1f578e768eec4ada90aeb81d11acb10eb2eKen Wakasa 242923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project /** 2434a7ff90d513f8b6cbf39688c08be0828a57e311bAmith Yamasani * Returns true if more than one character is upper case, otherwise returns false. 2444a7ff90d513f8b6cbf39688c08be0828a57e311bAmith Yamasani */ 2454a7ff90d513f8b6cbf39688c08be0828a57e311bAmith Yamasani public boolean isMostlyCaps() { 2464a7ff90d513f8b6cbf39688c08be0828a57e311bAmith Yamasani return mCapsCount > 1; 2474a7ff90d513f8b6cbf39688c08be0828a57e311bAmith Yamasani } 2481c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani 2490fd625bcfdfac1c10e7bd7f9088bf425fec08989Jean Chalard /** 2501c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani * Saves the reason why the word is capitalized - whether it was automatic or 2511c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani * due to the user hitting shift in the middle of a sentence. 2521c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani * @param auto whether it was an automatic capitalization due to start of sentence 2531c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani */ 2541c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani public void setAutoCapitalized(boolean auto) { 2551c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani mAutoCapitalized = auto; 2561c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani } 2571c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani 2581c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani /** 2591c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani * Returns whether the word was automatically capitalized. 2601c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani * @return whether the word was automatically capitalized 2611c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani */ 2621c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani public boolean isAutoCapitalized() { 2631c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani return mAutoCapitalized; 2641c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani } 265117fc93f373cb86d4120c1261f9d0562c6529fecJean Chalard 266117fc93f373cb86d4120c1261f9d0562c6529fecJean Chalard /** 267117fc93f373cb86d4120c1261f9d0562c6529fecJean Chalard * Sets the auto-correction for this word. 268117fc93f373cb86d4120c1261f9d0562c6529fecJean Chalard */ 269117fc93f373cb86d4120c1261f9d0562c6529fecJean Chalard public void setAutoCorrection(final CharSequence correction) { 270be79227dc99421ff7be62224c51c553b3fa73777Jean Chalard mAutoCorrection = correction; 271117fc93f373cb86d4120c1261f9d0562c6529fecJean Chalard } 272117fc93f373cb86d4120c1261f9d0562c6529fecJean Chalard 273117fc93f373cb86d4120c1261f9d0562c6529fecJean Chalard /** 274f7d6517d6b1a1dd88e2142e1a15703bb839be01bJean Chalard * @return the auto-correction for this word, or null if none. 275117fc93f373cb86d4120c1261f9d0562c6529fecJean Chalard */ 276117fc93f373cb86d4120c1261f9d0562c6529fecJean Chalard public CharSequence getAutoCorrectionOrNull() { 277be79227dc99421ff7be62224c51c553b3fa73777Jean Chalard return mAutoCorrection; 278117fc93f373cb86d4120c1261f9d0562c6529fecJean Chalard } 279c73c26790fa9dcd836a918774d6efa39a05c0152Jean Chalard 2804b5b46bb66bf74ef5edd65c55e186b02f3c56e5dJean Chalard /** 2814b5b46bb66bf74ef5edd65c55e186b02f3c56e5dJean Chalard * @return whether we started composing this word by resuming suggestion on an existing string 2824b5b46bb66bf74ef5edd65c55e186b02f3c56e5dJean Chalard */ 2834b5b46bb66bf74ef5edd65c55e186b02f3c56e5dJean Chalard public boolean isResumed() { 2844b5b46bb66bf74ef5edd65c55e186b02f3c56e5dJean Chalard return mIsResumed; 2854b5b46bb66bf74ef5edd65c55e186b02f3c56e5dJean Chalard } 2864b5b46bb66bf74ef5edd65c55e186b02f3c56e5dJean Chalard 287267563d1bb4d8091293fbd8774f0f95ef59f03c4Jean Chalard // `type' should be one of the LastComposedWord.COMMIT_TYPE_* constants above. 28866bb563535dbe3672f99f75bd71763a551444867Jean Chalard public LastComposedWord commitWord(final int type, final String committedWord, 289c54d558e2e70bdfb2c1078cae7b88440d421dc67satok final int separatorCode, final CharSequence prevWord) { 2909271b770e81350e232c351f76f9f7a2ec23dff5fJean Chalard // Note: currently, we come here whenever we commit a word. If it's a MANUAL_PICK 2919271b770e81350e232c351f76f9f7a2ec23dff5fJean Chalard // or a DECIDED_WORD we may cancel the commit later; otherwise, we should deactivate 2929271b770e81350e232c351f76f9f7a2ec23dff5fJean Chalard // the last composed word to ensure this does not happen. 29301ab7c8b59a7f12862fbd95fb252e56719f1757fsatok final int[] primaryKeyCodes = mPrimaryKeyCodes; 29401ab7c8b59a7f12862fbd95fb252e56719f1757fsatok mPrimaryKeyCodes = new int[N]; 29501ab7c8b59a7f12862fbd95fb252e56719f1757fsatok final LastComposedWord lastComposedWord = new LastComposedWord(primaryKeyCodes, 29671538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka mInputPointers, mTypedWord.toString(), committedWord, separatorCode, 297c54d558e2e70bdfb2c1078cae7b88440d421dc67satok prevWord); 29871538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka mInputPointers.reset(); 2999271b770e81350e232c351f76f9f7a2ec23dff5fJean Chalard if (type != LastComposedWord.COMMIT_TYPE_DECIDED_WORD 3009271b770e81350e232c351f76f9f7a2ec23dff5fJean Chalard && type != LastComposedWord.COMMIT_TYPE_MANUAL_PICK) { 301449415c72f437f523a49a9ccfcde8a3c0f583a18Jean Chalard lastComposedWord.deactivate(); 302449415c72f437f523a49a9ccfcde8a3c0f583a18Jean Chalard } 303be79227dc99421ff7be62224c51c553b3fa73777Jean Chalard mTypedWord.setLength(0); 30401ab7c8b59a7f12862fbd95fb252e56719f1757fsatok refreshSize(); 305be79227dc99421ff7be62224c51c553b3fa73777Jean Chalard mAutoCorrection = null; 3064b5b46bb66bf74ef5edd65c55e186b02f3c56e5dJean Chalard mIsResumed = false; 3071f8fc62ccb5018716457dc309ab11ad3e1506ad1Jean Chalard return lastComposedWord; 308c73c26790fa9dcd836a918774d6efa39a05c0152Jean Chalard } 309c73c26790fa9dcd836a918774d6efa39a05c0152Jean Chalard 3102712f23acbb197af3b125da4cc47108e71b7446dJean Chalard public void resumeSuggestionOnLastComposedWord(final LastComposedWord lastComposedWord) { 31101ab7c8b59a7f12862fbd95fb252e56719f1757fsatok mPrimaryKeyCodes = lastComposedWord.mPrimaryKeyCodes; 31271538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka mInputPointers.set(lastComposedWord.mInputPointers); 313be79227dc99421ff7be62224c51c553b3fa73777Jean Chalard mTypedWord.setLength(0); 314be79227dc99421ff7be62224c51c553b3fa73777Jean Chalard mTypedWord.append(lastComposedWord.mTypedWord); 31501ab7c8b59a7f12862fbd95fb252e56719f1757fsatok refreshSize(); 316cf9d92629cae88273805eaf7984fcfdd8afd11f5Jean Chalard mAutoCorrection = null; // This will be filled by the next call to updateSuggestion. 3174b5b46bb66bf74ef5edd65c55e186b02f3c56e5dJean Chalard mIsResumed = true; 3189e8761c4402ddc11c942ed2e583bd7d58f70c5eaJean Chalard } 319923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project} 320