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