1
0
Fork 0

Punctuation reordering (#639)

This commit is contained in:
Dimo Karaivanov 2024-10-01 10:31:46 +03:00 committed by GitHub
parent aee242b8fa
commit 9043165395
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
38 changed files with 808 additions and 26 deletions

View file

@ -75,11 +75,7 @@ public class CustomWordFile {
return null;
}
try {
return LanguageCollection.getLanguage(context, Integer.parseInt(parts[1]));
} catch (NumberFormatException e) {
return null;
}
return LanguageCollection.getLanguage(context, parts[1]);
}
@NonNull public static String getWord(String line) {

View file

@ -32,11 +32,17 @@ abstract public class InputMode {
protected int autoAcceptTimeout = -1;
@NonNull protected String digitSequence = "";
protected Language language;
protected final SettingsStore settings;
protected final ArrayList<String> suggestions = new ArrayList<>();
@NonNull protected Runnable onSuggestionsUpdated = () -> {};
protected int specialCharSelectedGroup = 0;
protected InputMode(SettingsStore settings) {
this.settings = settings;
}
public static InputMode getInstance(SettingsStore settings, Language language, InputType inputType, TextField textField, int mode) {
switch (mode) {
case MODE_PREDICTIVE:
@ -44,11 +50,11 @@ abstract public class InputMode {
case MODE_ABC:
return new ModeABC(settings, inputType, language);
case MODE_PASSTHROUGH:
return new ModePassthrough();
return new ModePassthrough(settings);
default:
Logger.w("InputMode", "Defaulting to mode: " + Mode123.class.getName() + " for unknown InputMode: " + mode);
case MODE_123:
return new Mode123(inputType, language);
return new Mode123(settings, inputType, language);
}
}
@ -180,14 +186,14 @@ abstract public class InputMode {
}
int key = digitSequence.charAt(0) - '0';
ArrayList<String> chars = altLanguage.getKeyCharacters(key, specialCharSelectedGroup);
ArrayList<String> chars = settings.getOrderedKeyChars(altLanguage, key, specialCharSelectedGroup);
if (chars.isEmpty() && specialCharSelectedGroup == 1) {
specialCharSelectedGroup = 0;
return false;
} else if (chars.isEmpty()) {
specialCharSelectedGroup = 0;
chars = altLanguage.getKeyCharacters(key, specialCharSelectedGroup);
chars = settings.getOrderedKeyChars(altLanguage, key, specialCharSelectedGroup);
}
suggestions.clear();

View file

@ -8,6 +8,7 @@ import java.util.Collections;
import io.github.sspanak.tt9.hacks.InputType;
import io.github.sspanak.tt9.languages.Language;
import io.github.sspanak.tt9.languages.NaturalLanguage;
import io.github.sspanak.tt9.preferences.settings.SettingsStore;
import io.github.sspanak.tt9.util.Characters;
public class Mode123 extends ModePassthrough {
@ -23,8 +24,10 @@ public class Mode123 extends ModePassthrough {
private final boolean isEmailMode;
public Mode123(InputType inputType, Language language) {
this.language = language;
public Mode123(SettingsStore settings, InputType inputType, Language language) {
super(settings);
changeLanguage(language);
isEmailMode = inputType.isEmail();
if (inputType.isPhoneNumber()) {
@ -55,7 +58,7 @@ public class Mode123 extends ModePassthrough {
private void setDefaultSpecialCharacters() {
// 0-key
KEY_CHARACTERS.add(new ArrayList<>(Collections.singletonList("+")));
for (String character : Characters.Special) {
for (String character : settings.getOrderedKeyChars(language, 0)) {
if (!character.equals("+") && !character.equals("\n")) {
KEY_CHARACTERS.get(0).add(character);
}
@ -63,7 +66,7 @@ public class Mode123 extends ModePassthrough {
// 1-key
KEY_CHARACTERS.add(new ArrayList<>(Collections.singletonList(".")));
for (String character : Characters.PunctuationEnglish) {
for (String character : settings.getOrderedKeyChars(language, 1)) {
if (!character.equals(".")) {
KEY_CHARACTERS.get(1).add(character);
}

View file

@ -14,13 +14,12 @@ import io.github.sspanak.tt9.util.Characters;
public class ModeABC extends InputMode {
private final ArrayList<ArrayList<String>> KEY_CHARACTERS = new ArrayList<>();
private final SettingsStore settings;
private boolean shouldSelectNextLetter = false;
@Override public int getId() { return MODE_ABC; }
ModeABC(SettingsStore settings, InputType inputType, Language lang) {
this.settings = settings;
super(settings);
changeLanguage(lang);
if (inputType.isEmail()) {
@ -55,7 +54,7 @@ public class ModeABC extends InputMode {
autoAcceptTimeout = settings.getAbcAutoAcceptTimeout();
digitSequence = String.valueOf(number);
shouldSelectNextLetter = false;
suggestions.addAll(KEY_CHARACTERS.size() > number ? KEY_CHARACTERS.get(number) : language.getKeyCharacters(number));
suggestions.addAll(KEY_CHARACTERS.size() > number ? KEY_CHARACTERS.get(number) : settings.getOrderedKeyChars(language, number));
suggestions.add(language.getKeyNumber(number));
}

View file

@ -2,9 +2,12 @@ package io.github.sspanak.tt9.ime.modes;
import androidx.annotation.NonNull;
import io.github.sspanak.tt9.preferences.settings.SettingsStore;
// see: InputType.isSpecialNumeric()
public class ModePassthrough extends InputMode {
ModePassthrough() {
ModePassthrough(SettingsStore settings) {
super(settings);
reset();
allowedTextCases.add(CASE_LOWER);
}

View file

@ -25,8 +25,6 @@ public class ModePredictive extends InputMode {
private final ArrayList<ArrayList<String>> KEY_CHARACTERS = new ArrayList<>();
private final SettingsStore settings;
public int getId() { return MODE_PREDICTIVE; }
private String lastAcceptedWord = "";
@ -46,11 +44,12 @@ public class ModePredictive extends InputMode {
ModePredictive(SettingsStore settings, InputType inputType, TextField textField, Language lang) {
super(settings);
autoSpace = new AutoSpace(settings).setLanguage(lang);
autoTextCase = new AutoTextCase(settings);
digitSequence = "";
predictions = new Predictions(settings, textField);
this.settings = settings;
if (inputType.isEmail()) {
KEY_CHARACTERS.add(new ArrayList<>(Characters.Email.get(0)));

View file

@ -204,7 +204,7 @@ public class Predictions {
// append all letters for the last digit in the sequence (the last pressed key)
int lastSequenceDigit = digitSequence.charAt(digitSequence.length() - 1) - '0';
for (String keyLetter : language.getKeyCharacters(lastSequenceDigit)) {
for (String keyLetter : settings.getOrderedKeyChars(language, lastSequenceDigit)) {
if (Character.isAlphabetic(keyLetter.charAt(0)) || Characters.isCombiningPunctuation(language, keyLetter.charAt(0))) {
generatedWords.add(baseWord + keyLetter);
}

View file

@ -38,6 +38,17 @@ public class LanguageCollection {
return self;
}
@Nullable
public static NaturalLanguage getLanguage(Context context, String langId) {
try {
return getLanguage(context, Integer.parseInt(langId));
} catch (NumberFormatException e) {
return null;
}
}
@Nullable
public static NaturalLanguage getLanguage(Context context, int langId) {
if (getInstance(context).languages.containsKey(langId)) {

View file

@ -30,6 +30,7 @@ import io.github.sspanak.tt9.preferences.screens.languages.LanguagesScreen;
import io.github.sspanak.tt9.preferences.screens.main.MainSettingsScreen;
import io.github.sspanak.tt9.preferences.screens.modeAbc.ModeAbcScreen;
import io.github.sspanak.tt9.preferences.screens.modePredictive.ModePredictiveScreen;
import io.github.sspanak.tt9.preferences.screens.punctuation.PunctuationScreen;
import io.github.sspanak.tt9.preferences.screens.setup.SetupScreen;
import io.github.sspanak.tt9.ui.ActivityWithNavigation;
import io.github.sspanak.tt9.util.Logger;
@ -89,10 +90,17 @@ public class PreferencesActivity extends ActivityWithNavigation implements Prefe
@Override
public void onBackPressed() {
Fragment previousFragment = getSupportFragmentManager().findFragmentById(R.id.preferences_container);
if (previousFragment instanceof BaseScreenFragment) {
((BaseScreenFragment) previousFragment).onBackPressed();
}
super.onBackPressed();
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.preferences_container);
if (fragment instanceof BaseScreenFragment) {
getOptionsCount = ((BaseScreenFragment) fragment)::getPreferenceCount;
Fragment nextFragment = getSupportFragmentManager().findFragmentById(R.id.preferences_container);
if (nextFragment instanceof BaseScreenFragment) {
((BaseScreenFragment) nextFragment).onBackPressed();
getOptionsCount = ((BaseScreenFragment) nextFragment)::getPreferenceCount;
}
}
@ -152,6 +160,8 @@ public class PreferencesActivity extends ActivityWithNavigation implements Prefe
return new ModePredictiveScreen(this);
case ModeAbcScreen.NAME:
return new ModeAbcScreen(this);
case PunctuationScreen.NAME:
return new PunctuationScreen(this);
case SetupScreen.NAME:
return new SetupScreen(this);
case UsageStatsScreen.NAME:

View file

@ -1,5 +1,6 @@
package io.github.sspanak.tt9.preferences.items;
import androidx.annotation.Nullable;
import androidx.preference.DropDownPreference;
import androidx.preference.Preference;
@ -80,4 +81,8 @@ abstract public class ItemDropDown {
}
return this;
}
@Nullable public String getValue() {
return item != null ? item.getValue() : null;
}
}

View file

@ -21,6 +21,7 @@ import io.github.sspanak.tt9.util.Logger;
abstract public class ItemTextInput extends ScreenPreference implements TextWatcher {
@NonNull private final Handler debouncer = new Handler(Looper.getMainLooper());
private EditText editText;
public ItemTextInput(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
@ -45,6 +46,7 @@ abstract public class ItemTextInput extends ScreenPreference implements TextWatc
if (editText == null) {
Logger.e(getClass().getSimpleName(), "Cannot attach a text change listener. Unable to find the EditText element.");
} else {
this.editText = editText;
editText.addTextChangedListener(this);
editText.setOnKeyListener(this::ignoreEnter);
}
@ -59,7 +61,17 @@ abstract public class ItemTextInput extends ScreenPreference implements TextWatc
@Override
public void afterTextChanged(Editable s) {
debouncer.removeCallbacksAndMessages(null);
debouncer.postDelayed(() -> onChange(s.toString()), SettingsStore.TEXT_INPUT_DEBOUNCE_TIME);
debouncer.postDelayed(() -> onChange(s.toString()), getChangeHandlerDebounceTime());
}
protected int getChangeHandlerDebounceTime() {
return SettingsStore.TEXT_INPUT_DEBOUNCE_TIME;
}
protected void setText(CharSequence text) {
if (editText != null) {
editText.setText(text);
}
}
/**

View file

@ -96,4 +96,6 @@ abstract public class BaseScreenFragment extends PreferenceFragmentCompat {
abstract protected int getTitle();
abstract protected int getXml();
abstract protected void onCreate();
public void onBackPressed() {}
}

View file

@ -0,0 +1,93 @@
package io.github.sspanak.tt9.preferences.screens.punctuation;
import android.content.Context;
import android.util.AttributeSet;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.preference.PreferenceViewHolder;
import io.github.sspanak.tt9.R;
import io.github.sspanak.tt9.languages.Language;
import io.github.sspanak.tt9.preferences.items.ItemTextInput;
import io.github.sspanak.tt9.preferences.settings.SettingsStore;
abstract class AbstractPreferenceCharList extends ItemTextInput {
@NonNull protected String currentChars = "";
protected Language language;
private Runnable onRender;
protected static SettingsStore settings;
AbstractPreferenceCharList(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); }
AbstractPreferenceCharList(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); }
AbstractPreferenceCharList(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); }
AbstractPreferenceCharList(@NonNull Context context) { super(context); }
@Override
public void onBindViewHolder(@NonNull PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
if (holder.itemView.findViewById(R.id.input_text_input_field) != null && onRender != null) {
onRender.run();
}
}
@Override
protected int getChangeHandlerDebounceTime() {
return SettingsStore.TEXT_INPUT_PUNCTUATION_ORDER_DEBOUNCE_TIME;
}
protected SettingsStore getSettings() {
if (settings == null) {
settings = new SettingsStore(getContext());
}
return settings;
}
@Override
protected void onChange(String word) {
currentChars = word == null ? "" : word;
validateCurrentChars();
}
void onLanguageChange(Language language) {
this.language = language;
String all = getChars();
char[] mandatory = getMandatoryChars();
StringBuilder optional = new StringBuilder();
for (int i = 0; i < all.length(); i++) {
char c = all.charAt(i);
boolean isMandatory = false;
for (char m : mandatory) {
if (m == c) {
isMandatory = true;
break;
}
}
if (!isMandatory) {
optional.append(c);
}
}
setText(optional.toString());
}
void setOnRender(Runnable onRender) {
this.onRender = onRender;
}
@NonNull abstract protected String getChars();
@NonNull abstract protected char[] getMandatoryChars();
abstract public boolean validateCurrentChars();
abstract public void saveCurrentChars();
}

View file

@ -0,0 +1,68 @@
package io.github.sspanak.tt9.preferences.screens.punctuation;
import androidx.preference.DropDownPreference;
import androidx.preference.Preference;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import io.github.sspanak.tt9.languages.Language;
import io.github.sspanak.tt9.languages.LanguageCollection;
import io.github.sspanak.tt9.preferences.items.ItemDropDown;
import io.github.sspanak.tt9.preferences.settings.SettingsStore;
import io.github.sspanak.tt9.util.ConsumerCompat;
class ItemPunctuationOrderLanguage extends ItemDropDown {
public static final String NAME = "punctuation_order_language";
private ConsumerCompat<String> onChangeCallback;
private final SettingsStore settings;
ItemPunctuationOrderLanguage(SettingsStore settings, DropDownPreference item) {
super(item);
this.settings = settings;
}
@Override
public ItemDropDown populate() {
populateLanguages();
return this;
}
private void populateLanguages() {
if (item == null) {
return;
}
LinkedHashMap<String, String> values = new LinkedHashMap<>();
ArrayList<Language> languages = LanguageCollection.getAll(item.getContext(), settings.getEnabledLanguageIds(), true);
if (languages.isEmpty()) {
return;
}
for (Language lang : languages) {
values.put(String.valueOf(lang.getId()), lang.getName());
}
super.populate(values);
super.setValue(String.valueOf(languages.get(0).getId()));
}
ItemPunctuationOrderLanguage onChange(ConsumerCompat<String> callback) {
onChangeCallback = callback;
return this;
}
@Override
protected boolean onClick(Preference preference, Object newKey) {
if (super.onClick(preference, newKey)) {
if (onChangeCallback != null) {
onChangeCallback.accept(newKey.toString());
}
return true;
}
return false;
}
}

View file

@ -0,0 +1,25 @@
package io.github.sspanak.tt9.preferences.screens.punctuation;
import androidx.preference.Preference;
import io.github.sspanak.tt9.preferences.items.ItemClickable;
public class ItemPunctuationOrderSave extends ItemClickable {
public static final String NAME = "punctuation_order_save";
private final Runnable clickHandler;
public ItemPunctuationOrderSave(Preference item, Runnable clickHandler) {
super(item);
this.clickHandler = clickHandler;
}
@Override
protected boolean onClick(Preference p) {
if (clickHandler == null) {
return false;
}
clickHandler.run();
return true;
}
}

View file

@ -0,0 +1,51 @@
package io.github.sspanak.tt9.preferences.screens.punctuation;
import androidx.annotation.NonNull;
import androidx.preference.Preference;
import io.github.sspanak.tt9.languages.Language;
import io.github.sspanak.tt9.preferences.items.ItemClickable;
import io.github.sspanak.tt9.preferences.settings.SettingsStore;
import io.github.sspanak.tt9.util.ConsumerCompat;
class ItemRestoreDefaultPunctuation extends ItemClickable {
public static final String NAME = "punctuation_order_reset_defaults";
private Language language;
private final ConsumerCompat<String> onClick;
private final SettingsStore settings;
ItemRestoreDefaultPunctuation(@NonNull SettingsStore settings, Preference item, ConsumerCompat<String> onClick) {
super(item);
this.onClick = onClick;
this.settings = settings;
}
ItemRestoreDefaultPunctuation setLanguage(Language language) {
this.language = language;
return this;
}
@Override
protected boolean onClick(Preference p) {
if (language == null) {
return false;
}
settings.saveSpecialChars(
language,
String.join("", language.getKeyCharacters(0))
);
settings.savePunctuation(
language,
String.join("", language.getKeyCharacters(1))
);
if (onClick != null) {
onClick.accept(String.valueOf(language.getId()));
}
return true;
}
}

View file

@ -0,0 +1,60 @@
package io.github.sspanak.tt9.preferences.screens.punctuation;
import android.content.Context;
import android.util.AttributeSet;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import io.github.sspanak.tt9.R;
public class PreferenceSentencePunctuationList extends AbstractPreferenceCharList {
public static final String NAME = "punctuation_order_sentence";
public PreferenceSentencePunctuationList(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); }
public PreferenceSentencePunctuationList(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); }
public PreferenceSentencePunctuationList(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); }
public PreferenceSentencePunctuationList(@NonNull Context context) { super(context); }
@Override
@NonNull
protected String getChars() {
return getSettings().getPunctuation(language);
}
/**
* We want to all the user to rearrange all characters even the mandatory ones.
* We will verify if they are present upon saving.
*/
@NonNull
@Override
protected char[] getMandatoryChars() {
return new char[0];
}
public boolean validateCurrentChars() {
StringBuilder missingCharList = new StringBuilder();
for (char c : getSettings().mandatoryPunctuation) {
if (currentChars.indexOf(c) == -1) {
missingCharList.append(" ").append(c).append(",");
}
}
String error = "";
if (missingCharList.length() > 0) {
int message = missingCharList.length() == 3 ? R.string.punctuation_order_mandatory_char_missing : R.string.punctuation_order_mandatory_chars_missing;
String missingChars = missingCharList.substring(0, missingCharList.length() - 1);
error = getContext().getString(message, missingChars);
}
setSummary(error);
return error.isEmpty();
}
@Override
public void saveCurrentChars() {
getSettings().savePunctuation(language, currentChars);
}
}

View file

@ -0,0 +1,48 @@
package io.github.sspanak.tt9.preferences.screens.punctuation;
import android.content.Context;
import android.util.AttributeSet;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public class PreferenceSpecialCharList extends AbstractPreferenceCharList {
public static final String NAME = "punctuation_order_special_chars";
public PreferenceSpecialCharList(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); }
public PreferenceSpecialCharList(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); }
public PreferenceSpecialCharList(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); }
public PreferenceSpecialCharList(@NonNull Context context) { super(context); }
@Override
@NonNull
protected String getChars() {
return getSettings().getSpecialChars(language);
}
@NonNull
@Override
protected char[] getMandatoryChars() {
return getSettings().mandatorySpecialChars;
}
@Override
public boolean validateCurrentChars() {
for (char c : getMandatoryChars()) {
currentChars = currentChars.replace(String.valueOf(c), "");
}
return true;
}
@Override
public void saveCurrentChars() {
StringBuilder all = new StringBuilder();
for (char c : getMandatoryChars()) {
all.append(c);
}
all.append(currentChars);
getSettings().saveSpecialChars(language, all.toString());
}
}

View file

@ -0,0 +1,130 @@
package io.github.sspanak.tt9.preferences.screens.punctuation;
import androidx.annotation.Nullable;
import androidx.preference.Preference;
import io.github.sspanak.tt9.R;
import io.github.sspanak.tt9.languages.Language;
import io.github.sspanak.tt9.languages.LanguageCollection;
import io.github.sspanak.tt9.preferences.PreferencesActivity;
import io.github.sspanak.tt9.preferences.screens.BaseScreenFragment;
public class PunctuationScreen extends BaseScreenFragment {
public static final String NAME = "Punctuation";
private ItemPunctuationOrderLanguage languageList;
private ItemRestoreDefaultPunctuation restoreDefaults;
private PreferenceSpecialCharList specialCharList;
private PreferenceSentencePunctuationList punctuationList;
public PunctuationScreen() { init(); }
public PunctuationScreen(PreferencesActivity activity) { init(activity); }
@Override
public String getName() {
return NAME;
}
@Override
protected int getTitle() {
return R.string.pref_category_punctuation_order;
}
@Override
protected int getXml() {
return R.xml.prefs_screen_punctuation;
}
@Override
public void onBackPressed() {
onSaveOrdering();
}
@Override
protected void onCreate() {
specialCharList = findPreference(PreferenceSpecialCharList.NAME);
punctuationList = findPreference(PreferenceSentencePunctuationList.NAME);
initLanguageList();
initResetDefaults();
initSaveButton();
loadCharLists();
resetFontSize(false);
}
private void initLanguageList() {
languageList = (new ItemPunctuationOrderLanguage(activity.getSettings(), findPreference(ItemPunctuationOrderLanguage.NAME)));
languageList
.onChange(this::onLanguageChanged)
.enableClickHandler()
.populate()
.preview();
}
private void initSaveButton() {
Preference item = findPreference(ItemPunctuationOrderSave.NAME);
if (item != null) {
new ItemPunctuationOrderSave(item, this::onSaveOrdering).enableClickHandler();
}
}
private void initResetDefaults() {
Preference item = findPreference(ItemRestoreDefaultPunctuation.NAME);
if (item == null) {
return;
}
restoreDefaults = new ItemRestoreDefaultPunctuation(activity.getSettings(), item, this::onLanguageChanged);
restoreDefaults
.setLanguage(LanguageCollection.getLanguage(activity, languageList.getValue()))
.enableClickHandler();
}
private void onSaveOrdering() {
if (specialCharList != null && specialCharList.validateCurrentChars()) {
specialCharList.saveCurrentChars();
}
if (punctuationList != null && punctuationList.validateCurrentChars()) {
punctuationList.saveCurrentChars();
}
}
private void onLanguageChanged(@Nullable String newLanguageId) {
Language language = LanguageCollection.getLanguage(activity, newLanguageId);
restoreDefaults.setLanguage(language);
if (specialCharList != null) {
specialCharList.onLanguageChange(language);
}
if (punctuationList != null) {
punctuationList.onLanguageChange(language);
}
}
private void loadCharLists() {
loadCharList(findPreference(PreferenceSpecialCharList.NAME));
loadCharList(findPreference(PreferenceSentencePunctuationList.NAME));
}
private void loadCharList(AbstractPreferenceCharList list) {
if (list == null) {
return;
}
list.setOnRender(() -> {
list.setOnRender(null);
onLanguageChanged(languageList.getValue());
});
}
}

View file

@ -0,0 +1,112 @@
package io.github.sspanak.tt9.preferences.settings;
import android.content.Context;
import androidx.annotation.NonNull;
import java.util.ArrayList;
import io.github.sspanak.tt9.languages.Language;
class SettingsPunctuation extends SettingsInput {
SettingsPunctuation(Context context) {
super(context);
}
public final char[] mandatoryPunctuation = new char[] {'\'', '"', '-'};
public final char[] mandatorySpecialChars = new char[] {' ', '\n'};
public void savePunctuation(@NonNull Language language, @NonNull String punctuation) {
prefsEditor.putString("pref_punctuation_" + language.getId(), punctuation);
prefsEditor.apply();
}
public void saveSpecialChars(@NonNull Language language, @NonNull String specialChars) {
prefsEditor.putString("pref_special_chars_" + language.getId(), specialChars);
prefsEditor.apply();
}
@NonNull public String getPunctuation(Language language) {
return String.join("", getPunctuationAsList(language));
}
@NonNull public String getSpecialChars(Language language) {
return String.join("", getSpecialCharsAsList(language));
}
@NonNull
public ArrayList<String> getPunctuationAsList(Language language) {
if (language == null) {
return new ArrayList<>();
}
return getCharsAsList(
prefs.getString("pref_punctuation_" + language.getId(), null),
language.getKeyCharacters(1)
);
}
@NonNull
public ArrayList<String> getSpecialCharsAsList(Language language) {
if (language == null) {
return new ArrayList<>();
}
return getCharsAsList(
prefs.getString("pref_special_chars_" + language.getId(), null),
language.getKeyCharacters(0)
);
}
@NonNull
public ArrayList<String> getOrderedKeyChars(Language language, int number) {
ArrayList<String> orderedChars = new ArrayList<>();
if (language == null) {
return orderedChars;
}
if (number == 0) {
orderedChars = getSpecialCharsAsList(language);
} else if (number == 1) {
orderedChars = getPunctuationAsList(language);
}
if (orderedChars.isEmpty()) {
orderedChars = language.getKeyCharacters(number);
}
return orderedChars;
}
@NonNull
public ArrayList<String> getOrderedKeyChars(Language language, int number, int group) {
if (group > 0 && language != null) {
return language.getKeyCharacters(number, group);
}
return getOrderedKeyChars(language, number);
}
private ArrayList<String> getCharsAsList(String chars, ArrayList<String> defaultValue) {
if (chars == null) {
return defaultValue;
}
ArrayList<String> charsList = new ArrayList<>();
for (int i = 0; i < chars.length(); i++) {
charsList.add(String.valueOf(chars.charAt(i)));
}
return charsList;
}
}

View file

@ -32,6 +32,7 @@ public class SettingsStore extends SettingsUI {
public final static int SUGGESTIONS_SELECT_ANIMATION_DURATION = 66;
public final static int SUGGESTIONS_TRANSLATE_ANIMATION_DURATION = 0;
public final static int TEXT_INPUT_DEBOUNCE_TIME = 500; // ms
public final static int TEXT_INPUT_PUNCTUATION_ORDER_DEBOUNCE_TIME = 100; // ms
public final static int WORD_BACKGROUND_TASKS_DELAY = 15000; // ms
public final static int WORD_FREQUENCY_MAX = 25500;
public final static int WORD_FREQUENCY_NORMALIZATION_DIVIDER = 100; // normalized frequency = WORD_FREQUENCY_MAX / WORD_FREQUENCY_NORMALIZATION_DIVIDER

View file

@ -2,7 +2,7 @@ package io.github.sspanak.tt9.preferences.settings;
import android.content.Context;
class SettingsTyping extends SettingsInput {
class SettingsTyping extends SettingsPunctuation {
SettingsTyping(Context context) { super(context); }
public int getAbcAutoAcceptTimeout() {

View file

@ -2,6 +2,7 @@ package io.github.sspanak.tt9.util;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Locale;
import java.util.TimeZone;
import java.util.regex.Pattern;

View file

@ -177,4 +177,13 @@
<string name="language_selection_words">думи</string>
<string name="pref_backspace_acceleration">Бързо изтриване</string>
<string name="pref_backspace_acceleration_summary">Изтривай цели думи при задържане или плъзване на Backspace. (Не работи в някои приложения.)</string>
<string name="pref_category_punctuation_order">Ред на пунктуацията</string>
<string name="punctuation_order_whitespace_will_be_added_automatically">Интервал и нов ред ще бъдат автоматично добавени в началото на списъка.</string>
<string name="punctuation_order_mandatory_char_missing">Липсва задължителен символ:%1$s</string>
<string name="punctuation_order_mandatory_chars_missing">Липсват задължителни символи:%1$s</string>
<string name="punctuation_order_sentence">Ред на символите на клавиш 1</string>
<string name="punctuation_order_special">Ред на символите на клавиш 0</string>
<string name="punctuation_order_reset_defaults">Възстанови реда по подразбиране</string>
<string name="language">Език</string>
<string name="punctuation_order_save">Запази подредбата</string>
</resources>

View file

@ -165,4 +165,13 @@
<string name="language_selection_words">Wörter</string>
<string name="pref_backspace_acceleration">Schnelles Löschen</string>
<string name="pref_backspace_acceleration_summary">Ganze Wörter löschen, indem Sie die Rücktaste gedrückt halten oder wischen. (Nicht in allen Apps unterstützt)</string>
<string name="pref_category_punctuation_order">Interpunktionsreihenfolge</string>
<string name="punctuation_order_whitespace_will_be_added_automatically">Leer- und Zeilenumbruchzeichen werden automatisch am Anfang der Liste hinzugefügt.</string>
<string name="punctuation_order_mandatory_char_missing">Fehlendes erforderliches Zeichen:%1$s</string>
<string name="punctuation_order_mandatory_chars_missing">Fehlende erforderliche Zeichen:%1$s</string>
<string name="punctuation_order_sentence">Zeichenreihenfolge der 1-Taste</string>
<string name="punctuation_order_special">Zeichenreihenfolge der 0-Taste</string>
<string name="punctuation_order_reset_defaults">Standardreihenfolge wiederherstellen</string>
<string name="language">Sprache</string>
<string name="punctuation_order_save">Reihenfolge speichern</string>
</resources>

View file

@ -175,4 +175,13 @@
<string name="language_selection_words">palabras</string>
<string name="pref_backspace_acceleration">Eliminación rápida</string>
<string name="pref_backspace_acceleration_summary">Borrar palabras completas manteniendo pulsado o deslizando Retroceso. (No compatible con algunas aplicaciones)</string>
<string name="pref_category_punctuation_order">Orden de puntuación</string>
<string name="punctuation_order_whitespace_will_be_added_automatically">Los caracteres Espacio y Nueva línea se añadirán automáticamente al principio de la lista.</string>
<string name="punctuation_order_mandatory_char_missing">Falta carácter obligatorio:%1$s</string>
<string name="punctuation_order_mandatory_chars_missing">Faltan caracteres obligatorios:%1$s</string>
<string name="punctuation_order_sentence">Orden de caracteres de la tecla 1</string>
<string name="punctuation_order_special">Orden de caracteres de la tecla 0</string>
<string name="punctuation_order_reset_defaults">Restaurar el orden predeterminado</string>
<string name="language">Idioma</string>
<string name="punctuation_order_save">Guardar orden</string>
</resources>

View file

@ -173,4 +173,13 @@
<string name="language_selection_words">mots</string>
<string name="pref_backspace_acceleration">Suppression rapide</string>
<string name="pref_backspace_acceleration_summary">Effacer des mots entiers en maintenant ou en glissant sur Retour arrière. (Non pris en charge dans certaines applications)</string>
<string name="pref_category_punctuation_order">Ordre de ponctuation</string>
<string name="punctuation_order_whitespace_will_be_added_automatically">Les caractères Espace et Retour à la ligne seront automatiquement ajoutés au début de la liste.</string>
<string name="punctuation_order_mandatory_char_missing">Caractère obligatoire manquant :%1$s</string>
<string name="punctuation_order_mandatory_chars_missing">Caractères obligatoires manquants :%1$s</string>
<string name="punctuation_order_sentence">Ordre des caractères de la touche 1</string>
<string name="punctuation_order_special">Ordre des caractères de la touche 0</string>
<string name="punctuation_order_reset_defaults">Restaurer lordre par défaut</string>
<string name="language">Langue</string>
<string name="punctuation_order_save">Enregistrer lordre</string>
</resources>

View file

@ -165,5 +165,14 @@
<string name="language_selection_words">parole</string>
<string name="pref_backspace_acceleration">Cancellazione rapida</string>
<string name="pref_backspace_acceleration_summary">Cancellare intere parole tenendo premuto o scorrendo Backspace. (Non supportato in alcune app)</string>
<string name="pref_category_punctuation_order">Ordine di punteggiatura</string>
<string name="punctuation_order_whitespace_will_be_added_automatically">I caratteri Spazio e Nuova linea verranno automaticamente aggiunti all\'inizio dell\'elenco.</string>
<string name="punctuation_order_mandatory_char_missing">Carattere obbligatorio mancante:%1$s</string>
<string name="punctuation_order_mandatory_chars_missing">Caratteri obbligatori mancanti:%1$s</string>
<string name="punctuation_order_sentence">Ordine dei caratteri del tasto 1</string>
<string name="punctuation_order_special">Ordine dei caratteri del tasto 0</string>
<string name="punctuation_order_reset_defaults">Ripristina ordine predefinito</string>
<string name="language">Lingua</string>
<string name="punctuation_order_save">Salvare l\'ordine</string>
</resources>

View file

@ -178,4 +178,13 @@
<string name="language_selection_words">מילים</string>
<string name="pref_backspace_acceleration">מחיקה מהירה</string>
<string name="pref_backspace_acceleration_summary">למחוק מילים שלמות על ידי החזקת Backspace או החלקה עליו. (לא נתמך בחלק מהאפליקציות)</string>
<string name="pref_category_punctuation_order">סדר סימני פיסוק</string>
<string name="punctuation_order_whitespace_will_be_added_automatically">תווי רווח ושורה חדשה יתווספו אוטומטית בתחילת הרשימה.</string>
<string name="punctuation_order_mandatory_char_missing">תו חובה חסר: %1$s</string>
<string name="punctuation_order_mandatory_chars_missing">תווי חובה חסרים:%1$s</string>
<string name="punctuation_order_sentence">סדר התווים של מקש 1</string>
<string name="punctuation_order_special">סדר התווים של מקש 0</string>
<string name="punctuation_order_reset_defaults">שחזר את הסדר המוגדר כברירת מחדל</string>
<string name="language">שפה</string>
<string name="punctuation_order_save">שמור את הסדר</string>
</resources>

View file

@ -184,4 +184,13 @@
<string name="language_selection_words">žodžių</string>
<string name="pref_backspace_acceleration">Greitas ištrynimas</string>
<string name="pref_backspace_acceleration_summary">Ištrinti visus žodžius laikant arba perbraukiant Backspace. (Nepalaikoma kai kuriose programėlėse)</string>
<string name="pref_category_punctuation_order">Skyrybos ženklų tvarka</string>
<string name="punctuation_order_whitespace_will_be_added_automatically">Tarpas ir naujos eilutės simboliai bus automatiškai pridėti sąrašo pradžioje.</string>
<string name="punctuation_order_mandatory_char_missing">Trūksta privalomo simbolio:%1$s</string>
<string name="punctuation_order_mandatory_chars_missing">Trūksta privalomų simbolių:%1$s</string>
<string name="punctuation_order_sentence">Simbolių tvarka ant klavišo 1</string>
<string name="punctuation_order_special">Simbolių tvarka ant klavišo 0</string>
<string name="punctuation_order_reset_defaults">Atkurti numatytąją tvarką</string>
<string name="language">Kalba</string>
<string name="punctuation_order_save">Išsaugoti tvarką</string>
</resources>

View file

@ -164,4 +164,13 @@
<string name="language_selection_words">woorden</string>
<string name="pref_backspace_acceleration">Snel verwijderen</string>
<string name="pref_backspace_acceleration_summary">Hele woorden wissen door Backspace ingedrukt te houden of te vegen. (Niet ondersteund in sommige apps)</string>
<string name="pref_category_punctuation_order">Interpunctievolgorde</string>
<string name="punctuation_order_whitespace_will_be_added_automatically">Spatie- en nieuwe regeltekens worden automatisch aan het begin van de lijst toegevoegd.</string>
<string name="punctuation_order_mandatory_char_missing">Ontbrekend verplicht teken:%1$s</string>
<string name="punctuation_order_mandatory_chars_missing">Ontbrekende verplichte tekens:%1$s</string>
<string name="punctuation_order_sentence">Tekenvolgorde van de 1-toets</string>
<string name="punctuation_order_special">Tekenvolgorde van de 0-toets</string>
<string name="punctuation_order_reset_defaults">Standaardvolgorde herstellen</string>
<string name="language">Taal</string>
<string name="punctuation_order_save">Volgorde opslaan</string>
</resources>

View file

@ -178,4 +178,13 @@
<string name="language_selection_words">palavras</string>
<string name="pref_backspace_acceleration">Exclusão rápida</string>
<string name="pref_backspace_acceleration_summary">Apagar palavras inteiras mantendo pressionado ou deslizando o Backspace. (Não suportado em alguns aplicativos)</string>
<string name="pref_category_punctuation_order">Ordem de pontuação</string>
<string name="punctuation_order_whitespace_will_be_added_automatically">Os caracteres de Espaço e Nova linha serão automaticamente adicionados no início da lista.</string>
<string name="punctuation_order_mandatory_char_missing">Caractere obrigatório ausente:%1$s</string>
<string name="punctuation_order_mandatory_chars_missing">Caracteres obrigatórios ausentes:%1$s</string>
<string name="punctuation_order_sentence">Ordem de caracteres da tecla 1</string>
<string name="punctuation_order_special">Ordem de caracteres da tecla 0</string>
<string name="punctuation_order_reset_defaults">Restaurar ordem padrão</string>
<string name="language">Idioma</string>
<string name="punctuation_order_save">Salvar ordem</string>
</resources>

View file

@ -175,4 +175,13 @@
<string name="language_selection_words">слов</string>
<string name="pref_backspace_acceleration">Быстрое удаление</string>
<string name="pref_backspace_acceleration_summary">Стереть целые слова, удерживая или проведя по клавише Backspace. (Не поддерживается в некоторых приложениях)</string>
<string name="pref_category_punctuation_order">Порядок пунктуации</string>
<string name="punctuation_order_whitespace_will_be_added_automatically">Пробел и символ новой строки будут автоматически добавлены в начало списка.</string>
<string name="punctuation_order_mandatory_char_missing">Отсутствует обязательный символ:%1$s</string>
<string name="punctuation_order_mandatory_chars_missing">Отсутствуют обязательные символы:%1$s</string>
<string name="punctuation_order_sentence">Порядок символов на клавише 1</string>
<string name="punctuation_order_special">Порядок символов на клавише 0</string>
<string name="punctuation_order_reset_defaults">Восстановить порядок по умолчанию</string>
<string name="language">Язык</string>
<string name="punctuation_order_save">Сохранить порядок</string>
</resources>

View file

@ -178,4 +178,13 @@
<string name="language_selection_words">kelime</string>
<string name="pref_backspace_acceleration">Hızlı Silme</string>
<string name="pref_backspace_acceleration_summary">Geri tuşunu basılı tutarak veya kaydırarak tüm kelimeleri sil. (Bazı uygulamalarda desteklenmez)</string>
<string name="pref_category_punctuation_order">Noktalama sırası</string>
<string name="punctuation_order_whitespace_will_be_added_automatically">Boşluk ve Yeni Satır karakterleri listenin başına otomatik olarak eklenecektir.</string>
<string name="punctuation_order_mandatory_char_missing">Zorunlu karakter eksik:%1$s</string>
<string name="punctuation_order_mandatory_chars_missing">Zorunlu karakterler eksik:%1$s</string>
<string name="punctuation_order_sentence">1 tuşunun karakter sırası</string>
<string name="punctuation_order_special">0 tuşunun karakter sırası</string>
<string name="punctuation_order_reset_defaults">Varsayılan sırayı geri yükle</string>
<string name="language">Dil</string>
<string name="punctuation_order_save">Sıralamayı kaydet</string>
</resources>

View file

@ -186,4 +186,13 @@
<string name="language_selection_words">слів</string>
<string name="pref_backspace_acceleration">Швидке видалення</string>
<string name="pref_backspace_acceleration_summary">Видалити цілі слова, утримуючи або провівши клавішею Backspace. (Не підтримується в деяких додатках)</string>
<string name="pref_category_punctuation_order">Порядок пунктуації</string>
<string name="punctuation_order_whitespace_will_be_added_automatically">Пробіл і символ нового рядка буде автоматично додано на початок списку.</string>
<string name="punctuation_order_mandatory_char_missing">Відсутній обов’язковий символ:%1$s</string>
<string name="punctuation_order_mandatory_chars_missing">Відсутні обов’язкові символи:%1$s</string>
<string name="punctuation_order_sentence">Порядок символів на клавіші 1</string>
<string name="punctuation_order_special">Порядок символів на клавіші 0</string>
<string name="punctuation_order_reset_defaults">Відновити початковий порядок</string>
<string name="language">Мова</string>
<string name="punctuation_order_save">Зберегти порядок</string>
</resources>

View file

@ -6,6 +6,7 @@
<string name="app_settings">TT9 Settings</string>
<string name="completed">Completed</string>
<string name="loading">Loading…</string>
<string name="language">Language</string>
<string name="no_language">No Language</string>
<string name="search_results">Search Results</string>
<string name="search_results_void">No results.</string>
@ -36,6 +37,7 @@
<string name="pref_category_hacks">Compatibility</string>
<string name="pref_category_keypad">Keypad</string>
<string name="pref_category_predictive_mode">Predictive Mode</string>
<string name="pref_category_punctuation_order">Punctuation Order</string>
<string name="pref_category_setup">Initial Setup</string>
<string name="pref_category_typing_modes">Typing Modes</string>
<string name="pref_category_usage_stats" translatable="false">Usage Stats</string>
@ -166,6 +168,13 @@
<string name="language_selection_search_placeholder">Search for Languages</string>
<string name="language_selection_words">words</string>
<string name="punctuation_order_whitespace_will_be_added_automatically">Space and Newline characters will be automatically added at the beginning of the list.</string>
<string name="punctuation_order_mandatory_char_missing">Missing mandatory character:%1$s</string>
<string name="punctuation_order_mandatory_chars_missing">Missing mandatory characters:%1$s</string>
<string name="punctuation_order_reset_defaults">Restore Default Order</string>
<string name="punctuation_order_save">Save Order</string>
<string name="punctuation_order_sentence">1-key Character Order</string>
<string name="punctuation_order_special">0-key Character Order</string>
<string name="setup_keyboard_status">Status</string>
<string name="setup_default_keyboard">Select Default Keyboard</string>

View file

@ -8,6 +8,11 @@
android:key="screen_hotkeys"
android:title="@string/pref_category_function_keys" />
<Preference
android:fragment="io.github.sspanak.tt9.preferences.screens.punctuation.PunctuationScreen"
android:key="screen_punctuation"
android:title="@string/pref_category_punctuation_order" />
<SwitchPreferenceCompat
android:defaultValue="false"
android:key="backspace_acceleration"

View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<DropDownPreference
android:key="punctuation_order_language"
android:title="@string/language" />
<io.github.sspanak.tt9.preferences.screens.punctuation.PreferenceSentencePunctuationList
android:key="punctuation_order_sentence"
android:title="@string/punctuation_order_sentence" />
<io.github.sspanak.tt9.preferences.screens.punctuation.PreferenceSpecialCharList
android:key="punctuation_order_special_chars"
android:title="@string/punctuation_order_special"
android:summary="@string/punctuation_order_whitespace_will_be_added_automatically"/>
<Preference
android:key="punctuation_order_reset_defaults"
android:title="@string/punctuation_order_reset_defaults" />
<Preference
android:key="punctuation_order_save"
android:title="@string/punctuation_order_save" />
</PreferenceScreen>