Remove Tutorial class and unused debug feature
This change also cleanups compiler warnings. Bug: 2897373 Change-Id: If972cf45c1eb40436adbddbf71969e5409f4c9c5main
parent
20cdb37bd0
commit
e26ef1bccd
|
@ -47,6 +47,7 @@ public class KeyStyles {
|
|||
|
||||
public static class EmptyKeyStyle implements KeyStyle {
|
||||
private EmptyKeyStyle() {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -18,6 +18,7 @@ package com.android.inputmethod.keyboard;
|
|||
|
||||
import com.android.inputmethod.latin.R;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import android.content.res.Resources;
|
||||
|
@ -142,8 +143,8 @@ public class KeyboardParser {
|
|||
public void parseKeyboard(XmlResourceParser parser)
|
||||
throws XmlPullParserException, IOException {
|
||||
int event;
|
||||
while ((event = parser.next()) != XmlResourceParser.END_DOCUMENT) {
|
||||
if (event == XmlResourceParser.START_TAG) {
|
||||
while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
|
||||
if (event == XmlPullParser.START_TAG) {
|
||||
final String tag = parser.getName();
|
||||
if (DEBUG_TAG) debugStartTag("parseKeyboard", tag, false);
|
||||
if (TAG_KEYBOARD.equals(tag)) {
|
||||
|
@ -186,8 +187,8 @@ public class KeyboardParser {
|
|||
private void parseKeyboardContent(XmlResourceParser parser, List<Key> keys)
|
||||
throws XmlPullParserException, IOException {
|
||||
int event;
|
||||
while ((event = parser.next()) != XmlResourceParser.END_DOCUMENT) {
|
||||
if (event == XmlResourceParser.START_TAG) {
|
||||
while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
|
||||
if (event == XmlPullParser.START_TAG) {
|
||||
final String tag = parser.getName();
|
||||
if (DEBUG_TAG) debugStartTag("parseKeyboardContent", tag, keys == null);
|
||||
if (TAG_ROW.equals(tag)) {
|
||||
|
@ -204,7 +205,7 @@ public class KeyboardParser {
|
|||
} else {
|
||||
throw new IllegalStartTag(parser, TAG_ROW);
|
||||
}
|
||||
} else if (event == XmlResourceParser.END_TAG) {
|
||||
} else if (event == XmlPullParser.END_TAG) {
|
||||
final String tag = parser.getName();
|
||||
if (DEBUG_TAG) debugEndTag("parseKeyboardContent", tag, keys == null);
|
||||
if (TAG_KEYBOARD.equals(tag)) {
|
||||
|
@ -226,8 +227,8 @@ public class KeyboardParser {
|
|||
private void parseRowContent(XmlResourceParser parser, Row row, List<Key> keys)
|
||||
throws XmlPullParserException, IOException {
|
||||
int event;
|
||||
while ((event = parser.next()) != XmlResourceParser.END_DOCUMENT) {
|
||||
if (event == XmlResourceParser.START_TAG) {
|
||||
while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
|
||||
if (event == XmlPullParser.START_TAG) {
|
||||
final String tag = parser.getName();
|
||||
if (DEBUG_TAG) debugStartTag("parseRowContent", tag, keys == null);
|
||||
if (TAG_KEY.equals(tag)) {
|
||||
|
@ -243,7 +244,7 @@ public class KeyboardParser {
|
|||
} else {
|
||||
throw new IllegalStartTag(parser, TAG_KEY);
|
||||
}
|
||||
} else if (event == XmlResourceParser.END_TAG) {
|
||||
} else if (event == XmlPullParser.END_TAG) {
|
||||
final String tag = parser.getName();
|
||||
if (DEBUG_TAG) debugEndTag("parseRowContent", tag, keys == null);
|
||||
if (TAG_ROW.equals(tag)) {
|
||||
|
@ -327,8 +328,8 @@ public class KeyboardParser {
|
|||
private void parseMerge(XmlResourceParser parser, Row row, List<Key> keys)
|
||||
throws XmlPullParserException, IOException {
|
||||
int event;
|
||||
while ((event = parser.next()) != XmlResourceParser.END_DOCUMENT) {
|
||||
if (event == XmlResourceParser.START_TAG) {
|
||||
while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
|
||||
if (event == XmlPullParser.START_TAG) {
|
||||
final String tag = parser.getName();
|
||||
if (DEBUG_TAG) debugStartTag("parseMerge", tag, keys == null);
|
||||
if (TAG_MERGE.equals(tag)) {
|
||||
|
@ -361,8 +362,8 @@ public class KeyboardParser {
|
|||
boolean selected = false;
|
||||
int event;
|
||||
if (DEBUG_TAG) Log.d(TAG, "parseSwitchInternal: id=" + mKeyboard.mId);
|
||||
while ((event = parser.next()) != XmlResourceParser.END_DOCUMENT) {
|
||||
if (event == XmlResourceParser.START_TAG) {
|
||||
while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
|
||||
if (event == XmlPullParser.START_TAG) {
|
||||
final String tag = parser.getName();
|
||||
if (DEBUG_TAG) debugStartTag("parseSwitchInternal", tag, keys == null);
|
||||
if (TAG_CASE.equals(tag)) {
|
||||
|
@ -372,7 +373,7 @@ public class KeyboardParser {
|
|||
} else {
|
||||
throw new IllegalStartTag(parser, TAG_KEY);
|
||||
}
|
||||
} else if (event == XmlResourceParser.END_TAG) {
|
||||
} else if (event == XmlPullParser.END_TAG) {
|
||||
final String tag = parser.getName();
|
||||
if (DEBUG_TAG) debugEndTag("parseRowContent", tag, keys == null);
|
||||
if (TAG_SWITCH.equals(tag)) {
|
||||
|
@ -469,8 +470,7 @@ public class KeyboardParser {
|
|||
return true;
|
||||
}
|
||||
|
||||
private void parseKeyStyle(XmlResourceParser parser, List<Key> keys)
|
||||
throws XmlPullParserException, IOException {
|
||||
private void parseKeyStyle(XmlResourceParser parser, List<Key> keys) {
|
||||
TypedArray a = mResources.obtainAttributes(Xml.asAttributeSet(parser),
|
||||
R.styleable.Keyboard_KeyStyle);
|
||||
TypedArray keyAttrs = mResources.obtainAttributes(Xml.asAttributeSet(parser),
|
||||
|
@ -489,7 +489,7 @@ public class KeyboardParser {
|
|||
|
||||
private static void checkEndTag(String tag, XmlResourceParser parser)
|
||||
throws XmlPullParserException, IOException {
|
||||
if (parser.next() == XmlResourceParser.END_TAG && tag.equals(parser.getName()))
|
||||
if (parser.next() == XmlPullParser.END_TAG && tag.equals(parser.getName()))
|
||||
return;
|
||||
throw new NonEmptyTag(tag, parser);
|
||||
}
|
||||
|
|
|
@ -100,6 +100,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
|||
}
|
||||
|
||||
private KeyboardSwitcher() {
|
||||
// Intentional empty constructor for singleton.
|
||||
}
|
||||
|
||||
public static void init(LatinIME ims, SharedPreferences prefs) {
|
||||
|
@ -554,12 +555,13 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
|||
}
|
||||
|
||||
private void createInputViewInternal(int newLayout, boolean forceReset) {
|
||||
if (mLayoutId != newLayout || mInputView == null || forceReset) {
|
||||
int layoutId = newLayout;
|
||||
if (mLayoutId != layoutId || mInputView == null || forceReset) {
|
||||
if (mInputView != null) {
|
||||
mInputView.closing();
|
||||
}
|
||||
if (THEMES.length <= newLayout) {
|
||||
newLayout = Integer.valueOf(DEFAULT_LAYOUT_ID);
|
||||
if (THEMES.length <= layoutId) {
|
||||
layoutId = Integer.valueOf(DEFAULT_LAYOUT_ID);
|
||||
}
|
||||
|
||||
Utils.GCUtils.getInstance().reset();
|
||||
|
@ -567,20 +569,20 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
|||
for (int i = 0; i < Utils.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) {
|
||||
try {
|
||||
mInputView = (LatinKeyboardView) mInputMethodService.getLayoutInflater(
|
||||
).inflate(THEMES[newLayout], null);
|
||||
).inflate(THEMES[layoutId], null);
|
||||
tryGC = false;
|
||||
} catch (OutOfMemoryError e) {
|
||||
Log.w(TAG, "load keyboard failed: " + e);
|
||||
tryGC = Utils.GCUtils.getInstance().tryGCOrWait(
|
||||
mLayoutId + "," + newLayout, e);
|
||||
mLayoutId + "," + layoutId, e);
|
||||
} catch (InflateException e) {
|
||||
Log.w(TAG, "load keyboard failed: " + e);
|
||||
tryGC = Utils.GCUtils.getInstance().tryGCOrWait(
|
||||
mLayoutId + "," + newLayout, e);
|
||||
mLayoutId + "," + layoutId, e);
|
||||
}
|
||||
}
|
||||
mInputView.setOnKeyboardActionListener(mInputMethodService);
|
||||
mLayoutId = newLayout;
|
||||
mLayoutId = layoutId;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -289,7 +289,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
|
|||
cancelPopupPreview();
|
||||
cancelDismissPreview();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public KeyboardView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, R.attr.keyboardViewStyle);
|
||||
|
@ -587,7 +587,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
|
|||
protected CharSequence adjustCase(CharSequence label) {
|
||||
if (mKeyboard.isShiftedOrShiftLocked() && label != null && label.length() < 3
|
||||
&& Character.isLowerCase(label.charAt(0))) {
|
||||
label = label.toString().toUpperCase();
|
||||
return label.toString().toUpperCase();
|
||||
}
|
||||
return label;
|
||||
}
|
||||
|
@ -1089,7 +1089,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
|
|||
mKeyboardActionListener.onKey(Keyboard.CODE_CAPSLOCK, null, 0, 0);
|
||||
}
|
||||
|
||||
private void onDoubleTapShiftKey(PointerTracker tracker) {
|
||||
private void onDoubleTapShiftKey(@SuppressWarnings("unused") PointerTracker tracker) {
|
||||
// When shift key is double tapped, the first tap is correctly processed as usual tap. And
|
||||
// the second tap is treated as this double tap event, so that we need not mark tracker
|
||||
// calling setAlreadyProcessed() nor remove the tracker from mPointerQueueueue.
|
||||
|
@ -1126,15 +1126,19 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
|
|||
|
||||
@Override
|
||||
public void swipeLeft() {
|
||||
// Nothing to do.
|
||||
}
|
||||
@Override
|
||||
public void swipeRight() {
|
||||
// Nothing to do.
|
||||
}
|
||||
@Override
|
||||
public void swipeUp() {
|
||||
// Nothing to do.
|
||||
}
|
||||
@Override
|
||||
public void swipeDown() {
|
||||
// Nothing to do.
|
||||
}
|
||||
@Override
|
||||
public void onPress(int primaryCode) {
|
||||
|
|
|
@ -280,7 +280,9 @@ public class LatinKeyboard extends Keyboard {
|
|||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unused") // SubtypeSwitcher.USE_SPACEBAR_LANGUAGE_SWITCHER is constant
|
||||
public boolean isInside(Key key, int x, int y) {
|
||||
public boolean isInside(Key key, int pointX, int pointY) {
|
||||
int x = pointX;
|
||||
int y = pointY;
|
||||
final int code = key.mCodes[0];
|
||||
if (code == CODE_SHIFT || code == CODE_DELETE) {
|
||||
y -= key.mHeight / 10;
|
||||
|
|
|
@ -21,16 +21,10 @@ import com.android.inputmethod.voice.VoiceIMEConnector;
|
|||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.SystemClock;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
// TODO: We should remove this class
|
||||
public class LatinKeyboardView extends KeyboardView {
|
||||
|
||||
|
@ -45,6 +39,8 @@ public class LatinKeyboardView extends KeyboardView {
|
|||
private int mJumpThresholdSquare = Integer.MAX_VALUE;
|
||||
/** The y coordinate of the last row */
|
||||
private int mLastRowY;
|
||||
private int mLastX;
|
||||
private int mLastY;
|
||||
|
||||
public LatinKeyboardView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
|
@ -73,7 +69,6 @@ public class LatinKeyboardView extends KeyboardView {
|
|||
mJumpThresholdSquare *= mJumpThresholdSquare;
|
||||
// Assuming there are 4 rows, this is the coordinate of the last row
|
||||
mLastRowY = (k.getHeight() * 3) / 4;
|
||||
setKeyboardLocal(k);
|
||||
}
|
||||
|
||||
public LatinKeyboard getLatinKeyboard() {
|
||||
|
@ -112,7 +107,7 @@ public class LatinKeyboardView extends KeyboardView {
|
|||
&& keyboard.isShiftedOrShiftLocked()
|
||||
&& !TextUtils.isEmpty(label) && label.length() < 3
|
||||
&& Character.isLowerCase(label.charAt(0))) {
|
||||
label = label.toString().toUpperCase();
|
||||
return label.toString().toUpperCase();
|
||||
}
|
||||
return label;
|
||||
}
|
||||
|
@ -197,11 +192,6 @@ public class LatinKeyboardView extends KeyboardView {
|
|||
@Override
|
||||
public boolean onTouchEvent(MotionEvent me) {
|
||||
LatinKeyboard keyboard = getLatinKeyboard();
|
||||
if (DEBUG_LINE) {
|
||||
mLastX = (int) me.getX();
|
||||
mLastY = (int) me.getY();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
// If there was a sudden jump, return without processing the actual motion event.
|
||||
if (handleSuddenJump(me))
|
||||
|
@ -228,106 +218,6 @@ public class LatinKeyboardView extends KeyboardView {
|
|||
return super.onTouchEvent(me);
|
||||
}
|
||||
|
||||
/**************************** INSTRUMENTATION *******************************/
|
||||
|
||||
public static final boolean DEBUG_AUTO_PLAY = false;
|
||||
public static final boolean DEBUG_LINE = false;
|
||||
private static final int MSG_TOUCH_DOWN = 1;
|
||||
private static final int MSG_TOUCH_UP = 2;
|
||||
|
||||
Handler mHandler2;
|
||||
|
||||
private String mStringToPlay;
|
||||
private int mStringIndex;
|
||||
private boolean mDownDelivered;
|
||||
private Key[] mAsciiKeys = new Key[256];
|
||||
private boolean mPlaying;
|
||||
private int mLastX;
|
||||
private int mLastY;
|
||||
private Paint mPaint;
|
||||
|
||||
private void setKeyboardLocal(LatinKeyboard k) {
|
||||
if (DEBUG_AUTO_PLAY) {
|
||||
findKeys();
|
||||
if (mHandler2 == null) {
|
||||
mHandler2 = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
removeMessages(MSG_TOUCH_DOWN);
|
||||
removeMessages(MSG_TOUCH_UP);
|
||||
if (mPlaying == false) return;
|
||||
|
||||
switch (msg.what) {
|
||||
case MSG_TOUCH_DOWN:
|
||||
if (mStringIndex >= mStringToPlay.length()) {
|
||||
mPlaying = false;
|
||||
return;
|
||||
}
|
||||
char c = mStringToPlay.charAt(mStringIndex);
|
||||
while (c > 255 || mAsciiKeys[c] == null) {
|
||||
mStringIndex++;
|
||||
if (mStringIndex >= mStringToPlay.length()) {
|
||||
mPlaying = false;
|
||||
return;
|
||||
}
|
||||
c = mStringToPlay.charAt(mStringIndex);
|
||||
}
|
||||
int x = mAsciiKeys[c].mX + 10;
|
||||
int y = mAsciiKeys[c].mY + 26;
|
||||
MotionEvent me = MotionEvent.obtain(SystemClock.uptimeMillis(),
|
||||
SystemClock.uptimeMillis(),
|
||||
MotionEvent.ACTION_DOWN, x, y, 0);
|
||||
LatinKeyboardView.this.dispatchTouchEvent(me);
|
||||
me.recycle();
|
||||
sendEmptyMessageDelayed(MSG_TOUCH_UP, 500); // Deliver up in 500ms if nothing else
|
||||
// happens
|
||||
mDownDelivered = true;
|
||||
break;
|
||||
case MSG_TOUCH_UP:
|
||||
char cUp = mStringToPlay.charAt(mStringIndex);
|
||||
int x2 = mAsciiKeys[cUp].mX + 10;
|
||||
int y2 = mAsciiKeys[cUp].mY + 26;
|
||||
mStringIndex++;
|
||||
|
||||
MotionEvent me2 = MotionEvent.obtain(SystemClock.uptimeMillis(),
|
||||
SystemClock.uptimeMillis(),
|
||||
MotionEvent.ACTION_UP, x2, y2, 0);
|
||||
LatinKeyboardView.this.dispatchTouchEvent(me2);
|
||||
me2.recycle();
|
||||
sendEmptyMessageDelayed(MSG_TOUCH_DOWN, 500); // Deliver up in 500ms if nothing else
|
||||
// happens
|
||||
mDownDelivered = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void findKeys() {
|
||||
List<Key> keys = getLatinKeyboard().getKeys();
|
||||
// Get the keys on this keyboard
|
||||
for (int i = 0; i < keys.size(); i++) {
|
||||
int code = keys.get(i).mCodes[0];
|
||||
if (code >= 0 && code <= 255) {
|
||||
mAsciiKeys[code] = keys.get(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void startPlaying(String s) {
|
||||
if (DEBUG_AUTO_PLAY) {
|
||||
if (s == null) return;
|
||||
mStringToPlay = s.toLowerCase();
|
||||
mPlaying = true;
|
||||
mDownDelivered = false;
|
||||
mStringIndex = 0;
|
||||
mHandler2.sendEmptyMessageDelayed(MSG_TOUCH_DOWN, 10);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas c) {
|
||||
Utils.GCUtils.getInstance().reset();
|
||||
|
@ -340,26 +230,6 @@ public class LatinKeyboardView extends KeyboardView {
|
|||
tryGC = Utils.GCUtils.getInstance().tryGCOrWait("LatinKeyboardView", e);
|
||||
}
|
||||
}
|
||||
if (DEBUG_AUTO_PLAY) {
|
||||
if (mPlaying) {
|
||||
mHandler2.removeMessages(MSG_TOUCH_DOWN);
|
||||
mHandler2.removeMessages(MSG_TOUCH_UP);
|
||||
if (mDownDelivered) {
|
||||
mHandler2.sendEmptyMessageDelayed(MSG_TOUCH_UP, 20);
|
||||
} else {
|
||||
mHandler2.sendEmptyMessageDelayed(MSG_TOUCH_DOWN, 20);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (DEBUG_LINE) {
|
||||
if (mPaint == null) {
|
||||
mPaint = new Paint();
|
||||
mPaint.setColor(0x80FFFFFF);
|
||||
mPaint.setAntiAlias(false);
|
||||
}
|
||||
c.drawLine(mLastX, 0, mLastX, getHeight(), mPaint);
|
||||
c.drawLine(0, mLastY, getWidth(), mLastY, mPaint);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -299,7 +299,7 @@ public class PointerTracker {
|
|||
showKeyPreviewAndUpdateKeyGraphics(keyIndex);
|
||||
}
|
||||
|
||||
public void onMoveEvent(int x, int y, long eventTime) {
|
||||
public void onMoveEvent(int x, int y, @SuppressWarnings("unused") long eventTime) {
|
||||
if (DEBUG_MOVE)
|
||||
debugLog("onMoveEvent:", x, y);
|
||||
if (mKeyAlreadyProcessed)
|
||||
|
@ -333,7 +333,9 @@ public class PointerTracker {
|
|||
showKeyPreviewAndUpdateKeyGraphics(mKeyState.getKeyIndex());
|
||||
}
|
||||
|
||||
public void onUpEvent(int x, int y, long eventTime) {
|
||||
public void onUpEvent(int pointX, int pointY, long eventTime) {
|
||||
int x = pointX;
|
||||
int y = pointY;
|
||||
if (DEBUG)
|
||||
debugLog("onUpEvent :", x, y);
|
||||
showKeyPreviewAndUpdateKeyGraphics(NOT_A_KEY);
|
||||
|
@ -356,7 +358,7 @@ public class PointerTracker {
|
|||
mProxy.invalidateKey(mKeys[keyIndex]);
|
||||
}
|
||||
|
||||
public void onCancelEvent(int x, int y, long eventTime) {
|
||||
public void onCancelEvent(int x, int y, @SuppressWarnings("unused") long eventTime) {
|
||||
if (DEBUG)
|
||||
debugLog("onCancelEvt:", x, y);
|
||||
mHandler.cancelKeyTimers();
|
||||
|
|
|
@ -58,7 +58,7 @@ public class SlidingLocaleDrawable extends Drawable {
|
|||
mContext = context;
|
||||
mRes = context.getResources();
|
||||
mBackground = background;
|
||||
LatinKeyboard.setDefaultBounds(mBackground);
|
||||
Keyboard.setDefaultBounds(mBackground);
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
final TextPaint textPaint = new TextPaint();
|
||||
|
@ -123,7 +123,7 @@ public class SlidingLocaleDrawable extends Drawable {
|
|||
canvas.drawText(mNextLanguage, diff - width / 2, baseline, paint);
|
||||
canvas.drawText(mPrevLanguage, diff + width + width / 2, baseline, paint);
|
||||
|
||||
LatinKeyboard.setDefaultBounds(lArrow);
|
||||
Keyboard.setDefaultBounds(lArrow);
|
||||
rArrow.setBounds(width - rArrow.getIntrinsicWidth(), 0, width,
|
||||
rArrow.getIntrinsicHeight());
|
||||
lArrow.draw(canvas);
|
||||
|
|
|
@ -98,7 +98,7 @@ public class AutoDictionary extends ExpandableDictionary {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidWord(CharSequence word) {
|
||||
public synchronized boolean isValidWord(CharSequence word) {
|
||||
final int frequency = getWordFrequency(word);
|
||||
return frequency >= VALIDITY_THRESHOLD;
|
||||
}
|
||||
|
@ -138,7 +138,8 @@ public class AutoDictionary extends ExpandableDictionary {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void addWord(String word, int addFrequency) {
|
||||
public void addWord(String newWord, int addFrequency) {
|
||||
String word = newWord;
|
||||
final int length = word.length();
|
||||
// Don't add very short or very long words.
|
||||
if (length < 2 || length > getMaxWordLength()) return;
|
||||
|
@ -224,7 +225,7 @@ public class AutoDictionary extends ExpandableDictionary {
|
|||
private final DatabaseHelper mDbHelper;
|
||||
private final String mLocale;
|
||||
|
||||
public UpdateDbTask(Context context, DatabaseHelper openHelper,
|
||||
public UpdateDbTask(@SuppressWarnings("unused") Context context, DatabaseHelper openHelper,
|
||||
HashMap<String, Integer> pendingWrites, String locale) {
|
||||
mMap = pendingWrites;
|
||||
mLocale = locale;
|
||||
|
|
|
@ -23,6 +23,7 @@ import android.os.Handler;
|
|||
import android.os.Message;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextUtils;
|
||||
import android.text.style.BackgroundColorSpan;
|
||||
import android.text.style.CharacterStyle;
|
||||
|
@ -35,6 +36,7 @@ import android.view.LayoutInflater;
|
|||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.View.OnLongClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.PopupWindow;
|
||||
|
@ -129,7 +131,7 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
|
|||
cancelHidePreview();
|
||||
cancelUpdateSuggestions();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a CandidateView for showing suggested words for completion.
|
||||
|
@ -143,7 +145,8 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
|
|||
mPreviewPopup = new PopupWindow(context);
|
||||
LayoutInflater inflater = LayoutInflater.from(context);
|
||||
mPreviewText = (TextView) inflater.inflate(R.layout.candidate_preview, null);
|
||||
mPreviewPopup.setWindowLayoutMode(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
|
||||
mPreviewPopup.setWindowLayoutMode(ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
mPreviewPopup.setContentView(mPreviewText);
|
||||
mPreviewPopup.setBackgroundDrawable(null);
|
||||
mPreviewPopup.setAnimationStyle(R.style.KeyPreviewAnimation);
|
||||
|
@ -222,7 +225,7 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
|
|||
style = UNDERLINE_SPAN;
|
||||
}
|
||||
final Spannable word = new SpannableString(suggestion);
|
||||
word.setSpan(style, 0, wordLength, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
word.setSpan(style, 0, wordLength, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
suggestion = word;
|
||||
existsAutoCompletion = true;
|
||||
} else if (i != 0 || (wordLength == 1 && count > 1)) {
|
||||
|
@ -255,10 +258,8 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
|
|||
final TextView tv = (TextView)mWords.get(1).findViewById(R.id.candidate_word);
|
||||
final Spannable word = new SpannableString(autoCorrectedWord);
|
||||
final int wordLength = word.length();
|
||||
word.setSpan(mInvertedBackgroundColorSpan, 0, wordLength,
|
||||
Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
word.setSpan(mInvertedForegroundColorSpan, 0, wordLength,
|
||||
Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
word.setSpan(mInvertedBackgroundColorSpan, 0, wordLength, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
word.setSpan(mInvertedForegroundColorSpan, 0, wordLength, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
tv.setText(word);
|
||||
mShowingAutoCorrectionInverted = true;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import android.content.Context;
|
|||
import android.database.ContentObserver;
|
||||
import android.database.Cursor;
|
||||
import android.os.SystemClock;
|
||||
import android.provider.BaseColumns;
|
||||
import android.provider.ContactsContract.Contacts;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
@ -28,7 +29,7 @@ import android.util.Log;
|
|||
public class ContactsDictionary extends ExpandableDictionary {
|
||||
|
||||
private static final String[] PROJECTION = {
|
||||
Contacts._ID,
|
||||
BaseColumns._ID,
|
||||
Contacts.DISPLAY_NAME,
|
||||
};
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ package com.android.inputmethod.latin;
|
|||
* Abstract base class for a dictionary that can do a fuzzy search for words based on a set of key
|
||||
* strokes.
|
||||
*/
|
||||
abstract public class Dictionary {
|
||||
public abstract class Dictionary {
|
||||
/**
|
||||
* Whether or not to replicate the typed word in the suggested list, even if it's valid.
|
||||
*/
|
||||
|
@ -42,11 +42,11 @@ abstract public class Dictionary {
|
|||
public interface WordCallback {
|
||||
/**
|
||||
* Adds a word to a list of suggestions. The word is expected to be ordered based on
|
||||
* the provided frequency.
|
||||
* the provided frequency.
|
||||
* @param word the character array containing the word
|
||||
* @param wordOffset starting offset of the word in the character array
|
||||
* @param wordLength length of valid characters in the character array
|
||||
* @param frequency the frequency of occurence. This is normalized between 1 and 255, but
|
||||
* @param frequency the frequency of occurrence. This is normalized between 1 and 255, but
|
||||
* can exceed those limits
|
||||
* @param dicTypeId of the dictionary where word was from
|
||||
* @param dataType tells type of this data
|
||||
|
@ -74,6 +74,7 @@ abstract public class Dictionary {
|
|||
* Searches for pairs in the bigram dictionary that matches the previous word and all the
|
||||
* possible words following are added through the callback object.
|
||||
* @param composer the key sequence to match
|
||||
* @param previousWord the word before
|
||||
* @param callback the callback object to send possible word following previous word
|
||||
* @param nextLettersFrequencies array of frequencies of next letters that could follow the
|
||||
* word so far. For instance, "bracke" can be followed by "t", so array['t'] will have
|
||||
|
@ -116,5 +117,6 @@ abstract public class Dictionary {
|
|||
* Override to clean up any resources.
|
||||
*/
|
||||
public void close() {
|
||||
// empty base implementation
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ import java.util.regex.Pattern;
|
|||
/**
|
||||
* Utility methods to deal with editing text through an InputConnection.
|
||||
*/
|
||||
public class EditingUtil {
|
||||
public class EditingUtils {
|
||||
/**
|
||||
* Number of characters we want to look back in order to identify the previous word
|
||||
*/
|
||||
|
@ -39,7 +39,9 @@ public class EditingUtil {
|
|||
private static Method sMethodGetSelectedText;
|
||||
private static Method sMethodSetComposingRegion;
|
||||
|
||||
private EditingUtil() {};
|
||||
private EditingUtils() {
|
||||
// Unintentional empty constructor for singleton.
|
||||
}
|
||||
|
||||
/**
|
||||
* Append newText to the text field represented by connection.
|
||||
|
@ -54,14 +56,15 @@ public class EditingUtil {
|
|||
connection.finishComposingText();
|
||||
|
||||
// Add a space if the field already has text.
|
||||
String text = newText;
|
||||
CharSequence charBeforeCursor = connection.getTextBeforeCursor(1, 0);
|
||||
if (charBeforeCursor != null
|
||||
&& !charBeforeCursor.equals(" ")
|
||||
&& (charBeforeCursor.length() > 0)) {
|
||||
newText = " " + newText;
|
||||
text = " " + text;
|
||||
}
|
||||
|
||||
connection.setComposingText(newText, 1);
|
||||
connection.setComposingText(text, 1);
|
||||
}
|
||||
|
||||
private static int getCursorPosition(InputConnection connection) {
|
||||
|
@ -76,33 +79,29 @@ public class EditingUtil {
|
|||
/**
|
||||
* @param connection connection to the current text field.
|
||||
* @param sep characters which may separate words
|
||||
* @param range the range object to store the result into
|
||||
* @return the word that surrounds the cursor, including up to one trailing
|
||||
* separator. For example, if the field contains "he|llo world", where |
|
||||
* represents the cursor, then "hello " will be returned.
|
||||
*/
|
||||
public static String getWordAtCursor(
|
||||
InputConnection connection, String separators, Range range) {
|
||||
Range r = getWordRangeAtCursor(connection, separators, range);
|
||||
return (r == null) ? null : r.word;
|
||||
public static String getWordAtCursor(InputConnection connection, String separators) {
|
||||
Range r = getWordRangeAtCursor(connection, separators);
|
||||
return (r == null) ? null : r.mWord;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the word surrounding the cursor. Parameters are identical to
|
||||
* getWordAtCursor.
|
||||
*/
|
||||
public static void deleteWordAtCursor(
|
||||
InputConnection connection, String separators) {
|
||||
|
||||
Range range = getWordRangeAtCursor(connection, separators, null);
|
||||
public static void deleteWordAtCursor(InputConnection connection, String separators) {
|
||||
Range range = getWordRangeAtCursor(connection, separators);
|
||||
if (range == null) return;
|
||||
|
||||
connection.finishComposingText();
|
||||
// Move cursor to beginning of word, to avoid crash when cursor is outside
|
||||
// of valid range after deleting text.
|
||||
int newCursor = getCursorPosition(connection) - range.charsBefore;
|
||||
int newCursor = getCursorPosition(connection) - range.mCharsBefore;
|
||||
connection.setSelection(newCursor, newCursor);
|
||||
connection.deleteSurroundingText(0, range.charsBefore + range.charsAfter);
|
||||
connection.deleteSurroundingText(0, range.mCharsBefore + range.mCharsAfter);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -110,31 +109,28 @@ public class EditingUtil {
|
|||
*/
|
||||
public static class Range {
|
||||
/** Characters before selection start */
|
||||
public int charsBefore;
|
||||
public final int mCharsBefore;
|
||||
|
||||
/**
|
||||
* Characters after selection start, including one trailing word
|
||||
* separator.
|
||||
*/
|
||||
public int charsAfter;
|
||||
public final int mCharsAfter;
|
||||
|
||||
/** The actual characters that make up a word */
|
||||
public String word;
|
||||
|
||||
public Range() {}
|
||||
public final String mWord;
|
||||
|
||||
public Range(int charsBefore, int charsAfter, String word) {
|
||||
if (charsBefore < 0 || charsAfter < 0) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
this.charsBefore = charsBefore;
|
||||
this.charsAfter = charsAfter;
|
||||
this.word = word;
|
||||
this.mCharsBefore = charsBefore;
|
||||
this.mCharsAfter = charsAfter;
|
||||
this.mWord = word;
|
||||
}
|
||||
}
|
||||
|
||||
private static Range getWordRangeAtCursor(
|
||||
InputConnection connection, String sep, Range range) {
|
||||
private static Range getWordRangeAtCursor(InputConnection connection, String sep) {
|
||||
if (connection == null || sep == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -150,18 +146,15 @@ public class EditingUtil {
|
|||
|
||||
// Find last word separator after the cursor
|
||||
int end = -1;
|
||||
while (++end < after.length() && !isWhitespace(after.charAt(end), sep));
|
||||
while (++end < after.length() && !isWhitespace(after.charAt(end), sep)) {
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
int cursor = getCursorPosition(connection);
|
||||
if (start >= 0 && cursor + end <= after.length() + before.length()) {
|
||||
String word = before.toString().substring(start, before.length())
|
||||
+ after.toString().substring(0, end);
|
||||
|
||||
Range returnRange = range != null? range : new Range();
|
||||
returnRange.charsBefore = before.length() - start;
|
||||
returnRange.charsAfter = end;
|
||||
returnRange.word = word;
|
||||
return returnRange;
|
||||
return new Range(before.length() - start, end, word);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -193,9 +186,15 @@ public class EditingUtil {
|
|||
}
|
||||
|
||||
public static class SelectedWord {
|
||||
public int start;
|
||||
public int end;
|
||||
public CharSequence word;
|
||||
public final int mStart;
|
||||
public final int mEnd;
|
||||
public final CharSequence mWord;
|
||||
|
||||
public SelectedWord(int start, int end, CharSequence word) {
|
||||
mStart = start;
|
||||
mEnd = end;
|
||||
mWord = word;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -223,14 +222,10 @@ public class EditingUtil {
|
|||
int selStart, int selEnd, String wordSeparators) {
|
||||
if (selStart == selEnd) {
|
||||
// There is just a cursor, so get the word at the cursor
|
||||
EditingUtil.Range range = new EditingUtil.Range();
|
||||
CharSequence touching = getWordAtCursor(ic, wordSeparators, range);
|
||||
if (!TextUtils.isEmpty(touching)) {
|
||||
SelectedWord selWord = new SelectedWord();
|
||||
selWord.word = touching;
|
||||
selWord.start = selStart - range.charsBefore;
|
||||
selWord.end = selEnd + range.charsAfter;
|
||||
return selWord;
|
||||
EditingUtils.Range range = getWordRangeAtCursor(ic, wordSeparators);
|
||||
if (range != null && !TextUtils.isEmpty(range.mWord)) {
|
||||
return new SelectedWord(selStart - range.mCharsBefore, selEnd + range.mCharsAfter,
|
||||
range.mWord);
|
||||
}
|
||||
} else {
|
||||
// Is the previous character empty or a word separator? If not, return null.
|
||||
|
@ -256,11 +251,7 @@ public class EditingUtil {
|
|||
}
|
||||
}
|
||||
// Prepare the selected word
|
||||
SelectedWord selWord = new SelectedWord();
|
||||
selWord.start = selStart;
|
||||
selWord.end = selEnd;
|
||||
selWord.word = touching;
|
||||
return selWord;
|
||||
return new SelectedWord(selStart, selEnd, touching);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -324,7 +315,7 @@ public class EditingUtil {
|
|||
}
|
||||
if (sMethodSetComposingRegion != null) {
|
||||
try {
|
||||
sMethodSetComposingRegion.invoke(ic, word.start, word.end);
|
||||
sMethodSetComposingRegion.invoke(ic, word.mStart, word.mEnd);
|
||||
} catch (InvocationTargetException exc) {
|
||||
// Ignore
|
||||
} catch (IllegalArgumentException e) {
|
|
@ -49,53 +49,65 @@ public class ExpandableDictionary extends Dictionary {
|
|||
// Use this lock before touching mUpdatingDictionary & mRequiresDownload
|
||||
private Object mUpdatingLock = new Object();
|
||||
|
||||
static class Node {
|
||||
char code;
|
||||
int frequency;
|
||||
boolean terminal;
|
||||
Node parent;
|
||||
NodeArray children;
|
||||
LinkedList<NextWord> ngrams; // Supports ngram
|
||||
private static class Node {
|
||||
char mCode;
|
||||
int mFrequency;
|
||||
boolean mTerminal;
|
||||
Node mParent;
|
||||
NodeArray mChildren;
|
||||
LinkedList<NextWord> mNGrams; // Supports ngram
|
||||
}
|
||||
|
||||
static class NodeArray {
|
||||
Node[] data;
|
||||
int length = 0;
|
||||
private static class NodeArray {
|
||||
Node[] mData;
|
||||
int mLength = 0;
|
||||
private static final int INCREMENT = 2;
|
||||
|
||||
NodeArray() {
|
||||
data = new Node[INCREMENT];
|
||||
mData = new Node[INCREMENT];
|
||||
}
|
||||
|
||||
void add(Node n) {
|
||||
if (length + 1 > data.length) {
|
||||
Node[] tempData = new Node[length + INCREMENT];
|
||||
if (length > 0) {
|
||||
System.arraycopy(data, 0, tempData, 0, length);
|
||||
if (mLength + 1 > mData.length) {
|
||||
Node[] tempData = new Node[mLength + INCREMENT];
|
||||
if (mLength > 0) {
|
||||
System.arraycopy(mData, 0, tempData, 0, mLength);
|
||||
}
|
||||
data = tempData;
|
||||
mData = tempData;
|
||||
}
|
||||
data[length++] = n;
|
||||
mData[mLength++] = n;
|
||||
}
|
||||
}
|
||||
|
||||
static class NextWord {
|
||||
Node word;
|
||||
NextWord nextWord;
|
||||
int frequency;
|
||||
private static class NextWord {
|
||||
public final Node mWord;
|
||||
private int mFrequency;
|
||||
|
||||
NextWord(Node word, int frequency) {
|
||||
this.word = word;
|
||||
this.frequency = frequency;
|
||||
public NextWord(Node word, int frequency) {
|
||||
mWord = word;
|
||||
mFrequency = frequency;
|
||||
}
|
||||
|
||||
public int getFrequency() {
|
||||
return mFrequency;
|
||||
}
|
||||
|
||||
public int setFrequency(int freq) {
|
||||
mFrequency = freq;
|
||||
return mFrequency;
|
||||
}
|
||||
|
||||
public int addFrequency(int add) {
|
||||
mFrequency += add;
|
||||
return mFrequency;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private NodeArray mRoots;
|
||||
|
||||
private int[][] mCodes;
|
||||
|
||||
ExpandableDictionary(Context context, int dicTypeId) {
|
||||
public ExpandableDictionary(Context context, int dicTypeId) {
|
||||
mContext = context;
|
||||
clearDictionary();
|
||||
mCodes = new int[MAX_WORD_LENGTH][];
|
||||
|
@ -128,13 +140,14 @@ public class ExpandableDictionary extends Dictionary {
|
|||
|
||||
/** Override to load your dictionary here, on a background thread. */
|
||||
public void loadDictionaryAsync() {
|
||||
// empty base implementation
|
||||
}
|
||||
|
||||
Context getContext() {
|
||||
public Context getContext() {
|
||||
return mContext;
|
||||
}
|
||||
|
||||
int getMaxWordLength() {
|
||||
public int getMaxWordLength() {
|
||||
return MAX_WORD_LENGTH;
|
||||
}
|
||||
|
||||
|
@ -147,33 +160,33 @@ public class ExpandableDictionary extends Dictionary {
|
|||
final int wordLength = word.length();
|
||||
final char c = word.charAt(depth);
|
||||
// Does children have the current character?
|
||||
final int childrenLength = children.length;
|
||||
final int childrenLength = children.mLength;
|
||||
Node childNode = null;
|
||||
boolean found = false;
|
||||
for (int i = 0; i < childrenLength; i++) {
|
||||
childNode = children.data[i];
|
||||
if (childNode.code == c) {
|
||||
childNode = children.mData[i];
|
||||
if (childNode.mCode == c) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
childNode = new Node();
|
||||
childNode.code = c;
|
||||
childNode.parent = parentNode;
|
||||
childNode.mCode = c;
|
||||
childNode.mParent = parentNode;
|
||||
children.add(childNode);
|
||||
}
|
||||
if (wordLength == depth + 1) {
|
||||
// Terminate this word
|
||||
childNode.terminal = true;
|
||||
childNode.frequency = Math.max(frequency, childNode.frequency);
|
||||
if (childNode.frequency > 255) childNode.frequency = 255;
|
||||
childNode.mTerminal = true;
|
||||
childNode.mFrequency = Math.max(frequency, childNode.mFrequency);
|
||||
if (childNode.mFrequency > 255) childNode.mFrequency = 255;
|
||||
return;
|
||||
}
|
||||
if (childNode.children == null) {
|
||||
childNode.children = new NodeArray();
|
||||
if (childNode.mChildren == null) {
|
||||
childNode.mChildren = new NodeArray();
|
||||
}
|
||||
addWordRec(childNode.children, word, depth + 1, frequency, childNode);
|
||||
addWordRec(childNode.mChildren, word, depth + 1, frequency, childNode);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -216,7 +229,7 @@ public class ExpandableDictionary extends Dictionary {
|
|||
*/
|
||||
public int getWordFrequency(CharSequence word) {
|
||||
Node node = searchNode(mRoots, word, 0, word.length());
|
||||
return (node == null) ? -1 : node.frequency;
|
||||
return (node == null) ? -1 : node.mFrequency;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -241,7 +254,7 @@ public class ExpandableDictionary extends Dictionary {
|
|||
protected void getWordsRec(NodeArray roots, final WordComposer codes, final char[] word,
|
||||
final int depth, boolean completion, int snr, int inputIndex, int skipPos,
|
||||
WordCallback callback) {
|
||||
final int count = roots.length;
|
||||
final int count = roots.mLength;
|
||||
final int codeSize = mInputLength;
|
||||
// Optimization: Prune out words that are too long compared to how much was typed.
|
||||
if (depth > mMaxDepth) {
|
||||
|
@ -255,12 +268,12 @@ public class ExpandableDictionary extends Dictionary {
|
|||
}
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
final Node node = roots.data[i];
|
||||
final char c = node.code;
|
||||
final Node node = roots.mData[i];
|
||||
final char c = node.mCode;
|
||||
final char lowerC = toLowerCase(c);
|
||||
final boolean terminal = node.terminal;
|
||||
final NodeArray children = node.children;
|
||||
final int freq = node.frequency;
|
||||
final boolean terminal = node.mTerminal;
|
||||
final NodeArray children = node.mChildren;
|
||||
final int freq = node.mFrequency;
|
||||
if (completion) {
|
||||
word[depth] = c;
|
||||
if (terminal) {
|
||||
|
@ -340,24 +353,22 @@ public class ExpandableDictionary extends Dictionary {
|
|||
private int addOrSetBigram(String word1, String word2, int frequency, boolean addFrequency) {
|
||||
Node firstWord = searchWord(mRoots, word1, 0, null);
|
||||
Node secondWord = searchWord(mRoots, word2, 0, null);
|
||||
LinkedList<NextWord> bigram = firstWord.ngrams;
|
||||
LinkedList<NextWord> bigram = firstWord.mNGrams;
|
||||
if (bigram == null || bigram.size() == 0) {
|
||||
firstWord.ngrams = new LinkedList<NextWord>();
|
||||
bigram = firstWord.ngrams;
|
||||
firstWord.mNGrams = new LinkedList<NextWord>();
|
||||
bigram = firstWord.mNGrams;
|
||||
} else {
|
||||
for (NextWord nw : bigram) {
|
||||
if (nw.word == secondWord) {
|
||||
if (nw.mWord == secondWord) {
|
||||
if (addFrequency) {
|
||||
nw.frequency += frequency;
|
||||
return nw.addFrequency(frequency);
|
||||
} else {
|
||||
nw.frequency = frequency;
|
||||
return nw.setFrequency(frequency);
|
||||
}
|
||||
return nw.frequency;
|
||||
}
|
||||
}
|
||||
}
|
||||
NextWord nw = new NextWord(secondWord, frequency);
|
||||
firstWord.ngrams.add(nw);
|
||||
firstWord.mNGrams.add(new NextWord(secondWord, frequency));
|
||||
return frequency;
|
||||
}
|
||||
|
||||
|
@ -369,31 +380,31 @@ public class ExpandableDictionary extends Dictionary {
|
|||
final int wordLength = word.length();
|
||||
final char c = word.charAt(depth);
|
||||
// Does children have the current character?
|
||||
final int childrenLength = children.length;
|
||||
final int childrenLength = children.mLength;
|
||||
Node childNode = null;
|
||||
boolean found = false;
|
||||
for (int i = 0; i < childrenLength; i++) {
|
||||
childNode = children.data[i];
|
||||
if (childNode.code == c) {
|
||||
childNode = children.mData[i];
|
||||
if (childNode.mCode == c) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
childNode = new Node();
|
||||
childNode.code = c;
|
||||
childNode.parent = parentNode;
|
||||
childNode.mCode = c;
|
||||
childNode.mParent = parentNode;
|
||||
children.add(childNode);
|
||||
}
|
||||
if (wordLength == depth + 1) {
|
||||
// Terminate this word
|
||||
childNode.terminal = true;
|
||||
childNode.mTerminal = true;
|
||||
return childNode;
|
||||
}
|
||||
if (childNode.children == null) {
|
||||
childNode.children = new NodeArray();
|
||||
if (childNode.mChildren == null) {
|
||||
childNode.mChildren = new NodeArray();
|
||||
}
|
||||
return searchWord(childNode.children, word, depth + 1, childNode);
|
||||
return searchWord(childNode.mChildren, word, depth + 1, childNode);
|
||||
}
|
||||
|
||||
// @VisibleForTesting
|
||||
|
@ -408,8 +419,8 @@ public class ExpandableDictionary extends Dictionary {
|
|||
|
||||
private void runReverseLookUp(final CharSequence previousWord, final WordCallback callback) {
|
||||
Node prevWord = searchNode(mRoots, previousWord, 0, previousWord.length());
|
||||
if (prevWord != null && prevWord.ngrams != null) {
|
||||
reverseLookUp(prevWord.ngrams, callback);
|
||||
if (prevWord != null && prevWord.mNGrams != null) {
|
||||
reverseLookUp(prevWord.mNGrams, callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -430,6 +441,7 @@ public class ExpandableDictionary extends Dictionary {
|
|||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
//
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -444,14 +456,14 @@ public class ExpandableDictionary extends Dictionary {
|
|||
Node node;
|
||||
int freq;
|
||||
for (NextWord nextWord : terminalNodes) {
|
||||
node = nextWord.word;
|
||||
freq = nextWord.frequency;
|
||||
node = nextWord.mWord;
|
||||
freq = nextWord.getFrequency();
|
||||
// TODO Not the best way to limit suggestion threshold
|
||||
if (freq >= UserBigramDictionary.SUGGEST_THRESHOLD) {
|
||||
sb.setLength(0);
|
||||
do {
|
||||
sb.insert(0, node.code);
|
||||
node = node.parent;
|
||||
sb.insert(0, node.mCode);
|
||||
node = node.mParent;
|
||||
} while(node != null);
|
||||
|
||||
// TODO better way to feed char array?
|
||||
|
@ -468,18 +480,18 @@ public class ExpandableDictionary extends Dictionary {
|
|||
private Node searchNode(final NodeArray children, final CharSequence word, final int offset,
|
||||
final int length) {
|
||||
// TODO Consider combining with addWordRec
|
||||
final int count = children.length;
|
||||
final int count = children.mLength;
|
||||
char currentChar = word.charAt(offset);
|
||||
for (int j = 0; j < count; j++) {
|
||||
final Node node = children.data[j];
|
||||
if (node.code == currentChar) {
|
||||
final Node node = children.mData[j];
|
||||
if (node.mCode == currentChar) {
|
||||
if (offset == length - 1) {
|
||||
if (node.terminal) {
|
||||
if (node.mTerminal) {
|
||||
return node;
|
||||
}
|
||||
} else {
|
||||
if (node.children != null) {
|
||||
Node returnNode = searchNode(node.children, word, offset + 1, length);
|
||||
if (node.mChildren != null) {
|
||||
Node returnNode = searchNode(node.mChildren, word, offset + 1, length);
|
||||
if (returnNode != null) return returnNode;
|
||||
}
|
||||
}
|
||||
|
@ -504,15 +516,16 @@ public class ExpandableDictionary extends Dictionary {
|
|||
}
|
||||
|
||||
static char toLowerCase(char c) {
|
||||
char baseChar = c;
|
||||
if (c < BASE_CHARS.length) {
|
||||
c = BASE_CHARS[c];
|
||||
baseChar = BASE_CHARS[c];
|
||||
}
|
||||
if (c >= 'A' && c <= 'Z') {
|
||||
c = (char) (c | 32);
|
||||
} else if (c > 127) {
|
||||
c = Character.toLowerCase(c);
|
||||
if (baseChar >= 'A' && baseChar <= 'Z') {
|
||||
return (char)(baseChar | 32);
|
||||
} else if (baseChar > 127) {
|
||||
return Character.toLowerCase(baseChar);
|
||||
}
|
||||
return c;
|
||||
return baseChar;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -42,24 +42,28 @@ public class InputLanguageSelection extends PreferenceActivity {
|
|||
};
|
||||
|
||||
private static class Loc implements Comparable<Object> {
|
||||
static Collator sCollator = Collator.getInstance();
|
||||
private static Collator sCollator = Collator.getInstance();
|
||||
|
||||
String label;
|
||||
Locale locale;
|
||||
private String mLabel;
|
||||
public final Locale mLocale;
|
||||
|
||||
public Loc(String label, Locale locale) {
|
||||
this.label = label;
|
||||
this.locale = locale;
|
||||
this.mLabel = label;
|
||||
this.mLocale = locale;
|
||||
}
|
||||
|
||||
public void setLabel(String label) {
|
||||
this.mLabel = label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.label;
|
||||
return this.mLabel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Object o) {
|
||||
return sCollator.compare(this.label, ((Loc) o).label);
|
||||
return sCollator.compare(this.mLabel, ((Loc) o).mLabel);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,7 +79,7 @@ public class InputLanguageSelection extends PreferenceActivity {
|
|||
PreferenceGroup parent = getPreferenceScreen();
|
||||
for (int i = 0; i < mAvailableLanguages.size(); i++) {
|
||||
CheckBoxPreference pref = new CheckBoxPreference(this);
|
||||
Locale locale = mAvailableLanguages.get(i).locale;
|
||||
Locale locale = mAvailableLanguages.get(i).mLocale;
|
||||
pref.setTitle(SubtypeSwitcher.getFullDisplayName(locale, true));
|
||||
boolean checked = isLocaleIn(locale, languageList);
|
||||
pref.setChecked(checked);
|
||||
|
@ -137,7 +141,7 @@ public class InputLanguageSelection extends PreferenceActivity {
|
|||
for (int i = 0; i < count; i++) {
|
||||
CheckBoxPreference pref = (CheckBoxPreference) parent.getPreference(i);
|
||||
if (pref.isChecked()) {
|
||||
Locale locale = mAvailableLanguages.get(i).locale;
|
||||
Locale locale = mAvailableLanguages.get(i).mLocale;
|
||||
checkedLanguages += get5Code(locale) + ",";
|
||||
}
|
||||
}
|
||||
|
@ -147,7 +151,7 @@ public class InputLanguageSelection extends PreferenceActivity {
|
|||
SharedPreferencesCompat.apply(editor);
|
||||
}
|
||||
|
||||
ArrayList<Loc> getUniqueLocales() {
|
||||
public ArrayList<Loc> getUniqueLocales() {
|
||||
String[] locales = getAssets().getLocales();
|
||||
Arrays.sort(locales);
|
||||
ArrayList<Loc> uniqueLocales = new ArrayList<Loc>();
|
||||
|
@ -174,15 +178,16 @@ public class InputLanguageSelection extends PreferenceActivity {
|
|||
// same lang and a country -> upgrade to full name and
|
||||
// insert ours with full name
|
||||
// diff lang -> insert ours with lang-only name
|
||||
if (preprocess[finalSize-1].locale.getLanguage().equals(
|
||||
if (preprocess[finalSize-1].mLocale.getLanguage().equals(
|
||||
language)) {
|
||||
preprocess[finalSize-1].label = SubtypeSwitcher.getFullDisplayName(
|
||||
preprocess[finalSize-1].locale, false);
|
||||
preprocess[finalSize-1].setLabel(SubtypeSwitcher.getFullDisplayName(
|
||||
preprocess[finalSize-1].mLocale, false));
|
||||
preprocess[finalSize++] =
|
||||
new Loc(SubtypeSwitcher.getFullDisplayName(l, false), l);
|
||||
} else {
|
||||
String displayName;
|
||||
if (s.equals("zz_ZZ")) {
|
||||
// ignore this locale
|
||||
} else {
|
||||
displayName = SubtypeSwitcher.getFullDisplayName(l, true);
|
||||
preprocess[finalSize++] = new Loc(displayName, l);
|
||||
|
|
|
@ -25,6 +25,7 @@ import com.android.inputmethod.keyboard.LatinKeyboardView;
|
|||
import com.android.inputmethod.latin.Utils.RingCharBuffer;
|
||||
import com.android.inputmethod.voice.VoiceIMEConnector;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
|
@ -46,6 +47,7 @@ import android.os.SystemClock;
|
|||
import android.os.Vibrator;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.InputType;
|
||||
import android.text.TextUtils;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
|
@ -82,7 +84,7 @@ import java.util.Locale;
|
|||
* Input method implementation for Qwerty'ish keyboard.
|
||||
*/
|
||||
public class LatinIME extends InputMethodService implements KeyboardActionListener,
|
||||
SharedPreferences.OnSharedPreferenceChangeListener, Tutorial.TutorialListener {
|
||||
SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
private static final String TAG = "LatinIME";
|
||||
private static final boolean PERF_DEBUG = false;
|
||||
private static final boolean DEBUG = false;
|
||||
|
@ -91,7 +93,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
private static final int DELAY_UPDATE_SUGGESTIONS = 180;
|
||||
private static final int DELAY_UPDATE_OLD_SUGGESTIONS = 300;
|
||||
private static final int DELAY_UPDATE_SHIFT_STATE = 300;
|
||||
private static final int DELAY_START_TUTORIAL = 500;
|
||||
|
||||
// How many continuous deletes at which to start deleting at a higher speed.
|
||||
private static final int DELETE_ACCELERATE_AT = 20;
|
||||
|
@ -172,8 +173,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
private int mDeleteCount;
|
||||
private long mLastKeyTime;
|
||||
|
||||
private Tutorial mTutorial;
|
||||
|
||||
private AudioManager mAudioManager;
|
||||
// Align sound effect volume on music volume
|
||||
private static final float FX_VOLUME = -1.0f;
|
||||
|
@ -246,7 +245,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
private static final int MSG_UPDATE_OLD_SUGGESTIONS = 1;
|
||||
private static final int MSG_UPDATE_SHIFT_STATE = 2;
|
||||
private static final int MSG_VOICE_RESULTS = 3;
|
||||
private static final int MSG_START_TUTORIAL = 4;
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
|
@ -261,21 +259,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
mKeyboardSwitcher.updateShiftState();
|
||||
break;
|
||||
case MSG_VOICE_RESULTS:
|
||||
mVoiceConnector.handleVoiceResults(mKeyboardSwitcher, preferCapitalization()
|
||||
mVoiceConnector.handleVoiceResults(preferCapitalization()
|
||||
|| (mKeyboardSwitcher.isAlphabetMode()
|
||||
&& mKeyboardSwitcher.isShiftedOrShiftLocked()));
|
||||
break;
|
||||
case MSG_START_TUTORIAL:
|
||||
if (mTutorial == null) {
|
||||
if (mKeyboardSwitcher.isInputViewShown()) {
|
||||
mTutorial = new Tutorial(LatinIME.this, mKeyboardSwitcher);
|
||||
mTutorial.start();
|
||||
} else {
|
||||
// Try again soon if the view is not yet showing
|
||||
sendMessageDelayed(obtainMessage(MSG_START_TUTORIAL), 100);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -314,10 +301,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
public void updateVoiceResults() {
|
||||
sendMessage(obtainMessage(MSG_VOICE_RESULTS));
|
||||
}
|
||||
|
||||
public void startTutorial() {
|
||||
sendMessageDelayed(obtainMessage(MSG_START_TUTORIAL), DELAY_START_TUTORIAL);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -369,8 +352,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
|
||||
try {
|
||||
int current = xrp.getEventType();
|
||||
while (current != XmlResourceParser.END_DOCUMENT) {
|
||||
if (current == XmlResourceParser.START_TAG) {
|
||||
while (current != XmlPullParser.END_DOCUMENT) {
|
||||
if (current == XmlPullParser.START_TAG) {
|
||||
String tag = xrp.getName();
|
||||
if (tag != null) {
|
||||
if (tag.equals("part")) {
|
||||
|
@ -501,14 +484,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
}
|
||||
|
||||
private static boolean isPasswordVariation(int variation) {
|
||||
return variation == EditorInfo.TYPE_TEXT_VARIATION_PASSWORD
|
||||
|| variation == EditorInfo.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
|
||||
|| variation == EditorInfo.TYPE_TEXT_VARIATION_WEB_PASSWORD;
|
||||
return variation == InputType.TYPE_TEXT_VARIATION_PASSWORD
|
||||
|| variation == InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
|
||||
|| variation == InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD;
|
||||
}
|
||||
|
||||
private static boolean isEmailVariation(int variation) {
|
||||
return variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
|
||||
|| variation == EditorInfo.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS;
|
||||
return variation == InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
|
||||
|| variation == InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -533,7 +516,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
// Most such things we decide below in the switch statement, but we need to know
|
||||
// now whether this is a password text field, because we need to know now (before
|
||||
// the switch statement) whether we want to enable the voice button.
|
||||
int variation = attribute.inputType & EditorInfo.TYPE_MASK_VARIATION;
|
||||
int variation = attribute.inputType & InputType.TYPE_MASK_VARIATION;
|
||||
mVoiceConnector.resetVoiceStates(isPasswordVariation(variation));
|
||||
mInputTypeNoAutoCorrect = false;
|
||||
mPredictionOn = false;
|
||||
|
@ -542,15 +525,15 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
mEnteredText = null;
|
||||
|
||||
final int mode;
|
||||
switch (attribute.inputType & EditorInfo.TYPE_MASK_CLASS) {
|
||||
case EditorInfo.TYPE_CLASS_NUMBER:
|
||||
case EditorInfo.TYPE_CLASS_DATETIME:
|
||||
switch (attribute.inputType & InputType.TYPE_MASK_CLASS) {
|
||||
case InputType.TYPE_CLASS_NUMBER:
|
||||
case InputType.TYPE_CLASS_DATETIME:
|
||||
mode = KeyboardId.MODE_NUMBER;
|
||||
break;
|
||||
case EditorInfo.TYPE_CLASS_PHONE:
|
||||
case InputType.TYPE_CLASS_PHONE:
|
||||
mode = KeyboardId.MODE_PHONE;
|
||||
break;
|
||||
case EditorInfo.TYPE_CLASS_TEXT:
|
||||
case InputType.TYPE_CLASS_TEXT:
|
||||
//startPrediction();
|
||||
mPredictionOn = true;
|
||||
// Make sure that passwords are not displayed in candidate view
|
||||
|
@ -558,7 +541,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
mPredictionOn = false;
|
||||
}
|
||||
if (isEmailVariation(variation)
|
||||
|| variation == EditorInfo.TYPE_TEXT_VARIATION_PERSON_NAME) {
|
||||
|| variation == InputType.TYPE_TEXT_VARIATION_PERSON_NAME) {
|
||||
mAutoSpace = false;
|
||||
} else {
|
||||
mAutoSpace = true;
|
||||
|
@ -566,19 +549,19 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
if (isEmailVariation(variation)) {
|
||||
mPredictionOn = false;
|
||||
mode = KeyboardId.MODE_EMAIL;
|
||||
} else if (variation == EditorInfo.TYPE_TEXT_VARIATION_URI) {
|
||||
} else if (variation == InputType.TYPE_TEXT_VARIATION_URI) {
|
||||
mPredictionOn = false;
|
||||
mode = KeyboardId.MODE_URL;
|
||||
} else if (variation == EditorInfo.TYPE_TEXT_VARIATION_SHORT_MESSAGE) {
|
||||
} else if (variation == InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE) {
|
||||
mode = KeyboardId.MODE_IM;
|
||||
} else if (variation == EditorInfo.TYPE_TEXT_VARIATION_FILTER) {
|
||||
} else if (variation == InputType.TYPE_TEXT_VARIATION_FILTER) {
|
||||
mPredictionOn = false;
|
||||
mode = KeyboardId.MODE_TEXT;
|
||||
} else if (variation == EditorInfo.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT) {
|
||||
} else if (variation == InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT) {
|
||||
mode = KeyboardId.MODE_WEB;
|
||||
// If it's a browser edit field and auto correct is not ON explicitly, then
|
||||
// disable auto correction, but keep suggestions on.
|
||||
if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0) {
|
||||
if ((attribute.inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0) {
|
||||
mInputTypeNoAutoCorrect = true;
|
||||
}
|
||||
} else {
|
||||
|
@ -586,16 +569,16 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
}
|
||||
|
||||
// If NO_SUGGESTIONS is set, don't do prediction.
|
||||
if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_NO_SUGGESTIONS) != 0) {
|
||||
if ((attribute.inputType & InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS) != 0) {
|
||||
mPredictionOn = false;
|
||||
mInputTypeNoAutoCorrect = true;
|
||||
}
|
||||
// If it's not multiline and the autoCorrect flag is not set, then don't correct
|
||||
if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0 &&
|
||||
(attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE) == 0) {
|
||||
if ((attribute.inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0 &&
|
||||
(attribute.inputType & InputType.TYPE_TEXT_FLAG_MULTI_LINE) == 0) {
|
||||
mInputTypeNoAutoCorrect = true;
|
||||
}
|
||||
if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) {
|
||||
if ((attribute.inputType & InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) {
|
||||
mPredictionOn = false;
|
||||
mCompletionOn = isFullscreenMode();
|
||||
}
|
||||
|
@ -632,7 +615,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
mPredictionOn = mPredictionOn && (mCorrectionMode > 0 || isSuggestionShown());
|
||||
// If we just entered a text field, maybe it has some old text that requires correction
|
||||
checkReCorrectionOnStart();
|
||||
checkTutorial(attribute.privateImeOptions);
|
||||
inputView.setForeground(true);
|
||||
|
||||
mVoiceConnector.onStartInputView(mKeyboardSwitcher.getInputView().getWindowToken());
|
||||
|
@ -733,12 +715,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
mVoiceConnector.setVoiceInputHighlighted(false);
|
||||
} else if (!mPredicting && !mJustAccepted) {
|
||||
switch (TextEntryState.getState()) {
|
||||
case ACCEPTED_DEFAULT:
|
||||
TextEntryState.reset();
|
||||
// fall through
|
||||
case SPACE_AFTER_PICKED:
|
||||
mJustAddedAutoSpace = false; // The user moved the cursor.
|
||||
break;
|
||||
case ACCEPTED_DEFAULT:
|
||||
TextEntryState.reset();
|
||||
// $FALL-THROUGH$
|
||||
case SPACE_AFTER_PICKED:
|
||||
mJustAddedAutoSpace = false; // The user moved the cursor.
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
mJustAccepted = false;
|
||||
|
@ -835,7 +819,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
}
|
||||
|
||||
List<CharSequence> stringList = new ArrayList<CharSequence>();
|
||||
for (int i=0; i<(completions != null ? completions.length : 0); i++) {
|
||||
for (int i = 0; i < completions.length; i++) {
|
||||
CompletionInfo ci = completions[i];
|
||||
if (ci != null) stringList.add(ci.getText());
|
||||
}
|
||||
|
@ -883,25 +867,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
switch (keyCode) {
|
||||
case KeyEvent.KEYCODE_BACK:
|
||||
if (event.getRepeatCount() == 0 && mKeyboardSwitcher.getInputView() != null) {
|
||||
if (mKeyboardSwitcher.getInputView().handleBack()) {
|
||||
return true;
|
||||
} else if (mTutorial != null) {
|
||||
mTutorial.close();
|
||||
mTutorial = null;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case KeyEvent.KEYCODE_DPAD_DOWN:
|
||||
case KeyEvent.KEYCODE_DPAD_UP:
|
||||
case KeyEvent.KEYCODE_DPAD_LEFT:
|
||||
case KeyEvent.KEYCODE_DPAD_RIGHT:
|
||||
// If tutorial is visible, don't allow dpad to work
|
||||
if (mTutorial != null) {
|
||||
case KeyEvent.KEYCODE_BACK:
|
||||
if (event.getRepeatCount() == 0 && mKeyboardSwitcher.getInputView() != null) {
|
||||
if (mKeyboardSwitcher.getInputView().handleBack()) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
@ -909,26 +881,23 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
@Override
|
||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||
switch (keyCode) {
|
||||
case KeyEvent.KEYCODE_DPAD_DOWN:
|
||||
case KeyEvent.KEYCODE_DPAD_UP:
|
||||
case KeyEvent.KEYCODE_DPAD_LEFT:
|
||||
case KeyEvent.KEYCODE_DPAD_RIGHT:
|
||||
// If tutorial is visible, don't allow dpad to work
|
||||
if (mTutorial != null) {
|
||||
return true;
|
||||
}
|
||||
// Enable shift key and DPAD to do selections
|
||||
if (mKeyboardSwitcher.isInputViewShown()
|
||||
&& mKeyboardSwitcher.isShiftedOrShiftLocked()) {
|
||||
event = new KeyEvent(event.getDownTime(), event.getEventTime(),
|
||||
event.getAction(), event.getKeyCode(), event.getRepeatCount(),
|
||||
event.getDeviceId(), event.getScanCode(),
|
||||
KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_SHIFT_ON);
|
||||
InputConnection ic = getCurrentInputConnection();
|
||||
if (ic != null) ic.sendKeyEvent(event);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case KeyEvent.KEYCODE_DPAD_DOWN:
|
||||
case KeyEvent.KEYCODE_DPAD_UP:
|
||||
case KeyEvent.KEYCODE_DPAD_LEFT:
|
||||
case KeyEvent.KEYCODE_DPAD_RIGHT:
|
||||
// Enable shift key and DPAD to do selections
|
||||
if (mKeyboardSwitcher.isInputViewShown()
|
||||
&& mKeyboardSwitcher.isShiftedOrShiftLocked()) {
|
||||
KeyEvent newEvent = new KeyEvent(event.getDownTime(), event.getEventTime(),
|
||||
event.getAction(), event.getKeyCode(), event.getRepeatCount(),
|
||||
event.getDeviceId(), event.getScanCode(),
|
||||
KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_SHIFT_ON);
|
||||
InputConnection ic = getCurrentInputConnection();
|
||||
if (ic != null)
|
||||
ic.sendKeyEvent(newEvent);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return super.onKeyUp(keyCode, event);
|
||||
}
|
||||
|
@ -951,7 +920,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
public boolean getCurrentAutoCapsState() {
|
||||
InputConnection ic = getCurrentInputConnection();
|
||||
EditorInfo ei = getCurrentInputEditorInfo();
|
||||
if (mAutoCap && ic != null && ei != null && ei.inputType != EditorInfo.TYPE_NULL) {
|
||||
if (mAutoCap && ic != null && ei != null && ei.inputType != InputType.TYPE_NULL) {
|
||||
return ic.getCursorCapsMode(ei.inputType) != 0;
|
||||
}
|
||||
return false;
|
||||
|
@ -1262,7 +1231,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
abortCorrection(false);
|
||||
}
|
||||
|
||||
if (isAlphabet(primaryCode) && isPredictionOn() && !isCursorTouchingWord()) {
|
||||
int code = primaryCode;
|
||||
if (isAlphabet(code) && isPredictionOn() && !isCursorTouchingWord()) {
|
||||
if (!mPredicting) {
|
||||
mPredicting = true;
|
||||
mComposing.setLength(0);
|
||||
|
@ -1276,14 +1246,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
|| keyCodes[0] > Character.MAX_CODE_POINT) {
|
||||
return;
|
||||
}
|
||||
primaryCode = keyCodes[0];
|
||||
if (switcher.isAlphabetMode() && Character.isLowerCase(primaryCode)) {
|
||||
int upperCaseCode = Character.toUpperCase(primaryCode);
|
||||
if (upperCaseCode != primaryCode) {
|
||||
primaryCode = upperCaseCode;
|
||||
code = keyCodes[0];
|
||||
if (switcher.isAlphabetMode() && Character.isLowerCase(code)) {
|
||||
int upperCaseCode = Character.toUpperCase(code);
|
||||
if (upperCaseCode != code) {
|
||||
code = upperCaseCode;
|
||||
} else {
|
||||
// Some keys, such as [eszett], have upper case as multi-characters.
|
||||
String upperCase = new String(new int[] {primaryCode}, 0, 1).toUpperCase();
|
||||
String upperCase = new String(new int[] {code}, 0, 1).toUpperCase();
|
||||
onText(upperCase);
|
||||
return;
|
||||
}
|
||||
|
@ -1294,8 +1264,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
&& switcher.isShiftedOrShiftLocked()) {
|
||||
mWord.setFirstCharCapitalized(true);
|
||||
}
|
||||
mComposing.append((char) primaryCode);
|
||||
mWord.add(primaryCode, keyCodes);
|
||||
mComposing.append((char) code);
|
||||
mWord.add(code, keyCodes);
|
||||
InputConnection ic = getCurrentInputConnection();
|
||||
if (ic != null) {
|
||||
// If it's the first letter, make note of auto-caps state
|
||||
|
@ -1306,11 +1276,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
}
|
||||
mHandler.postUpdateSuggestions();
|
||||
} else {
|
||||
sendKeyChar((char)primaryCode);
|
||||
sendKeyChar((char)code);
|
||||
}
|
||||
switcher.updateShiftState();
|
||||
if (LatinIME.PERF_DEBUG) measureCps();
|
||||
TextEntryState.typedCharacter((char) primaryCode, isWordSeparator(primaryCode));
|
||||
TextEntryState.typedCharacter((char) code, isWordSeparator(code));
|
||||
}
|
||||
|
||||
private void handleSeparator(int primaryCode) {
|
||||
|
@ -1502,7 +1472,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
private void showSuggestions(WordComposer word) {
|
||||
// long startTime = System.currentTimeMillis(); // TIME MEASUREMENT!
|
||||
// TODO Maybe need better way of retrieving previous word
|
||||
CharSequence prevWord = EditingUtil.getPreviousWord(getCurrentInputConnection(),
|
||||
CharSequence prevWord = EditingUtils.getPreviousWord(getCurrentInputConnection(),
|
||||
mWordSeparators);
|
||||
List<CharSequence> stringList = mSuggest.getSuggestions(
|
||||
mKeyboardSwitcher.getInputView(), word, false, prevWord);
|
||||
|
@ -1672,12 +1642,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
* @param touching The word that the cursor is touching, with position information
|
||||
* @return true if an alternative was found, false otherwise.
|
||||
*/
|
||||
private boolean applyTypedAlternatives(EditingUtil.SelectedWord touching) {
|
||||
private boolean applyTypedAlternatives(EditingUtils.SelectedWord touching) {
|
||||
// If we didn't find a match, search for result in typed word history
|
||||
WordComposer foundWord = null;
|
||||
WordAlternatives alternatives = null;
|
||||
for (WordAlternatives entry : mWordHistory) {
|
||||
if (TextUtils.equals(entry.getChosenWord(), touching.word)) {
|
||||
if (TextUtils.equals(entry.getChosenWord(), touching.mWord)) {
|
||||
if (entry instanceof TypedWordAlternatives) {
|
||||
foundWord = ((TypedWordAlternatives) entry).word;
|
||||
}
|
||||
|
@ -1687,20 +1657,20 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
}
|
||||
// If we didn't find a match, at least suggest completions
|
||||
if (foundWord == null
|
||||
&& (mSuggest.isValidWord(touching.word)
|
||||
|| mSuggest.isValidWord(touching.word.toString().toLowerCase()))) {
|
||||
&& (mSuggest.isValidWord(touching.mWord)
|
||||
|| mSuggest.isValidWord(touching.mWord.toString().toLowerCase()))) {
|
||||
foundWord = new WordComposer();
|
||||
for (int i = 0; i < touching.word.length(); i++) {
|
||||
foundWord.add(touching.word.charAt(i), new int[] {
|
||||
touching.word.charAt(i)
|
||||
for (int i = 0; i < touching.mWord.length(); i++) {
|
||||
foundWord.add(touching.mWord.charAt(i), new int[] {
|
||||
touching.mWord.charAt(i)
|
||||
});
|
||||
}
|
||||
foundWord.setFirstCharCapitalized(Character.isUpperCase(touching.word.charAt(0)));
|
||||
foundWord.setFirstCharCapitalized(Character.isUpperCase(touching.mWord.charAt(0)));
|
||||
}
|
||||
// Found a match, show suggestions
|
||||
if (foundWord != null || alternatives != null) {
|
||||
if (alternatives == null) {
|
||||
alternatives = new TypedWordAlternatives(touching.word, foundWord);
|
||||
alternatives = new TypedWordAlternatives(touching.mWord, foundWord);
|
||||
}
|
||||
showCorrections(alternatives);
|
||||
if (foundWord != null) {
|
||||
|
@ -1722,10 +1692,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
if (ic == null) return;
|
||||
if (!mPredicting) {
|
||||
// Extract the selected or touching text
|
||||
EditingUtil.SelectedWord touching = EditingUtil.getWordAtCursorOrSelection(ic,
|
||||
EditingUtils.SelectedWord touching = EditingUtils.getWordAtCursorOrSelection(ic,
|
||||
mLastSelectionStart, mLastSelectionEnd, mWordSeparators);
|
||||
|
||||
if (touching != null && touching.word.length() > 1) {
|
||||
if (touching != null && touching.mWord.length() > 1) {
|
||||
ic.beginBatchEdit();
|
||||
|
||||
if (!mVoiceConnector.applyVoiceAlternatives(touching)
|
||||
|
@ -1733,7 +1703,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
abortCorrection(true);
|
||||
} else {
|
||||
TextEntryState.selectedForCorrection();
|
||||
EditingUtil.underlineWord(ic, touching);
|
||||
EditingUtils.underlineWord(ic, touching);
|
||||
}
|
||||
|
||||
ic.endBatchEdit();
|
||||
|
@ -1773,19 +1743,17 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
|| mCorrectionMode == Suggest.CORRECTION_FULL_BIGRAM)) {
|
||||
return;
|
||||
}
|
||||
if (suggestion != null) {
|
||||
if (!addToBigramDictionary && mAutoDictionary.isValidWord(suggestion)
|
||||
|| (!mSuggest.isValidWord(suggestion.toString())
|
||||
&& !mSuggest.isValidWord(suggestion.toString().toLowerCase()))) {
|
||||
mAutoDictionary.addWord(suggestion.toString(), frequencyDelta);
|
||||
}
|
||||
if (!addToBigramDictionary && mAutoDictionary.isValidWord(suggestion)
|
||||
|| (!mSuggest.isValidWord(suggestion.toString())
|
||||
&& !mSuggest.isValidWord(suggestion.toString().toLowerCase()))) {
|
||||
mAutoDictionary.addWord(suggestion.toString(), frequencyDelta);
|
||||
}
|
||||
|
||||
if (mUserBigramDictionary != null) {
|
||||
CharSequence prevWord = EditingUtil.getPreviousWord(getCurrentInputConnection(),
|
||||
mSentenceSeparators);
|
||||
if (!TextUtils.isEmpty(prevWord)) {
|
||||
mUserBigramDictionary.addBigrams(prevWord.toString(), suggestion.toString());
|
||||
}
|
||||
if (mUserBigramDictionary != null) {
|
||||
CharSequence prevWord = EditingUtils.getPreviousWord(getCurrentInputConnection(),
|
||||
mSentenceSeparators);
|
||||
if (!TextUtils.isEmpty(prevWord)) {
|
||||
mUserBigramDictionary.addBigrams(prevWord.toString(), suggestion.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1896,17 +1864,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
|
||||
@Override
|
||||
public void swipeRight() {
|
||||
if (LatinKeyboardView.DEBUG_AUTO_PLAY) {
|
||||
CharSequence text = ((android.text.ClipboardManager)getSystemService(
|
||||
CLIPBOARD_SERVICE)).getText();
|
||||
if (!TextUtils.isEmpty(text)) {
|
||||
mKeyboardSwitcher.getInputView().startPlaying(text.toString());
|
||||
}
|
||||
}
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public void swipeLeft() {
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1916,6 +1879,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
|
||||
@Override
|
||||
public void swipeUp() {
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2004,26 +1968,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
}
|
||||
}
|
||||
|
||||
private void checkTutorial(String privateImeOptions) {
|
||||
if (privateImeOptions == null) return;
|
||||
if (privateImeOptions.equals("com.android.setupwizard:ShowTutorial")) {
|
||||
if (mTutorial == null) mHandler.startTutorial();
|
||||
} else if (privateImeOptions.equals("com.android.setupwizard:HideTutorial")) {
|
||||
if (mTutorial != null) {
|
||||
if (mTutorial.close()) {
|
||||
mTutorial = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tutorial.TutorialListener
|
||||
@Override
|
||||
public void onTutorialDone() {
|
||||
sendDownUpKeyEvents(-1); // Inform the setupwizard that tutorial is in last bubble
|
||||
mTutorial = null;
|
||||
}
|
||||
|
||||
public void promoteToUserDictionary(String word, int frequency) {
|
||||
if (mUserDictionary.isValidWord(word)) return;
|
||||
mUserDictionary.addWord(word, frequency);
|
||||
|
|
|
@ -92,6 +92,7 @@ public class SubtypeSwitcher {
|
|||
}
|
||||
|
||||
private SubtypeSwitcher() {
|
||||
// Intentional empty constructor for singleton.
|
||||
}
|
||||
|
||||
private void resetParams(LatinIME service) {
|
||||
|
|
|
@ -113,7 +113,7 @@ public class TextEntryState {
|
|||
sKeyLocationFile = null;
|
||||
sUserActionFile = null;
|
||||
} catch (IOException ioe) {
|
||||
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,16 +135,18 @@ public class TextEntryState {
|
|||
public static void backToAcceptedDefault(CharSequence typedWord) {
|
||||
if (typedWord == null) return;
|
||||
switch (sState) {
|
||||
case SPACE_AFTER_ACCEPTED:
|
||||
case PUNCTUATION_AFTER_ACCEPTED:
|
||||
case IN_WORD:
|
||||
sState = State.ACCEPTED_DEFAULT;
|
||||
break;
|
||||
case SPACE_AFTER_ACCEPTED:
|
||||
case PUNCTUATION_AFTER_ACCEPTED:
|
||||
case IN_WORD:
|
||||
sState = State.ACCEPTED_DEFAULT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
displayState();
|
||||
}
|
||||
|
||||
public static void acceptedTyped(CharSequence typedWord) {
|
||||
public static void acceptedTyped(@SuppressWarnings("unused") CharSequence typedWord) {
|
||||
sWordNotInDictionaryCount++;
|
||||
sState = State.PICKED_SUGGESTION;
|
||||
displayState();
|
||||
|
|
|
@ -1,251 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.android.inputmethod.latin;
|
||||
|
||||
import com.android.inputmethod.keyboard.KeyboardSwitcher;
|
||||
import com.android.inputmethod.keyboard.LatinKeyboardView;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.text.Layout;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.StaticLayout;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnTouchListener;
|
||||
import android.widget.PopupWindow;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Tutorial implements OnTouchListener {
|
||||
|
||||
public interface TutorialListener {
|
||||
public void onTutorialDone();
|
||||
}
|
||||
|
||||
private final ArrayList<Bubble> mBubbles = new ArrayList<Bubble>();
|
||||
private final KeyboardSwitcher mKeyboardSwitcher;
|
||||
private final View mInputView;
|
||||
private final TutorialListener mListener;
|
||||
private final int[] mLocation = new int[2];
|
||||
|
||||
private static final int MSG_SHOW_BUBBLE = 0;
|
||||
|
||||
private int mBubbleIndex;
|
||||
|
||||
private final Handler mHandler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case MSG_SHOW_BUBBLE:
|
||||
Bubble bubba = (Bubble) msg.obj;
|
||||
bubba.show(mLocation[0], mLocation[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private class Bubble {
|
||||
private final Drawable bubbleBackground;
|
||||
private final int x;
|
||||
private final int y;
|
||||
private final int width;
|
||||
private final int gravity;
|
||||
private final CharSequence text;
|
||||
private final PopupWindow window;
|
||||
private final TextView textView;
|
||||
private final View inputView;
|
||||
|
||||
private Bubble(Context context, View inputView,
|
||||
int backgroundResource, int bx, int by, int textResource1, int textResource2) {
|
||||
bubbleBackground = context.getResources().getDrawable(backgroundResource);
|
||||
x = bx;
|
||||
y = by;
|
||||
width = (int) (inputView.getWidth() * 0.9);
|
||||
this.gravity = Gravity.TOP | Gravity.LEFT;
|
||||
text = new SpannableStringBuilder()
|
||||
.append(context.getResources().getText(textResource1))
|
||||
.append("\n")
|
||||
.append(context.getResources().getText(textResource2));
|
||||
this.inputView = inputView;
|
||||
window = new PopupWindow(context);
|
||||
window.setBackgroundDrawable(null);
|
||||
LayoutInflater inflate =
|
||||
(LayoutInflater) context
|
||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
textView = (TextView) inflate.inflate(R.layout.bubble_text, null);
|
||||
textView.setBackgroundDrawable(bubbleBackground);
|
||||
textView.setText(text);
|
||||
//textView.setText(textResource1);
|
||||
window.setContentView(textView);
|
||||
window.setFocusable(false);
|
||||
window.setTouchable(true);
|
||||
window.setOutsideTouchable(false);
|
||||
}
|
||||
|
||||
private int chooseSize(PopupWindow pop, View parentView, CharSequence text, TextView tv) {
|
||||
int wid = tv.getPaddingLeft() + tv.getPaddingRight();
|
||||
int ht = tv.getPaddingTop() + tv.getPaddingBottom();
|
||||
|
||||
/*
|
||||
* Figure out how big the text would be if we laid it out to the
|
||||
* full width of this view minus the border.
|
||||
*/
|
||||
int cap = width - wid;
|
||||
|
||||
Layout l = new StaticLayout(text, tv.getPaint(), cap,
|
||||
Layout.Alignment.ALIGN_NORMAL, 1, 0, true);
|
||||
float max = 0;
|
||||
for (int i = 0; i < l.getLineCount(); i++) {
|
||||
max = Math.max(max, l.getLineWidth(i));
|
||||
}
|
||||
|
||||
/*
|
||||
* Now set the popup size to be big enough for the text plus the border.
|
||||
*/
|
||||
pop.setWidth(width);
|
||||
pop.setHeight(ht + l.getHeight());
|
||||
return l.getHeight();
|
||||
}
|
||||
|
||||
private void show(int offx, int offy) {
|
||||
int textHeight = chooseSize(window, inputView, text, textView);
|
||||
offy -= textView.getPaddingTop() + textHeight;
|
||||
if (inputView.getVisibility() == View.VISIBLE
|
||||
&& inputView.getWindowVisibility() == View.VISIBLE) {
|
||||
try {
|
||||
if ((gravity & Gravity.BOTTOM) == Gravity.BOTTOM) offy -= window.getHeight();
|
||||
if ((gravity & Gravity.RIGHT) == Gravity.RIGHT) offx -= window.getWidth();
|
||||
textView.setOnTouchListener(new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View view, MotionEvent me) {
|
||||
Tutorial.this.next();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
window.showAtLocation(inputView, Gravity.NO_GRAVITY, x + offx, y + offy);
|
||||
} catch (Exception e) {
|
||||
// Input view is not valid
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void hide() {
|
||||
if (window.isShowing()) {
|
||||
textView.setOnTouchListener(null);
|
||||
window.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isShowing() {
|
||||
return window.isShowing();
|
||||
}
|
||||
}
|
||||
|
||||
public Tutorial(TutorialListener listener, KeyboardSwitcher keyboardSwitcher) {
|
||||
mListener = listener;
|
||||
mKeyboardSwitcher = keyboardSwitcher;
|
||||
LatinKeyboardView inputView = keyboardSwitcher.getInputView();
|
||||
mInputView = inputView;
|
||||
Context context = inputView.getContext();
|
||||
int inputWidth = inputView.getWidth();
|
||||
final int x = inputWidth / 20; // Half of 1/10th
|
||||
ArrayList<Bubble> bubbles = mBubbles;
|
||||
Bubble bWelcome = new Bubble(context, inputView,
|
||||
R.drawable.dialog_bubble_step02, x, 0,
|
||||
R.string.tip_to_open_keyboard, R.string.touch_to_continue);
|
||||
bubbles.add(bWelcome);
|
||||
Bubble bAccents = new Bubble(context, inputView,
|
||||
R.drawable.dialog_bubble_step02, x, 0,
|
||||
R.string.tip_to_view_accents, R.string.touch_to_continue);
|
||||
bubbles.add(bAccents);
|
||||
Bubble b123 = new Bubble(context, inputView,
|
||||
R.drawable.dialog_bubble_step07, x, 0,
|
||||
R.string.tip_to_open_symbols, R.string.touch_to_continue);
|
||||
bubbles.add(b123);
|
||||
Bubble bABC = new Bubble(context, inputView,
|
||||
R.drawable.dialog_bubble_step07, x, 0,
|
||||
R.string.tip_to_close_symbols, R.string.touch_to_continue);
|
||||
bubbles.add(bABC);
|
||||
Bubble bSettings = new Bubble(context, inputView,
|
||||
R.drawable.dialog_bubble_step07, x, 0,
|
||||
R.string.tip_to_launch_settings, R.string.touch_to_continue);
|
||||
bubbles.add(bSettings);
|
||||
Bubble bDone = new Bubble(context, inputView,
|
||||
R.drawable.dialog_bubble_step02, x, 0,
|
||||
R.string.tip_to_start_typing, R.string.touch_to_finish);
|
||||
bubbles.add(bDone);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
mInputView.getLocationInWindow(mLocation);
|
||||
mBubbleIndex = -1;
|
||||
mInputView.setOnTouchListener(this);
|
||||
next();
|
||||
}
|
||||
|
||||
private void next() {
|
||||
if (mBubbleIndex >= 0) {
|
||||
// If the bubble is not yet showing, don't move to the next.
|
||||
if (!mBubbles.get(mBubbleIndex).isShowing()) {
|
||||
return;
|
||||
}
|
||||
// Hide all previous bubbles as well, as they may have had a delayed show
|
||||
for (int i = 0; i <= mBubbleIndex; i++) {
|
||||
mBubbles.get(i).hide();
|
||||
}
|
||||
}
|
||||
mBubbleIndex++;
|
||||
if (mBubbleIndex >= mBubbles.size()) {
|
||||
mInputView.setOnTouchListener(null);
|
||||
mListener.onTutorialDone();
|
||||
return;
|
||||
}
|
||||
if (mBubbleIndex == 3 || mBubbleIndex == 4) {
|
||||
mKeyboardSwitcher.changeKeyboardMode();
|
||||
}
|
||||
mHandler.sendMessageDelayed(
|
||||
mHandler.obtainMessage(MSG_SHOW_BUBBLE, mBubbles.get(mBubbleIndex)), 500);
|
||||
return;
|
||||
}
|
||||
|
||||
private void hide() {
|
||||
for (Bubble bubble : mBubbles) {
|
||||
bubble.hide();
|
||||
}
|
||||
mInputView.setOnTouchListener(null);
|
||||
}
|
||||
|
||||
public boolean close() {
|
||||
mHandler.removeMessages(MSG_SHOW_BUBBLE);
|
||||
hide();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
next();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -108,25 +108,25 @@ public class UserBigramDictionary extends ExpandableDictionary {
|
|||
private static DatabaseHelper sOpenHelper = null;
|
||||
|
||||
private static class Bigram {
|
||||
String word1;
|
||||
String word2;
|
||||
int frequency;
|
||||
public final String mWord1;
|
||||
public final String mWord2;
|
||||
public final int frequency;
|
||||
|
||||
Bigram(String word1, String word2, int frequency) {
|
||||
this.word1 = word1;
|
||||
this.word2 = word2;
|
||||
this.mWord1 = word1;
|
||||
this.mWord2 = word2;
|
||||
this.frequency = frequency;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object bigram) {
|
||||
Bigram bigram2 = (Bigram) bigram;
|
||||
return (word1.equals(bigram2.word1) && word2.equals(bigram2.word2));
|
||||
return (mWord1.equals(bigram2.mWord1) && mWord2.equals(bigram2.mWord2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (word1 + " " + word2).hashCode();
|
||||
return (mWord1 + " " + mWord2).hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -357,7 +357,7 @@ public class UserBigramDictionary extends ExpandableDictionary {
|
|||
Cursor c = db.query(MAIN_TABLE_NAME, new String[] { MAIN_COLUMN_ID },
|
||||
MAIN_COLUMN_WORD1 + "=? AND " + MAIN_COLUMN_WORD2 + "=? AND "
|
||||
+ MAIN_COLUMN_LOCALE + "=?",
|
||||
new String[] { bi.word1, bi.word2, mLocale }, null, null, null);
|
||||
new String[] { bi.mWord1, bi.mWord2, mLocale }, null, null, null);
|
||||
|
||||
int pairId;
|
||||
if (c.moveToFirst()) {
|
||||
|
@ -368,7 +368,7 @@ public class UserBigramDictionary extends ExpandableDictionary {
|
|||
} else {
|
||||
// new pair
|
||||
Long pairIdLong = db.insert(MAIN_TABLE_NAME, null,
|
||||
getContentValues(bi.word1, bi.word2, mLocale));
|
||||
getContentValues(bi.mWord1, bi.mWord2, mLocale));
|
||||
pairId = pairIdLong.intValue();
|
||||
}
|
||||
c.close();
|
||||
|
|
|
@ -66,7 +66,7 @@ public class UserDictionary extends ExpandableDictionary {
|
|||
@Override
|
||||
public void loadDictionaryAsync() {
|
||||
Cursor cursor = getContext().getContentResolver()
|
||||
.query(Words.CONTENT_URI, PROJECTION, "(locale IS NULL) or (locale=?)",
|
||||
.query(Words.CONTENT_URI, PROJECTION, "(locale IS NULL) or (locale=?)",
|
||||
new String[] { mLocale }, null);
|
||||
addWords(cursor);
|
||||
}
|
||||
|
|
|
@ -110,6 +110,7 @@ public class Utils {
|
|||
private int[] mYBuf = new int[BUFSIZE];
|
||||
|
||||
private RingCharBuffer() {
|
||||
// Intentional empty constructor for singleton.
|
||||
}
|
||||
public static RingCharBuffer getInstance() {
|
||||
return sRingCharBuffer;
|
||||
|
@ -349,6 +350,7 @@ public class Utils {
|
|||
try {
|
||||
br.close();
|
||||
} catch (IOException e) {
|
||||
// ignore.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,8 +16,7 @@
|
|||
|
||||
package com.android.inputmethod.voice;
|
||||
|
||||
import com.android.inputmethod.keyboard.KeyboardSwitcher;
|
||||
import com.android.inputmethod.latin.EditingUtil;
|
||||
import com.android.inputmethod.latin.EditingUtils;
|
||||
import com.android.inputmethod.latin.LatinIME;
|
||||
import com.android.inputmethod.latin.LatinIME.UIHandler;
|
||||
import com.android.inputmethod.latin.R;
|
||||
|
@ -133,6 +132,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
|
|||
}
|
||||
|
||||
private VoiceIMEConnector() {
|
||||
// Intentional empty constructor for singleton.
|
||||
}
|
||||
|
||||
public void resetVoiceStates(boolean isPasswordText) {
|
||||
|
@ -228,7 +228,8 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
|
|||
}
|
||||
|
||||
private static class CustomLinkMovementMethod extends LinkMovementMethod {
|
||||
private static CustomLinkMovementMethod sInstance = new CustomLinkMovementMethod();
|
||||
private static CustomLinkMovementMethod sLinkMovementMethodInstance =
|
||||
new CustomLinkMovementMethod();
|
||||
private AlertDialog mAlertDialog;
|
||||
|
||||
public void setVoiceWarningDialog(AlertDialog alertDialog) {
|
||||
|
@ -236,7 +237,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
|
|||
}
|
||||
|
||||
public static CustomLinkMovementMethod getInstance() {
|
||||
return sInstance;
|
||||
return sLinkMovementMethodInstance;
|
||||
}
|
||||
|
||||
// Almost the same as LinkMovementMethod.onTouchEvent(), but overrides it for
|
||||
|
@ -391,9 +392,8 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
|
|||
public void rememberReplacedWord(CharSequence suggestion,String wordSeparators) {
|
||||
if (mShowingVoiceSuggestions) {
|
||||
// Retain the replaced word in the alternatives array.
|
||||
EditingUtil.Range range = new EditingUtil.Range();
|
||||
String wordToBeReplaced = EditingUtil.getWordAtCursor(
|
||||
mContext.getCurrentInputConnection(), wordSeparators, range);
|
||||
String wordToBeReplaced = EditingUtils.getWordAtCursor(
|
||||
mContext.getCurrentInputConnection(), wordSeparators);
|
||||
if (!mWordToSuggestions.containsKey(wordToBeReplaced)) {
|
||||
wordToBeReplaced = wordToBeReplaced.toLowerCase();
|
||||
}
|
||||
|
@ -415,9 +415,9 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
|
|||
* @param touching The word that the cursor is touching, with position information
|
||||
* @return true if an alternative was found, false otherwise.
|
||||
*/
|
||||
public boolean applyVoiceAlternatives(EditingUtil.SelectedWord touching) {
|
||||
public boolean applyVoiceAlternatives(EditingUtils.SelectedWord touching) {
|
||||
// Search for result in spoken word alternatives
|
||||
String selectedWord = touching.word.toString().trim();
|
||||
String selectedWord = touching.mWord.toString().trim();
|
||||
if (!mWordToSuggestions.containsKey(selectedWord)) {
|
||||
selectedWord = selectedWord.toLowerCase();
|
||||
}
|
||||
|
@ -426,7 +426,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
|
|||
List<CharSequence> suggestions = mWordToSuggestions.get(selectedWord);
|
||||
// If the first letter of touching is capitalized, make all the suggestions
|
||||
// start with a capital letter.
|
||||
if (Character.isUpperCase(touching.word.charAt(0))) {
|
||||
if (Character.isUpperCase(touching.mWord.charAt(0))) {
|
||||
for (int i = 0; i < suggestions.size(); i++) {
|
||||
String origSugg = (String) suggestions.get(i);
|
||||
String capsSugg = origSugg.toUpperCase().charAt(0)
|
||||
|
@ -478,7 +478,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
|
|||
}
|
||||
|
||||
|
||||
public void handleVoiceResults(KeyboardSwitcher switcher, boolean capitalizeFirstWord) {
|
||||
public void handleVoiceResults(boolean capitalizeFirstWord) {
|
||||
mAfterVoiceInput = true;
|
||||
mImmediatelyAfterVoiceInput = true;
|
||||
|
||||
|
@ -508,7 +508,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
|
|||
|
||||
if (ic != null) ic.beginBatchEdit(); // To avoid extra updates on committing older text
|
||||
mContext.commitTyped(ic);
|
||||
EditingUtil.appendText(ic, bestResult);
|
||||
EditingUtils.appendText(ic, bestResult);
|
||||
if (ic != null) ic.endBatchEdit();
|
||||
|
||||
mVoiceInputHighlighted = true;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
package com.android.inputmethod.voice;
|
||||
|
||||
import com.android.inputmethod.latin.EditingUtil;
|
||||
import com.android.inputmethod.latin.EditingUtils;
|
||||
import com.android.inputmethod.latin.R;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
|
@ -241,7 +241,7 @@ public class VoiceInput implements OnClickListener {
|
|||
}
|
||||
|
||||
public void incrementTextModificationInsertPunctuationCount(int count){
|
||||
mAfterVoiceInputInsertPunctuationCount += 1;
|
||||
mAfterVoiceInputInsertPunctuationCount += count;
|
||||
if (mAfterVoiceInputSelectionSpan > 0) {
|
||||
// If text was highlighted before inserting the char, count this as
|
||||
// a delete.
|
||||
|
@ -429,8 +429,7 @@ public class VoiceInput implements OnClickListener {
|
|||
|
||||
public void logTextModifiedByChooseSuggestion(String suggestion, int index,
|
||||
String wordSeparators, InputConnection ic) {
|
||||
EditingUtil.Range range = new EditingUtil.Range();
|
||||
String wordToBeReplaced = EditingUtil.getWordAtCursor(ic, wordSeparators, range);
|
||||
String wordToBeReplaced = EditingUtils.getWordAtCursor(ic, wordSeparators);
|
||||
// If we enable phrase-based alternatives, only send up the first word
|
||||
// in suggestion and wordToBeReplaced.
|
||||
mLogger.textModifiedByChooseSuggestion(suggestion.length(), wordToBeReplaced.length(),
|
||||
|
@ -578,7 +577,9 @@ public class VoiceInput implements OnClickListener {
|
|||
public void onBufferReceived(byte[] buf) {
|
||||
try {
|
||||
mWaveBuffer.write(buf);
|
||||
} catch (IOException e) {}
|
||||
} catch (IOException e) {
|
||||
// ignore.
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -33,7 +33,9 @@ import java.nio.ShortBuffer;
|
|||
public class WaveformImage {
|
||||
private static final int SAMPLING_RATE = 8000;
|
||||
|
||||
private WaveformImage() {}
|
||||
private WaveformImage() {
|
||||
// Intentional empty constructor.
|
||||
}
|
||||
|
||||
public static Bitmap drawWaveform(
|
||||
ByteArrayOutputStream waveBuffer, int w, int h, int start, int end) {
|
||||
|
|
|
@ -116,13 +116,6 @@ public class SuggestHelper {
|
|||
return word;
|
||||
}
|
||||
|
||||
private void showList(String title, List<CharSequence> suggestions) {
|
||||
Log.i(TAG, title);
|
||||
for (int i = 0; i < suggestions.size(); i++) {
|
||||
Log.i(title, suggestions.get(i) + ", ");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isDefaultSuggestion(List<CharSequence> suggestions, CharSequence word) {
|
||||
// Check if either the word is what you typed or the first alternative
|
||||
return suggestions.size() > 0 &&
|
||||
|
@ -191,8 +184,6 @@ public class SuggestHelper {
|
|||
|
||||
boolean isUserBigramSuggestion(CharSequence previous, char typed,
|
||||
CharSequence expected) {
|
||||
WordComposer word = createWordComposer(Character.toString(typed));
|
||||
|
||||
if (mUserBigram == null) return false;
|
||||
|
||||
flushUserBigrams();
|
||||
|
|
Loading…
Reference in New Issue