Merge pull request #90 from alexandrius/master

Fix Georgian automatic uppercase since Georgian script doesn't have uppercase
This commit is contained in:
Daniele Laudani 2020-04-23 23:09:22 +02:00 committed by GitHub
commit 363e27dc5e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 234 additions and 200 deletions

View file

@ -36,6 +36,7 @@ import org.dslul.openboard.inputmethod.keyboard.internal.UniqueKeysCache;
import org.dslul.openboard.inputmethod.latin.InputAttributes; import org.dslul.openboard.inputmethod.latin.InputAttributes;
import org.dslul.openboard.inputmethod.latin.R; import org.dslul.openboard.inputmethod.latin.R;
import org.dslul.openboard.inputmethod.latin.RichInputMethodSubtype; import org.dslul.openboard.inputmethod.latin.RichInputMethodSubtype;
import org.dslul.openboard.inputmethod.latin.common.StringUtils;
import org.dslul.openboard.inputmethod.latin.utils.InputTypeUtils; import org.dslul.openboard.inputmethod.latin.utils.InputTypeUtils;
import org.dslul.openboard.inputmethod.latin.utils.ScriptUtils; import org.dslul.openboard.inputmethod.latin.utils.ScriptUtils;
import org.dslul.openboard.inputmethod.latin.utils.SubtypeLocaleUtils; import org.dslul.openboard.inputmethod.latin.utils.SubtypeLocaleUtils;
@ -104,7 +105,9 @@ public final class KeyboardLayoutSet {
boolean mProximityCharsCorrectionEnabled; boolean mProximityCharsCorrectionEnabled;
boolean mSupportsSplitLayout; boolean mSupportsSplitLayout;
boolean mAllowRedundantMoreKeys; boolean mAllowRedundantMoreKeys;
public ElementParams() {}
public ElementParams() {
}
} }
public static final class Params { public static final class Params {
@ -162,6 +165,8 @@ public final class KeyboardLayoutSet {
mParams = params; mParams = params;
} }
public static final String LOCALE_GEORGIAN = "ka";
@Nonnull @Nonnull
public Keyboard getKeyboard(final int baseKeyboardLayoutSetElementId) { public Keyboard getKeyboard(final int baseKeyboardLayoutSetElementId) {
final int keyboardLayoutSetElementId; final int keyboardLayoutSetElementId;
@ -197,6 +202,7 @@ public final class KeyboardLayoutSet {
mParams.mIsSplitLayoutEnabled = mParams.mIsSplitLayoutEnabledByUser mParams.mIsSplitLayoutEnabled = mParams.mIsSplitLayoutEnabledByUser
&& elementParams.mSupportsSplitLayout; && elementParams.mSupportsSplitLayout;
final KeyboardId id = new KeyboardId(keyboardLayoutSetElementId, mParams); final KeyboardId id = new KeyboardId(keyboardLayoutSetElementId, mParams);
try { try {
return getKeyboard(elementParams, id); return getKeyboard(elementParams, id);
@ -279,8 +285,7 @@ public final class KeyboardLayoutSet {
// be locked down. // be locked down.
// TODO: Switch to {@code UserManagerCompat.isUserUnlocked()} in the support-v4 library // TODO: Switch to {@code UserManagerCompat.isUserUnlocked()} in the support-v4 library
// when it becomes publicly available. // when it becomes publicly available.
@UserManagerCompatUtils.LockState @UserManagerCompatUtils.LockState final int lockState = UserManagerCompatUtils.getUserLockState(context);
final int lockState = UserManagerCompatUtils.getUserLockState(context);
if (lockState == UserManagerCompatUtils.LOCK_STATE_LOCKED) { if (lockState == UserManagerCompatUtils.LOCK_STATE_LOCKED) {
params.mNoSettingsKey = true; params.mNoSettingsKey = true;
} }
@ -295,8 +300,7 @@ public final class KeyboardLayoutSet {
public Builder setSubtype(@Nonnull final RichInputMethodSubtype subtype) { public Builder setSubtype(@Nonnull final RichInputMethodSubtype subtype) {
final boolean asciiCapable = subtype.getmSubtype().isAsciiCapable(); final boolean asciiCapable = subtype.getmSubtype().isAsciiCapable();
// TODO: Consolidate with {@link InputAttributes}. // TODO: Consolidate with {@link InputAttributes}.
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation") final boolean deprecatedForceAscii = InputAttributes.inPrivateImeOptions(
final boolean deprecatedForceAscii = InputAttributes.inPrivateImeOptions(
mPackageName, FORCE_ASCII, mParams.mEditorInfo); mPackageName, FORCE_ASCII, mParams.mEditorInfo);
final boolean forceAscii = EditorInfoCompatUtils.hasFlagForceAscii( final boolean forceAscii = EditorInfoCompatUtils.hasFlagForceAscii(
mParams.mEditorInfo.imeOptions) mParams.mEditorInfo.imeOptions)

View file

@ -16,7 +16,10 @@
package org.dslul.openboard.inputmethod.latin.common; package org.dslul.openboard.inputmethod.latin.common;
import android.renderscript.Script;
import org.dslul.openboard.inputmethod.annotations.UsedForTesting; import org.dslul.openboard.inputmethod.annotations.UsedForTesting;
import org.dslul.openboard.inputmethod.latin.utils.ScriptUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -26,6 +29,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public final class StringUtils { public final class StringUtils {
public static final int CAPITALIZE_NONE = 0; // No caps, or mixed case public static final int CAPITALIZE_NONE = 0; // No caps, or mixed case
public static final int CAPITALIZE_FIRST = 1; // First only public static final int CAPITALIZE_FIRST = 1; // First only
public static final int CAPITALIZE_ALL = 2; // All caps public static final int CAPITALIZE_ALL = 2; // All caps
@ -47,8 +51,10 @@ public final class StringUtils {
// Taken from android.text.TextUtils. We are extensively using this method in many places, // Taken from android.text.TextUtils. We are extensively using this method in many places,
// some of which don't have the android libraries available. // some of which don't have the android libraries available.
/** /**
* Returns true if the string is null or 0-length. * Returns true if the string is null or 0-length.
*
* @param str the string to be examined * @param str the string to be examined
* @return true if str is null or zero length * @return true if str is null or zero length
*/ */
@ -57,8 +63,10 @@ public final class StringUtils {
} }
// Taken from android.text.TextUtils to cut the dependency to the Android framework. // Taken from android.text.TextUtils to cut the dependency to the Android framework.
/** /**
* Returns a string containing the tokens joined by delimiters. * Returns a string containing the tokens joined by delimiters.
*
* @param delimiter the delimiter * @param delimiter the delimiter
* @param tokens an array objects to be joined. Strings will be formed from * @param tokens an array objects to be joined. Strings will be formed from
* the objects by calling object.toString(). * the objects by calling object.toString().
@ -80,10 +88,12 @@ public final class StringUtils {
} }
// Taken from android.text.TextUtils to cut the dependency to the Android framework. // Taken from android.text.TextUtils to cut the dependency to the Android framework.
/** /**
* Returns true if a and b are equal, including if they are both null. * Returns true if a and b are equal, including if they are both null.
* <p><i>Note: In platform versions 1.1 and earlier, this method only worked well if * <p><i>Note: In platform versions 1.1 and earlier, this method only worked well if
* both the arguments were instances of String.</i></p> * both the arguments were instances of String.</i></p>
*
* @param a first CharSequence to check * @param a first CharSequence to check
* @param b second CharSequence to check * @param b second CharSequence to check
* @return true if a and b are equal * @return true if a and b are equal
@ -172,7 +182,7 @@ public final class StringUtils {
/** /**
* Remove duplicates from an array of strings. * Remove duplicates from an array of strings.
* * <p>
* This method will always keep the first occurrence of all strings at their position * This method will always keep the first occurrence of all strings at their position
* in the array, removing the subsequent ones. * in the array, removing the subsequent ones.
*/ */
@ -238,6 +248,7 @@ public final class StringUtils {
/** /**
* Converts a range of a string to an array of code points. * Converts a range of a string to an array of code points.
*
* @param charSequence the source string. * @param charSequence the source string.
* @param startIndex the start index inside the string in java chars, inclusive. * @param startIndex the start index inside the string in java chars, inclusive.
* @param endIndex the end index inside the string in java chars, exclusive. * @param endIndex the end index inside the string in java chars, exclusive.
@ -259,7 +270,7 @@ public final class StringUtils {
/** /**
* Copies the codepoints in a CharSequence to an int array. * Copies the codepoints in a CharSequence to an int array.
* * <p>
* This method assumes there is enough space in the array to store the code points. The size * This method assumes there is enough space in the array to store the code points. The size
* can be measured with Character#codePointCount(CharSequence, int, int) before passing to this * can be measured with Character#codePointCount(CharSequence, int, int) before passing to this
* method. If the int array is too small, an ArrayIndexOutOfBoundsException will be thrown. * method. If the int array is too small, an ArrayIndexOutOfBoundsException will be thrown.
@ -421,7 +432,7 @@ public final class StringUtils {
/** /**
* Approximates whether the text before the cursor looks like a URL. * Approximates whether the text before the cursor looks like a URL.
* * <p>
* This is not foolproof, but it should work well in the practice. * 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, * 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 * digit, or common URL symbol like underscore. If it hasn't found a period yet, then it
@ -430,9 +441,9 @@ public final class StringUtils {
* - starts with www and contains a period * - starts with www and contains a period
* - starts with a slash preceded by either a slash, whitespace, or start-of-string * - 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. * Then it looks like a URL and we return true. Otherwise, we return false.
* * <p>
* Note: this method is called quite often, and should be fast. * Note: this method is called quite often, and should be fast.
* * <p>
* TODO: This will return that "abc./def" and ".abc/def" look like URLs to keep down the * 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. * code complexity, but ideally it should not. It's acceptable for now.
*/ */
@ -491,7 +502,7 @@ public final class StringUtils {
/** /**
* Examines the string and returns whether we're inside a double quote. * Examines the string and returns whether we're inside a double quote.
* * <p>
* This is used to decide whether we should put an automatic space before or after a double * This is used to decide whether we should put an automatic space before or after a double
* quote character. If we're inside a quotation, then we want to close it, so we want a space * quote character. If we're inside a quotation, then we want to close it, so we want a space
* after and not before. Otherwise, we want to open the quotation, so we want a space before * after and not before. Otherwise, we want to open the quotation, so we want a space before
@ -597,9 +608,10 @@ public final class StringUtils {
@Nullable @Nullable
public static String toTitleCaseOfKeyLabel(@Nullable final String label, public static String toTitleCaseOfKeyLabel(@Nullable final String label,
@Nonnull final Locale locale) { @Nonnull final Locale locale) {
if (label == null) { if (label == null || !ScriptUtils.scriptSupportsUppercase(locale.getLanguage())) {
return label; return label;
} }
return label.toUpperCase(getLocaleUsedForToTitleCase(locale)); return label.toUpperCase(getLocaleUsedForToTitleCase(locale));
} }
@ -676,6 +688,7 @@ public final class StringUtils {
/** /**
* Returns whether the last composed word contains line-breaking character (e.g. CR or LF). * Returns whether the last composed word contains line-breaking character (e.g. CR or LF).
*
* @param text the text to be examined. * @param text the text to be examined.
* @return {@code true} if the last composed word contains line-breaking separator. * @return {@code true} if the last composed word contains line-breaking separator.
*/ */

View file

@ -28,8 +28,10 @@ import org.dslul.openboard.inputmethod.compat.AppWorkaroundsUtils;
import org.dslul.openboard.inputmethod.latin.InputAttributes; import org.dslul.openboard.inputmethod.latin.InputAttributes;
import org.dslul.openboard.inputmethod.latin.R; import org.dslul.openboard.inputmethod.latin.R;
import org.dslul.openboard.inputmethod.latin.RichInputMethodManager; import org.dslul.openboard.inputmethod.latin.RichInputMethodManager;
import org.dslul.openboard.inputmethod.latin.common.StringUtils;
import org.dslul.openboard.inputmethod.latin.utils.AsyncResultHolder; import org.dslul.openboard.inputmethod.latin.utils.AsyncResultHolder;
import org.dslul.openboard.inputmethod.latin.utils.ResourceUtils; import org.dslul.openboard.inputmethod.latin.utils.ResourceUtils;
import org.dslul.openboard.inputmethod.latin.utils.ScriptUtils;
import org.dslul.openboard.inputmethod.latin.utils.TargetPackageInfoGetterTask; import org.dslul.openboard.inputmethod.latin.utils.TargetPackageInfoGetterTask;
import java.util.Arrays; import java.util.Arrays;
@ -118,7 +120,8 @@ public class SettingsValues {
public final float mKeyPreviewDismissEndXScale; public final float mKeyPreviewDismissEndXScale;
public final float mKeyPreviewDismissEndYScale; public final float mKeyPreviewDismissEndYScale;
@Nullable public final String mAccount; @Nullable
public final String mAccount;
public SettingsValues(final Context context, final SharedPreferences prefs, final Resources res, public SettingsValues(final Context context, final SharedPreferences prefs, final Resources res,
@Nonnull final InputAttributes inputAttributes) { @Nonnull final InputAttributes inputAttributes) {
@ -132,7 +135,7 @@ public class SettingsValues {
mInputAttributes = inputAttributes; mInputAttributes = inputAttributes;
// Get the settings preferences // Get the settings preferences
mAutoCap = prefs.getBoolean(Settings.PREF_AUTO_CAP, true); mAutoCap = prefs.getBoolean(Settings.PREF_AUTO_CAP, true) && ScriptUtils.scriptSupportsUppercase(mLocale.getLanguage());
mVibrateOn = Settings.readVibrationEnabled(prefs, res); mVibrateOn = Settings.readVibrationEnabled(prefs, res);
mSoundOn = Settings.readKeypressSoundEnabled(prefs, res); mSoundOn = Settings.readKeypressSoundEnabled(prefs, res);
mKeyPreviewPopupOn = Settings.readKeyPreviewPopupEnabled(prefs, res); mKeyPreviewPopupOn = Settings.readKeyPreviewPopupEnabled(prefs, res);

View file

@ -16,6 +16,9 @@
package org.dslul.openboard.inputmethod.latin.utils; package org.dslul.openboard.inputmethod.latin.utils;
import androidx.collection.ArraySet;
import java.util.Locale; import java.util.Locale;
import java.util.TreeMap; import java.util.TreeMap;
@ -47,7 +50,11 @@ public class ScriptUtils {
public static final int SCRIPT_THAI = 17; public static final int SCRIPT_THAI = 17;
public static final int SCRIPT_BULGARIAN = 18; public static final int SCRIPT_BULGARIAN = 18;
public static final String LANGUAGE_GEORGIAN = "ka";
private static final TreeMap<String, Integer> mLanguageCodeToScriptCode; private static final TreeMap<String, Integer> mLanguageCodeToScriptCode;
private final static ArraySet<String> NON_UPPERCASE_SCRIPTS = new ArraySet<>();
static { static {
mLanguageCodeToScriptCode = new TreeMap<>(); mLanguageCodeToScriptCode = new TreeMap<>();
@ -70,6 +77,13 @@ public class ScriptUtils {
mLanguageCodeToScriptCode.put("te", SCRIPT_TELUGU); mLanguageCodeToScriptCode.put("te", SCRIPT_TELUGU);
mLanguageCodeToScriptCode.put("th", SCRIPT_THAI); mLanguageCodeToScriptCode.put("th", SCRIPT_THAI);
mLanguageCodeToScriptCode.put("uk", SCRIPT_CYRILLIC); mLanguageCodeToScriptCode.put("uk", SCRIPT_CYRILLIC);
NON_UPPERCASE_SCRIPTS.add(LANGUAGE_GEORGIAN);
}
public static boolean scriptSupportsUppercase(String language) {
return !NON_UPPERCASE_SCRIPTS.contains(language);
} }
/* /*