mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-05-25 11:22:20 +00:00
comments, unused code, minor adjustments
This commit is contained in:
parent
5f42d00bca
commit
66267f8ce5
13 changed files with 43 additions and 368 deletions
|
@ -129,6 +129,7 @@ internal class KeyCodeDescriptionMapper private constructor() {
|
|||
}
|
||||
|
||||
// TODO: Remove this method once TTS supports those accented letters' verbalization.
|
||||
// see also the comment for emoji
|
||||
private fun getSpokenAccentedLetterDescription(context: Context, code: Int): String? {
|
||||
val isUpperCase = Character.isUpperCase(code)
|
||||
val baseCode = if (isUpperCase) Character.toLowerCase(code) else code
|
||||
|
@ -142,6 +143,7 @@ internal class KeyCodeDescriptionMapper private constructor() {
|
|||
}
|
||||
|
||||
// TODO: Remove this method once TTS supports those symbols' verbalization.
|
||||
// see also the comment for emoji
|
||||
private fun getSpokenSymbolDescription(context: Context, code: Int): String? {
|
||||
val resId = getSpokenDescriptionId(context, code, SPOKEN_SYMBOL_RESOURCE_NAME_FORMAT)
|
||||
if (resId == 0) {
|
||||
|
@ -155,6 +157,8 @@ internal class KeyCodeDescriptionMapper private constructor() {
|
|||
}
|
||||
|
||||
// TODO: Remove this method once TTS supports emoji verbalization.
|
||||
// todo 2: this comment above is about 10 years old, can we remove this?
|
||||
// emoji descriptions will be missing for many more recent emojis anyway
|
||||
private fun getSpokenEmojiDescription(context: Context, code: Int): String? {
|
||||
val resId = getSpokenDescriptionId(context, code, SPOKEN_EMOJI_RESOURCE_NAME_FORMAT)
|
||||
if (resId == 0) {
|
||||
|
@ -258,6 +262,7 @@ internal class KeyCodeDescriptionMapper private constructor() {
|
|||
}
|
||||
|
||||
// TODO: Remove this method once TTS supports emoticon verbalization.
|
||||
// see also the comment for emoji
|
||||
private fun getSpokenEmoticonDescription(context: Context, outputText: String): String? {
|
||||
val sb = StringBuilder(SPOKEN_EMOTICON_RESOURCE_NAME_PREFIX)
|
||||
val textLength = outputText.length
|
||||
|
|
|
@ -23,7 +23,6 @@ import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardBuilder;
|
|||
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardParams;
|
||||
import org.dslul.openboard.inputmethod.keyboard.internal.UniqueKeysCache;
|
||||
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.LocaleKeyTextsKt;
|
||||
import org.dslul.openboard.inputmethod.latin.InputAttributes;
|
||||
import org.dslul.openboard.inputmethod.latin.R;
|
||||
import org.dslul.openboard.inputmethod.latin.RichInputMethodSubtype;
|
||||
import org.dslul.openboard.inputmethod.latin.utils.InputTypeUtils;
|
||||
|
@ -36,8 +35,6 @@ import java.io.IOException;
|
|||
import java.lang.ref.SoftReference;
|
||||
import java.util.HashMap;
|
||||
|
||||
import static org.dslul.openboard.inputmethod.latin.common.Constants.ImeOption.FORCE_ASCII;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
|
@ -248,9 +245,7 @@ public final class KeyboardLayoutSet {
|
|||
|
||||
public Builder setSubtype(@NonNull final RichInputMethodSubtype subtype) {
|
||||
final boolean asciiCapable = subtype.getRawSubtype().isAsciiCapable();
|
||||
// TODO: Consolidate with {@link InputAttributes}.
|
||||
final boolean forceAscii = (mParams.mEditorInfo.imeOptions & EditorInfo.IME_FLAG_FORCE_ASCII) != 0
|
||||
|| InputAttributes.inPrivateImeOptions(mPackageName, FORCE_ASCII, mParams.mEditorInfo);
|
||||
final boolean forceAscii = (mParams.mEditorInfo.imeOptions & EditorInfo.IME_FLAG_FORCE_ASCII) != 0;
|
||||
final RichInputMethodSubtype keyboardSubtype = (forceAscii && !asciiCapable)
|
||||
? RichInputMethodSubtype.getNoLanguageSubtype()
|
||||
: subtype;
|
||||
|
|
|
@ -19,14 +19,14 @@ import org.dslul.openboard.inputmethod.latin.utils.RecapitalizeStatus;
|
|||
|
||||
/**
|
||||
* Keyboard state machine.
|
||||
*
|
||||
* <p>
|
||||
* This class contains all keyboard state transition logic.
|
||||
*
|
||||
* <p>
|
||||
* The input events are {@link #onLoadKeyboard(int, int, boolean)}, {@link #onSaveKeyboardState()},
|
||||
* {@link #onPressKey(int,boolean,int,int)}, {@link #onReleaseKey(int,boolean,int,int)},
|
||||
* {@link #onEvent(Event,int,int)}, {@link #onFinishSlidingInput(int,int)},
|
||||
* {@link #onUpdateShiftState(int,int)}, {@link #onResetKeyboardStateToAlphabet(int,int)}.
|
||||
*
|
||||
* <p>
|
||||
* The actions are {@link SwitchActions}'s methods.
|
||||
*/
|
||||
public final class KeyboardState {
|
||||
|
@ -65,9 +65,9 @@ public final class KeyboardState {
|
|||
|
||||
private final SwitchActions mSwitchActions;
|
||||
|
||||
private ShiftKeyState mShiftKeyState = new ShiftKeyState("Shift");
|
||||
private ModifierKeyState mSymbolKeyState = new ModifierKeyState("Symbol");
|
||||
private ModifierKeyState mAlphaNumpadKeyState = new ModifierKeyState("AlphaNumpad");
|
||||
private final ShiftKeyState mShiftKeyState = new ShiftKeyState("Shift");
|
||||
private final ModifierKeyState mSymbolKeyState = new ModifierKeyState("Symbol");
|
||||
private final ModifierKeyState mAlphaNumpadKeyState = new ModifierKeyState("AlphaNumpad");
|
||||
private final AlphabetShiftState mAlphabetShiftState = new AlphabetShiftState();
|
||||
|
||||
// TODO: Merge {@link #mSwitchState}, {@link #mIsAlphabetMode}, {@link #mAlphabetShiftState},
|
||||
|
|
|
@ -19,7 +19,6 @@ import java.util.Arrays;
|
|||
|
||||
import static org.dslul.openboard.inputmethod.latin.common.Constants.ImeOption.NO_FLOATING_GESTURE_PREVIEW;
|
||||
import static org.dslul.openboard.inputmethod.latin.common.Constants.ImeOption.NO_MICROPHONE;
|
||||
import static org.dslul.openboard.inputmethod.latin.common.Constants.ImeOption.NO_MICROPHONE_COMPAT;
|
||||
|
||||
/**
|
||||
* Class to hold attributes of the input field.
|
||||
|
@ -141,12 +140,7 @@ public final class InputAttributes {
|
|||
}
|
||||
|
||||
private boolean hasNoMicrophoneKeyOption() {
|
||||
@SuppressWarnings("deprecation")
|
||||
final boolean deprecatedNoMicrophone = InputAttributes.inPrivateImeOptions(
|
||||
null, NO_MICROPHONE_COMPAT, mEditorInfo);
|
||||
final boolean noMicrophone = InputAttributes.inPrivateImeOptions(
|
||||
mPackageNameForPrivateImeOptions, NO_MICROPHONE, mEditorInfo);
|
||||
return noMicrophone || deprecatedNoMicrophone;
|
||||
return InputAttributes.inPrivateImeOptions(mPackageNameForPrivateImeOptions, NO_MICROPHONE, mEditorInfo);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
|
|
|
@ -92,10 +92,6 @@ import java.util.List;
|
|||
import java.util.Locale;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.dslul.openboard.inputmethod.latin.common.Constants.ImeOption.FORCE_ASCII;
|
||||
import static org.dslul.openboard.inputmethod.latin.common.Constants.ImeOption.NO_MICROPHONE;
|
||||
import static org.dslul.openboard.inputmethod.latin.common.Constants.ImeOption.NO_MICROPHONE_COMPAT;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
@ -955,17 +951,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
+ ", word caps = "
|
||||
+ ((editorInfo.inputType & InputType.TYPE_TEXT_FLAG_CAP_WORDS) != 0));
|
||||
}
|
||||
Log.i(TAG, "Starting input. Cursor position = "
|
||||
+ editorInfo.initialSelStart + "," + editorInfo.initialSelEnd);
|
||||
// TODO: Consolidate these checks with {@link InputAttributes}.
|
||||
if (InputAttributes.inPrivateImeOptions(null, NO_MICROPHONE_COMPAT, editorInfo)) {
|
||||
Log.w(TAG, "Deprecated private IME option specified: " + editorInfo.privateImeOptions);
|
||||
Log.w(TAG, "Use " + getPackageName() + "." + NO_MICROPHONE + " instead");
|
||||
}
|
||||
if (InputAttributes.inPrivateImeOptions(getPackageName(), FORCE_ASCII, editorInfo)) {
|
||||
Log.w(TAG, "Deprecated private IME option specified: " + editorInfo.privateImeOptions);
|
||||
Log.w(TAG, "Use EditorInfo.IME_FLAG_FORCE_ASCII flag instead");
|
||||
}
|
||||
Log.i(TAG, "Starting input. Cursor position = " + editorInfo.initialSelStart + "," + editorInfo.initialSelEnd);
|
||||
|
||||
// In landscape mode, this method gets called without the input view being created.
|
||||
if (mainKeyboardView == null) {
|
||||
|
|
|
@ -1,107 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
* modified
|
||||
* SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.dslul.openboard.inputmethod.latin.common;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.dslul.openboard.inputmethod.annotations.UsedForTesting;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
// Utility methods related with code points used for tests.
|
||||
// TODO: Figure out where this class should be.
|
||||
@UsedForTesting
|
||||
public class CodePointUtils {
|
||||
private CodePointUtils() {
|
||||
// This utility class is not publicly instantiable.
|
||||
}
|
||||
|
||||
public static final int[] LATIN_ALPHABETS_LOWER = {
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
||||
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||
0x00E0 /* LATIN SMALL LETTER A WITH GRAVE */,
|
||||
0x00E1 /* LATIN SMALL LETTER A WITH ACUTE */,
|
||||
0x00E2 /* LATIN SMALL LETTER A WITH CIRCUMFLEX */,
|
||||
0x00E3 /* LATIN SMALL LETTER A WITH TILDE */,
|
||||
0x00E4 /* LATIN SMALL LETTER A WITH DIAERESIS */,
|
||||
0x00E5 /* LATIN SMALL LETTER A WITH RING ABOVE */,
|
||||
0x00E6 /* LATIN SMALL LETTER AE */,
|
||||
0x00E7 /* LATIN SMALL LETTER C WITH CEDILLA */,
|
||||
0x00E8 /* LATIN SMALL LETTER E WITH GRAVE */,
|
||||
0x00E9 /* LATIN SMALL LETTER E WITH ACUTE */,
|
||||
0x00EA /* LATIN SMALL LETTER E WITH CIRCUMFLEX */,
|
||||
0x00EB /* LATIN SMALL LETTER E WITH DIAERESIS */,
|
||||
0x00EC /* LATIN SMALL LETTER I WITH GRAVE */,
|
||||
0x00ED /* LATIN SMALL LETTER I WITH ACUTE */,
|
||||
0x00EE /* LATIN SMALL LETTER I WITH CIRCUMFLEX */,
|
||||
0x00EF /* LATIN SMALL LETTER I WITH DIAERESIS */,
|
||||
0x00F0 /* LATIN SMALL LETTER ETH */,
|
||||
0x00F1 /* LATIN SMALL LETTER N WITH TILDE */,
|
||||
0x00F2 /* LATIN SMALL LETTER O WITH GRAVE */,
|
||||
0x00F3 /* LATIN SMALL LETTER O WITH ACUTE */,
|
||||
0x00F4 /* LATIN SMALL LETTER O WITH CIRCUMFLEX */,
|
||||
0x00F5 /* LATIN SMALL LETTER O WITH TILDE */,
|
||||
0x00F6 /* LATIN SMALL LETTER O WITH DIAERESIS */,
|
||||
0x00F7 /* LATIN SMALL LETTER O WITH STROKE */,
|
||||
0x00F9 /* LATIN SMALL LETTER U WITH GRAVE */,
|
||||
0x00FA /* LATIN SMALL LETTER U WITH ACUTE */,
|
||||
0x00FB /* LATIN SMALL LETTER U WITH CIRCUMFLEX */,
|
||||
0x00FC /* LATIN SMALL LETTER U WITH DIAERESIS */,
|
||||
0x00FD /* LATIN SMALL LETTER Y WITH ACUTE */,
|
||||
0x00FE /* LATIN SMALL LETTER THORN */,
|
||||
0x00FF /* LATIN SMALL LETTER Y WITH DIAERESIS */
|
||||
};
|
||||
|
||||
@UsedForTesting
|
||||
@NonNull
|
||||
public static int[] generateCodePointSet(final int codePointSetSize,
|
||||
@NonNull final Random random) {
|
||||
final int[] codePointSet = new int[codePointSetSize];
|
||||
for (int i = codePointSet.length - 1; i >= 0; ) {
|
||||
final int r = Math.abs(random.nextInt());
|
||||
if (r < 0) {
|
||||
continue;
|
||||
}
|
||||
// Don't insert 0~0x20, but insert any other code point.
|
||||
// Code points are in the range 0~0x10FFFF.
|
||||
final int candidateCodePoint = 0x20 + r % (Character.MAX_CODE_POINT - 0x20);
|
||||
// Code points between MIN_ and MAX_SURROGATE are not valid on their own.
|
||||
if (candidateCodePoint >= Character.MIN_SURROGATE
|
||||
&& candidateCodePoint <= Character.MAX_SURROGATE) {
|
||||
continue;
|
||||
}
|
||||
codePointSet[i] = candidateCodePoint;
|
||||
--i;
|
||||
}
|
||||
return codePointSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random word.
|
||||
*/
|
||||
@UsedForTesting
|
||||
@NonNull
|
||||
public static String generateWord(@NonNull final Random random,
|
||||
@NonNull final int[] codePointSet) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
// 8 * 4 = 32 chars max, but we do it the following way so as to bias the random toward
|
||||
// longer words. This should be closer to natural language, and more importantly, it will
|
||||
// exercise the algorithms in dicttool much more.
|
||||
final int count = 1 + (Math.abs(random.nextInt()) % 5)
|
||||
+ (Math.abs(random.nextInt()) % 5)
|
||||
+ (Math.abs(random.nextInt()) % 5)
|
||||
+ (Math.abs(random.nextInt()) % 5)
|
||||
+ (Math.abs(random.nextInt()) % 5)
|
||||
+ (Math.abs(random.nextInt()) % 5)
|
||||
+ (Math.abs(random.nextInt()) % 5)
|
||||
+ (Math.abs(random.nextInt()) % 5);
|
||||
while (builder.length() < count) {
|
||||
builder.appendCodePoint(codePointSet[Math.abs(random.nextInt()) % codePointSet.length]);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
|
@ -7,13 +7,8 @@
|
|||
package org.dslul.openboard.inputmethod.latin.common;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.dslul.openboard.inputmethod.annotations.UsedForTesting;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Utility methods for working with collections.
|
||||
|
@ -44,24 +39,4 @@ public final class CollectionUtils {
|
|||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether c contains no elements, true if c is null or c is empty.
|
||||
* @param c Collection to test.
|
||||
* @return Whether c contains no elements.
|
||||
*/
|
||||
@UsedForTesting
|
||||
public static boolean isNullOrEmpty(@Nullable final Collection c) {
|
||||
return c == null || c.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether map contains no elements, true if map is null or map is empty.
|
||||
* @param map Map to test.
|
||||
* @return Whether map contains no elements.
|
||||
*/
|
||||
@UsedForTesting
|
||||
public static boolean isNullOrEmpty(@Nullable final Map map) {
|
||||
return map == null || map.isEmpty();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,16 +21,6 @@ public final class Constants {
|
|||
}
|
||||
|
||||
public static final class ImeOption {
|
||||
/**
|
||||
* The private IME option used to indicate that no microphone should be shown for a given
|
||||
* text field. For instance, this is specified by the search dialog when the dialog is
|
||||
* already showing a voice search button.
|
||||
*
|
||||
* @deprecated Use {@link ImeOption#NO_MICROPHONE} with package name prefixed.
|
||||
*/
|
||||
@SuppressWarnings("dep-ann")
|
||||
public static final String NO_MICROPHONE_COMPAT = "nm";
|
||||
|
||||
/**
|
||||
* The private IME option used to indicate that no microphone should be shown for a given
|
||||
* text field. For instance, this is specified by the search dialog when the dialog is
|
||||
|
@ -38,15 +28,6 @@ public final class Constants {
|
|||
*/
|
||||
public static final String NO_MICROPHONE = "noMicrophoneKey";
|
||||
|
||||
/**
|
||||
* The private IME option used to indicate that the given text field needs ASCII code points
|
||||
* input.
|
||||
*
|
||||
* @deprecated Use EditorInfo#IME_FLAG_FORCE_ASCII.
|
||||
*/
|
||||
@SuppressWarnings("dep-ann")
|
||||
public static final String FORCE_ASCII = "forceAscii";
|
||||
|
||||
/**
|
||||
* The private IME option used to suppress the floating gesture preview for a given text
|
||||
* field. This overrides the corresponding keyboard settings preference.
|
||||
|
@ -291,19 +272,6 @@ public final class Constants {
|
|||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String printableCodes(@NonNull final int[] codes) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
boolean addDelimiter = false;
|
||||
for (final int code : codes) {
|
||||
if (code == NOT_A_CODE) break;
|
||||
if (addDelimiter) sb.append(", ");
|
||||
sb.append(printableCode(code));
|
||||
addDelimiter = true;
|
||||
}
|
||||
return "[" + sb + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Screen metrics (a.k.a. Device form factor) constants of
|
||||
* {@link org.dslul.openboard.inputmethod.latin.R.integer#config_screen_metrics}.
|
||||
|
@ -313,18 +281,6 @@ public final class Constants {
|
|||
public static final int SCREEN_METRICS_LARGE_TABLET = 2;
|
||||
public static final int SCREEN_METRICS_SMALL_TABLET = 3;
|
||||
|
||||
@UsedForTesting
|
||||
public static boolean isPhone(final int screenMetrics) {
|
||||
return screenMetrics == SCREEN_METRICS_SMALL_PHONE
|
||||
|| screenMetrics == SCREEN_METRICS_LARGE_PHONE;
|
||||
}
|
||||
|
||||
@UsedForTesting
|
||||
public static boolean isTablet(final int screenMetrics) {
|
||||
return screenMetrics == SCREEN_METRICS_SMALL_TABLET
|
||||
|| screenMetrics == SCREEN_METRICS_LARGE_TABLET;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default capacity of gesture points container.
|
||||
* This constant is used by {@link org.dslul.openboard.inputmethod.keyboard.internal.BatchInputArbiter}
|
||||
|
|
|
@ -17,7 +17,6 @@ import java.io.OutputStream;
|
|||
* A simple class to help with removing directories recursively.
|
||||
*/
|
||||
public class FileUtils {
|
||||
private static final String TAG = "FileUtils";
|
||||
|
||||
public static boolean deleteRecursively(final File path) {
|
||||
if (path.isDirectory()) {
|
||||
|
@ -48,11 +47,6 @@ public class FileUtils {
|
|||
return hasDeletedAllFiles;
|
||||
}
|
||||
|
||||
public static boolean renameTo(final File fromFile, final File toFile) {
|
||||
toFile.delete();
|
||||
return fromFile.renameTo(toFile);
|
||||
}
|
||||
|
||||
public static void copyStreamToNewFile(InputStream in, File outfile) throws IOException {
|
||||
File parentFile = outfile.getParentFile();
|
||||
if (parentFile == null || (!parentFile.exists() && !parentFile.mkdirs())) {
|
||||
|
|
|
@ -19,7 +19,7 @@ import java.util.Locale;
|
|||
|
||||
/**
|
||||
* A class to help with handling Locales in string form.
|
||||
*
|
||||
* <p>
|
||||
* This file has the same meaning and features (and shares all of its code) with the one with the
|
||||
* same name in Latin IME. They need to be kept synchronized; for any update/bugfix to
|
||||
* this file, consider also updating/fixing the version in Latin IME.
|
||||
|
@ -60,13 +60,9 @@ public final class LocaleUtils {
|
|||
// Don't use this directly, use #isMatch to test.
|
||||
private static final int LOCALE_MATCH = LOCALE_ANY_MATCH;
|
||||
|
||||
// Make this match the maximum match level. If this evolves to have more than 2 digits
|
||||
// when written in base 10, also adjust the getMatchLevelSortedString method.
|
||||
private static final int MATCH_LEVEL_MAX = 30;
|
||||
|
||||
/**
|
||||
* Return how well a tested locale matches a reference locale.
|
||||
*
|
||||
* <p>
|
||||
* This will check the tested locale against the reference locale and return a measure of how
|
||||
* a well it matches the reference. The general idea is that the tested locale has to match
|
||||
* every specified part of the required locale. A full match occur when they are equal, a
|
||||
|
@ -130,21 +126,9 @@ public final class LocaleUtils {
|
|||
return LOCALE_NO_MATCH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string that represents this match level, with better matches first.
|
||||
*
|
||||
* The strings are sorted in lexicographic order: a better match will always be less than
|
||||
* a worse match when compared together.
|
||||
*/
|
||||
public static String getMatchLevelSortedString(final int matchLevel) {
|
||||
// This works because the match levels are 0~99 (actually 0~30)
|
||||
// Ideally this should use a number of digits equals to the 1og10 of the greater matchLevel
|
||||
return String.format(Locale.ROOT, "%02d", MATCH_LEVEL_MAX - matchLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find out whether a match level should be considered a match.
|
||||
*
|
||||
* <p>
|
||||
* This method takes a match level as returned by the #getMatchLevel method, and returns whether
|
||||
* it should be considered a match in the usual sense with standard Locale functions.
|
||||
*
|
||||
|
@ -176,12 +160,11 @@ public final class LocaleUtils {
|
|||
final String[] elements = localeString.split("_", 3);
|
||||
final Locale locale;
|
||||
if (elements.length == 1) {
|
||||
locale = new Locale(elements[0] /* language */);
|
||||
locale = new Locale(elements[0]);
|
||||
} else if (elements.length == 2) {
|
||||
locale = new Locale(elements[0] /* language */, elements[1] /* country */);
|
||||
locale = new Locale(elements[0], elements[1]);
|
||||
} else { // localeParams.length == 3
|
||||
locale = new Locale(elements[0] /* language */, elements[1] /* country */,
|
||||
elements[2] /* variant */);
|
||||
locale = new Locale(elements[0], elements[1], elements[2]);
|
||||
}
|
||||
sLocaleCache.put(localeString, locale);
|
||||
return locale;
|
||||
|
@ -212,8 +195,7 @@ public final class LocaleUtils {
|
|||
if (localeString.equals("zz"))
|
||||
return context.getString(R.string.subtype_no_language);
|
||||
if (localeString.endsWith("_ZZ") || localeString.endsWith("_zz")) {
|
||||
final int resId = context.getResources()
|
||||
.getIdentifier("subtype_"+localeString, "string", context.getPackageName());
|
||||
final int resId = context.getResources().getIdentifier("subtype_"+localeString, "string", context.getPackageName());
|
||||
if (resId != 0)
|
||||
return context.getString(resId);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ package org.dslul.openboard.inputmethod.latin.common;
|
|||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.dslul.openboard.inputmethod.annotations.UsedForTesting;
|
||||
import org.dslul.openboard.inputmethod.latin.utils.ScriptUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -556,41 +555,6 @@ public final class StringUtils {
|
|||
return true;
|
||||
}
|
||||
|
||||
@UsedForTesting
|
||||
@NonNull
|
||||
public static String byteArrayToHexString(@Nullable final byte[] bytes) {
|
||||
if (bytes == null || bytes.length == 0) {
|
||||
return EMPTY_STRING;
|
||||
}
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
for (final byte b : bytes) {
|
||||
sb.append(String.format("%02x", b & 0xff));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert hex string to byte array. The string length must be an even number.
|
||||
*/
|
||||
@UsedForTesting
|
||||
@Nullable
|
||||
public static byte[] hexStringToByteArray(@Nullable final String hexString) {
|
||||
if (isEmpty(hexString)) {
|
||||
return null;
|
||||
}
|
||||
final int N = hexString.length();
|
||||
if (N % 2 != 0) {
|
||||
throw new NumberFormatException("Input hex string length must be an even number."
|
||||
+ " Length = " + N);
|
||||
}
|
||||
final byte[] bytes = new byte[N / 2];
|
||||
for (int i = 0; i < N; i += 2) {
|
||||
bytes[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
|
||||
+ Character.digit(hexString.charAt(i + 1), 16));
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
private static final String LANGUAGE_GREEK = "el";
|
||||
|
||||
@NonNull
|
||||
|
@ -634,58 +598,6 @@ public final class StringUtils {
|
|||
return lastIndex - i;
|
||||
}
|
||||
|
||||
@UsedForTesting
|
||||
public static class Stringizer<E> {
|
||||
@NonNull
|
||||
private static final String[] EMPTY_STRING_ARRAY = new String[0];
|
||||
|
||||
@UsedForTesting
|
||||
@NonNull
|
||||
public String stringize(@Nullable final E element) {
|
||||
if (element == null) {
|
||||
return "null";
|
||||
}
|
||||
return element.toString();
|
||||
}
|
||||
|
||||
@UsedForTesting
|
||||
@NonNull
|
||||
public final String join(@Nullable final E[] array) {
|
||||
return joinStringArray(toStringArray(array), null /* delimiter */);
|
||||
}
|
||||
|
||||
@UsedForTesting
|
||||
public final String join(@Nullable final E[] array, @Nullable final String delimiter) {
|
||||
return joinStringArray(toStringArray(array), delimiter);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
protected String[] toStringArray(@Nullable final E[] array) {
|
||||
if (array == null) {
|
||||
return EMPTY_STRING_ARRAY;
|
||||
}
|
||||
final String[] stringArray = new String[array.length];
|
||||
for (int index = 0; index < array.length; index++) {
|
||||
stringArray[index] = stringize(array[index]);
|
||||
}
|
||||
return stringArray;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
protected String joinStringArray(@NonNull final String[] stringArray,
|
||||
@Nullable final String delimiter) {
|
||||
if (delimiter == null) {
|
||||
return Arrays.toString(stringArray);
|
||||
}
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
for (int index = 0; index < stringArray.length; index++) {
|
||||
sb.append(index == 0 ? "[" : delimiter);
|
||||
sb.append(stringArray[index]);
|
||||
}
|
||||
return sb + "]";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the last composed word contains line-breaking character (e.g. CR or LF).
|
||||
*
|
||||
|
|
|
@ -84,7 +84,7 @@ final class SuggestionStripLayoutHelper {
|
|||
private final int mCenterPositionInStrip;
|
||||
private final int mTypedWordPositionWhenAutocorrect;
|
||||
private final Drawable mMoreSuggestionsHint;
|
||||
private static final String MORE_SUGGESTIONS_HINT = "\u2026";
|
||||
private static final String MORE_SUGGESTIONS_HINT = "…";
|
||||
|
||||
private static final CharacterStyle BOLD_SPAN = new StyleSpan(Typeface.BOLD);
|
||||
private static final CharacterStyle UNDERLINE_SPAN = new UnderlineSpan();
|
||||
|
@ -106,8 +106,7 @@ final class SuggestionStripLayoutHelper {
|
|||
final TextView wordView = wordViews.get(0);
|
||||
final View dividerView = dividerViews.get(0);
|
||||
mPadding = wordView.getCompoundPaddingLeft() + wordView.getCompoundPaddingRight();
|
||||
dividerView.measure(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
|
||||
dividerView.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
|
||||
mDividerWidth = dividerView.getMeasuredWidth();
|
||||
|
||||
final Resources res = wordView.getResources();
|
||||
|
@ -116,10 +115,8 @@ final class SuggestionStripLayoutHelper {
|
|||
|
||||
final TypedArray a = context.obtainStyledAttributes(attrs,
|
||||
R.styleable.SuggestionStripView, defStyle, R.style.SuggestionStripView);
|
||||
mSuggestionStripOptions = a.getInt(
|
||||
R.styleable.SuggestionStripView_suggestionStripOptions, 0);
|
||||
mAlphaObsoleted = ResourceUtils.getFraction(a,
|
||||
R.styleable.SuggestionStripView_alphaObsoleted, 1.0f);
|
||||
mSuggestionStripOptions = a.getInt(R.styleable.SuggestionStripView_suggestionStripOptions, 0);
|
||||
mAlphaObsoleted = ResourceUtils.getFraction(a, R.styleable.SuggestionStripView_alphaObsoleted, 1.0f);
|
||||
|
||||
final Colors colors = Settings.getInstance().getCurrent().mColors;
|
||||
mColorValidTypedWord = colors.get(ColorType.SUGGESTION_VALID_WORD);
|
||||
|
@ -168,9 +165,7 @@ final class SuggestionStripLayoutHelper {
|
|||
if (currentHeight <= remainingHeight) {
|
||||
return;
|
||||
}
|
||||
|
||||
mMaxMoreSuggestionsRow = (remainingHeight - mMoreSuggestionsBottomGap)
|
||||
/ mMoreSuggestionsRowHeight;
|
||||
mMaxMoreSuggestionsRow = (remainingHeight - mMoreSuggestionsBottomGap) / mMoreSuggestionsRowHeight;
|
||||
}
|
||||
|
||||
private static Drawable getMoreSuggestionsHint(final Resources res, final float textSize, final int color) {
|
||||
|
@ -243,8 +238,7 @@ final class SuggestionStripLayoutHelper {
|
|||
final boolean shouldShowUiToAcceptTypedWord) {
|
||||
final boolean omitTypedWord = (inputStyle == SuggestedWords.INPUT_STYLE_TYPING)
|
||||
|| (inputStyle == SuggestedWords.INPUT_STYLE_TAIL_BATCH)
|
||||
|| (inputStyle == SuggestedWords.INPUT_STYLE_UPDATE_BATCH
|
||||
&& gestureFloatingPreviewTextEnabled);
|
||||
|| (inputStyle == SuggestedWords.INPUT_STYLE_UPDATE_BATCH && gestureFloatingPreviewTextEnabled);
|
||||
return shouldShowUiToAcceptTypedWord && omitTypedWord;
|
||||
}
|
||||
|
||||
|
@ -264,10 +258,8 @@ final class SuggestionStripLayoutHelper {
|
|||
// If neither of those, the order in the suggestion strip is left of the center first
|
||||
// then right of the center, to both edges of the suggestion strip.
|
||||
// For example, center-1, center+1, center-2, center+2, and so on.
|
||||
final int n = indexInSuggestedWords;
|
||||
final int offsetFromCenter = (n % 2) == 0 ? -(n / 2) : (n / 2);
|
||||
final int positionInSuggestionStrip = centerPositionInStrip + offsetFromCenter;
|
||||
return positionInSuggestionStrip;
|
||||
final int offsetFromCenter = (indexInSuggestedWords % 2) == 0 ? -(indexInSuggestedWords / 2) : (indexInSuggestedWords / 2);
|
||||
return centerPositionInStrip + offsetFromCenter;
|
||||
}
|
||||
final int indexToDisplayMostImportantSuggestion;
|
||||
final int indexToDisplaySecondMostImportantSuggestion;
|
||||
|
@ -291,19 +283,16 @@ final class SuggestionStripLayoutHelper {
|
|||
// For example, Center+1, center-2, center+2, center-3, and so on.
|
||||
final int n = indexInSuggestedWords + 1;
|
||||
final int offsetFromCenter = (n % 2) == 0 ? -(n / 2) : (n / 2);
|
||||
final int positionInSuggestionStrip = centerPositionInStrip + offsetFromCenter;
|
||||
return positionInSuggestionStrip;
|
||||
return centerPositionInStrip + offsetFromCenter;
|
||||
}
|
||||
|
||||
private int getSuggestionTextColor(final SuggestedWords suggestedWords,
|
||||
final int indexInSuggestedWords) {
|
||||
// Use identity for strings, not #equals : it's the typed word if it's the same object
|
||||
final boolean isTypedWord = suggestedWords.getInfo(indexInSuggestedWords).isKindOf(
|
||||
SuggestedWordInfo.KIND_TYPED);
|
||||
final boolean isTypedWord = suggestedWords.getInfo(indexInSuggestedWords).isKindOf(SuggestedWordInfo.KIND_TYPED);
|
||||
|
||||
final int color;
|
||||
if (indexInSuggestedWords == SuggestedWords.INDEX_OF_AUTO_CORRECTION
|
||||
&& suggestedWords.mWillAutoCorrect) {
|
||||
if (indexInSuggestedWords == SuggestedWords.INDEX_OF_AUTO_CORRECTION && suggestedWords.mWillAutoCorrect) {
|
||||
color = mColorAutoCorrect;
|
||||
} else if (isTypedWord && suggestedWords.mTypedWordValid) {
|
||||
color = mColorValidTypedWord;
|
||||
|
@ -325,8 +314,7 @@ final class SuggestionStripLayoutHelper {
|
|||
|
||||
private static void addDivider(final ViewGroup stripView, final View dividerView) {
|
||||
stripView.addView(dividerView);
|
||||
final LinearLayout.LayoutParams params =
|
||||
(LinearLayout.LayoutParams)dividerView.getLayoutParams();
|
||||
final LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)dividerView.getLayoutParams();
|
||||
params.gravity = Gravity.CENTER;
|
||||
}
|
||||
|
||||
|
@ -387,8 +375,7 @@ final class SuggestionStripLayoutHelper {
|
|||
final int width = getSuggestionWidth(positionInStrip, stripWidth);
|
||||
final TextView wordView = layoutWord(context, positionInStrip, width);
|
||||
stripView.addView(wordView);
|
||||
setLayoutWeight(wordView, getSuggestionWeight(positionInStrip),
|
||||
ViewGroup.LayoutParams.MATCH_PARENT);
|
||||
setLayoutWeight(wordView, getSuggestionWeight(positionInStrip), ViewGroup.LayoutParams.MATCH_PARENT);
|
||||
x += wordView.getMeasuredWidth();
|
||||
|
||||
if (SuggestionStripView.DEBUG_SUGGESTIONS) {
|
||||
|
@ -403,7 +390,7 @@ final class SuggestionStripLayoutHelper {
|
|||
* <code>positionInStrip</code>. When the suggested word doesn't exist, the corresponding
|
||||
* {@link TextView} will be disabled and never respond to user interaction. The suggested word
|
||||
* may be shrunk or ellipsized to fit in the specified width.
|
||||
*
|
||||
* <p>
|
||||
* The <code>positionInStrip</code> argument is the index in the suggestion strip. The indices
|
||||
* increase towards the right for LTR scripts and the left for RTL scripts, starting with 0.
|
||||
* The position of the most important suggestion is in {@link #mCenterPositionInStrip}. This
|
||||
|
@ -419,8 +406,7 @@ final class SuggestionStripLayoutHelper {
|
|||
final CharSequence word = wordView.getText();
|
||||
if (positionInStrip == mCenterPositionInStrip && mMoreSuggestionsAvailable) {
|
||||
// TODO: This "more suggestions hint" should have a nicely designed icon.
|
||||
wordView.setCompoundDrawablesWithIntrinsicBounds(
|
||||
null, null, null, mMoreSuggestionsHint);
|
||||
wordView.setCompoundDrawablesWithIntrinsicBounds(null, null, null, mMoreSuggestionsHint);
|
||||
// HACK: Align with other TextViews that have no compound drawables.
|
||||
wordView.setCompoundDrawablePadding(-mMoreSuggestionsHint.getIntrinsicHeight());
|
||||
} else {
|
||||
|
@ -457,8 +443,7 @@ final class SuggestionStripLayoutHelper {
|
|||
debugInfoView.measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
final int infoWidth = debugInfoView.getMeasuredWidth();
|
||||
final int y = debugInfoView.getMeasuredHeight();
|
||||
ViewLayoutUtils.placeViewAt(
|
||||
debugInfoView, x - infoWidth, y, infoWidth, debugInfoView.getMeasuredHeight());
|
||||
ViewLayoutUtils.placeViewAt(debugInfoView, x - infoWidth, y, infoWidth, debugInfoView.getMeasuredHeight());
|
||||
}
|
||||
|
||||
private int getSuggestionWidth(final int positionInStrip, final int maxWidth) {
|
||||
|
@ -539,16 +524,14 @@ final class SuggestionStripLayoutHelper {
|
|||
|
||||
static void setLayoutWeight(final View v, final float weight, final int height) {
|
||||
final ViewGroup.LayoutParams lp = v.getLayoutParams();
|
||||
if (lp instanceof LinearLayout.LayoutParams) {
|
||||
final LinearLayout.LayoutParams llp = (LinearLayout.LayoutParams)lp;
|
||||
if (lp instanceof final LinearLayout.LayoutParams llp) {
|
||||
llp.weight = weight;
|
||||
llp.width = 0;
|
||||
llp.height = height;
|
||||
}
|
||||
}
|
||||
|
||||
private static float getTextScaleX(@Nullable final CharSequence text, final int maxWidth,
|
||||
final TextPaint paint) {
|
||||
private static float getTextScaleX(@Nullable final CharSequence text, final int maxWidth, final TextPaint paint) {
|
||||
paint.setTextScaleX(1.0f);
|
||||
final int width = getTextWidth(text, paint);
|
||||
if (width <= maxWidth || maxWidth <= 0) {
|
||||
|
@ -575,8 +558,7 @@ final class SuggestionStripLayoutHelper {
|
|||
final boolean hasUnderlineStyle = hasStyleSpan(text, UNDERLINE_SPAN);
|
||||
// TextUtils.ellipsize erases any span object existed after ellipsized point.
|
||||
// We have to restore these spans afterward.
|
||||
final CharSequence ellipsizedText = TextUtils.ellipsize(
|
||||
text, paint, maxWidth, TextUtils.TruncateAt.MIDDLE);
|
||||
final CharSequence ellipsizedText = TextUtils.ellipsize(text, paint, maxWidth, TextUtils.TruncateAt.MIDDLE);
|
||||
if (!hasBoldStyle && !hasUnderlineStyle) {
|
||||
return ellipsizedText;
|
||||
}
|
||||
|
|
|
@ -60,9 +60,10 @@ public final class JniUtils {
|
|||
} else {
|
||||
// delete if checksum doesn't match
|
||||
// this actually is bad if we can't get the application and the user has a different library than expected
|
||||
// todo: this is disabled until app is renamed, otherwise it will delete everyone's library!
|
||||
// though there could be a default check?
|
||||
// todo: until the app is renamed, we continue loading the library anyway
|
||||
// userSuppliedLibrary.delete();
|
||||
System.load(userSuppliedLibrary.getAbsolutePath());
|
||||
sHaveGestureLib = true;
|
||||
}
|
||||
} catch (Throwable t) { // catch everything, maybe provided library simply doesn't work
|
||||
Log.w(TAG, "Could not load user-supplied library", t);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue