work on a bunch of todos

This commit is contained in:
Helium314 2024-02-03 10:59:46 +01:00
parent f06193f1f0
commit 38fd364178
265 changed files with 1002 additions and 1696 deletions

View file

@ -1,27 +0,0 @@
/*
* Copyright (C) 2011 The Android Open Source Project
* modified
* SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only
*/
package helium314.keyboard.compat
import android.content.Context
import android.text.Spannable
import android.text.SpannableString
import android.text.Spanned
import android.text.style.SuggestionSpan
import java.util.*
// todo: this is not compat any more
object SuggestionSpanUtils {
@JvmStatic
fun getTextWithAutoCorrectionIndicatorUnderline(context: Context?, text: String, locale: Locale?): CharSequence {
if (text.isEmpty())
return text
val spannable: Spannable = SpannableString(text)
val suggestionSpan = SuggestionSpan(context, locale, arrayOf(), SuggestionSpan.FLAG_AUTO_CORRECTION, null)
spannable.setSpan(suggestionSpan, 0, text.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE or Spanned.SPAN_COMPOSING)
return spannable
}
}

View file

@ -1172,7 +1172,6 @@ public class Key implements Comparable<Key> {
actionFlags |= ACTION_FLAGS_ALT_CODE_WHILE_TYPING;
mActionFlags = actionFlags;
// todo: for what it is actually used? maybe it could be removed?
final int altCodeInAttr; // settings and language switch keys have alt code space, all others nothing
if (mCode == Constants.CODE_SETTINGS || mCode == Constants.CODE_LANGUAGE_SWITCH)
altCodeInAttr = Constants.CODE_SPACE;

View file

@ -115,7 +115,6 @@ class ClipboardHistoryView @JvmOverloads constructor(
spacebar.tag = Constants.CODE_SPACE
spacebar.setOnTouchListener(this)
spacebar.setOnClickListener(this)
// todo: add more buttons, like select all, arrow keys, copy, clear (and maybe start/end select?)
val clipboardStrip = KeyboardSwitcher.getInstance().clipboardStrip
toolbarKeys.forEach {
clipboardStrip.addView(it)

View file

@ -87,17 +87,17 @@ final class EmojiCategory {
R.styleable.EmojiPalettesView_iconEmojiCategory10Tab };
private static final int[] sAccessibilityDescriptionResourceIdsForCategories = {
R.string.spoken_descrption_emoji_category_recents,
R.string.spoken_descrption_emoji_category_eight_smiley_people, // todo: actually this is smiley only... and duplicate string
R.string.spoken_descrption_emoji_category_eight_smiley_people,
R.string.spoken_descrption_emoji_category_eight_animals_nature,
R.string.spoken_descrption_emoji_category_eight_food_drink,
R.string.spoken_descrption_emoji_category_eight_travel_places,
R.string.spoken_descrption_emoji_category_eight_activity,
R.string.spoken_descrption_emoji_category_objects,
R.string.spoken_descrption_emoji_category_symbols,
R.string.spoken_descrption_emoji_category_flags,
R.string.spoken_descrption_emoji_category_emoticons };
R.string.spoken_description_emoji_category_recents,
R.string.spoken_description_emoji_category_eight_smiley,
R.string.spoken_description_emoji_category_eight_smiley_people,
R.string.spoken_description_emoji_category_eight_animals_nature,
R.string.spoken_description_emoji_category_eight_food_drink,
R.string.spoken_description_emoji_category_eight_travel_places,
R.string.spoken_description_emoji_category_eight_activity,
R.string.spoken_description_emoji_category_objects,
R.string.spoken_description_emoji_category_symbols,
R.string.spoken_description_emoji_category_flags,
R.string.spoken_description_emoji_category_emoticons};
private static final int[] sCategoryElementId = {
KeyboardId.ELEMENT_EMOJI_RECENTS,

View file

@ -17,6 +17,8 @@ import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyType
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.SimplePopups
import helium314.keyboard.latin.R
import helium314.keyboard.latin.common.Constants
import helium314.keyboard.latin.common.LocaleUtils
import helium314.keyboard.latin.common.LocaleUtils.constructLocale
import helium314.keyboard.latin.common.isEmoji
import helium314.keyboard.latin.common.splitOnWhitespace
import helium314.keyboard.latin.define.DebugFlags
@ -455,8 +457,6 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
SimplePopups(moreKeys?.let { getCommaMoreKeys() + it } ?: getCommaMoreKeys())
)
FunctionalKey.PERIOD -> KeyParams(
// special period moreKey only in alphabet layout, except for ar and fa
// todo: here is not the place to decide this, put it somewhere else (labelPeriod and labelPeriodSymbols?)
label ?: getPeriodLabel(),
params,
width,
@ -665,12 +665,9 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
}
private fun getInLocale(@StringRes id: Int): String {
val locale = when (params.mId.locale.toString().lowercase()) {
// todo: improve this when switching (rich input) subtype to use language tag
"hi_zz" -> Locale("en", "IN")
"sr_zz" -> Locale.forLanguageTag("sr-Latn")
else -> params.mId.locale
}
// todo: hi-Latn strings instead of this workaround?
val locale = if (params.mId.locale.toLanguageTag() == "hi-Latn") "en_IN".constructLocale()
else params.mId.locale
return runInLocale(context, locale) { it.getString(id) }
}
@ -703,7 +700,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
private fun getPeriodLabel(): String {
if (params.mId.isNumberLayout) return "."
if (params.mId.isAlphabetKeyboard || params.mId.locale.language in listOf("ar", "fa"))
if (params.mId.isAlphabetKeyboard || params.mId.locale.language in listOf("ar", "fa")) // todo: this exception is not so great...
return params.mLocaleKeyTexts.labelPeriod
return "."
}
@ -738,7 +735,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
return listOf("")
if (params.mId.isNumberLayout)
return listOf(":", "", ";", "", "π", "", "°", "^")
val moreKeys = params.mLocaleKeyTexts.getMoreKeys("punctuation")!!
val moreKeys = params.mLocaleKeyTexts.getMoreKeys("punctuation")!!.toMutableList()
if (params.mId.mSubtype.isRtlSubtype) {
for (i in moreKeys.indices)
moreKeys[i] = moreKeys[i].rtlLabel(params) // for parentheses
@ -752,7 +749,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
if (columns != null)
moreKeys[0] = "${Key.MORE_KEYS_AUTO_COLUMN_ORDER}${columns - 1}"
}
return moreKeys.toList()
return moreKeys
}
private fun getSpaceLabel(): String =

View file

@ -16,8 +16,8 @@ import java.util.Locale
import kotlin.math.round
class LocaleKeyTexts(dataStream: InputStream?, locale: Locale) {
private val moreKeys = hashMapOf<String, Array<String>>() // todo: no need for arrays any more, better use a list?
private val priorityMoreKeys = hashMapOf<String, Array<String>>()
private val moreKeys = hashMapOf<String, List<String>>()
private val priorityMoreKeys = hashMapOf<String, List<String>>()
private val extraKeys = Array<MutableList<KeyData>?>(5) { null }
var labelSymbol = "\\?123"
private set
@ -50,15 +50,15 @@ class LocaleKeyTexts(dataStream: InputStream?, locale: Locale) {
// set default quote moreKeys if necessary
// should this also be done with punctuation moreKeys?
if ("\'" !in moreKeys)
moreKeys["\'"] = arrayOf("!fixedColumnOrder!5", "", "", "", "", "")
moreKeys["\'"] = listOf("!fixedColumnOrder!5", "", "", "", "", "")
if ("\"" !in moreKeys)
moreKeys["\""] = arrayOf("!fixedColumnOrder!5", "", "", "", "«", "»")
moreKeys["\""] = listOf("!fixedColumnOrder!5", "", "", "", "«", "»")
if ("!" !in moreKeys)
moreKeys["!"] = arrayOf("¡")
moreKeys["!"] = listOf("¡")
if (labelQuestion !in moreKeys)
moreKeys[labelQuestion] = if (labelQuestion == "?") arrayOf("¿") else arrayOf("?", "¿")
moreKeys[labelQuestion] = if (labelQuestion == "?") listOf("¿") else listOf("?", "¿")
if ("punctuation" !in moreKeys)
moreKeys["punctuation"] = arrayOf("${Key.MORE_KEYS_AUTO_COLUMN_ORDER}8", "\\,", "?", "!", "#", ")", "(", "/", ";", "'", "@", ":", "-", "\"", "+", "\\%", "&")
moreKeys["punctuation"] = listOf("${Key.MORE_KEYS_AUTO_COLUMN_ORDER}8", "\\,", "?", "!", "#", ")", "(", "/", ";", "'", "@", ":", "-", "\"", "+", "\\%", "&")
}
private fun readStream(stream: InputStream?, onlyMoreKeys: Boolean) {
@ -98,8 +98,8 @@ class LocaleKeyTexts(dataStream: InputStream?, locale: Locale) {
fun getShiftSymbolLabel(isTablet: Boolean) = if (isTablet) labelShiftSymbolTablet else labelShiftSymbol
fun getMoreKeys(label: String): Array<String>? = moreKeys[label]
fun getPriorityMoreKeys(label: String): Array<String>? = priorityMoreKeys[label]
fun getMoreKeys(label: String): List<String>? = moreKeys[label]
fun getPriorityMoreKeys(label: String): List<String>? = priorityMoreKeys[label]
// used by simple parser only, but could be possible for json as well (if necessary)
fun getExtraKeys(row: Int): List<KeyData>? =
@ -122,17 +122,17 @@ class LocaleKeyTexts(dataStream: InputStream?, locale: Locale) {
if (priorityMarkerIndex > 0) {
val existingPriorityMoreKeys = priorityMoreKeys[key]
priorityMoreKeys[key] = if (existingPriorityMoreKeys == null)
Array(priorityMarkerIndex - 1) { split[it + 1] }
split.subList(1, priorityMarkerIndex)
else existingPriorityMoreKeys + split.subList(1, priorityMarkerIndex)
val existingMoreKeys = moreKeys[key]
moreKeys[key] = if (existingMoreKeys == null)
Array(split.size - priorityMarkerIndex - 1) { split[it + priorityMarkerIndex + 1] }
split.subList(priorityMarkerIndex, split.size)
else existingMoreKeys + split.subList(priorityMarkerIndex, split.size)
} else {
// a but more special treatment, this should not occur together with priority marker (but technically could)
val existingMoreKeys = moreKeys[key]
val newMoreKeys = if (existingMoreKeys == null)
Array(split.size - 1) { split[it + 1] }
split.drop(1)
else mergeMoreKeys(existingMoreKeys, split.drop(1))
moreKeys[key] = when (key) {
"'", "\"", "«", "»" -> addFixedColumnOrder(newMoreKeys)
@ -191,7 +191,7 @@ class LocaleKeyTexts(dataStream: InputStream?, locale: Locale) {
fun getNumberLabel(numberIndex: Int?): String? = numberIndex?.let { numberKeys.getOrNull(it) }
}
private fun mergeMoreKeys(original: Array<String>, added: List<String>): Array<String> {
private fun mergeMoreKeys(original: List<String>, added: List<String>): List<String> {
if (original.any { it.startsWith(Key.MORE_KEYS_AUTO_COLUMN_ORDER) } || added.any { it.startsWith(Key.MORE_KEYS_AUTO_COLUMN_ORDER) }) {
val moreKeys = (original + added).toSet()
val originalColumnCount = original.firstOrNull { it.startsWith(Key.MORE_KEYS_AUTO_COLUMN_ORDER) }
@ -200,22 +200,17 @@ private fun mergeMoreKeys(original: Array<String>, added: List<String>): Array<S
if (originalColumnCount != null && moreKeys.size <= 20 // not for too wide layout
&& originalColumnCount == round((original.size - 1 + 0.1f) / 2f).toInt()) { // +0.1 f against rounding issues
// we had 2 rows, and want it again
return (l + "${Key.MORE_KEYS_AUTO_COLUMN_ORDER}${round(l.size / 2f).toInt()}").toTypedArray()
return (l + "${Key.MORE_KEYS_AUTO_COLUMN_ORDER}${round(l.size / 2f).toInt()}")
}
// just drop autoColumnOrder otherwise
return l.toTypedArray()
return l
}
return original + added
}
private fun addFixedColumnOrder(moreKeys: Array<String>): Array<String> {
if (moreKeys.none { it.startsWith(Key.MORE_KEYS_FIXED_COLUMN_ORDER) })
return arrayOf("${Key.MORE_KEYS_FIXED_COLUMN_ORDER}${moreKeys.size}", *moreKeys)
private fun addFixedColumnOrder(moreKeys: List<String>): List<String> {
val newMoreKeys = moreKeys.filterNot { it.startsWith(Key.MORE_KEYS_FIXED_COLUMN_ORDER) }
return Array(newMoreKeys.size + 1) {
if (it == 0) "${Key.MORE_KEYS_FIXED_COLUMN_ORDER}${newMoreKeys.size}"
else newMoreKeys[it - 1]
}
return listOf("${Key.MORE_KEYS_FIXED_COLUMN_ORDER}${newMoreKeys.size}") + newMoreKeys
}
fun getOrCreate(context: Context, locale: Locale): LocaleKeyTexts =

View file

@ -86,7 +86,7 @@ public interface DictionaryFacilitator {
boolean isActive();
Locale getLocale();
Locale getMainLocale();
// useful for multilingual typing
Locale getCurrentLocale();

View file

@ -30,7 +30,6 @@ import helium314.keyboard.latin.personalization.UserHistoryDictionary;
import helium314.keyboard.latin.settings.Settings;
import helium314.keyboard.latin.settings.SettingsValuesForSuggestion;
import helium314.keyboard.latin.utils.ExecutorUtils;
import helium314.keyboard.latin.utils.SubtypeUtilsKt;
import helium314.keyboard.latin.utils.SuggestionResults;
import java.io.File;
@ -267,13 +266,8 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
return !mDictionaryGroups.get(0).mLocale.getLanguage().isEmpty();
}
// used in
// putWordIntoValidSpellingWordCache -> should probably return most confidence locale, but the cache is not used anyway
// LatinIME.resetSuggestMainDict -> should return primary locale
// Suggest.getSuggestedWordsFor... -> should not matter if suggestions have a word locale, todo: check whether they do!
// InputLogic.getDictionaryFacilitatorLocale -> not sure, but probably doesn't matter
@Override
public Locale getLocale() {
public Locale getMainLocale() {
return mDictionaryGroups.get(0).mLocale;
}
@ -640,12 +634,12 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
return;
}
final String lowerCaseWord = originalWord.toLowerCase(getLocale());
final String lowerCaseWord = originalWord.toLowerCase(getCurrentLocale());
final boolean lowerCaseValid = isValidSpellingWord(lowerCaseWord);
mValidSpellingWordWriteCache.put(lowerCaseWord, lowerCaseValid);
final String capitalWord =
StringUtils.capitalizeFirstAndDowncaseRest(originalWord, getLocale());
StringUtils.capitalizeFirstAndDowncaseRest(originalWord, getCurrentLocale());
final boolean capitalValid;
if (lowerCaseValid) {
// The lower case form of the word is valid, so the upper case must be valid.

View file

@ -42,8 +42,7 @@ import android.view.inputmethod.InputMethodSubtype;
import helium314.keyboard.accessibility.AccessibilityUtils;
import helium314.keyboard.compat.ConfigurationCompatKt;
import helium314.keyboard.compat.EditorInfoCompatUtils;
import helium314.keyboard.compat.InsetsOutlineProvider;
import helium314.keyboard.compat.ViewOutlineProviderCompatUtils;
import helium314.keyboard.latin.common.InsetsOutlineProvider;
import helium314.keyboard.dictionarypack.DictionaryPackConstants;
import helium314.keyboard.event.Event;
import helium314.keyboard.event.HangulEventDecoder;
@ -62,6 +61,7 @@ import helium314.keyboard.latin.common.ColorType;
import helium314.keyboard.latin.common.Constants;
import helium314.keyboard.latin.common.CoordinateUtils;
import helium314.keyboard.latin.common.InputPointers;
import helium314.keyboard.latin.common.ViewOutlineProviderUtilsKt;
import helium314.keyboard.latin.define.DebugFlags;
import helium314.keyboard.latin.define.ProductionFlags;
import helium314.keyboard.latin.inputlogic.InputLogic;
@ -732,7 +732,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
/* package private */ void resetSuggestMainDict() {
final SettingsValues settingsValues = mSettings.getCurrent();
mDictionaryFacilitator.resetDictionaries(this /* context */,
mDictionaryFacilitator.getLocale(), settingsValues.mUseContactsDictionary,
mDictionaryFacilitator.getMainLocale(), settingsValues.mUseContactsDictionary,
settingsValues.mUsePersonalizedDicts,
true /* forceReloadMainDictionary */,
settingsValues.mAccount, "" /* dictNamePrefix */,
@ -844,7 +844,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
public void setInputView(final View view) {
super.setInputView(view);
mInputView = view;
mInsetsUpdater = ViewOutlineProviderCompatUtils.setInsetsOutlineProvider(view);
mInsetsUpdater = ViewOutlineProviderUtilsKt.setInsetsOutlineProvider(view);
updateSoftInputWindowLayoutParameters();
mSuggestionStripView = view.findViewById(R.id.suggestion_strip_view);
if (hasSuggestionStripView()) {

View file

@ -155,7 +155,7 @@ public final class Suggest {
: mDictionaryFacilitator.getSuggestionResults(
wordComposer.getComposedDataSnapshot(), ngramContext, keyboard,
settingsValuesForSuggestion, SESSION_ID_TYPING, inputStyleIfNotPrediction);
final Locale locale = mDictionaryFacilitator.getLocale();
final Locale locale = mDictionaryFacilitator.getMainLocale();
final ArrayList<SuggestedWordInfo> suggestionsContainer =
getTransformedSuggestedWordInfoList(wordComposer, suggestionResults,
trailingSingleQuotesCount, locale);
@ -418,7 +418,7 @@ public final class Suggest {
replaceSingleLetterFirstSuggestion(suggestionResults);
// For transforming words that don't come from a dictionary, because it's our best bet
final Locale locale = mDictionaryFacilitator.getLocale();
final Locale locale = mDictionaryFacilitator.getMainLocale();
final ArrayList<SuggestedWordInfo> suggestionsContainer = new ArrayList<>(suggestionResults);
final int suggestionsCount = suggestionsContainer.size();
final boolean isFirstCharCapitalized = wordComposer.wasShiftedNoLock();

View file

@ -0,0 +1,22 @@
/*
* Copyright (C) 2011 The Android Open Source Project
* modified
* SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only
*/
package helium314.keyboard.latin.common
import android.content.Context
import android.text.Spannable
import android.text.SpannableString
import android.text.Spanned
import android.text.style.SuggestionSpan
import java.util.*
fun getTextWithAutoCorrectionIndicatorUnderline(context: Context?, text: String, locale: Locale?): CharSequence {
if (text.isEmpty())
return text
val spannable: Spannable = SpannableString(text)
val suggestionSpan = SuggestionSpan(context, locale, arrayOf(), SuggestionSpan.FLAG_AUTO_CORRECTION, null)
spannable.setSpan(suggestionSpan, 0, text.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE or Spanned.SPAN_COMPOSING)
return spannable
}

View file

@ -3,22 +3,17 @@
* modified
* SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only
*/
package helium314.keyboard.compat
package helium314.keyboard.latin.common
import android.graphics.Outline
import android.inputmethodservice.InputMethodService
import android.view.View
import android.view.ViewOutlineProvider
// todo: this is not compat any more
object ViewOutlineProviderCompatUtils {
@JvmStatic
fun setInsetsOutlineProvider(view: View): InsetsOutlineProvider {
val provider = InsetsOutlineProvider(view)
view.outlineProvider = provider
return provider
}
fun setInsetsOutlineProvider(view: View): InsetsOutlineProvider {
val provider = InsetsOutlineProvider(view)
view.outlineProvider = provider
return provider
}
class InsetsOutlineProvider(private val mView: View) : ViewOutlineProvider() {

View file

@ -13,7 +13,6 @@ import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.BackgroundColorSpan;
import android.text.style.SuggestionSpan;
import helium314.keyboard.latin.utils.Log;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.inputmethod.CorrectionInfo;
@ -21,7 +20,6 @@ import android.view.inputmethod.EditorInfo;
import androidx.annotation.NonNull;
import helium314.keyboard.compat.SuggestionSpanUtils;
import helium314.keyboard.event.Event;
import helium314.keyboard.event.HangulEventDecoder;
import helium314.keyboard.event.InputTransaction;
@ -42,12 +40,14 @@ import helium314.keyboard.latin.common.Constants;
import helium314.keyboard.latin.common.InputPointers;
import helium314.keyboard.latin.common.StringUtils;
import helium314.keyboard.latin.common.StringUtilsKt;
import helium314.keyboard.latin.common.SuggestionSpanUtilsKt;
import helium314.keyboard.latin.define.DebugFlags;
import helium314.keyboard.latin.settings.SettingsValues;
import helium314.keyboard.latin.settings.SpacingAndPunctuations;
import helium314.keyboard.latin.suggestions.SuggestionStripViewAccessor;
import helium314.keyboard.latin.utils.AsyncResultHolder;
import helium314.keyboard.latin.utils.InputTypeUtils;
import helium314.keyboard.latin.utils.Log;
import helium314.keyboard.latin.utils.RecapitalizeStatus;
import helium314.keyboard.latin.utils.ScriptUtils;
import helium314.keyboard.latin.utils.StatsUtils;
@ -2023,12 +2023,12 @@ public final class InputLogic {
}
/**
* @return the {@link Locale} of the {@link #mDictionaryFacilitator} if available. Otherwise
* @return the current {@link Locale} of the {@link #mDictionaryFacilitator} if available. Otherwise
* {@link Locale#ROOT}.
*/
@NonNull
private Locale getDictionaryFacilitatorLocale() {
return mDictionaryFacilitator != null ? mDictionaryFacilitator.getLocale() : Locale.ROOT;
return mDictionaryFacilitator != null ? mDictionaryFacilitator.getCurrentLocale() : Locale.ROOT;
}
/**
@ -2052,7 +2052,7 @@ public final class InputLogic {
private CharSequence getTextWithUnderline(final String text) {
// TODO: Locale should be determined based on context and the text given.
return mIsAutoCorrectionIndicatorOn
? SuggestionSpanUtils.getTextWithAutoCorrectionIndicatorUnderline(
? SuggestionSpanUtilsKt.getTextWithAutoCorrectionIndicatorUnderline(
mLatinIME, text, getDictionaryFacilitatorLocale())
: text;
}

View file

@ -14,6 +14,7 @@ import helium314.keyboard.latin.PunctuationSuggestions;
import helium314.keyboard.latin.R;
import helium314.keyboard.latin.common.Constants;
import helium314.keyboard.latin.common.StringUtils;
import helium314.keyboard.latin.common.StringUtilsKt;
import java.util.Arrays;
import java.util.Locale;
@ -74,10 +75,13 @@ public final class SpacingAndPunctuations {
}
public boolean containsSometimesWordConnector(final CharSequence word) {
// todo: this only works if all mSortedSometimesWordConnectors are simple chars
for (int i = 0; i < word.length(); i++) {
if (isSometimesWordConnector(word.charAt(i)))
return true;
final String s = (word instanceof String) ? (String) word : word.toString();
final int length = s.length();
int offset = 0;
while (offset < length) {
int cp = s.codePointAt(offset);
if (isSometimesWordConnector(cp)) return true;
offset += Character.charCount(cp);
}
return false;
}