diff options
Diffstat (limited to 'java/src')
16 files changed, 305 insertions, 139 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index fb84f1d73..53b448515 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java @@ -187,7 +187,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { final MainKeyboardView keyboardView = mKeyboardView; final Keyboard oldKeyboard = keyboardView.getKeyboard(); keyboardView.setKeyboard(keyboard); - mCurrentInputView.setKeyboardGeometry(keyboard.mTopPadding); + mCurrentInputView.setKeyboardTopPadding(keyboard.mTopPadding); keyboardView.setKeyPreviewPopupEnabled( Settings.readKeyPreviewPopupEnabled(mPrefs, mResources), Settings.readKeyPreviewPopupDismissDelay(mPrefs, mResources)); diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java index 1400e05c8..4b6e12f8e 100644 --- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java @@ -932,11 +932,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack @Override public void onShowMoreKeysPanel(final MoreKeysPanel panel) { locatePreviewPlacerView(); - // TODO: Remove this check - if (panel.isShowingInParent()) { - panel.dismissMoreKeysPanel(); - } - mPreviewPlacerView.addView(panel.getContainerView()); + panel.showInParent(mPreviewPlacerView); mMoreKeysPanel = panel; dimEntireKeyboard(true /* dimmed */); } @@ -954,7 +950,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack public void onDismissMoreKeysPanel(final MoreKeysPanel panel) { dimEntireKeyboard(false /* dimmed */); if (isShowingMoreKeysPanel()) { - mPreviewPlacerView.removeView(mMoreKeysPanel.getContainerView()); + mMoreKeysPanel.removeFromParent(); mMoreKeysPanel = null; } } diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java index a7c468538..5b13e9a41 100644 --- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java @@ -21,6 +21,7 @@ import android.content.res.Resources; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; +import android.view.ViewGroup; import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.R; @@ -216,12 +217,26 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel return true; } - @Override - public View getContainerView() { + private View getContainerView() { return (View)getParent(); } @Override + public void showInParent(final ViewGroup parentView) { + removeFromParent(); + parentView.addView(getContainerView()); + } + + @Override + public void removeFromParent() { + final View containerView = getContainerView(); + final ViewGroup currentParent = (ViewGroup)containerView.getParent(); + if (currentParent != null) { + currentParent.removeView(containerView); + } + } + + @Override public boolean isShowingInParent() { return (getContainerView().getParent() != null); } diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysPanel.java b/java/src/com/android/inputmethod/keyboard/MoreKeysPanel.java index 886c6286f..4a33e6536 100644 --- a/java/src/com/android/inputmethod/keyboard/MoreKeysPanel.java +++ b/java/src/com/android/inputmethod/keyboard/MoreKeysPanel.java @@ -17,6 +17,7 @@ package com.android.inputmethod.keyboard; import android.view.View; +import android.view.ViewGroup; public interface MoreKeysPanel { public interface Controller { @@ -119,9 +120,16 @@ public interface MoreKeysPanel { public int translateY(int y); /** - * Return the view containing the more keys panel. + * Show this {@link MoreKeysPanel} in the parent view. + * + * @param parentView the {@link ViewGroup} that hosts this {@link MoreKeysPanel}. + */ + public void showInParent(ViewGroup parentView); + + /** + * Remove this {@link MoreKeysPanel} from the parent view. */ - public View getContainerView(); + public void removeFromParent(); /** * Return whether the panel is currently being shown. diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java index a2528e046..e23d5a773 100644 --- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java +++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java @@ -167,10 +167,10 @@ public final class PointerTracker implements PointerTrackerQueue.Element { private static boolean sInGesture = false; private static long sGestureFirstDownTime; private static TimeRecorder sTimeRecorder; - private static final InputPointers sAggregratedPointers = new InputPointers( + private static final InputPointers sAggregatedPointers = new InputPointers( GestureStroke.DEFAULT_CAPACITY); - private static int sLastRecognitionPointSize = 0; // synchronized using sAggregratedPointers - private static long sLastRecognitionTime = 0; // synchronized using sAggregratedPointers + private static int sLastRecognitionPointSize = 0; // synchronized using sAggregatedPointers + private static long sLastRecognitionTime = 0; // synchronized using sAggregatedPointers static final class BogusMoveEventDetector { // Move these thresholds to resource. @@ -737,8 +737,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element { Log.d(TAG, String.format("[%d] onStartBatchInput", mPointerId)); } sInGesture = true; - synchronized (sAggregratedPointers) { - sAggregratedPointers.reset(); + synchronized (sAggregatedPointers) { + sAggregatedPointers.reset(); sLastRecognitionPointSize = 0; sLastRecognitionTime = 0; sListener.onStartBatchInput(); @@ -769,10 +769,10 @@ public final class PointerTracker implements PointerTrackerQueue.Element { } private void updateBatchInput(final long eventTime) { - synchronized (sAggregratedPointers) { + synchronized (sAggregatedPointers) { final GestureStroke stroke = mGestureStrokeWithPreviewPoints; - stroke.appendIncrementalBatchPoints(sAggregratedPointers); - final int size = sAggregratedPointers.getPointerSize(); + stroke.appendIncrementalBatchPoints(sAggregatedPointers); + final int size = sAggregatedPointers.getPointerSize(); if (size > sLastRecognitionPointSize && stroke.hasRecognitionTimePast(eventTime, sLastRecognitionTime)) { if (DEBUG_LISTENER) { @@ -780,18 +780,18 @@ public final class PointerTracker implements PointerTrackerQueue.Element { size)); } sTimerProxy.startUpdateBatchInputTimer(this); - sListener.onUpdateBatchInput(sAggregratedPointers); + sListener.onUpdateBatchInput(sAggregatedPointers); // The listener may change the size of the pointers (when auto-committing // for example), so we need to get the size from the pointers again. - sLastRecognitionPointSize = sAggregratedPointers.getPointerSize(); + sLastRecognitionPointSize = sAggregatedPointers.getPointerSize(); sLastRecognitionTime = eventTime; } } } private void mayEndBatchInput(final long eventTime) { - synchronized (sAggregratedPointers) { - mGestureStrokeWithPreviewPoints.appendAllBatchPoints(sAggregratedPointers); + synchronized (sAggregatedPointers) { + mGestureStrokeWithPreviewPoints.appendAllBatchPoints(sAggregatedPointers); if (getActivePointerTrackerCount() == 1) { sInGesture = false; sTimeRecorder.onEndBatchInput(eventTime); @@ -799,9 +799,9 @@ public final class PointerTracker implements PointerTrackerQueue.Element { if (!mIsTrackingForActionDisabled) { if (DEBUG_LISTENER) { Log.d(TAG, String.format("[%d] onEndBatchInput : batchPoints=%d", - mPointerId, sAggregratedPointers.getPointerSize())); + mPointerId, sAggregatedPointers.getPointerSize())); } - sListener.onEndBatchInput(sAggregratedPointers); + sListener.onEndBatchInput(sAggregatedPointers); } } } diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java index f708c2cdd..9f33fcc0a 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java @@ -1811,7 +1811,7 @@ public final class KeyboardTextsSet { // U+055A: "՚" ARMENIAN APOSTROPHE // U+055B: "՛" ARMENIAN EMPHASIS MARK // U+055F: "՟" ARMENIAN ABBREVIATION MARK - /* 59 */ "!fixedColumnOrder!8,!,?,\\,,.,\u058A,\u055C,\u055D,\u055E,:,;,@,\u0559,\u055A,\u055B,\u055F", + /* 59 */ "!fixedColumnOrder!8,!,?,\u0559,\u055A,.,\u055C,\\,,\u055E,:,;,\u055F,\u00AB,\u00BB,\u058A,\u055D,\u055B", /* 60~ */ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, diff --git a/java/src/com/android/inputmethod/latin/InputView.java b/java/src/com/android/inputmethod/latin/InputView.java index 81ccf83d8..76b0912f6 100644 --- a/java/src/com/android/inputmethod/latin/InputView.java +++ b/java/src/com/android/inputmethod/latin/InputView.java @@ -23,87 +23,203 @@ import android.view.MotionEvent; import android.view.View; import android.widget.LinearLayout; -public final class InputView extends LinearLayout { - private View mSuggestionStripView; - private View mKeyboardView; - private int mKeyboardTopPadding; +import com.android.inputmethod.keyboard.MainKeyboardView; +import com.android.inputmethod.latin.suggestions.MoreSuggestionsView; +import com.android.inputmethod.latin.suggestions.SuggestionStripView; - private boolean mIsForwardingEvent; +public final class InputView extends LinearLayout { private final Rect mInputViewRect = new Rect(); - private final Rect mEventForwardingRect = new Rect(); - private final Rect mEventReceivingRect = new Rect(); + private KeyboardTopPaddingForwarder mKeyboardTopPaddingForwarder; + private MoreSuggestionsViewCanceler mMoreSuggestionsViewCanceler; public InputView(final Context context, final AttributeSet attrs) { super(context, attrs, 0); } - public void setKeyboardGeometry(final int keyboardTopPadding) { - mKeyboardTopPadding = keyboardTopPadding; - } - @Override protected void onFinishInflate() { - mSuggestionStripView = findViewById(R.id.suggestion_strip_view); - mKeyboardView = findViewById(R.id.keyboard_view); + final SuggestionStripView suggestionStripView = + (SuggestionStripView)findViewById(R.id.suggestion_strip_view); + final MainKeyboardView mainKeyboardView = + (MainKeyboardView)findViewById(R.id.keyboard_view); + mKeyboardTopPaddingForwarder = new KeyboardTopPaddingForwarder( + mainKeyboardView, suggestionStripView); + mMoreSuggestionsViewCanceler = new MoreSuggestionsViewCanceler( + mainKeyboardView, suggestionStripView); + } + + public void setKeyboardTopPadding(final int keyboardTopPadding) { + mKeyboardTopPaddingForwarder.setKeyboardTopPadding(keyboardTopPadding); } @Override public boolean dispatchTouchEvent(final MotionEvent me) { - if (mSuggestionStripView.getVisibility() != VISIBLE - || mKeyboardView.getVisibility() != VISIBLE) { - return super.dispatchTouchEvent(me); - } - - // The touch events that hit the top padding of keyboard should be forwarded to - // {@link SuggestionStripView}. final Rect rect = mInputViewRect; - this.getGlobalVisibleRect(rect); + getGlobalVisibleRect(rect); final int x = (int)me.getX() + rect.left; final int y = (int)me.getY() + rect.top; - final Rect forwardingRect = mEventForwardingRect; - mKeyboardView.getGlobalVisibleRect(forwardingRect); - if (!mIsForwardingEvent && !forwardingRect.contains(x, y)) { - return super.dispatchTouchEvent(me); + // The touch events that hit the top padding of keyboard should be + // forwarded to {@link SuggestionStripView}. + if (mKeyboardTopPaddingForwarder.dispatchTouchEvent(x, y, me)) { + return true; + } + // To cancel {@link MoreSuggestionsView}, we should intercept a touch event to + // {@link MainKeyboardView} and dismiss the {@link MoreSuggestionsView}. + if (mMoreSuggestionsViewCanceler.dispatchTouchEvent(x, y, me)) { + return true; + } + return super.dispatchTouchEvent(me); + } + + /** + * This class forwards series of {@link MotionEvent}s from <code>Forwarder</code> view to + * <code>Receiver</code> view. + * + * @param <Sender> a {@link View} that may send a {@link MotionEvent} to <Receiver>. + * @param <Receiver> a {@link View} that receives forwarded {@link MotionEvent} from + * <Forwarder>. + */ + private static abstract class MotionEventForwarder<Sender extends View, Receiver extends View> { + protected final Sender mSenderView; + protected final Receiver mReceiverView; + + private boolean mIsForwardingEvent; + protected final Rect mEventSendingRect = new Rect(); + protected final Rect mEventReceivingRect = new Rect(); + + public MotionEventForwarder(final Sender senderView, final Receiver receiverView) { + mSenderView = senderView; + mReceiverView = receiverView; } - final int forwardingLimitY = forwardingRect.top + mKeyboardTopPadding; - boolean sendToTarget = false; + // Return true if a touch event of global coordinate x, y needs to be forwarded. + protected abstract boolean needsToForward(final int x, final int y); - switch (me.getAction()) { - case MotionEvent.ACTION_DOWN: - if (y < forwardingLimitY) { - // This down event and further move and up events should be forwarded to the target. - mIsForwardingEvent = true; - sendToTarget = true; + // Translate global x-coordinate to <code>Receiver</code> local coordinate. + protected int translateX(final int x) { + return x - mEventReceivingRect.left; + } + + // Translate global y-coordinate to <code>Receiver</code> local coordinate. + protected int translateY(final int y) { + return y - mEventReceivingRect.top; + } + + // Callback when a {@link MotionEvent} is forwarded. + protected void onForwardingEvent(final MotionEvent me) {} + + // Dispatches a {@link MotioneEvent} to <code>Receiver</code> if needed and returns true. + // Otherwise returns false. + public boolean dispatchTouchEvent(final int x, final int y, final MotionEvent me) { + // Forwards a {link MotionEvent} only if both <code>Sender</code> and + // <code>Receiver</code> are visible. + if (mSenderView.getVisibility() != View.VISIBLE || + mReceiverView.getVisibility() != View.VISIBLE) { + return false; + } + final Rect sendingRect = mEventSendingRect; + mSenderView.getGlobalVisibleRect(sendingRect); + if (!mIsForwardingEvent && !sendingRect.contains(x, y)) { + return false; } - break; - case MotionEvent.ACTION_MOVE: - sendToTarget = mIsForwardingEvent; - break; - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_CANCEL: - sendToTarget = mIsForwardingEvent; - mIsForwardingEvent = false; - break; + + boolean shouldForwardToReceiver = false; + + switch (me.getActionMasked()) { + case MotionEvent.ACTION_DOWN: + // If the down event happens in the forwarding area, successive {@link MotionEvent}s + // should be forwarded. + if (needsToForward(x, y)) { + mIsForwardingEvent = true; + shouldForwardToReceiver = true; + } + break; + case MotionEvent.ACTION_MOVE: + shouldForwardToReceiver = mIsForwardingEvent; + break; + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_CANCEL: + shouldForwardToReceiver = mIsForwardingEvent; + mIsForwardingEvent = false; + break; + } + + if (!shouldForwardToReceiver) { + return false; + } + + final Rect receivingRect = mEventReceivingRect; + mReceiverView.getGlobalVisibleRect(receivingRect); + // Translate global coordinates to <code>Receiver</code> local coordinates. + me.setLocation(translateX(x), translateY(y)); + mReceiverView.dispatchTouchEvent(me); + onForwardingEvent(me); + return true; } + } + + /** + * This class forwards {@link MotionEvent}s happened in the top padding of + * {@link MainKeyboardView} to {@link SuggestionStripView}. + */ + private static class KeyboardTopPaddingForwarder + extends MotionEventForwarder<MainKeyboardView, SuggestionStripView> { + private int mKeyboardTopPadding; - if (!sendToTarget) { - return super.dispatchTouchEvent(me); + public KeyboardTopPaddingForwarder(final MainKeyboardView mainKeyboardView, + final SuggestionStripView suggestionStripView) { + super(mainKeyboardView, suggestionStripView); } - final Rect receivingRect = mEventReceivingRect; - mSuggestionStripView.getGlobalVisibleRect(receivingRect); - final int translatedX = x - receivingRect.left; - final int translatedY; - if (y < forwardingLimitY) { - // The forwarded event should have coordinates that are inside of the target. - translatedY = Math.min(y - receivingRect.top, receivingRect.height() - 1); - } else { - translatedY = y - receivingRect.top; + public void setKeyboardTopPadding(final int keyboardTopPadding) { + mKeyboardTopPadding = keyboardTopPadding; + } + + private boolean isInKeyboardTopPadding(final int y) { + return y < mEventSendingRect.top + mKeyboardTopPadding; + } + + @Override + protected boolean needsToForward(final int x, final int y) { + return isInKeyboardTopPadding(y); + } + + @Override + protected int translateY(final int y) { + final int translatedY = super.translateY(y); + if (isInKeyboardTopPadding(y)) { + // The forwarded event should have coordinates that are inside of + // the target. + return Math.min(translatedY, mEventReceivingRect.height() - 1); + } + return translatedY; + } + } + + /** + * This class forwards {@link MotionEvent}s happened in the {@link MainKeyboardView} to + * {@link SuggestionStripView} when the {@link MoreSuggestionsView} is showing. + * {@link SuggestionStripView} dismisses {@link MoreSuggestionsView} when it receives those + * events. + */ + private static class MoreSuggestionsViewCanceler + extends MotionEventForwarder<MainKeyboardView, SuggestionStripView> { + public MoreSuggestionsViewCanceler(final MainKeyboardView mainKeyboardView, + final SuggestionStripView suggestionStripView) { + super(mainKeyboardView, suggestionStripView); + } + + @Override + protected boolean needsToForward(final int x, final int y) { + return mReceiverView.isShowingMoreSuggestionPanel() && mEventSendingRect.contains(x, y); + } + + @Override + protected void onForwardingEvent(final MotionEvent me) { + if (me.getActionMasked() == MotionEvent.ACTION_DOWN) { + mReceiverView.dismissMoreSuggestionsPanel(); + } } - me.setLocation(translatedX, translatedY); - mSuggestionStripView.dispatchTouchEvent(me); - return true; } } diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 8b466559c..72d5435a8 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -1469,7 +1469,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen ResearchLogger.latinIME_maybeDoubleSpacePeriod(textToInsert, false /* isBatchMode */); } - mWordComposer.doubleSpacePeriod(); + mWordComposer.discardPreviousWordForSuggestion(); mKeyboardSwitcher.updateShiftState(); return true; } @@ -2565,29 +2565,23 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen final SettingsValues currentSettings = mSettings.getCurrent(); final int[] additionalFeaturesOptions = currentSettings.mAdditionalFeaturesSettingValues; - final String previousWord; - if (mWordComposer.isComposingWord() || mWordComposer.isBatchMode()) { - previousWord = mWordComposer.getPreviousWord(); - } else { - // Not composing: this is for prediction. - // TODO: read the previous word earlier for prediction, like we are doing for - // normal suggestions. - previousWord = getNthPreviousWordForSuggestion(currentSettings, 1 /* nthPreviousWord*/); - } if (DEBUG) { - // TODO: this is for checking consistency with older versions. Remove this when - // we are confident this is stable. - // We're checking the previous word in the text field against the memorized previous - // word. If we are composing a word we should have the second word before the cursor - // memorized, otherwise we should have the first. - final String rereadPrevWord = getNthPreviousWordForSuggestion(currentSettings, - mWordComposer.isComposingWord() ? 2 : 1); - if (!TextUtils.equals(previousWord, rereadPrevWord)) { - throw new RuntimeException("Unexpected previous word: " - + previousWord + " <> " + rereadPrevWord); - } - } - suggest.getSuggestedWords(mWordComposer, mWordComposer.getPreviousWord(), + if (mWordComposer.isComposingWord() || mWordComposer.isBatchMode()) { + final String previousWord = mWordComposer.getPreviousWordForSuggestion(); + // TODO: this is for checking consistency with older versions. Remove this when + // we are confident this is stable. + // We're checking the previous word in the text field against the memorized previous + // word. If we are composing a word we should have the second word before the cursor + // memorized, otherwise we should have the first. + final String rereadPrevWord = getNthPreviousWordForSuggestion(currentSettings, + mWordComposer.isComposingWord() ? 2 : 1); + if (!TextUtils.equals(previousWord, rereadPrevWord)) { + throw new RuntimeException("Unexpected previous word: " + + previousWord + " <> " + rereadPrevWord); + } + } + } + suggest.getSuggestedWords(mWordComposer, mWordComposer.getPreviousWordForSuggestion(), keyboard.getProximityInfo(), currentSettings.mBlockPotentiallyOffensive, currentSettings.mCorrectionEnabled, additionalFeaturesOptions, sessionId, sequenceNumber, callback); @@ -2830,6 +2824,19 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // strings. mLastComposedWord = mWordComposer.commitWord(commitType, chosenWord, separatorString, prevWord); + final boolean shouldDiscardPreviousWordForSuggestion; + if (0 == StringUtils.codePointCount(separatorString)) { + // Separator is 0-length. Discard the word only if the current language has spaces. + shouldDiscardPreviousWordForSuggestion = + mSettings.getCurrent().mCurrentLanguageHasSpaces; + } else { + // Otherwise, we discard if the separator contains any non-whitespace. + shouldDiscardPreviousWordForSuggestion = + !StringUtils.containsOnlyWhitespace(separatorString); + } + if (shouldDiscardPreviousWordForSuggestion) { + mWordComposer.discardPreviousWordForSuggestion(); + } } private void setPunctuationSuggestions() { diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java index 5ecfc67b2..7da97e57a 100644 --- a/java/src/com/android/inputmethod/latin/WordComposer.java +++ b/java/src/com/android/inputmethod/latin/WordComposer.java @@ -50,8 +50,9 @@ public final class WordComposer { private final StringBuilder mTypedWord; // The previous word (before the composing word). Used as context for suggestions. May be null // after resetting and before starting a new composing word, or when there is no context like - // at the start of text for example. - private String mPreviousWord; + // at the start of text for example. It can also be set to null externally when the user + // enters a separator that does not let bigrams across, like a period or a comma. + private String mPreviousWordForSuggestion; private String mAutoCorrection; private boolean mIsResumed; private boolean mIsBatchMode; @@ -89,7 +90,7 @@ public final class WordComposer { mIsBatchMode = false; mCursorPositionWithinWord = 0; mRejectedBatchModeSuggestion = null; - mPreviousWord = null; + mPreviousWordForSuggestion = null; refreshSize(); } @@ -106,7 +107,7 @@ public final class WordComposer { mIsBatchMode = source.mIsBatchMode; mCursorPositionWithinWord = source.mCursorPositionWithinWord; mRejectedBatchModeSuggestion = source.mRejectedBatchModeSuggestion; - mPreviousWord = source.mPreviousWord; + mPreviousWordForSuggestion = source.mPreviousWordForSuggestion; refreshSize(); } @@ -124,7 +125,7 @@ public final class WordComposer { mIsBatchMode = false; mCursorPositionWithinWord = 0; mRejectedBatchModeSuggestion = null; - mPreviousWord = null; + mPreviousWordForSuggestion = null; refreshSize(); } @@ -305,7 +306,7 @@ public final class WordComposer { addKeyInfo(codePoint, keyboard); } mIsResumed = true; - mPreviousWord = previousWord; + mPreviousWordForSuggestion = previousWord; } /** @@ -356,8 +357,8 @@ public final class WordComposer { return mTypedWord.toString(); } - public String getPreviousWord() { - return mPreviousWord; + public String getPreviousWordForSuggestion() { + return mPreviousWordForSuggestion; } /** @@ -419,7 +420,7 @@ public final class WordComposer { public void setCapitalizedModeAndPreviousWordAtStartComposingTime(final int mode, final String previousWord) { mCapitalizedMode = mode; - mPreviousWord = previousWord; + mPreviousWordForSuggestion = previousWord; } /** @@ -471,12 +472,7 @@ public final class WordComposer { mCapsCount = 0; mDigitsCount = 0; mIsBatchMode = false; - final boolean isWhitespace = 1 == StringUtils.codePointCount(separatorString) - && Character.isWhitespace(separatorString.codePointAt(0)); - // If not whitespace, we don't use the previous word for suggestion. This is consistent - // with how we get the previous word for suggestion: see RichInputConnection#spaceRegex and - // LatinIME#getNthPreviousWordForSuggestion. - mPreviousWord = isWhitespace ? mTypedWord.toString() : null; + mPreviousWordForSuggestion = mTypedWord.toString(); mTypedWord.setLength(0); mCodePointSize = 0; mTrailingSingleQuotesCount = 0; @@ -490,11 +486,11 @@ public final class WordComposer { return lastComposedWord; } - public void doubleSpacePeriod() { - // When a period was entered with a double space, the separator we got has been - // changed by a period (see #commitWord). We should not use the previous word for - // suggestion. - mPreviousWord = null; + // Call this when the recorded previous word should be discarded. This is typically called + // when the user inputs a separator that's not whitespace (including the case of the + // double-space-to-period feature). + public void discardPreviousWordForSuggestion() { + mPreviousWordForSuggestion = null; } public void resumeSuggestionOnLastComposedWord(final LastComposedWord lastComposedWord, @@ -509,7 +505,7 @@ public final class WordComposer { mCursorPositionWithinWord = mCodePointSize; mRejectedBatchModeSuggestion = null; mIsResumed = true; - mPreviousWord = previousWord; + mPreviousWordForSuggestion = previousWord; } public boolean isBatchMode() { diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java index 4d1abfa3e..2dbb5eb93 100644 --- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java +++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java @@ -439,7 +439,7 @@ public final class BinaryDictDecoderUtils { final FormatOptions options) { dictDecoder.setPosition(headerSize); final int count = dictDecoder.readPtNodeCount(); - int groupPos = headerSize + BinaryDictIOUtils.getPtNodeCountSize(count); + int groupPos = dictDecoder.getPosition(); final StringBuilder builder = new StringBuilder(); WeightedString result = null; @@ -501,9 +501,9 @@ public final class BinaryDictDecoderUtils { do { // Scan the linked-list node. final int nodeArrayHeadPos = dictDecoder.getPosition(); final int count = dictDecoder.readPtNodeCount(); - int groupOffsetPos = nodeArrayHeadPos + BinaryDictIOUtils.getPtNodeCountSize(count); + int groupPos = dictDecoder.getPosition(); for (int i = count; i > 0; --i) { // Scan the array of PtNode. - PtNodeInfo info = dictDecoder.readPtNode(groupOffsetPos, options); + PtNodeInfo info = dictDecoder.readPtNode(groupPos, options); if (BinaryDictIOUtils.isMovedPtNode(info.mFlags, options)) continue; ArrayList<WeightedString> shortcutTargets = info.mShortcutTargets; ArrayList<WeightedString> bigrams = null; @@ -539,7 +539,7 @@ public final class BinaryDictDecoderUtils { 0 != (info.mFlags & FormatSpec.FLAG_IS_NOT_A_WORD), 0 != (info.mFlags & FormatSpec.FLAG_IS_BLACKLISTED))); } - groupOffsetPos = info.mEndAddress; + groupPos = info.mEndAddress; } // reach the end of the array. diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java index 7a7d45241..07ba777c7 100644 --- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java +++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java @@ -85,7 +85,7 @@ public final class BinaryDictIOUtils { if (p.mNumOfPtNode == Position.NOT_READ_PTNODE_COUNT) { p.mNumOfPtNode = dictDecoder.readPtNodeCount(); - p.mAddress += getPtNodeCountSize(p.mNumOfPtNode); + p.mAddress = dictDecoder.getPosition(); p.mPosition = 0; } if (p.mNumOfPtNode == 0) { diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java index af54805f7..437fa942b 100644 --- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java +++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java @@ -188,7 +188,7 @@ public final class FormatSpec { // us to change the format during development while having testing devices remove // older files with each upgrade, while still having a readable versioning scheme. public static final int VERSION2 = 2; - public static final int VERSION4 = 400; + public static final int VERSION4 = 401; static final int MINIMUM_SUPPORTED_VERSION = VERSION2; static final int MAXIMUM_SUPPORTED_VERSION = VERSION4; diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java index 714c3a97a..94f145813 100644 --- a/java/src/com/android/inputmethod/latin/settings/Settings.java +++ b/java/src/com/android/inputmethod/latin/settings/Settings.java @@ -53,6 +53,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang public static final String PREF_MISC_SETTINGS = "misc_settings"; public static final String PREF_ADVANCED_SETTINGS = "pref_advanced_settings"; public static final String PREF_KEY_USE_CONTACTS_DICT = "pref_key_use_contacts_dict"; + public static final String PREF_KEY_USE_PERSONALIZED_DICTS = "pref_key_use_personalized_dicts"; public static final String PREF_KEY_USE_DOUBLE_SPACE_PERIOD = "pref_key_use_double_space_period"; public static final String PREF_BLOCK_POTENTIALLY_OFFENSIVE = diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java index 06406c19b..d98e547fc 100644 --- a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java +++ b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java @@ -29,11 +29,9 @@ import com.android.inputmethod.latin.Dictionary; import com.android.inputmethod.latin.InputAttributes; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.RichInputMethodManager; -import com.android.inputmethod.latin.SubtypeSwitcher; import com.android.inputmethod.latin.SuggestedWords; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.utils.CollectionUtils; -import com.android.inputmethod.latin.utils.InputTypeUtils; import com.android.inputmethod.latin.utils.StringUtils; import java.util.ArrayList; @@ -71,6 +69,7 @@ public final class SettingsValues { public final boolean mIncludesOtherImesInLanguageSwitchList; public final boolean mShowsLanguageSwitchKey; public final boolean mUseContactsDict; + public final boolean mUsePersonalizedDicts; public final boolean mUseDoubleSpacePeriod; public final boolean mBlockPotentiallyOffensive; // Use bigrams to predict the next word when there is no input for it yet @@ -148,6 +147,7 @@ public final class SettingsValues { Settings.PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST, false); mShowsLanguageSwitchKey = Settings.readShowsLanguageSwitchKey(prefs); mUseContactsDict = prefs.getBoolean(Settings.PREF_KEY_USE_CONTACTS_DICT, true); + mUsePersonalizedDicts = prefs.getBoolean(Settings.PREF_KEY_USE_PERSONALIZED_DICTS, true); mUseDoubleSpacePeriod = prefs.getBoolean(Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD, true); mBlockPotentiallyOffensive = Settings.readBlockPotentiallyOffensive(prefs, res); mAutoCorrectEnabled = Settings.readAutoCorrectEnabled(autoCorrectionThresholdRawValue, res); @@ -206,6 +206,7 @@ public final class SettingsValues { mIncludesOtherImesInLanguageSwitchList = false; mShowsLanguageSwitchKey = true; mUseContactsDict = true; + mUsePersonalizedDicts = true; mUseDoubleSpacePeriod = true; mBlockPotentiallyOffensive = true; mAutoCorrectEnabled = true; diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java index aa87affa2..073148a50 100644 --- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java +++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java @@ -162,19 +162,19 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick mSuggestionsStrip.removeAllViews(); removeAllViews(); addView(mSuggestionsStrip); - mMoreSuggestionsView.dismissMoreKeysPanel(); + dismissMoreSuggestionsPanel(); } private final MoreSuggestionsListener mMoreSuggestionsListener = new MoreSuggestionsListener() { @Override public void onSuggestionSelected(final int index, final SuggestedWordInfo wordInfo) { mListener.pickSuggestionManually(index, wordInfo); - mMoreSuggestionsView.dismissMoreKeysPanel(); + dismissMoreSuggestionsPanel(); } @Override public void onCancelInput() { - mMoreSuggestionsView.dismissMoreKeysPanel(); + dismissMoreSuggestionsPanel(); } }; @@ -192,10 +192,18 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick @Override public void onCancelMoreKeysPanel(final MoreKeysPanel panel) { - mMoreSuggestionsView.dismissMoreKeysPanel(); + dismissMoreSuggestionsPanel(); } }; + public boolean isShowingMoreSuggestionPanel() { + return mMoreSuggestionsView.isShowingInParent(); + } + + public void dismissMoreSuggestionsPanel() { + mMoreSuggestionsView.dismissMoreKeysPanel(); + } + @Override public boolean onLongClick(final View view) { AudioAndHapticFeedbackManager.getInstance().performHapticAndAudioFeedback( @@ -322,6 +330,6 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); - mMoreSuggestionsView.dismissMoreKeysPanel(); + dismissMoreSuggestionsPanel(); } } diff --git a/java/src/com/android/inputmethod/latin/utils/StringUtils.java b/java/src/com/android/inputmethod/latin/utils/StringUtils.java index df420417d..85f44541e 100644 --- a/java/src/com/android/inputmethod/latin/utils/StringUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/StringUtils.java @@ -250,6 +250,24 @@ public final class StringUtils { return true; } + /** + * Returns true if all code points in text are whitespace, false otherwise. Empty is true. + */ + // Interestingly enough, U+00A0 NO-BREAK SPACE and U+200B ZERO-WIDTH SPACE are not considered + // whitespace, while EN SPACE, EM SPACE and IDEOGRAPHIC SPACES are. + public static boolean containsOnlyWhitespace(final String text) { + final int length = text.length(); + int i = 0; + while (i < length) { + final int codePoint = text.codePointAt(i); + if (!Character.isWhitespace(codePoint)) { + return false; + } + i += Character.charCount(codePoint); + } + return true; + } + @UsedForTesting public static boolean looksValidForDictionaryInsertion(final CharSequence text, final SettingsValues settings) { |