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