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;
18 
19 import android.view.KeyEvent;
20 import android.view.View;
21 import android.view.ViewGroup;
22 import android.view.inputmethod.EditorInfo;
23 import android.view.inputmethod.InputConnection;
24 import android.widget.TextView;
25 import android.content.SharedPreferences;
26 import android.preference.PreferenceManager;
27 import android.content.res.*;
28 import android.os.Vibrator;
29 import android.media.MediaPlayer;
30 import android.content.Context;
31 
32 import android.util.Log;
33 
34 import jp.co.omronsoft.openwnn.Keyboard;
35 import jp.co.omronsoft.openwnn.KeyboardView;
36 import jp.co.omronsoft.openwnn.KeyboardView.OnKeyboardActionListener;
37 
38 /**
39  * The default software keyboard class.
40  *
41  * @author Copyright (C) 2009-2011 OMRON SOFTWARE CO., LTD.  All Rights Reserved.
42  */
43 public class DefaultSoftKeyboard implements InputViewManager, KeyboardView.OnKeyboardActionListener {
44     /*
45      *----------------------------------------------------------------------
46      * key codes for a software keyboard
47      *----------------------------------------------------------------------
48      */
49     /** Change the keyboard language */
50     public static final int KEYCODE_CHANGE_LANG = -500;
51 
52     /* for Japanese 12-key keyboard */
53     /** Japanese 12-key keyboard [1] */
54     public static final int KEYCODE_JP12_1 = -201;
55     /** Japanese 12-key keyboard [2] */
56     public static final int KEYCODE_JP12_2 = -202;
57     /** Japanese 12-key keyboard [3] */
58     public static final int KEYCODE_JP12_3 = -203;
59     /** Japanese 12-key keyboard [4] */
60     public static final int KEYCODE_JP12_4 = -204;
61     /** Japanese 12-key keyboard [5] */
62     public static final int KEYCODE_JP12_5 = -205;
63     /** Japanese 12-key keyboard [6] */
64     public static final int KEYCODE_JP12_6 = -206;
65     /** Japanese 12-key keyboard [7] */
66     public static final int KEYCODE_JP12_7 = -207;
67     /** Japanese 12-key keyboard [8] */
68     public static final int KEYCODE_JP12_8 = -208;
69     /** Japanese 12-key keyboard [9] */
70     public static final int KEYCODE_JP12_9 = -209;
71     /** Japanese 12-key keyboard [0] */
72     public static final int KEYCODE_JP12_0 = -210;
73     /** Japanese 12-key keyboard [#] */
74     public static final int KEYCODE_JP12_SHARP = -211;
75     /** Japanese 12-key keyboard [*] */
76     public static final int KEYCODE_JP12_ASTER = -213;
77     /** Japanese 12-key keyboard [DEL] */
78     public static final int KEYCODE_JP12_BACKSPACE = -214;
79     /** Japanese 12-key keyboard [SPACE] */
80     public static final int KEYCODE_JP12_SPACE = -215;
81     /** Japanese 12-key keyboard [ENTER] */
82     public static final int KEYCODE_JP12_ENTER = -216;
83     /** Japanese 12-key keyboard [RIGHT ARROW] */
84     public static final int KEYCODE_JP12_RIGHT = -217;
85     /** Japanese 12-key keyboard [LEFT ARROW] */
86     public static final int KEYCODE_JP12_LEFT = -218;
87     /** Japanese 12-key keyboard [REVERSE TOGGLE] */
88     public static final int KEYCODE_JP12_REVERSE = -219;
89     /** Japanese 12-key keyboard [CLOSE] */
90     public static final int KEYCODE_JP12_CLOSE   = -220;
91     /** Japanese 12-key keyboard [KEYBOARD TYPE CHANGE] */
92     public static final int KEYCODE_JP12_KBD   = -221;
93     /** Japanese 12-key keyboard [EMOJI] */
94     public static final int KEYCODE_JP12_EMOJI      = -222;
95     /** Japanese 12-key keyboard [FULL-WIDTH HIRAGANA MODE] */
96     public static final int KEYCODE_JP12_ZEN_HIRA   = -223;
97     /** Japanese 12-key keyboard [FULL-WIDTH NUMBER MODE] */
98     public static final int KEYCODE_JP12_ZEN_NUM    = -224;
99     /** Japanese 12-key keyboard [FULL-WIDTH ALPHABET MODE] */
100     public static final int KEYCODE_JP12_ZEN_ALPHA  = -225;
101     /** Japanese 12-key keyboard [FULL-WIDTH KATAKANA MODE] */
102     public static final int KEYCODE_JP12_ZEN_KATA   = -226;
103     /** Japanese 12-key keyboard [HALF-WIDTH KATAKANA MODE] */
104     public static final int KEYCODE_JP12_HAN_KATA   = -227;
105     /** Japanese 12-key keyboard [HALF-WIDTH NUMBER MODE] */
106     public static final int KEYCODE_JP12_HAN_NUM    = -228;
107     /** Japanese 12-key keyboard [HALF-WIDTH ALPHABET MODE] */
108     public static final int KEYCODE_JP12_HAN_ALPHA  = -229;
109     /** Japanese 12-key keyboard [MODE TOOGLE CHANGE] */
110     public static final int KEYCODE_JP12_TOGGLE_MODE = -230;
111 
112     /** Key code for symbol keyboard alt key */
113     public static final int KEYCODE_4KEY_MODE        = -300;
114     /** Key code for symbol keyboard up key */
115     public static final int KEYCODE_4KEY_UP          = -301;
116     /** Key code for symbol keyboard down key */
117     public static final int KEYCODE_4KEY_DOWN        = -302;
118     /** Key code for symbol keyboard del key */
119     public static final int KEYCODE_4KEY_CLEAR       = -303;
120 
121     /* for Qwerty keyboard */
122     /** Qwerty keyboard [DEL] */
123     public static final int KEYCODE_QWERTY_BACKSPACE = -100;
124     /** Qwerty keyboard [ENTER] */
125     public static final int KEYCODE_QWERTY_ENTER = -101;
126     /** Qwerty keyboard [SHIFT] */
127     public static final int KEYCODE_QWERTY_SHIFT = Keyboard.KEYCODE_SHIFT;
128     /** Qwerty keyboard [ALT] */
129     public static final int KEYCODE_QWERTY_ALT   = -103;
130     /** Qwerty keyboard [KEYBOARD TYPE CHANGE] */
131     public static final int KEYCODE_QWERTY_KBD   = -104;
132     /** Qwerty keyboard [CLOSE] */
133     public static final int KEYCODE_QWERTY_CLOSE = -105;
134     /** Japanese Qwerty keyboard [EMOJI] */
135     public static final int KEYCODE_QWERTY_EMOJI = -106;
136     /** Japanese Qwerty keyboard [FULL-WIDTH HIRAGANA MODE] */
137     public static final int KEYCODE_QWERTY_ZEN_HIRA   = -107;
138     /** Japanese Qwerty keyboard [FULL-WIDTH NUMBER MODE] */
139     public static final int KEYCODE_QWERTY_ZEN_NUM    = -108;
140     /** Japanese Qwerty keyboard [FULL-WIDTH ALPHABET MODE] */
141     public static final int KEYCODE_QWERTY_ZEN_ALPHA  = -109;
142     /** Japanese Qwerty keyboard [FULL-WIDTH KATAKANA MODE] */
143     public static final int KEYCODE_QWERTY_ZEN_KATA   = -110;
144     /** Japanese Qwerty keyboard [HALF-WIDTH KATAKANA MODE] */
145     public static final int KEYCODE_QWERTY_HAN_KATA   = -111;
146     /** Qwerty keyboard [NUMBER MODE] */
147     public static final int KEYCODE_QWERTY_HAN_NUM    = -112;
148     /** Qwerty keyboard [ALPHABET MODE] */
149     public static final int KEYCODE_QWERTY_HAN_ALPHA  = -113;
150     /** Qwerty keyboard [MODE TOOGLE CHANGE] */
151     public static final int KEYCODE_QWERTY_TOGGLE_MODE = -114;
152     /** Qwerty keyboard [PINYIN MODE] */
153     public static final int KEYCODE_QWERTY_PINYIN  = -115;
154 
155     /** OpenWnn instance which hold this software keyboard*/
156     protected OpenWnn      mWnn;
157 
158     /** Current keyboard view */
159     protected KeyboardView mKeyboardView;
160 
161     /** View objects (main side) */
162     protected BaseInputView mMainView;
163     /** View objects (sub side) */
164     protected ViewGroup mSubView;
165 
166     /** Current keyboard definition */
167     protected Keyboard mCurrentKeyboard;
168 
169     /** Caps lock state */
170     protected boolean mCapsLock;
171 
172     /** Input restraint */
173     protected boolean mDisableKeyInput = true;
174     /**
175      * Keyboard surfaces
176      * <br>
177      * Keyboard[language][portrait/landscape][keyboard type][shift off/on][key-mode]
178      */
179     protected Keyboard[][][][][][] mKeyboard;
180 
181     /* languages */
182     /** Current language */
183     protected int mCurrentLanguage;
184     /** Language (English) */
185     public static final int LANG_EN  = 0;
186     /** Language (Japanese) */
187     public static final int LANG_JA  = 1;
188     /** Language (Chinese) */
189     public static final int LANG_CN  = 2;
190 
191     /* portrait/landscape */
192     /** State of the display */
193     protected int mDisplayMode = 0;
194     /** Display mode (Portrait) */
195     public static final int PORTRAIT  = 0;
196     /** Display mode (Landscape) */
197     public static final int LANDSCAPE = 1;
198 
199     /* keyboard type */
200     /** Current keyboard type */
201     protected int mCurrentKeyboardType;
202     /** Keyboard (QWERTY keyboard) */
203     public static final int KEYBOARD_QWERTY  = 0;
204     /** Keyboard (12-keys keyboard) */
205     public static final int KEYBOARD_12KEY   = 1;
206     /** State of the shift key */
207     protected int mShiftOn = 0;
208     /** Shift key off */
209     public static final int KEYBOARD_SHIFT_OFF = 0;
210     /** Shift key on */
211     public static final int KEYBOARD_SHIFT_ON  = 1;
212 
213     /* key-modes */
214     /** Current key-mode */
215     protected int mCurrentKeyMode;
216 
217     /* key-modes for English */
218     /** English key-mode (alphabet) */
219     public static final int KEYMODE_EN_ALPHABET = 0;
220     /** English key-mode (number) */
221     public static final int KEYMODE_EN_NUMBER   = 1;
222     /** English key-mode (phone number) */
223     public static final int KEYMODE_EN_PHONE    = 2;
224 
225     /* key-modes for Japanese */
226     /** Japanese key-mode (Full-width Hiragana) */
227     public static final int KEYMODE_JA_FULL_HIRAGANA = 0;
228     /** Japanese key-mode (Full-width alphabet) */
229     public static final int KEYMODE_JA_FULL_ALPHABET = 1;
230     /** Japanese key-mode (Full-width number) */
231     public static final int KEYMODE_JA_FULL_NUMBER   = 2;
232     /** Japanese key-mode (Full-width Katakana) */
233     public static final int KEYMODE_JA_FULL_KATAKANA = 3;
234     /** Japanese key-mode (Half-width alphabet) */
235     public static final int KEYMODE_JA_HALF_ALPHABET = 4;
236     /** Japanese key-mode (Half-width number) */
237     public static final int KEYMODE_JA_HALF_NUMBER   = 5;
238     /** Japanese key-mode (Half-width Katakana) */
239     public static final int KEYMODE_JA_HALF_KATAKANA = 6;
240     /** Japanese key-mode (Half-width phone number) */
241     public static final int KEYMODE_JA_HALF_PHONE    = 7;
242 
243     /* key-modes for Chinese */
244     /** Chinese key-mode (pinyin) */
245     public static final int KEYMODE_CN_PINYIN   = 0;
246     /** Chinese key-mode (Full-width number) */
247     public static final int KEYMODE_CN_FULL_NUMBER   = 1;
248     /** Chinese key-mode (alphabet) */
249     public static final int KEYMODE_CN_ALPHABET = 2;
250     /** Chinese key-mode (phone) */
251     public static final int KEYMODE_CN_PHONE    = 3;
252     /** Chinese key-mode (Half-width number) */
253     public static final int KEYMODE_CN_HALF_NUMBER   = 4;
254 
255     /* key-modes for HARD */
256     /** HARD key-mode (SHIFT_OFF_ALT_OFF) */
257     public static final int HARD_KEYMODE_SHIFT_OFF_ALT_OFF     = 2;
258     /** HARD key-mode (SHIFT_ON_ALT_OFF) */
259     public static final int HARD_KEYMODE_SHIFT_ON_ALT_OFF      = 3;
260     /** HARD key-mode (SHIFT_OFF_ALT_ON) */
261     public static final int HARD_KEYMODE_SHIFT_OFF_ALT_ON      = 4;
262     /** HARD key-mode (SHIFT_ON_ALT_ON) */
263     public static final int HARD_KEYMODE_SHIFT_ON_ALT_ON       = 5;
264     /** HARD key-mode (SHIFT_LOCK_ALT_OFF) */
265     public static final int HARD_KEYMODE_SHIFT_LOCK_ALT_OFF    = 6;
266     /** HARD key-mode (SHIFT_LOCK_ALT_ON) */
267     public static final int HARD_KEYMODE_SHIFT_LOCK_ALT_ON     = 7;
268     /** HARD key-mode (SHIFT_LOCK_ALT_LOCK) */
269     public static final int HARD_KEYMODE_SHIFT_LOCK_ALT_LOCK   = 8;
270     /** HARD key-mode (SHIFT_OFF_ALT_LOCK) */
271     public static final int HARD_KEYMODE_SHIFT_OFF_ALT_LOCK    = 9;
272     /** HARD key-mode (SHIFT_ON_ALT_LOCK) */
273     public static final int HARD_KEYMODE_SHIFT_ON_ALT_LOCK     = 10;
274 
275     /** Whether the H/W keyboard is hidden. */
276     protected boolean mHardKeyboardHidden = true;
277 
278     /** Whether the H/W 12key keyboard. */
279     protected boolean mEnableHardware12Keyboard = false;
280 
281     /** Symbol keyboard */
282     protected Keyboard mSymbolKeyboard;
283 
284     /** Symbol keyboard state */
285     protected boolean mIsSymbolKeyboard = false;
286 
287     /**
288      * Status of the composing text
289      * <br>
290      * {@code true} if there is no composing text.
291      */
292     protected boolean mNoInput = true;
293 
294     /** Vibratior for key click vibration */
295     protected Vibrator mVibrator = null;
296 
297     /** MediaPlayer for key click sound */
298     protected MediaPlayer mSound = null;
299 
300     /** Key toggle cycle table currently using */
301     protected String[] mCurrentCycleTable;
302 
303     /** Event listener for symbol keyboard */
304     private OnKeyboardActionListener mSymbolOnKeyboardAction = new OnKeyboardActionListener() {
305         public void onKey(int primaryCode, int[] keyCodes) {
306             switch (primaryCode) {
307             case KEYCODE_4KEY_MODE:
308                 mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.INPUT_KEY,
309                                               new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK)));
310                 break;
311 
312             case KEYCODE_4KEY_UP:
313                 mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.CANDIDATE_VIEW_SCROLL_UP));
314                 break;
315 
316             case KEYCODE_4KEY_DOWN:
317                 mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.CANDIDATE_VIEW_SCROLL_DOWN));
318                 break;
319 
320             case KEYCODE_4KEY_CLEAR:
321                 InputConnection connection = mWnn.getCurrentInputConnection();
322                 if (connection != null) {
323                     connection.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL));
324                 }
325                 return;
326 
327             default:
328                 break;
329             }
330         }
331         public void onPress(int primaryCode) {
332             playSoundAndVibration();
333         }
334         public void onText(CharSequence text) { }
335         public void swipeLeft() { }
336         public void swipeRight() { }
337         public void swipeUp() { }
338         public void swipeDown() { }
339         public void onRelease(int primaryCode) { }
340         public boolean onLongPress(Keyboard.Key key) {
341             switch (key.codes[0]) {
342             case KEYCODE_4KEY_UP:
343                 mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.CANDIDATE_VIEW_SCROLL_FULL_UP));
344                 return true;
345 
346             case KEYCODE_4KEY_DOWN:
347                 mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.CANDIDATE_VIEW_SCROLL_FULL_DOWN));
348                 return true;
349 
350             default:
351                 break;
352             }
353             return false;
354         }
355     };
356 
357     /**
358      * Constructor
359      */
DefaultSoftKeyboard()360     public DefaultSoftKeyboard() { }
361 
362     /**
363      * Create keyboard views
364      *
365      * @param parent   OpenWnn using the keyboards.
366      */
createKeyboards(OpenWnn parent)367     protected void createKeyboards(OpenWnn parent) {
368         /*
369          *  Keyboard[# of Languages][portrait/landscape][# of keyboard type]
370          *          [shift off/on][max # of key-modes][non-input/input]
371          */
372         mKeyboard = new Keyboard[3][2][4][2][7][2];
373     }
374 
375     /**
376      * Get the keyboard changed the specified shift state.
377      *
378      * @param shift     Shift state
379      * @return          Keyboard view
380      */
getShiftChangeKeyboard(int shift)381     protected Keyboard getShiftChangeKeyboard(int shift) {
382         try {
383             Keyboard[] kbd = mKeyboard[mCurrentLanguage][mDisplayMode][mCurrentKeyboardType][shift][mCurrentKeyMode];
384 
385             if (!mNoInput && kbd[1] != null) {
386                 return kbd[1];
387             }
388             return kbd[0];
389         } catch (Exception ex) {
390             return null;
391         }
392     }
393 
394     /**
395      * Get the keyboard changed the specified input mode.
396      *
397      * @param mode      Input mode
398      * @return          Keyboard view
399      */
getModeChangeKeyboard(int mode)400     protected Keyboard getModeChangeKeyboard(int mode) {
401         try {
402             Keyboard[] kbd = mKeyboard[mCurrentLanguage][mDisplayMode][mCurrentKeyboardType][mShiftOn][mode];
403 
404             if (!mNoInput && kbd[1] != null) {
405                 return kbd[1];
406             }
407             return kbd[0];
408         } catch (Exception ex) {
409             return null;
410         }
411     }
412 
413     /**
414      * Get the keyboard changed the specified keyboard type
415      *
416      * @param type      Keyboard type
417      * @return          Keyboard view
418      */
getTypeChangeKeyboard(int type)419     protected Keyboard getTypeChangeKeyboard(int type) {
420         try {
421             Keyboard[] kbd = mKeyboard[mCurrentLanguage][mDisplayMode][type][mShiftOn][mCurrentKeyMode];
422 
423             if (!mNoInput && kbd[1] != null) {
424                 return kbd[1];
425             }
426             return kbd[0];
427         } catch (Exception ex) {
428             return null;
429         }
430     }
431 
432     /**
433      * Get the keyboard when some characters are input or no character is input.
434      *
435      * @param inputed   {@code true} if some characters are inputed; {@code false} if no character is inputed.
436      * @return          Keyboard view
437      */
getKeyboardInputed(boolean inputed)438     protected Keyboard getKeyboardInputed(boolean inputed) {
439         try {
440             Keyboard[] kbd = mKeyboard[mCurrentLanguage][mDisplayMode][mCurrentKeyboardType][mShiftOn][mCurrentKeyMode];
441 
442             if (inputed && kbd[1] != null) {
443                 return kbd[1];
444             }
445             return kbd[0];
446         } catch (Exception ex) {
447             return null;
448         }
449     }
450 
451     /**
452      * Change the circulative key-mode.
453      */
toggleKeyMode()454     protected void toggleKeyMode() {
455         /* unlock shift */
456         mShiftOn = KEYBOARD_SHIFT_OFF;
457 
458         /* search next defined key-mode */
459         Keyboard[][] keyboardList = mKeyboard[mCurrentLanguage][mDisplayMode][mCurrentKeyboardType][mShiftOn];
460         do {
461             if (++mCurrentKeyMode >= keyboardList.length) {
462                 mCurrentKeyMode = 0;
463             }
464         } while (keyboardList[mCurrentKeyMode][0] == null);
465 
466         Keyboard kbd;
467         if (!mNoInput && keyboardList[mCurrentKeyMode][1] != null) {
468             kbd = keyboardList[mCurrentKeyMode][1];
469         } else {
470             kbd = keyboardList[mCurrentKeyMode][0];
471         }
472         changeKeyboard(kbd);
473 
474         mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.CHANGE_MODE,
475                                       OpenWnnEvent.Mode.DEFAULT));
476     }
477 
478     /**
479      * Toggle change the shift lock state.
480      */
toggleShiftLock()481     protected void toggleShiftLock() {
482         if (mShiftOn == 0) {
483             /* turn shift on */
484             Keyboard newKeyboard = getShiftChangeKeyboard(KEYBOARD_SHIFT_ON);
485             if (newKeyboard != null) {
486                 mShiftOn = 1;
487                 changeKeyboard(newKeyboard);
488             }
489             mCapsLock = true;
490         } else {
491             /* turn shift off */
492             Keyboard newKeyboard = getShiftChangeKeyboard(KEYBOARD_SHIFT_OFF);
493             if (newKeyboard != null) {
494                 mShiftOn = 0;
495                 changeKeyboard(newKeyboard);
496             }
497             mCapsLock = false;
498         }
499     }
500 
501     /**
502      * Handling Alt key event.
503      */
processAltKey()504     protected void processAltKey() {
505         /* invalid if it is not qwerty mode */
506         if (mCurrentKeyboardType != KEYBOARD_QWERTY) {
507             return;
508         }
509 
510         int mode = -1;
511         int keymode = mCurrentKeyMode;
512         switch (mCurrentLanguage) {
513         case LANG_EN:
514             if (keymode == KEYMODE_EN_ALPHABET) {
515                 mode = KEYMODE_EN_NUMBER;
516             } else if (keymode == KEYMODE_EN_NUMBER) {
517                 mode = KEYMODE_EN_ALPHABET;
518             }
519             break;
520 
521         case LANG_JA:
522             if (keymode == KEYMODE_JA_HALF_ALPHABET) {
523                 mode = KEYMODE_JA_HALF_NUMBER;
524             } else if (keymode == KEYMODE_JA_HALF_NUMBER) {
525                 mode = KEYMODE_JA_HALF_ALPHABET;
526             } else if (keymode == KEYMODE_JA_FULL_ALPHABET) {
527                 mode = KEYMODE_JA_FULL_NUMBER;
528             } else if (keymode == KEYMODE_JA_FULL_NUMBER) {
529                 mode = KEYMODE_JA_FULL_ALPHABET;
530             }
531             break;
532 
533         default:
534             /* invalid */
535         }
536 
537         if (mode >= 0) {
538             Keyboard kbd = getModeChangeKeyboard(mode);
539             if (kbd != null) {
540                 mCurrentKeyMode = mode;
541                 changeKeyboard(kbd);
542             }
543         }
544     }
545 
546     /**
547      * Change the keyboard type.
548      *
549      * @param type  Type of the keyboard
550      * @see jp.co.omronsoft.openwnn.DefaultSoftKeyboard#KEYBOARD_QWERTY
551      * @see jp.co.omronsoft.openwnn.DefaultSoftKeyboard#KEYBOARD_12KEY
552      */
changeKeyboardType(int type)553     public void changeKeyboardType(int type) {
554         /* ignore invalid parameter */
555         if (type != KEYBOARD_QWERTY && type != KEYBOARD_12KEY) {
556             return;
557         }
558 
559         /* change keyboard view */
560         Keyboard kbd = getTypeChangeKeyboard(type);
561         if (kbd != null) {
562             mCurrentKeyboardType = type;
563             changeKeyboard(kbd);
564         }
565 
566         /* notice that the keyboard is changed */
567         mWnn.onEvent(new OpenWnnEvent(OpenWnnEvent.CHANGE_MODE,
568                                       OpenWnnEvent.Mode.DEFAULT));
569     }
570 
571     /**
572      * Change the keyboard.
573      *
574      * @param keyboard  The new keyboard
575      * @return          {@code true} if the keyboard is changed; {@code false} if not changed.
576      */
changeKeyboard(Keyboard keyboard)577     protected boolean changeKeyboard(Keyboard keyboard) {
578 
579         if (keyboard == null) {
580             return false;
581         }
582         if (mCurrentKeyboard != keyboard) {
583             mKeyboardView.setKeyboard(keyboard);
584             mKeyboardView.setShifted((mShiftOn == 0) ? false : true);
585             mCurrentKeyboard = keyboard;
586             return true;
587         } else {
588             mKeyboardView.setShifted((mShiftOn == 0) ? false : true);
589             return false;
590         }
591     }
592     /** @see jp.co.omronsoft.openwnn.InputViewManager#initView */
initView(OpenWnn parent, int width, int height)593     public View initView(OpenWnn parent, int width, int height) {
594         mWnn = parent;
595         mDisplayMode =
596             (parent.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)
597             ? LANDSCAPE : PORTRAIT;
598 
599         /*
600          * create keyboards & the view.
601          * To re-display the input view when the display mode is changed portrait <-> landscape,
602          * create keyboards every time.
603          */
604         createKeyboards(parent);
605 
606         /* create symbol keyboard */
607         mSymbolKeyboard = new Keyboard(parent, R.xml.keyboard_4key);
608 
609         SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(parent);
610         String skin = pref.getString("keyboard_skin",
611                                      mWnn.getResources().getString(R.string.keyboard_skin_id_default));
612         int id = parent.getResources().getIdentifier(skin, "layout", "jp.co.omronsoft.openwnn");
613 
614         mKeyboardView = (KeyboardView) mWnn.getLayoutInflater().inflate(id, null);
615         mKeyboardView.setOnKeyboardActionListener(this);
616         mCurrentKeyboard = null;
617 
618         mMainView = (BaseInputView) parent.getLayoutInflater().inflate(R.layout.keyboard_default_main, null);
619         mSubView = (ViewGroup) parent.getLayoutInflater().inflate(R.layout.keyboard_default_sub, null);
620 
621         if (!mHardKeyboardHidden) {
622             if (!mEnableHardware12Keyboard) {
623                 mMainView.addView(mSubView);
624             }
625         } else if (mKeyboardView != null) {
626             mMainView.addView(mKeyboardView);
627         }
628 
629         return mMainView;
630     }
631 
632     /**
633      * Update the SHFIT/ALT keys indicator.
634      *
635      * @param mode  The state of SHIFT/ALT keys.
636      */
updateIndicator(int mode)637     public void updateIndicator(int mode) {
638         Resources res = mWnn.getResources();
639         TextView text1 = (TextView)mSubView.findViewById(R.id.shift);
640         TextView text2 = (TextView)mSubView.findViewById(R.id.alt);
641 
642         switch (mode) {
643         case HARD_KEYMODE_SHIFT_OFF_ALT_OFF:
644             text1.setTextColor(res.getColor(R.color.indicator_textcolor_caps_off));
645             text2.setTextColor(res.getColor(R.color.indicator_textcolor_alt_off));
646             text1.setBackgroundColor(res.getColor(R.color.indicator_textbackground_default));
647             text2.setBackgroundColor(res.getColor(R.color.indicator_textbackground_default));
648             break;
649         case HARD_KEYMODE_SHIFT_ON_ALT_OFF:
650             text1.setTextColor(res.getColor(R.color.indicator_textcolor_caps_on));
651             text2.setTextColor(res.getColor(R.color.indicator_textcolor_alt_off));
652             text1.setBackgroundColor(res.getColor(R.color.indicator_textbackground_default));
653             text2.setBackgroundColor(res.getColor(R.color.indicator_textbackground_default));
654             break;
655         case HARD_KEYMODE_SHIFT_LOCK_ALT_OFF:
656             text1.setTextColor(res.getColor(R.color.indicator_textcolor_caps_lock));
657             text2.setTextColor(res.getColor(R.color.indicator_textcolor_alt_off));
658             text1.setBackgroundColor(res.getColor(R.color.indicator_background_lock_caps));
659             text2.setBackgroundColor(res.getColor(R.color.indicator_textbackground_default));
660             break;
661         case HARD_KEYMODE_SHIFT_OFF_ALT_ON:
662             text1.setTextColor(res.getColor(R.color.indicator_textcolor_caps_off));
663             text2.setTextColor(res.getColor(R.color.indicator_textcolor_alt_on));
664             text1.setBackgroundColor(res.getColor(R.color.indicator_textbackground_default));
665             text2.setBackgroundColor(res.getColor(R.color.indicator_textbackground_default));
666             break;
667         case HARD_KEYMODE_SHIFT_OFF_ALT_LOCK:
668             text1.setTextColor(res.getColor(R.color.indicator_textcolor_caps_off));
669             text2.setTextColor(res.getColor(R.color.indicator_textcolor_alt_lock));
670             text1.setBackgroundColor(res.getColor(R.color.indicator_textbackground_default));
671             text2.setBackgroundColor(res.getColor(R.color.indicator_background_lock_alt));
672             break;
673         case HARD_KEYMODE_SHIFT_ON_ALT_ON:
674             text1.setTextColor(res.getColor(R.color.indicator_textcolor_caps_on));
675             text2.setTextColor(res.getColor(R.color.indicator_textcolor_alt_on));
676             text1.setBackgroundColor(res.getColor(R.color.indicator_textbackground_default));
677             text2.setBackgroundColor(res.getColor(R.color.indicator_textbackground_default));
678             break;
679         case HARD_KEYMODE_SHIFT_ON_ALT_LOCK:
680             text1.setTextColor(res.getColor(R.color.indicator_textcolor_caps_on));
681             text2.setTextColor(res.getColor(R.color.indicator_textcolor_alt_lock));
682             text1.setBackgroundColor(res.getColor(R.color.indicator_textbackground_default));
683             text2.setBackgroundColor(res.getColor(R.color.indicator_background_lock_alt));
684             break;
685         case HARD_KEYMODE_SHIFT_LOCK_ALT_ON:
686             text1.setTextColor(res.getColor(R.color.indicator_textcolor_caps_lock));
687             text2.setTextColor(res.getColor(R.color.indicator_textcolor_alt_on));
688             text1.setBackgroundColor(res.getColor(R.color.indicator_background_lock_caps));
689             text2.setBackgroundColor(res.getColor(R.color.indicator_textbackground_default));
690             break;
691         case HARD_KEYMODE_SHIFT_LOCK_ALT_LOCK:
692             text1.setTextColor(res.getColor(R.color.indicator_textcolor_caps_lock));
693             text2.setTextColor(res.getColor(R.color.indicator_textcolor_alt_lock));
694             text1.setBackgroundColor(res.getColor(R.color.indicator_background_lock_caps));
695             text2.setBackgroundColor(res.getColor(R.color.indicator_background_lock_alt));
696             break;
697         default:
698             text1.setTextColor(res.getColor(R.color.indicator_textcolor_caps_off));
699             text2.setTextColor(res.getColor(R.color.indicator_textcolor_alt_off));
700             text1.setBackgroundColor(res.getColor(R.color.indicator_textbackground_default));
701             text2.setBackgroundColor(res.getColor(R.color.indicator_textbackground_default));
702             break;
703         }
704         return;
705     }
706 
707     /** @see jp.co.omronsoft.openwnn.InputViewManager#getCurrentView */
getCurrentView()708     public View getCurrentView() {
709         return mMainView;
710     }
711 
712     /** @see jp.co.omronsoft.openwnn.InputViewManager#onUpdateState */
onUpdateState(OpenWnn parent)713     public void onUpdateState(OpenWnn parent) {
714         try {
715             if (parent.mComposingText.size(1) == 0) {
716                 if (!mNoInput) {
717                     /* when the mode changed to "no input" */
718                     mNoInput = true;
719                     Keyboard newKeyboard = getKeyboardInputed(false);
720                     if (mCurrentKeyboard != newKeyboard) {
721                         changeKeyboard(newKeyboard);
722                     }
723                 }
724             } else {
725                 if (mNoInput) {
726                     /* when the mode changed to "input some characters" */
727                     mNoInput = false;
728                     Keyboard newKeyboard = getKeyboardInputed(true);
729                     if (mCurrentKeyboard != newKeyboard) {
730                         changeKeyboard(newKeyboard);
731                     }
732                 }
733             }
734         } catch (Exception ex) {
735         }
736     }
737 
738     /** @see jp.co.omronsoft.openwnn.InputViewManager#setPreferences */
setPreferences(SharedPreferences pref, EditorInfo editor)739     public void setPreferences(SharedPreferences pref, EditorInfo editor) {
740 
741         /* vibrator */
742         try {
743             if (pref.getBoolean("key_vibration", false)) {
744                 mVibrator = (Vibrator)mWnn.getSystemService(Context.VIBRATOR_SERVICE);
745             } else {
746                 mVibrator = null;
747             }
748         } catch (Exception ex) {
749             Log.d("OpenWnn", "NO VIBRATOR");
750         }
751 
752         /* sound */
753         try {
754             if (pref.getBoolean("key_sound", false)) {
755                 mSound = MediaPlayer.create(mWnn, R.raw.type);
756             } else {
757                 mSound = null;
758             }
759         } catch (Exception ex) {
760             Log.d("OpenWnn", "NO SOUND");
761         }
762 
763         /* pop-up preview */
764         if (OpenWnn.isXLarge()) {
765             mKeyboardView.setPreviewEnabled(false);
766         } else {
767             mKeyboardView.setPreviewEnabled(pref.getBoolean("popup_preview", true));
768             mKeyboardView.clearWindowInfo();
769         }
770 
771     }
772 
773     /** @see jp.co.omronsoft.openwnn.InputViewManager#closing */
closing()774     public void closing() {
775         if (mKeyboardView != null) {
776             mKeyboardView.closing();
777         }
778         mDisableKeyInput = true;
779     }
780 
781     /** @see jp.co.omronsoft.openwnn.InputViewManager#showInputView */
showInputView()782     public void showInputView() {
783         if (mKeyboardView != null) {
784             mKeyboardView.setVisibility(View.VISIBLE);
785         }
786     }
787 
788     /** @see jp.co.omronsoft.openwnn.InputViewManager#hideInputView */
hideInputView()789     public void hideInputView() {
790         mKeyboardView.setVisibility(View.GONE);
791     }
792 
793     /***********************************************************************
794      * onKeyboardActionListener
795      ***********************************************************************/
796     /** @see jp.co.omronsoft.openwnn.KeyboardView.OnKeyboardActionListener#onKey */
onKey(int primaryCode, int[] keyCodes)797     public void onKey(int primaryCode, int[] keyCodes) { }
798 
799     /** @see jp.co.omronsoft.openwnn.KeyboardView.OnKeyboardActionListener#swipeRight */
swipeRight()800     public void swipeRight() { }
801 
802     /** @see jp.co.omronsoft.openwnn.KeyboardView.OnKeyboardActionListener#swipeLeft */
swipeLeft()803     public void swipeLeft() { }
804 
805     /** @see jp.co.omronsoft.openwnn.KeyboardView.OnKeyboardActionListener#swipeDown */
swipeDown()806     public void swipeDown() { }
807 
808     /** @see jp.co.omronsoft.openwnn.KeyboardView.OnKeyboardActionListener#swipeUp */
swipeUp()809     public void swipeUp() { }
810 
811     /** @see jp.co.omronsoft.openwnn.KeyboardView.OnKeyboardActionListener#onRelease */
onRelease(int x)812     public void onRelease(int x) { }
813 
814     /** @see jp.co.omronsoft.openwnn.KeyboardView.OnKeyboardActionListener#onPress */
onPress(int x)815     public void onPress(int x) {
816         playSoundAndVibration();
817     }
818 
819     /** @see android.jp.co.omronsoft.openwnn.KeyboardView.OnKeyboardActionListener#onLongPress */
onLongPress(Keyboard.Key key)820     public boolean onLongPress(Keyboard.Key key) {
821         return false;
822     }
823 
824     /**
825      * Play sound & vibration.
826      */
playSoundAndVibration()827     private void playSoundAndVibration() {
828         /* key click sound & vibration */
829         if (mVibrator != null) {
830             try { mVibrator.vibrate(5); } catch (Exception ex) { }
831         }
832         if (mSound != null) {
833             try { mSound.seekTo(0); mSound.start(); } catch (Exception ex) { }
834         }
835     }
836 
837     /** @see jp.co.omronsoft.openwnn.KeyboardView.OnKeyboardActionListener#onText */
onText(CharSequence text)838     public void onText(CharSequence text) {}
839 
840     /**
841      * Get current key mode.
842      *
843      * @return Current key mode
844      */
getKeyMode()845     public int getKeyMode() {
846         return mCurrentKeyMode;
847     }
848 
849     /**
850      * Get current keyboard type.
851      *
852      * @return Current keyboard type
853      */
getKeyboardType()854     public int getKeyboardType() {
855         return mCurrentKeyboardType;
856     }
857 
858     /**
859      * Set the H/W keyboard's state.
860      *
861      * @param hidden {@code true} if hidden.
862      */
setHardKeyboardHidden(boolean hidden)863     public void setHardKeyboardHidden(boolean hidden) {
864         mHardKeyboardHidden = hidden;
865     }
866 
867     /**
868      * Set the H/W keyboard's type.
869      *
870      * @param type12Key {@code true} if 12Key.
871      */
setHardware12Keyboard(boolean type12Key)872     public void setHardware12Keyboard(boolean type12Key) {
873         mEnableHardware12Keyboard = type12Key;
874     }
875 
876     /**
877      * Get current keyboard view.
878      */
getKeyboardView()879     public View getKeyboardView() {
880         return mKeyboardView;
881     }
882 
883     /**
884      * Reset the current keyboard
885      */
resetCurrentKeyboard()886     public void resetCurrentKeyboard() {
887         closing();
888         Keyboard keyboard = mCurrentKeyboard;
889         mCurrentKeyboard = null;
890         changeKeyboard(keyboard);
891     }
892 
893     /**
894      * Set the normal keyboard.
895      */
setNormalKeyboard()896     public void setNormalKeyboard() {
897         if (mCurrentKeyboard == null) {
898             return;
899         }
900         mKeyboardView.setKeyboard(mCurrentKeyboard);
901         mKeyboardView.setOnKeyboardActionListener(this);
902         mIsSymbolKeyboard = false;
903     }
904 
905     /**
906      * Set the symbol keyboard.
907      */
setSymbolKeyboard()908     public void setSymbolKeyboard() {
909         mKeyboardView.setKeyboard(mSymbolKeyboard);
910         mKeyboardView.setOnKeyboardActionListener(mSymbolOnKeyboardAction);
911         mIsSymbolKeyboard = true;
912     }
913 }
914