Home | History | Annotate | Download | only in JAJP
      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 */
    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 */
    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      */
    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      */
    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 */
    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 */
    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 */
    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 */
    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 */
    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 */
    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      */
    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      */
    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      */
    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      */
    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      */
   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      */
   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      */
   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      */
   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      */
   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      */
   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 */
   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 */
   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      */
   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      */
   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      */
   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