From 1799d618c585adb920e3eaa5790b35465a8f3ac0 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Wed, 28 Jun 2023 21:18:41 +0200 Subject: [PATCH] add words to system personal dictionary --- README.md | 2 + .../latin/DictionaryFacilitatorImpl.java | 47 ++++++++++++++++++- .../settings/CorrectionSettingsFragment.java | 1 + .../inputmethod/latin/settings/Settings.java | 1 + .../latin/settings/SettingsValues.java | 4 ++ app/src/main/res/values/strings.xml | 4 ++ .../main/res/xml/prefs_screen_correction.xml | 7 +++ 7 files changed, 64 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cac0c2ab..7ee869bd 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ Changes: * Allow adjusting keyboard colors, https://github.com/openboard-team/openboard/issues/124 * Remove suggestions by long pressing on suggestion strip while the more suggestions popup is open, https://github.com/openboard-team/openboard/issues/106 * suggestions get re-added if they are entered again +* Optionally add typed words to system personal dictionary Plan / to do: * ~upgrade dependencies~ @@ -47,6 +48,7 @@ Plan / to do: * fix buttons on long-press action key not themed * allow adjusting colors without requiring manual reload of keyboard * ~delete suggestions, https://github.com/openboard-team/openboard/issues/106~ + * make functionality more discoverable, e.g. add a button to the more suggestions menu * ~gesture typing, https://github.com/openboard-team/openboard/issues/3~ * ~license issues, require using an external library~ * re-consider preferring lowercase word for typed history in some cases (DictionaryFacilitatorImpl.addWordToUserHistory) diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/DictionaryFacilitatorImpl.java b/app/src/main/java/org/dslul/openboard/inputmethod/latin/DictionaryFacilitatorImpl.java index 4d06d7aa..c8915d30 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/DictionaryFacilitatorImpl.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/DictionaryFacilitatorImpl.java @@ -18,6 +18,7 @@ package org.dslul.openboard.inputmethod.latin; import android.Manifest; import android.content.Context; +import android.provider.UserDictionary; import android.text.TextUtils; import android.util.Log; import android.util.LruCache; @@ -652,6 +653,8 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { final String[] words = suggestion.split(Constants.WORD_SEPARATOR); // increase / decrease confidence if we have a secondary dictionary group + Boolean validMainWord = null; + Boolean validSecondaryWord = null; if (mSecondaryDictionaryGroup != null && words.length == 1) { // if suggestion was auto-capitalized, check against both the suggestion and the de-capitalized suggestion final String decapitalizedSuggestion; @@ -659,15 +662,55 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { decapitalizedSuggestion = suggestion.substring(0, 1).toLowerCase() + suggestion.substring(1); else decapitalizedSuggestion = suggestion; + validMainWord = isValidWord(suggestion, ALL_DICTIONARY_TYPES, mDictionaryGroup); if ((wasAutoCapitalized && isValidWord(decapitalizedSuggestion, ALL_DICTIONARY_TYPES, mDictionaryGroup)) - || isValidWord(suggestion, ALL_DICTIONARY_TYPES, mDictionaryGroup)) + || validMainWord) mDictionaryGroup.increaseConfidence(); else mDictionaryGroup.decreaseConfidence(); + validSecondaryWord = isValidWord(suggestion, ALL_DICTIONARY_TYPES, mSecondaryDictionaryGroup); if ((wasAutoCapitalized && isValidWord(decapitalizedSuggestion, ALL_DICTIONARY_TYPES, mSecondaryDictionaryGroup)) - || isValidWord(suggestion, ALL_DICTIONARY_TYPES, mSecondaryDictionaryGroup)) + || validSecondaryWord) mSecondaryDictionaryGroup.increaseConfidence(); else mSecondaryDictionaryGroup.decreaseConfidence(); } + + // add word to user dictionary if it is in no other dictionary except user history dictionary + // reasoning: typing the same word again -> we probably want it in some dictionary permanently + // we need a clearly preferred group to assign it to the correct language (in most cases at least...) + if (mDictionaryGroup.hasDict(Dictionary.TYPE_USER_HISTORY, mDictionaryGroup.mAccount) // disable if personalized suggestions are off + && Settings.getInstance().getCurrent().mAddToPersonalDictionary + && (mSecondaryDictionaryGroup == null || mDictionaryGroup.mConfidence != mSecondaryDictionaryGroup.mConfidence) + && !wasAutoCapitalized && words.length == 1) { + // user history always reports words as invalid, so we need to check isInDictionary instead + // also maybe a problem: words added to dictionaries (user and history) are apparently found + // only after some delay. but this is not too bad, it just delays adding + + final DictionaryGroup dictionaryGroup = getCurrentlyPreferredDictionaryGroup(); + final ExpandableBinaryDictionary userDict = dictionaryGroup.getSubDict(Dictionary.TYPE_USER); + final Dictionary userHistoryDict = dictionaryGroup.getSubDict(Dictionary.TYPE_USER_HISTORY); + if (userDict != null && userHistoryDict.isInDictionary(suggestion)) { + if (validMainWord == null) + validMainWord = isValidWord(suggestion, ALL_DICTIONARY_TYPES, mDictionaryGroup); + if (validMainWord) + return; + if (mSecondaryDictionaryGroup != null) { + if (validSecondaryWord == null) + validSecondaryWord = isValidWord(suggestion, ALL_DICTIONARY_TYPES, mSecondaryDictionaryGroup); + if (validSecondaryWord) + return; + } + if (userDict.isInDictionary(suggestion)) + return; + ExecutorUtils.getBackgroundExecutor(ExecutorUtils.KEYBOARD).execute(new Runnable() { + @Override + public void run() { + UserDictionary.Words.addWord(userDict.mContext, suggestion, + 250 /*FREQUENCY_FOR_USER_DICTIONARY_ADDS*/, null, dictionaryGroup.mLocale); + } + }); + } + } + NgramContext ngramContextForCurrentWord = ngramContext; for (int i = 0; i < words.length; i++) { final String currentWord = words[i]; diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/CorrectionSettingsFragment.java b/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/CorrectionSettingsFragment.java index 7a73457d..ae12c00e 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/CorrectionSettingsFragment.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/CorrectionSettingsFragment.java @@ -81,6 +81,7 @@ public final class CorrectionSettingsFragment extends SubScreenFragment private void refreshEnabledSettings() { setPreferenceEnabled(Settings.PREF_AUTO_CORRECTION_CONFIDENCE, Settings.readAutoCorrectEnabled(getSharedPreferences(), getResources())); + setPreferenceEnabled(Settings.PREF_ADD_TO_PERSONAL_DICTIONARY, getSharedPreferences().getBoolean(Settings.PREF_KEY_USE_PERSONALIZED_DICTS, true)); } private void overwriteUserDictionaryPreference(final Preference userDictionaryPreference) { diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/Settings.java b/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/Settings.java index ae69eeb1..b3869831 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/Settings.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/Settings.java @@ -136,6 +136,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang public static final String PREF_CLIPBOARD_HISTORY_RETENTION_TIME = "pref_clipboard_history_retention_time"; public static final String PREF_SECONDARY_LOCALES = "pref_secondary_locales"; + public static final String PREF_ADD_TO_PERSONAL_DICTIONARY = "add_to_personal_dictionary"; // This preference key is deprecated. Use {@link #PREF_SHOW_LANGUAGE_SWITCH_KEY} instead. // This is being used only for the backward compatibility. diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/SettingsValues.java b/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/SettingsValues.java index e54113e5..88258967 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/SettingsValues.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/SettingsValues.java @@ -108,6 +108,7 @@ public class SettingsValues { // Use split layout for keyboard. public final boolean mIsSplitKeyboardEnabled; public final int mScreenMetrics; + public final boolean mAddToPersonalDictionary; // From the input box @Nonnull @@ -259,6 +260,7 @@ public class SettingsValues { mOneHandedModeEnabled = Settings.readOneHandedModeEnabled(prefs); mOneHandedModeGravity = Settings.readOneHandedModeGravity(prefs); mSecondaryLocale = Settings.getSecondaryLocale(prefs, RichInputMethodManager.getInstance().getCurrentSubtypeLocale().toString()); + mUserTheme = KeyboardTheme.getIsUser(KeyboardTheme.getThemeForParameters( prefs.getString(Settings.PREF_THEME_FAMILY, ""), prefs.getString(Settings.PREF_THEME_VARIANT, ""), @@ -278,6 +280,8 @@ public class SettingsValues { mKeyTextColorFilter = BlendModeColorFilterCompat.createBlendModeColorFilterCompat(mKeyTextColor, BlendModeCompat.SRC_ATOP); mBackgroundColor = prefs.getInt(Settings.PREF_THEME_USER_COLOR_BACKGROUND, Color.DKGRAY); mBackgroundColorFilter = BlendModeColorFilterCompat.createBlendModeColorFilterCompat(mBackgroundColor, BlendModeCompat.MODULATE); + + mAddToPersonalDictionary = prefs.getBoolean(Settings.PREF_ADD_TO_PERSONAL_DICTIONARY, false); } public boolean isMetricsLoggingEnabled() { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 00b982c3..036364db 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -111,6 +111,10 @@ Use contact names for suggestions and corrections Personalized suggestions + + Add words to user dictionary + + Use device personal dictionary to store learned words "Improve %s" diff --git a/app/src/main/res/xml/prefs_screen_correction.xml b/app/src/main/res/xml/prefs_screen_correction.xml index 286b1469..dad968fe 100644 --- a/app/src/main/res/xml/prefs_screen_correction.xml +++ b/app/src/main/res/xml/prefs_screen_correction.xml @@ -82,6 +82,13 @@ android:defaultValue="true" android:persistent="true" /> + +