• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008,2009  OMRON SOFTWARE Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of 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,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package jp.co.omronsoft.openwnn.JAJP;
18 
19 import jp.co.omronsoft.openwnn.*;
20 import android.view.KeyEvent;
21 import android.view.inputmethod.EditorInfo;
22 import android.view.inputmethod.InputConnection;
23 import android.inputmethodservice.Keyboard;
24 import android.util.Log;
25 import android.view.View;
26 import android.content.SharedPreferences;
27 import java.util.HashMap;
28 import java.util.Locale;
29 import java.util.List;
30 
31 /**
32  * The default Software Keyboard class for Japanese IME.
33  *
34  * @author Copyright (C) 2009 OMRON SOFTWARE CO., LTD.  All Rights Reserved.
35  */
36 public class DefaultSoftKeyboardJAJP extends DefaultSoftKeyboard {
37     /** Enable English word prediction on half-width alphabet mode */
38     private static final boolean USE_ENGLISH_PREDICT = true;
39 
40     /** Key code for switching to full-width HIRAGANA mode */
41     private static final int KEYCODE_SWITCH_FULL_HIRAGANA = -301;
42 
43     /** Key code for switching to full-width KATAKANA mode */
44     private static final int KEYCODE_SWITCH_FULL_KATAKANA = -302;
45 
46     /** Key code for switching to full-width alphabet mode */
47     private static final int KEYCODE_SWITCH_FULL_ALPHABET = -303;
48 
49     /** Key code for switching to full-width number mode */
50     private static final int KEYCODE_SWITCH_FULL_NUMBER = -304;
51 
52     /** Key code for switching to half-width KATAKANA mode */
53     private static final int KEYCODE_SWITCH_HALF_KATAKANA = -306;
54 
55     /** Key code for switching to half-width alphabet mode */
56     private static final int KEYCODE_SWITCH_HALF_ALPHABET = -307;
57 
58     /** Key code for switching to half-width number mode */
59     private static final int KEYCODE_SWITCH_HALF_NUMBER = -308;
60 
61     /** Key code for case toggle key */
62     private static final int KEYCODE_SELECT_CASE = -309;
63 
64     /** Key code for EISU-KANA conversion */
65     private static final int KEYCODE_EISU_KANA = -305;
66 
67     /** Key code for NOP (no-operation) */
68     private static final int KEYCODE_NOP = -310;
69 
70 
71     /** Input mode toggle cycle table */
72     private static final int[] JP_MODE_CYCLE_TABLE = {
73         KEYMODE_JA_FULL_HIRAGANA, KEYMODE_JA_HALF_ALPHABET, KEYMODE_JA_HALF_NUMBER
74     };
75 
76     /** Definition for {@code mInputType} (toggle) */
77     private static final int INPUT_TYPE_TOGGLE = 1;
78 
79     /** Definition for {@code mInputType} (commit instantly) */
80     private static final int INPUT_TYPE_INSTANT = 2;
81 
82     /** Max key number of the 12 key keyboard (depends on the definition of keyboards) */
83     private static final int KEY_NUMBER_12KEY = 20;
84 
85     /** Toggle cycle table for full-width HIRAGANA */
86     private static final String[][] JP_FULL_HIRAGANA_CYCLE_TABLE = {
87         {"\u3042", "\u3044", "\u3046", "\u3048", "\u304a", "\u3041", "\u3043", "\u3045", "\u3047", "\u3049"},
88         {"\u304b", "\u304d", "\u304f", "\u3051", "\u3053"},
89         {"\u3055", "\u3057", "\u3059", "\u305b", "\u305d"},
90         {"\u305f", "\u3061", "\u3064", "\u3066", "\u3068", "\u3063"},
91         {"\u306a", "\u306b", "\u306c", "\u306d", "\u306e"},
92         {"\u306f", "\u3072", "\u3075", "\u3078", "\u307b"},
93         {"\u307e", "\u307f", "\u3080", "\u3081", "\u3082"},
94         {"\u3084", "\u3086", "\u3088", "\u3083", "\u3085", "\u3087"},
95         {"\u3089", "\u308a", "\u308b", "\u308c", "\u308d"},
96         {"\u308f", "\u3092", "\u3093", "\u308e", "\u30fc"},
97         {"\u3001", "\u3002", "\uff1f", "\uff01", "\u30fb", "\u3000"},
98     };
99 
100     /** Replace table for full-width HIRAGANA */
101     private static final HashMap<String, String> JP_FULL_HIRAGANA_REPLACE_TABLE = new HashMap<String, String>() {{
102           put("\u3042", "\u3041"); put("\u3044", "\u3043"); put("\u3046", "\u3045"); put("\u3048", "\u3047"); put("\u304a", "\u3049");
103           put("\u3041", "\u3042"); put("\u3043", "\u3044"); put("\u3045", "\u30f4"); put("\u3047", "\u3048"); put("\u3049", "\u304a");
104           put("\u304b", "\u304c"); put("\u304d", "\u304e"); put("\u304f", "\u3050"); put("\u3051", "\u3052"); put("\u3053", "\u3054");
105           put("\u304c", "\u304b"); put("\u304e", "\u304d"); put("\u3050", "\u304f"); put("\u3052", "\u3051"); put("\u3054", "\u3053");
106           put("\u3055", "\u3056"); put("\u3057", "\u3058"); put("\u3059", "\u305a"); put("\u305b", "\u305c"); put("\u305d", "\u305e");
107           put("\u3056", "\u3055"); put("\u3058", "\u3057"); put("\u305a", "\u3059"); put("\u305c", "\u305b"); put("\u305e", "\u305d");
108           put("\u305f", "\u3060"); put("\u3061", "\u3062"); put("\u3064", "\u3063"); put("\u3066", "\u3067"); put("\u3068", "\u3069");
109           put("\u3060", "\u305f"); put("\u3062", "\u3061"); put("\u3063", "\u3065"); put("\u3067", "\u3066"); put("\u3069", "\u3068");
110           put("\u3065", "\u3064"); put("\u30f4", "\u3046");
111           put("\u306f", "\u3070"); put("\u3072", "\u3073"); put("\u3075", "\u3076"); put("\u3078", "\u3079"); put("\u307b", "\u307c");
112           put("\u3070", "\u3071"); put("\u3073", "\u3074"); put("\u3076", "\u3077"); put("\u3079", "\u307a"); put("\u307c", "\u307d");
113           put("\u3071", "\u306f"); put("\u3074", "\u3072"); put("\u3077", "\u3075"); put("\u307a", "\u3078"); put("\u307d", "\u307b");
114           put("\u3084", "\u3083"); put("\u3086", "\u3085"); put("\u3088", "\u3087");
115           put("\u3083", "\u3084"); put("\u3085", "\u3086"); put("\u3087", "\u3088");
116           put("\u308f", "\u308e");
117           put("\u308e", "\u308f");
118           put("\u309b", "\u309c");
119           put("\u309c", "\u309b");
120     }};
121 
122     /** Toggle cycle table for full-width KATAKANA */
123     private static final String[][] JP_FULL_KATAKANA_CYCLE_TABLE = {
124         {"\u30a2", "\u30a4", "\u30a6", "\u30a8", "\u30aa", "\u30a1", "\u30a3",
125          "\u30a5", "\u30a7", "\u30a9"},
126         {"\u30ab", "\u30ad", "\u30af", "\u30b1", "\u30b3"},
127         {"\u30b5", "\u30b7", "\u30b9", "\u30bb", "\u30bd"},
128         {"\u30bf", "\u30c1", "\u30c4", "\u30c6", "\u30c8", "\u30c3"},
129         {"\u30ca", "\u30cb", "\u30cc", "\u30cd", "\u30ce"},
130         {"\u30cf", "\u30d2", "\u30d5", "\u30d8", "\u30db"},
131         {"\u30de", "\u30df", "\u30e0", "\u30e1", "\u30e2"},
132         {"\u30e4", "\u30e6", "\u30e8", "\u30e3", "\u30e5", "\u30e7"},
133         {"\u30e9", "\u30ea", "\u30eb", "\u30ec", "\u30ed"},
134         {"\u30ef", "\u30f2", "\u30f3", "\u30ee", "\u30fc"},
135         {"\u3001", "\u3002", "\uff1f", "\uff01", "\u30fb", "\u3000"}
136     };
137 
138     /** Replace table for full-width KATAKANA */
139     private static final HashMap<String,String> JP_FULL_KATAKANA_REPLACE_TABLE = new HashMap<String,String>() {{
140         put("\u30a2", "\u30a1"); put("\u30a4", "\u30a3"); put("\u30a6", "\u30a5"); put("\u30a8", "\u30a7"); put("\u30aa", "\u30a9");
141         put("\u30a1", "\u30a2"); put("\u30a3", "\u30a4"); put("\u30a5", "\u30f4"); put("\u30a7", "\u30a8"); put("\u30a9", "\u30aa");
142         put("\u30ab", "\u30ac"); put("\u30ad", "\u30ae"); put("\u30af", "\u30b0"); put("\u30b1", "\u30b2"); put("\u30b3", "\u30b4");
143         put("\u30ac", "\u30ab"); put("\u30ae", "\u30ad"); put("\u30b0", "\u30af"); put("\u30b2", "\u30b1"); put("\u30b4", "\u30b3");
144         put("\u30b5", "\u30b6"); put("\u30b7", "\u30b8"); put("\u30b9", "\u30ba"); put("\u30bb", "\u30bc"); put("\u30bd", "\u30be");
145         put("\u30b6", "\u30b5"); put("\u30b8", "\u30b7"); put("\u30ba", "\u30b9"); put("\u30bc", "\u30bb"); put("\u30be", "\u30bd");
146         put("\u30bf", "\u30c0"); put("\u30c1", "\u30c2"); put("\u30c4", "\u30c3"); put("\u30c6", "\u30c7"); put("\u30c8", "\u30c9");
147         put("\u30c0", "\u30bf"); put("\u30c2", "\u30c1"); put("\u30c3", "\u30c5"); put("\u30c7", "\u30c6"); put("\u30c9", "\u30c8");
148         put("\u30c5", "\u30c4"); put("\u30f4", "\u30a6");
149         put("\u30cf", "\u30d0"); put("\u30d2", "\u30d3"); put("\u30d5", "\u30d6"); put("\u30d8", "\u30d9"); put("\u30db", "\u30dc");
150         put("\u30d0", "\u30d1"); put("\u30d3", "\u30d4"); put("\u30d6", "\u30d7"); put("\u30d9", "\u30da"); put("\u30dc", "\u30dd");
151         put("\u30d1", "\u30cf"); put("\u30d4", "\u30d2"); put("\u30d7", "\u30d5"); put("\u30da", "\u30d8"); put("\u30dd", "\u30db");
152         put("\u30e4", "\u30e3"); put("\u30e6", "\u30e5"); put("\u30e8", "\u30e7");
153         put("\u30e3", "\u30e4"); put("\u30e5", "\u30e6"); put("\u30e7", "\u30e8");
154         put("\u30ef", "\u30ee");
155         put("\u30ee", "\u30ef");
156     }};
157 
158     /** Toggle cycle table for half-width KATAKANA */
159     private static final String[][] JP_HALF_KATAKANA_CYCLE_TABLE = {
160         {"\uff71", "\uff72", "\uff73", "\uff74", "\uff75", "\uff67", "\uff68", "\uff69", "\uff6a", "\uff6b"},
161         {"\uff76", "\uff77", "\uff78", "\uff79", "\uff7a"},
162         {"\uff7b", "\uff7c", "\uff7d", "\uff7e", "\uff7f"},
163         {"\uff80", "\uff81", "\uff82", "\uff83", "\uff84", "\uff6f"},
164         {"\uff85", "\uff86", "\uff87", "\uff88", "\uff89"},
165         {"\uff8a", "\uff8b", "\uff8c", "\uff8d", "\uff8e"},
166         {"\uff8f", "\uff90", "\uff91", "\uff92", "\uff93"},
167         {"\uff94", "\uff95", "\uff96", "\uff6c", "\uff6d", "\uff6e"},
168         {"\uff97", "\uff98", "\uff99", "\uff9a", "\uff9b"},
169         {"\uff9c", "\uff66", "\uff9d", "\uff70"},
170         {"\uff64", "\uff61", "?", "!", "\uff65", " "},
171     };
172 
173     /** Replace table for half-width KATAKANA */
174     private static final HashMap<String,String> JP_HALF_KATAKANA_REPLACE_TABLE = new HashMap<String,String>() {{
175         put("\uff71", "\uff67");  put("\uff72", "\uff68");  put("\uff73", "\uff69");  put("\uff74", "\uff6a");  put("\uff75", "\uff6b");
176         put("\uff67", "\uff71");  put("\uff68", "\uff72");  put("\uff69", "\uff73\uff9e");  put("\uff6a", "\uff74");  put("\uff6b", "\uff75");
177         put("\uff76", "\uff76\uff9e"); put("\uff77", "\uff77\uff9e"); put("\uff78", "\uff78\uff9e"); put("\uff79", "\uff79\uff9e"); put("\uff7a", "\uff7a\uff9e");
178         put("\uff76\uff9e", "\uff76"); put("\uff77\uff9e", "\uff77"); put("\uff78\uff9e", "\uff78"); put("\uff79\uff9e", "\uff79"); put("\uff7a\uff9e", "\uff7a");
179         put("\uff7b", "\uff7b\uff9e"); put("\uff7c", "\uff7c\uff9e"); put("\uff7d", "\uff7d\uff9e"); put("\uff7e", "\uff7e\uff9e"); put("\uff7f", "\uff7f\uff9e");
180         put("\uff7b\uff9e", "\uff7b"); put("\uff7c\uff9e", "\uff7c"); put("\uff7d\uff9e", "\uff7d"); put("\uff7e\uff9e", "\uff7e"); put("\uff7f\uff9e", "\uff7f");
181         put("\uff80", "\uff80\uff9e"); put("\uff81", "\uff81\uff9e"); put("\uff82", "\uff6f");  put("\uff83", "\uff83\uff9e"); put("\uff84", "\uff84\uff9e");
182         put("\uff80\uff9e", "\uff80"); put("\uff81\uff9e", "\uff81"); put("\uff6f", "\uff82\uff9e"); put("\uff83\uff9e", "\uff83"); put("\uff84\uff9e", "\uff84");
183         put("\uff82\uff9e", "\uff82");
184         put("\uff8a", "\uff8a\uff9e"); put("\uff8b", "\uff8b\uff9e"); put("\uff8c", "\uff8c\uff9e"); put("\uff8d", "\uff8d\uff9e"); put("\uff8e", "\uff8e\uff9e");
185         put("\uff8a\uff9e", "\uff8a\uff9f");put("\uff8b\uff9e", "\uff8b\uff9f");put("\uff8c\uff9e", "\uff8c\uff9f");put("\uff8d\uff9e", "\uff8d\uff9f");put("\uff8e\uff9e", "\uff8e\uff9f");
186         put("\uff8a\uff9f", "\uff8a"); put("\uff8b\uff9f", "\uff8b"); put("\uff8c\uff9f", "\uff8c"); put("\uff8d\uff9f", "\uff8d"); put("\uff8e\uff9f", "\uff8e");
187         put("\uff94", "\uff6c");  put("\uff95", "\uff6d");  put("\uff96", "\uff6e");
188         put("\uff6c", "\uff94");  put("\uff6d", "\uff95");  put("\uff6e", "\uff96");
189         put("\uff9c", "\uff9c"); put("\uff73\uff9e", "\uff73");
190     }};
191 
192     /** Toggle cycle table for full-width alphabet */
193     private static final String[][] JP_FULL_ALPHABET_CYCLE_TABLE = {
194         {"\uff0e", "\uff20", "\uff0d", "\uff3f", "\uff0f", "\uff1a", "\uff5e", "\uff11"},
195         {"\uff41", "\uff42", "\uff43", "\uff21", "\uff22", "\uff23", "\uff12"},
196         {"\uff44", "\uff45", "\uff46", "\uff24", "\uff25", "\uff26", "\uff13"},
197         {"\uff47", "\uff48", "\uff49", "\uff27", "\uff28", "\uff29", "\uff14"},
198         {"\uff4a", "\uff4b", "\uff4c", "\uff2a", "\uff2b", "\uff2c", "\uff15"},
199         {"\uff4d", "\uff4e", "\uff4f", "\uff2d", "\uff2e", "\uff2f", "\uff16"},
200         {"\uff50", "\uff51", "\uff52", "\uff53", "\uff30", "\uff31", "\uff32", "\uff33", "\uff17"},
201         {"\uff54", "\uff55", "\uff56", "\uff34", "\uff35", "\uff36", "\uff18"},
202         {"\uff57", "\uff58", "\uff59", "\uff5a", "\uff37", "\uff38", "\uff39", "\uff3a", "\uff19"},
203         {"\uff0d", "\uff10"},
204         {"\uff0c", "\uff0e", "\uff1f", "\uff01", "\u30fb", "\u3000"}
205     };
206 
207     /** Replace table for full-width alphabet */
208     private static final HashMap<String,String> JP_FULL_ALPHABET_REPLACE_TABLE = new HashMap<String,String>() {{
209         put("\uff21", "\uff41"); put("\uff22", "\uff42"); put("\uff23", "\uff43"); put("\uff24", "\uff44"); put("\uff25", "\uff45");
210         put("\uff41", "\uff21"); put("\uff42", "\uff22"); put("\uff43", "\uff23"); put("\uff44", "\uff24"); put("\uff45", "\uff25");
211         put("\uff26", "\uff46"); put("\uff27", "\uff47"); put("\uff28", "\uff48"); put("\uff29", "\uff49"); put("\uff2a", "\uff4a");
212         put("\uff46", "\uff26"); put("\uff47", "\uff27"); put("\uff48", "\uff28"); put("\uff49", "\uff29"); put("\uff4a", "\uff2a");
213         put("\uff2b", "\uff4b"); put("\uff2c", "\uff4c"); put("\uff2d", "\uff4d"); put("\uff2e", "\uff4e"); put("\uff2f", "\uff4f");
214         put("\uff4b", "\uff2b"); put("\uff4c", "\uff2c"); put("\uff4d", "\uff2d"); put("\uff4e", "\uff2e"); put("\uff4f", "\uff2f");
215         put("\uff30", "\uff50"); put("\uff31", "\uff51"); put("\uff32", "\uff52"); put("\uff33", "\uff53"); put("\uff34", "\uff54");
216         put("\uff50", "\uff30"); put("\uff51", "\uff31"); put("\uff52", "\uff32"); put("\uff53", "\uff33"); put("\uff54", "\uff34");
217         put("\uff35", "\uff55"); put("\uff36", "\uff56"); put("\uff37", "\uff57"); put("\uff38", "\uff58"); put("\uff39", "\uff59");
218         put("\uff55", "\uff35"); put("\uff56", "\uff36"); put("\uff57", "\uff37"); put("\uff58", "\uff38"); put("\uff59", "\uff39");
219         put("\uff3a", "\uff5a");
220         put("\uff5a", "\uff3a");
221     }};
222 
223     /** Toggle cycle table for half-width alphabet */
224     private static final String[][] JP_HALF_ALPHABET_CYCLE_TABLE = {
225         {".", "@", "-", "_", "/", ":", "~", "1"},
226         {"a", "b", "c", "A", "B", "C", "2"},
227         {"d", "e", "f", "D", "E", "F", "3"},
228         {"g", "h", "i", "G", "H", "I", "4"},
229         {"j", "k", "l", "J", "K", "L", "5"},
230         {"m", "n", "o", "M", "N", "O", "6"},
231         {"p", "q", "r", "s", "P", "Q", "R", "S", "7"},
232         {"t", "u", "v", "T", "U", "V", "8"},
233         {"w", "x", "y", "z", "W", "X", "Y", "Z", "9"},
234         {"-", "0"},
235         {",", ".", "?", "!", ";", " "}
236     };
237 
238     /** Replace table for half-width alphabet */
239     private static final HashMap<String,String> JP_HALF_ALPHABET_REPLACE_TABLE = new HashMap<String,String>() {{
240         put("A", "a"); put("B", "b"); put("C", "c"); put("D", "d"); put("E", "e");
241         put("a", "A"); put("b", "B"); put("c", "C"); put("d", "D"); put("e", "E");
242         put("F", "f"); put("G", "g"); put("H", "h"); put("I", "i"); put("J", "j");
243         put("f", "F"); put("g", "G"); put("h", "H"); put("i", "I"); put("j", "J");
244         put("K", "k"); put("L", "l"); put("M", "m"); put("N", "n"); put("O", "o");
245         put("k", "K"); put("l", "L"); put("m", "M"); put("n", "N"); put("o", "O");
246         put("P", "p"); put("Q", "q"); put("R", "r"); put("S", "s"); put("T", "t");
247         put("p", "P"); put("q", "Q"); put("r", "R"); put("s", "S"); put("t", "T");
248         put("U", "u"); put("V", "v"); put("W", "w"); put("X", "x"); put("Y", "y");
249         put("u", "U"); put("v", "V"); put("w", "W"); put("x", "X"); put("y", "Y");
250         put("Z", "z");
251         put("z", "Z");
252     }};
253 
254     /** Character table for full-width number */
255     private static final char[] INSTANT_CHAR_CODE_FULL_NUMBER =
256         "\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18\uff19\uff10\uff03\uff0a".toCharArray();
257 
258     /** Character table for half-width number */
259     private static final char[] INSTANT_CHAR_CODE_HALF_NUMBER =
260         "1234567890#*".toCharArray();
261 
262     /** The constant for mFixedKeyMode. It means that input mode is not fixed. */
263     private static final int INVALID_KEYMODE = -1;
264 
265     /** KeyIndex of "Moji" key on 12 keyboard (depends on the definition of keyboards) */
266     private static final int KEY_INDEX_CHANGE_MODE_12KEY = 15;
267 
268     /** KeyIndex of "Moji" key on QWERTY keyboard (depends on the definition of keyboards) */
269     private static final int KEY_INDEX_CHANGE_MODE_QWERTY = 29;
270 
271     /** Type of input mode */
272     private int mInputType = INPUT_TYPE_TOGGLE;
273 
274     /** Previous input character code */
275     private int mPrevInputKeyCode = 0;
276 
277     /**
278      * Character table to input when mInputType becomes INPUT_TYPE_INSTANT.
279      * (Either INSTANT_CHAR_CODE_FULL_NUMBER or INSTANT_CHAR_CODE_HALF_NUMBER)
280      */
281     private char[] mCurrentInstantTable = null;
282 
283     /** Input mode that is not able to be changed. If ENABLE_CHANGE_KEYMODE is set, input mode can change. */
284     private int[] mLimitedKeyMode = null;
285 
286     /** Input mode that is given the first priority. If ENABLE_CHANGE_KEYMODE is set, input mode can change. */
287     private int mPreferenceKeyMode = INVALID_KEYMODE;
288 
289     /** The last input type */
290     private int mLastInputType = 0;
291 
292     /** Auto caps mode */
293     private boolean mEnableAutoCaps = true;
294 
295     /** PopupResId of "Moji" key (this is used for canceling long-press) */
296     private int mPopupResId = 0;
297 
298     /** Whether the InputType is null */
299     private boolean mIsInputTypeNull = false;
300 
301     /** {@code SharedPreferences} for save the keyboard type */
302     private SharedPreferences.Editor mPrefEditor = null;
303 
304     /** "Moji" key (this is used for canceling long-press) */
305     private Keyboard.Key mChangeModeKey = null;
306 
307 
308     /** Default constructor */
DefaultSoftKeyboardJAJP()309     public DefaultSoftKeyboardJAJP() {
310         mCurrentLanguage     = LANG_JA;
311         mCurrentKeyboardType = KEYBOARD_12KEY;
312         mShiftOn             = KEYBOARD_SHIFT_OFF;
313         mCurrentKeyMode      = KEYMODE_JA_FULL_HIRAGANA;
314     }
315 
316     /** @see jp.co.omronsoft.openwnn.DefaultSoftKeyboard#createKeyboards */
createKeyboards(OpenWnn parent)317     @Override protected void createKeyboards(OpenWnn parent) {
318 
319         /* Keyboard[# of Languages][portrait/landscape][# of keyboard type][shift off/on][max # of key-modes][noinput/input] */
320         mKeyboard = new Keyboard[3][2][4][2][8][2];
321 
322         if (mHardKeyboardHidden) {
323             /* Create the suitable keyboard object */
324             if (mDisplayMode == DefaultSoftKeyboard.PORTRAIT) {
325                 createKeyboardsPortrait(parent);
326             } else {
327                 createKeyboardsLandscape(parent);
328             }
329 
330             if (mCurrentKeyboardType == KEYBOARD_12KEY) {
331                 mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.CHANGE_MODE,
332                                               OpenWnnJAJP.ENGINE_MODE_OPT_TYPE_12KEY));
333             } else {
334                 mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.CHANGE_MODE,
335                                               OpenWnnJAJP.ENGINE_MODE_OPT_TYPE_QWERTY));
336             }
337         } else {
338             mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.CHANGE_MODE,
339                                           OpenWnnJAJP.ENGINE_MODE_OPT_TYPE_QWERTY));
340         }
341     }
342 
343     /**
344      * Commit the pre-edit string for committing operation that is not explicit
345      * (ex. when a candidate is selected)
346      */
commitText()347     private void commitText() {
348         if (!mNoInput) {
349             mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.COMMIT_COMPOSING_TEXT));
350         }
351     }
352 
353     /**
354      * Change input mode
355      * <br>
356      * @param keyMode   The type of input mode
357      */
changeKeyMode(int keyMode)358     public void changeKeyMode(int keyMode) {
359         int targetMode = filterKeyMode(keyMode);
360         if (targetMode == INVALID_KEYMODE) {
361             return;
362         }
363 
364         commitText();
365 
366         if (mCapsLock) {
367             mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.INPUT_SOFT_KEY,
368                                           new KeyEvent(KeyEvent.ACTION_UP,
369                                                        KeyEvent.KEYCODE_SHIFT_LEFT)));
370             mCapsLock = false;
371         }
372         mShiftOn = KEYBOARD_SHIFT_OFF;
373         Keyboard kbd = getModeChangeKeyboard(targetMode);
374         mCurrentKeyMode = targetMode;
375         mPrevInputKeyCode = 0;
376 
377         int mode = OpenWnnEvent.Mode.DIRECT;
378 
379         switch (targetMode) {
380         case KEYMODE_JA_FULL_HIRAGANA:
381             mInputType = INPUT_TYPE_TOGGLE;
382             mode = OpenWnnEvent.Mode.DEFAULT;
383             break;
384 
385         case KEYMODE_JA_HALF_ALPHABET:
386             if (USE_ENGLISH_PREDICT) {
387                 mInputType = INPUT_TYPE_TOGGLE;
388                 mode = OpenWnnEvent.Mode.NO_LV1_CONV;
389             } else {
390                 mInputType = INPUT_TYPE_TOGGLE;
391                 mode = OpenWnnEvent.Mode.DIRECT;
392             }
393             break;
394 
395         case KEYMODE_JA_FULL_NUMBER:
396             mInputType = INPUT_TYPE_INSTANT;
397             mode = OpenWnnEvent.Mode.DIRECT;
398             mCurrentInstantTable = INSTANT_CHAR_CODE_FULL_NUMBER;
399             break;
400 
401         case KEYMODE_JA_HALF_NUMBER:
402             mInputType = INPUT_TYPE_INSTANT;
403             mode = OpenWnnEvent.Mode.DIRECT;
404             mCurrentInstantTable = INSTANT_CHAR_CODE_HALF_NUMBER;
405             break;
406 
407         case KEYMODE_JA_FULL_KATAKANA:
408             mInputType = INPUT_TYPE_TOGGLE;
409             mode = OpenWnnJAJP.ENGINE_MODE_FULL_KATAKANA;
410             break;
411 
412         case KEYMODE_JA_FULL_ALPHABET:
413             mInputType = INPUT_TYPE_TOGGLE;
414             mode = OpenWnnEvent.Mode.DIRECT;
415             break;
416 
417         case KEYMODE_JA_HALF_KATAKANA:
418             mInputType = INPUT_TYPE_TOGGLE;
419             mode = OpenWnnJAJP.ENGINE_MODE_HALF_KATAKANA;
420             break;
421 
422         default:
423             break;
424         }
425 
426         setStatusIcon();
427         changeKeyboard(kbd);
428         mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.CHANGE_MODE, mode));
429     }
430 
431      /** @see jp.co.omronsoft.openwnn.DefaultSoftKeyboard#initView */
initView(OpenWnn parent, int width, int height)432      @Override public View initView(OpenWnn parent, int width, int height) {
433 
434         View view = super.initView(parent, width, height);
435         changeKeyboard(mKeyboard[mCurrentLanguage][mDisplayMode][mCurrentKeyboardType][mShiftOn][mCurrentKeyMode][0]);
436 
437         return view;
438      }
439 
440     /** @see jp.co.omronsoft.openwnn.DefaultSoftKeyboard#changeKeyboard */
changeKeyboard(Keyboard keyboard)441     @Override protected boolean changeKeyboard(Keyboard keyboard) {
442         if (keyboard != null) {
443             if (mIsInputTypeNull) {
444                 mChangeModeKey.popupResId = mPopupResId;
445             }
446 
447             List<Keyboard.Key> keys = keyboard.getKeys();
448             int keyIndex = (KEY_NUMBER_12KEY < keys.size())
449                 ? KEY_INDEX_CHANGE_MODE_QWERTY : KEY_INDEX_CHANGE_MODE_12KEY;
450             mChangeModeKey = keys.get(keyIndex);
451 
452             if (mIsInputTypeNull) {
453                 mPopupResId = mChangeModeKey.popupResId;
454                 mChangeModeKey.popupResId = 0;
455             }
456         }
457 
458         return super.changeKeyboard(keyboard);
459     }
460 
461     /** @see jp.co.omronsoft.openwnn.DefaultSoftKeyboard#changeKeyboardType */
changeKeyboardType(int type)462     @Override public void changeKeyboardType(int type) {
463         commitText();
464         Keyboard kbd = getTypeChangeKeyboard(type);
465         if (kbd != null) {
466             mCurrentKeyboardType = type;
467             mPrefEditor.putBoolean("opt_enable_qwerty", type == KEYBOARD_QWERTY);
468             mPrefEditor.commit();
469             changeKeyboard(kbd);
470         }
471         if (type == KEYBOARD_12KEY) {
472             mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.CHANGE_MODE, OpenWnnJAJP.ENGINE_MODE_OPT_TYPE_12KEY));
473         } else {
474             mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.CHANGE_MODE, OpenWnnJAJP.ENGINE_MODE_OPT_TYPE_QWERTY));
475         }
476     }
477 
478     /** @see jp.co.omronsoft.openwnn.DefaultSoftKeyboard#onKey */
onKey(int primaryCode, int[] keyCodes)479     @Override public void onKey(int primaryCode, int[] keyCodes) {
480 
481         if (mDisableKeyInput) {
482             return;
483         }
484 
485         switch (primaryCode) {
486         case KEYCODE_JP12_TOGGLE_MODE:
487         case KEYCODE_QWERTY_TOGGLE_MODE:
488             if (!mIsInputTypeNull) {
489                 nextKeyMode();
490             }
491             break;
492 
493         case DefaultSoftKeyboard.KEYCODE_QWERTY_BACKSPACE:
494         case KEYCODE_JP12_BACKSPACE:
495             mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.INPUT_SOFT_KEY,
496                                           new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL)));
497             break;
498 
499         case DefaultSoftKeyboard.KEYCODE_QWERTY_SHIFT:
500             toggleShiftLock();
501             break;
502 
503         case DefaultSoftKeyboard.KEYCODE_QWERTY_ALT:
504             processAltKey();
505             break;
506 
507         case KEYCODE_QWERTY_ENTER:
508         case KEYCODE_JP12_ENTER:
509             mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.INPUT_SOFT_KEY,
510                                           new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER)));
511             break;
512 
513         case KEYCODE_JP12_REVERSE:
514             if (!mNoInput) {
515                 mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.TOGGLE_REVERSE_CHAR, mCurrentCycleTable));
516             }
517             break;
518 
519         case KEYCODE_QWERTY_KBD:
520             changeKeyboardType(KEYBOARD_12KEY);
521             break;
522 
523         case KEYCODE_JP12_KBD:
524             changeKeyboardType(KEYBOARD_QWERTY);
525             break;
526 
527         case KEYCODE_JP12_EMOJI:
528         case KEYCODE_QWERTY_EMOJI:
529                 commitText();
530                 mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.CHANGE_MODE, OpenWnnJAJP.ENGINE_MODE_SYMBOL));
531             break;
532 
533         case KEYCODE_JP12_1:
534         case KEYCODE_JP12_2:
535         case KEYCODE_JP12_3:
536         case KEYCODE_JP12_4:
537         case KEYCODE_JP12_5:
538         case KEYCODE_JP12_6:
539         case KEYCODE_JP12_7:
540         case KEYCODE_JP12_8:
541         case KEYCODE_JP12_9:
542         case KEYCODE_JP12_0:
543         case KEYCODE_JP12_SHARP:
544             /* Processing to input by ten key */
545             if (mInputType == INPUT_TYPE_INSTANT) {
546                 /* Send a input character directly if instant input type is selected */
547                 commitText();
548                 mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.INPUT_CHAR,
549                                               mCurrentInstantTable[getTableIndex(primaryCode)]));
550             } else {
551                 if ((mPrevInputKeyCode != primaryCode)) {
552                     mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.TOUCH_OTHER_KEY));
553                     if ((mCurrentKeyMode == KEYMODE_JA_HALF_ALPHABET)
554                             && (primaryCode == KEYCODE_JP12_SHARP)) {
555                         /* Commit text by symbol character (',' '.') when alphabet input mode is selected */
556                         commitText();
557                     }
558                 }
559 
560                 /* Convert the key code to the table index and send the toggle event with the table index */
561                 String[][] cycleTable = getCycleTable();
562                 if (cycleTable == null) {
563                     Log.e("OpenWnn", "not founds cycle table");
564                 } else {
565                     int index = getTableIndex(primaryCode);
566                     mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.TOGGLE_CHAR, cycleTable[index]));
567                     mCurrentCycleTable = cycleTable[index];
568                 }
569                 mPrevInputKeyCode = primaryCode;
570             }
571             break;
572 
573         case KEYCODE_JP12_ASTER:
574             if (mInputType == INPUT_TYPE_INSTANT) {
575                 commitText();
576                 mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.INPUT_CHAR,
577                                               mCurrentInstantTable[getTableIndex(primaryCode)]));
578             } else {
579                 if (!mNoInput) {
580                     /* Processing to toggle Dakuten, Handakuten, and capital */
581                     HashMap replaceTable = getReplaceTable();
582                     if (replaceTable == null) {
583                         Log.e("OpenWnn", "not founds replace table");
584                     } else {
585                         mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.REPLACE_CHAR, replaceTable));
586                         mPrevInputKeyCode = primaryCode;
587                     }
588                 }
589             }
590             break;
591 
592         case KEYCODE_SWITCH_FULL_HIRAGANA:
593             /* Change mode to Full width hiragana */
594             changeKeyMode(KEYMODE_JA_FULL_HIRAGANA);
595             break;
596 
597         case KEYCODE_SWITCH_FULL_KATAKANA:
598             /* Change mode to Full width katakana */
599             changeKeyMode(KEYMODE_JA_FULL_KATAKANA);
600             break;
601 
602         case KEYCODE_SWITCH_FULL_ALPHABET:
603             /* Change mode to Full width alphabet */
604             changeKeyMode(KEYMODE_JA_FULL_ALPHABET);
605             break;
606 
607         case KEYCODE_SWITCH_FULL_NUMBER:
608             /* Change mode to Full width numeric */
609             changeKeyMode(KEYMODE_JA_FULL_NUMBER);
610             break;
611 
612         case KEYCODE_SWITCH_HALF_KATAKANA:
613             /* Change mode to Half width katakana */
614             changeKeyMode(KEYMODE_JA_HALF_KATAKANA);
615             break;
616 
617         case KEYCODE_SWITCH_HALF_ALPHABET:
618             /* Change mode to Half width alphabet */
619             changeKeyMode(KEYMODE_JA_HALF_ALPHABET);
620             break;
621 
622         case KEYCODE_SWITCH_HALF_NUMBER:
623             /* Change mode to Half width numeric */
624             changeKeyMode(KEYMODE_JA_HALF_NUMBER);
625             break;
626 
627 
628         case KEYCODE_SELECT_CASE:
629             int shifted = (mShiftOn == 0) ? 1 : 0;
630             Keyboard newKeyboard = getShiftChangeKeyboard(shifted);
631             if (newKeyboard != null) {
632                 mShiftOn = shifted;
633                 changeKeyboard(newKeyboard);
634             }
635             break;
636 
637         case KEYCODE_JP12_SPACE:
638             if ((mCurrentKeyMode == KEYMODE_JA_FULL_HIRAGANA) && !mNoInput) {
639                 mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.CONVERT));
640             } else {
641                 mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.INPUT_CHAR, ' '));
642             }
643             break;
644 
645         case KEYCODE_EISU_KANA:
646             mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.CHANGE_MODE, OpenWnnJAJP.ENGINE_MODE_EISU_KANA));
647             break;
648 
649         case KEYCODE_JP12_CLOSE:
650             mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.INPUT_KEY,
651                                           new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK)));
652             break;
653 
654         case KEYCODE_JP12_LEFT:
655             mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.INPUT_SOFT_KEY,
656                                           new KeyEvent(KeyEvent.ACTION_DOWN,
657                                                        KeyEvent.KEYCODE_DPAD_LEFT)));
658             break;
659 
660         case KEYCODE_JP12_RIGHT:
661             mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.INPUT_SOFT_KEY,
662                                           new KeyEvent(KeyEvent.ACTION_DOWN,
663                                                        KeyEvent.KEYCODE_DPAD_RIGHT)));
664             break;
665         case KEYCODE_NOP:
666             break;
667 
668         default:
669             if (primaryCode >= 0) {
670                 if (mKeyboardView.isShifted()) {
671                     primaryCode = Character.toUpperCase(primaryCode);
672                 }
673                 mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.INPUT_CHAR, (char)primaryCode));
674             }
675             break;
676         }
677 
678         /* update shift key's state */
679         if (!mCapsLock && (primaryCode != DefaultSoftKeyboard.KEYCODE_QWERTY_SHIFT)) {
680             setShiftByEditorInfo();
681         }
682     }
683 
684     /** @see jp.co.omronsoft.openwnn.DefaultSoftKeyboard#setPreferences */
setPreferences(SharedPreferences pref, EditorInfo editor)685     @Override public void setPreferences(SharedPreferences pref, EditorInfo editor) {
686         mPrefEditor = pref.edit();
687         boolean isQwerty = pref.getBoolean("opt_enable_qwerty", false);
688         if (isQwerty && (mCurrentKeyboardType == KEYBOARD_12KEY)) {
689             changeKeyboardType(KEYBOARD_QWERTY);
690         }
691 
692         super.setPreferences(pref, editor);
693 
694         int inputType = editor.inputType;
695         if (mHardKeyboardHidden) {
696             if (inputType == EditorInfo.TYPE_NULL) {
697                 if (!mIsInputTypeNull) {
698                     mIsInputTypeNull = true;
699                     mPopupResId = mChangeModeKey.popupResId;
700                     mChangeModeKey.popupResId = 0;
701                 }
702                 return;
703             }
704 
705             if (mIsInputTypeNull) {
706                 mIsInputTypeNull = false;
707                 mChangeModeKey.popupResId = mPopupResId;
708             }
709         }
710 
711         mEnableAutoCaps = pref.getBoolean("auto_caps", true);
712         mLimitedKeyMode = null;
713         mPreferenceKeyMode = INVALID_KEYMODE;
714         mNoInput = true;
715         mDisableKeyInput = false;
716         mCapsLock = false;
717 
718         switch (inputType & EditorInfo.TYPE_MASK_CLASS) {
719 
720         case EditorInfo.TYPE_CLASS_NUMBER:
721         case EditorInfo.TYPE_CLASS_DATETIME:
722             mPreferenceKeyMode = KEYMODE_JA_HALF_NUMBER;
723             break;
724 
725         case EditorInfo.TYPE_CLASS_PHONE:
726             if (mHardKeyboardHidden) {
727                 mLimitedKeyMode = new int[] {KEYMODE_JA_HALF_PHONE};
728             } else {
729                 mLimitedKeyMode = new int[] {KEYMODE_JA_HALF_ALPHABET};
730             }
731             break;
732 
733         case EditorInfo.TYPE_CLASS_TEXT:
734             switch (inputType & EditorInfo.TYPE_MASK_VARIATION) {
735 
736             case EditorInfo.TYPE_TEXT_VARIATION_PASSWORD:
737                 mLimitedKeyMode = new int[] {KEYMODE_JA_HALF_ALPHABET, KEYMODE_JA_HALF_NUMBER};
738                 break;
739 
740             case EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS:
741                 mLimitedKeyMode = new int[] {KEYMODE_JA_HALF_ALPHABET, KEYMODE_JA_HALF_NUMBER};
742                 break;
743             case EditorInfo.TYPE_TEXT_VARIATION_URI:
744                 mPreferenceKeyMode = KEYMODE_JA_HALF_ALPHABET;
745                 break;
746 
747             default:
748                 break;
749             }
750             break;
751 
752         default:
753             break;
754         }
755 
756         if (inputType != mLastInputType) {
757             setDefaultKeyboard();
758             mLastInputType = inputType;
759         }
760 
761         setStatusIcon();
762         setShiftByEditorInfo();
763     }
764 
765     /** @see jp.co.omronsoft.openwnn.DefaultSoftKeyboard#onUpdateState */
onUpdateState(OpenWnn parent)766     @Override public void onUpdateState(OpenWnn parent) {
767         super.onUpdateState(parent);
768         if (!mCapsLock) {
769             setShiftByEditorInfo();
770         }
771     }
772 
773     /**
774      * Change the keyboard to default
775      */
setDefaultKeyboard()776     public void setDefaultKeyboard() {
777         Locale locale = Locale.getDefault();
778         int keymode = KEYMODE_JA_FULL_HIRAGANA;
779 
780         if (mPreferenceKeyMode != INVALID_KEYMODE) {
781             keymode = mPreferenceKeyMode;
782         } else if (mLimitedKeyMode != null) {
783             keymode = mLimitedKeyMode[0];
784         } else {
785             if (!locale.getLanguage().equals(Locale.JAPANESE.getLanguage())) {
786                 keymode = KEYMODE_JA_HALF_ALPHABET;
787             }
788         }
789         changeKeyMode(keymode);
790     }
791 
792 
793     /**
794      * Change to the next input mode
795      */
nextKeyMode()796     public void nextKeyMode() {
797         /* Search the current mode in the toggle table */
798         boolean found = false;
799         int index;
800         for (index = 0; index < JP_MODE_CYCLE_TABLE.length; index++) {
801             if (JP_MODE_CYCLE_TABLE[index] == mCurrentKeyMode) {
802                 found = true;
803                 break;
804             }
805         }
806 
807         if (!found) {
808             /* If the current mode not exists, set the default mode */
809             setDefaultKeyboard();
810         } else {
811             /* If the current mode exists, set the next input mode */
812             int size = JP_MODE_CYCLE_TABLE.length;
813             int keyMode = INVALID_KEYMODE;
814             for (int i = 0; i < size; i++) {
815                 index = (++index) % size;
816 
817                 keyMode = filterKeyMode(JP_MODE_CYCLE_TABLE[index]);
818                 if (keyMode != INVALID_KEYMODE) {
819                     break;
820                 }
821             }
822 
823             if (keyMode != INVALID_KEYMODE) {
824                 changeKeyMode(keyMode);
825             }
826         }
827     }
828 
829     /**
830      * Create the keyboard for portrait mode
831      * <br>
832      * @param parent  The context
833      */
createKeyboardsPortrait(OpenWnn parent)834     private void createKeyboardsPortrait(OpenWnn parent) {
835         Keyboard[][] keyList;
836         /* qwerty shift_off (portrait) */
837         keyList = mKeyboard[LANG_JA][PORTRAIT][KEYBOARD_QWERTY][KEYBOARD_SHIFT_OFF];
838         keyList[KEYMODE_JA_FULL_HIRAGANA][0] = new Keyboard(parent, R.xml.keyboard_qwerty_jp);
839         keyList[KEYMODE_JA_FULL_ALPHABET][0] = new Keyboard(parent, R.xml.keyboard_qwerty_jp_full_alphabet);
840         keyList[KEYMODE_JA_FULL_NUMBER][0]   = new Keyboard(parent, R.xml.keyboard_qwerty_jp_full_symbols);
841         keyList[KEYMODE_JA_FULL_KATAKANA][0] = new Keyboard(parent, R.xml.keyboard_qwerty_jp_full_katakana);
842         keyList[KEYMODE_JA_HALF_ALPHABET][0] = new Keyboard(parent, R.xml.keyboard_qwerty_jp_half_alphabet);
843         keyList[KEYMODE_JA_HALF_NUMBER][0]   = new Keyboard(parent, R.xml.keyboard_qwerty_jp_half_symbols);
844         keyList[KEYMODE_JA_HALF_KATAKANA][0] = new Keyboard(parent, R.xml.keyboard_qwerty_jp_half_katakana);
845         keyList[KEYMODE_JA_HALF_PHONE][0]    = new Keyboard(parent, R.xml.keyboard_12key_phone);
846 
847         /* qwerty shift_on (portrait) */
848         keyList = mKeyboard[LANG_JA][PORTRAIT][KEYBOARD_QWERTY][KEYBOARD_SHIFT_ON];
849         keyList[KEYMODE_JA_FULL_HIRAGANA][0] = new Keyboard(parent, R.xml.keyboard_qwerty_jp_shift);
850         keyList[KEYMODE_JA_FULL_ALPHABET][0] = new Keyboard(parent, R.xml.keyboard_qwerty_jp_full_alphabet_shift);
851         keyList[KEYMODE_JA_FULL_NUMBER][0]   = new Keyboard(parent, R.xml.keyboard_qwerty_jp_full_symbols_shift);
852         keyList[KEYMODE_JA_FULL_KATAKANA][0] = new Keyboard(parent, R.xml.keyboard_qwerty_jp_full_katakana_shift);
853         keyList[KEYMODE_JA_HALF_ALPHABET][0] = new Keyboard(parent, R.xml.keyboard_qwerty_jp_half_alphabet_shift);
854         keyList[KEYMODE_JA_HALF_NUMBER][0]   = new Keyboard(parent, R.xml.keyboard_qwerty_jp_half_symbols_shift);
855         keyList[KEYMODE_JA_HALF_KATAKANA][0] = new Keyboard(parent, R.xml.keyboard_qwerty_jp_half_katakana_shift);
856         keyList[KEYMODE_JA_HALF_PHONE][0] =
857             mKeyboard[LANG_JA][PORTRAIT][KEYBOARD_QWERTY][KEYBOARD_SHIFT_OFF][KEYMODE_JA_HALF_PHONE][0];
858 
859 
860         /* 12-keys shift_off (portrait) */
861         keyList = mKeyboard[LANG_JA][PORTRAIT][KEYBOARD_12KEY][KEYBOARD_SHIFT_OFF];
862         keyList[KEYMODE_JA_FULL_HIRAGANA][0] = new Keyboard(parent, R.xml.keyboard_12keyjp);
863         keyList[KEYMODE_JA_FULL_HIRAGANA][1] = new Keyboard(parent, R.xml.keyboard_12keyjp_input);
864         keyList[KEYMODE_JA_FULL_ALPHABET][0] = new Keyboard(parent, R.xml.keyboard_12key_full_alphabet);
865         keyList[KEYMODE_JA_FULL_ALPHABET][1] = new Keyboard(parent, R.xml.keyboard_12key_full_alphabet_input);
866         keyList[KEYMODE_JA_FULL_NUMBER][0]   = new Keyboard(parent, R.xml.keyboard_12key_full_num);
867         keyList[KEYMODE_JA_FULL_KATAKANA][0] = new Keyboard(parent, R.xml.keyboard_12key_full_katakana);
868         keyList[KEYMODE_JA_FULL_KATAKANA][1] = new Keyboard(parent, R.xml.keyboard_12key_full_katakana_input);
869         keyList[KEYMODE_JA_HALF_ALPHABET][0] = new Keyboard(parent, R.xml.keyboard_12key_half_alphabet);
870         keyList[KEYMODE_JA_HALF_ALPHABET][1] = new Keyboard(parent, R.xml.keyboard_12key_half_alphabet_input);
871         keyList[KEYMODE_JA_HALF_NUMBER][0]   = new Keyboard(parent, R.xml.keyboard_12key_half_num);
872         keyList[KEYMODE_JA_HALF_KATAKANA][0] = new Keyboard(parent, R.xml.keyboard_12key_half_katakana);
873         keyList[KEYMODE_JA_HALF_KATAKANA][1] = new Keyboard(parent, R.xml.keyboard_12key_half_katakana_input);
874         keyList[KEYMODE_JA_HALF_PHONE][0]    = new Keyboard(parent, R.xml.keyboard_12key_phone);
875 
876         /* 12-keys shift_on (portrait) */
877         keyList = mKeyboard[LANG_JA][PORTRAIT][KEYBOARD_12KEY][KEYBOARD_SHIFT_ON];
878         keyList[KEYMODE_JA_FULL_HIRAGANA]
879             = mKeyboard[LANG_JA][PORTRAIT][KEYBOARD_12KEY][KEYBOARD_SHIFT_OFF][KEYMODE_JA_FULL_HIRAGANA];
880         keyList[KEYMODE_JA_FULL_ALPHABET]
881             = mKeyboard[LANG_JA][PORTRAIT][KEYBOARD_12KEY][KEYBOARD_SHIFT_OFF][KEYMODE_JA_FULL_ALPHABET];
882         keyList[KEYMODE_JA_FULL_NUMBER]
883             = mKeyboard[LANG_JA][PORTRAIT][KEYBOARD_12KEY][KEYBOARD_SHIFT_OFF][KEYMODE_JA_FULL_NUMBER];
884         keyList[KEYMODE_JA_FULL_KATAKANA]
885             = mKeyboard[LANG_JA][PORTRAIT][KEYBOARD_12KEY][KEYBOARD_SHIFT_OFF][KEYMODE_JA_FULL_KATAKANA];
886         keyList[KEYMODE_JA_HALF_ALPHABET]
887             = mKeyboard[LANG_JA][PORTRAIT][KEYBOARD_12KEY][KEYBOARD_SHIFT_OFF][KEYMODE_JA_HALF_ALPHABET];;
888         keyList[KEYMODE_JA_HALF_NUMBER]
889             = mKeyboard[LANG_JA][PORTRAIT][KEYBOARD_12KEY][KEYBOARD_SHIFT_OFF][KEYMODE_JA_HALF_NUMBER];
890         keyList[KEYMODE_JA_HALF_KATAKANA]
891             = mKeyboard[LANG_JA][PORTRAIT][KEYBOARD_12KEY][KEYBOARD_SHIFT_OFF][KEYMODE_JA_HALF_KATAKANA];
892         keyList[KEYMODE_JA_HALF_PHONE]
893             = mKeyboard[LANG_JA][PORTRAIT][KEYBOARD_12KEY][KEYBOARD_SHIFT_OFF][KEYMODE_JA_HALF_PHONE];
894 
895     }
896 
897     /**
898      * Create the keyboard for landscape mode
899      * <br>
900      * @param parent  The context
901      */
createKeyboardsLandscape(OpenWnn parent)902     private void createKeyboardsLandscape(OpenWnn parent) {
903     	/*
904         Keyboard[][] keyList;
905         */
906         /* qwerty shift_off (landscape) */
907         /*
908         keyList = mKeyboard[LANG_JA][LANDSCAPE][KEYBOARD_QWERTY][KEYBOARD_SHIFT_OFF];
909         keyList[KEYMODE_JA_FULL_HIRAGANA][0] = new Keyboard(parent, R.xml.keyboard_qwerty_jp_landscape);
910         keyList[KEYMODE_JA_FULL_ALPHABET][0] = new Keyboard(parent, R.xml.keyboard_qwerty_jp_full_alphabet_landscape);
911         keyList[KEYMODE_JA_FULL_NUMBER][0]   = new Keyboard(parent, R.xml.keyboard_qwerty_jp_full_symbols_landscape);
912         keyList[KEYMODE_JA_FULL_KATAKANA][0] = new Keyboard(parent, R.xml.keyboard_qwerty_jp_full_katakana_landscape);
913         keyList[KEYMODE_JA_HALF_ALPHABET][0] = new Keyboard(parent, R.xml.keyboard_qwerty_jp_half_alphabet_landscape);
914         keyList[KEYMODE_JA_HALF_NUMBER][0]   = new Keyboard(parent, R.xml.keyboard_qwerty_jp_half_symbols_landscape);
915         keyList[KEYMODE_JA_HALF_KATAKANA][0] = new Keyboard(parent, R.xml.keyboard_qwerty_jp_half_katakana_landscape);
916         keyList[KEYMODE_JA_HALF_PHONE][0]    = new Keyboard(parent, R.xml.keyboard_12key_phone_landscape);
917         */
918         /* qwerty shift_on (landscape) */
919         /*
920         keyList = mKeyboard[LANG_JA][LANDSCAPE][KEYBOARD_QWERTY][KEYBOARD_SHIFT_ON];
921         keyList[KEYMODE_JA_FULL_HIRAGANA][0] = new Keyboard(parent, R.xml.keyboard_qwerty_jp_shift_landscape);
922         keyList[KEYMODE_JA_FULL_ALPHABET][0] = new Keyboard(parent, R.xml.keyboard_qwerty_jp_full_alphabet_shift_landscape);
923         keyList[KEYMODE_JA_FULL_NUMBER][0]   = new Keyboard(parent, R.xml.keyboard_qwerty_jp_full_symbols_shift_landscape);
924         keyList[KEYMODE_JA_FULL_KATAKANA][0] = new Keyboard(parent, R.xml.keyboard_qwerty_jp_full_katakana_shift_landscape);
925         keyList[KEYMODE_JA_HALF_ALPHABET][0] = new Keyboard(parent, R.xml.keyboard_qwerty_jp_half_alphabet_shift_landscape);
926         keyList[KEYMODE_JA_HALF_NUMBER][0]   = new Keyboard(parent, R.xml.keyboard_qwerty_jp_half_symbols_shift_landscape);
927         keyList[KEYMODE_JA_HALF_KATAKANA][0] = new Keyboard(parent, R.xml.keyboard_qwerty_jp_half_katakana_shift_landscape);
928         keyList[KEYMODE_JA_HALF_PHONE][0] =
929             mKeyboard[LANG_JA][LANDSCAPE][KEYBOARD_QWERTY][KEYBOARD_SHIFT_OFF][KEYMODE_JA_HALF_PHONE][0];
930         */
931         /* 12-keys shift_off (landscape) */
932         /*
933         keyList = mKeyboard[LANG_JA][LANDSCAPE][KEYBOARD_12KEY][KEYBOARD_SHIFT_OFF];
934         keyList[KEYMODE_JA_FULL_HIRAGANA][0] = new Keyboard(parent, R.xml.keyboard_12keyjp_landscape);
935         keyList[KEYMODE_JA_FULL_HIRAGANA][1] = new Keyboard(parent, R.xml.keyboard_12keyjp_input_landscape);
936         keyList[KEYMODE_JA_FULL_ALPHABET][0] = new Keyboard(parent, R.xml.keyboard_12key_full_alphabet_landscape);
937         keyList[KEYMODE_JA_FULL_ALPHABET][1] = new Keyboard(parent, R.xml.keyboard_12key_full_alphabet_input_landscape);
938         keyList[KEYMODE_JA_FULL_NUMBER][0]   = new Keyboard(parent, R.xml.keyboard_12key_full_num_landscape);
939         keyList[KEYMODE_JA_FULL_KATAKANA][0] = new Keyboard(parent, R.xml.keyboard_12key_full_katakana_landscape);
940         keyList[KEYMODE_JA_FULL_KATAKANA][1] = new Keyboard(parent, R.xml.keyboard_12key_full_katakana_input_landscape);
941         keyList[KEYMODE_JA_HALF_ALPHABET][0] = new Keyboard(parent, R.xml.keyboard_12key_half_alphabet_landscape);
942         keyList[KEYMODE_JA_HALF_ALPHABET][1] = new Keyboard(parent, R.xml.keyboard_12key_half_alphabet_input_landscape);
943         keyList[KEYMODE_JA_HALF_NUMBER][0]   = new Keyboard(parent, R.xml.keyboard_12key_half_num_landscape);
944         keyList[KEYMODE_JA_HALF_KATAKANA][0] = new Keyboard(parent, R.xml.keyboard_12key_half_katakana_landscape);
945         keyList[KEYMODE_JA_HALF_KATAKANA][1] = new Keyboard(parent, R.xml.keyboard_12key_half_katakana_input_landscape);
946         keyList[KEYMODE_JA_HALF_PHONE][0]    = new Keyboard(parent, R.xml.keyboard_12key_phone_landscape);
947         */
948         /* 12-keys shift_on (landscape) */
949         /*
950         keyList = mKeyboard[LANG_JA][LANDSCAPE][KEYBOARD_12KEY][KEYBOARD_SHIFT_ON];
951         keyList[KEYMODE_JA_FULL_HIRAGANA]
952             = mKeyboard[LANG_JA][LANDSCAPE][KEYBOARD_12KEY][KEYBOARD_SHIFT_OFF][KEYMODE_JA_FULL_HIRAGANA];
953         keyList[KEYMODE_JA_FULL_ALPHABET]
954             = mKeyboard[LANG_JA][LANDSCAPE][KEYBOARD_12KEY][KEYBOARD_SHIFT_OFF][KEYMODE_JA_FULL_ALPHABET];
955         keyList[KEYMODE_JA_FULL_NUMBER]
956             = mKeyboard[LANG_JA][LANDSCAPE][KEYBOARD_12KEY][KEYBOARD_SHIFT_OFF][KEYMODE_JA_FULL_NUMBER];
957         keyList[KEYMODE_JA_FULL_KATAKANA]
958             = mKeyboard[LANG_JA][LANDSCAPE][KEYBOARD_12KEY][KEYBOARD_SHIFT_OFF][KEYMODE_JA_FULL_KATAKANA];
959         keyList[KEYMODE_JA_HALF_ALPHABET]
960             = mKeyboard[LANG_JA][LANDSCAPE][KEYBOARD_12KEY][KEYBOARD_SHIFT_OFF][KEYMODE_JA_HALF_ALPHABET];;
961         keyList[KEYMODE_JA_HALF_NUMBER]
962             = mKeyboard[LANG_JA][LANDSCAPE][KEYBOARD_12KEY][KEYBOARD_SHIFT_OFF][KEYMODE_JA_HALF_NUMBER];
963         keyList[KEYMODE_JA_HALF_KATAKANA]
964             = mKeyboard[LANG_JA][LANDSCAPE][KEYBOARD_12KEY][KEYBOARD_SHIFT_OFF][KEYMODE_JA_HALF_KATAKANA];
965         keyList[KEYMODE_JA_HALF_PHONE]
966             = mKeyboard[LANG_JA][LANDSCAPE][KEYBOARD_12KEY][KEYBOARD_SHIFT_OFF][KEYMODE_JA_HALF_PHONE];
967         */
968     }
969 
970     /**
971      * Convert the key code to the index of table
972      * <br>
973      * @param index     The key code
974      * @return          The index of the toggle table for input
975      */
getTableIndex(int keyCode)976     private int getTableIndex(int keyCode) {
977         int index =
978             (keyCode == KEYCODE_JP12_1)     ?  0 :
979             (keyCode == KEYCODE_JP12_2)     ?  1 :
980             (keyCode == KEYCODE_JP12_3)     ?  2 :
981             (keyCode == KEYCODE_JP12_4)     ?  3 :
982             (keyCode == KEYCODE_JP12_5)     ?  4 :
983             (keyCode == KEYCODE_JP12_6)     ?  5 :
984             (keyCode == KEYCODE_JP12_7)     ?  6 :
985             (keyCode == KEYCODE_JP12_8)     ?  7 :
986             (keyCode == KEYCODE_JP12_9)     ?  8 :
987             (keyCode == KEYCODE_JP12_0)     ?  9 :
988             (keyCode == KEYCODE_JP12_SHARP) ? 10 :
989             (keyCode == KEYCODE_JP12_ASTER) ? 11 :
990             0;
991 
992         return index;
993     }
994 
995     /**
996      * Get the toggle table for input that is appropriate in current mode.
997      *
998      * @return      The toggle table for input
999      */
getCycleTable()1000     private String[][] getCycleTable() {
1001         String[][] cycleTable = null;
1002         switch (mCurrentKeyMode) {
1003         case KEYMODE_JA_FULL_HIRAGANA:
1004             cycleTable = JP_FULL_HIRAGANA_CYCLE_TABLE;
1005             break;
1006 
1007         case KEYMODE_JA_FULL_KATAKANA:
1008             cycleTable = JP_FULL_KATAKANA_CYCLE_TABLE;
1009             break;
1010 
1011         case KEYMODE_JA_FULL_ALPHABET:
1012             cycleTable = JP_FULL_ALPHABET_CYCLE_TABLE;
1013             break;
1014 
1015         case KEYMODE_JA_FULL_NUMBER:
1016         case KEYMODE_JA_HALF_NUMBER:
1017             /* Because these modes belong to direct input group, No toggle table exists */
1018             break;
1019 
1020         case KEYMODE_JA_HALF_ALPHABET:
1021             cycleTable = JP_HALF_ALPHABET_CYCLE_TABLE;
1022             break;
1023 
1024         case KEYMODE_JA_HALF_KATAKANA:
1025             cycleTable = JP_HALF_KATAKANA_CYCLE_TABLE;
1026             break;
1027 
1028         default:
1029             break;
1030         }
1031         return cycleTable;
1032     }
1033 
1034     /**
1035      * Get the replace table that is appropriate in current mode.
1036      *
1037      * @return      The replace table
1038      */
getReplaceTable()1039     private HashMap getReplaceTable() {
1040         HashMap hashTable = null;
1041         switch (mCurrentKeyMode) {
1042         case KEYMODE_JA_FULL_HIRAGANA:
1043             hashTable = JP_FULL_HIRAGANA_REPLACE_TABLE;
1044             break;
1045         case KEYMODE_JA_FULL_KATAKANA:
1046             hashTable = JP_FULL_KATAKANA_REPLACE_TABLE;
1047             break;
1048 
1049         case KEYMODE_JA_FULL_ALPHABET:
1050             hashTable = JP_FULL_ALPHABET_REPLACE_TABLE;
1051             break;
1052 
1053         case KEYMODE_JA_FULL_NUMBER:
1054         case KEYMODE_JA_HALF_NUMBER:
1055             /* Because these modes belong to direct input group, No replacing table exists */
1056             break;
1057 
1058         case KEYMODE_JA_HALF_ALPHABET:
1059             hashTable = JP_HALF_ALPHABET_REPLACE_TABLE;
1060             break;
1061 
1062         case KEYMODE_JA_HALF_KATAKANA:
1063             hashTable = JP_HALF_KATAKANA_REPLACE_TABLE;
1064             break;
1065 
1066         default:
1067             break;
1068         }
1069         return hashTable;
1070     }
1071 
1072     /**
1073      * Set the status icon that is appropriate in current mode
1074      */
setStatusIcon()1075     private void setStatusIcon() {
1076         int icon = 0;
1077 
1078         switch (mCurrentKeyMode) {
1079         case KEYMODE_JA_FULL_HIRAGANA:
1080             icon = R.drawable.immodeic_hiragana;
1081             break;
1082         case KEYMODE_JA_FULL_KATAKANA:
1083             icon = R.drawable.immodeic_full_kana;
1084             break;
1085         case KEYMODE_JA_FULL_ALPHABET:
1086             icon = R.drawable.immodeic_full_alphabet;
1087             break;
1088         case KEYMODE_JA_FULL_NUMBER:
1089             icon = R.drawable.immodeic_full_number;
1090             break;
1091         case KEYMODE_JA_HALF_KATAKANA:
1092             icon = R.drawable.immodeic_half_kana;
1093             break;
1094         case KEYMODE_JA_HALF_ALPHABET:
1095             icon = R.drawable.immodeic_half_alphabet;
1096             break;
1097         case KEYMODE_JA_HALF_NUMBER:
1098         case KEYMODE_JA_HALF_PHONE:
1099             icon = R.drawable.immodeic_half_number;
1100             break;
1101         default:
1102             break;
1103         }
1104 
1105         mWnn.showStatusIcon(icon);
1106     }
1107 
1108     /**
1109      * Get the shift key state from the editor.
1110      * <br>
1111      * @param editor    The editor information
1112      * @return          The state id of the shift key (0:off, 1:on)
1113      */
getShiftKeyState(EditorInfo editor)1114     protected int getShiftKeyState(EditorInfo editor) {
1115         InputConnection connection = mWnn.getCurrentInputConnection();
1116         if (connection != null) {
1117             int caps = connection.getCursorCapsMode(editor.inputType);
1118             return (caps == 0) ? 0 : 1;
1119         } else {
1120             return 0;
1121         }
1122     }
1123 
1124     /**
1125      * Set the shift key state from {@link EditorInfo}.
1126      */
setShiftByEditorInfo()1127     private void setShiftByEditorInfo() {
1128         if (mEnableAutoCaps && (mCurrentKeyMode == KEYMODE_JA_HALF_ALPHABET)) {
1129             int shift = getShiftKeyState(mWnn.getCurrentInputEditorInfo());
1130 
1131             mShiftOn = shift;
1132             changeKeyboard(getShiftChangeKeyboard(shift));
1133         }
1134     }
1135 
1136     /** @see jp.co.omronsoft.openwnn.DefaultSoftKeyboard#setHardKeyboardHidden */
setHardKeyboardHidden(boolean hidden)1137     @Override public void setHardKeyboardHidden(boolean hidden) {
1138         if (mWnn != null) {
1139             if (!hidden) {
1140                 mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.CHANGE_MODE,
1141                                               OpenWnnJAJP.ENGINE_MODE_OPT_TYPE_QWERTY));
1142             }
1143 
1144             if (mHardKeyboardHidden != hidden) {
1145                 if ((mLimitedKeyMode != null)
1146                     || ((mCurrentKeyMode != KEYMODE_JA_FULL_HIRAGANA)
1147                         && (mCurrentKeyMode != KEYMODE_JA_HALF_ALPHABET))) {
1148 
1149                     mLastInputType = EditorInfo.TYPE_NULL;
1150                     if (mWnn.isInputViewShown()) {
1151                         setDefaultKeyboard();
1152                     }
1153                 }
1154             }
1155         }
1156         super.setHardKeyboardHidden(hidden);
1157     }
1158 
1159     /**
1160      * Change the key-mode to the allowed one which is restricted
1161      *  by the text input field or the type of the keyboard.
1162      * @param keyMode The key-mode
1163      * @return the key-mode allowed
1164      */
filterKeyMode(int keyMode)1165     private int filterKeyMode(int keyMode) {
1166         int targetMode = keyMode;
1167         int[] limits = mLimitedKeyMode;
1168 
1169         if (!mHardKeyboardHidden) { /* for hardware keyboard */
1170             if ((targetMode != KEYMODE_JA_FULL_HIRAGANA)
1171                 && (targetMode != KEYMODE_JA_HALF_ALPHABET)) {
1172 
1173                 Locale locale = Locale.getDefault();
1174                 int keymode = KEYMODE_JA_HALF_ALPHABET;
1175                 if (locale.getLanguage().equals(Locale.JAPANESE.getLanguage())) {
1176                     switch (targetMode) {
1177                     case KEYMODE_JA_FULL_HIRAGANA:
1178                     case KEYMODE_JA_FULL_KATAKANA:
1179                     case KEYMODE_JA_HALF_KATAKANA:
1180                         keymode = KEYMODE_JA_FULL_HIRAGANA;
1181                         break;
1182                     default:
1183                         /* half-alphabet */
1184                         break;
1185                     }
1186                 }
1187                 targetMode = keymode;
1188             }
1189         }
1190 
1191         /* restrict by the type of the text field */
1192         if (limits != null) {
1193             boolean hasAccepted = false;
1194             boolean hasRequiredChange = true;
1195             int size = limits.length;
1196             int nowMode = mCurrentKeyMode;
1197 
1198             for (int i = 0; i < size; i++) {
1199                 if (targetMode == limits[i]) {
1200                     hasAccepted = true;
1201                     break;
1202                 }
1203                 if (nowMode == limits[i]) {
1204                     hasRequiredChange = false;
1205                 }
1206             }
1207 
1208             if (!hasAccepted) {
1209                 if (hasRequiredChange) {
1210                     targetMode = mLimitedKeyMode[0];
1211                 } else {
1212                     targetMode = INVALID_KEYMODE;
1213                 }
1214             }
1215         }
1216 
1217         return targetMode;
1218     }
1219 }
1220