Example usage for android.view.inputmethod InputConnection endBatchEdit

List of usage examples for android.view.inputmethod InputConnection endBatchEdit

Introduction

In this page you can find the example usage for android.view.inputmethod InputConnection endBatchEdit.

Prototype

boolean endBatchEdit();

Source Link

Document

Tell the editor that you are done with a batch edit previously initiated with #beginBatchEdit .

Usage

From source file:com.anysoftkeyboard.AnySoftKeyboard.java

public void performRestartWordSuggestion(final InputConnection ic) {
    // I assume ASK DOES NOT predict at this moment!

    // 2) predicting and moved outside the word - abort predicting, update
    // shift state
    // 2.1) to a new word - restart predicting on the new word
    // 2.2) to no word land - nothing else

    // this means that the new cursor position is outside the candidates
    // underline//ww w.j  a v a2  s . co m
    // this can be either because the cursor is really outside the
    // previously underlined (suggested)
    // or nothing was suggested.
    // in this case, we would like to reset the prediction and restart
    // if the user clicked inside a different word
    // restart required?
    if (canRestartWordSuggestion()) {// 2.1
        ic.beginBatchEdit();// don't want any events till I finish handling
        // this touch
        abortCorrectionAndResetPredictionState(false);

        // locating the word
        CharSequence toLeft = "";
        CharSequence toRight = "";
        while (true) {
            CharSequence newToLeft = ic.getTextBeforeCursor(toLeft.length() + 1, 0);
            if (TextUtils.isEmpty(newToLeft) || isWordSeparator(newToLeft.charAt(0))
                    || newToLeft.length() == toLeft.length()) {
                break;
            }
            toLeft = newToLeft;
        }
        while (true) {
            CharSequence newToRight = ic.getTextAfterCursor(toRight.length() + 1, 0);
            if (TextUtils.isEmpty(newToRight) || isWordSeparator(newToRight.charAt(newToRight.length() - 1))
                    || newToRight.length() == toRight.length()) {
                break;
            }
            toRight = newToRight;
        }
        CharSequence word = toLeft.toString() + toRight.toString();
        Logger.d(TAG, "Starting new prediction on word '%s'.", word);
        mUndoCommitCursorPosition = UNDO_COMMIT_NONE;
        mWord.reset();

        final int[] tempNearByKeys = new int[1];

        for (int index = 0; index < word.length(); index++) {
            final char c = word.charAt(index);
            if (index == 0)
                mWord.setFirstCharCapitalized(Character.isUpperCase(c));

            tempNearByKeys[0] = c;
            mWord.add(c, tempNearByKeys);

            TextEntryState.typedCharacter(c, false);
        }
        ic.deleteSurroundingText(toLeft.length(), toRight.length());
        ic.setComposingText(word, 1);
        // repositioning the cursor
        if (toRight.length() > 0) {
            final int cursorPosition = getCursorPosition(ic) - toRight.length();
            Logger.d(TAG, "Repositioning the cursor inside the word to position %d", cursorPosition);
            ic.setSelection(cursorPosition, cursorPosition);
        }

        mWord.setCursorPosition(toLeft.length());
        ic.endBatchEdit();
        postUpdateSuggestions();
    } else {
        Logger.d(TAG, "performRestartWordSuggestion canRestartWordSuggestion == false");
    }
}

From source file:com.anysoftkeyboard.AnySoftKeyboard.java

public void pickSuggestionManually(int index, CharSequence suggestion) {
    final String typedWord = mWord.getTypedWord().toString();

    if (mWord.isAtTagsSearchState()) {
        if (index == 0) {
            //this is a special case for tags-searcher
            //since we append a magnifying glass to the suggestions, the "suggestion"
            //value is not a valid output suggestion
            suggestion = typedWord;// w w w .j  av  a 2 s  .  c  o m
        } else {
            //regular emoji. Storing in history.
            List<QuickKeyHistoryRecords.HistoryKey> keys = QuickKeyHistoryRecords.load(getSharedPrefs());
            QuickKeyHistoryRecords.store(getSharedPrefs(), keys,
                    new QuickKeyHistoryRecords.HistoryKey(suggestion.toString(), suggestion.toString()));
        }
    }

    final InputConnection ic = getCurrentInputConnection();
    if (ic != null) {
        ic.beginBatchEdit();
    }

    TextEntryState.acceptedSuggestion(typedWord, suggestion);

    try {
        if (mCompletionOn && mCompletions != null && index >= 0 && index < mCompletions.length) {
            CompletionInfo ci = mCompletions[index];
            if (ic != null) {
                ic.commitCompletion(ci);
            }
            mCommittedWord = suggestion;
            if (mCandidateView != null) {
                mCandidateView.clear();
            }
            return;
        }
        commitWordToInput(suggestion,
                false/*user physically picked a word from the suggestions strip. this is not a fix*/);

        TextEntryState.acceptedSuggestion(mWord.getTypedWord(), suggestion);
        // Follow it with a space
        if (mAutoSpace && (index == 0 || !mWord.isAtTagsSearchState())) {
            sendKeyChar((char) KeyCodes.SPACE);
            mJustAddedAutoSpace = true;
            setSpaceTimeStamp(true);
            TextEntryState.typedCharacter(' ', true);
        }
        // Add the word to the auto dictionary if it's not a known word
        mJustAutoAddedWord = false;

        if (!mWord.isAtTagsSearchState()) {
            if (index == 0) {
                mJustAutoAddedWord = checkAddToDictionaryWithAutoDictionary(mWord,
                        AutoDictionary.AdditionType.Picked);
                if (mJustAutoAddedWord)
                    TextEntryState.acceptedSuggestionAddedToDictionary();
            }

            final boolean showingAddToDictionaryHint = (!mJustAutoAddedWord) && index == 0
                    && (mQuickFixes || mShowSuggestions) && (!mSuggest.isValidWord(suggestion))// this is for the case that the word was auto-added upon picking
                    && (!mSuggest.isValidWord(
                            suggestion.toString().toLowerCase(getCurrentAlphabetKeyboard().getLocale())));

            if (showingAddToDictionaryHint) {
                if (mCandidateView != null)
                    mCandidateView.showAddToDictionaryHint(suggestion);
            } else if (!TextUtils.isEmpty(mCommittedWord) && !mJustAutoAddedWord) {
                //showing next-words if:
                //showingAddToDictionaryHint == false, we most likely do not have a next-word suggestion! The committed word is not in the dictionary
                //mJustAutoAddedWord == false, we most likely do not have a next-word suggestion for a newly added word.
                setSuggestions(mSuggest.getNextSuggestions(mCommittedWord, mWord.isAllUpperCase()), false,
                        false, false);
                mWord.setFirstCharCapitalized(false);
            }
        }
    } finally {
        if (ic != null) {
            ic.endBatchEdit();
        }
    }
}

From source file:com.anysoftkeyboard.AnySoftKeyboard.java

private void handleSeparator(int primaryCode) {
    // Issue 146: Right to left languages require reversed parenthesis
    if (!getCurrentAlphabetKeyboard().isLeftToRightLanguage()) {
        if (primaryCode == (int) ')')
            primaryCode = (int) '(';
        else if (primaryCode == (int) '(')
            primaryCode = (int) ')';
    }/*from ww  w. ja  va 2s . c  o m*/
    mExpectingSelectionUpdateBy = SystemClock.uptimeMillis() + MAX_TIME_TO_EXPECT_SELECTION_UPDATE;
    //will not show next-word suggestion in case of a new line or if the separator is a sentence separator.
    boolean isEndOfSentence = (primaryCode == KeyCodes.ENTER || mSentenceSeparators.get(primaryCode));

    // Should dismiss the "Touch again to save" message when handling
    // separator
    if (mCandidateView != null && mCandidateView.dismissAddToDictionaryHint()) {
        postUpdateSuggestions();
    }

    // Handle separator
    InputConnection ic = getCurrentInputConnection();
    if (ic != null) {
        ic.beginBatchEdit();
    }
    // this is a special case, when the user presses a separator WHILE
    // inside the predicted word.
    // in this case, I will want to just dump the separator.
    final boolean separatorInsideWord = (mWord.cursorPosition() < mWord.length());
    if (TextEntryState.isPredicting() && !separatorInsideWord) {
        //ACTION does not invoke default picking. See https://github.com/AnySoftKeyboard/AnySoftKeyboard/issues/198
        pickDefaultSuggestion(mAutoCorrectOn && primaryCode != KeyCodes.ENTER);
        // Picked the suggestion by a space/punctuation character: we will treat it
        // as "added an auto space".
        mJustAddedAutoSpace = true;
    } else if (separatorInsideWord) {
        // when putting a separator in the middle of a word, there is no
        // need to do correction, or keep knowledge
        abortCorrectionAndResetPredictionState(false);
    }

    if (mJustAddedAutoSpace && primaryCode == KeyCodes.ENTER) {
        removeTrailingSpace();
        mJustAddedAutoSpace = false;
    }

    boolean handledOutputToInputConnection = false;

    if (ic != null) {
        if (primaryCode == KeyCodes.SPACE) {
            if (mAskPrefs.isDoubleSpaceChangesToPeriod()) {
                if ((SystemClock.uptimeMillis()
                        - mLastSpaceTimeStamp) < ((long) mAskPrefs.getMultiTapTimeout())) {
                    //current text in the input-box should be something like "word "
                    //the user pressed on space again. So we want to change the text in the input-box
                    //into "word "->"word. "
                    ic.deleteSurroundingText(1, 0);
                    ic.commitText(". ", 1);
                    mJustAddedAutoSpace = true;
                    isEndOfSentence = true;
                    handledOutputToInputConnection = true;
                }
            }
        } else if (mJustAddedAutoSpace && mLastSpaceTimeStamp != NEVER_TIME_STAMP/*meaning last key was SPACE*/
                && mAskPrefs.shouldSwapPunctuationAndSpace() && primaryCode != KeyCodes.ENTER
                && isSentenceSeparator(primaryCode)) {
            //current text in the input-box should be something like "word "
            //the user pressed a punctuation (say ","). So we want to change the text in the input-box
            //into "word "->"word, "
            ic.deleteSurroundingText(1, 0);
            ic.commitText(((char) primaryCode) + " ", 1);
            mJustAddedAutoSpace = true;
            handledOutputToInputConnection = true;
        }
    }

    if (!handledOutputToInputConnection) {
        sendKeyChar((char) primaryCode);
    }
    TextEntryState.typedCharacter((char) primaryCode, true);

    if (ic != null) {
        ic.endBatchEdit();
    }

    if (isEndOfSentence) {
        mSuggest.resetNextWordSentence();
        clearSuggestions();
    } else if (!TextUtils.isEmpty(mCommittedWord)) {
        setSuggestions(mSuggest.getNextSuggestions(mCommittedWord, mWord.isAllUpperCase()), false, false,
                false);
        mWord.setFirstCharCapitalized(false);
    }
}

From source file:org.distantshoresmedia.keyboard.LatinIME.java

private void handleSeparator(int primaryCode) {

    // Should dismiss the "Touch again to save" message when handling
    // separator/*from  www.  j  av a  2 s.c o m*/
    if (mCandidateView != null && mCandidateView.dismissAddToDictionaryHint()) {
        postUpdateSuggestions();
    }

    boolean pickedDefault = false;
    // Handle separator
    InputConnection ic = getCurrentInputConnection();
    if (ic != null) {
        ic.beginBatchEdit();
        abortCorrection(false);
    }
    if (mPredicting) {
        // In certain languages where single quote is a separator, it's
        // better
        // not to auto correct, but accept the typed word. For instance,
        // in Italian dov' should not be expanded to dove' because the
        // elision
        // requires the last vowel to be removed.
        if (mAutoCorrectOn && primaryCode != '\'' && (mJustRevertedSeparator == null
                || mJustRevertedSeparator.length() == 0 || mJustRevertedSeparator.charAt(0) != primaryCode)) {
            pickedDefault = pickDefaultSuggestion();
            // Picked the suggestion by the space key. We consider this
            // as "added an auto space" in autocomplete mode, but as manually
            // typed space in "quick fixes" mode.
            if (primaryCode == ASCII_SPACE) {
                if (mAutoCorrectEnabled) {
                    mJustAddedAutoSpace = true;
                } else {
                    TextEntryState.manualTyped("");
                }
            }
        } else {
            commitTyped(ic, true);
        }
    }
    if (mJustAddedAutoSpace && primaryCode == ASCII_ENTER) {
        removeTrailingSpace();
        mJustAddedAutoSpace = false;
    }
    sendModifiableKeyChar((char) primaryCode);

    // Handle the case of ". ." -> " .." with auto-space if necessary
    // before changing the TextEntryState.
    if (TextEntryState.getState() == TextEntryState.State.PUNCTUATION_AFTER_ACCEPTED
            && primaryCode == ASCII_PERIOD) {
        reswapPeriodAndSpace();
    }

    TextEntryState.typedCharacter((char) primaryCode, true);
    if (TextEntryState.getState() == TextEntryState.State.PUNCTUATION_AFTER_ACCEPTED
            && primaryCode != ASCII_ENTER) {
        swapPunctuationAndSpace();
    } else if (isPredictionOn() && primaryCode == ASCII_SPACE) {
        doubleSpace();
    }
    if (pickedDefault) {
        TextEntryState.backToAcceptedDefault(mWord.getTypedWord());
    }
    updateShiftKeyState(getCurrentInputEditorInfo());
    if (ic != null) {
        ic.endBatchEdit();
    }
}

From source file:com.yek.keyboard.anysoftkeyboard.AnySoftKeyboard.java

@Override
public boolean onKeyDown(final int keyEventKeyCode, @NonNull KeyEvent event) {
    InputConnection ic = getCurrentInputConnection();
    if (handleSelectionExpending(keyEventKeyCode, ic, mGlobalSelectionStartPosition, mGlobalCursorPosition))
        return true;
    final boolean shouldTranslateSpecialKeys = isInputViewShown();

    //greater than zero means it is a physical keyboard.
    //we also want to hide the view if it's a glyph (for example, not physical volume-up key)
    if (event.getDeviceId() > 0 && event.isPrintingKey())
        onPhysicalKeyboardKeyPressed();//from w ww.j  av  a2 s . co m

    mHardKeyboardAction.initializeAction(event, mMetaState);

    switch (keyEventKeyCode) {
    /****
     * SPECIAL translated HW keys If you add new keys here, do not forget
     * to add to the
     */
    case KeyEvent.KEYCODE_CAMERA:
        if (shouldTranslateSpecialKeys && mAskPrefs.useCameraKeyForBackspaceBackword()) {
            handleBackWord(getCurrentInputConnection());
            return true;
        }
        // DO NOT DELAY CAMERA KEY with unneeded checks in default mark
        return super.onKeyDown(keyEventKeyCode, event);
    case KeyEvent.KEYCODE_FOCUS:
        if (shouldTranslateSpecialKeys && mAskPrefs.useCameraKeyForBackspaceBackword()) {
            handleDeleteLastCharacter(false);
            return true;
        }
        // DO NOT DELAY FOCUS KEY with unneeded checks in default mark
        return super.onKeyDown(keyEventKeyCode, event);
    case KeyEvent.KEYCODE_VOLUME_UP:
        if (shouldTranslateSpecialKeys && mAskPrefs.useVolumeKeyForLeftRight()) {
            sendDownUpKeyEvents(KeyEvent.KEYCODE_DPAD_LEFT);
            return true;
        }
        // DO NOT DELAY VOLUME UP KEY with unneeded checks in default
        // mark
        return super.onKeyDown(keyEventKeyCode, event);
    case KeyEvent.KEYCODE_VOLUME_DOWN:
        if (shouldTranslateSpecialKeys && mAskPrefs.useVolumeKeyForLeftRight()) {
            sendDownUpKeyEvents(KeyEvent.KEYCODE_DPAD_RIGHT);
            return true;
        }
        // DO NOT DELAY VOLUME DOWN KEY with unneeded checks in default
        // mark
        return super.onKeyDown(keyEventKeyCode, event);
    /****
     * END of SPECIAL translated HW keys code section
     */
    case KeyEvent.KEYCODE_BACK:
        if (event.getRepeatCount() == 0 && getInputView() != null) {
            if (getInputView().handleBack()) {
                // consuming the meta keys
                if (ic != null) {
                    // translated, so we also take care of the metakeys
                    ic.clearMetaKeyStates(Integer.MAX_VALUE);
                }
                mMetaState = 0;
                return true;
            }
        }
        break;
    case 0x000000cc:// API 14: KeyEvent.KEYCODE_LANGUAGE_SWITCH
        switchToNextPhysicalKeyboard(ic);
        return true;
    case KeyEvent.KEYCODE_SHIFT_LEFT:
    case KeyEvent.KEYCODE_SHIFT_RIGHT:
        if (event.isAltPressed() && Workarounds.isAltSpaceLangSwitchNotPossible()) {
            switchToNextPhysicalKeyboard(ic);
            return true;
        }
        // NOTE: letting it fall-through to the other meta-keys
    case KeyEvent.KEYCODE_ALT_LEFT:
    case KeyEvent.KEYCODE_ALT_RIGHT:
    case KeyEvent.KEYCODE_SYM:
        Logger.d(TAG + "-meta-key", getMetaKeysStates("onKeyDown before handle"));
        mMetaState = MyMetaKeyKeyListener.handleKeyDown(mMetaState, keyEventKeyCode, event);
        Logger.d(TAG + "-meta-key", getMetaKeysStates("onKeyDown after handle"));
        break;
    case KeyEvent.KEYCODE_SPACE:
        if ((event.isAltPressed() && !Workarounds.isAltSpaceLangSwitchNotPossible())
                || event.isShiftPressed()) {
            switchToNextPhysicalKeyboard(ic);
            return true;
        }
        // NOTE:
        // letting it fall through to the "default"
    default:

        // Fix issue 185, check if we should process key repeat
        if (!mAskPrefs.getUseRepeatingKeys() && event.getRepeatCount() > 0)
            return true;

        AnyKeyboard.HardKeyboardTranslator keyTranslator = (AnyKeyboard.HardKeyboardTranslator) getCurrentAlphabetKeyboard();
        if (getKeyboardSwitcher().isCurrentKeyboardPhysical() && keyTranslator != null) {
            // sometimes, the physical keyboard will delete input, and then add some.
            // we'll try to make it nice.
            if (ic != null)
                ic.beginBatchEdit();
            try {
                // issue 393, backword on the hw keyboard!
                if (mAskPrefs.useBackword() && keyEventKeyCode == KeyEvent.KEYCODE_DEL
                        && event.isShiftPressed()) {
                    handleBackWord(ic);
                    return true;
                } else {
                    // http://article.gmane.org/gmane.comp.handhelds.openmoko.android-freerunner/629
                    keyTranslator.translatePhysicalCharacter(mHardKeyboardAction, this);

                    if (mHardKeyboardAction.getKeyCodeWasChanged()) {
                        final int translatedChar = mHardKeyboardAction.getKeyCode();
                        // typing my own.
                        onKey(translatedChar, null, -1, new int[] { translatedChar }, true/*faking from UI*/);
                        // my handling we are at a regular key press, so we'll update
                        // our meta-state member
                        mMetaState = MyMetaKeyKeyListener.adjustMetaAfterKeypress(mMetaState);
                        Logger.d(TAG + "-meta-key", getMetaKeysStates("onKeyDown after adjust - translated"));
                        return true;
                    }
                }
            } finally {
                if (ic != null)
                    ic.endBatchEdit();
            }
        }
        if (event.isPrintingKey()) {
            // we are at a regular key press, so we'll update our
            // meta-state
            // member
            mMetaState = MyMetaKeyKeyListener.adjustMetaAfterKeypress(mMetaState);
            Logger.d(TAG + "-meta-key", getMetaKeysStates("onKeyDown after adjust"));
        }
    }
    return super.onKeyDown(keyEventKeyCode, event);
}

From source file:com.anysoftkeyboard.AnySoftKeyboard.java

@Override
public boolean onKeyDown(final int keyEventKeyCode, @NonNull KeyEvent event) {
    InputConnection ic = getCurrentInputConnection();
    if (handleSelectionExpending(keyEventKeyCode, ic, mGlobalSelectionStartPosition, mGlobalCursorPosition))
        return true;
    final boolean shouldTranslateSpecialKeys = isInputViewShown();

    //greater than zero means it is a physical keyboard.
    //we also want to hide the view if it's a glyph (for example, not physical volume-up key)
    if (event.getDeviceId() > 0 && event.isPrintingKey())
        onPhysicalKeyboardKeyPressed();/*www.j  a  va 2 s  . c  om*/

    mHardKeyboardAction.initializeAction(event, mMetaState);

    switch (keyEventKeyCode) {
    /****
     * SPECIAL translated HW keys If you add new keys here, do not forget
     * to add to the
     */
    case KeyEvent.KEYCODE_CAMERA:
        if (shouldTranslateSpecialKeys && mAskPrefs.useCameraKeyForBackspaceBackword()) {
            handleBackWord(getCurrentInputConnection());
            return true;
        }
        // DO NOT DELAY CAMERA KEY with unneeded checks in default mark
        return super.onKeyDown(keyEventKeyCode, event);
    case KeyEvent.KEYCODE_FOCUS:
        if (shouldTranslateSpecialKeys && mAskPrefs.useCameraKeyForBackspaceBackword()) {
            handleDeleteLastCharacter(false);
            return true;
        }
        // DO NOT DELAY FOCUS KEY with unneeded checks in default mark
        return super.onKeyDown(keyEventKeyCode, event);
    case KeyEvent.KEYCODE_VOLUME_UP:
        if (shouldTranslateSpecialKeys && mAskPrefs.useVolumeKeyForLeftRight()) {
            sendDownUpKeyEvents(KeyEvent.KEYCODE_DPAD_LEFT);
            return true;
        }
        // DO NOT DELAY VOLUME UP KEY with unneeded checks in default
        // mark
        return super.onKeyDown(keyEventKeyCode, event);
    case KeyEvent.KEYCODE_VOLUME_DOWN:
        if (shouldTranslateSpecialKeys && mAskPrefs.useVolumeKeyForLeftRight()) {
            sendDownUpKeyEvents(KeyEvent.KEYCODE_DPAD_RIGHT);
            return true;
        }
        // DO NOT DELAY VOLUME DOWN KEY with unneeded checks in default
        // mark
        return super.onKeyDown(keyEventKeyCode, event);
    /****
     * END of SPECIAL translated HW keys code section
     */
    case KeyEvent.KEYCODE_BACK:
        if (event.getRepeatCount() == 0 && getInputView() != null) {
            if (getInputView().handleBack()) {
                // consuming the meta keys
                if (ic != null) {
                    // translated, so we also take care of the metakeys
                    ic.clearMetaKeyStates(Integer.MAX_VALUE);
                }
                mMetaState = 0;
                return true;
            }
        }
        break;
    case 0x000000cc:// API 14: KeyEvent.KEYCODE_LANGUAGE_SWITCH
        switchToNextPhysicalKeyboard(ic);
        return true;
    case KeyEvent.KEYCODE_SHIFT_LEFT:
    case KeyEvent.KEYCODE_SHIFT_RIGHT:
        if (event.isAltPressed() && Workarounds.isAltSpaceLangSwitchNotPossible()) {
            switchToNextPhysicalKeyboard(ic);
            return true;
        }
        // NOTE: letting it fall-through to the other meta-keys
    case KeyEvent.KEYCODE_ALT_LEFT:
    case KeyEvent.KEYCODE_ALT_RIGHT:
    case KeyEvent.KEYCODE_SYM:
        Logger.d(TAG + "-meta-key", getMetaKeysStates("onKeyDown before handle"));
        mMetaState = MyMetaKeyKeyListener.handleKeyDown(mMetaState, keyEventKeyCode, event);
        Logger.d(TAG + "-meta-key", getMetaKeysStates("onKeyDown after handle"));
        break;
    case KeyEvent.KEYCODE_SPACE:
        if ((event.isAltPressed() && !Workarounds.isAltSpaceLangSwitchNotPossible())
                || event.isShiftPressed()) {
            switchToNextPhysicalKeyboard(ic);
            return true;
        }
        // NOTE:
        // letting it fall through to the "default"
    default:

        // Fix issue 185, check if we should process key repeat
        if (!mAskPrefs.getUseRepeatingKeys() && event.getRepeatCount() > 0)
            return true;

        HardKeyboardTranslator keyTranslator = (HardKeyboardTranslator) getCurrentAlphabetKeyboard();
        if (getKeyboardSwitcher().isCurrentKeyboardPhysical() && keyTranslator != null) {
            // sometimes, the physical keyboard will delete input, and then add some.
            // we'll try to make it nice.
            if (ic != null)
                ic.beginBatchEdit();
            try {
                // issue 393, backword on the hw keyboard!
                if (mAskPrefs.useBackword() && keyEventKeyCode == KeyEvent.KEYCODE_DEL
                        && event.isShiftPressed()) {
                    handleBackWord(ic);
                    return true;
                } else {
                    // http://article.gmane.org/gmane.comp.handhelds.openmoko.android-freerunner/629
                    keyTranslator.translatePhysicalCharacter(mHardKeyboardAction, this);

                    if (mHardKeyboardAction.getKeyCodeWasChanged()) {
                        final int translatedChar = mHardKeyboardAction.getKeyCode();
                        // typing my own.
                        onKey(translatedChar, null, -1, new int[] { translatedChar }, true/*faking from UI*/);
                        // my handling we are at a regular key press, so we'll update
                        // our meta-state member
                        mMetaState = MyMetaKeyKeyListener.adjustMetaAfterKeypress(mMetaState);
                        Logger.d(TAG + "-meta-key", getMetaKeysStates("onKeyDown after adjust - translated"));
                        return true;
                    }
                }
            } finally {
                if (ic != null)
                    ic.endBatchEdit();
            }
        }
        if (event.isPrintingKey()) {
            // we are at a regular key press, so we'll update our
            // meta-state
            // member
            mMetaState = MyMetaKeyKeyListener.adjustMetaAfterKeypress(mMetaState);
            Logger.d(TAG + "-meta-key", getMetaKeysStates("onKeyDown after adjust"));
        }
    }
    return super.onKeyDown(keyEventKeyCode, event);
}