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
17package jp.co.omronsoft.openwnn;
18
19import android.view.KeyEvent;
20import android.view.View;
21import android.view.ViewGroup;
22import android.view.inputmethod.EditorInfo;
23import android.view.inputmethod.InputConnection;
24import android.widget.TextView;
25import android.content.SharedPreferences;
26import android.preference.PreferenceManager;
27import android.content.res.*;
28import android.os.Vibrator;
29import android.media.MediaPlayer;
30import android.content.Context;
31
32import android.util.Log;
33
34import jp.co.omronsoft.openwnn.Keyboard;
35import jp.co.omronsoft.openwnn.KeyboardView;
36import 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 */
43public 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     */
360    public DefaultSoftKeyboard() { }
361
362    /**
363     * Create keyboard views
364     *
365     * @param parent   OpenWnn using the keyboards.
366     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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 */
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     */
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 */
708    public View getCurrentView() {
709        return mMainView;
710    }
711
712    /** @see jp.co.omronsoft.openwnn.InputViewManager#onUpdateState */
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 */
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 */
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 */
782    public void showInputView() {
783        if (mKeyboardView != null) {
784            mKeyboardView.setVisibility(View.VISIBLE);
785        }
786    }
787
788    /** @see jp.co.omronsoft.openwnn.InputViewManager#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 */
797    public void onKey(int primaryCode, int[] keyCodes) { }
798
799    /** @see jp.co.omronsoft.openwnn.KeyboardView.OnKeyboardActionListener#swipeRight */
800    public void swipeRight() { }
801
802    /** @see jp.co.omronsoft.openwnn.KeyboardView.OnKeyboardActionListener#swipeLeft */
803    public void swipeLeft() { }
804
805    /** @see jp.co.omronsoft.openwnn.KeyboardView.OnKeyboardActionListener#swipeDown */
806    public void swipeDown() { }
807
808    /** @see jp.co.omronsoft.openwnn.KeyboardView.OnKeyboardActionListener#swipeUp */
809    public void swipeUp() { }
810
811    /** @see jp.co.omronsoft.openwnn.KeyboardView.OnKeyboardActionListener#onRelease */
812    public void onRelease(int x) { }
813
814    /** @see jp.co.omronsoft.openwnn.KeyboardView.OnKeyboardActionListener#onPress */
815    public void onPress(int x) {
816        playSoundAndVibration();
817    }
818
819    /** @see android.jp.co.omronsoft.openwnn.KeyboardView.OnKeyboardActionListener#onLongPress */
820    public boolean onLongPress(Keyboard.Key key) {
821        return false;
822    }
823
824    /**
825     * Play sound & vibration.
826     */
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 */
838    public void onText(CharSequence text) {}
839
840    /**
841     * Get current key mode.
842     *
843     * @return Current key mode
844     */
845    public int getKeyMode() {
846        return mCurrentKeyMode;
847    }
848
849    /**
850     * Get current keyboard type.
851     *
852     * @return Current keyboard type
853     */
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     */
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     */
872    public void setHardware12Keyboard(boolean type12Key) {
873        mEnableHardware12Keyboard = type12Key;
874    }
875
876    /**
877     * Get current keyboard view.
878     */
879    public View getKeyboardView() {
880        return mKeyboardView;
881    }
882
883    /**
884     * Reset the current keyboard
885     */
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     */
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     */
908    public void setSymbolKeyboard() {
909        mKeyboardView.setKeyboard(mSymbolKeyboard);
910        mKeyboardView.setOnKeyboardActionListener(mSymbolOnKeyboardAction);
911        mIsSymbolKeyboard = true;
912    }
913}
914