1
0
Fork 0

0-key multi press is now 0-key double press (because this is what makes sense)

This commit is contained in:
Dimo Karaivanov 2023-02-08 14:24:23 +02:00
parent f5357396f5
commit a88250d634
12 changed files with 166 additions and 136 deletions

View file

@ -60,7 +60,7 @@ _Predictive mode only._
- **Hold:** type "0". - **Hold:** type "0".
- **In Predictive mode:** - **In Predictive mode:**
- **Press:** type space, newline or special/math characters. - **Press:** type space, newline or special/math characters.
- **Multiple Press:** type multiple spaces. - **Double Press:** type the character assigned in Predictive mode settings. (Default: ".")
- **Hold:** type "0". - **Hold:** type "0".
#### 1- to 9-key: #### 1- to 9-key:

View file

@ -46,7 +46,7 @@
<string name="pref_category_predictive_mode">Подсказващ режим</string> <string name="pref_category_predictive_mode">Подсказващ режим</string>
<string name="dictionary_missing_go_load_it">Няма речник за език „%1$s“. Заредете го в Настройки.</string> <string name="dictionary_missing_go_load_it">Няма речник за език „%1$s“. Заредете го в Настройки.</string>
<string name="pref_category_keypad">Клавиатура</string> <string name="pref_category_keypad">Клавиатура</string>
<string name="pref_double_zero_char">Символ при многократно натисната \"0\"</string> <string name="pref_double_zero_char">Символ при двойно натисната \"0\"</string>
<string name="char_newline">Нов ред</string> <string name="char_newline">Нов ред</string>
<string name="char_space">Интервал</string> <string name="char_space">Интервал</string>
<string name="add_word_field_placeholder">Напишете дума…</string> <string name="add_word_field_placeholder">Напишете дума…</string>

View file

@ -28,7 +28,7 @@
<string name="pref_auto_text_case_summary">Escribir la primera letra de cada frase en mayúscula.</string> <string name="pref_auto_text_case_summary">Escribir la primera letra de cada frase en mayúscula.</string>
<string name="pref_auto_space">Espacio automático</string> <string name="pref_auto_space">Espacio automático</string>
<string name="pref_auto_space_summary">Insertar un espacio automático después des palabras y signos de puntuación.</string> <string name="pref_auto_space_summary">Insertar un espacio automático después des palabras y signos de puntuación.</string>
<string name="pref_double_zero_char">Carácter cuando se presiona \"0\" varias veces</string> <string name="pref_double_zero_char">Carácter cuando se presiona \"0\" dos veces</string>
<string name="pref_show_soft_function_keys">Teclado en pantalla</string> <string name="pref_show_soft_function_keys">Teclado en pantalla</string>
<string name="dictionary_loaded">Diccionario cargado con éxito.</string> <string name="dictionary_loaded">Diccionario cargado con éxito.</string>
<string name="pref_upside_down_keys">Orden de teclas inverso</string> <string name="pref_upside_down_keys">Orden de teclas inverso</string>

View file

@ -39,7 +39,7 @@
<string name="pref_category_keypad">Clavier</string> <string name="pref_category_keypad">Clavier</string>
<string name="char_space">Espace</string> <string name="char_space">Espace</string>
<string name="char_newline">Nouvelle ligne</string> <string name="char_newline">Nouvelle ligne</string>
<string name="pref_double_zero_char">Caractère lorsque «0» est appuyé plusieurs fois</string> <string name="pref_double_zero_char">Caractère lorsque «0» est appuyé deux fois</string>
<string name="add_word_field_placeholder">Tapez un mot…</string> <string name="add_word_field_placeholder">Tapez un mot…</string>
<string name="pref_upside_down_keys">Inverser l\'ordre des clés</string> <string name="pref_upside_down_keys">Inverser l\'ordre des clés</string>
<string name="pref_upside_down_keys_summary">Activez le paramètre s\'il y a 789 sur le premier rang, au lieu de 123.</string> <string name="pref_upside_down_keys_summary">Activez le paramètre s\'il y a 789 sur le premier rang, au lieu de 123.</string>

View file

@ -35,7 +35,7 @@
<string name="pref_auto_space_summary">Автоматически добавлять пробел после слов и знаков препинания.</string> <string name="pref_auto_space_summary">Автоматически добавлять пробел после слов и знаков препинания.</string>
<string name="pref_auto_text_case">Авто заглавные буквы</string> <string name="pref_auto_text_case">Авто заглавные буквы</string>
<string name="pref_auto_text_case_summary">Автоматически начинать предложение с заглавной буквы.</string> <string name="pref_auto_text_case_summary">Автоматически начинать предложение с заглавной буквы.</string>
<string name="pref_double_zero_char">Символ при многократном нажатии клавиши 0</string> <string name="pref_double_zero_char">Символ при двойном нажатии клавиши 0</string>
<string name="pref_show_soft_function_keys">Кнопки на экране</string> <string name="pref_show_soft_function_keys">Кнопки на экране</string>
<string name="dictionary_load_bad_char">Не удалось загрузить словарь. Проблема в слове «%1$s» в строке %2$d для языка «%3$s».</string> <string name="dictionary_load_bad_char">Не удалось загрузить словарь. Проблема в слове «%1$s» в строке %2$d для языка «%3$s».</string>
<string name="dictionary_missing_go_load_it">Отсутствует словарь для языка «%1$s». Вы можете загрузить его в Настройках.</string> <string name="dictionary_missing_go_load_it">Отсутствует словарь для языка «%1$s». Вы можете загрузить его в Настройках.</string>

View file

@ -34,7 +34,7 @@
<string name="pref_auto_space_summary">Автоматично додавати пробіл після слів і розділових знаків.</string> <string name="pref_auto_space_summary">Автоматично додавати пробіл після слів і розділових знаків.</string>
<string name="pref_auto_text_case">Авто заголовні букви</string> <string name="pref_auto_text_case">Авто заголовні букви</string>
<string name="pref_auto_text_case_summary">Автоматично починати речення з заголовної букви.</string> <string name="pref_auto_text_case_summary">Автоматично починати речення з заголовної букви.</string>
<string name="pref_double_zero_char">Символ при багаторазовому натисканні клавіші 0</string> <string name="pref_double_zero_char">Символ при подвійному натисканні клавіші 0</string>
<string name="pref_show_soft_function_keys">Кнопки на екрані</string> <string name="pref_show_soft_function_keys">Кнопки на екрані</string>
<string name="key_back">Назад</string> <string name="key_back">Назад</string>
<string name="key_call">Виклик</string> <string name="key_call">Виклик</string>

View file

@ -26,7 +26,7 @@
<string name="pref_auto_text_case_summary">Automatically start sentences with a capital letter.</string> <string name="pref_auto_text_case_summary">Automatically start sentences with a capital letter.</string>
<string name="pref_choose_languages">Languages</string> <string name="pref_choose_languages">Languages</string>
<string name="pref_dark_theme">Dark Theme</string> <string name="pref_dark_theme">Dark Theme</string>
<string name="pref_double_zero_char">Character for Multiple 0-key Press</string> <string name="pref_double_zero_char">Character for Double 0-key Press</string>
<string name="pref_show_soft_function_keys">Show On-Screen Keys</string> <string name="pref_show_soft_function_keys">Show On-Screen Keys</string>
<string name="pref_help">Help</string> <string name="pref_help">Help</string>
<string name="pref_upside_down_keys">Reverse Key Order</string> <string name="pref_upside_down_keys">Reverse Key Order</string>

View file

@ -166,7 +166,7 @@ public class TraditionalT9 extends KeyPadHandler {
mInputMode.onAcceptSuggestion(mLanguage, word); mInputMode.onAcceptSuggestion(mLanguage, word);
commitCurrentSuggestion(); commitCurrentSuggestion();
autoCorrectSpace(word, true, -1, false); autoCorrectSpace(word, true, -1, false, false);
resetKeyRepeat(); resetKeyRepeat();
return true; return true;
@ -235,7 +235,7 @@ public class TraditionalT9 extends KeyPadHandler {
if (mInputMode.shouldAcceptCurrentSuggestion(mLanguage, key, hold, repeat > 0)) { if (mInputMode.shouldAcceptCurrentSuggestion(mLanguage, key, hold, repeat > 0)) {
mInputMode.onAcceptSuggestion(mLanguage, currentWord); mInputMode.onAcceptSuggestion(mLanguage, currentWord);
commitCurrentSuggestion(false); commitCurrentSuggestion(false);
autoCorrectSpace(currentWord, false, key, hold); autoCorrectSpace(currentWord, false, key, hold, repeat > 0);
currentWord = ""; currentWord = "";
} }
@ -255,7 +255,13 @@ public class TraditionalT9 extends KeyPadHandler {
} }
if (mInputMode.getWord() != null) { if (mInputMode.getWord() != null) {
commitText(mInputMode.getWord()); currentWord = mInputMode.getWord();
mInputMode.onAcceptSuggestion(mLanguage, currentWord);
commitText(currentWord);
clearSuggestions();
autoCorrectSpace(currentWord, true, key, hold, repeat > 0);
resetKeyRepeat();
} else { } else {
getSuggestions(); getSuggestions();
} }
@ -560,12 +566,12 @@ public class TraditionalT9 extends KeyPadHandler {
} }
private void autoCorrectSpace(String currentWord, boolean isWordAcceptedManually, int incomingKey, boolean hold) { private void autoCorrectSpace(String currentWord, boolean isWordAcceptedManually, int incomingKey, boolean hold, boolean repeat) {
if (mInputMode.shouldDeletePrecedingSpace(inputField)) { if (mInputMode.shouldDeletePrecedingSpace(inputField)) {
InputFieldHelper.deletePrecedingSpace(currentInputConnection, currentWord); InputFieldHelper.deletePrecedingSpace(currentInputConnection, currentWord);
} }
if (mInputMode.shouldAddAutoSpace(currentInputConnection, inputField, isWordAcceptedManually, incomingKey, hold)) { if (mInputMode.shouldAddAutoSpace(currentInputConnection, inputField, isWordAcceptedManually, incomingKey, hold, repeat)) {
commitText(" "); commitText(" ");
} }
} }

View file

@ -74,8 +74,14 @@ abstract public class InputMode {
abstract public int getId(); abstract public int getId();
abstract public int getSequenceLength(); // The number of key presses for the current word. abstract public int getSequenceLength(); // The number of key presses for the current word.
public boolean shouldAddAutoSpace(InputConnection inputConnection, EditorInfo inputField, boolean isWordAcceptedManually, int incomingKey, boolean hold) { return false; } // Interaction with the IME. Return "true" if it should perform the respective action.
public boolean shouldAcceptCurrentSuggestion(Language language, int key, boolean hold, boolean repeat) { return false; }
public boolean shouldAddAutoSpace(InputConnection inputConnection, EditorInfo inputField, boolean isWordAcceptedManually, int incomingKey, boolean hold, boolean repeat) { return false; }
public boolean shouldDeletePrecedingSpace(EditorInfo inputField) { return false; } public boolean shouldDeletePrecedingSpace(EditorInfo inputField) { return false; }
public boolean shouldSelectNextSuggestion() { return false; }
public boolean shouldTrackNumPress() { return true; }
public boolean shouldTrackUpDown() { return false; }
public boolean shouldTrackLeftRight() { return false; }
public void reset() { public void reset() {
suggestions = new ArrayList<>(); suggestions = new ArrayList<>();
@ -118,10 +124,4 @@ abstract public class InputMode {
public boolean isStemFilterFuzzy() { return false; } public boolean isStemFilterFuzzy() { return false; }
public String getWordStem() { return ""; } public String getWordStem() { return ""; }
public boolean setWordStem(Language language, String stem, boolean exact) { return false; } public boolean setWordStem(Language language, String stem, boolean exact) { return false; }
public boolean shouldTrackNumPress() { return true; }
public boolean shouldTrackUpDown() { return false; }
public boolean shouldTrackLeftRight() { return false; }
public boolean shouldAcceptCurrentSuggestion(Language language, int key, boolean hold, boolean repeat) { return false; }
public boolean shouldSelectNextSuggestion() { return false; }
} }

View file

@ -13,6 +13,7 @@ import io.github.sspanak.tt9.Logger;
import io.github.sspanak.tt9.db.DictionaryDb; import io.github.sspanak.tt9.db.DictionaryDb;
import io.github.sspanak.tt9.ime.EmptyDatabaseWarning; import io.github.sspanak.tt9.ime.EmptyDatabaseWarning;
import io.github.sspanak.tt9.ime.helpers.InputFieldHelper; import io.github.sspanak.tt9.ime.helpers.InputFieldHelper;
import io.github.sspanak.tt9.languages.InvalidLanguageCharactersException;
import io.github.sspanak.tt9.languages.Language; import io.github.sspanak.tt9.languages.Language;
import io.github.sspanak.tt9.languages.Punctuation; import io.github.sspanak.tt9.languages.Punctuation;
import io.github.sspanak.tt9.preferences.SettingsStore; import io.github.sspanak.tt9.preferences.SettingsStore;
@ -81,15 +82,13 @@ public class ModePredictive extends InputMode {
@Override @Override
public boolean onNumber(Language l, int key, boolean hold, int repeat) { public boolean onNumber(Language language, int key, boolean hold, int repeat) {
if (hold) { if (hold) {
// hold to type any digit // hold to type any digit
reset(); reset();
word = String.valueOf(key); word = String.valueOf(key);
} else if (key == 0 && repeat > 0) { } else if (key == 0 && repeat > 0) {
// repeat "0" is a shortcut for the preferred character (default: space) onDouble0(language);
reset();
word = settings.getDoubleZeroChar();
} else { } else {
// words // words
super.reset(); super.reset();
@ -100,6 +99,23 @@ public class ModePredictive extends InputMode {
} }
/**
* onDouble0
* Double "0" is a shortcut for the preferred character.
*/
private void onDouble0(Language language) {
try {
reset();
word = settings.getDoubleZeroChar();
digitSequence = language.getDigitSequenceForWord(word);
} catch (InvalidLanguageCharactersException e) {
Logger.w("tt9/onDouble0", "Failed getting the sequence for word: '" + word + "'. Performing standard 0-key action.");
reset();
digitSequence = "0";
}
}
@Override @Override
public void reset() { public void reset() {
super.reset(); super.reset();
@ -108,113 +124,6 @@ public class ModePredictive extends InputMode {
} }
/**
* shouldAddAutoSpace
* When the "auto-space" settings is enabled, this determines whether to automatically add a space
* at the end of a sentence or after accepting a suggestion. This allows faster typing, without
* pressing space.
*
* See the helper functions for the list of rules.
*/
@Override
public boolean shouldAddAutoSpace(InputConnection inputConnection, EditorInfo inputField, boolean isWordAcceptedManually, int incomingKey, boolean hold) {
return
settings.getAutoSpace()
&& !hold
&& (
shouldAddAutoSpaceAfterPunctuation(inputField, incomingKey)
|| shouldAddAutoSpaceAfterWord(inputField, isWordAcceptedManually)
)
&& !InputFieldHelper.isThereSpaceAhead(inputConnection);
}
/**
* shouldDeletePrecedingSpace
* When the "auto-space" settings is enabled, determine whether to delete spaces before punctuation.
* This allows automatic conversion from: "words ." to: "words."
*/
@Override
public boolean shouldDeletePrecedingSpace(EditorInfo inputField) {
return
settings.getAutoSpace()
&& (
lastAcceptedWord.equals(".")
|| lastAcceptedWord.equals(",")
|| lastAcceptedWord.equals(";")
|| lastAcceptedWord.equals(":")
|| lastAcceptedWord.equals("!")
|| lastAcceptedWord.equals("?")
|| lastAcceptedWord.equals(")")
|| lastAcceptedWord.equals("]")
|| lastAcceptedWord.equals("'")
|| lastAcceptedWord.equals("@")
)
&& !InputFieldHelper.isSpecializedTextField(inputField);
}
/**
* shouldAddAutoSpaceAfterPunctuation
* Determines whether to automatically adding a space after certain punctuation signs makes sense.
* The rules are similar to the ones in the standard Android keyboard (with some exceptions,
* because we are not using a QWERTY keyboard here).
*/
private boolean shouldAddAutoSpaceAfterPunctuation(EditorInfo inputField, int incomingKey) {
return
incomingKey != 0
&& (
lastAcceptedWord.endsWith(".")
|| lastAcceptedWord.endsWith(",")
|| lastAcceptedWord.endsWith(";")
|| lastAcceptedWord.endsWith(":")
|| lastAcceptedWord.endsWith("!")
|| lastAcceptedWord.endsWith("?")
|| lastAcceptedWord.endsWith(")")
|| lastAcceptedWord.endsWith("]")
|| lastAcceptedWord.endsWith("%")
)
&& !InputFieldHelper.isSpecializedTextField(inputField);
}
/**
* shouldAddAutoSpaceAfterPunctuation
* Similar to "shouldAddAutoSpaceAfterPunctuation()", but determines whether to add a space after
* words.
*/
private boolean shouldAddAutoSpaceAfterWord(EditorInfo inputField, boolean isWordAcceptedManually) {
return
// Do not add space when auto-accepting words, because it feels very confusing when typing.
isWordAcceptedManually
// Secondary punctuation
&& !lastAcceptedSequence.equals("0")
// Emoji
&& !lastAcceptedSequence.startsWith("1")
&& !InputFieldHelper.isSpecializedTextField(inputField);
}
/**
* shouldAcceptCurrentSuggestion
* In this mode, In addition to confirming the suggestion in the input field,
* we also increase its' priority. This function determines whether we want to do all this or not.
*/
@Override
public boolean shouldAcceptCurrentSuggestion(Language language, int key, boolean hold, boolean repeat) {
return
hold
// Quickly accept suggestions using "space" instead of pressing "ok" then "space"
|| key == 0
// Punctuation is considered "a word", so that we can increase the priority as needed
// Also, it must break the current word.
|| (!language.isPunctuationPartOfWords() && key == 1 && digitSequence.length() > 0 && !digitSequence.endsWith("1"))
// On the other hand, letters also "break" punctuation.
|| (!language.isPunctuationPartOfWords() && key != 1 && digitSequence.endsWith("1"))
|| (digitSequence.endsWith("0"));
}
/** /**
* clearWordStem * clearWordStem
* Do not filter the suggestions by the word set using "setWordStem()", use only the digit sequence. * Do not filter the suggestions by the word set using "setWordStem()", use only the digit sequence.
@ -284,6 +193,7 @@ public class ModePredictive extends InputMode {
return isStemFuzzy; return isStemFuzzy;
} }
/** /**
* loadStaticSuggestions * loadStaticSuggestions
* Similar to "loadSuggestions()", but loads suggestions that are not in the database. * Similar to "loadSuggestions()", but loads suggestions that are not in the database.
@ -493,7 +403,7 @@ public class ModePredictive extends InputMode {
// emoji and punctuation are not in the database, so there is no point in // emoji and punctuation are not in the database, so there is no point in
// running queries that would update nothing // running queries that would update nothing
if (!sequence.startsWith("11") && !sequence.equals("1") && !sequence.equals("0")) { if (!sequence.startsWith("11") && !sequence.equals("1") && !sequence.startsWith("0")) {
DictionaryDb.incrementWordFrequency(language, currentWord, sequence); DictionaryDb.incrementWordFrequency(language, currentWord, sequence);
} }
} catch (Exception e) { } catch (Exception e) {
@ -572,8 +482,117 @@ public class ModePredictive extends InputMode {
super.nextTextCase(); super.nextTextCase();
} }
@Override final public boolean isPredictive() { return true; }
@Override public int getSequenceLength() { return digitSequence.length(); } /**
* shouldAcceptCurrentSuggestion
* In this mode, In addition to confirming the suggestion in the input field,
* we also increase its' priority. This function determines whether we want to do all this or not.
*/
@Override
public boolean shouldAcceptCurrentSuggestion(Language language, int key, boolean hold, boolean repeat) {
return
hold
// Quickly accept suggestions using "space" instead of pressing "ok" then "space"
|| (key == 0 && !repeat)
// Punctuation is considered "a word", so that we can increase the priority as needed
// Also, it must break the current word.
|| (!language.isPunctuationPartOfWords() && key == 1 && digitSequence.length() > 0 && !digitSequence.endsWith("1"))
// On the other hand, letters also "break" punctuation.
|| (!language.isPunctuationPartOfWords() && key != 1 && digitSequence.endsWith("1"))
|| (digitSequence.endsWith("0") && key != 0);
}
/**
* shouldAddAutoSpace
* When the "auto-space" settings is enabled, this determines whether to automatically add a space
* at the end of a sentence or after accepting a suggestion. This allows faster typing, without
* pressing space.
*
* See the helper functions for the list of rules.
*/
@Override
public boolean shouldAddAutoSpace(InputConnection inputConnection, EditorInfo inputField, boolean isWordAcceptedManually, int incomingKey, boolean hold, boolean repeat) {
return
settings.getAutoSpace()
&& !hold
&& (
shouldAddAutoSpaceAfterPunctuation(inputField, incomingKey, repeat)
|| shouldAddAutoSpaceAfterWord(inputField, isWordAcceptedManually)
)
&& !InputFieldHelper.isThereSpaceAhead(inputConnection);
}
/**
* shouldAddAutoSpaceAfterPunctuation
* Determines whether to automatically adding a space after certain punctuation signs makes sense.
* The rules are similar to the ones in the standard Android keyboard (with some exceptions,
* because we are not using a QWERTY keyboard here).
*/
private boolean shouldAddAutoSpaceAfterPunctuation(EditorInfo inputField, int incomingKey, boolean repeat) {
return
(incomingKey != 0 || repeat)
&& (
lastAcceptedWord.endsWith(".")
|| lastAcceptedWord.endsWith(",")
|| lastAcceptedWord.endsWith(";")
|| lastAcceptedWord.endsWith(":")
|| lastAcceptedWord.endsWith("!")
|| lastAcceptedWord.endsWith("?")
|| lastAcceptedWord.endsWith(")")
|| lastAcceptedWord.endsWith("]")
|| lastAcceptedWord.endsWith("%")
)
&& !InputFieldHelper.isSpecializedTextField(inputField);
}
/**
* shouldAddAutoSpaceAfterPunctuation
* Similar to "shouldAddAutoSpaceAfterPunctuation()", but determines whether to add a space after
* words.
*/
private boolean shouldAddAutoSpaceAfterWord(EditorInfo inputField, boolean isWordAcceptedManually) {
return
// Do not add space when auto-accepting words, because it feels very confusing when typing.
isWordAcceptedManually
// Secondary punctuation
&& !lastAcceptedSequence.equals("0")
// Emoji
&& !lastAcceptedSequence.startsWith("1")
&& !InputFieldHelper.isSpecializedTextField(inputField);
}
/**
* shouldDeletePrecedingSpace
* When the "auto-space" settings is enabled, determine whether to delete spaces before punctuation.
* This allows automatic conversion from: "words ." to: "words."
*/
@Override
public boolean shouldDeletePrecedingSpace(EditorInfo inputField) {
return
settings.getAutoSpace()
&& (
lastAcceptedWord.equals(".")
|| lastAcceptedWord.equals(",")
|| lastAcceptedWord.equals(";")
|| lastAcceptedWord.equals(":")
|| lastAcceptedWord.equals("!")
|| lastAcceptedWord.equals("?")
|| lastAcceptedWord.equals(")")
|| lastAcceptedWord.equals("]")
|| lastAcceptedWord.equals("'")
|| lastAcceptedWord.equals("@")
)
&& !InputFieldHelper.isSpecializedTextField(inputField);
}
@Override public boolean shouldTrackUpDown() { return true; } @Override public boolean shouldTrackUpDown() { return true; }
@Override public boolean shouldTrackLeftRight() { return true; } @Override public boolean shouldTrackLeftRight() { return true; }
@Override final public boolean isPredictive() { return true; }
@Override public int getSequenceLength() { return digitSequence.length(); }
} }

View file

@ -209,7 +209,12 @@ public class SettingsStore {
public boolean getAutoSpace() { return prefs.getBoolean("auto_space", false); } public boolean getAutoSpace() { return prefs.getBoolean("auto_space", false); }
public boolean getAutoTextCase() { return prefs.getBoolean("auto_text_case", true); } public boolean getAutoTextCase() { return prefs.getBoolean("auto_text_case", true); }
public String getDoubleZeroChar() { return prefs.getString("pref_double_zero_char", " "); } public String getDoubleZeroChar() {
String character = prefs.getString("pref_double_zero_char", ".");
// SharedPreferences return a corrupted string when using the real "\n"... :(
return character.equals("\\n") ? "\n" : character;
}
public boolean getUpsideDownKeys() { return prefs.getBoolean("pref_upside_down_keys", false); } public boolean getUpsideDownKeys() { return prefs.getBoolean("pref_upside_down_keys", false); }

View file

@ -21,9 +21,9 @@ public class ItemSelectZeroKeyCharacter {
Resources resources = context.getResources(); Resources resources = context.getResources();
KEYS.put(" ", resources.getString(R.string.char_space));
KEYS.put("\n", resources.getString(R.string.char_newline));
KEYS.put(".", resources.getString(R.string.char_dot)); KEYS.put(".", resources.getString(R.string.char_dot));
KEYS.put("\\n", resources.getString(R.string.char_newline)); // SharedPreferences return a corrupted string when using the real "\n"... :(
KEYS.put(" ", resources.getString(R.string.char_space));
} }