use of com.android.inputmethod.latin.settings.SettingsValues in project android_packages_inputmethods_LatinIME by CyanogenMod.
the class InputLogic method handleSeparatorEvent.
/**
* Handle input of a separator code point.
* @param event The event to handle.
* @param inputTransaction The transaction in progress.
*/
private void handleSeparatorEvent(final Event event, final InputTransaction inputTransaction, final LatinIME.UIHandler handler) {
final int codePoint = event.mCodePoint;
final SettingsValues settingsValues = inputTransaction.mSettingsValues;
final boolean wasComposingWord = mWordComposer.isComposingWord();
// We avoid sending spaces in languages without spaces if we were composing.
final boolean shouldAvoidSendingCode = Constants.CODE_SPACE == codePoint && !settingsValues.mSpacingAndPunctuations.mCurrentLanguageHasSpaces && wasComposingWord;
if (mWordComposer.isCursorFrontOrMiddleOfComposingWord()) {
// If we are in the middle of a recorrection, we need to commit the recorrection
// first so that we can insert the separator at the current cursor position.
// We also need to unlearn the original word that is now being corrected.
unlearnWord(mWordComposer.getTypedWord(), inputTransaction.mSettingsValues, Constants.EVENT_BACKSPACE);
resetEntireInputState(mConnection.getExpectedSelectionStart(), mConnection.getExpectedSelectionEnd(), true);
}
// isComposingWord() may have changed since we stored wasComposing
if (mWordComposer.isComposingWord()) {
if (settingsValues.mAutoCorrectionEnabledPerUserSettings) {
final String separator = shouldAvoidSendingCode ? LastComposedWord.NOT_A_SEPARATOR : StringUtils.newSingleCodePointString(codePoint);
commitCurrentAutoCorrection(settingsValues, separator, handler);
inputTransaction.setDidAutoCorrect();
} else {
commitTyped(settingsValues, StringUtils.newSingleCodePointString(codePoint));
}
}
final boolean swapWeakSpace = tryStripSpaceAndReturnWhetherShouldSwapInstead(event, inputTransaction);
final boolean isInsideDoubleQuoteOrAfterDigit = Constants.CODE_DOUBLE_QUOTE == codePoint && mConnection.isInsideDoubleQuoteOrAfterDigit();
final boolean needsPrecedingSpace;
if (SpaceState.PHANTOM != inputTransaction.mSpaceState) {
needsPrecedingSpace = false;
} else if (Constants.CODE_DOUBLE_QUOTE == codePoint) {
// Double quotes behave like they are usually preceded by space iff we are
// not inside a double quote or after a digit.
needsPrecedingSpace = !isInsideDoubleQuoteOrAfterDigit;
} else if (settingsValues.mSpacingAndPunctuations.isClusteringSymbol(codePoint) && settingsValues.mSpacingAndPunctuations.isClusteringSymbol(mConnection.getCodePointBeforeCursor())) {
needsPrecedingSpace = false;
} else {
needsPrecedingSpace = settingsValues.isUsuallyPrecededBySpace(codePoint);
}
if (needsPrecedingSpace) {
insertAutomaticSpaceIfOptionsAndTextAllow(settingsValues);
}
if (tryPerformDoubleSpacePeriod(event, inputTransaction)) {
mSpaceState = SpaceState.DOUBLE;
inputTransaction.setRequiresUpdateSuggestions();
StatsUtils.onDoubleSpacePeriod();
} else if (swapWeakSpace && trySwapSwapperAndSpace(event, inputTransaction)) {
mSpaceState = SpaceState.SWAP_PUNCTUATION;
mSuggestionStripViewAccessor.setNeutralSuggestionStrip();
} else if (Constants.CODE_SPACE == codePoint) {
if (!mSuggestedWords.isPunctuationSuggestions()) {
mSpaceState = SpaceState.WEAK;
}
startDoubleSpacePeriodCountdown(inputTransaction);
if (wasComposingWord || mSuggestedWords.isEmpty()) {
inputTransaction.setRequiresUpdateSuggestions();
}
if (!shouldAvoidSendingCode) {
sendKeyCodePoint(settingsValues, codePoint);
}
} else {
if ((SpaceState.PHANTOM == inputTransaction.mSpaceState && settingsValues.isUsuallyFollowedBySpace(codePoint)) || (Constants.CODE_DOUBLE_QUOTE == codePoint && isInsideDoubleQuoteOrAfterDigit)) {
// If we are in phantom space state, and the user presses a separator, we want to
// stay in phantom space state so that the next keypress has a chance to add the
// space. For example, if I type "Good dat", pick "day" from the suggestion strip
// then insert a comma and go on to typing the next word, I want the space to be
// inserted automatically before the next word, the same way it is when I don't
// input the comma. A double quote behaves like it's usually followed by space if
// we're inside a double quote.
// The case is a little different if the separator is a space stripper. Such a
// separator does not normally need a space on the right (that's the difference
// between swappers and strippers), so we should not stay in phantom space state if
// the separator is a stripper. Hence the additional test above.
mSpaceState = SpaceState.PHANTOM;
}
sendKeyCodePoint(settingsValues, codePoint);
// Set punctuation right away. onUpdateSelection will fire but tests whether it is
// already displayed or not, so it's okay.
mSuggestionStripViewAccessor.setNeutralSuggestionStrip();
}
inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
}
use of com.android.inputmethod.latin.settings.SettingsValues in project android_packages_inputmethods_LatinIME by CyanogenMod.
the class LatinIME method onUpdateSelection.
@Override
public void onUpdateSelection(final int oldSelStart, final int oldSelEnd, final int newSelStart, final int newSelEnd, final int composingSpanStart, final int composingSpanEnd) {
super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd, composingSpanStart, composingSpanEnd);
if (DebugFlags.DEBUG_ENABLED) {
Log.i(TAG, "onUpdateSelection: oss=" + oldSelStart + ", ose=" + oldSelEnd + ", nss=" + newSelStart + ", nse=" + newSelEnd + ", cs=" + composingSpanStart + ", ce=" + composingSpanEnd);
}
// This call happens whether our view is displayed or not, but if it's not then we should
// not attempt recorrection. This is true even with a hardware keyboard connected: if the
// view is not displayed we have no means of showing suggestions anyway, and if it is then
// we want to show suggestions anyway.
final SettingsValues settingsValues = mSettings.getCurrent();
if (isInputViewShown() && mInputLogic.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd, settingsValues)) {
mKeyboardSwitcher.requestUpdatingShiftState(getCurrentAutoCapsState(), getCurrentRecapitalizeState());
}
}
use of com.android.inputmethod.latin.settings.SettingsValues in project android_packages_inputmethods_LatinIME by CyanogenMod.
the class LatinIME method onStartInputViewInternal.
@SuppressWarnings("deprecation")
void onStartInputViewInternal(final EditorInfo editorInfo, final boolean restarting) {
super.onStartInputView(editorInfo, restarting);
mDictionaryFacilitator.onStartInput();
// Switch to the null consumer to handle cases leading to early exit below, for which we
// also wouldn't be consuming gesture data.
mGestureConsumer = GestureConsumer.NULL_GESTURE_CONSUMER;
mRichImm.refreshSubtypeCaches();
final KeyboardSwitcher switcher = mKeyboardSwitcher;
switcher.updateKeyboardTheme();
final MainKeyboardView mainKeyboardView = switcher.getMainKeyboardView();
// If we are starting input in a different text field from before, we'll have to reload
// settings, so currentSettingsValues can't be final.
SettingsValues currentSettingsValues = mSettings.getCurrent();
if (editorInfo == null) {
Log.e(TAG, "Null EditorInfo in onStartInputView()");
if (DebugFlags.DEBUG_ENABLED) {
throw new NullPointerException("Null EditorInfo in onStartInputView()");
}
return;
}
if (DebugFlags.DEBUG_ENABLED) {
Log.d(TAG, "onStartInputView: editorInfo:" + String.format("inputType=0x%08x imeOptions=0x%08x", editorInfo.inputType, editorInfo.imeOptions));
Log.d(TAG, "All caps = " + ((editorInfo.inputType & InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS) != 0) + ", sentence caps = " + ((editorInfo.inputType & InputType.TYPE_TEXT_FLAG_CAP_SENTENCES) != 0) + ", word caps = " + ((editorInfo.inputType & InputType.TYPE_TEXT_FLAG_CAP_WORDS) != 0));
}
Log.i(TAG, "Starting input. Cursor position = " + editorInfo.initialSelStart + "," + editorInfo.initialSelEnd);
// TODO: Consolidate these checks with {@link InputAttributes}.
if (InputAttributes.inPrivateImeOptions(null, NO_MICROPHONE_COMPAT, editorInfo)) {
Log.w(TAG, "Deprecated private IME option specified: " + editorInfo.privateImeOptions);
Log.w(TAG, "Use " + getPackageName() + "." + NO_MICROPHONE + " instead");
}
if (InputAttributes.inPrivateImeOptions(getPackageName(), FORCE_ASCII, editorInfo)) {
Log.w(TAG, "Deprecated private IME option specified: " + editorInfo.privateImeOptions);
Log.w(TAG, "Use EditorInfo.IME_FLAG_FORCE_ASCII flag instead");
}
// In landscape mode, this method gets called without the input view being created.
if (mainKeyboardView == null) {
return;
}
// Update to a gesture consumer with the current editor and IME state.
mGestureConsumer = GestureConsumer.newInstance(editorInfo, mInputLogic.getPrivateCommandPerformer(), mRichImm.getCurrentSubtypeLocale(), switcher.getKeyboard());
// Forward this event to the accessibility utilities, if enabled.
final AccessibilityUtils accessUtils = AccessibilityUtils.getInstance();
if (accessUtils.isTouchExplorationEnabled()) {
accessUtils.onStartInputViewInternal(mainKeyboardView, editorInfo, restarting);
}
final boolean inputTypeChanged = !currentSettingsValues.isSameInputType(editorInfo);
final boolean isDifferentTextField = !restarting || inputTypeChanged;
StatsUtils.onStartInputView(editorInfo.inputType, Settings.getInstance().getCurrent().mDisplayOrientation, !isDifferentTextField);
// The EditorInfo might have a flag that affects fullscreen mode.
// Note: This call should be done by InputMethodService?
updateFullscreenMode();
// ALERT: settings have not been reloaded and there is a chance they may be stale.
// In the practice, if it is, we should have gotten onConfigurationChanged so it should
// be fine, but this is horribly confusing and must be fixed AS SOON AS POSSIBLE.
// In some cases the input connection has not been reset yet and we can't access it. In
// this case we will need to call loadKeyboard() later, when it's accessible, so that we
// can go into the correct mode, so we need to do some housekeeping here.
final boolean needToCallLoadKeyboardLater;
final Suggest suggest = mInputLogic.mSuggest;
if (!isImeSuppressedByHardwareKeyboard()) {
// The app calling setText() has the effect of clearing the composing
// span, so we should reset our state unconditionally, even if restarting is true.
// We also tell the input logic about the combining rules for the current subtype, so
// it can adjust its combiners if needed.
mInputLogic.startInput(mRichImm.getCombiningRulesExtraValueOfCurrentSubtype(), currentSettingsValues);
resetDictionaryFacilitatorIfNecessary();
// TODO[IL]: Can the following be moved to InputLogic#startInput?
if (!mInputLogic.mConnection.resetCachesUponCursorMoveAndReturnSuccess(editorInfo.initialSelStart, editorInfo.initialSelEnd, false)) {
// Sometimes, while rotating, for some reason the framework tells the app we are not
// connected to it and that means we can't refresh the cache. In this case, schedule
// a refresh later.
// We try resetting the caches up to 5 times before giving up.
mHandler.postResetCaches(isDifferentTextField, 5);
// mLastSelection{Start,End} are reset later in this method, no need to do it here
needToCallLoadKeyboardLater = true;
} else {
// When rotating, and when input is starting again in a field from where the focus
// didn't move (the keyboard having been closed with the back key),
// initialSelStart and initialSelEnd sometimes are lying. Make a best effort to
// work around this bug.
mInputLogic.mConnection.tryFixLyingCursorPosition();
mHandler.postResumeSuggestionsForStartInput(true);
needToCallLoadKeyboardLater = false;
}
} else {
// If we have a hardware keyboard we don't need to call loadKeyboard later anyway.
needToCallLoadKeyboardLater = false;
}
if (isDifferentTextField || !currentSettingsValues.hasSameOrientation(getResources().getConfiguration())) {
loadSettings();
}
if (isDifferentTextField) {
mainKeyboardView.closing();
currentSettingsValues = mSettings.getCurrent();
if (currentSettingsValues.mAutoCorrectionEnabledPerUserSettings) {
suggest.setAutoCorrectionThreshold(currentSettingsValues.mAutoCorrectionThreshold);
}
suggest.setPlausibilityThreshold(currentSettingsValues.mPlausibilityThreshold);
switcher.loadKeyboard(editorInfo, currentSettingsValues, getCurrentAutoCapsState(), getCurrentRecapitalizeState());
if (needToCallLoadKeyboardLater) {
// If we need to call loadKeyboard again later, we need to save its state now. The
// later call will be done in #retryResetCaches.
switcher.saveKeyboardState();
}
} else if (restarting) {
// TODO: Come up with a more comprehensive way to reset the keyboard layout when
// a keyboard layout set doesn't get reloaded in this method.
switcher.resetKeyboardStateToAlphabet(getCurrentAutoCapsState(), getCurrentRecapitalizeState());
// In apps like Talk, we come here when the text is sent and the field gets emptied and
// we need to re-evaluate the shift state, but not the whole layout which would be
// disruptive.
// Space state must be updated before calling updateShiftState
switcher.requestUpdatingShiftState(getCurrentAutoCapsState(), getCurrentRecapitalizeState());
}
// This will set the punctuation suggestions if next word suggestion is off;
// otherwise it will clear the suggestion strip.
setNeutralSuggestionStrip();
mHandler.cancelUpdateSuggestionStrip();
mainKeyboardView.setMainDictionaryAvailability(mDictionaryFacilitator.hasAtLeastOneInitializedMainDictionary());
mainKeyboardView.setKeyPreviewPopupEnabled(currentSettingsValues.mKeyPreviewPopupOn, currentSettingsValues.mKeyPreviewPopupDismissDelay);
mainKeyboardView.setSlidingKeyInputPreviewEnabled(currentSettingsValues.mSlidingKeyInputPreviewEnabled);
mainKeyboardView.setGestureHandlingEnabledByUser(currentSettingsValues.mGestureInputEnabled, currentSettingsValues.mGestureTrailEnabled, currentSettingsValues.mGestureFloatingPreviewTextEnabled);
if (TRACE)
Debug.startMethodTracing("/data/trace/latinime");
}
use of com.android.inputmethod.latin.settings.SettingsValues in project android_packages_inputmethods_LatinIME by CyanogenMod.
the class LatinIME method onEvaluateFullscreenMode.
@Override
public boolean onEvaluateFullscreenMode() {
final SettingsValues settingsValues = mSettings.getCurrent();
if (isImeSuppressedByHardwareKeyboard()) {
// If there is a hardware keyboard, disable full screen mode.
return false;
}
// Reread resource value here, because this method is called by the framework as needed.
final boolean isFullscreenModeAllowed = Settings.readUseFullscreenMode(getResources());
if (super.onEvaluateFullscreenMode() && isFullscreenModeAllowed) {
// TODO: Remove this hack. Actually we should not really assume NO_EXTRACT_UI
// implies NO_FULLSCREEN. However, the framework mistakenly does. i.e. NO_EXTRACT_UI
// without NO_FULLSCREEN doesn't work as expected. Because of this we need this
// hack for now. Let's get rid of this once the framework gets fixed.
final EditorInfo ei = getCurrentInputEditorInfo();
return !(ei != null && ((ei.imeOptions & EditorInfo.IME_FLAG_NO_EXTRACT_UI) != 0));
}
return false;
}
use of com.android.inputmethod.latin.settings.SettingsValues in project android_packages_inputmethods_LatinIME by CyanogenMod.
the class LatinIME method onConfigurationChanged.
@Override
public void onConfigurationChanged(final Configuration conf) {
SettingsValues settingsValues = mSettings.getCurrent();
if (settingsValues.mDisplayOrientation != conf.orientation) {
mHandler.startOrientationChanging();
mInputLogic.onOrientationChange(mSettings.getCurrent());
}
if (settingsValues.mHasHardwareKeyboard != Settings.readHasHardwareKeyboard(conf)) {
// If the state of having a hardware keyboard changed, then we want to reload the
// settings to adjust for that.
// TODO: we should probably do this unconditionally here, rather than only when we
// have a change in hardware keyboard configuration.
loadSettings();
settingsValues = mSettings.getCurrent();
if (isImeSuppressedByHardwareKeyboard()) {
// We call cleanupInternalStateForFinishInput() because it's the right thing to do;
// however, it seems at the moment the framework is passing us a seemingly valid
// but actually non-functional InputConnection object. So if this bug ever gets
// fixed we'll be able to remove the composition, but until it is this code is
// actually not doing much.
cleanupInternalStateForFinishInput();
}
}
super.onConfigurationChanged(conf);
}
Aggregations