Fields Summary |
---|
static final String | TAGTAG for debug. |
private static final boolean | SIMULATE_KEY_DELETEIf is is true, IME will simulate key events for delete key, and send the
events back to the application. |
private Environment | mEnvironmentNecessary environment configurations like screen size for this IME. |
private InputModeSwitcher | mInputModeSwitcherUsed to switch input mode. |
private SkbContainer | mSkbContainerSoft keyboard container view to host real soft keyboard view. |
private android.widget.LinearLayout | mFloatingContainerThe floating container which contains the composing view. If necessary,
some other view like candiates container can also be put here. |
private ComposingView | mComposingViewView to show the composing string. |
private android.widget.PopupWindow | mFloatingWindowWindow to show the composing string. |
private PopupTimer | mFloatingWindowTimerUsed to show the floating window. |
private CandidatesContainer | mCandidatesContainerView to show candidates list. |
private BalloonHint | mCandidatesBalloonBalloon used when user presses a candidate. |
private ChoiceNotifier | mChoiceNotifierUsed to notify the input method when the user touch a candidate. |
private OnGestureListener | mGestureListenerSkbUsed to notify gestures from soft keyboard. |
private OnGestureListener | mGestureListenerCandidatesUsed to notify gestures from candidates view. |
private android.view.GestureDetector | mGestureDetectorSkbThe on-screen movement gesture detector for soft keyboard. |
private android.view.GestureDetector | mGestureDetectorCandidatesThe on-screen movement gesture detector for candidates view. |
private android.app.AlertDialog | mOptionsDialogOption dialog to choose settings and other IMEs. |
private PinyinDecoderServiceConnection | mPinyinDecoderServiceConnectionConnection used to bind the decoding service. |
private ImeState | mImeStateThe current IME status. |
private DecodingInfo | mDecInfoThe decoding information, include spelling(Pinyin) string, decoding
result, etc. |
private EnglishInputProcessor | mImEnFor English input. |
private android.content.BroadcastReceiver | mReceiver |
Methods Summary |
---|
private void | changeToStateComposing(boolean updateUi)
mImeState = ImeState.STATE_COMPOSING;
if (!updateUi) return;
if (null != mSkbContainer && mSkbContainer.isShown()) {
mSkbContainer.toggleCandidateMode(true);
}
|
private void | changeToStateInput(boolean updateUi)
mImeState = ImeState.STATE_INPUT;
if (!updateUi) return;
if (null != mSkbContainer && mSkbContainer.isShown()) {
mSkbContainer.toggleCandidateMode(true);
}
showCandidateWindow(true);
|
private void | chooseAndUpdate(int candId)
if (!mInputModeSwitcher.isChineseText()) {
String choice = mDecInfo.getCandidate(candId);
if (null != choice) {
commitResultText(choice);
}
resetToIdleState(false);
return;
}
if (ImeState.STATE_PREDICT != mImeState) {
// Get result candidate list, if choice_id < 0, do a new decoding.
// If choice_id >=0, select the candidate, and get the new candidate
// list.
mDecInfo.chooseDecodingCandidate(candId);
} else {
// Choose a prediction item.
mDecInfo.choosePredictChoice(candId);
}
if (mDecInfo.getComposingStr().length() > 0) {
String resultStr;
resultStr = mDecInfo.getComposingStrActivePart();
// choiceId >= 0 means user finishes a choice selection.
if (candId >= 0 && mDecInfo.canDoPrediction()) {
commitResultText(resultStr);
mImeState = ImeState.STATE_PREDICT;
if (null != mSkbContainer && mSkbContainer.isShown()) {
mSkbContainer.toggleCandidateMode(false);
}
// Try to get the prediction list.
if (Settings.getPrediction()) {
InputConnection ic = getCurrentInputConnection();
if (null != ic) {
CharSequence cs = ic.getTextBeforeCursor(3, 0);
if (null != cs) {
mDecInfo.preparePredicts(cs);
}
}
} else {
mDecInfo.resetCandidates();
}
if (mDecInfo.mCandidatesList.size() > 0) {
showCandidateWindow(false);
} else {
resetToIdleState(false);
}
} else {
if (ImeState.STATE_IDLE == mImeState) {
if (mDecInfo.getSplStrDecodedLen() == 0) {
changeToStateComposing(true);
} else {
changeToStateInput(true);
}
} else {
if (mDecInfo.selectionFinished()) {
changeToStateComposing(true);
}
}
showCandidateWindow(true);
}
} else {
resetToIdleState(false);
}
|
private void | chooseCandidate(int activeCandNo)
if (activeCandNo < 0) {
activeCandNo = mCandidatesContainer.getActiveCandiatePos();
}
if (activeCandNo >= 0) {
chooseAndUpdate(activeCandNo);
}
|
private void | commitResultText(java.lang.String resultText)
InputConnection ic = getCurrentInputConnection();
if (null != ic) ic.commitText(resultText, 1);
if (null != mComposingView) {
mComposingView.setVisibility(View.INVISIBLE);
mComposingView.invalidate();
}
|
private void | dismissCandidateWindow()
if (mEnvironment.needDebug()) {
Log.d(TAG, "Candidates window is to be dismissed");
}
if (null == mCandidatesContainer) return;
try {
mFloatingWindowTimer.cancelShowing();
mFloatingWindow.dismiss();
} catch (Exception e) {
Log.e(TAG, "Fail to show the PopupWindow.");
}
setCandidatesViewShown(false);
if (null != mSkbContainer && mSkbContainer.isShown()) {
mSkbContainer.toggleCandidateMode(false);
}
|
private void | inputCommaPeriod(java.lang.String preEdit, int keyChar, boolean dismissCandWindow, com.android.inputmethod.pinyin.PinyinIME$ImeState nextState)
if (keyChar == ',")
preEdit += '\uff0c";
else if (keyChar == '.")
preEdit += '\u3002";
else
return;
commitResultText(preEdit);
if (dismissCandWindow) resetCandidateWindow();
mImeState = nextState;
|
private void | launchSettings()
Intent intent = new Intent();
intent.setClass(PinyinIME.this, SettingsActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
|
private void | onChoiceTouched(int activeCandNo)
if (mImeState == ImeState.STATE_COMPOSING) {
changeToStateInput(true);
} else if (mImeState == ImeState.STATE_INPUT
|| mImeState == ImeState.STATE_PREDICT) {
chooseCandidate(activeCandNo);
} else if (mImeState == ImeState.STATE_APP_COMPLETION) {
if (null != mDecInfo.mAppCompletions && activeCandNo >= 0 &&
activeCandNo < mDecInfo.mAppCompletions.length) {
CompletionInfo ci = mDecInfo.mAppCompletions[activeCandNo];
if (null != ci) {
InputConnection ic = getCurrentInputConnection();
ic.commitCompletion(ci);
}
}
resetToIdleState(false);
}
|
public void | onConfigurationChanged(android.content.res.Configuration newConfig)
Environment env = Environment.getInstance();
if (mEnvironment.needDebug()) {
Log.d(TAG, "onConfigurationChanged");
Log.d(TAG, "--last config: " + env.getConfiguration().toString());
Log.d(TAG, "---new config: " + newConfig.toString());
}
// We need to change the local environment first so that UI components
// can get the environment instance to handle size issues. When
// super.onConfigurationChanged() is called, onCreateCandidatesView()
// and onCreateInputView() will be executed if necessary.
env.onConfigurationChanged(newConfig, this);
// Clear related UI of the previous configuration.
if (null != mSkbContainer) {
mSkbContainer.dismissPopups();
}
if (null != mCandidatesBalloon) {
mCandidatesBalloon.dismiss();
}
super.onConfigurationChanged(newConfig);
resetToIdleState(false);
|
public void | onCreate()
mEnvironment = Environment.getInstance();
if (mEnvironment.needDebug()) {
Log.d(TAG, "onCreate.");
}
super.onCreate();
startPinyinDecoderService();
mImEn = new EnglishInputProcessor();
Settings.getInstance(PreferenceManager
.getDefaultSharedPreferences(getApplicationContext()));
mInputModeSwitcher = new InputModeSwitcher(this);
mChoiceNotifier = new ChoiceNotifier(this);
mGestureListenerSkb = new OnGestureListener(false);
mGestureListenerCandidates = new OnGestureListener(true);
mGestureDetectorSkb = new GestureDetector(this, mGestureListenerSkb);
mGestureDetectorCandidates = new GestureDetector(this,
mGestureListenerCandidates);
mEnvironment.onConfigurationChanged(getResources().getConfiguration(),
this);
|
public android.view.View | onCreateCandidatesView()
if (mEnvironment.needDebug()) {
Log.d(TAG, "onCreateCandidatesView.");
}
LayoutInflater inflater = getLayoutInflater();
// Inflate the floating container view
mFloatingContainer = (LinearLayout) inflater.inflate(
R.layout.floating_container, null);
// The first child is the composing view.
mComposingView = (ComposingView) mFloatingContainer.getChildAt(0);
mCandidatesContainer = (CandidatesContainer) inflater.inflate(
R.layout.candidates_container, null);
// Create balloon hint for candidates view.
mCandidatesBalloon = new BalloonHint(this, mCandidatesContainer,
MeasureSpec.UNSPECIFIED);
mCandidatesBalloon.setBalloonBackground(getResources().getDrawable(
R.drawable.candidate_balloon_bg));
mCandidatesContainer.initialize(mChoiceNotifier, mCandidatesBalloon,
mGestureDetectorCandidates);
// The floating window
if (null != mFloatingWindow && mFloatingWindow.isShowing()) {
mFloatingWindowTimer.cancelShowing();
mFloatingWindow.dismiss();
}
mFloatingWindow = new PopupWindow(this);
mFloatingWindow.setClippingEnabled(false);
mFloatingWindow.setBackgroundDrawable(null);
mFloatingWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
mFloatingWindow.setContentView(mFloatingContainer);
setCandidatesViewShown(true);
return mCandidatesContainer;
|
public android.view.View | onCreateInputView()
if (mEnvironment.needDebug()) {
Log.d(TAG, "onCreateInputView.");
}
LayoutInflater inflater = getLayoutInflater();
mSkbContainer = (SkbContainer) inflater.inflate(R.layout.skb_container,
null);
mSkbContainer.setService(this);
mSkbContainer.setInputModeSwitcher(mInputModeSwitcher);
mSkbContainer.setGestureDetector(mGestureDetectorSkb);
return mSkbContainer;
|
public void | onDestroy()
if (mEnvironment.needDebug()) {
Log.d(TAG, "onDestroy.");
}
unbindService(mPinyinDecoderServiceConnection);
Settings.releaseInstance();
super.onDestroy();
|
public void | onDisplayCompletions(android.view.inputmethod.CompletionInfo[] completions)
if (!isFullscreenMode()) return;
if (null == completions || completions.length <= 0) return;
if (null == mSkbContainer || !mSkbContainer.isShown()) return;
if (!mInputModeSwitcher.isChineseText() ||
ImeState.STATE_IDLE == mImeState ||
ImeState.STATE_PREDICT == mImeState) {
mImeState = ImeState.STATE_APP_COMPLETION;
mDecInfo.prepareAppCompletions(completions);
showCandidateWindow(false);
}
|
public void | onFinishCandidatesView(boolean finishingInput)
if (mEnvironment.needDebug()) {
Log.d(TAG, "onFinishCandidateView.");
}
resetToIdleState(false);
super.onFinishCandidatesView(finishingInput);
|
public void | onFinishInput()
if (mEnvironment.needDebug()) {
Log.d(TAG, "onFinishInput.");
}
resetToIdleState(false);
super.onFinishInput();
|
public void | onFinishInputView(boolean finishingInput)
if (mEnvironment.needDebug()) {
Log.d(TAG, "onFinishInputView.");
}
resetToIdleState(false);
super.onFinishInputView(finishingInput);
|
public boolean | onKeyDown(int keyCode, android.view.KeyEvent event)
if (processKey(event, 0 != event.getRepeatCount())) return true;
return super.onKeyDown(keyCode, event);
|
public boolean | onKeyUp(int keyCode, android.view.KeyEvent event)
if (processKey(event, true)) return true;
return super.onKeyUp(keyCode, event);
|
public void | onStartInput(android.view.inputmethod.EditorInfo editorInfo, boolean restarting)
if (mEnvironment.needDebug()) {
Log.d(TAG, "onStartInput " + " ccontentType: "
+ String.valueOf(editorInfo.inputType) + " Restarting:"
+ String.valueOf(restarting));
}
updateIcon(mInputModeSwitcher.requestInputWithHkb(editorInfo));
resetToIdleState(false);
|
public void | onStartInputView(android.view.inputmethod.EditorInfo editorInfo, boolean restarting)
if (mEnvironment.needDebug()) {
Log.d(TAG, "onStartInputView " + " contentType: "
+ String.valueOf(editorInfo.inputType) + " Restarting:"
+ String.valueOf(restarting));
}
updateIcon(mInputModeSwitcher.requestInputWithSkb(editorInfo));
resetToIdleState(false);
mSkbContainer.updateInputMode();
setCandidatesViewShown(false);
|
private boolean | processFunctionKeys(int keyCode, boolean realAction)
// Back key is used to dismiss all popup UI in a soft keyboard.
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (isInputViewShown()) {
if (mSkbContainer.handleBack(realAction)) return true;
}
}
// Chinese related input is handle separately.
if (mInputModeSwitcher.isChineseText()) {
return false;
}
if (null != mCandidatesContainer && mCandidatesContainer.isShown()
&& !mDecInfo.isCandidatesListEmpty()) {
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
if (!realAction) return true;
chooseCandidate(-1);
return true;
}
if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
if (!realAction) return true;
mCandidatesContainer.activeCurseBackward();
return true;
}
if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
if (!realAction) return true;
mCandidatesContainer.activeCurseForward();
return true;
}
if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
if (!realAction) return true;
mCandidatesContainer.pageBackward(false, true);
return true;
}
if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
if (!realAction) return true;
mCandidatesContainer.pageForward(false, true);
return true;
}
if (keyCode == KeyEvent.KEYCODE_DEL &&
ImeState.STATE_PREDICT == mImeState) {
if (!realAction) return true;
resetToIdleState(false);
return true;
}
} else {
if (keyCode == KeyEvent.KEYCODE_DEL) {
if (!realAction) return true;
if (SIMULATE_KEY_DELETE) {
simulateKeyEventDownUp(keyCode);
} else {
getCurrentInputConnection().deleteSurroundingText(1, 0);
}
return true;
}
if (keyCode == KeyEvent.KEYCODE_ENTER) {
if (!realAction) return true;
sendKeyChar('\n");
return true;
}
if (keyCode == KeyEvent.KEYCODE_SPACE) {
if (!realAction) return true;
sendKeyChar(' ");
return true;
}
}
return false;
|
private boolean | processKey(android.view.KeyEvent event, boolean realAction)
if (ImeState.STATE_BYPASS == mImeState) return false;
int keyCode = event.getKeyCode();
// SHIFT-SPACE is used to switch between Chinese and English
// when HKB is on.
if (KeyEvent.KEYCODE_SPACE == keyCode && event.isShiftPressed()) {
if (!realAction) return true;
updateIcon(mInputModeSwitcher.switchLanguageWithHkb());
resetToIdleState(false);
int allMetaState = KeyEvent.META_ALT_ON | KeyEvent.META_ALT_LEFT_ON
| KeyEvent.META_ALT_RIGHT_ON | KeyEvent.META_SHIFT_ON
| KeyEvent.META_SHIFT_LEFT_ON
| KeyEvent.META_SHIFT_RIGHT_ON | KeyEvent.META_SYM_ON;
getCurrentInputConnection().clearMetaKeyStates(allMetaState);
return true;
}
// If HKB is on to input English, by-pass the key event so that
// default key listener will handle it.
if (mInputModeSwitcher.isEnglishWithHkb()) {
return false;
}
if (processFunctionKeys(keyCode, realAction)) {
return true;
}
int keyChar = 0;
if (keyCode >= KeyEvent.KEYCODE_A && keyCode <= KeyEvent.KEYCODE_Z) {
keyChar = keyCode - KeyEvent.KEYCODE_A + 'a";
} else if (keyCode >= KeyEvent.KEYCODE_0
&& keyCode <= KeyEvent.KEYCODE_9) {
keyChar = keyCode - KeyEvent.KEYCODE_0 + '0";
} else if (keyCode == KeyEvent.KEYCODE_COMMA) {
keyChar = ',";
} else if (keyCode == KeyEvent.KEYCODE_PERIOD) {
keyChar = '.";
} else if (keyCode == KeyEvent.KEYCODE_SPACE) {
keyChar = ' ";
} else if (keyCode == KeyEvent.KEYCODE_APOSTROPHE) {
keyChar = '\'";
}
if (mInputModeSwitcher.isEnglishWithSkb()) {
return mImEn.processKey(getCurrentInputConnection(), event,
mInputModeSwitcher.isEnglishUpperCaseWithSkb(), realAction);
} else if (mInputModeSwitcher.isChineseText()) {
if (mImeState == ImeState.STATE_IDLE ||
mImeState == ImeState.STATE_APP_COMPLETION) {
mImeState = ImeState.STATE_IDLE;
return processStateIdle(keyChar, keyCode, event, realAction);
} else if (mImeState == ImeState.STATE_INPUT) {
return processStateInput(keyChar, keyCode, event, realAction);
} else if (mImeState == ImeState.STATE_PREDICT) {
return processStatePredict(keyChar, keyCode, event, realAction);
} else if (mImeState == ImeState.STATE_COMPOSING) {
return processStateEditComposing(keyChar, keyCode, event,
realAction);
}
} else {
if (0 != keyChar && realAction) {
commitResultText(String.valueOf((char) keyChar));
}
}
return false;
|
private boolean | processStateEditComposing(int keyChar, int keyCode, android.view.KeyEvent event, boolean realAction)
if (!realAction) return true;
ComposingView.ComposingStatus cmpsvStatus =
mComposingView.getComposingStatus();
// If ALT key is pressed, input alternative key. But if the
// alternative key is quote key, it will be used for input a splitter
// in Pinyin string.
if (event.isAltPressed()) {
if ('\'" != event.getUnicodeChar(event.getMetaState())) {
char fullwidth_char = KeyMapDream.getChineseLabel(keyCode);
if (0 != fullwidth_char) {
String retStr;
if (ComposingView.ComposingStatus.SHOW_STRING_LOWERCASE ==
cmpsvStatus) {
retStr = mDecInfo.getOrigianlSplStr().toString();
} else {
retStr = mDecInfo.getComposingStr();
}
commitResultText(retStr + String.valueOf(fullwidth_char));
resetToIdleState(false);
}
return true;
} else {
keyChar = '\'";
}
}
if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
if (!mDecInfo.selectionFinished()) {
changeToStateInput(true);
}
} else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT
|| keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
mComposingView.moveCursor(keyCode);
} else if ((keyCode == KeyEvent.KEYCODE_ENTER && mInputModeSwitcher
.isEnterNoramlState())
|| keyCode == KeyEvent.KEYCODE_DPAD_CENTER
|| keyCode == KeyEvent.KEYCODE_SPACE) {
if (ComposingView.ComposingStatus.SHOW_STRING_LOWERCASE == cmpsvStatus) {
String str = mDecInfo.getOrigianlSplStr().toString();
if (!tryInputRawUnicode(str)) {
commitResultText(str);
}
} else if (ComposingView.ComposingStatus.EDIT_PINYIN == cmpsvStatus) {
String str = mDecInfo.getComposingStr();
if (!tryInputRawUnicode(str)) {
commitResultText(str);
}
} else {
commitResultText(mDecInfo.getComposingStr());
}
resetToIdleState(false);
} else if (keyCode == KeyEvent.KEYCODE_ENTER
&& !mInputModeSwitcher.isEnterNoramlState()) {
String retStr;
if (!mDecInfo.isCandidatesListEmpty()) {
retStr = mDecInfo.getCurrentFullSent(mCandidatesContainer
.getActiveCandiatePos());
} else {
retStr = mDecInfo.getComposingStr();
}
commitResultText(retStr);
sendKeyChar('\n");
resetToIdleState(false);
} else if (keyCode == KeyEvent.KEYCODE_BACK) {
resetToIdleState(false);
requestHideSelf(0);
return true;
} else {
return processSurfaceChange(keyChar, keyCode);
}
return true;
|
private boolean | processStateIdle(int keyChar, int keyCode, android.view.KeyEvent event, boolean realAction)
// In this status, when user presses keys in [a..z], the status will
// change to input state.
if (keyChar >= 'a" && keyChar <= 'z" && !event.isAltPressed()) {
if (!realAction) return true;
mDecInfo.addSplChar((char) keyChar, true);
chooseAndUpdate(-1);
return true;
} else if (keyCode == KeyEvent.KEYCODE_DEL) {
if (!realAction) return true;
if (SIMULATE_KEY_DELETE) {
simulateKeyEventDownUp(keyCode);
} else {
getCurrentInputConnection().deleteSurroundingText(1, 0);
}
return true;
} else if (keyCode == KeyEvent.KEYCODE_ENTER) {
if (!realAction) return true;
sendKeyChar('\n");
return true;
} else if (keyCode == KeyEvent.KEYCODE_ALT_LEFT
|| keyCode == KeyEvent.KEYCODE_ALT_RIGHT
|| keyCode == KeyEvent.KEYCODE_SHIFT_LEFT
|| keyCode == KeyEvent.KEYCODE_SHIFT_RIGHT) {
return true;
} else if (event.isAltPressed()) {
char fullwidth_char = KeyMapDream.getChineseLabel(keyCode);
if (0 != fullwidth_char) {
if (realAction) {
String result = String.valueOf(fullwidth_char);
commitResultText(result);
}
return true;
} else {
if (keyCode >= KeyEvent.KEYCODE_A
&& keyCode <= KeyEvent.KEYCODE_Z) {
return true;
}
}
} else if (keyChar != 0 && keyChar != '\t") {
if (realAction) {
if (keyChar == '," || keyChar == '.") {
inputCommaPeriod("", keyChar, false, ImeState.STATE_IDLE);
} else {
if (0 != keyChar) {
String result = String.valueOf((char) keyChar);
commitResultText(result);
}
}
}
return true;
}
return false;
|
private boolean | processStateInput(int keyChar, int keyCode, android.view.KeyEvent event, boolean realAction)
// If ALT key is pressed, input alternative key. But if the
// alternative key is quote key, it will be used for input a splitter
// in Pinyin string.
if (event.isAltPressed()) {
if ('\'" != event.getUnicodeChar(event.getMetaState())) {
if (realAction) {
char fullwidth_char = KeyMapDream.getChineseLabel(keyCode);
if (0 != fullwidth_char) {
commitResultText(mDecInfo
.getCurrentFullSent(mCandidatesContainer
.getActiveCandiatePos()) +
String.valueOf(fullwidth_char));
resetToIdleState(false);
}
}
return true;
} else {
keyChar = '\'";
}
}
if (keyChar >= 'a" && keyChar <= 'z" || keyChar == '\'"
&& !mDecInfo.charBeforeCursorIsSeparator()
|| keyCode == KeyEvent.KEYCODE_DEL) {
if (!realAction) return true;
return processSurfaceChange(keyChar, keyCode);
} else if (keyChar == '," || keyChar == '.") {
if (!realAction) return true;
inputCommaPeriod(mDecInfo.getCurrentFullSent(mCandidatesContainer
.getActiveCandiatePos()), keyChar, true,
ImeState.STATE_IDLE);
return true;
} else if (keyCode == KeyEvent.KEYCODE_DPAD_UP
|| keyCode == KeyEvent.KEYCODE_DPAD_DOWN
|| keyCode == KeyEvent.KEYCODE_DPAD_LEFT
|| keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
if (!realAction) return true;
if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
mCandidatesContainer.activeCurseBackward();
} else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
mCandidatesContainer.activeCurseForward();
} else if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
// If it has been the first page, a up key will shift
// the state to edit composing string.
if (!mCandidatesContainer.pageBackward(false, true)) {
mCandidatesContainer.enableActiveHighlight(false);
changeToStateComposing(true);
updateComposingText(true);
}
} else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
mCandidatesContainer.pageForward(false, true);
}
return true;
} else if (keyCode >= KeyEvent.KEYCODE_1
&& keyCode <= KeyEvent.KEYCODE_9) {
if (!realAction) return true;
int activePos = keyCode - KeyEvent.KEYCODE_1;
int currentPage = mCandidatesContainer.getCurrentPage();
if (activePos < mDecInfo.getCurrentPageSize(currentPage)) {
activePos = activePos
+ mDecInfo.getCurrentPageStart(currentPage);
if (activePos >= 0) {
chooseAndUpdate(activePos);
}
}
return true;
} else if (keyCode == KeyEvent.KEYCODE_ENTER) {
if (!realAction) return true;
if (mInputModeSwitcher.isEnterNoramlState()) {
commitResultText(mDecInfo.getOrigianlSplStr().toString());
resetToIdleState(false);
} else {
commitResultText(mDecInfo
.getCurrentFullSent(mCandidatesContainer
.getActiveCandiatePos()));
sendKeyChar('\n");
resetToIdleState(false);
}
return true;
} else if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER
|| keyCode == KeyEvent.KEYCODE_SPACE) {
if (!realAction) return true;
chooseCandidate(-1);
return true;
} else if (keyCode == KeyEvent.KEYCODE_BACK) {
if (!realAction) return true;
resetToIdleState(false);
requestHideSelf(0);
return true;
}
return false;
|
private boolean | processStatePredict(int keyChar, int keyCode, android.view.KeyEvent event, boolean realAction)
if (!realAction) return true;
// If ALT key is pressed, input alternative key.
if (event.isAltPressed()) {
char fullwidth_char = KeyMapDream.getChineseLabel(keyCode);
if (0 != fullwidth_char) {
commitResultText(mDecInfo.getCandidate(mCandidatesContainer
.getActiveCandiatePos()) +
String.valueOf(fullwidth_char));
resetToIdleState(false);
}
return true;
}
// In this status, when user presses keys in [a..z], the status will
// change to input state.
if (keyChar >= 'a" && keyChar <= 'z") {
changeToStateInput(true);
mDecInfo.addSplChar((char) keyChar, true);
chooseAndUpdate(-1);
} else if (keyChar == '," || keyChar == '.") {
inputCommaPeriod("", keyChar, true, ImeState.STATE_IDLE);
} else if (keyCode == KeyEvent.KEYCODE_DPAD_UP
|| keyCode == KeyEvent.KEYCODE_DPAD_DOWN
|| keyCode == KeyEvent.KEYCODE_DPAD_LEFT
|| keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
mCandidatesContainer.activeCurseBackward();
}
if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
mCandidatesContainer.activeCurseForward();
}
if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
mCandidatesContainer.pageBackward(false, true);
}
if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
mCandidatesContainer.pageForward(false, true);
}
} else if (keyCode == KeyEvent.KEYCODE_DEL) {
resetToIdleState(false);
} else if (keyCode == KeyEvent.KEYCODE_BACK) {
resetToIdleState(false);
requestHideSelf(0);
} else if (keyCode >= KeyEvent.KEYCODE_1
&& keyCode <= KeyEvent.KEYCODE_9) {
int activePos = keyCode - KeyEvent.KEYCODE_1;
int currentPage = mCandidatesContainer.getCurrentPage();
if (activePos < mDecInfo.getCurrentPageSize(currentPage)) {
activePos = activePos
+ mDecInfo.getCurrentPageStart(currentPage);
if (activePos >= 0) {
chooseAndUpdate(activePos);
}
}
} else if (keyCode == KeyEvent.KEYCODE_ENTER) {
sendKeyChar('\n");
resetToIdleState(false);
} else if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER
|| keyCode == KeyEvent.KEYCODE_SPACE) {
chooseCandidate(-1);
}
return true;
|
private boolean | processSurfaceChange(int keyChar, int keyCode)
if (mDecInfo.isSplStrFull() && KeyEvent.KEYCODE_DEL != keyCode) {
return true;
}
if ((keyChar >= 'a" && keyChar <= 'z")
|| (keyChar == '\'" && !mDecInfo.charBeforeCursorIsSeparator())
|| (((keyChar >= '0" && keyChar <= '9") || keyChar == ' ") && ImeState.STATE_COMPOSING == mImeState)) {
mDecInfo.addSplChar((char) keyChar, false);
chooseAndUpdate(-1);
} else if (keyCode == KeyEvent.KEYCODE_DEL) {
mDecInfo.prepareDeleteBeforeCursor();
chooseAndUpdate(-1);
}
return true;
|
public void | requestHideSelf(int flags)
if (mEnvironment.needDebug()) {
Log.d(TAG, "DimissSoftInput.");
}
dismissCandidateWindow();
if (null != mSkbContainer && mSkbContainer.isShown()) {
mSkbContainer.dismissPopups();
}
super.requestHideSelf(flags);
|
private void | resetCandidateWindow()
if (mEnvironment.needDebug()) {
Log.d(TAG, "Candidates window is to be reset");
}
if (null == mCandidatesContainer) return;
try {
mFloatingWindowTimer.cancelShowing();
mFloatingWindow.dismiss();
} catch (Exception e) {
Log.e(TAG, "Fail to show the PopupWindow.");
}
if (null != mSkbContainer && mSkbContainer.isShown()) {
mSkbContainer.toggleCandidateMode(false);
}
mDecInfo.resetCandidates();
if (null != mCandidatesContainer && mCandidatesContainer.isShown()) {
showCandidateWindow(false);
}
|
private void | resetToIdleState(boolean resetInlineText)
if (ImeState.STATE_IDLE == mImeState) return;
mImeState = ImeState.STATE_IDLE;
mDecInfo.reset();
if (null != mComposingView) mComposingView.reset();
if (resetInlineText) commitResultText("");
resetCandidateWindow();
|
public void | responseSoftKeyEvent(SoftKey sKey)
if (null == sKey) return;
InputConnection ic = getCurrentInputConnection();
if (ic == null) return;
int keyCode = sKey.getKeyCode();
// Process some general keys, including KEYCODE_DEL, KEYCODE_SPACE,
// KEYCODE_ENTER and KEYCODE_DPAD_CENTER.
if (sKey.isKeyCodeKey()) {
if (processFunctionKeys(keyCode, true)) return;
}
if (sKey.isUserDefKey()) {
updateIcon(mInputModeSwitcher.switchModeForUserKey(keyCode));
resetToIdleState(false);
mSkbContainer.updateInputMode();
} else {
if (sKey.isKeyCodeKey()) {
KeyEvent eDown = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
keyCode, 0, 0, 0, 0, KeyEvent.FLAG_SOFT_KEYBOARD);
KeyEvent eUp = new KeyEvent(0, 0, KeyEvent.ACTION_UP, keyCode,
0, 0, 0, 0, KeyEvent.FLAG_SOFT_KEYBOARD);
onKeyDown(keyCode, eDown);
onKeyUp(keyCode, eUp);
} else if (sKey.isUniStrKey()) {
boolean kUsed = false;
String keyLabel = sKey.getKeyLabel();
if (mInputModeSwitcher.isChineseTextWithSkb()
&& (ImeState.STATE_INPUT == mImeState || ImeState.STATE_COMPOSING == mImeState)) {
if (mDecInfo.length() > 0 && keyLabel.length() == 1
&& keyLabel.charAt(0) == '\'") {
processSurfaceChange('\'", 0);
kUsed = true;
}
}
if (!kUsed) {
if (ImeState.STATE_INPUT == mImeState) {
commitResultText(mDecInfo
.getCurrentFullSent(mCandidatesContainer
.getActiveCandiatePos()));
} else if (ImeState.STATE_COMPOSING == mImeState) {
commitResultText(mDecInfo.getComposingStr());
}
commitResultText(keyLabel);
resetToIdleState(false);
}
}
// If the current soft keyboard is not sticky, IME needs to go
// back to the previous soft keyboard automatically.
if (!mSkbContainer.isCurrentSkbSticky()) {
updateIcon(mInputModeSwitcher.requestBackToPreviousSkb());
resetToIdleState(false);
mSkbContainer.updateInputMode();
}
}
|
private void | showCandidateWindow(boolean showComposingView)
if (mEnvironment.needDebug()) {
Log.d(TAG, "Candidates window is shown. Parent = "
+ mCandidatesContainer);
}
setCandidatesViewShown(true);
if (null != mSkbContainer) mSkbContainer.requestLayout();
if (null == mCandidatesContainer) {
resetToIdleState(false);
return;
}
updateComposingText(showComposingView);
mCandidatesContainer.showCandidates(mDecInfo,
ImeState.STATE_COMPOSING != mImeState);
mFloatingWindowTimer.postShowFloatingWindow();
|
public void | showOptionsMenu()
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setCancelable(true);
builder.setIcon(R.drawable.app_icon);
builder.setNegativeButton(android.R.string.cancel, null);
CharSequence itemSettings = getString(R.string.ime_settings_activity_name);
CharSequence itemInputMethod = getString(com.android.internal.R.string.inputMethod);
builder.setItems(new CharSequence[] {itemSettings, itemInputMethod},
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface di, int position) {
di.dismiss();
switch (position) {
case 0:
launchSettings();
break;
case 1:
InputMethodManager.getInstance(PinyinIME.this)
.showInputMethodPicker();
break;
}
}
});
builder.setTitle(getString(R.string.ime_name));
mOptionsDialog = builder.create();
Window window = mOptionsDialog.getWindow();
WindowManager.LayoutParams lp = window.getAttributes();
lp.token = mSkbContainer.getWindowToken();
lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
window.setAttributes(lp);
window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
mOptionsDialog.show();
|
private void | simulateKeyEventDownUp(int keyCode)
InputConnection ic = getCurrentInputConnection();
if (null == ic) return;
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, keyCode));
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, keyCode));
|
private boolean | startPinyinDecoderService()
if (null == mDecInfo.mIPinyinDecoderService) {
Intent serviceIntent = new Intent();
serviceIntent.setClass(this, PinyinDecoderService.class);
if (null == mPinyinDecoderServiceConnection) {
mPinyinDecoderServiceConnection = new PinyinDecoderServiceConnection();
}
// Bind service
if (bindService(serviceIntent, mPinyinDecoderServiceConnection,
Context.BIND_AUTO_CREATE)) {
return true;
} else {
return false;
}
}
return true;
|
private boolean | tryInputRawUnicode(java.lang.String str)
if (str.length() > 7) {
if (str.substring(0, 7).compareTo("unicode") == 0) {
try {
String digitStr = str.substring(7);
int startPos = 0;
int radix = 10;
if (digitStr.length() > 2 && digitStr.charAt(0) == '0"
&& digitStr.charAt(1) == 'x") {
startPos = 2;
radix = 16;
}
digitStr = digitStr.substring(startPos);
int unicode = Integer.parseInt(digitStr, radix);
if (unicode > 0) {
char low = (char) (unicode & 0x0000ffff);
char high = (char) ((unicode & 0xffff0000) >> 16);
commitResultText(String.valueOf(low));
if (0 != high) {
commitResultText(String.valueOf(high));
}
}
return true;
} catch (NumberFormatException e) {
return false;
}
} else if (str.substring(str.length() - 7, str.length()).compareTo(
"unicode") == 0) {
String resultStr = "";
for (int pos = 0; pos < str.length() - 7; pos++) {
if (pos > 0) {
resultStr += " ";
}
resultStr += "0x" + Integer.toHexString(str.charAt(pos));
}
commitResultText(String.valueOf(resultStr));
return true;
}
}
return false;
|
private void | updateComposingText(boolean visible)
if (!visible) {
mComposingView.setVisibility(View.INVISIBLE);
} else {
mComposingView.setDecodingInfo(mDecInfo, mImeState);
mComposingView.setVisibility(View.VISIBLE);
}
mComposingView.invalidate();
|
private void | updateIcon(int iconId)
if (iconId > 0) {
showStatusIcon(iconId);
} else {
hideStatusIcon();
}
|