From 33d433d206c83a1bd0546a7179d68c7e509507e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Wed, 15 Jun 2022 00:54:44 +0100 Subject: [PATCH] Make transliteration configurable per-language --- .../gadgetbridge/GBApplication.java | 26 ++- .../DeviceSettingsPreferenceConst.java | 2 +- .../service/DeviceCommunicationService.java | 13 +- .../gadgetbridge/util/LanguageUtils.java | 184 ------------------ .../util/language/LanguageUtils.java | 127 ++++++++++++ .../util/language/MultiTransliterator.java | 42 ++++ .../util/language/SimpleTransliterator.java | 64 ++++++ .../util/language/Transliterator.java | 21 ++ .../language/impl/ArabicTransliterator.java | 39 ++++ .../impl/BengaliTransliterator.java} | 11 +- .../language/impl/CzechTransliterator.java | 32 +++ .../language/impl/EstonianTransliterator.java | 34 ++++ .../impl/ExtendedAsciiTransliterator.java | 31 +++ .../impl/FlattenToAsciiTransliterator.java | 37 ++++ .../language/impl/GermanTransliterator.java | 33 ++++ .../language/impl/GreekTransliterator.java | 38 ++++ .../language/impl/HebrewTransliterator.java | 34 ++++ .../impl/IcelandicTransliterator.java | 31 +++ .../impl/KoreanTransliterator.java} | 9 +- .../impl/LithuanianTransliterator.java | 31 +++ .../language/impl/PersianTransliterator.java | 35 ++++ .../language/impl/PolishTransliterator.java | 32 +++ .../language/impl/RussianTransliterator.java | 37 ++++ .../impl/ScandinavianTransliterator.java | 33 ++++ .../language/impl/TurkishTransliterator.java | 31 +++ .../language/impl/UkranianTransliterator.java | 31 +++ app/src/main/res/values/arrays.xml | 44 ++++- app/src/main/res/values/strings.xml | 9 + .../xml/devicesettings_transliteration.xml | 12 +- .../service/TestDeviceSupport.java | 5 + .../language}/LanguageUtilsTest.java | 91 +++++---- 31 files changed, 957 insertions(+), 242 deletions(-) delete mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/LanguageUtils.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/LanguageUtils.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/MultiTransliterator.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/SimpleTransliterator.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/Transliterator.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/ArabicTransliterator.java rename app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/{BengaliLanguageUtils.java => language/impl/BengaliTransliterator.java} (97%) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/CzechTransliterator.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/EstonianTransliterator.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/ExtendedAsciiTransliterator.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/FlattenToAsciiTransliterator.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/GermanTransliterator.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/GreekTransliterator.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/HebrewTransliterator.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/IcelandicTransliterator.java rename app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/{KoreanLanguageUtils.java => language/impl/KoreanTransliterator.java} (98%) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/LithuanianTransliterator.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/PersianTransliterator.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/PolishTransliterator.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/RussianTransliterator.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/ScandinavianTransliterator.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/TurkishTransliterator.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/UkranianTransliterator.java rename app/src/test/java/nodomain/freeyourgadget/gadgetbridge/{test => util/language}/LanguageUtilsTest.java (68%) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java index 82a6e166a..f32c441dc 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java @@ -117,7 +117,7 @@ public class GBApplication extends Application { private static SharedPreferences sharedPrefs; private static final String PREFS_VERSION = "shared_preferences_version"; //if preferences have to be migrated, increment the following and add the migration logic in migratePrefs below; see http://stackoverflow.com/questions/16397848/how-can-i-migrate-android-preferences-with-a-new-version - private static final int CURRENT_PREFS_VERSION = 15; + private static final int CURRENT_PREFS_VERSION = 16; private static LimitedQueue mIDSenderLookup = new LimitedQueue(16); private static Prefs prefs; @@ -1166,6 +1166,30 @@ public class GBApplication extends Application { } } + if (oldVersion < 16) { + // If transliteration was enabled for a device, migrate it to the per-language setting + final String defaultLanguagesIfEnabled = "extended_ascii,scandinavian,german,russian,hebrew,greek,ukranian,arabic,persian,lithuanian,polish,estonian,icelandic,czech,turkish,bengali,korean"; + try (DBHandler db = acquireDB()) { + final DaoSession daoSession = db.getDaoSession(); + final List activeDevices = DBHelper.getActiveDevices(daoSession); + + for (Device dbDevice : activeDevices) { + final SharedPreferences deviceSharedPrefs = GBApplication.getDeviceSpecificSharedPrefs(dbDevice.getIdentifier()); + final SharedPreferences.Editor deviceSharedPrefsEdit = deviceSharedPrefs.edit(); + + if (deviceSharedPrefs.getBoolean("pref_transliteration_enabled", false)) { + deviceSharedPrefsEdit.putString("pref_transliteration_languages", defaultLanguagesIfEnabled); + } + + deviceSharedPrefsEdit.remove("pref_transliteration_enabled"); + + deviceSharedPrefsEdit.apply(); + } + } catch (Exception e) { + Log.w(TAG, "error acquiring DB lock"); + } + } + editor.putString(PREFS_VERSION, Integer.toString(CURRENT_PREFS_VERSION)); editor.apply(); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java index a07af38d8..5e22f256c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java @@ -141,7 +141,7 @@ public class DeviceSettingsPreferenceConst { public static final String PREF_SONYSWR12_SMART_INTERVAL = "smart_alarm_interval_preference"; public static final String PREF_BT_CONNECTED_ADVERTISEMENT = "bt_connected_advertisement"; - public static final String PREF_TRANSLITERATION_ENABLED = "pref_transliteration_enabled"; + public static final String PREF_TRANSLITERATION_LANGUAGES = "pref_transliteration_languages"; public static final String PREF_NOTHING_EAR1_INEAR = "pref_nothing_inear_detection"; public static final String PREF_NOTHING_EAR1_AUDIOMODE = "pref_nothing_audiomode"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java index 546f88f71..bd116730b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java @@ -45,6 +45,7 @@ import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.GBApplication; @@ -85,10 +86,11 @@ import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper; import nodomain.freeyourgadget.gadgetbridge.util.EmojiConverter; import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs; -import nodomain.freeyourgadget.gadgetbridge.util.LanguageUtils; +import nodomain.freeyourgadget.gadgetbridge.util.language.LanguageUtils; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; +import nodomain.freeyourgadget.gadgetbridge.util.language.Transliterator; -import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_TRANSLITERATION_ENABLED; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_TRANSLITERATION_LANGUAGES; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_ADD_CALENDAREVENT; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_APP_CONFIGURE; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_APP_REORDER; @@ -576,12 +578,13 @@ public class DeviceCommunicationService extends Service implements SharedPrefere DeviceSupport deviceSupport = getDeviceSupport(device); Prefs devicePrefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(device.getAddress())); - boolean transliterate = devicePrefs.getBoolean(PREF_TRANSLITERATION_ENABLED, false); - if (transliterate) { + final Transliterator transliterator = LanguageUtils.getTransliterator(device); + + if (transliterator != null) { for (String extra : GBDeviceService.transliterationExtras) { if (intent.hasExtra(extra)) { - intent.putExtra(extra, LanguageUtils.transliterate(intent.getStringExtra(extra))); + intent.putExtra(extra, transliterator.transliterate(intent.getStringExtra(extra))); } } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/LanguageUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/LanguageUtils.java deleted file mode 100644 index 6675492f0..000000000 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/LanguageUtils.java +++ /dev/null @@ -1,184 +0,0 @@ -/* Copyright (C) 2017-2021 Andreas Shimokawa, Aniruddha Adhikary, Daniele - Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg, - Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani - - This file is part of Gadgetbridge. - - Gadgetbridge is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published - by the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Gadgetbridge is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . */ -package nodomain.freeyourgadget.gadgetbridge.util; - -import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_TRANSLITERATION_ENABLED; - -import android.content.SharedPreferences; - -import org.apache.commons.lang3.text.WordUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.text.Normalizer; -import java.util.HashMap; -import java.util.Map; - -import nodomain.freeyourgadget.gadgetbridge.GBApplication; -import nodomain.freeyourgadget.gadgetbridge.R; -import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; - -public class LanguageUtils { - private static final Logger LOG = LoggerFactory.getLogger(LanguageUtils.class); - // Transliteration map with english equivalent for unsupported chars - @SuppressWarnings("OverwrittenKey") - private static final Map transliterateMap = new HashMap() { - { - // Extended ASCII characters - put('œ', "oe"); put('ª', "a"); put('º', "o"); put('«',"\""); put('»',"\""); - - // Scandinavian characters - put('Æ',"Ae"); put('æ',"ae"); - put('Ø',"Oe"); put('ø',"oe"); - put('Å',"Aa"); put('å',"aa"); - - // German characters - put('ä',"ae"); put('ö',"oe"); put('ü',"ue"); - put('Ä',"Ae"); put('Ö',"Oe"); put('Ü',"Üe"); - put('ß',"ss"); put('ẞ',"SS"); - - // Russian chars - put('а', "a"); put('б', "b"); put('в', "v"); put('г', "g"); put('д', "d"); put('е', "e"); put('ё', "jo"); put('ж', "zh"); - put('з', "z"); put('и', "i"); put('й', "jj"); put('к', "k"); put('л', "l"); put('м', "m"); put('н', "n"); put('о', "o"); - put('п', "p"); put('р', "r"); put('с', "s"); put('т', "t"); put('у', "u"); put('ф', "f"); put('х', "kh"); put('ц', "c"); - put('ч', "ch");put('ш', "sh");put('щ', "shh");put('ъ', "\"");put('ы', "y"); put('ь', "'"); put('э', "eh"); put('ю', "ju"); - put('я', "ja"); - - // Hebrew chars - put('א', "a"); put('ב', "b"); put('ג', "g"); put('ד', "d"); put('ה', "h"); put('ו', "u"); put('ז', "z"); put('ח', "kh"); - put('ט', "t"); put('י', "y"); put('כ', "c"); put('ל', "l"); put('מ', "m"); put('נ', "n"); put('ס', "s"); put('ע', "'"); - put('פ', "p"); put('צ', "ts"); put('ק', "k"); put('ר', "r"); put('ש', "sh"); put('ת', "th"); put('ף', "f"); put('ץ', "ts"); - put('ך', "ch");put('ם', "m");put('ן', "n"); - - // Greek chars - put('α',"a");put('ά',"a");put('β',"v");put('γ',"g");put('δ',"d");put('ε',"e");put('έ',"e");put('ζ',"z");put('η',"i"); - put('ή',"i");put('θ',"th");put('ι',"i");put('ί',"i");put('ϊ',"i");put('ΐ',"i");put('κ',"k");put('λ',"l");put('μ',"m"); - put('ν',"n");put('ξ',"ks");put('ο',"o");put('ό',"o");put('π',"p");put('ρ',"r");put('σ',"s");put('ς',"s");put('τ',"t"); - put('υ',"y");put('ύ',"y");put('ϋ',"y");put('ΰ',"y");put('φ',"f");put('χ',"ch");put('ψ',"ps");put('ω',"o");put('ώ',"o"); - put('Α',"A");put('Ά',"A");put('Β',"B");put('Γ',"G");put('Δ',"D");put('Ε',"E");put('Έ',"E");put('Ζ',"Z");put('Η',"I"); - put('Ή',"I");put('Θ',"TH");put('Ι',"I");put('Ί',"I");put('Ϊ',"I");put('Κ',"K");put('Λ',"L");put('Μ',"M");put('Ν',"N"); - put('Ξ',"KS");put('Ο',"O");put('Ό',"O");put('Π',"P");put('Ρ',"R");put('Σ',"S");put('Τ',"T");put('Υ',"Y");put('Ύ',"Y"); - put('Ϋ',"Y");put('Φ',"F");put('Χ',"CH");put('Ψ',"PS");put('Ω',"O");put('Ώ',"O"); - - // Ukrainian characters - put('ґ', "gh"); put('є', "je"); put('і', "i"); put('ї', "ji"); put('Ґ', "GH"); put('Є', "JE"); put('І', "I"); put('Ї', "JI"); - - // Arabic - put('ا', "a"); put('ب', "b"); put('ت', "t"); put('ث', "th"); put('ج', "j"); put('ح', "7"); put('خ', "5"); - put('د', "d"); put('ذ', "th"); put('ر', "r"); put('ز', "z"); put('س', "s"); put('ش', "sh"); put('ص', "9"); - put('ض', "9'"); put('ط', "6"); put('ظ', "6'"); put('ع', "3"); put('غ', "3'"); put('ف', "f"); - put('ق', "q"); put('ك', "k"); put('ل', "l"); put('م', "m"); put('ن', "n"); put('ه', "h"); - put('و', "w"); put('ي', "y"); put('ى', "a"); put('ﺓ', ""); - put('آ', "2"); put('ئ', "2"); put('إ', "2"); put('ؤ', "2"); put('أ', "2"); put('ء', "2"); - put('٠', "0"); put('١', "1"); put('٢', "2"); put('٣', "3"); put('٤', "4"); put('٥', "5"); - put('٦', "6"); put('٧', "7"); put('٨', "8"); put('٩', "9"); - - // Persian(Farsi) - put('پ', "p"); put('چ', "ch"); put('ژ', "zh"); put('ک', "k"); put('گ', "g"); put('ی', "y"); put('‌', " "); - put('؟', "?"); put('٪', "%"); put('؛', ";"); put('،', ","); put('۱', "1"); put('۲', "2"); put('۳', "3"); - put('۴', "4"); put('۵', "5"); put('۶', "6"); put('۷', "7"); put('۸', "8"); put('۹', "9"); put('۰', "0"); - put('»', "<"); put('«', ">"); put('ِ', "e"); put('َ', "a"); put('ُ', "o"); put('ّ', ""); - - // Polish - put('Ł', "L"); put('ł', "l"); - - //Lithuanian - put('ą', "a"); put('č', "c"); put('ę', "e"); put('ė', "e"); put('į', "i"); put('š', "s"); put('ų', "u"); put('ū', "u"); put('ž', "z"); - - - // Estonian - put('ä', "a"); put('Ä', "A"); - put('ö', "o"); put('õ', "o"); - put('Ö', "O"); put('Õ', "O"); - put('ü', "u"); put('Ü', "U"); - - // Icelandic - put('Þ',"Th"); put('þ',"th"); put('Ð',"D"); put('ð',"d"); - - // Czech - put('ř',"r"); put('ě',"e"); put('ý',"y"); put('á',"a"); put('í',"i"); put('é',"e"); - put('ó',"o"); put('ú',"u"); put('ů',"u"); put('ď',"d"); put('ť',"t"); put('ň',"n"); - - // Turkish - put('ı',"i"); - - //TODO: these must be configurable. If someone wants to transliterate cyrillic it does not mean his device has no German umlauts - // all or nothing is really bad here - } - }; - - /** - * Replaces unsupported symbols to english - * @param txt input text - * @return transliterated text - */ - public static String transliterate(String txt){ - if (txt == null || txt.isEmpty()) { - return txt; - } - - StringBuilder messageBuilder = new StringBuilder(); - - // Simple, char-by-char transliteration. - char[] chars = txt.toCharArray(); - for (char c : chars) - { - messageBuilder.append(transliterate(c)); - } - String message = messageBuilder.toString(); - - // More complex transliteration for specific languages. - message = BengaliLanguageUtils.transliterate(message); - message = KoreanLanguageUtils.transliterate(message); - - return flattenToAscii(message); - } - - /** - * Replaces unsupported symbol to english by {@code transliterateMap} - * @param c input char - * @return replacement text - */ - private static String transliterate(char c){ - char lowerChar = Character.toLowerCase(c); - - if (transliterateMap.containsKey(lowerChar)) { - String replace = transliterateMap.get(lowerChar); - - if (lowerChar != c) - { - return WordUtils.capitalize(replace); - } - - return replace; - } - - return String.valueOf(c); - } - - /** - * Converts the diacritics - * @param string input text - * @return converted text - */ - private static String flattenToAscii(String string) { - string = Normalizer.normalize(string, Normalizer.Form.NFD); - return string.replaceAll("\\p{M}", ""); - } -} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/LanguageUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/LanguageUtils.java new file mode 100644 index 000000000..e4471c327 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/LanguageUtils.java @@ -0,0 +1,127 @@ +/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele + Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg, + Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.util.language; + +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_TRANSLITERATION_LANGUAGES; + +import androidx.annotation.Nullable; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.text.Normalizer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import nodomain.freeyourgadget.gadgetbridge.GBApplication; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.util.Prefs; +import nodomain.freeyourgadget.gadgetbridge.util.language.impl.ArabicTransliterator; +import nodomain.freeyourgadget.gadgetbridge.util.language.impl.BengaliTransliterator; +import nodomain.freeyourgadget.gadgetbridge.util.language.impl.CzechTransliterator; +import nodomain.freeyourgadget.gadgetbridge.util.language.impl.EstonianTransliterator; +import nodomain.freeyourgadget.gadgetbridge.util.language.impl.ExtendedAsciiTransliterator; +import nodomain.freeyourgadget.gadgetbridge.util.language.impl.FlattenToAsciiTransliterator; +import nodomain.freeyourgadget.gadgetbridge.util.language.impl.GermanTransliterator; +import nodomain.freeyourgadget.gadgetbridge.util.language.impl.GreekTransliterator; +import nodomain.freeyourgadget.gadgetbridge.util.language.impl.HebrewTransliterator; +import nodomain.freeyourgadget.gadgetbridge.util.language.impl.IcelandicTransliterator; +import nodomain.freeyourgadget.gadgetbridge.util.language.impl.KoreanTransliterator; +import nodomain.freeyourgadget.gadgetbridge.util.language.impl.LithuanianTransliterator; +import nodomain.freeyourgadget.gadgetbridge.util.language.impl.PersianTransliterator; +import nodomain.freeyourgadget.gadgetbridge.util.language.impl.PolishTransliterator; +import nodomain.freeyourgadget.gadgetbridge.util.language.impl.RussianTransliterator; +import nodomain.freeyourgadget.gadgetbridge.util.language.impl.ScandinavianTransliterator; +import nodomain.freeyourgadget.gadgetbridge.util.language.impl.TurkishTransliterator; +import nodomain.freeyourgadget.gadgetbridge.util.language.impl.UkranianTransliterator; + +public class LanguageUtils { + private static final Logger LOG = LoggerFactory.getLogger(LanguageUtils.class); + + private static final Map TRANSLITERATORS_MAP = new HashMap() {{ + put("arabic", new ArabicTransliterator()); + put("bengali", new BengaliTransliterator()); + put("czech", new CzechTransliterator()); + put("estonian", new EstonianTransliterator()); + put("extended_ascii", new ExtendedAsciiTransliterator()); + put("german", new GermanTransliterator()); + put("greek", new GreekTransliterator()); + put("hebrew", new HebrewTransliterator()); + put("icelandic", new IcelandicTransliterator()); + put("korean", new KoreanTransliterator()); + put("lithuanian", new LithuanianTransliterator()); + put("persian", new PersianTransliterator()); + put("polish", new PolishTransliterator()); + put("russian", new RussianTransliterator()); + put("scandinavian", new ScandinavianTransliterator()); + put("turkish", new TurkishTransliterator()); + put("ukranian", new UkranianTransliterator()); + }}; + + /** + * Get a {@link Transliterator} for a specific language. + * + * @param language the language + * @return the transliterator, if it exists + * @throws IllegalArgumentException if there is no transliterator for the provided language + */ + public static Transliterator getTransliterator(final String language) { + if (!TRANSLITERATORS_MAP.containsKey(language)) { + throw new IllegalArgumentException(String.format("Transliterator for %s not found", language)); + } + + return TRANSLITERATORS_MAP.get(language); + } + + /** + * Get the configured transliterator for the provided {@link GBDevice}, if any. + * + * @param device the device + * @return the configured transliterator, null if not configured + */ + @Nullable + public static Transliterator getTransliterator(final GBDevice device) { + final Prefs devicePrefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(device.getAddress())); + final String transliterateLanguagesPref = devicePrefs.getString(PREF_TRANSLITERATION_LANGUAGES, ""); + + if (transliterateLanguagesPref.isEmpty()) { + return null; + } + + final List languages = Arrays.asList(transliterateLanguagesPref.split(",")); + final List transliterators = new ArrayList<>(languages.size()); + + for (String language : languages) { + if (!TRANSLITERATORS_MAP.containsKey(language)) { + LOG.warn("Transliterator for {} not found", language); + continue; + } + + transliterators.add(TRANSLITERATORS_MAP.get(language)); + } + + transliterators.add(new FlattenToAsciiTransliterator()); + + return new MultiTransliterator(transliterators); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/MultiTransliterator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/MultiTransliterator.java new file mode 100644 index 000000000..ee5a12596 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/MultiTransliterator.java @@ -0,0 +1,42 @@ +/* Copyright (C) 2022 José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.util.language; + +import java.text.Normalizer; +import java.util.List; +import java.util.Map; + +public class MultiTransliterator implements Transliterator { + private final List transliterators; + + public MultiTransliterator(final List transliterators) { + this.transliterators = transliterators; + } + + @Override + public String transliterate(String txt) { + if (txt == null || txt.isEmpty()) { + return txt; + } + + for (Transliterator transliterator : transliterators) { + txt = transliterator.transliterate(txt); + } + + return txt; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/SimpleTransliterator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/SimpleTransliterator.java new file mode 100644 index 000000000..1b4c287bb --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/SimpleTransliterator.java @@ -0,0 +1,64 @@ +/* Copyright (C) 2022 José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.util.language; + +import org.apache.commons.lang3.text.WordUtils; + +import java.text.Normalizer; +import java.util.Map; + +public class SimpleTransliterator implements Transliterator { + private final Map transliterateMap; + + public SimpleTransliterator(final Map transliterateMap) { + this.transliterateMap = transliterateMap; + } + + @Override + public String transliterate(String txt) { + if (txt == null || txt.isEmpty()) { + return txt; + } + + final StringBuilder messageBuilder = new StringBuilder(); + + // Simple, char-by-char transliteration. + final char[] chars = txt.toCharArray(); + for (char c : chars) { + messageBuilder.append(transliterate(c)); + } + final String message = messageBuilder.toString(); + + return message; + } + + private String transliterate(char c) { + final char lowerChar = Character.toLowerCase(c); + + if (transliterateMap.containsKey(lowerChar)) { + final String replace = transliterateMap.get(lowerChar); + + if (lowerChar != c) { + return WordUtils.capitalize(replace); + } + + return replace; + } + + return String.valueOf(c); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/Transliterator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/Transliterator.java new file mode 100644 index 000000000..445721cd8 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/Transliterator.java @@ -0,0 +1,21 @@ +/* Copyright (C) 2022 José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.util.language; + +public interface Transliterator { + String transliterate(String txt); +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/ArabicTransliterator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/ArabicTransliterator.java new file mode 100644 index 000000000..eafe22430 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/ArabicTransliterator.java @@ -0,0 +1,39 @@ +/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele + Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg, + Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.util.language.impl; + +import java.util.HashMap; +import java.util.Map; + +import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator; + +public class ArabicTransliterator extends SimpleTransliterator { + public ArabicTransliterator() { + super(new HashMap() {{ + put('ا', "a"); put('ب', "b"); put('ت', "t"); put('ث', "th"); put('ج', "j"); put('ح', "7"); put('خ', "5"); + put('د', "d"); put('ذ', "th"); put('ر', "r"); put('ز', "z"); put('س', "s"); put('ش', "sh"); put('ص', "9"); + put('ض', "9'"); put('ط', "6"); put('ظ', "6'"); put('ع', "3"); put('غ', "3'"); put('ف', "f"); + put('ق', "q"); put('ك', "k"); put('ل', "l"); put('م', "m"); put('ن', "n"); put('ه', "h"); + put('و', "w"); put('ي', "y"); put('ى', "a"); put('ﺓ', ""); + put('آ', "2"); put('ئ', "2"); put('إ', "2"); put('ؤ', "2"); put('أ', "2"); put('ء', "2"); + put('٠', "0"); put('١', "1"); put('٢', "2"); put('٣', "3"); put('٤', "4"); put('٥', "5"); + put('٦', "6"); put('٧', "7"); put('٨', "8"); put('٩', "9"); + }}); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/BengaliLanguageUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/BengaliTransliterator.java similarity index 97% rename from app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/BengaliLanguageUtils.java rename to app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/BengaliTransliterator.java index aa544d343..0db3dfa93 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/BengaliLanguageUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/BengaliTransliterator.java @@ -15,15 +15,17 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ -package nodomain.freeyourgadget.gadgetbridge.util; +package nodomain.freeyourgadget.gadgetbridge.util.language.impl; import java.util.HashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; +import nodomain.freeyourgadget.gadgetbridge.util.language.Transliterator; + // What's the reason to extending LanguageUtils? // Just doing it because already done in the previous code. -public class BengaliLanguageUtils extends LanguageUtils { +public class BengaliTransliterator implements Transliterator { // Composite Letters. private final static HashMap composites = new HashMap() { { @@ -187,8 +189,9 @@ public class BengaliLanguageUtils extends LanguageUtils { return null; } - public static String transliterate(String txt) { - if (txt.isEmpty()) { + @Override + public String transliterate(String txt) { + if (txt == null || txt.isEmpty()) { return txt; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/CzechTransliterator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/CzechTransliterator.java new file mode 100644 index 000000000..47098327d --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/CzechTransliterator.java @@ -0,0 +1,32 @@ +/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele + Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg, + Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.util.language.impl; + +import java.util.HashMap; + +import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator; + +public class CzechTransliterator extends SimpleTransliterator { + public CzechTransliterator() { + super(new HashMap() {{ + put('ř',"r"); put('ě',"e"); put('ý',"y"); put('á',"a"); put('í',"i"); put('é',"e"); + put('ó',"o"); put('ú',"u"); put('ů',"u"); put('ď',"d"); put('ť',"t"); put('ň',"n"); + }}); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/EstonianTransliterator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/EstonianTransliterator.java new file mode 100644 index 000000000..de0e1020c --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/EstonianTransliterator.java @@ -0,0 +1,34 @@ +/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele + Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg, + Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.util.language.impl; + +import java.util.HashMap; + +import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator; + +public class EstonianTransliterator extends SimpleTransliterator { + public EstonianTransliterator() { + super(new HashMap() {{ + put('ä', "a"); put('Ä', "A"); + put('ö', "o"); put('õ', "o"); + put('Ö', "O"); put('Õ', "O"); + put('ü', "u"); put('Ü', "U"); + }}); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/ExtendedAsciiTransliterator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/ExtendedAsciiTransliterator.java new file mode 100644 index 000000000..c6f72c463 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/ExtendedAsciiTransliterator.java @@ -0,0 +1,31 @@ +/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele + Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg, + Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.util.language.impl; + +import java.util.HashMap; + +import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator; + +public class ExtendedAsciiTransliterator extends SimpleTransliterator { + public ExtendedAsciiTransliterator() { + super(new HashMap() {{ + put('œ', "oe"); put('ª', "a"); put('º', "o"); put('«',"\""); put('»',"\""); + }}); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/FlattenToAsciiTransliterator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/FlattenToAsciiTransliterator.java new file mode 100644 index 000000000..4ffe34dd2 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/FlattenToAsciiTransliterator.java @@ -0,0 +1,37 @@ +/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele + Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg, + Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.util.language.impl; + +import java.text.Normalizer; +import java.util.HashMap; + +import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator; +import nodomain.freeyourgadget.gadgetbridge.util.language.Transliterator; + +public class FlattenToAsciiTransliterator implements Transliterator { + @Override + public String transliterate(String txt) { + if (txt == null || txt.isEmpty()) { + return txt; + } + + txt = Normalizer.normalize(txt, Normalizer.Form.NFD); + return txt.replaceAll("\\p{M}", ""); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/GermanTransliterator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/GermanTransliterator.java new file mode 100644 index 000000000..47fcce49e --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/GermanTransliterator.java @@ -0,0 +1,33 @@ +/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele + Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg, + Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.util.language.impl; + +import java.util.HashMap; + +import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator; + +public class GermanTransliterator extends SimpleTransliterator { + public GermanTransliterator() { + super(new HashMap() {{ + put('ä',"ae"); put('ö',"oe"); put('ü',"ue"); + put('Ä',"Ae"); put('Ö',"Oe"); put('Ü',"Üe"); + put('ß',"ss"); put('ẞ',"SS"); + }}); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/GreekTransliterator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/GreekTransliterator.java new file mode 100644 index 000000000..af76637d3 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/GreekTransliterator.java @@ -0,0 +1,38 @@ +/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele + Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg, + Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.util.language.impl; + +import java.util.HashMap; + +import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator; + +public class GreekTransliterator extends SimpleTransliterator { + public GreekTransliterator() { + super(new HashMap() {{ + put('α',"a");put('ά',"a");put('β',"v");put('γ',"g");put('δ',"d");put('ε',"e");put('έ',"e");put('ζ',"z");put('η',"i"); + put('ή',"i");put('θ',"th");put('ι',"i");put('ί',"i");put('ϊ',"i");put('ΐ',"i");put('κ',"k");put('λ',"l");put('μ',"m"); + put('ν',"n");put('ξ',"ks");put('ο',"o");put('ό',"o");put('π',"p");put('ρ',"r");put('σ',"s");put('ς',"s");put('τ',"t"); + put('υ',"y");put('ύ',"y");put('ϋ',"y");put('ΰ',"y");put('φ',"f");put('χ',"ch");put('ψ',"ps");put('ω',"o");put('ώ',"o"); + put('Α',"A");put('Ά',"A");put('Β',"B");put('Γ',"G");put('Δ',"D");put('Ε',"E");put('Έ',"E");put('Ζ',"Z");put('Η',"I"); + put('Ή',"I");put('Θ',"TH");put('Ι',"I");put('Ί',"I");put('Ϊ',"I");put('Κ',"K");put('Λ',"L");put('Μ',"M");put('Ν',"N"); + put('Ξ',"KS");put('Ο',"O");put('Ό',"O");put('Π',"P");put('Ρ',"R");put('Σ',"S");put('Τ',"T");put('Υ',"Y");put('Ύ',"Y"); + put('Ϋ',"Y");put('Φ',"F");put('Χ',"CH");put('Ψ',"PS");put('Ω',"O");put('Ώ',"O"); + }}); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/HebrewTransliterator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/HebrewTransliterator.java new file mode 100644 index 000000000..f0b85dfc3 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/HebrewTransliterator.java @@ -0,0 +1,34 @@ +/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele + Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg, + Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.util.language.impl; + +import java.util.HashMap; + +import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator; + +public class HebrewTransliterator extends SimpleTransliterator { + public HebrewTransliterator() { + super(new HashMap() {{ + put('א', "a"); put('ב', "b"); put('ג', "g"); put('ד', "d"); put('ה', "h"); put('ו', "u"); put('ז', "z"); put('ח', "kh"); + put('ט', "t"); put('י', "y"); put('כ', "c"); put('ל', "l"); put('מ', "m"); put('נ', "n"); put('ס', "s"); put('ע', "'"); + put('פ', "p"); put('צ', "ts"); put('ק', "k"); put('ר', "r"); put('ש', "sh"); put('ת', "th"); put('ף', "f"); put('ץ', "ts"); + put('ך', "ch");put('ם', "m");put('ן', "n"); + }}); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/IcelandicTransliterator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/IcelandicTransliterator.java new file mode 100644 index 000000000..05d94a130 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/IcelandicTransliterator.java @@ -0,0 +1,31 @@ +/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele + Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg, + Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.util.language.impl; + +import java.util.HashMap; + +import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator; + +public class IcelandicTransliterator extends SimpleTransliterator { + public IcelandicTransliterator() { + super(new HashMap() {{ + put('Þ',"Th"); put('þ',"th"); put('Ð',"D"); put('ð',"d"); + }}); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/KoreanLanguageUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/KoreanTransliterator.java similarity index 98% rename from app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/KoreanLanguageUtils.java rename to app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/KoreanTransliterator.java index f5db7fff3..2c4c150d3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/KoreanLanguageUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/KoreanTransliterator.java @@ -14,16 +14,18 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ -package nodomain.freeyourgadget.gadgetbridge.util; +package nodomain.freeyourgadget.gadgetbridge.util.language.impl; import java.util.Optional; import java.text.Normalizer; import java.text.Normalizer.Form; +import nodomain.freeyourgadget.gadgetbridge.util.language.Transliterator; + // Implements Revised Romanization of Korean as well as we can without understanding any grammar. // // https://en.wikipedia.org/wiki/Revised_Romanization_of_Korean -public class KoreanLanguageUtils { +public class KoreanTransliterator implements Transliterator { // https://en.wikipedia.org/wiki/Hangul_Jamo_%28Unicode_block%29 private static final char JAMO_BLOCK_START = 0x1100; private static final char JAMO_BLOCK_END = 0x11FF; @@ -282,7 +284,8 @@ public class KoreanLanguageUtils { } // Transliterate any Hangul in the given string. Leaves any non-Hangul characters unmodified. - public static String transliterate(String txt) { + @Override + public String transliterate(String txt) { if (txt == null || txt.isEmpty()) { return txt; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/LithuanianTransliterator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/LithuanianTransliterator.java new file mode 100644 index 000000000..11268efff --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/LithuanianTransliterator.java @@ -0,0 +1,31 @@ +/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele + Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg, + Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.util.language.impl; + +import java.util.HashMap; + +import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator; + +public class LithuanianTransliterator extends SimpleTransliterator { + public LithuanianTransliterator() { + super(new HashMap() {{ + put('ą', "a"); put('č', "c"); put('ę', "e"); put('ė', "e"); put('į', "i"); put('š', "s"); put('ų', "u"); put('ū', "u"); put('ž', "z"); + }}); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/PersianTransliterator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/PersianTransliterator.java new file mode 100644 index 000000000..578e077ef --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/PersianTransliterator.java @@ -0,0 +1,35 @@ +/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele + Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg, + Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.util.language.impl; + +import java.util.HashMap; + +import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator; + +public class PersianTransliterator extends SimpleTransliterator { + public PersianTransliterator() { + super(new HashMap() {{ + // Persian (Farsi) + put('پ', "p"); put('چ', "ch"); put('ژ', "zh"); put('ک', "k"); put('گ', "g"); put('ی', "y"); put('‌', " "); + put('؟', "?"); put('٪', "%"); put('؛', ";"); put('،', ","); put('۱', "1"); put('۲', "2"); put('۳', "3"); + put('۴', "4"); put('۵', "5"); put('۶', "6"); put('۷', "7"); put('۸', "8"); put('۹', "9"); put('۰', "0"); + put('»', "<"); put('«', ">"); put('ِ', "e"); put('َ', "a"); put('ُ', "o"); put('ّ', ""); + }}); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/PolishTransliterator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/PolishTransliterator.java new file mode 100644 index 000000000..3af330ab3 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/PolishTransliterator.java @@ -0,0 +1,32 @@ +/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele + Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg, + Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.util.language.impl; + +import java.util.HashMap; + +import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator; + +public class PolishTransliterator extends SimpleTransliterator { + public PolishTransliterator() { + super(new HashMap() {{ + // Polish + put('Ł', "L"); put('ł', "l"); + }}); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/RussianTransliterator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/RussianTransliterator.java new file mode 100644 index 000000000..e1f6b864d --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/RussianTransliterator.java @@ -0,0 +1,37 @@ +/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele + Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg, + Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.util.language.impl; + +import java.util.HashMap; + +import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator; + +public class RussianTransliterator extends SimpleTransliterator { + public RussianTransliterator() { + super(new HashMap() {{ + put('а', "a"); put('б', "b"); put('в', "v"); put('г', "g"); put('д', "d"); put('е', "e"); put('ё', "jo"); put('ж', "zh"); + put('з', "z"); put('и', "i"); put('й', "jj"); put('к', "k"); put('л', "l"); put('м', "m"); put('н', "n"); put('о', "o"); + put('п', "p"); put('р', "r"); put('с', "s"); put('т', "t"); put('у', "u"); put('ф', "f"); put('х', "kh"); put('ц', "c"); + put('ч', "ch");put('ш', "sh");put('щ', "shh");put('ъ', "\"");put('ы', "y"); put('ь', "'"); put('э', "eh"); put('ю', "ju"); + put('я', "ja"); + + put('õ', "o"); put('č', "c"); + }}); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/ScandinavianTransliterator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/ScandinavianTransliterator.java new file mode 100644 index 000000000..e4ecfe841 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/ScandinavianTransliterator.java @@ -0,0 +1,33 @@ +/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele + Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg, + Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.util.language.impl; + +import java.util.HashMap; + +import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator; + +public class ScandinavianTransliterator extends SimpleTransliterator { + public ScandinavianTransliterator() { + super(new HashMap() {{ + put('Æ',"Ae"); put('æ',"ae"); + put('Ø',"Oe"); put('ø',"oe"); + put('Å',"Aa"); put('å',"aa"); + }}); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/TurkishTransliterator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/TurkishTransliterator.java new file mode 100644 index 000000000..997835d99 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/TurkishTransliterator.java @@ -0,0 +1,31 @@ +/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele + Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg, + Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.util.language.impl; + +import java.util.HashMap; + +import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator; + +public class TurkishTransliterator extends SimpleTransliterator { + public TurkishTransliterator() { + super(new HashMap() {{ + put('ı',"i"); + }}); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/UkranianTransliterator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/UkranianTransliterator.java new file mode 100644 index 000000000..3441585f0 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/language/impl/UkranianTransliterator.java @@ -0,0 +1,31 @@ +/* Copyright (C) 2017-2022 Andreas Shimokawa, Aniruddha Adhikary, Daniele + Gobbetti, ivanovlev, kalaee, lazarosfs, McSym28, M. Hadi, Roi Greenberg, + Taavi Eomäe, Ted Stein, Thomas, Yaron Shahrabani, José Rebelo + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.util.language.impl; + +import java.util.HashMap; + +import nodomain.freeyourgadget.gadgetbridge.util.language.SimpleTransliterator; + +public class UkranianTransliterator extends SimpleTransliterator { + public UkranianTransliterator() { + super(new HashMap() {{ + put('ґ', "gh"); put('є', "je"); put('і', "i"); put('ї', "ji"); put('Ґ', "GH"); put('Є', "JE"); put('І', "I"); put('Ї', "JI"); + }}); + } +} diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 944be85ea..ed69801e4 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -2278,5 +2278,47 @@ de.dennisguse.opentracks.nightly - + + @string/arabic + @string/bengali + @string/czech + @string/estonian + @string/extended_ascii + @string/german + @string/greek + @string/hebrew + @string/icelandic + @string/korean + @string/lithuanian + @string/persian + @string/polish + @string/russian + @string/scandinavian + @string/turkish + @string/ukranian + + + arabic + bengali + czech + estonian + extended_ascii + german + greek + hebrew + icelandic + korean + lithuanian + persian + polish + russian + scandinavian + turkish + ukranian + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 20d95325d..880fd8c88 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -746,6 +746,15 @@ Spanish Russian German + Bengali + Czech + Estonian + Extended ASCII + Icelandic + Lithuanian + Persian + Scandinavian + Ukranian Italian French Polish diff --git a/app/src/main/res/xml/devicesettings_transliteration.xml b/app/src/main/res/xml/devicesettings_transliteration.xml index 20b578c8c..59e0c4426 100644 --- a/app/src/main/res/xml/devicesettings_transliteration.xml +++ b/app/src/main/res/xml/devicesettings_transliteration.xml @@ -1,9 +1,13 @@ - - \ No newline at end of file + diff --git a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/TestDeviceSupport.java b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/TestDeviceSupport.java index ab336b28a..383e8b19a 100644 --- a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/TestDeviceSupport.java +++ b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/TestDeviceSupport.java @@ -2,6 +2,7 @@ package nodomain.freeyourgadget.gadgetbridge.service; import android.bluetooth.BluetoothAdapter; import android.content.Context; +import android.location.Location; import android.net.Uri; import java.util.ArrayList; @@ -225,4 +226,8 @@ class TestDeviceSupport extends AbstractDeviceSupport { public void onPowerOff() { } + + @Override public void onSetGpsLocation(Location location) { + + } } diff --git a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/LanguageUtilsTest.java b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/util/language/LanguageUtilsTest.java similarity index 68% rename from app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/LanguageUtilsTest.java rename to app/src/test/java/nodomain/freeyourgadget/gadgetbridge/util/language/LanguageUtilsTest.java index b25044174..ac23f26f1 100644 --- a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/LanguageUtilsTest.java +++ b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/util/language/LanguageUtilsTest.java @@ -1,4 +1,4 @@ -package nodomain.freeyourgadget.gadgetbridge.test; +package nodomain.freeyourgadget.gadgetbridge.util.language; import android.content.SharedPreferences; @@ -6,14 +6,12 @@ import org.junit.Test; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; -import nodomain.freeyourgadget.gadgetbridge.util.LanguageUtils; -import nodomain.freeyourgadget.gadgetbridge.util.KoreanLanguageUtils; -import nodomain.freeyourgadget.gadgetbridge.util.Prefs; +import nodomain.freeyourgadget.gadgetbridge.test.TestBase; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_TRANSLITERATION_ENABLED; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_TRANSLITERATION_LANGUAGES; /** * Tests LanguageUtils @@ -31,9 +29,11 @@ public class LanguageUtilsTest extends TestBase { @Test public void testStringTransliterateCyrillic() throws Exception { + final Transliterator transliterator = LanguageUtils.getTransliterator("russian"); + // input with cyrillic and diacritic letters String input = "Прõсто текčт"; - String output = LanguageUtils.transliterate(input); + String output = transliterator.transliterate(input); String result = "Prosto tekct"; assertEquals("Transliteration failed", result, output); @@ -41,8 +41,10 @@ public class LanguageUtilsTest extends TestBase { @Test public void testStringTransliterateHebrew() throws Exception { + final Transliterator transliterator = LanguageUtils.getTransliterator("hebrew"); + String input = "בדיקה עברית"; - String output = LanguageUtils.transliterate(input); + String output = transliterator.transliterate(input); String result = "bdykh 'bryth"; assertEquals("Transliteration failed", result, output); @@ -50,37 +52,48 @@ public class LanguageUtilsTest extends TestBase { @Test public void testStringTransliterateArabic() { + final Transliterator transliterator = LanguageUtils.getTransliterator("arabic"); + String pangram = "نص حكيم له سر قاطع وذو شأن عظيم مكتوب على ثوب أخضر ومغلف بجلد أزرق"; String pangramExpected = "n9 7kym lh sr qa63 wthw sh2n 36'ym mktwb 3la thwb 259'r wm3'lf bjld 2zrq"; - String pangramActual = LanguageUtils.transliterate(pangram); + String pangramActual = transliterator.transliterate(pangram); assertEquals("Arabic pangram transliteration failed", pangramExpected, pangramActual); String taMarbutah = "ﺓ"; String taMarbutahExpected = ""; - String taMarbutahActual = LanguageUtils.transliterate(taMarbutah); + String taMarbutahActual = transliterator.transliterate(taMarbutah); assertEquals("ta marbutah transliteration failed", taMarbutahExpected, taMarbutahActual); String hamza = "ءأؤإئآ"; String hamzaExpected = "222222"; - String hamzaActual = LanguageUtils.transliterate(hamza); + String hamzaActual = transliterator.transliterate(hamza); assertEquals("hamza transliteration failed", hamzaExpected, hamzaActual); String easternArabicNumeralsArabic = "٠١٢٣٤٥٦٧٨٩"; - String easternArabicNumeralsFarsi = "۰۱۲۳۴۵۶۷۸۹"; String easternArabicNumeralsExpected = "0123456789"; assertEquals("Eastern Arabic numerals (Arabic) failed", easternArabicNumeralsExpected, - LanguageUtils.transliterate(easternArabicNumeralsArabic)); - assertEquals("Eastern Arabic numerals (Farsi) failed", easternArabicNumeralsExpected, - LanguageUtils.transliterate(easternArabicNumeralsFarsi)); + transliterator.transliterate(easternArabicNumeralsArabic)); + } + + public void testStringTransliteratePersian() { + final Transliterator transliterator = LanguageUtils.getTransliterator("persian"); String farsi = "گچپژ"; String farsiExpected = "gchpzh"; - String farsiActual = LanguageUtils.transliterate(farsi); + String farsiActual = transliterator.transliterate(farsi); assertEquals("Farsi transiteration failed", farsiExpected, farsiActual); + + String easternArabicNumeralsFarsi = "۰۱۲۳۴۵۶۷۸۹"; + String easternArabicNumeralsExpected = "0123456789"; + + assertEquals("Eastern Arabic numerals (Farsi) failed", easternArabicNumeralsExpected, + transliterator.transliterate(easternArabicNumeralsFarsi)); } @Test public void testStringTransliterateBengali() throws Exception { + final Transliterator transliterator = LanguageUtils.getTransliterator("bengali"); + // input with cyrillic and diacritic letters String[] inputs = { "অনিরুদ্ধ", "বিজ্ঞানযাত্রা চলছে চলবে।", "আমি সব দেখেশুনে ক্ষেপে গিয়ে করি বাঙলায় চিৎকার!", "আমার জাভা কোড is so bad! কী আর বলবো!" }; @@ -91,17 +104,19 @@ public class LanguageUtilsTest extends TestBase { String result; for (int i = 0; i < inputs.length; i++) { - result = LanguageUtils.transliterate(inputs[i]); + result = transliterator.transliterate(inputs[i]); assertEquals("Transliteration failed", outputs[i], result); } } @Test public void testStringTransliterateKorean() { + final Transliterator transliterator = LanguageUtils.getTransliterator("korean"); + // A familiar phrase with no special provisions. String hello = "안녕하세요"; String helloExpected = "annyeonghaseyo"; - String helloActual = LanguageUtils.transliterate(hello); + String helloActual = transliterator.transliterate(hello); assertEquals("Korean hello transliteration failed", helloExpected, helloActual); // Korean pangram. Includes some ASCII punctuation which should not be changed by @@ -111,67 +126,65 @@ public class LanguageUtilsTest extends TestBase { // you complaining again?" String pangram = "\"웬 초콜릿? 제가 원했던 건 뻥튀기 쬐끔과 의류예요.\" \"얘야, 왜 또 불평?\""; String pangramExpected = "\"wen chokollit? jega wonhaetdeon geon ppeongtwigi jjoekkeumgwa uiryuyeyo.\" \"yaeya, wae tto bulpyeong?\""; - String pangramActual = LanguageUtils.transliterate(pangram); + String pangramActual = transliterator.transliterate(pangram); assertEquals("Korean pangram transliteration failed", pangramExpected, pangramActual); // Several words excercising special provisions, from Wikipedia. String special = "좋고, 놓다, 잡혀, 낳지"; String specialExpected = "joko, nota, japhyeo, nachi"; - String specialActual = LanguageUtils.transliterate(special); + String specialActual = transliterator.transliterate(special); assertEquals("Korean special provisions transliteration failed", specialExpected, specialActual); // Isolated jamo. String isolatedJamo = "ㅋㅋㅋ"; String isolatedJamoExpected = "kkk"; - String isolatedJamoActual = LanguageUtils.transliterate(isolatedJamo); + String isolatedJamoActual = transliterator.transliterate(isolatedJamo); assertEquals("Korean isolated jamo transliteration failed", isolatedJamoExpected, isolatedJamoActual); // Korean transliteration shouldn't touch non-Hangul composites. String german = "schön"; String germanExpected = german; - String germanActual = KoreanLanguageUtils.transliterate(german); + String germanActual = transliterator.transliterate(german); assertEquals("Korean transliteration modified a non-Hangul composite", germanExpected, germanActual); } @Test public void testStringTransliterateLithuanian() { + final Transliterator transliterator = LanguageUtils.getTransliterator("lithuanian"); + String input = "ą č ę ė į š ų ū ž"; - String output = LanguageUtils.transliterate(input); + String output = transliterator.transliterate(input); String expected = "a c e e i s u u z"; assertEquals("lithuanian translation failed", expected, output); input = "aąa cčc eęe eėe iįi sšs uųu uūu zžz"; - output = LanguageUtils.transliterate(input); + output = transliterator.transliterate(input); expected = "aaa ccc eee eee iii sss uuu uuu zzz"; assertEquals("lithuanian translation failed", expected, output); } @Test public void testTransliterateOption() throws Exception { - setDefaultTransliteration(); - assertFalse("Transliteration option fail! Expected 'Off' by default, but result is 'On'", + enableTransliteration(false); + assertNull("Transliteration option fail! Expected 'Off' by default, but result is 'On'", getTransliteration()); enableTransliteration(true); - assertTrue("Transliteration option fail! Expected 'On', but result is 'Off'", getTransliteration()); - } - - private void setDefaultTransliteration() { - SharedPreferences devicePrefs = GBApplication.getDeviceSpecificSharedPrefs(dummyGBDevice.getAddress()); - SharedPreferences.Editor editor = devicePrefs.edit(); - editor.remove(PREF_TRANSLITERATION_ENABLED); - editor.apply(); + assertNotNull("Transliteration option fail! Expected 'On', but result is 'Off'", getTransliteration()); } private void enableTransliteration(boolean enable) { SharedPreferences devicePrefs = GBApplication.getDeviceSpecificSharedPrefs(dummyGBDevice.getAddress()); SharedPreferences.Editor editor = devicePrefs.edit(); - editor.putBoolean(PREF_TRANSLITERATION_ENABLED, enable); + if (enable) { + editor.putString(PREF_TRANSLITERATION_LANGUAGES, "extended_ascii,scandinavian,german,russian,hebrew,greek,ukranian,arabic,persian,lithuanian,polish,estonian,icelandic,czech,turkish,bengali,korean"); + } else { + editor.remove(PREF_TRANSLITERATION_LANGUAGES); + } editor.apply(); } - private boolean getTransliteration(){ - Prefs devicePrefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(dummyGBDevice.getAddress())); - return devicePrefs.getBoolean(PREF_TRANSLITERATION_ENABLED, false); + private Transliterator getTransliteration() { + return LanguageUtils.getTransliterator(dummyGBDevice); } }