-
-
Notifications
You must be signed in to change notification settings - Fork 112
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(android): Add controls for auto-correct #12443
Changes from 2 commits
4927922
9096105
a6f9082
cc2bc23
6eba88c
39f2d3e
ad7bf1f
15993ff
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,9 +16,13 @@ | |
import android.widget.ImageButton; | ||
import android.widget.ImageView; | ||
import android.widget.ListView; | ||
import android.widget.RadioButton; | ||
import android.widget.RadioGroup; | ||
import android.widget.RadioGroup.OnCheckedChangeListener; | ||
import android.widget.RelativeLayout; | ||
import android.widget.TextView; | ||
|
||
import androidx.annotation.IdRes; | ||
import androidx.annotation.NonNull; | ||
import androidx.appcompat.app.AlertDialog; | ||
import androidx.appcompat.app.AppCompatActivity; | ||
|
@@ -55,50 +59,6 @@ public final class LanguageSettingsActivity extends AppCompatActivity { | |
|
||
private final static String TAG = "LanguageSettingsAct"; | ||
|
||
private class PreferenceToggleListener implements View.OnClickListener { | ||
String prefsKey; | ||
String lgCode; | ||
|
||
public PreferenceToggleListener(String prefsKey, String lgCode) { | ||
this.prefsKey = prefsKey; | ||
this.lgCode = lgCode; | ||
} | ||
|
||
@Override | ||
public void onClick(View v) { | ||
// For predictions/corrections toggle | ||
SwitchCompat toggle = (SwitchCompat) v; | ||
|
||
SharedPreferences.Editor prefEditor = prefs.edit(); | ||
|
||
// predictionsToggle overrides correctionToggle and correctionsTextView | ||
if (prefsKey.endsWith(KMManager.predictionPrefSuffix)) { | ||
boolean override = toggle.isChecked(); | ||
overrideCorrectionsToggle(override); | ||
} | ||
|
||
// This will allow preemptively making settings for languages without models. | ||
// Seems more trouble than it's worth to block this. | ||
prefEditor.putBoolean(prefsKey, toggle.isChecked()); | ||
prefEditor.apply(); | ||
|
||
// Don't use/apply language modeling settings for languages without models. | ||
if (associatedLexicalModel.isEmpty()) { | ||
return; | ||
} | ||
|
||
Keyboard kbInfo = KMManager.getCurrentKeyboardInfo(context); | ||
if(kbInfo != null) { | ||
// If the active keyboard is for this language, immediately enact the new pref setting. | ||
String kbdLgCode = kbInfo.getLanguageID(); | ||
if (kbdLgCode.equals(lgCode)) { | ||
// Not only registers the model but also applies our modeling preferences. | ||
KMManager.registerAssociatedLexicalModel(lgCode); | ||
} | ||
} | ||
} | ||
} | ||
|
||
@Override | ||
public void onCreate(Bundle savedInstanceState) { | ||
super.onCreate(savedInstanceState); | ||
|
@@ -139,33 +99,59 @@ public void onCreate(Bundle savedInstanceState) { | |
|
||
FilteredKeyboardsAdapter adapter = new FilteredKeyboardsAdapter(context, KeyboardPickerActivity.getInstalledDataset(context), lgCode); | ||
|
||
// The following two layouts/toggles will need to link with these objects. | ||
// The following radio group will need to link with these objects. | ||
Context appContext = this.getApplicationContext(); | ||
prefs = appContext.getSharedPreferences(appContext.getString(R.string.kma_prefs_name), Context.MODE_PRIVATE); | ||
boolean mayPredict = prefs.getBoolean(KMManager.getLanguagePredictionPreferenceKey(lgCode), true); | ||
boolean mayCorrect = prefs.getBoolean(KMManager.getLanguageCorrectionPreferenceKey(lgCode), true); | ||
|
||
RelativeLayout layout = (RelativeLayout)findViewById(R.id.corrections_toggle); | ||
int maySuggest = prefs.getInt(KMManager.getLanguageAutoCorrectionPreferenceKey(lgCode), KMManager.KMDefault_Suggestion); | ||
|
||
// Radio button change listeners | ||
RadioGroup radioGroup = (RadioGroup) findViewById(R.id.suggestion_radio_group); | ||
RadioButton radioButton; | ||
// Initialize radio button group | ||
switch(maySuggest) { | ||
case 1: | ||
radioButton = (RadioButton) radioGroup.findViewById(R.id.suggestion_radio_1); | ||
break; | ||
case 2: | ||
radioButton = (RadioButton) radioGroup.findViewById(R.id.suggestion_radio_2); | ||
break; | ||
case 3: | ||
radioButton = (RadioButton) radioGroup.findViewById(R.id.suggestion_radio_3); | ||
break; | ||
case 0: | ||
default: | ||
radioButton = (RadioButton) radioGroup.findViewById(R.id.suggestion_radio_0); | ||
} | ||
radioGroup.clearCheck(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This would be neater with an array but it's not critical. |
||
radioButton.setChecked(true); | ||
|
||
correctionsTextView = (TextView) layout.findViewById(R.id.text1); | ||
correctionsTextView.setText(getString(R.string.enable_corrections)); | ||
correctionsToggle = layout.findViewById(R.id.toggle); | ||
correctionsToggle.setChecked(mayCorrect); // Link to persistent option storage! Also needs handler. | ||
String prefsKey = KMManager.getLanguageCorrectionPreferenceKey(lgCode); | ||
correctionsToggle.setOnClickListener(new PreferenceToggleListener(prefsKey, lgCode)); | ||
radioGroup.setOnCheckedChangeListener(new OnCheckedChangeListener() { | ||
@Override | ||
public void onCheckedChanged(RadioGroup group, @IdRes int checkId) { | ||
RadioButton checkedButton = (RadioButton)radioGroup.findViewById(checkId); | ||
int index = radioGroup.indexOfChild(checkedButton); | ||
int radioButtonID = radioGroup.getCheckedRadioButtonId(); | ||
|
||
layout = (RelativeLayout)findViewById(R.id.predictions_toggle); | ||
KMManager.setMaySuggest(lgCode, index); | ||
|
||
textView = (TextView) layout.findViewById(R.id.text1); | ||
textView.setText(getString(R.string.enable_predictions)); | ||
SwitchCompat predictionsToggle = layout.findViewById(R.id.toggle); | ||
predictionsToggle.setChecked(mayPredict); // Link to persistent option storage! Also needs handler. | ||
prefsKey = KMManager.getLanguagePredictionPreferenceKey(lgCode); | ||
predictionsToggle.setOnClickListener(new PreferenceToggleListener(prefsKey, lgCode)); | ||
// Don't use/apply language modeling settings for languages without models. | ||
if (associatedLexicalModel.isEmpty()) { | ||
return; | ||
} | ||
|
||
overrideCorrectionsToggle(mayPredict); | ||
Keyboard kbInfo = KMManager.getCurrentKeyboardInfo(context); | ||
if(kbInfo != null) { | ||
// If the active keyboard is for this language, immediately enact the new pref setting. | ||
String kbdLgCode = kbInfo.getLanguageID(); | ||
if (kbdLgCode.equals(lgCode)) { | ||
// Not only registers the model but also applies our modeling preferences. | ||
KMManager.registerAssociatedLexicalModel(lgCode); | ||
} | ||
} | ||
} | ||
}); | ||
|
||
layout = (RelativeLayout)findViewById(R.id.model_picker); | ||
RelativeLayout layout = (RelativeLayout)findViewById(R.id.model_picker); | ||
textView = (TextView) layout.findViewById(R.id.text1); | ||
textView.setText(getString(R.string.model_label)); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -192,6 +192,36 @@ public enum EnterModeType { | |
DEFAULT, // Default ENTER action | ||
} | ||
|
||
// Enum for whether the suggestion banner allows predictions, corrections, auto-corrections | ||
public enum SuggestionType { | ||
// Suggestion Disabled - No Predictions, No corrections, No auto-corrections | ||
SUGGESTIONS_DISABLED, | ||
|
||
// Suggestions Enabled | ||
PREDICTIONS_ONLY, // Predictions with no corrections | ||
PREDICTIONS_WITH_CORRECTIONS, // Predictions with corrections | ||
PREDICTIONS_WITH_AUTO_CORRECT; // Predictions with auto-corrections | ||
|
||
public static SuggestionType fromInt(int mode) { | ||
switch (mode) { | ||
case 0: | ||
return SUGGESTIONS_DISABLED; | ||
case 1: | ||
return PREDICTIONS_ONLY; | ||
case 2: | ||
return PREDICTIONS_WITH_CORRECTIONS; | ||
case 3: | ||
return PREDICTIONS_WITH_AUTO_CORRECT; | ||
} | ||
return SUGGESTIONS_DISABLED; | ||
} | ||
|
||
public int toInt() { | ||
int modes[] = { 0, 1, 2, 3 }; | ||
return modes[this.ordinal()]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not just |
||
} | ||
} | ||
|
||
protected static InputMethodService IMService; | ||
|
||
private static boolean debugMode = false; | ||
|
@@ -220,6 +250,7 @@ public enum EnterModeType { | |
|
||
public final static String predictionPrefSuffix = ".mayPredict"; | ||
public final static String correctionPrefSuffix = ".mayCorrect"; | ||
public final static String autoCorrectionPrefSuffix = ".mayAutoCorect"; | ||
|
||
// Special override for when the keyboard may have haptic feedback when typing. | ||
// haptic feedback disabled for hardware keystrokes | ||
|
@@ -315,6 +346,8 @@ public enum EnterModeType { | |
public static final int KMMinimum_LongpressDelay = 300; | ||
public static final int KMMaximum_LongpressDelay = 1500; | ||
|
||
// Default prediction/correction setting - corresponds to SuggestionType.PREDICTIONS_WITH_CORRECTIONS | ||
public static final int KMDefault_Suggestion = 2; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Still got a magic number here |
||
|
||
// Keyman files | ||
protected static final String KMFilename_KeyboardHtml = "keyboard.html"; | ||
|
@@ -707,6 +740,10 @@ public static String getLanguageCorrectionPreferenceKey(String langID) { | |
return langID + correctionPrefSuffix; | ||
} | ||
|
||
public static String getLanguageAutoCorrectionPreferenceKey(String langID) { | ||
return langID + autoCorrectionPrefSuffix; | ||
} | ||
|
||
public static void hideSystemKeyboard() { | ||
if (SystemKeyboard != null) { | ||
SystemKeyboard.hideKeyboard(); | ||
|
@@ -1350,6 +1387,22 @@ public static boolean getMayPredictOverride() { | |
return mayPredictOverride; | ||
} | ||
|
||
/** | ||
* Maps radio button index 0..3 to SuggestionType and then store as preference | ||
* @param languageID as String | ||
* @param suggestType Radio button index 0 to 3 | ||
*/ | ||
public static void setMaySuggest(String languageID, int suggestType) { | ||
if (suggestType < 0 || suggestType > 3) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we use |
||
// Invalid values go to SUGGESTIONS_DISABLED | ||
suggestType = 0; | ||
} | ||
SharedPreferences prefs = appContext.getSharedPreferences(appContext.getString(R.string.kma_prefs_name), Context.MODE_PRIVATE); | ||
SharedPreferences.Editor editor = prefs.edit(); | ||
editor.putInt(KMManager.getLanguageAutoCorrectionPreferenceKey(languageID), suggestType); | ||
editor.commit(); | ||
} | ||
|
||
/** | ||
* Determines if the InputType field is a numeric field | ||
* @param inputType | ||
|
@@ -1464,22 +1517,22 @@ public static boolean registerLexicalModel(HashMap<String, String> lexicalModelI | |
|
||
// When entering password field, mayPredict should override to false | ||
SharedPreferences prefs = appContext.getSharedPreferences(appContext.getString(R.string.kma_prefs_name), Context.MODE_PRIVATE); | ||
int maySuggest = prefs.getInt(getLanguageAutoCorrectionPreferenceKey(languageID), KMDefault_Suggestion); | ||
boolean mayPredict = (mayPredictOverride) ? false : | ||
prefs.getBoolean(getLanguagePredictionPreferenceKey(languageID), true); | ||
boolean mayCorrect = prefs.getBoolean(getLanguageCorrectionPreferenceKey(languageID), true); | ||
maySuggest > 0; | ||
|
||
RelativeLayout.LayoutParams params; | ||
if (isKeyboardLoaded(KeyboardType.KEYBOARD_TYPE_INAPP) && !InAppKeyboard.shouldIgnoreTextChange() && modelFileExists) { | ||
params = getKeyboardLayoutParams(); | ||
|
||
// Do NOT re-layout here; it'll be triggered once the banner loads. | ||
InAppKeyboard.loadJavascript(KMString.format("enableSuggestions(%s, %s, %s)", model, mayPredict, mayCorrect)); | ||
InAppKeyboard.loadJavascript(KMString.format("enableSuggestions(%s, %s, %d)", model, mayPredict, maySuggest)); | ||
} | ||
if (isKeyboardLoaded(KeyboardType.KEYBOARD_TYPE_SYSTEM) && !SystemKeyboard.shouldIgnoreTextChange() && modelFileExists) { | ||
params = getKeyboardLayoutParams(); | ||
|
||
// Do NOT re-layout here; it'll be triggered once the banner loads. | ||
SystemKeyboard.loadJavascript(KMString.format("enableSuggestions(%s, %s, %s)", model, mayPredict, mayCorrect)); | ||
SystemKeyboard.loadJavascript(KMString.format("enableSuggestions(%s, %s, %d)", model, mayPredict, maySuggest)); | ||
} | ||
return true; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we avoid using a number 0 here and use
SuggestionType.SUGGESTIONS_DISABLED
?