17898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project/*
27898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * Copyright (C) 2009 The Android Open Source Project
37898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project *
47898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
57898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * you may not use this file except in compliance with the License.
67898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * You may obtain a copy of the License at
77898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project *
87898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
97898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project *
107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * See the License for the specific language governing permissions and
147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * limitations under the License.
157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */
167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectpackage com.android.inputmethod.pinyin;
187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.app.AlertDialog;
207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.content.BroadcastReceiver;
217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.content.ComponentName;
227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.content.Context;
237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.content.DialogInterface;
247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.content.Intent;
257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.content.ServiceConnection;
267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.content.res.Configuration;
277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.inputmethodservice.InputMethodService;
287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.os.Handler;
297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.os.IBinder;
307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.os.RemoteException;
317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.preference.PreferenceManager;
327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.util.Log;
337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.view.Gravity;
347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.view.GestureDetector;
357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.view.LayoutInflater;
367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.view.KeyEvent;
377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.view.MotionEvent;
387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.view.View;
397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.view.Window;
407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.view.WindowManager;
417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.view.View.MeasureSpec;
427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.view.ViewGroup.LayoutParams;
437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.view.inputmethod.CompletionInfo;
447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.view.inputmethod.InputConnection;
457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.view.inputmethod.EditorInfo;
467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.view.inputmethod.InputMethodManager;
477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.widget.LinearLayout;
487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.widget.PopupWindow;
497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport java.util.ArrayList;
517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport java.util.List;
527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport java.util.Vector;
537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project/**
557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * Main class of the Pinyin input method.
567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */
577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectpublic class PinyinIME extends InputMethodService {
587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    /**
597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * TAG for debug.
607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     */
617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    static final String TAG = "PinyinIME";
627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    /**
647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * If is is true, IME will simulate key events for delete key, and send the
657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * events back to the application.
667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     */
677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private static final boolean SIMULATE_KEY_DELETE = true;
687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    /**
707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * Necessary environment configurations like screen size for this IME.
717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     */
727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private Environment mEnvironment;
737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    /**
757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * Used to switch input mode.
767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     */
777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private InputModeSwitcher mInputModeSwitcher;
787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    /**
807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * Soft keyboard container view to host real soft keyboard view.
817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     */
827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private SkbContainer mSkbContainer;
837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    /**
857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * The floating container which contains the composing view. If necessary,
867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * some other view like candiates container can also be put here.
877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     */
887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private LinearLayout mFloatingContainer;
897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    /**
917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * View to show the composing string.
927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     */
937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private ComposingView mComposingView;
947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    /**
967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * Window to show the composing string.
977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     */
987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private PopupWindow mFloatingWindow;
997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    /**
1017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * Used to show the floating window.
1027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     */
1037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private PopupTimer mFloatingWindowTimer = new PopupTimer();
1047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    /**
1067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * View to show candidates list.
1077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     */
1087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private CandidatesContainer mCandidatesContainer;
1097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    /**
1117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * Balloon used when user presses a candidate.
1127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     */
1137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private BalloonHint mCandidatesBalloon;
1147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    /**
1167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * Used to notify the input method when the user touch a candidate.
1177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     */
1187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private ChoiceNotifier mChoiceNotifier;
1197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    /**
1217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * Used to notify gestures from soft keyboard.
1227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     */
1237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private OnGestureListener mGestureListenerSkb;
1247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    /**
1267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * Used to notify gestures from candidates view.
1277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     */
1287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private OnGestureListener mGestureListenerCandidates;
1297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    /**
1317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * The on-screen movement gesture detector for soft keyboard.
1327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     */
1337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private GestureDetector mGestureDetectorSkb;
1347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    /**
1367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * The on-screen movement gesture detector for candidates view.
1377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     */
1387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private GestureDetector mGestureDetectorCandidates;
1397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    /**
1417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * Option dialog to choose settings and other IMEs.
1427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     */
1437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private AlertDialog mOptionsDialog;
1447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    /**
1467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * Connection used to bind the decoding service.
1477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     */
1487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private PinyinDecoderServiceConnection mPinyinDecoderServiceConnection;
1497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    /**
1517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * The current IME status.
1527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     *
1537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * @see com.android.inputmethod.pinyin.PinyinIME.ImeState
1547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     */
1557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private ImeState mImeState = ImeState.STATE_IDLE;
1567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    /**
1587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * The decoding information, include spelling(Pinyin) string, decoding
1597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * result, etc.
1607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     */
1617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private DecodingInfo mDecInfo = new DecodingInfo();
1627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    /**
1647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * For English input.
1657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     */
1667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private EnglishInputProcessor mImEn;
1677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    // receive ringer mode changes
1697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
1707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        @Override
1717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public void onReceive(Context context, Intent intent) {
1727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            SoundManager.getInstance(context).updateRingerMode();
1737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
1747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    };
1757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    @Override
1777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    public void onCreate() {
1787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mEnvironment = Environment.getInstance();
1797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (mEnvironment.needDebug()) {
1807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            Log.d(TAG, "onCreate.");
1817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
1827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        super.onCreate();
1837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        startPinyinDecoderService();
1857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mImEn = new EnglishInputProcessor();
1867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        Settings.getInstance(PreferenceManager
1877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                .getDefaultSharedPreferences(getApplicationContext()));
1887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mInputModeSwitcher = new InputModeSwitcher(this);
1907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mChoiceNotifier = new ChoiceNotifier(this);
1917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mGestureListenerSkb = new OnGestureListener(false);
1927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mGestureListenerCandidates = new OnGestureListener(true);
1937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mGestureDetectorSkb = new GestureDetector(this, mGestureListenerSkb);
1947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mGestureDetectorCandidates = new GestureDetector(this,
1957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mGestureListenerCandidates);
1967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mEnvironment.onConfigurationChanged(getResources().getConfiguration(),
1987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                this);
1997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
2007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
2017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    @Override
2027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    public void onDestroy() {
2037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (mEnvironment.needDebug()) {
2047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            Log.d(TAG, "onDestroy.");
2057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
2067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        unbindService(mPinyinDecoderServiceConnection);
2077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        Settings.releaseInstance();
2087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        super.onDestroy();
2097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
2107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
2117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    @Override
2127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    public void onConfigurationChanged(Configuration newConfig) {
2137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        Environment env = Environment.getInstance();
2147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (mEnvironment.needDebug()) {
2157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            Log.d(TAG, "onConfigurationChanged");
2167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            Log.d(TAG, "--last config: " + env.getConfiguration().toString());
2177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            Log.d(TAG, "---new config: " + newConfig.toString());
2187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
2197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        // We need to change the local environment first so that UI components
2207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        // can get the environment instance to handle size issues. When
2217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        // super.onConfigurationChanged() is called, onCreateCandidatesView()
2227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        // and onCreateInputView() will be executed if necessary.
2237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        env.onConfigurationChanged(newConfig, this);
2247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
2257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        // Clear related UI of the previous configuration.
2267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (null != mSkbContainer) {
2277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mSkbContainer.dismissPopups();
2287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
2297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (null != mCandidatesBalloon) {
2307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mCandidatesBalloon.dismiss();
2317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
2327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        super.onConfigurationChanged(newConfig);
2337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        resetToIdleState(false);
2347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
2357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
2367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    @Override
2377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    public boolean onKeyDown(int keyCode, KeyEvent event) {
2384248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project        if (processKey(event, 0 != event.getRepeatCount())) return true;
2397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        return super.onKeyDown(keyCode, event);
2407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
2417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
2427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    @Override
2437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    public boolean onKeyUp(int keyCode, KeyEvent event) {
2447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (processKey(event, true)) return true;
2457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        return super.onKeyUp(keyCode, event);
2467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
2477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
2487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private boolean processKey(KeyEvent event, boolean realAction) {
2497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (ImeState.STATE_BYPASS == mImeState) return false;
2507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
2517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        int keyCode = event.getKeyCode();
2527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        // SHIFT-SPACE is used to switch between Chinese and English
2537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        // when HKB is on.
2547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (KeyEvent.KEYCODE_SPACE == keyCode && event.isShiftPressed()) {
2557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (!realAction) return true;
2567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
2577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            updateIcon(mInputModeSwitcher.switchLanguageWithHkb());
2584248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project            resetToIdleState(false);
2597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
2607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            int allMetaState = KeyEvent.META_ALT_ON | KeyEvent.META_ALT_LEFT_ON
2617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    | KeyEvent.META_ALT_RIGHT_ON | KeyEvent.META_SHIFT_ON
2627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    | KeyEvent.META_SHIFT_LEFT_ON
2637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    | KeyEvent.META_SHIFT_RIGHT_ON | KeyEvent.META_SYM_ON;
2647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            getCurrentInputConnection().clearMetaKeyStates(allMetaState);
2657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return true;
2667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
2677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
2687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        // If HKB is on to input English, by-pass the key event so that
2697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        // default key listener will handle it.
2707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (mInputModeSwitcher.isEnglishWithHkb()) {
2717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return false;
2727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
2737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
2747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (processFunctionKeys(keyCode, realAction)) {
2757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return true;
2767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
2777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
2787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        int keyChar = 0;
2797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (keyCode >= KeyEvent.KEYCODE_A && keyCode <= KeyEvent.KEYCODE_Z) {
2807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            keyChar = keyCode - KeyEvent.KEYCODE_A + 'a';
2817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else if (keyCode >= KeyEvent.KEYCODE_0
2827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                && keyCode <= KeyEvent.KEYCODE_9) {
2837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            keyChar = keyCode - KeyEvent.KEYCODE_0 + '0';
2847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else if (keyCode == KeyEvent.KEYCODE_COMMA) {
2857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            keyChar = ',';
2867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else if (keyCode == KeyEvent.KEYCODE_PERIOD) {
2877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            keyChar = '.';
2887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else if (keyCode == KeyEvent.KEYCODE_SPACE) {
2897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            keyChar = ' ';
2907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else if (keyCode == KeyEvent.KEYCODE_APOSTROPHE) {
2917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            keyChar = '\'';
2927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
2937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
2947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (mInputModeSwitcher.isEnglishWithSkb()) {
2957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return mImEn.processKey(getCurrentInputConnection(), event,
2967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    mInputModeSwitcher.isEnglishUpperCaseWithSkb(), realAction);
2977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else if (mInputModeSwitcher.isChineseText()) {
2987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (mImeState == ImeState.STATE_IDLE ||
2997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    mImeState == ImeState.STATE_APP_COMPLETION) {
3007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mImeState = ImeState.STATE_IDLE;
3017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                return processStateIdle(keyChar, keyCode, event, realAction);
3027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            } else if (mImeState == ImeState.STATE_INPUT) {
3037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                return processStateInput(keyChar, keyCode, event, realAction);
3047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            } else if (mImeState == ImeState.STATE_PREDICT) {
3057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                return processStatePredict(keyChar, keyCode, event, realAction);
3067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            } else if (mImeState == ImeState.STATE_COMPOSING) {
3077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                return processStateEditComposing(keyChar, keyCode, event,
3087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        realAction);
3097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
3107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else {
3117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (0 != keyChar && realAction) {
3127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                commitResultText(String.valueOf((char) keyChar));
3137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
3147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
3157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
3167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        return false;
3177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
3187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
3197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    // keyCode can be from both hard key or soft key.
3207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private boolean processFunctionKeys(int keyCode, boolean realAction) {
3217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        // Back key is used to dismiss all popup UI in a soft keyboard.
3227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (keyCode == KeyEvent.KEYCODE_BACK) {
3237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (isInputViewShown()) {
3247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (mSkbContainer.handleBack(realAction)) return true;
3257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
3267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
3277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
3287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        // Chinese related input is handle separately.
3297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (mInputModeSwitcher.isChineseText()) {
3307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return false;
3317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
3327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
3337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (null != mCandidatesContainer && mCandidatesContainer.isShown()
3347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                && !mDecInfo.isCandidatesListEmpty()) {
3357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
3367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (!realAction) return true;
3377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
3387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                chooseCandidate(-1);
3397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                return true;
3407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
3417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
3427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
3437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (!realAction) return true;
3447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mCandidatesContainer.activeCurseBackward();
3457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                return true;
3467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
3477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
3487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
3497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (!realAction) return true;
3507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mCandidatesContainer.activeCurseForward();
3517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                return true;
3527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
3537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
3547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
3557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (!realAction) return true;
3567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mCandidatesContainer.pageBackward(false, true);
3577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                return true;
3587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
3597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
3607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
3617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (!realAction) return true;
3627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mCandidatesContainer.pageForward(false, true);
3637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                return true;
3647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
3657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
3667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (keyCode == KeyEvent.KEYCODE_DEL &&
3677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    ImeState.STATE_PREDICT == mImeState) {
3687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (!realAction) return true;
3697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                resetToIdleState(false);
3707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                return true;
3717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
3727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else {
3737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (keyCode == KeyEvent.KEYCODE_DEL) {
3747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (!realAction) return true;
3757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (SIMULATE_KEY_DELETE) {
3767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    simulateKeyEventDownUp(keyCode);
3777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                } else {
3787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    getCurrentInputConnection().deleteSurroundingText(1, 0);
3797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
3807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                return true;
3817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
3827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (keyCode == KeyEvent.KEYCODE_ENTER) {
3837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (!realAction) return true;
3847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                sendKeyChar('\n');
3857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                return true;
3867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
3877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (keyCode == KeyEvent.KEYCODE_SPACE) {
3887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (!realAction) return true;
3897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                sendKeyChar(' ');
3907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                return true;
3917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
3927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
3937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
3947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        return false;
3957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
3967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
3977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private boolean processStateIdle(int keyChar, int keyCode, KeyEvent event,
3987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            boolean realAction) {
3997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        // In this status, when user presses keys in [a..z], the status will
4007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        // change to input state.
4017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (keyChar >= 'a' && keyChar <= 'z' && !event.isAltPressed()) {
4027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (!realAction) return true;
4037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mDecInfo.addSplChar((char) keyChar, true);
4047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            chooseAndUpdate(-1);
4057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return true;
4067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else if (keyCode == KeyEvent.KEYCODE_DEL) {
4077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (!realAction) return true;
4087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (SIMULATE_KEY_DELETE) {
4097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                simulateKeyEventDownUp(keyCode);
4107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            } else {
4117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                getCurrentInputConnection().deleteSurroundingText(1, 0);
4127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
4137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return true;
4147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else if (keyCode == KeyEvent.KEYCODE_ENTER) {
4157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (!realAction) return true;
4167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            sendKeyChar('\n');
4177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return true;
4187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else if (keyCode == KeyEvent.KEYCODE_ALT_LEFT
4197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                || keyCode == KeyEvent.KEYCODE_ALT_RIGHT
4207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                || keyCode == KeyEvent.KEYCODE_SHIFT_LEFT
4217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                || keyCode == KeyEvent.KEYCODE_SHIFT_RIGHT) {
4227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return true;
4237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else if (event.isAltPressed()) {
4247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            char fullwidth_char = KeyMapDream.getChineseLabel(keyCode);
4257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (0 != fullwidth_char) {
4267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (realAction) {
4277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    String result = String.valueOf(fullwidth_char);
4287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    commitResultText(result);
4297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
4307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                return true;
4317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            } else {
4327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (keyCode >= KeyEvent.KEYCODE_A
4337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        && keyCode <= KeyEvent.KEYCODE_Z) {
4347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    return true;
4357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
4367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
4377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else if (keyChar != 0 && keyChar != '\t') {
4387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (realAction) {
4397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (keyChar == ',' || keyChar == '.') {
4407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    inputCommaPeriod("", keyChar, false, ImeState.STATE_IDLE);
4417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                } else {
4427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    if (0 != keyChar) {
4437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        String result = String.valueOf((char) keyChar);
4447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        commitResultText(result);
4457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    }
4467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
4477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
4487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return true;
4497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
4507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        return false;
4517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
4527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
4537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private boolean processStateInput(int keyChar, int keyCode, KeyEvent event,
4547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            boolean realAction) {
4554248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project        // If ALT key is pressed, input alternative key. But if the
4564248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project        // alternative key is quote key, it will be used for input a splitter
4574248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project        // in Pinyin string.
4584248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project        if (event.isAltPressed()) {
4594248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project            if ('\'' != event.getUnicodeChar(event.getMetaState())) {
4604248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                if (realAction) {
4614248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                    char fullwidth_char = KeyMapDream.getChineseLabel(keyCode);
4624248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                    if (0 != fullwidth_char) {
4634248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                        commitResultText(mDecInfo
4644248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                                .getCurrentFullSent(mCandidatesContainer
4654248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                                        .getActiveCandiatePos()) +
4664248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                                        String.valueOf(fullwidth_char));
4674248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                        resetToIdleState(false);
4684248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                    }
4694248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                }
4704248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                return true;
4714248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project            } else {
4724248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                keyChar = '\'';
4734248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project            }
4744248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project        }
4754248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project
4767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (keyChar >= 'a' && keyChar <= 'z' || keyChar == '\''
4777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                && !mDecInfo.charBeforeCursorIsSeparator()
4787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                || keyCode == KeyEvent.KEYCODE_DEL) {
4797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (!realAction) return true;
4807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return processSurfaceChange(keyChar, keyCode);
4817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else if (keyChar == ',' || keyChar == '.') {
4827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (!realAction) return true;
4837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            inputCommaPeriod(mDecInfo.getCurrentFullSent(mCandidatesContainer
4847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    .getActiveCandiatePos()), keyChar, true,
4857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    ImeState.STATE_IDLE);
4867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return true;
4877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else if (keyCode == KeyEvent.KEYCODE_DPAD_UP
4887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                || keyCode == KeyEvent.KEYCODE_DPAD_DOWN
4897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                || keyCode == KeyEvent.KEYCODE_DPAD_LEFT
4907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
4917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (!realAction) return true;
4927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
4937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
4947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mCandidatesContainer.activeCurseBackward();
4957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            } else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
4967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mCandidatesContainer.activeCurseForward();
4977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            } else if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
4987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                // If it has been the first page, a up key will shift
4997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                // the state to edit composing string.
5007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (!mCandidatesContainer.pageBackward(false, true)) {
5017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    mCandidatesContainer.enableActiveHighlight(false);
5027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    changeToStateComposing(true);
5037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    updateComposingText(true);
5047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
5057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            } else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
5067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mCandidatesContainer.pageForward(false, true);
5077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
5087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return true;
5097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else if (keyCode >= KeyEvent.KEYCODE_1
5107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                && keyCode <= KeyEvent.KEYCODE_9) {
5117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (!realAction) return true;
5127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
5137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            int activePos = keyCode - KeyEvent.KEYCODE_1;
5147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            int currentPage = mCandidatesContainer.getCurrentPage();
5157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (activePos < mDecInfo.getCurrentPageSize(currentPage)) {
5167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                activePos = activePos
5177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        + mDecInfo.getCurrentPageStart(currentPage);
5187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (activePos >= 0) {
5197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    chooseAndUpdate(activePos);
5207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
5217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
5227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return true;
5237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else if (keyCode == KeyEvent.KEYCODE_ENTER) {
5247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (!realAction) return true;
5257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (mInputModeSwitcher.isEnterNoramlState()) {
5267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                commitResultText(mDecInfo.getOrigianlSplStr().toString());
5274248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                resetToIdleState(false);
5287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            } else {
5297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                commitResultText(mDecInfo
5307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        .getCurrentFullSent(mCandidatesContainer
5317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                                .getActiveCandiatePos()));
5327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                sendKeyChar('\n');
5334248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                resetToIdleState(false);
5347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
5357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return true;
5367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER
5377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                || keyCode == KeyEvent.KEYCODE_SPACE) {
5387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (!realAction) return true;
5397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            chooseCandidate(-1);
5407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return true;
5417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else if (keyCode == KeyEvent.KEYCODE_BACK) {
5427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (!realAction) return true;
5434248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project            resetToIdleState(false);
5447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            requestHideSelf(0);
5457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return true;
5467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
5477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        return false;
5487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
5497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
5507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private boolean processStatePredict(int keyChar, int keyCode,
5517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            KeyEvent event, boolean realAction) {
5527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (!realAction) return true;
5537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
5544248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project        // If ALT key is pressed, input alternative key.
5554248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project        if (event.isAltPressed()) {
5564248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project            char fullwidth_char = KeyMapDream.getChineseLabel(keyCode);
5574248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project            if (0 != fullwidth_char) {
5584248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                commitResultText(mDecInfo.getCandidate(mCandidatesContainer
5594248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                                .getActiveCandiatePos()) +
5604248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                                String.valueOf(fullwidth_char));
5614248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                resetToIdleState(false);
5624248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project            }
5634248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project            return true;
5644248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project        }
5654248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project
5667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        // In this status, when user presses keys in [a..z], the status will
5677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        // change to input state.
5687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (keyChar >= 'a' && keyChar <= 'z') {
5697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            changeToStateInput(true);
5707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mDecInfo.addSplChar((char) keyChar, true);
5717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            chooseAndUpdate(-1);
5727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else if (keyChar == ',' || keyChar == '.') {
5737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            inputCommaPeriod("", keyChar, true, ImeState.STATE_IDLE);
5747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else if (keyCode == KeyEvent.KEYCODE_DPAD_UP
5757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                || keyCode == KeyEvent.KEYCODE_DPAD_DOWN
5767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                || keyCode == KeyEvent.KEYCODE_DPAD_LEFT
5777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
5787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
5797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mCandidatesContainer.activeCurseBackward();
5807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
5817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
5827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mCandidatesContainer.activeCurseForward();
5837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
5847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
5857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mCandidatesContainer.pageBackward(false, true);
5867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
5877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
5887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mCandidatesContainer.pageForward(false, true);
5897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
5907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else if (keyCode == KeyEvent.KEYCODE_DEL) {
5917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            resetToIdleState(false);
5927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else if (keyCode == KeyEvent.KEYCODE_BACK) {
5937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            resetToIdleState(false);
5947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            requestHideSelf(0);
5954248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project        } else if (keyCode >= KeyEvent.KEYCODE_1
5967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                && keyCode <= KeyEvent.KEYCODE_9) {
5977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            int activePos = keyCode - KeyEvent.KEYCODE_1;
5987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            int currentPage = mCandidatesContainer.getCurrentPage();
5997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (activePos < mDecInfo.getCurrentPageSize(currentPage)) {
6007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                activePos = activePos
6017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        + mDecInfo.getCurrentPageStart(currentPage);
6027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (activePos >= 0) {
6037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    chooseAndUpdate(activePos);
6047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
6057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
6067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else if (keyCode == KeyEvent.KEYCODE_ENTER) {
6077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            sendKeyChar('\n');
6087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            resetToIdleState(false);
6097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER
6107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                || keyCode == KeyEvent.KEYCODE_SPACE) {
6117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            chooseCandidate(-1);
6127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
6137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
6147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        return true;
6157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
6167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
6177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private boolean processStateEditComposing(int keyChar, int keyCode,
6187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            KeyEvent event, boolean realAction) {
6197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (!realAction) return true;
6207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
6214248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project        ComposingView.ComposingStatus cmpsvStatus =
6224248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                mComposingView.getComposingStatus();
6234248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project
6244248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project        // If ALT key is pressed, input alternative key. But if the
6254248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project        // alternative key is quote key, it will be used for input a splitter
6264248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project        // in Pinyin string.
6274248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project        if (event.isAltPressed()) {
6284248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project            if ('\'' != event.getUnicodeChar(event.getMetaState())) {
6294248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                char fullwidth_char = KeyMapDream.getChineseLabel(keyCode);
6304248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                if (0 != fullwidth_char) {
6314248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                    String retStr;
6324248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                    if (ComposingView.ComposingStatus.SHOW_STRING_LOWERCASE ==
6334248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                            cmpsvStatus) {
6344248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                        retStr = mDecInfo.getOrigianlSplStr().toString();
6354248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                    } else {
6364248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                        retStr = mDecInfo.getComposingStr();
6374248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                    }
6384248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                    commitResultText(retStr + String.valueOf(fullwidth_char));
6394248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                    resetToIdleState(false);
6404248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                }
6414248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                return true;
6424248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project            } else {
6434248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                keyChar = '\'';
6444248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project            }
6454248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project        }
6464248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project
6477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
6487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (!mDecInfo.selectionFinished()) {
6497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                changeToStateInput(true);
6507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
6517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT
6527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
6537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mComposingView.moveCursor(keyCode);
6547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else if ((keyCode == KeyEvent.KEYCODE_ENTER && mInputModeSwitcher
6557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                .isEnterNoramlState())
6567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                || keyCode == KeyEvent.KEYCODE_DPAD_CENTER
6577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                || keyCode == KeyEvent.KEYCODE_SPACE) {
6587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (ComposingView.ComposingStatus.SHOW_STRING_LOWERCASE == cmpsvStatus) {
6597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                String str = mDecInfo.getOrigianlSplStr().toString();
6607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (!tryInputRawUnicode(str)) {
6617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    commitResultText(str);
6627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
6637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            } else if (ComposingView.ComposingStatus.EDIT_PINYIN == cmpsvStatus) {
6647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                String str = mDecInfo.getComposingStr();
6657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (!tryInputRawUnicode(str)) {
6667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    commitResultText(str);
6677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
6687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            } else {
6697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                commitResultText(mDecInfo.getComposingStr());
6707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
6717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            resetToIdleState(false);
6727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else if (keyCode == KeyEvent.KEYCODE_ENTER
6737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                && !mInputModeSwitcher.isEnterNoramlState()) {
6747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            String retStr;
6757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (!mDecInfo.isCandidatesListEmpty()) {
6767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                retStr = mDecInfo.getCurrentFullSent(mCandidatesContainer
6777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        .getActiveCandiatePos());
6787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            } else {
6797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                retStr = mDecInfo.getComposingStr();
6807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
6817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            commitResultText(retStr);
6827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            sendKeyChar('\n');
6837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            resetToIdleState(false);
6847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else if (keyCode == KeyEvent.KEYCODE_BACK) {
6857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            resetToIdleState(false);
6867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            requestHideSelf(0);
6877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return true;
6887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else {
6897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return processSurfaceChange(keyChar, keyCode);
6907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
6917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        return true;
6927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
6937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
6947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private boolean tryInputRawUnicode(String str) {
6957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (str.length() > 7) {
6967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (str.substring(0, 7).compareTo("unicode") == 0) {
6977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                try {
6987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    String digitStr = str.substring(7);
6997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    int startPos = 0;
7007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    int radix = 10;
7017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    if (digitStr.length() > 2 && digitStr.charAt(0) == '0'
7027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                            && digitStr.charAt(1) == 'x') {
7037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        startPos = 2;
7047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        radix = 16;
7057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    }
7067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    digitStr = digitStr.substring(startPos);
7077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    int unicode = Integer.parseInt(digitStr, radix);
7087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    if (unicode > 0) {
7097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        char low = (char) (unicode & 0x0000ffff);
7107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        char high = (char) ((unicode & 0xffff0000) >> 16);
7117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        commitResultText(String.valueOf(low));
7127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        if (0 != high) {
7137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                            commitResultText(String.valueOf(high));
7147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        }
7157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    }
7167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    return true;
7177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                } catch (NumberFormatException e) {
7187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    return false;
7197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
7207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            } else if (str.substring(str.length() - 7, str.length()).compareTo(
7217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    "unicode") == 0) {
7227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                String resultStr = "";
7237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                for (int pos = 0; pos < str.length() - 7; pos++) {
7247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    if (pos > 0) {
7257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        resultStr += " ";
7267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    }
7277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
7287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    resultStr += "0x" + Integer.toHexString(str.charAt(pos));
7297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
7307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                commitResultText(String.valueOf(resultStr));
7317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                return true;
7327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
7337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
7347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        return false;
7357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
7367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
7377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private boolean processSurfaceChange(int keyChar, int keyCode) {
7387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (mDecInfo.isSplStrFull() && KeyEvent.KEYCODE_DEL != keyCode) {
7397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return true;
7407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
7417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
7427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if ((keyChar >= 'a' && keyChar <= 'z')
7437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                || (keyChar == '\'' && !mDecInfo.charBeforeCursorIsSeparator())
7447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                || (((keyChar >= '0' && keyChar <= '9') || keyChar == ' ') && ImeState.STATE_COMPOSING == mImeState)) {
7457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mDecInfo.addSplChar((char) keyChar, false);
7467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            chooseAndUpdate(-1);
7477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else if (keyCode == KeyEvent.KEYCODE_DEL) {
7487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mDecInfo.prepareDeleteBeforeCursor();
7497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            chooseAndUpdate(-1);
7507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
7517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        return true;
7527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
7537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
7547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private void changeToStateComposing(boolean updateUi) {
7557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mImeState = ImeState.STATE_COMPOSING;
7567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (!updateUi) return;
7577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
7587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (null != mSkbContainer && mSkbContainer.isShown()) {
7597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mSkbContainer.toggleCandidateMode(true);
7607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
7617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
7627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
7637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private void changeToStateInput(boolean updateUi) {
7647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mImeState = ImeState.STATE_INPUT;
7657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (!updateUi) return;
7667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
7677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (null != mSkbContainer && mSkbContainer.isShown()) {
7687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mSkbContainer.toggleCandidateMode(true);
7697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
7707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        showCandidateWindow(true);
7717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
7727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
7737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private void simulateKeyEventDownUp(int keyCode) {
7747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        InputConnection ic = getCurrentInputConnection();
7757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (null == ic) return;
7767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
7777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, keyCode));
7787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, keyCode));
7797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
7807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
7817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private void commitResultText(String resultText) {
7827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        InputConnection ic = getCurrentInputConnection();
7834248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project        if (null != ic) ic.commitText(resultText, 1);
7847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (null != mComposingView) {
7857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mComposingView.setVisibility(View.INVISIBLE);
7867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mComposingView.invalidate();
7877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
7887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
7897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
7907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private void updateComposingText(boolean visible) {
7917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (!visible) {
7927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mComposingView.setVisibility(View.INVISIBLE);
7937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else {
7947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mComposingView.setDecodingInfo(mDecInfo, mImeState);
7957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mComposingView.setVisibility(View.VISIBLE);
7967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
7977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mComposingView.invalidate();
7987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
7997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
8007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private void inputCommaPeriod(String preEdit, int keyChar,
8017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            boolean dismissCandWindow, ImeState nextState) {
8027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (keyChar == ',')
8037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            preEdit += '\uff0c';
8047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        else if (keyChar == '.')
8057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            preEdit += '\u3002';
8067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        else
8077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return;
8087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        commitResultText(preEdit);
8097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (dismissCandWindow) resetCandidateWindow();
8107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mImeState = nextState;
8117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
8127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
8137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private void resetToIdleState(boolean resetInlineText) {
8147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (ImeState.STATE_IDLE == mImeState) return;
8157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
8167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mImeState = ImeState.STATE_IDLE;
8177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mDecInfo.reset();
8187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
8197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (null != mComposingView) mComposingView.reset();
8207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (resetInlineText) commitResultText("");
8217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        resetCandidateWindow();
8227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
8237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
8247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private void chooseAndUpdate(int candId) {
8257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (!mInputModeSwitcher.isChineseText()) {
8267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            String choice = mDecInfo.getCandidate(candId);
8277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (null != choice) {
8287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                commitResultText(choice);
8297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
8307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            resetToIdleState(false);
8317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return;
8327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
8337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
8347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (ImeState.STATE_PREDICT != mImeState) {
8357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            // Get result candidate list, if choice_id < 0, do a new decoding.
8367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            // If choice_id >=0, select the candidate, and get the new candidate
8377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            // list.
8387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mDecInfo.chooseDecodingCandidate(candId);
8397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else {
8407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            // Choose a prediction item.
8417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mDecInfo.choosePredictChoice(candId);
8427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
8437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
8447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (mDecInfo.getComposingStr().length() > 0) {
8457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            String resultStr;
8467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            resultStr = mDecInfo.getComposingStrActivePart();
8477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
8487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            // choiceId >= 0 means user finishes a choice selection.
8497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (candId >= 0 && mDecInfo.canDoPrediction()) {
8507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                commitResultText(resultStr);
8517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mImeState = ImeState.STATE_PREDICT;
8527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (null != mSkbContainer && mSkbContainer.isShown()) {
8537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    mSkbContainer.toggleCandidateMode(false);
8547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
8557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                // Try to get the prediction list.
8567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (Settings.getPrediction()) {
8577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    InputConnection ic = getCurrentInputConnection();
8587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    if (null != ic) {
8597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        CharSequence cs = ic.getTextBeforeCursor(3, 0);
8607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        if (null != cs) {
8617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                            mDecInfo.preparePredicts(cs);
8627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        }
8637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    }
8647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                } else {
8657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    mDecInfo.resetCandidates();
8667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
8677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
8687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (mDecInfo.mCandidatesList.size() > 0) {
8697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    showCandidateWindow(false);
8707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                } else {
8717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    resetToIdleState(false);
8727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
8737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            } else {
8747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (ImeState.STATE_IDLE == mImeState) {
8757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    if (mDecInfo.getSplStrDecodedLen() == 0) {
8767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        changeToStateComposing(true);
8777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    } else {
8787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        changeToStateInput(true);
8797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    }
8807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                } else {
8817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    if (mDecInfo.selectionFinished()) {
8827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        changeToStateComposing(true);
8837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    }
8847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
8857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                showCandidateWindow(true);
8867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
8877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else {
8887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            resetToIdleState(false);
8897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
8907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
8917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
8927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    // If activeCandNo is less than 0, get the current active candidate number
8937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    // from candidate view, otherwise use activeCandNo.
8947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private void chooseCandidate(int activeCandNo) {
8957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (activeCandNo < 0) {
8967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            activeCandNo = mCandidatesContainer.getActiveCandiatePos();
8977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
8987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (activeCandNo >= 0) {
8997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            chooseAndUpdate(activeCandNo);
9007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
9017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
9027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
9037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private boolean startPinyinDecoderService() {
9047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (null == mDecInfo.mIPinyinDecoderService) {
9057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            Intent serviceIntent = new Intent();
9067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            serviceIntent.setClass(this, PinyinDecoderService.class);
9077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
9087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (null == mPinyinDecoderServiceConnection) {
9097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mPinyinDecoderServiceConnection = new PinyinDecoderServiceConnection();
9107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
9117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
9127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            // Bind service
9137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (bindService(serviceIntent, mPinyinDecoderServiceConnection,
9147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    Context.BIND_AUTO_CREATE)) {
9157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                return true;
9167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            } else {
9177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                return false;
9187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
9197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
9207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        return true;
9217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
9227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
9237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    @Override
9247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    public View onCreateCandidatesView() {
9257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (mEnvironment.needDebug()) {
9267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            Log.d(TAG, "onCreateCandidatesView.");
9277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
9287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
9297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        LayoutInflater inflater = getLayoutInflater();
9307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        // Inflate the floating container view
9317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mFloatingContainer = (LinearLayout) inflater.inflate(
9327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                R.layout.floating_container, null);
9337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
9347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        // The first child is the composing view.
9357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mComposingView = (ComposingView) mFloatingContainer.getChildAt(0);
9367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
9377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mCandidatesContainer = (CandidatesContainer) inflater.inflate(
9387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                R.layout.candidates_container, null);
9397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
9407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        // Create balloon hint for candidates view.
9417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mCandidatesBalloon = new BalloonHint(this, mCandidatesContainer,
9427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                MeasureSpec.UNSPECIFIED);
9437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mCandidatesBalloon.setBalloonBackground(getResources().getDrawable(
9447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                R.drawable.candidate_balloon_bg));
9457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mCandidatesContainer.initialize(mChoiceNotifier, mCandidatesBalloon,
9467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mGestureDetectorCandidates);
9477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
9487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        // The floating window
9497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (null != mFloatingWindow && mFloatingWindow.isShowing()) {
9507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mFloatingWindowTimer.cancelShowing();
9517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mFloatingWindow.dismiss();
9527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
9537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mFloatingWindow = new PopupWindow(this);
9547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mFloatingWindow.setClippingEnabled(false);
9557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mFloatingWindow.setBackgroundDrawable(null);
9567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mFloatingWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
9577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mFloatingWindow.setContentView(mFloatingContainer);
9587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
9597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        setCandidatesViewShown(true);
9607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        return mCandidatesContainer;
9617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
9627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
9637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    public void responseSoftKeyEvent(SoftKey sKey) {
9647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (null == sKey) return;
9657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
9667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        InputConnection ic = getCurrentInputConnection();
9677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (ic == null) return;
9687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
9697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        int keyCode = sKey.getKeyCode();
9707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        // Process some general keys, including KEYCODE_DEL, KEYCODE_SPACE,
9717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        // KEYCODE_ENTER and KEYCODE_DPAD_CENTER.
9727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (sKey.isKeyCodeKey()) {
9737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (processFunctionKeys(keyCode, true)) return;
9747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
9757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
9767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (sKey.isUserDefKey()) {
9777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            updateIcon(mInputModeSwitcher.switchModeForUserKey(keyCode));
9784248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project            resetToIdleState(false);
9797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mSkbContainer.updateInputMode();
9807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else {
9817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (sKey.isKeyCodeKey()) {
9827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                KeyEvent eDown = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
9837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        keyCode, 0, 0, 0, 0, KeyEvent.FLAG_SOFT_KEYBOARD);
9847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                KeyEvent eUp = new KeyEvent(0, 0, KeyEvent.ACTION_UP, keyCode,
9857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        0, 0, 0, 0, KeyEvent.FLAG_SOFT_KEYBOARD);
9867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
9877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                onKeyDown(keyCode, eDown);
9887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                onKeyUp(keyCode, eUp);
9897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            } else if (sKey.isUniStrKey()) {
9907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                boolean kUsed = false;
9917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                String keyLabel = sKey.getKeyLabel();
9927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (mInputModeSwitcher.isChineseTextWithSkb()
9937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        && (ImeState.STATE_INPUT == mImeState || ImeState.STATE_COMPOSING == mImeState)) {
9947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    if (mDecInfo.length() > 0 && keyLabel.length() == 1
9957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                            && keyLabel.charAt(0) == '\'') {
9967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        processSurfaceChange('\'', 0);
9977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        kUsed = true;
9987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    }
9997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
10007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (!kUsed) {
10017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    if (ImeState.STATE_INPUT == mImeState) {
10027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        commitResultText(mDecInfo
10037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                                .getCurrentFullSent(mCandidatesContainer
10047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                                        .getActiveCandiatePos()));
10057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    } else if (ImeState.STATE_COMPOSING == mImeState) {
10067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        commitResultText(mDecInfo.getComposingStr());
10077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    }
10087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    commitResultText(keyLabel);
10097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    resetToIdleState(false);
10107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
10117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
10127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
10137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            // If the current soft keyboard is not sticky, IME needs to go
10147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            // back to the previous soft keyboard automatically.
10157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (!mSkbContainer.isCurrentSkbSticky()) {
10167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                updateIcon(mInputModeSwitcher.requestBackToPreviousSkb());
10174248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                resetToIdleState(false);
10187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mSkbContainer.updateInputMode();
10197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
10207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
10217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
10227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
10237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private void showCandidateWindow(boolean showComposingView) {
10247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (mEnvironment.needDebug()) {
10257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            Log.d(TAG, "Candidates window is shown. Parent = "
10267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    + mCandidatesContainer);
10277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
10287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
10297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        setCandidatesViewShown(true);
10307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
10317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (null != mSkbContainer) mSkbContainer.requestLayout();
10327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
10337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (null == mCandidatesContainer) {
10347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            resetToIdleState(false);
10357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return;
10367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
10377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
10387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        updateComposingText(showComposingView);
10397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mCandidatesContainer.showCandidates(mDecInfo,
10407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                ImeState.STATE_COMPOSING != mImeState);
10417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mFloatingWindowTimer.postShowFloatingWindow();
10427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
10437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
10447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private void dismissCandidateWindow() {
10457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (mEnvironment.needDebug()) {
10467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            Log.d(TAG, "Candidates window is to be dismissed");
10477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
10487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (null == mCandidatesContainer) return;
10497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        try {
10507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mFloatingWindowTimer.cancelShowing();
10517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mFloatingWindow.dismiss();
10527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } catch (Exception e) {
10537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            Log.e(TAG, "Fail to show the PopupWindow.");
10547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
10557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        setCandidatesViewShown(false);
10567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
10577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (null != mSkbContainer && mSkbContainer.isShown()) {
10587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mSkbContainer.toggleCandidateMode(false);
10597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
10607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
10617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
10627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private void resetCandidateWindow() {
10637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (mEnvironment.needDebug()) {
10647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            Log.d(TAG, "Candidates window is to be reset");
10657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
10667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (null == mCandidatesContainer) return;
10677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        try {
10687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mFloatingWindowTimer.cancelShowing();
10697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mFloatingWindow.dismiss();
10707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } catch (Exception e) {
10717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            Log.e(TAG, "Fail to show the PopupWindow.");
10727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
10737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
10747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (null != mSkbContainer && mSkbContainer.isShown()) {
10757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mSkbContainer.toggleCandidateMode(false);
10767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
10777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
10787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mDecInfo.resetCandidates();
10797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
10807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (null != mCandidatesContainer && mCandidatesContainer.isShown()) {
10817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            showCandidateWindow(false);
10827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
10837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
10847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
10857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private void updateIcon(int iconId) {
10867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (iconId > 0) {
10877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            showStatusIcon(iconId);
10887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else {
10897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            hideStatusIcon();
10907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
10917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
10927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
10937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    @Override
10947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    public View onCreateInputView() {
10957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (mEnvironment.needDebug()) {
10967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            Log.d(TAG, "onCreateInputView.");
10977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
10987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        LayoutInflater inflater = getLayoutInflater();
10997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mSkbContainer = (SkbContainer) inflater.inflate(R.layout.skb_container,
11007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                null);
11017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mSkbContainer.setService(this);
11027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mSkbContainer.setInputModeSwitcher(mInputModeSwitcher);
11037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mSkbContainer.setGestureDetector(mGestureDetectorSkb);
11047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        return mSkbContainer;
11057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
11067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
11077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    @Override
11087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    public void onStartInput(EditorInfo editorInfo, boolean restarting) {
11097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (mEnvironment.needDebug()) {
11107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            Log.d(TAG, "onStartInput " + " ccontentType: "
11117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    + String.valueOf(editorInfo.inputType) + " Restarting:"
11127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    + String.valueOf(restarting));
11137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
11147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        updateIcon(mInputModeSwitcher.requestInputWithHkb(editorInfo));
11157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        resetToIdleState(false);
11167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
11177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
11187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    @Override
11197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    public void onStartInputView(EditorInfo editorInfo, boolean restarting) {
11207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (mEnvironment.needDebug()) {
11217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            Log.d(TAG, "onStartInputView " + " contentType: "
11227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    + String.valueOf(editorInfo.inputType) + " Restarting:"
11237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    + String.valueOf(restarting));
11247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
11257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        updateIcon(mInputModeSwitcher.requestInputWithSkb(editorInfo));
11267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        resetToIdleState(false);
11277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mSkbContainer.updateInputMode();
11287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        setCandidatesViewShown(false);
11297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
11307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
11317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    @Override
11327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    public void onFinishInputView(boolean finishingInput) {
11337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (mEnvironment.needDebug()) {
11347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            Log.d(TAG, "onFinishInputView.");
11357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
11367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        resetToIdleState(false);
11377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        super.onFinishInputView(finishingInput);
11387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
11397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
11407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    @Override
11417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    public void onFinishInput() {
11427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (mEnvironment.needDebug()) {
11437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            Log.d(TAG, "onFinishInput.");
11447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
11457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        resetToIdleState(false);
11467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        super.onFinishInput();
11477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
11487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
11497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    @Override
11507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    public void onFinishCandidatesView(boolean finishingInput) {
11517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (mEnvironment.needDebug()) {
11527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            Log.d(TAG, "onFinishCandidateView.");
11537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
11547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        resetToIdleState(false);
11557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        super.onFinishCandidatesView(finishingInput);
11567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
11577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
11587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    @Override public void onDisplayCompletions(CompletionInfo[] completions) {
11597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (!isFullscreenMode()) return;
11607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (null == completions || completions.length <= 0) return;
11617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (null == mSkbContainer || !mSkbContainer.isShown()) return;
11627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
11637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (!mInputModeSwitcher.isChineseText() ||
11647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                ImeState.STATE_IDLE == mImeState ||
11657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                ImeState.STATE_PREDICT == mImeState) {
11667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mImeState = ImeState.STATE_APP_COMPLETION;
11677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mDecInfo.prepareAppCompletions(completions);
11687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            showCandidateWindow(false);
11697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
11707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
11717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
11727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private void onChoiceTouched(int activeCandNo) {
11737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (mImeState == ImeState.STATE_COMPOSING) {
11747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            changeToStateInput(true);
11757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else if (mImeState == ImeState.STATE_INPUT
11767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                || mImeState == ImeState.STATE_PREDICT) {
11777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            chooseCandidate(activeCandNo);
11787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else if (mImeState == ImeState.STATE_APP_COMPLETION) {
11797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (null != mDecInfo.mAppCompletions && activeCandNo >= 0 &&
11807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    activeCandNo < mDecInfo.mAppCompletions.length) {
11817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                CompletionInfo ci = mDecInfo.mAppCompletions[activeCandNo];
11827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (null != ci) {
11837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    InputConnection ic = getCurrentInputConnection();
11847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    ic.commitCompletion(ci);
11857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
11867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
11877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            resetToIdleState(false);
11887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
11897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
11907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
11917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    @Override
11927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    public void requestHideSelf(int flags) {
11937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (mEnvironment.needDebug()) {
11947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            Log.d(TAG, "DimissSoftInput.");
11957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
11967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        dismissCandidateWindow();
11977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (null != mSkbContainer && mSkbContainer.isShown()) {
11987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mSkbContainer.dismissPopups();
11997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
12007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        super.requestHideSelf(flags);
12017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
12027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
12037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    public void showOptionsMenu() {
12047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        AlertDialog.Builder builder = new AlertDialog.Builder(this);
12057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        builder.setCancelable(true);
12067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        builder.setIcon(R.drawable.app_icon);
12077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        builder.setNegativeButton(android.R.string.cancel, null);
12087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        CharSequence itemSettings = getString(R.string.ime_settings_activity_name);
12097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        CharSequence itemInputMethod = getString(com.android.internal.R.string.inputMethod);
12107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        builder.setItems(new CharSequence[] {itemSettings, itemInputMethod},
12117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                new DialogInterface.OnClickListener() {
12127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
12137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    public void onClick(DialogInterface di, int position) {
12147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        di.dismiss();
12157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        switch (position) {
12167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        case 0:
12177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                            launchSettings();
12187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                            break;
12197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        case 1:
12207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                            InputMethodManager.getInstance(PinyinIME.this)
12217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                                    .showInputMethodPicker();
12227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                            break;
12237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        }
12247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    }
12257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                });
12267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        builder.setTitle(getString(R.string.ime_name));
12277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mOptionsDialog = builder.create();
12287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        Window window = mOptionsDialog.getWindow();
12297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        WindowManager.LayoutParams lp = window.getAttributes();
12307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        lp.token = mSkbContainer.getWindowToken();
12317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
12327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        window.setAttributes(lp);
12337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
12347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mOptionsDialog.show();
12357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
12367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
12377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private void launchSettings() {
12387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        Intent intent = new Intent();
12397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        intent.setClass(PinyinIME.this, SettingsActivity.class);
12407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        startActivity(intent);
12427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
12437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
12447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private class PopupTimer extends Handler implements Runnable {
12457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        private int mParentLocation[] = new int[2];
12467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
12477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        void postShowFloatingWindow() {
12487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mFloatingContainer.measure(LayoutParams.WRAP_CONTENT,
12497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    LayoutParams.WRAP_CONTENT);
12507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mFloatingWindow.setWidth(mFloatingContainer.getMeasuredWidth());
12517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mFloatingWindow.setHeight(mFloatingContainer.getMeasuredHeight());
12527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            post(this);
12537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
12547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
12557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        void cancelShowing() {
12567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (mFloatingWindow.isShowing()) {
12577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mFloatingWindow.dismiss();
12587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
12597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            removeCallbacks(this);
12607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
12617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
12627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public void run() {
12637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mCandidatesContainer.getLocationInWindow(mParentLocation);
12647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
12657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (!mFloatingWindow.isShowing()) {
12667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mFloatingWindow.showAtLocation(mCandidatesContainer,
12677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        Gravity.LEFT | Gravity.TOP, mParentLocation[0],
12687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        mParentLocation[1] -mFloatingWindow.getHeight());
12697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            } else {
12707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mFloatingWindow
12717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                .update(mParentLocation[0],
12727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        mParentLocation[1] - mFloatingWindow.getHeight(),
12737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        mFloatingWindow.getWidth(),
12747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        mFloatingWindow.getHeight());
12757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
12767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
12777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
12787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
12797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    /**
12807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * Used to notify IME that the user selects a candidate or performs an
12817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * gesture.
12827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     */
12837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    public class ChoiceNotifier extends Handler implements
12847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            CandidateViewListener {
12857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        PinyinIME mIme;
12867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
12877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        ChoiceNotifier(PinyinIME ime) {
12887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mIme = ime;
12897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
12907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
12917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public void onClickChoice(int choiceId) {
12927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (choiceId >= 0) {
12937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mIme.onChoiceTouched(choiceId);
12947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
12957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
12967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
12977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public void onToLeftGesture() {
12987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (ImeState.STATE_COMPOSING == mImeState) {
12997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                changeToStateInput(true);
13007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
13017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mCandidatesContainer.pageForward(true, false);
13027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
13037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
13047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public void onToRightGesture() {
13057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (ImeState.STATE_COMPOSING == mImeState) {
13067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                changeToStateInput(true);
13077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
13087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mCandidatesContainer.pageBackward(true, false);
13097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
13107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
13117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public void onToTopGesture() {
13127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
13137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
13147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public void onToBottomGesture() {
13157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
13167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
13177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
13187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    public class OnGestureListener extends
13197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            GestureDetector.SimpleOnGestureListener {
13207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /**
13217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * When user presses and drags, the minimum x-distance to make a
13227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * response to the drag event.
13237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         */
13247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        private static final int MIN_X_FOR_DRAG = 60;
13257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
13267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /**
13277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * When user presses and drags, the minimum y-distance to make a
13287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * response to the drag event.
13297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         */
13307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        private static final int MIN_Y_FOR_DRAG = 40;
13317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
13327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /**
13337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * Velocity threshold for a screen-move gesture. If the minimum
13347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * x-velocity is less than it, no gesture.
13357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         */
13367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        static private final float VELOCITY_THRESHOLD_X1 = 0.3f;
13377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
13387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /**
13397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * Velocity threshold for a screen-move gesture. If the maximum
13407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * x-velocity is less than it, no gesture.
13417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         */
13427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        static private final float VELOCITY_THRESHOLD_X2 = 0.7f;
13437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
13447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /**
13457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * Velocity threshold for a screen-move gesture. If the minimum
13467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * y-velocity is less than it, no gesture.
13477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         */
13487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        static private final float VELOCITY_THRESHOLD_Y1 = 0.2f;
13497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
13507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /**
13517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * Velocity threshold for a screen-move gesture. If the maximum
13527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * y-velocity is less than it, no gesture.
13537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         */
13547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        static private final float VELOCITY_THRESHOLD_Y2 = 0.45f;
13557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
13567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /** If it false, we will not response detected gestures. */
13577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        private boolean mReponseGestures;
13587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
13597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /** The minimum X velocity observed in the gesture. */
13607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        private float mMinVelocityX = Float.MAX_VALUE;
13617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
13627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /** The minimum Y velocity observed in the gesture. */
13637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        private float mMinVelocityY = Float.MAX_VALUE;
13647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
13657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /** The first down time for the series of touch events for an action. */
13667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        private long mTimeDown;
13677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
13687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /** The last time when onScroll() is called. */
13697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        private long mTimeLastOnScroll;
13707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
13717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /** This flag used to indicate that this gesture is not a gesture. */
13727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        private boolean mNotGesture;
13737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
13747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /** This flag used to indicate that this gesture has been recognized. */
13757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        private boolean mGestureRecognized;
13767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
13777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public OnGestureListener(boolean reponseGestures) {
13787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mReponseGestures = reponseGestures;
13797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
13807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
13817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        @Override
13827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public boolean onDown(MotionEvent e) {
13837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mMinVelocityX = Integer.MAX_VALUE;
13847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mMinVelocityY = Integer.MAX_VALUE;
13857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mTimeDown = e.getEventTime();
13867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mTimeLastOnScroll = mTimeDown;
13877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mNotGesture = false;
13887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mGestureRecognized = false;
13897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return false;
13907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
13917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
13927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        @Override
13937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public boolean onScroll(MotionEvent e1, MotionEvent e2,
13947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                float distanceX, float distanceY) {
13957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (mNotGesture) return false;
13967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (mGestureRecognized) return true;
13977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
13987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (Math.abs(e1.getX() - e2.getX()) < MIN_X_FOR_DRAG
13997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    && Math.abs(e1.getY() - e2.getY()) < MIN_Y_FOR_DRAG)
14007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                return false;
14017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
14027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            long timeNow = e2.getEventTime();
14037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            long spanTotal = timeNow - mTimeDown;
14047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            long spanThis = timeNow - mTimeLastOnScroll;
14057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (0 == spanTotal) spanTotal = 1;
14067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (0 == spanThis) spanThis = 1;
14077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
14087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            float vXTotal = (e2.getX() - e1.getX()) / spanTotal;
14097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            float vYTotal = (e2.getY() - e1.getY()) / spanTotal;
14107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
14117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            // The distances are from the current point to the previous one.
14127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            float vXThis = -distanceX / spanThis;
14137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            float vYThis = -distanceY / spanThis;
14147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
14157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            float kX = vXTotal * vXThis;
14167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            float kY = vYTotal * vYThis;
14177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            float k1 = kX + kY;
14187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            float k2 = Math.abs(kX) + Math.abs(kY);
14197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
14207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (k1 / k2 < 0.8) {
14217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mNotGesture = true;
14227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                return false;
14237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
14247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            float absVXTotal = Math.abs(vXTotal);
14257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            float absVYTotal = Math.abs(vYTotal);
14267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (absVXTotal < mMinVelocityX) {
14277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mMinVelocityX = absVXTotal;
14287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
14297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (absVYTotal < mMinVelocityY) {
14307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mMinVelocityY = absVYTotal;
14317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
14327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
14337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (mMinVelocityX < VELOCITY_THRESHOLD_X1
14347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    && mMinVelocityY < VELOCITY_THRESHOLD_Y1) {
14357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mNotGesture = true;
14367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                return false;
14377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
14387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
14397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (vXTotal > VELOCITY_THRESHOLD_X2
14407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    && absVYTotal < VELOCITY_THRESHOLD_Y2) {
14417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (mReponseGestures) onDirectionGesture(Gravity.RIGHT);
14427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mGestureRecognized = true;
14437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            } else if (vXTotal < -VELOCITY_THRESHOLD_X2
14447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    && absVYTotal < VELOCITY_THRESHOLD_Y2) {
14457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (mReponseGestures) onDirectionGesture(Gravity.LEFT);
14467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mGestureRecognized = true;
14477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            } else if (vYTotal > VELOCITY_THRESHOLD_Y2
14487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    && absVXTotal < VELOCITY_THRESHOLD_X2) {
14497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (mReponseGestures) onDirectionGesture(Gravity.BOTTOM);
14507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mGestureRecognized = true;
14517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            } else if (vYTotal < -VELOCITY_THRESHOLD_Y2
14527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    && absVXTotal < VELOCITY_THRESHOLD_X2) {
14537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (mReponseGestures) onDirectionGesture(Gravity.TOP);
14547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mGestureRecognized = true;
14557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
14567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
14577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mTimeLastOnScroll = timeNow;
14587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return mGestureRecognized;
14597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
14607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
14617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        @Override
14627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public boolean onFling(MotionEvent me1, MotionEvent me2,
14637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                float velocityX, float velocityY) {
14647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return mGestureRecognized;
14657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
14667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
14677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public void onDirectionGesture(int gravity) {
14687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (Gravity.NO_GRAVITY == gravity) {
14697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                return;
14707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
14717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
14727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (Gravity.LEFT == gravity || Gravity.RIGHT == gravity) {
14737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (mCandidatesContainer.isShown()) {
14747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    if (Gravity.LEFT == gravity) {
14757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        mCandidatesContainer.pageForward(true, true);
14767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    } else {
14777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        mCandidatesContainer.pageBackward(true, true);
14787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    }
14797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    return;
14807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
14817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
14827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
14837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
14847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
14857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    /**
14867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * Connection used for binding to the Pinyin decoding service.
14877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     */
14887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    public class PinyinDecoderServiceConnection implements ServiceConnection {
14897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public void onServiceConnected(ComponentName name, IBinder service) {
14907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mDecInfo.mIPinyinDecoderService = IPinyinDecoderService.Stub
14917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    .asInterface(service);
14927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
14937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
14947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public void onServiceDisconnected(ComponentName name) {
14957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
14967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
14977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
14987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    public enum ImeState {
14997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        STATE_BYPASS, STATE_IDLE, STATE_INPUT, STATE_COMPOSING, STATE_PREDICT,
15007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        STATE_APP_COMPLETION
15017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
15027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
15037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    public class DecodingInfo {
15047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /**
15057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * Maximum length of the Pinyin string
15067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         */
15077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        private static final int PY_STRING_MAX = 28;
15087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
15097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /**
15107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * Maximum number of candidates to display in one page.
15117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         */
15127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        private static final int MAX_PAGE_SIZE_DISPLAY = 10;
15137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
15147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /**
15157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * Spelling (Pinyin) string.
15167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         */
15177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        private StringBuffer mSurface;
15187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
15197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /**
15207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * Byte buffer used as the Pinyin string parameter for native function
15217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * call.
15227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         */
15237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        private byte mPyBuf[];
15247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
15257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /**
15267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * The length of surface string successfully decoded by engine.
15277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         */
15287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        private int mSurfaceDecodedLen;
15297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
15307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /**
15317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * Composing string.
15327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         */
15337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        private String mComposingStr;
15347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
15357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /**
15367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * Length of the active composing string.
15377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         */
15387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        private int mActiveCmpsLen;
15397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
15407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /**
15417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * Composing string for display, it is copied from mComposingStr, and
15427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * add spaces between spellings.
15437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         **/
15447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        private String mComposingStrDisplay;
15457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
15467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /**
15477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * Length of the active composing string for display.
15487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         */
15497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        private int mActiveCmpsDisplayLen;
15507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
15517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /**
15527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * The first full sentence choice.
15537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         */
15547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        private String mFullSent;
15557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
15567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /**
15577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * Number of characters which have been fixed.
15587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         */
15597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        private int mFixedLen;
15607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
15617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /**
15627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * If this flag is true, selection is finished.
15637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         */
15647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        private boolean mFinishSelection;
15657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
15667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /**
15677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * The starting position for each spelling. The first one is the number
15687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * of the real starting position elements.
15697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         */
15707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        private int mSplStart[];
15717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
15727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /**
15737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * Editing cursor in mSurface.
15747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         */
15757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        private int mCursorPos;
15767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
15777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /**
15787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * Remote Pinyin-to-Hanzi decoding engine service.
15797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         */
15807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        private IPinyinDecoderService mIPinyinDecoderService;
15817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
15827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /**
15837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * The complication information suggested by application.
15847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         */
15857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        private CompletionInfo[] mAppCompletions;
15867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
15877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /**
15887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * The total number of choices for display. The list may only contains
15897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * the first part. If user tries to navigate to next page which is not
15907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * in the result list, we need to get these items.
15917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         **/
15927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public int mTotalChoicesNum;
15937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
15947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /**
15957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * Candidate list. The first one is the full-sentence candidate.
15967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         */
15977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public List<String> mCandidatesList = new Vector<String>();
15987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
15997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /**
16007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * Element i stores the starting position of page i.
16017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         */
16027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public Vector<Integer> mPageStart = new Vector<Integer>();
16037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
16047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /**
16057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * Element i stores the number of characters to page i.
16067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         */
16077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public Vector<Integer> mCnToPage = new Vector<Integer>();
16087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
16097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /**
16107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * The position to delete in Pinyin string. If it is less than 0, IME
16117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * will do an incremental search, otherwise IME will do a deletion
16127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * operation. if {@link #mIsPosInSpl} is true, IME will delete the whole
16137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * string for mPosDelSpl-th spelling, otherwise it will only delete
16147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * mPosDelSpl-th character in the Pinyin string.
16157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         */
16167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public int mPosDelSpl = -1;
16177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
16187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        /**
16197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * If {@link #mPosDelSpl} is big than or equal to 0, this member is used
16207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * to indicate that whether the postion is counted in spelling id or
16217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         * character.
16227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project         */
16237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public boolean mIsPosInSpl;
16247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
16257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public DecodingInfo() {
16267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mSurface = new StringBuffer();
16277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mSurfaceDecodedLen = 0;
16287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
16297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
16307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public void reset() {
16317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mSurface.delete(0, mSurface.length());
16327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mSurfaceDecodedLen = 0;
16337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mCursorPos = 0;
16347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mFullSent = "";
16357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mFixedLen = 0;
16367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mFinishSelection = false;
16377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mComposingStr = "";
16387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mComposingStrDisplay = "";
16397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mActiveCmpsLen = 0;
16407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mActiveCmpsDisplayLen = 0;
16417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
16427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            resetCandidates();
16437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
16447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
16457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public boolean isCandidatesListEmpty() {
16467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return mCandidatesList.size() == 0;
16477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
16487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
16497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public boolean isSplStrFull() {
16507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (mSurface.length() >= PY_STRING_MAX - 1) return true;
16517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return false;
16527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
16537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
16547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public void addSplChar(char ch, boolean reset) {
16557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (reset) {
16567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mSurface.delete(0, mSurface.length());
16577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mSurfaceDecodedLen = 0;
16587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mCursorPos = 0;
16597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                try {
16607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    mIPinyinDecoderService.imResetSearch();
16617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                } catch (RemoteException e) {
16627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
16637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
16647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mSurface.insert(mCursorPos, ch);
16657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mCursorPos++;
16667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
16677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
16687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        // Prepare to delete before cursor. We may delete a spelling char if
16697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        // the cursor is in the range of unfixed part, delete a whole spelling
16707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        // if the cursor in inside the range of the fixed part.
16717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        // This function only marks the position used to delete.
16727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public void prepareDeleteBeforeCursor() {
16737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (mCursorPos > 0) {
16747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                int pos;
16757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                for (pos = 0; pos < mFixedLen; pos++) {
16767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    if (mSplStart[pos + 2] >= mCursorPos
16777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                            && mSplStart[pos + 1] < mCursorPos) {
16787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        mPosDelSpl = pos;
16797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        mCursorPos = mSplStart[pos + 1];
16807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        mIsPosInSpl = true;
16817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        break;
16827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    }
16837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
16847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (mPosDelSpl < 0) {
16857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    mPosDelSpl = mCursorPos - 1;
16867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    mCursorPos--;
16877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    mIsPosInSpl = false;
16887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
16897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
16907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
16917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
16927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public int length() {
16937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return mSurface.length();
16947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
16957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
16967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public char charAt(int index) {
16977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return mSurface.charAt(index);
16987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
16997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
17007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public StringBuffer getOrigianlSplStr() {
17017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return mSurface;
17027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
17037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
17047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public int getSplStrDecodedLen() {
17057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return mSurfaceDecodedLen;
17067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
17077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
17087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public int[] getSplStart() {
17097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return mSplStart;
17107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
17117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
17127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public String getComposingStr() {
17137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return mComposingStr;
17147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
17157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
17167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public String getComposingStrActivePart() {
17177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            assert (mActiveCmpsLen <= mComposingStr.length());
17187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return mComposingStr.substring(0, mActiveCmpsLen);
17197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
17207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
17217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public int getActiveCmpsLen() {
17227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return mActiveCmpsLen;
17237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
17247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
17257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public String getComposingStrForDisplay() {
17267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return mComposingStrDisplay;
17277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
17287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
17297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public int getActiveCmpsDisplayLen() {
17307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return mActiveCmpsDisplayLen;
17317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
17327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
17337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public String getFullSent() {
17347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return mFullSent;
17357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
17367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
17377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public String getCurrentFullSent(int activeCandPos) {
17384248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project            try {
17394248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                String retStr = mFullSent.substring(0, mFixedLen);
17404248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                retStr += mCandidatesList.get(activeCandPos);
17414248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                return retStr;
17424248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project            } catch (Exception e) {
17434248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                return "";
17444248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project            }
17457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
17467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
17477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public void resetCandidates() {
17487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mCandidatesList.clear();
17497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mTotalChoicesNum = 0;
17507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
17517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mPageStart.clear();
17527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mPageStart.add(0);
17537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mCnToPage.clear();
17547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mCnToPage.add(0);
17557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
17567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
17577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public boolean candidatesFromApp() {
17587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return ImeState.STATE_APP_COMPLETION == mImeState;
17597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
17607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
17617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public boolean canDoPrediction() {
17627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return mComposingStr.length() == mFixedLen;
17637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
17647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
17657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public boolean selectionFinished() {
17667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return mFinishSelection;
17677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
17687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
17697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        // After the user chooses a candidate, input method will do a
17707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        // re-decoding and give the new candidate list.
17717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        // If candidate id is less than 0, means user is inputting Pinyin,
17727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        // not selecting any choice.
17737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        private void chooseDecodingCandidate(int candId) {
17747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (mImeState != ImeState.STATE_PREDICT) {
17757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                resetCandidates();
17767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                int totalChoicesNum = 0;
17777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                try {
17787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    if (candId < 0) {
17797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        if (length() == 0) {
17807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                            totalChoicesNum = 0;
17817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        } else {
17827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                            if (mPyBuf == null)
17837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                                mPyBuf = new byte[PY_STRING_MAX];
17847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                            for (int i = 0; i < length(); i++)
17857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                                mPyBuf[i] = (byte) charAt(i);
17867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                            mPyBuf[length()] = 0;
17877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
17887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                            if (mPosDelSpl < 0) {
17897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                                totalChoicesNum = mIPinyinDecoderService
17907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                                        .imSearch(mPyBuf, length());
17917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                            } else {
17927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                                boolean clear_fixed_this_step = true;
17937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                                if (ImeState.STATE_COMPOSING == mImeState) {
17947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                                    clear_fixed_this_step = false;
17957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                                }
17967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                                totalChoicesNum = mIPinyinDecoderService
17977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                                        .imDelSearch(mPosDelSpl, mIsPosInSpl,
17987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                                                clear_fixed_this_step);
17997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                                mPosDelSpl = -1;
18007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                            }
18017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        }
18027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    } else {
18037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        totalChoicesNum = mIPinyinDecoderService
18047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                                .imChoose(candId);
18057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    }
18067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                } catch (RemoteException e) {
18077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
18087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                updateDecInfoForSearch(totalChoicesNum);
18097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
18107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
18117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
18127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        private void updateDecInfoForSearch(int totalChoicesNum) {
18137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mTotalChoicesNum = totalChoicesNum;
18147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (mTotalChoicesNum < 0) {
18157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mTotalChoicesNum = 0;
18167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                return;
18177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
18187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
18197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            try {
18207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                String pyStr;
18217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
18227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mSplStart = mIPinyinDecoderService.imGetSplStart();
18237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                pyStr = mIPinyinDecoderService.imGetPyStr(false);
18247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mSurfaceDecodedLen = mIPinyinDecoderService.imGetPyStrLen(true);
18257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                assert (mSurfaceDecodedLen <= pyStr.length());
18267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
18277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mFullSent = mIPinyinDecoderService.imGetChoice(0);
18287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mFixedLen = mIPinyinDecoderService.imGetFixedLen();
18297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
18307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                // Update the surface string to the one kept by engine.
18317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mSurface.replace(0, mSurface.length(), pyStr);
18327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
18337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (mCursorPos > mSurface.length())
18347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    mCursorPos = mSurface.length();
18357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mComposingStr = mFullSent.substring(0, mFixedLen)
18367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        + mSurface.substring(mSplStart[mFixedLen + 1]);
18377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
18387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mActiveCmpsLen = mComposingStr.length();
18397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (mSurfaceDecodedLen > 0) {
18407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    mActiveCmpsLen = mActiveCmpsLen
18417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                            - (mSurface.length() - mSurfaceDecodedLen);
18427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
18437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
18447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                // Prepare the display string.
18457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (0 == mSurfaceDecodedLen) {
18467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    mComposingStrDisplay = mComposingStr;
18477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    mActiveCmpsDisplayLen = mComposingStr.length();
18487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                } else {
18497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    mComposingStrDisplay = mFullSent.substring(0, mFixedLen);
18507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    for (int pos = mFixedLen + 1; pos < mSplStart.length - 1; pos++) {
18517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        mComposingStrDisplay += mSurface.substring(
18527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                                mSplStart[pos], mSplStart[pos + 1]);
18537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        if (mSplStart[pos + 1] < mSurfaceDecodedLen) {
18547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                            mComposingStrDisplay += " ";
18557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        }
18567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    }
18577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    mActiveCmpsDisplayLen = mComposingStrDisplay.length();
18587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    if (mSurfaceDecodedLen < mSurface.length()) {
18597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        mComposingStrDisplay += mSurface
18607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                                .substring(mSurfaceDecodedLen);
18617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    }
18627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
18637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
18647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (mSplStart.length == mFixedLen + 2) {
18657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    mFinishSelection = true;
18667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                } else {
18677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    mFinishSelection = false;
18687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
18697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            } catch (RemoteException e) {
18707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                Log.w(TAG, "PinyinDecoderService died", e);
18714248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project            } catch (Exception e) {
18724248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                mTotalChoicesNum = 0;
18734248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                mComposingStr = "";
18747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
18757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            // Prepare page 0.
18767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (!mFinishSelection) {
18777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                preparePage(0);
18787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
18797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
18807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
18817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        private void choosePredictChoice(int choiceId) {
18827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (ImeState.STATE_PREDICT != mImeState || choiceId < 0
18837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    || choiceId >= mTotalChoicesNum) {
18847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                return;
18857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
18867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
18877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            String tmp = mCandidatesList.get(choiceId);
18887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
18897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            resetCandidates();
18907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
18917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mCandidatesList.add(tmp);
18927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mTotalChoicesNum = 1;
18937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
18947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mSurface.replace(0, mSurface.length(), "");
18957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mCursorPos = 0;
18967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mFullSent = tmp;
18977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mFixedLen = tmp.length();
18987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mComposingStr = mFullSent;
18997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mActiveCmpsLen = mFixedLen;
19007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
19017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mFinishSelection = true;
19027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
19037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
19047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public String getCandidate(int candId) {
19057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            // Only loaded items can be gotten, so we use mCandidatesList.size()
19067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            // instead mTotalChoiceNum.
19077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (candId < 0 || candId > mCandidatesList.size()) {
19087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                return null;
19097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
19107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return mCandidatesList.get(candId);
19117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
19127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
19137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        private void getCandiagtesForCache() {
19147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            int fetchStart = mCandidatesList.size();
19157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            int fetchSize = mTotalChoicesNum - fetchStart;
19167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (fetchSize > MAX_PAGE_SIZE_DISPLAY) {
19177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                fetchSize = MAX_PAGE_SIZE_DISPLAY;
19187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
19197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            try {
19207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                List<String> newList = null;
19217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (ImeState.STATE_INPUT == mImeState ||
19227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        ImeState.STATE_IDLE == mImeState ||
19237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        ImeState.STATE_COMPOSING == mImeState){
19247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    newList = mIPinyinDecoderService.imGetChoiceList(
19257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                            fetchStart, fetchSize, mFixedLen);
19267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                } else if (ImeState.STATE_PREDICT == mImeState) {
19277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    newList = mIPinyinDecoderService.imGetPredictList(
19287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                            fetchStart, fetchSize);
19297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                } else if (ImeState.STATE_APP_COMPLETION == mImeState) {
19307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    newList = new ArrayList<String>();
19317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    if (null != mAppCompletions) {
19327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        for (int pos = fetchStart; pos < fetchSize; pos++) {
19337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                            CompletionInfo ci = mAppCompletions[pos];
19347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                            if (null != ci) {
19357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                                CharSequence s = ci.getText();
19367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                                if (null != s) newList.add(s.toString());
19377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                            }
19387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        }
19397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    }
19407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
19417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mCandidatesList.addAll(newList);
19427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            } catch (RemoteException e) {
19437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                Log.w(TAG, "PinyinDecoderService died", e);
19447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
19457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
19467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
19477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public boolean pageReady(int pageNo) {
19487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            // If the page number is less than 0, return false
19497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (pageNo < 0) return false;
19507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
19517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            // Page pageNo's ending information is not ready.
19527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (mPageStart.size() <= pageNo + 1) {
19537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                return false;
19547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
19557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
19567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return true;
19577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
19587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
19597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public boolean preparePage(int pageNo) {
19607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            // If the page number is less than 0, return false
19617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (pageNo < 0) return false;
19627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
19637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            // Make sure the starting information for page pageNo is ready.
19647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (mPageStart.size() <= pageNo) {
19657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                return false;
19667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
19677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
19687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            // Page pageNo's ending information is also ready.
19697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (mPageStart.size() > pageNo + 1) {
19707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                return true;
19717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
19727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
19737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            // If cached items is enough for page pageNo.
19747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (mCandidatesList.size() - mPageStart.elementAt(pageNo) >= MAX_PAGE_SIZE_DISPLAY) {
19757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                return true;
19767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
19777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
19787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            // Try to get more items from engine
19797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            getCandiagtesForCache();
19807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
19817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            // Try to find if there are available new items to display.
19827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            // If no new item, return false;
19837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (mPageStart.elementAt(pageNo) >= mCandidatesList.size()) {
19847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                return false;
19857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
19867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
19877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            // If there are new items, return true;
19887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return true;
19897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
19907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
19917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public void preparePredicts(CharSequence history) {
19927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (null == history) return;
19937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
19947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            resetCandidates();
19957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
19967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (Settings.getPrediction()) {
19977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                String preEdit = history.toString();
19987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                int predictNum = 0;
19997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (null != preEdit) {
20007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    try {
20017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        mTotalChoicesNum = mIPinyinDecoderService
20027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                                .imGetPredictsNum(preEdit);
20037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    } catch (RemoteException e) {
20047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        return;
20057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    }
20067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
20077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
20087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
20097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            preparePage(0);
20107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mFinishSelection = false;
20117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
20127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
20137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        private void prepareAppCompletions(CompletionInfo completions[]) {
20147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            resetCandidates();
20157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mAppCompletions = completions;
20167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mTotalChoicesNum = completions.length;
20177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            preparePage(0);
20187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mFinishSelection = false;
20197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return;
20207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
20217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
20227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public int getCurrentPageSize(int currentPage) {
20237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (mPageStart.size() <= currentPage + 1) return 0;
20247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return mPageStart.elementAt(currentPage + 1)
20257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    - mPageStart.elementAt(currentPage);
20267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
20277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
20287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public int getCurrentPageStart(int currentPage) {
20297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (mPageStart.size() < currentPage + 1) return mTotalChoicesNum;
20307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return mPageStart.elementAt(currentPage);
20317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
20327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
20337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public boolean pageForwardable(int currentPage) {
20347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (mPageStart.size() <= currentPage + 1) return false;
20357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (mPageStart.elementAt(currentPage + 1) >= mTotalChoicesNum) {
20367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                return false;
20377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
20387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return true;
20397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
20407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
20417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public boolean pageBackwardable(int currentPage) {
20427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (currentPage > 0) return true;
20437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return false;
20447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
20457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
20467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public boolean charBeforeCursorIsSeparator() {
20477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            int len = mSurface.length();
20487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (mCursorPos > len) return false;
20497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (mCursorPos > 0 && mSurface.charAt(mCursorPos - 1) == '\'') {
20507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                return true;
20517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
20527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return false;
20537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
20547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
20557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public int getCursorPos() {
20567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return mCursorPos;
20577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
20587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
20597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public int getCursorPosInCmps() {
20607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            int cursorPos = mCursorPos;
20617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            int fixedLen = 0;
20627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
20637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            for (int hzPos = 0; hzPos < mFixedLen; hzPos++) {
20647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (mCursorPos >= mSplStart[hzPos + 2]) {
20657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    cursorPos -= mSplStart[hzPos + 2] - mSplStart[hzPos + 1];
20667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    cursorPos += 1;
20677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
20687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
20697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return cursorPos;
20707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
20717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
20727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public int getCursorPosInCmpsDisplay() {
20737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            int cursorPos = getCursorPosInCmps();
20747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            // +2 is because: one for mSplStart[0], which is used for other
20757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            // purpose(The length of the segmentation string), and another
20767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            // for the first spelling which does not need a space before it.
20777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            for (int pos = mFixedLen + 2; pos < mSplStart.length - 1; pos++) {
20787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (mCursorPos <= mSplStart[pos]) {
20797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    break;
20807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                } else {
20817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    cursorPos++;
20827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
20837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
20847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return cursorPos;
20857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
20867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
20877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public void moveCursorToEdge(boolean left) {
20887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (left)
20897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mCursorPos = 0;
20907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            else
20917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mCursorPos = mSurface.length();
20927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
20937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
20947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        // Move cursor. If offset is 0, this function can be used to adjust
20957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        // the cursor into the bounds of the string.
20967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public void moveCursor(int offset) {
20977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (offset > 1 || offset < -1) return;
20987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
20997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (offset != 0) {
21007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                int hzPos = 0;
21017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                for (hzPos = 0; hzPos <= mFixedLen; hzPos++) {
21027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    if (mCursorPos == mSplStart[hzPos + 1]) {
21037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        if (offset < 0) {
21047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                            if (hzPos > 0) {
21057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                                offset = mSplStart[hzPos]
21067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                                        - mSplStart[hzPos + 1];
21077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                            }
21087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        } else {
21097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                            if (hzPos < mFixedLen) {
21107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                                offset = mSplStart[hzPos + 2]
21117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                                        - mSplStart[hzPos + 1];
21127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                            }
21137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        }
21147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                        break;
21157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    }
21167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
21177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
21187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mCursorPos += offset;
21197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (mCursorPos < 0) {
21207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mCursorPos = 0;
21217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            } else if (mCursorPos > mSurface.length()) {
21227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mCursorPos = mSurface.length();
21237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
21247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
21257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
21267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public int getSplNum() {
21277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return mSplStart[0];
21287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
21297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
21307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        public int getFixedLen() {
21317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return mFixedLen;
21327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
21337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
21347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project}
2135