aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod/latin
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android/inputmethod/latin')
-rw-r--r--java/src/com/android/inputmethod/latin/Constants.java2
-rw-r--r--java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java2
-rw-r--r--java/src/com/android/inputmethod/latin/InputTypeUtils.java1
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java3
-rw-r--r--java/src/com/android/inputmethod/latin/RichInputConnection.java12
-rw-r--r--java/src/com/android/inputmethod/latin/SettingsFragment.java9
-rw-r--r--java/src/com/android/inputmethod/latin/StringUtils.java65
-rw-r--r--java/src/com/android/inputmethod/latin/SubtypeSwitcher.java10
-rw-r--r--java/src/com/android/inputmethod/latin/setup/SetupActivity.java13
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java8
10 files changed, 104 insertions, 21 deletions
diff --git a/java/src/com/android/inputmethod/latin/Constants.java b/java/src/com/android/inputmethod/latin/Constants.java
index 50e50233e..86bb25562 100644
--- a/java/src/com/android/inputmethod/latin/Constants.java
+++ b/java/src/com/android/inputmethod/latin/Constants.java
@@ -160,6 +160,8 @@ public final class Constants {
public static final int CODE_DOUBLE_QUOTE = '"';
public static final int CODE_QUESTION_MARK = '?';
public static final int CODE_EXCLAMATION_MARK = '!';
+ public static final int CODE_SLASH = '/';
+ public static final int CODE_COMMERCIAL_AT = '@';
// TODO: Check how this should work for right-to-left languages. It seems to stand
// that for rtl languages, a closing parenthesis is a left parenthesis. Is this
// managed by the font? Or is it a different char?
diff --git a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
index 22d189987..75c2cf2c8 100644
--- a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
@@ -252,7 +252,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
}
private static boolean isValidName(final String name) {
- if (name != null && -1 == name.indexOf('@')) {
+ if (name != null && -1 == name.indexOf(Constants.CODE_COMMERCIAL_AT)) {
return true;
}
return false;
diff --git a/java/src/com/android/inputmethod/latin/InputTypeUtils.java b/java/src/com/android/inputmethod/latin/InputTypeUtils.java
index ecb20144b..46194f6e4 100644
--- a/java/src/com/android/inputmethod/latin/InputTypeUtils.java
+++ b/java/src/com/android/inputmethod/latin/InputTypeUtils.java
@@ -33,7 +33,6 @@ public final class InputTypeUtils implements InputType {
private static final int[] SUPPRESSING_AUTO_SPACES_FIELD_VARIATION = {
InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS,
InputType.TYPE_TEXT_VARIATION_PASSWORD,
- InputType.TYPE_TEXT_VARIATION_URI,
InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD,
InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD };
public static final int IME_ACTION_CUSTOM_LABEL = EditorInfo.IME_MASK_ACTION + 1;
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 0a6f2ab00..0e1c4dc31 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -2559,7 +2559,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// This essentially inserts a space, and that's it.
public void promotePhantomSpace() {
- if (mSettings.getCurrent().shouldInsertSpacesAutomatically()) {
+ if (mSettings.getCurrent().shouldInsertSpacesAutomatically()
+ && !mConnection.textBeforeCursorLooksLikeURL()) {
sendKeyCodePoint(Constants.CODE_SPACE);
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
ResearchLogger.latinIME_promotePhantomSpace();
diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java
index e17846618..8ed7ab264 100644
--- a/java/src/com/android/inputmethod/latin/RichInputConnection.java
+++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java
@@ -19,7 +19,6 @@ package com.android.inputmethod.latin;
import android.inputmethodservice.InputMethodService;
import android.text.SpannableString;
import android.text.TextUtils;
-import android.text.style.SuggestionSpan;
import android.util.Log;
import android.view.KeyEvent;
import android.view.inputmethod.CompletionInfo;
@@ -721,4 +720,15 @@ public final class RichInputConnection {
// position and the expected position, then it must be a belated update.
return (newSelStart - oldSelStart) * (mCurrentCursorPosition - newSelStart) >= 0;
}
+
+ /**
+ * Looks at the text just before the cursor to find out if it looks like a URL.
+ *
+ * The weakest point here is, if we don't have enough text bufferized, we may fail to realize
+ * we are in URL situation, but other places in this class have the same limitation and it
+ * does not matter too much in the practice.
+ */
+ public boolean textBeforeCursorLooksLikeURL() {
+ return StringUtils.lastPartLooksLikeURL(mCommittedTextBeforeComposingText);
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/SettingsFragment.java b/java/src/com/android/inputmethod/latin/SettingsFragment.java
index a96c997c8..79036c276 100644
--- a/java/src/com/android/inputmethod/latin/SettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/SettingsFragment.java
@@ -77,10 +77,13 @@ public final class SettingsFragment extends InputMethodSettingsFragment
final Resources res = getResources();
final Context context = getActivity();
- // When we are called from the Settings application but we are not already running, the
- // {@link SubtypeLocale} class may not have been initialized. It is safe to call
- // {@link SubtypeLocale#init(Context)} multiple times.
+ // When we are called from the Settings application but we are not already running, some
+ // singleton and utility classes may not have been initialized. We have to call
+ // initialization method of these classes here. See {@link LatinIME#onCreate()}.
+ SubtypeSwitcher.init(context);
SubtypeLocale.init(context);
+ AudioAndHapticFeedbackManager.init(context);
+
mVoicePreference = (ListPreference) findPreference(Settings.PREF_VOICE_MODE);
mShowCorrectionSuggestionsPreference =
(ListPreference) findPreference(Settings.PREF_SHOW_SUGGESTIONS_SETTING);
diff --git a/java/src/com/android/inputmethod/latin/StringUtils.java b/java/src/com/android/inputmethod/latin/StringUtils.java
index 7f1e7c619..d5ee58a63 100644
--- a/java/src/com/android/inputmethod/latin/StringUtils.java
+++ b/java/src/com/android/inputmethod/latin/StringUtils.java
@@ -282,4 +282,69 @@ public final class StringUtils {
}
return builder.toString();
}
+
+ /**
+ * Approximates whether the text before the cursor looks like a URL.
+ *
+ * This is not foolproof, but it should work well in the practice.
+ * Essentially it walks backward from the cursor until it finds something that's not a letter,
+ * digit, or common URL symbol like underscore. If it hasn't found a period yet, then it
+ * does not look like a URL.
+ * If the text:
+ * - starts with www and contains a period
+ * - starts with a slash preceded by either a slash, whitespace, or start-of-string
+ * Then it looks like a URL and we return true. Otherwise, we return false.
+ *
+ * Note: this method is called quite often, and should be fast.
+ *
+ * TODO: This will return that "abc./def" and ".abc/def" look like URLs to keep down the
+ * code complexity, but ideally it should not. It's acceptable for now.
+ */
+ public static boolean lastPartLooksLikeURL(final CharSequence text) {
+ int i = text.length();
+ if (0 == i) return false;
+ int wCount = 0;
+ int slashCount = 0;
+ boolean hasSlash = false;
+ boolean hasPeriod = false;
+ int codePoint = 0;
+ while (i > 0) {
+ codePoint = Character.codePointBefore(text, i);
+ if (codePoint < Constants.CODE_PERIOD || codePoint > 'z') {
+ // Handwavy heuristic to see if that's a URL character. Anything between period
+ // and z. This includes all lower- and upper-case ascii letters, period,
+ // underscore, arrobase, question mark, equal sign. It excludes spaces, exclamation
+ // marks, double quotes...
+ // Anything that's not a URL-like character causes us to break from here and
+ // evaluate normally.
+ break;
+ }
+ if (Constants.CODE_PERIOD == codePoint) {
+ hasPeriod = true;
+ }
+ if (Constants.CODE_SLASH == codePoint) {
+ hasSlash = true;
+ if (2 == ++slashCount) {
+ return true;
+ }
+ } else {
+ slashCount = 0;
+ }
+ if ('w' == codePoint) {
+ ++wCount;
+ } else {
+ wCount = 0;
+ }
+ i = Character.offsetByCodePoints(text, i, -1);
+ }
+ // End of the text run.
+ // If it starts with www and includes a period, then it looks like a URL.
+ if (wCount >= 3 && hasPeriod) return true;
+ // If it starts with a slash, and the code point before is whitespace, it looks like an URL.
+ if (1 == slashCount && (0 == i || Character.isWhitespace(codePoint))) return true;
+ // If it has both a period and a slash, it looks like an URL.
+ if (hasPeriod && hasSlash) return true;
+ // Otherwise, it doesn't look like an URL.
+ return false;
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
index 2f9e34ff1..bef8a3cf1 100644
--- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
+++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
@@ -80,6 +80,7 @@ public final class SubtypeSwitcher {
public static void init(final Context context) {
SubtypeLocale.init(context);
+ RichInputMethodManager.init(context);
sInstance.initialize(context);
}
@@ -87,10 +88,13 @@ public final class SubtypeSwitcher {
// Intentional empty constructor for singleton.
}
- private void initialize(final Context service) {
- mResources = service.getResources();
+ private void initialize(final Context context) {
+ if (mResources != null) {
+ return;
+ }
+ mResources = context.getResources();
mRichImm = RichInputMethodManager.getInstance();
- mConnectivityManager = (ConnectivityManager) service.getSystemService(
+ mConnectivityManager = (ConnectivityManager) context.getSystemService(
Context.CONNECTIVITY_SERVICE);
mNoLanguageSubtype = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
SubtypeLocale.NO_LANGUAGE, SubtypeLocale.QWERTY);
diff --git a/java/src/com/android/inputmethod/latin/setup/SetupActivity.java b/java/src/com/android/inputmethod/latin/setup/SetupActivity.java
index 15d0bac37..099169aa9 100644
--- a/java/src/com/android/inputmethod/latin/setup/SetupActivity.java
+++ b/java/src/com/android/inputmethod/latin/setup/SetupActivity.java
@@ -20,7 +20,6 @@ import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
-import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Message;
@@ -113,13 +112,13 @@ public final class SetupActivity extends Activity {
// the SDK version.
final TextView titleView = (TextView)findViewById(R.id.setup_title);
final int appName = getApplicationInfo().labelRes;
- titleView.setText(getString(R.string.setup_title, getString(appName)));
+ titleView.setText(getString(R.string.setup_steps_title, getString(appName)));
mStepIndicatorView = (SetupStepIndicatorView)findViewById(R.id.setup_step_indicator);
final SetupStep step1 = new SetupStep(findViewById(R.id.setup_step1),
appName, R.string.setup_step1_title, R.string.setup_step1_instruction,
- R.drawable.ic_settings_language, R.string.language_settings);
+ R.drawable.ic_setup_step1, R.string.setup_step1_action);
step1.setAction(new Runnable() {
@Override
public void run() {
@@ -131,7 +130,7 @@ public final class SetupActivity extends Activity {
final SetupStep step2 = new SetupStep(findViewById(R.id.setup_step2),
appName, R.string.setup_step2_title, R.string.setup_step2_instruction,
- 0 /* actionIcon */, R.string.select_input_method);
+ R.drawable.ic_setup_step2, R.string.setup_step2_action);
step2.setAction(new Runnable() {
@Override
public void run() {
@@ -143,8 +142,8 @@ public final class SetupActivity extends Activity {
mSetupSteps.addStep(STEP_2, step2);
final SetupStep step3 = new SetupStep(findViewById(R.id.setup_step3),
- appName, R.string.setup_step3_title, 0 /* instruction */,
- R.drawable.sym_keyboard_language_switch, R.string.setup_step3_instruction);
+ appName, R.string.setup_step3_title, R.string.setup_step3_instruction,
+ R.drawable.ic_setup_step3, R.string.setup_step3_action);
step3.setAction(new Runnable() {
@Override
public void run() {
@@ -314,9 +313,7 @@ public final class SetupActivity extends Activity {
final int paddingEnd = ViewCompatUtils.getPaddingEnd(mActionLabel);
ViewCompatUtils.setPaddingRelative(mActionLabel, paddingEnd, 0, paddingEnd, 0);
} else {
- final int overrideColor = res.getColor(R.color.setup_text_action);
final Drawable icon = res.getDrawable(actionIcon);
- icon.setColorFilter(overrideColor, PorterDuff.Mode.MULTIPLY);
icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight());
TextViewCompatUtils.setCompoundDrawablesRelative(
mActionLabel, icon, null, null, null);
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
index 96b2c818d..da8657201 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
@@ -189,10 +189,12 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
int letterCount = 0;
for (int i = 0; i < length; i = text.offsetByCodePoints(i, 1)) {
final int codePoint = text.codePointAt(i);
- // Any word containing a '@' is probably an e-mail address
- // Any word containing a '/' is probably either an ad-hoc combination of two
+ // Any word containing a COMMERCIAL_AT is probably an e-mail address
+ // Any word containing a SLASH is probably either an ad-hoc combination of two
// words or a URI - in either case we don't want to spell check that
- if ('@' == codePoint || '/' == codePoint) return true;
+ if (Constants.CODE_COMMERCIAL_AT == codePoint || Constants.CODE_SLASH == codePoint) {
+ return true;
+ }
if (isLetterCheckableByLanguage(codePoint, script)) ++letterCount;
}
// Guestimate heuristic: perform spell checking if at least 3/4 of the characters