YAML language definitions (#292)
This commit is contained in:
parent
241a4125b0
commit
6756de4466
89 changed files with 689 additions and 522 deletions
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
|
|
@ -25,7 +25,7 @@ jobs:
|
||||||
|
|
||||||
# validation
|
# validation
|
||||||
- name: Validate Dictionaries
|
- name: Validate Dictionaries
|
||||||
run: ./gradlew validateDictionaries
|
run: ./gradlew validateLanguages
|
||||||
- name: Lint
|
- name: Lint
|
||||||
run: ./gradlew lint
|
run: ./gradlew lint
|
||||||
- name: Build Release APK
|
- name: Build Release APK
|
||||||
|
|
|
||||||
|
|
@ -48,17 +48,15 @@ Make sure you have a signing key. If you don't have one, follow the [official ma
|
||||||
## Adding a New Language
|
## Adding a New Language
|
||||||
To support a new language one needs to:
|
To support a new language one needs to:
|
||||||
|
|
||||||
- Find a suitable dictionary and add it to the `assets/` folder. Two file formats are supported, [see below](#dictionary-formats).
|
- Find a suitable dictionary and add it to the `assets/languages/dictionaries/` folder. Two file formats are supported, [see below](#dictionary-formats).
|
||||||
- Do not forget to include the dictionary license (or readme) file in the `docs/` folder.
|
- Do not forget to include the dictionary license (or readme) file in the `docs/` folder.
|
||||||
- Create a new language class in `languages/definitions/` and define its properties.
|
- Create a new `.yml` file in `assets/languages/definitions/` and define the language properties.
|
||||||
- `locale` contains the language and the country codes (e.g. "en-US", "es-AR", "it-IT"). Refer to the list of [supported locales in Java](https://www.oracle.com/java/technologies/javase/jdk8-jre8-suported-locales.html#util-text).
|
- `locale` contains the language and the country codes (e.g. "en-US", "es-AR", "it-IT"). Refer to the list of [supported locales in Java](https://www.oracle.com/java/technologies/javase/jdk8-jre8-suported-locales.html#util-text).
|
||||||
- `dictionaryFile` is the name of the dictionary in `assets/` folder.
|
- `dictionaryFile` is the name of the dictionary in `assets/languages/dictionaries/` folder.
|
||||||
- `characterMap` contains the letters and punctuation marks associated with each key.
|
- `layout` contains the letters and punctuation marks associated with each key. For 0-key and 1-key using `[DEFAULT]`, will be fine for most languages. However, if the language has extra punctuation marks, like Spanish, you could complement the list: `[DEFAULT, ¡, ¿]`
|
||||||
- `abcString` _(optional)_. A custom string to display in ABC mode. By default, the first three letters on 2-key are used (e.g. "ABC" or "АБВ"). Set this if the first letters of the alphabet are _not_ on 2-key, like in Hebrew, or if a different string makes more sense.
|
- `abcString` _(optional)_. A custom string to display in ABC mode. By default, the first three letters on 2-key are used (e.g. "ABC" or "АБВ"). Set this if the first letters of the alphabet are _not_ on 2-key, like in Hebrew, or if a different string makes more sense.
|
||||||
- `hasUpperCase` _(optional)_ set to `false` when the language has no upper- and lowercase letters. For example: Arabic, Hebrew, East Asian languages, and so on. The default is `true`.
|
- `hasUpperCase` _(optional)_ set to `no` when the language has no upper- and lowercase letters. For example: Arabic, Hebrew, East Asian languages, and so on. The default is `yes`.
|
||||||
- `name` _(optional)_ is automatically generated and equals the native name of the language (e.g. "English", "Deutsch", "Українська"). However, sometimes, the automatically selected name may be ambiguous. For example, both Portuguese in Portugal and Brazil will default to "Português", so assigning "Português brasileiro" would make it clear it's the language used in Brazil.
|
- `name` _(optional)_ is automatically generated and equals the native name of the language (e.g. "English", "Deutsch", "Українська"). However, sometimes, the automatically selected name may be ambiguous. For example, both Portuguese in Portugal and Brazil will default to "Português", so assigning "Português brasileiro" would make it clear it's the language used in Brazil.
|
||||||
- Finally, add the new language to the list in `LanguageCollection.java`. You only need to add it in one place, in the constructor. Please, be nice and maintain the alphabetical order.
|
|
||||||
|
|
||||||
|
|
||||||
### Dictionary Formats
|
### Dictionary Formats
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
# Traditional T9
|
# Traditional T9
|
||||||
TT9 is an IME (Input Method Editor) for Android devices with a hardware keypad. It supports [multiple languages](src/io/github/sspanak/tt9/languages/definitions) and predictive text typing.
|
TT9 is an IME (Input Method Editor) for Android devices with a hardware keypad. It supports [multiple languages](assets/languages/definitions) and predictive text typing.
|
||||||
|
|
||||||
This is an updated version of the [original project](https://github.com/Clam-/TraditionalT9) by Clam-.
|
This is an updated version of the [original project](https://github.com/Clam-/TraditionalT9) by Clam-.
|
||||||
|
|
||||||
|
|
@ -36,7 +36,7 @@ If you like Traditional T9, buy me a beer. Donations are currently accepted on [
|
||||||
|
|
||||||
## License
|
## License
|
||||||
- The source code, the logo image and the icons are licensed under the conditions described in [LICENSE.txt](LICENSE.txt).
|
- The source code, the logo image and the icons are licensed under the conditions described in [LICENSE.txt](LICENSE.txt).
|
||||||
- The dictionaries are licensed under the licenses provided in the [respective readme files](docs/dictionaries/), where applicable. Detailed information about the dictionaries is also available there.
|
- The dictionaries are licensed under the licenses provided in the [respective readme files](docs/dictionaries), where applicable. Detailed information about the dictionaries is also available there.
|
||||||
- [Silver foil photo created by rawpixel.com - www.freepik.com](https://www.freepik.com/photos/silver-foil)
|
- [Silver foil photo created by rawpixel.com - www.freepik.com](https://www.freepik.com/photos/silver-foil)
|
||||||
- "Negotiate" and "Vibrocentric" fonts are under [The Fontspring Desktop/Ebook Font End User License](docs/desktop-ebook-EULA-1.8.txt).
|
- "Negotiate" and "Vibrocentric" fonts are under [The Fontspring Desktop/Ebook Font End User License](docs/desktop-ebook-EULA-1.8.txt).
|
||||||
|
|
||||||
|
|
|
||||||
15
assets/languages/definitions/BrazilianPortuguese.yml
Normal file
15
assets/languages/definitions/BrazilianPortuguese.yml
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
---
|
||||||
|
locale: pt-BR
|
||||||
|
dictionaryFile: pt-BR-utf8.csv
|
||||||
|
name: Português brasileiro
|
||||||
|
layout:
|
||||||
|
- [DEFAULT] # 0
|
||||||
|
- [DEFAULT] # 1
|
||||||
|
- [a, b, c, ç, á, â, ã, à] # 2
|
||||||
|
- [d, e, f, é, ê, è] # 3
|
||||||
|
- [g, h, i, í] # 4
|
||||||
|
- [j, k, l] # 5
|
||||||
|
- [m, n, o, ó, ô, õ] # 6
|
||||||
|
- [p, q, r, s] # 7
|
||||||
|
- [t, u, v, ú] # 8
|
||||||
|
- [w, x, y, z] # 9
|
||||||
14
assets/languages/definitions/Bulgarian.yml
Normal file
14
assets/languages/definitions/Bulgarian.yml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
locale: bg-BG
|
||||||
|
dictionaryFile: bg-utf8.csv
|
||||||
|
layout:
|
||||||
|
- [DEFAULT] # 0
|
||||||
|
- [DEFAULT] # 1
|
||||||
|
- [а, б, в, г] # 2
|
||||||
|
- [д, е, ж, з] # 3
|
||||||
|
- [и, й, к, л, ѝ] # 4
|
||||||
|
- [м, н, о, п] # 5
|
||||||
|
- [р, с, т, у] # 6
|
||||||
|
- [ф, х, ц, ч] # 7
|
||||||
|
- [ш, щ, ъ] # 8
|
||||||
|
- [ь, ю, я] # 9
|
||||||
14
assets/languages/definitions/Dutch.yml
Normal file
14
assets/languages/definitions/Dutch.yml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
locale: nl-NL
|
||||||
|
dictionaryFile: nl-utf8.csv
|
||||||
|
layout:
|
||||||
|
- [DEFAULT] # 0
|
||||||
|
- [DEFAULT] # 1
|
||||||
|
- [a, b, c, à, ä, ç] # 2
|
||||||
|
- [d, e, f, é, è, ê, ë] # 3
|
||||||
|
- [g, h, i, î, ï] # 4
|
||||||
|
- [j, k, l] # 5
|
||||||
|
- [m, n, o, ö] # 6
|
||||||
|
- [p, q, r, s] # 7
|
||||||
|
- [t, u, v, û, ü] # 8
|
||||||
|
- [w, x, y, z] # 9
|
||||||
14
assets/languages/definitions/English.yml
Normal file
14
assets/languages/definitions/English.yml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
locale: en
|
||||||
|
dictionaryFile: en-utf8.csv
|
||||||
|
layout:
|
||||||
|
- [DEFAULT] # 0
|
||||||
|
- [DEFAULT] # 1
|
||||||
|
- [a, b, c] # 2
|
||||||
|
- [d, e, f] # 3
|
||||||
|
- [g, h, i] # 4
|
||||||
|
- [j, k, l] # 5
|
||||||
|
- [m, n, o] # 6
|
||||||
|
- [p, q, r, s] # 7
|
||||||
|
- [t, u, v] # 8
|
||||||
|
- [w, x, y, z] # 9
|
||||||
14
assets/languages/definitions/Finnish.yml
Normal file
14
assets/languages/definitions/Finnish.yml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
locale: fi-FI
|
||||||
|
dictionaryFile: fi-utf8.csv
|
||||||
|
layout:
|
||||||
|
- [DEFAULT] # 0
|
||||||
|
- [DEFAULT] # 1
|
||||||
|
- [a, b, c, ä, å] # 2
|
||||||
|
- [d, e, f] # 3
|
||||||
|
- [g, h, i] # 4
|
||||||
|
- [j, k, l] # 5
|
||||||
|
- [m, n, o, ö] # 6
|
||||||
|
- [p, q, r, s] # 7
|
||||||
|
- [t, u, v] # 8
|
||||||
|
- [w, x, y, z] # 9
|
||||||
14
assets/languages/definitions/French.yml
Normal file
14
assets/languages/definitions/French.yml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
locale: fr
|
||||||
|
dictionaryFile: fr-utf8.csv
|
||||||
|
layout:
|
||||||
|
- [DEFAULT] # 0
|
||||||
|
- [DEFAULT] # 1
|
||||||
|
- [a, b, c, à, â, æ, ç] # 2
|
||||||
|
- [d, e, f, é, è, ê, ë] # 3
|
||||||
|
- [g, h, i, î, ï] # 4
|
||||||
|
- [j, k, l] # 5
|
||||||
|
- [m, n, o, ô, œ] # 6
|
||||||
|
- [p, q, r, s] # 7
|
||||||
|
- [t, u, v, ù, û, ü] # 8
|
||||||
|
- [w, x, y, z, ÿ] # 9
|
||||||
14
assets/languages/definitions/German.yml
Normal file
14
assets/languages/definitions/German.yml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
locale: de
|
||||||
|
dictionaryFile: de-utf8.csv
|
||||||
|
layout:
|
||||||
|
- [DEFAULT] # 0
|
||||||
|
- [DEFAULT] # 1
|
||||||
|
- [a, b, c, ä] # 2
|
||||||
|
- [d, e, f] # 3
|
||||||
|
- [g, h, i] # 4
|
||||||
|
- [j, k, l] # 5
|
||||||
|
- [m, n, o, ö] # 6
|
||||||
|
- [p, q, r, s, ß] # 7
|
||||||
|
- [t, u, v, ü] # 8
|
||||||
|
- [w, x, y, z] # 9
|
||||||
16
assets/languages/definitions/Hebrew.yml
Normal file
16
assets/languages/definitions/Hebrew.yml
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
locale: iw-IL
|
||||||
|
dictionaryFile: he-utf8.csv
|
||||||
|
abcString: אבג
|
||||||
|
hasUpperCase: no
|
||||||
|
layout:
|
||||||
|
- [DEFAULT] # 0
|
||||||
|
- [DEFAULT] # 1
|
||||||
|
- [ד, ה, ו] # 2
|
||||||
|
- [א, ב, ג] # 3
|
||||||
|
- [מ, ם, נ, ן] # 4
|
||||||
|
- [י, כ, ך, ל] # 5
|
||||||
|
- [ז, ח, ט] # 6
|
||||||
|
- [ר, ש, ת] # 7
|
||||||
|
- [צ, ץ, ק] # 8
|
||||||
|
- [ס, ע, פ, ף] # 9
|
||||||
15
assets/languages/definitions/Indonesian.yml
Normal file
15
assets/languages/definitions/Indonesian.yml
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
---
|
||||||
|
locale: in-ID
|
||||||
|
dictionaryFile: id-utf8.csv
|
||||||
|
name: Bahasa Indonesia
|
||||||
|
layout:
|
||||||
|
- [DEFAULT] # 0
|
||||||
|
- [DEFAULT] # 1
|
||||||
|
- [a, b, c] # 2
|
||||||
|
- [d, e, f] # 3
|
||||||
|
- [g, h, i] # 4
|
||||||
|
- [j, k, l] # 5
|
||||||
|
- [m, n, o] # 6
|
||||||
|
- [p, q, r, s] # 7
|
||||||
|
- [t, u, v] # 8
|
||||||
|
- [w, x, y, z] # 9
|
||||||
14
assets/languages/definitions/Italian.yml
Normal file
14
assets/languages/definitions/Italian.yml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
locale: it
|
||||||
|
dictionaryFile: it-utf8.csv
|
||||||
|
layout:
|
||||||
|
- [DEFAULT] # 0
|
||||||
|
- [DEFAULT] # 1
|
||||||
|
- [a, b, c, à] # 2
|
||||||
|
- [d, e, f, é, è] # 3
|
||||||
|
- [g, h, i, ì, í, î] # 4
|
||||||
|
- [j, k, l] # 5
|
||||||
|
- [m, n, o, ò, ó] # 6
|
||||||
|
- [p, q, r, s] # 7
|
||||||
|
- [t, u, v, ù, ú] # 8
|
||||||
|
- [w, x, y, z] # 9
|
||||||
14
assets/languages/definitions/Norwegian.yml
Normal file
14
assets/languages/definitions/Norwegian.yml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
locale: nb-NO
|
||||||
|
dictionaryFile: nb-utf8.csv
|
||||||
|
layout:
|
||||||
|
- [DEFAULT] # 0
|
||||||
|
- [DEFAULT] # 1
|
||||||
|
- [a, b, c, æ, å] # 2
|
||||||
|
- [d, e, f, é, è] # 3
|
||||||
|
- [g, h, i] # 4
|
||||||
|
- [j, k, l] # 5
|
||||||
|
- [m, n, o, ø, ó, ò, ô] # 6
|
||||||
|
- [p, q, r, s] # 7
|
||||||
|
- [t, u, v, ü] # 8
|
||||||
|
- [w, x, y, z] # 9
|
||||||
14
assets/languages/definitions/Polish.yml
Normal file
14
assets/languages/definitions/Polish.yml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
locale: pl-PL
|
||||||
|
dictionaryFile: pl-utf8.csv
|
||||||
|
layout:
|
||||||
|
- [DEFAULT] # 0
|
||||||
|
- [DEFAULT] # 1
|
||||||
|
- [a, b, c, ą, ć] # 2
|
||||||
|
- [d, e, f, ę] # 3
|
||||||
|
- [g, h, i] # 4
|
||||||
|
- [j, k, l, ł] # 5
|
||||||
|
- [m, n, o, ó, ń] # 6
|
||||||
|
- [p, q, r, s, ś] # 7
|
||||||
|
- [t, u, v] # 8
|
||||||
|
- [w, x, y, z, ź, ż] # 9
|
||||||
14
assets/languages/definitions/Russian.yml
Normal file
14
assets/languages/definitions/Russian.yml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
locale: ru-RU
|
||||||
|
dictionaryFile: ru-utf8.csv
|
||||||
|
layout:
|
||||||
|
- [DEFAULT] # 0
|
||||||
|
- [DEFAULT] # 1
|
||||||
|
- [а, б, в, г] # 2
|
||||||
|
- [д, е, ё, ж, з] # 3
|
||||||
|
- [и, й, к, л] # 4
|
||||||
|
- [м, н, о, п] # 5
|
||||||
|
- [р, с, т, у] # 6
|
||||||
|
- [ф, х, ц, ч] # 7
|
||||||
|
- [ш, щ, ъ, ы] # 8
|
||||||
|
- [ь, э, ю, я] # 9
|
||||||
14
assets/languages/definitions/Spanish.yml
Normal file
14
assets/languages/definitions/Spanish.yml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
locale: es-ES
|
||||||
|
dictionaryFile: es-utf8.csv
|
||||||
|
layout:
|
||||||
|
- [DEFAULT] # 0
|
||||||
|
- [DEFAULT, ¡, ¿] # 1
|
||||||
|
- [a, b, c, á] # 2
|
||||||
|
- [d, e, f, é] # 3
|
||||||
|
- [g, h, i, í] # 4
|
||||||
|
- [j, k, l] # 5
|
||||||
|
- [m, n, ñ, o, ó] # 6
|
||||||
|
- [p, q, r, s] # 7
|
||||||
|
- [t, u, v, ú, ü] # 8
|
||||||
|
- [w, x, y, z] # 9
|
||||||
14
assets/languages/definitions/Swedish.yml
Normal file
14
assets/languages/definitions/Swedish.yml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
locale: sv-SE
|
||||||
|
dictionaryFile: sv-utf8.csv
|
||||||
|
layout:
|
||||||
|
- [DEFAULT] # 0
|
||||||
|
- [DEFAULT] # 1
|
||||||
|
- [a, b, c, å, ä] # 2
|
||||||
|
- [d, e, f, é] # 3
|
||||||
|
- [g, h, i] # 4
|
||||||
|
- [j, k, l] # 5
|
||||||
|
- [m, n, o, ö] # 6
|
||||||
|
- [p, q, r, s] # 7
|
||||||
|
- [t, u, v] # 8
|
||||||
|
- [w, x, y, z] # 9
|
||||||
14
assets/languages/definitions/Ukrainian.yml
Normal file
14
assets/languages/definitions/Ukrainian.yml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
locale: uk-UA
|
||||||
|
dictionaryFile: uk-utf8.csv
|
||||||
|
layout:
|
||||||
|
- [DEFAULT] # 0
|
||||||
|
- [DEFAULT] # 1
|
||||||
|
- [а, б, в, г, ґ] # 2
|
||||||
|
- [д, е, є, ж, з] # 3
|
||||||
|
- [и, і, ї, й, к, л] # 4
|
||||||
|
- [м, н, о, п] # 5
|
||||||
|
- [р, с, т, у] # 6
|
||||||
|
- [ф, х, ц, ч] # 7
|
||||||
|
- [ш, щ] # 8
|
||||||
|
- [ь, ю, я] # 9
|
||||||
16
assets/languages/definitions/Yiddish.yml
Normal file
16
assets/languages/definitions/Yiddish.yml
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
locale: ji-JI
|
||||||
|
dictionaryFile: ji-utf8.csv
|
||||||
|
abcString: אבג
|
||||||
|
hasUpperCase: no
|
||||||
|
layout:
|
||||||
|
- [DEFAULT] # 0
|
||||||
|
- [DEFAULT] # 1
|
||||||
|
- [ד, ה, ו] # 2
|
||||||
|
- [א, ב, ג] # 3
|
||||||
|
- [מ, ם, נ, ן] # 4
|
||||||
|
- [י, כ, ך, ל] # 5
|
||||||
|
- [ז, ח, ט] # 6
|
||||||
|
- [ר, ש, ת] # 7
|
||||||
|
- [צ, ץ, ק] # 8
|
||||||
|
- [ס, ע, פ, ף] # 9
|
||||||
|
Can't render this file because it is too large.
|
|
Can't render this file because it is too large.
|
|
Can't render this file because it is too large.
|
|
Can't render this file because it is too large.
|
|
Can't render this file because it is too large.
|
|
Can't render this file because it is too large.
|
|
Can't render this file because it is too large.
|
|
Can't render this file because it is too large.
|
|
Can't render this file because it is too large.
|
|
Can't render this file because it is too large.
|
|
Can't render this file because it is too large.
|
|
Can't render this file because it is too large.
|
|
Can't render this file because it is too large.
|
|
Can't render this file because it is too large.
|
|
Can't render this file because it is too large.
|
|
Can't render this file because it is too large.
|
|
Can't render this file because it is too large.
|
123
build.gradle
123
build.gradle
|
|
@ -2,17 +2,26 @@ buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
google()
|
google()
|
||||||
|
maven {
|
||||||
|
url "https://plugins.gradle.org/m2/"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:8.0.2'
|
classpath 'com.android.tools.build:gradle:8.0.2'
|
||||||
|
classpath 'gradle.plugin.at.zierler:yaml-validator-plugin:1.5.0'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
|
apply plugin: 'at.zierler.yamlvalidator'
|
||||||
|
|
||||||
configurations.all {
|
configurations.all {
|
||||||
// fixes 'duplicate class error', when using these combine: androidx.core:1.10.1, androidx.preference:1.2.0 and androidx.room:2.5.1
|
// fixes 'duplicate class error', when using these combine: androidx.core:1.10.1, androidx.preference:1.2.0 and androidx.room:2.5.1
|
||||||
// see: https://stackoverflow.com/questions/75274720/a-failure-occurred-while-executing-appcheckdebugduplicateclasses/75315276#75315276
|
// see: https://stackoverflow.com/questions/75274720/a-failure-occurred-while-executing-appcheckdebugduplicateclasses/75315276#75315276
|
||||||
exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-jdk8'
|
exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-jdk8'
|
||||||
|
|
||||||
|
yamlValidator {
|
||||||
|
searchPaths = ['assets/languages/definitions']
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
@ -20,11 +29,15 @@ dependencies {
|
||||||
implementation 'androidx.preference:preference:1.2.0'
|
implementation 'androidx.preference:preference:1.2.0'
|
||||||
implementation 'androidx.room:room-runtime:2.5.1'
|
implementation 'androidx.room:room-runtime:2.5.1'
|
||||||
annotationProcessor 'androidx.room:room-compiler:2.5.1'
|
annotationProcessor 'androidx.room:room-compiler:2.5.1'
|
||||||
|
implementation 'org.yaml:snakeyaml:2.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
google()
|
google()
|
||||||
|
maven {
|
||||||
|
url "https://plugins.gradle.org/m2/"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def execThing ( String cmdStr ) {
|
def execThing ( String cmdStr ) {
|
||||||
|
|
@ -86,9 +99,13 @@ def getReleaseVersion = { ->
|
||||||
return "${getVersionName()} (${getCurrentGitHash()})"
|
return "${getVersionName()} (${getCurrentGitHash()})"
|
||||||
}
|
}
|
||||||
|
|
||||||
task validateDictionaries {
|
task validateLanguages {
|
||||||
inputs.dir fileTree(dir:'assets', excludes:['dict.properties'])
|
final baseDir = "${project.rootDir}/assets/languages"
|
||||||
outputs.file "${project.buildDir}/dict.validation.txt"
|
final definitionsDir = "${baseDir}/definitions"
|
||||||
|
final dictionariesDir = "${baseDir}/dictionaries"
|
||||||
|
|
||||||
|
inputs.dir fileTree(dir:baseDir, excludes:['dict.properties'])
|
||||||
|
outputs.file "${project.buildDir}/lang.validation.txt"
|
||||||
|
|
||||||
doLast {
|
doLast {
|
||||||
final String CSV_DELIMITER = ' ' // TAB
|
final String CSV_DELIMITER = ' ' // TAB
|
||||||
|
|
@ -100,19 +117,86 @@ task validateDictionaries {
|
||||||
|
|
||||||
outputs.files.singleFile.text = ""
|
outputs.files.singleFile.text = ""
|
||||||
|
|
||||||
inputs.getFiles().each {File file ->
|
fileTree(definitionsDir).getFiles().each { File languageFile ->
|
||||||
if (errorCount >= MAX_ERRORS) {
|
if (errorCount >= MAX_ERRORS) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
println "Validating dictionary: " + file.name
|
println "Validating language: ${languageFile.name}"
|
||||||
|
|
||||||
def uniqueWords = [:]
|
|
||||||
|
|
||||||
int lineNumber = 0
|
|
||||||
boolean isFileValid = true
|
boolean isFileValid = true
|
||||||
|
|
||||||
file.eachLine {line ->
|
boolean hasLayout = false
|
||||||
|
boolean isLocaleValid = false
|
||||||
|
def localeString = ''
|
||||||
|
def dictionaryFileName = ''
|
||||||
|
|
||||||
|
languageFile.eachLine { line ->
|
||||||
|
if (
|
||||||
|
line.matches("^[a-zA-Z].*")
|
||||||
|
&& !line.startsWith("abcString")
|
||||||
|
&& !line.startsWith("dictionaryFile")
|
||||||
|
&& !line.startsWith("hasUpperCase")
|
||||||
|
&& !line.startsWith("layout")
|
||||||
|
&& !line.startsWith("locale")
|
||||||
|
&& !line.startsWith("name")
|
||||||
|
) {
|
||||||
|
isFileValid = false
|
||||||
|
def parts = line.split(":")
|
||||||
|
def property = parts.length > 0 ? parts[0] : line
|
||||||
|
|
||||||
|
errorCount++
|
||||||
|
errors += "Language '${languageFile.name}' is invalid. Found unknown property: '${property}'.\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.startsWith("hasUpperCase") && !line.endsWith("yes") && !line.endsWith("no")) {
|
||||||
|
def invalidVal = line.replace("hasUpperCase:", "").trim()
|
||||||
|
isFileValid = false
|
||||||
|
errorCount++
|
||||||
|
errors += "Language '${languageFile.name}' is invalid. Unrecognized 'hasUpperCase' value: '${invalidVal}'. Only 'yes' and 'no' are allowed.\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.startsWith("layout")) {
|
||||||
|
hasLayout = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.startsWith("locale")) {
|
||||||
|
localeString = line.replace("locale:", "").trim()
|
||||||
|
isLocaleValid = line.matches("^locale:\\s*[a-z]{2}(?:-[A-Z]{2})?")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.startsWith("dictionaryFile")) {
|
||||||
|
dictionaryFileName = line.replace("dictionaryFile:", "").trim()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasLayout) {
|
||||||
|
isFileValid = false
|
||||||
|
errorCount++
|
||||||
|
errors += "Language '${languageFile.name}' is invalid. Missing 'layout' property.\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isLocaleValid) {
|
||||||
|
isFileValid = false
|
||||||
|
errorCount++
|
||||||
|
def msg = localeString.isEmpty() ? "Missing 'locale' property." : "Unrecognized locale format: '${localeString}'"
|
||||||
|
errors += "Language '${languageFile.name}' is invalid. ${msg}\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
def dictionaryFile = new File("$dictionariesDir/${dictionaryFileName}")
|
||||||
|
if (dictionaryFileName.isEmpty() || !dictionaryFile.exists()) {
|
||||||
|
errorCount++
|
||||||
|
errors += "Could not find dictionary file: '${dictionaryFileName}' in: '${dictionariesDir}'. Make sure 'dictionaryFile' is set correctly in: '${languageFile.name}'.\n"
|
||||||
|
|
||||||
|
outputs.files.singleFile.text += "${languageFile.name} INVALID \n"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def uniqueWords = [:]
|
||||||
|
int lineNumber = 0
|
||||||
|
|
||||||
|
dictionaryFile.eachLine {line ->
|
||||||
if (errorCount >= MAX_ERRORS) {
|
if (errorCount >= MAX_ERRORS) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -122,14 +206,14 @@ task validateDictionaries {
|
||||||
if (line == "") {
|
if (line == "") {
|
||||||
isFileValid = false
|
isFileValid = false
|
||||||
errorCount++
|
errorCount++
|
||||||
errors += "Dictionary '" + file.name + "' is invalid. There is no word on line " + lineNumber + ". Remove all empty lines.\n"
|
errors += "Dictionary '${dictionaryFile.name}' is invalid. There is no word on line ${lineNumber}. Remove all empty lines.\n"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (line.contains(" ")) {
|
if (line.contains(" ")) {
|
||||||
isFileValid = false
|
isFileValid = false
|
||||||
errorCount++
|
errorCount++
|
||||||
errors += "Dictionary '" + file.name + "' is invalid. Found space on line " + lineNumber + ". Make sure each word is on a new line. Phrases are not allowed.\n"
|
errors += "Dictionary '${dictionaryFile.name}' is invalid. Found space on line ${lineNumber}. Make sure each word is on a new line. Phrases are not allowed.\n"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -140,32 +224,32 @@ task validateDictionaries {
|
||||||
if (frequency.length() > 0 && !frequency.matches("^\\d+\$")) {
|
if (frequency.length() > 0 && !frequency.matches("^\\d+\$")) {
|
||||||
isFileValid = false
|
isFileValid = false
|
||||||
errorCount++
|
errorCount++
|
||||||
errors += "Dictionary '" + file.name + "' is invalid. Found out-of-range word frequency: '" + frequency + "' on line " + lineNumber + ". Frequency must be a non-negative integer.\n"
|
errors += "Dictionary '${dictionaryFile.name}' is invalid. Found out-of-range word frequency: '${frequency}' on line ${lineNumber}. Frequency must be a non-negative integer.\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
if (word.matches("(\\d.+?|.+?\\d|\\d)")) {
|
if (word.matches("(\\d.+?|.+?\\d|\\d)")) {
|
||||||
isFileValid = false
|
isFileValid = false
|
||||||
errorCount++
|
errorCount++
|
||||||
errors += "Dictionary '" + file.name + "' is invalid. Found numbers on line " + lineNumber + ". Remove all numbers.\n"
|
errors += "Dictionary '${dictionaryFile.name}' is invalid. Found numbers on line ${lineNumber}. Remove all numbers.\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
if (word.matches("^\\P{L}+\$")) {
|
if (word.matches("^\\P{L}+\$")) {
|
||||||
isFileValid = false
|
isFileValid = false
|
||||||
errorCount++
|
errorCount++
|
||||||
errors += "Dictionary '" + file.name + "' is invalid. Found a garbage word: '" + word + "' on line " + lineNumber + ".\n"
|
errors += "Dictionary '${dictionaryFile.name}' is invalid. Found a garbage word: '${word}' on line ${lineNumber}.\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
if (word.matches("^.\$") && !Character.isUpperCase(word.charAt(0))) {
|
if (word.matches("^.\$") && !Character.isUpperCase(word.charAt(0))) {
|
||||||
isFileValid = false
|
isFileValid = false
|
||||||
errorCount++
|
errorCount++
|
||||||
errors += "Dictionary '" + file.name + "' is invalid. Found a single letter: '" + word + "' on line " + lineNumber + ". Only uppercase single letters are allowed. The rest of the alphabet will be added automatically.\n"
|
errors += "Dictionary '${dictionaryFile.name}' is invalid. Found a single letter: '${word}' on line ${lineNumber}. Only uppercase single letters are allowed. The rest of the alphabet will be added automatically.\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
String uniqueWordKey = word ==~ GEOGRAPHICAL_NAME ? word : word.toLowerCase()
|
String uniqueWordKey = word ==~ GEOGRAPHICAL_NAME ? word : word.toLowerCase()
|
||||||
if (uniqueWords[uniqueWordKey] != null && uniqueWords[uniqueWordKey] == true) {
|
if (uniqueWords[uniqueWordKey] != null && uniqueWords[uniqueWordKey] == true) {
|
||||||
isFileValid = false
|
isFileValid = false
|
||||||
errorCount++
|
errorCount++
|
||||||
errors += "Dictionary '" + file.name + "' is invalid. Found a repeating word: '" + word + "' on line " + lineNumber + ". Ensure all words appear only once.\n"
|
errors += "Dictionary '${dictionaryFile.name}' is invalid. Found a repeating word: '${word}' on line ${lineNumber}. Ensure all words appear only once.\n"
|
||||||
} else {
|
} else {
|
||||||
uniqueWords[uniqueWordKey] = true
|
uniqueWords[uniqueWordKey] = true
|
||||||
}
|
}
|
||||||
|
|
@ -175,7 +259,7 @@ task validateDictionaries {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
outputs.files.singleFile.text += file.name + " " + (isFileValid ? "OK" : "INVALID") + "\n"
|
outputs.files.singleFile.text += "${languageFile.name} ${isFileValid ? 'OK' : 'INVALID'}\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errors != "") {
|
if (errors != "") {
|
||||||
|
|
@ -239,7 +323,10 @@ android {
|
||||||
aidl true
|
aidl true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
applicationVariants.all { variant ->
|
applicationVariants.all { variant ->
|
||||||
tasks["merge${variant.name.capitalize()}Assets"].dependsOn(validateDictionaries)
|
tasks["merge${variant.name.capitalize()}Assets"]
|
||||||
|
.dependsOn(validateYaml)
|
||||||
|
.dependsOn(validateLanguages)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,4 +19,16 @@
|
||||||
# public *;
|
# public *;
|
||||||
#}
|
#}
|
||||||
|
|
||||||
-keep class io.github.sspanak.tt9.languages.definitions.** { *; }
|
# LanguageDefinition properties must be preserved so that SnakeYAML can map them
|
||||||
|
# to the language YAMLs.
|
||||||
|
-keepclassmembers class io.github.sspanak.tt9.languages.LanguageDefinition {
|
||||||
|
public *;
|
||||||
|
}
|
||||||
|
|
||||||
|
# SnakeYAML shall not complain. As resolved by Mozilla:
|
||||||
|
# https://github.com/mozilla-mobile/focus-android/blob/main/app/proguard-rules.pro
|
||||||
|
-dontwarn java.beans.BeanInfo
|
||||||
|
-dontwarn java.beans.FeatureDescriptor
|
||||||
|
-dontwarn java.beans.IntrospectionException
|
||||||
|
-dontwarn java.beans.Introspector
|
||||||
|
-dontwarn java.beans.PropertyDescriptor
|
||||||
|
|
|
||||||
|
|
@ -2,19 +2,18 @@
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_settings">Настройки на TT9</string>
|
<string name="app_settings">Настройки на TT9</string>
|
||||||
<string name="completed">Завършено</string>
|
<string name="completed">Завършено</string>
|
||||||
|
<string name="no_language">Няма език</string>
|
||||||
<string name="error_unexpected">Възникна неочаквана грешка.</string>
|
<string name="error_unexpected">Възникна неочаквана грешка.</string>
|
||||||
|
<string name="failed_loading_language_definitions">Не може да се заредят езиковите дефиниции.</string>
|
||||||
<string name="add_word_add">Добави</string>
|
<string name="add_word_add">Добави</string>
|
||||||
<string name="add_word_blank">Не може да се въведе празна дума.</string>
|
<string name="add_word_blank">Не може да се въведе празна дума.</string>
|
||||||
<string name="add_word_exist">Думата „%1$s“ е вече речника.</string>
|
<string name="add_word_exist">Думата „%1$s“ е вече речника.</string>
|
||||||
<string name="add_word_title">Добавяне на дума</string>
|
<string name="add_word_title">Добавяне на дума</string>
|
||||||
|
|
||||||
<string name="pref_category_about">За приложението</string>
|
<string name="pref_category_about">За приложението</string>
|
||||||
<string name="pref_help">Помощ</string>
|
<string name="pref_help">Помощ</string>
|
||||||
<string name="pref_dark_theme">Тъмен облик</string>
|
<string name="pref_dark_theme">Тъмен облик</string>
|
||||||
<string name="pref_choose_languages">Езици</string>
|
<string name="pref_choose_languages">Езици</string>
|
||||||
<string name="dictionary_truncate_title">Изтрий всички</string>
|
<string name="dictionary_truncate_title">Изтрий всички</string>
|
||||||
|
|
||||||
<string name="dictionary_cancel_load">Отмени зареждането</string>
|
<string name="dictionary_cancel_load">Отмени зареждането</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_load_error">Несупешно зареждане на речник за език „%1$s“ (%2$s).</string>
|
<string name="dictionary_load_error">Несупешно зареждане на речник за език „%1$s“ (%2$s).</string>
|
||||||
|
|
@ -69,4 +68,5 @@
|
||||||
<string name="key_volume_down">Намаляне на звук</string>
|
<string name="key_volume_down">Намаляне на звук</string>
|
||||||
<string name="key_volume_up">Усилване на звук</string>
|
<string name="key_volume_up">Усилване на звук</string>
|
||||||
<string name="dictionary_truncating">Изтриване…</string>
|
<string name="dictionary_truncating">Изтриване…</string>
|
||||||
|
<string name="error">Грешка</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_settings">TT9 Einstellungen</string>
|
<string name="app_settings">TT9 Einstellungen</string>
|
||||||
|
<string name="no_language">Keine Sprache</string>
|
||||||
<string name="error_unexpected">Unerwarteter Fehler aufgetreten.</string>
|
<string name="error_unexpected">Unerwarteter Fehler aufgetreten.</string>
|
||||||
|
|
||||||
<string name="add_word_add">Hinzufügen</string>
|
<string name="add_word_add">Hinzufügen</string>
|
||||||
|
|
@ -21,4 +22,5 @@
|
||||||
<string name="char_space">Leerzeichen</string>
|
<string name="char_space">Leerzeichen</string>
|
||||||
<string name="char_newline">Neue Zeile</string>
|
<string name="char_newline">Neue Zeile</string>
|
||||||
<string name="pref_category_setup">Ersteinrichtung</string>
|
<string name="pref_category_setup">Ersteinrichtung</string>
|
||||||
|
<string name="error">Fehler</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
<string name="add_word_blank">Palabra en blanco no agregada.</string>
|
<string name="add_word_blank">Palabra en blanco no agregada.</string>
|
||||||
<string name="pref_help">Ayuda</string>
|
<string name="pref_help">Ayuda</string>
|
||||||
<string name="completed">Acabado</string>
|
<string name="completed">Acabado</string>
|
||||||
|
<string name="no_language">Sin idioma</string>
|
||||||
<string name="error_unexpected">Ocurrió un error inesperado.</string>
|
<string name="error_unexpected">Ocurrió un error inesperado.</string>
|
||||||
<string name="add_word_exist">La palabra \"%1$s\" ya esta en el diccionario.</string>
|
<string name="add_word_exist">La palabra \"%1$s\" ya esta en el diccionario.</string>
|
||||||
<string name="add_word_title">Agregar palabra</string>
|
<string name="add_word_title">Agregar palabra</string>
|
||||||
|
|
@ -35,4 +36,5 @@
|
||||||
<string name="pref_upside_down_keys_summary">Habilite la configuración si hay 7–8–9 en la primera fila, en lugar de 1–2–3.</string>
|
<string name="pref_upside_down_keys_summary">Habilite la configuración si hay 7–8–9 en la primera fila, en lugar de 1–2–3.</string>
|
||||||
<string name="pref_category_setup">Configuración inicial</string>
|
<string name="pref_category_setup">Configuración inicial</string>
|
||||||
<string name="pref_show_soft_numpad">Teclado numérico en pantalla</string>
|
<string name="pref_show_soft_numpad">Teclado numérico en pantalla</string>
|
||||||
|
<string name="error">Error</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -2,19 +2,18 @@
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_settings">Paramètres de TT9</string>
|
<string name="app_settings">Paramètres de TT9</string>
|
||||||
<string name="completed">Fini</string>
|
<string name="completed">Fini</string>
|
||||||
|
<string name="no_language">Aucun langue</string>
|
||||||
<string name="error_unexpected">Une erreur inattendue s\'est produite.</string>
|
<string name="error_unexpected">Une erreur inattendue s\'est produite.</string>
|
||||||
|
<string name="failed_loading_language_definitions">Impossible de charger aucune définition de langue</string>
|
||||||
<string name="add_word_add">Ajouter</string>
|
<string name="add_word_add">Ajouter</string>
|
||||||
<string name="add_word_blank">Mot vide non ajouté.</string>
|
<string name="add_word_blank">Mot vide non ajouté.</string>
|
||||||
<string name="add_word_exist">Le mot «%1$s» est déjà dans le dictionnaire.</string>
|
<string name="add_word_exist">Le mot «%1$s» est déjà dans le dictionnaire.</string>
|
||||||
<string name="add_word_title">Ajouter un mot</string>
|
<string name="add_word_title">Ajouter un mot</string>
|
||||||
|
|
||||||
<string name="pref_category_about">À propos de l\'application</string>
|
<string name="pref_category_about">À propos de l\'application</string>
|
||||||
<string name="pref_help">Aide</string>
|
<string name="pref_help">Aide</string>
|
||||||
<string name="pref_dark_theme">Thème sombre</string>
|
<string name="pref_dark_theme">Thème sombre</string>
|
||||||
<string name="pref_choose_languages">Langues</string>
|
<string name="pref_choose_languages">Langues</string>
|
||||||
<string name="dictionary_truncate_title">Supprimer tous</string>
|
<string name="dictionary_truncate_title">Supprimer tous</string>
|
||||||
|
|
||||||
<string name="dictionary_cancel_load">Annuler le chargement</string>
|
<string name="dictionary_cancel_load">Annuler le chargement</string>
|
||||||
<string name="dictionary_load_error">Echec du chargement de dictionnaire pour langue «%1$s» (%2$s).</string>
|
<string name="dictionary_load_error">Echec du chargement de dictionnaire pour langue «%1$s» (%2$s).</string>
|
||||||
<string name="dictionary_loaded">Chargement du dictionnaire terminé.</string>
|
<string name="dictionary_loaded">Chargement du dictionnaire terminé.</string>
|
||||||
|
|
@ -64,4 +63,5 @@
|
||||||
<string name="pref_category_setup">Configuration initiale</string>
|
<string name="pref_category_setup">Configuration initiale</string>
|
||||||
<string name="pref_show_soft_numpad">Pavé numérique à l\'écran</string>
|
<string name="pref_show_soft_numpad">Pavé numérique à l\'écran</string>
|
||||||
<string name="dictionary_truncating">Suppression…</string>
|
<string name="dictionary_truncating">Suppression…</string>
|
||||||
|
<string name="error">Erreur</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_settings">TT9 Impostazioni</string>
|
<string name="app_settings">TT9 Impostazioni</string>
|
||||||
<string name="completed">Completato</string>
|
<string name="completed">Completato</string>
|
||||||
|
<string name="no_language">Nessuna lingua</string>
|
||||||
<string name="error_unexpected">Si è verificato un errore imprevisto.</string>
|
<string name="error_unexpected">Si è verificato un errore imprevisto.</string>
|
||||||
|
|
||||||
<string name="add_word_add">Aggiungere</string>
|
<string name="add_word_add">Aggiungere</string>
|
||||||
|
|
@ -30,5 +31,6 @@
|
||||||
<string name="pref_upside_down_keys">Invertire l\'ordine delle chiavi</string>
|
<string name="pref_upside_down_keys">Invertire l\'ordine delle chiavi</string>
|
||||||
<string name="pref_upside_down_keys_summary">Abilita l\'impostazione se ci sono 7–8–9 sulla prima riga, invece di 1–2–3.</string>
|
<string name="pref_upside_down_keys_summary">Abilita l\'impostazione se ci sono 7–8–9 sulla prima riga, invece di 1–2–3.</string>
|
||||||
<string name="pref_category_setup">Configurazione iniziale</string>
|
<string name="pref_category_setup">Configurazione iniziale</string>
|
||||||
|
<string name="error">Errore</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_settings">TT9 הגדרות</string>
|
<string name="app_settings">TT9 הגדרות</string>
|
||||||
<string name="completed">הסתיים</string>
|
<string name="completed">הסתיים</string>
|
||||||
|
<string name="no_language">אין שפה</string>
|
||||||
<string name="error_unexpected">אירעה שגיאה לא צפויה.</string>
|
<string name="error_unexpected">אירעה שגיאה לא צפויה.</string>
|
||||||
|
|
||||||
<string name="add_word_add">הוסף</string>
|
<string name="add_word_add">הוסף</string>
|
||||||
|
|
@ -53,4 +54,5 @@
|
||||||
|
|
||||||
<string name="char_newline">שורה חדשה</string>
|
<string name="char_newline">שורה חדשה</string>
|
||||||
<string name="char_space">רווח</string>
|
<string name="char_space">רווח</string>
|
||||||
|
<string name="error">טעות</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_settings">TT9 Opties</string>
|
<string name="app_settings">TT9 Opties</string>
|
||||||
|
<string name="no_language">Geen taal</string>
|
||||||
<string name="error_unexpected">Er is een onverwachte fout opgetreden.</string>
|
<string name="error_unexpected">Er is een onverwachte fout opgetreden.</string>
|
||||||
|
|
||||||
<string name="add_word_add">Toevoegen</string>
|
<string name="add_word_add">Toevoegen</string>
|
||||||
|
|
@ -21,4 +22,5 @@
|
||||||
<string name="char_newline">Nieuwe regel</string>
|
<string name="char_newline">Nieuwe regel</string>
|
||||||
<string name="pref_category_setup">Initiële setup</string>
|
<string name="pref_category_setup">Initiële setup</string>
|
||||||
<string name="dictionary_truncating">Verwijderen…</string>
|
<string name="dictionary_truncating">Verwijderen…</string>
|
||||||
|
<string name="error">Fout</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_settings">Configurações do Teclado</string>
|
<string name="app_settings">Configurações do Teclado</string>
|
||||||
<string name="completed">Concluído</string>
|
<string name="completed">Concluído</string>
|
||||||
|
<string name="no_language">Sem idioma</string>
|
||||||
<string name="error_unexpected">Um erro inesperado aconteceu.</string>
|
<string name="error_unexpected">Um erro inesperado aconteceu.</string>
|
||||||
|
|
||||||
<string name="add_word_add">Adicionar</string>
|
<string name="add_word_add">Adicionar</string>
|
||||||
|
|
@ -56,4 +57,5 @@
|
||||||
<string name="pref_upside_down_keys_summary">Utilize essa opção se você possuir as teclas 7–8–9 na linha de cima, ao invés de 1–2–3.</string>
|
<string name="pref_upside_down_keys_summary">Utilize essa opção se você possuir as teclas 7–8–9 na linha de cima, ao invés de 1–2–3.</string>
|
||||||
<string name="pref_upside_down_keys">Inverter Ordem das Teclas</string>
|
<string name="pref_upside_down_keys">Inverter Ordem das Teclas</string>
|
||||||
<string name="dictionary_truncate_unselected">Limpar Não Selecionados</string>
|
<string name="dictionary_truncate_unselected">Limpar Não Selecionados</string>
|
||||||
|
<string name="error">Erro</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -2,19 +2,18 @@
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_settings">TT9 настройки</string>
|
<string name="app_settings">TT9 настройки</string>
|
||||||
<string name="completed">Выполнено</string>
|
<string name="completed">Выполнено</string>
|
||||||
|
<string name="no_language">Нет языка</string>
|
||||||
<string name="error_unexpected">Произошла непредвиденная ошибка.</string>
|
<string name="error_unexpected">Произошла непредвиденная ошибка.</string>
|
||||||
|
<string name="failed_loading_language_definitions">Не удалось загрузить какое-либо определение языка.</string>
|
||||||
<string name="add_word_add">Добавить</string>
|
<string name="add_word_add">Добавить</string>
|
||||||
<string name="add_word_blank">Невозможно добавить слово.</string>
|
<string name="add_word_blank">Невозможно добавить слово.</string>
|
||||||
<string name="add_word_exist">Слово «%1$s» уже есть в словаре.</string>
|
<string name="add_word_exist">Слово «%1$s» уже есть в словаре.</string>
|
||||||
<string name="add_word_title">Добавить слово</string>
|
<string name="add_word_title">Добавить слово</string>
|
||||||
|
|
||||||
<string name="pref_category_about">О приложении</string>
|
<string name="pref_category_about">О приложении</string>
|
||||||
<string name="pref_help">Помощь</string>
|
<string name="pref_help">Помощь</string>
|
||||||
<string name="pref_dark_theme">Темная тема</string>
|
<string name="pref_dark_theme">Темная тема</string>
|
||||||
<string name="pref_choose_languages">Языки</string>
|
<string name="pref_choose_languages">Языки</string>
|
||||||
<string name="dictionary_truncate_title">Удалить все</string>
|
<string name="dictionary_truncate_title">Удалить все</string>
|
||||||
|
|
||||||
<string name="dictionary_cancel_load">Отменить загрузку</string>
|
<string name="dictionary_cancel_load">Отменить загрузку</string>
|
||||||
<string name="dictionary_load_error">Ошибка загрузки словаря для языка «%1$s» (%2$s).</string>
|
<string name="dictionary_load_error">Ошибка загрузки словаря для языка «%1$s» (%2$s).</string>
|
||||||
<string name="dictionary_loaded">Загрузка словаря завершена.</string>
|
<string name="dictionary_loaded">Загрузка словаря завершена.</string>
|
||||||
|
|
@ -69,4 +68,5 @@
|
||||||
<string name="key_volume_down">Уменьшить громкости</string>
|
<string name="key_volume_down">Уменьшить громкости</string>
|
||||||
<string name="key_volume_up">Увеличить громкости</string>
|
<string name="key_volume_up">Увеличить громкости</string>
|
||||||
<string name="dictionary_truncating">Удаление…</string>
|
<string name="dictionary_truncating">Удаление…</string>
|
||||||
|
<string name="error">Ошибка</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -2,19 +2,18 @@
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_settings">Налаштування TT9</string>
|
<string name="app_settings">Налаштування TT9</string>
|
||||||
<string name="completed">Зроблено</string>
|
<string name="completed">Зроблено</string>
|
||||||
|
<string name="no_language">Немає мови</string>
|
||||||
<string name="error_unexpected">Сталася неочікувана помилка.</string>
|
<string name="error_unexpected">Сталася неочікувана помилка.</string>
|
||||||
|
<string name="failed_loading_language_definitions">Не вдалося завантажити всі визначення мови.</string>
|
||||||
<string name="add_word_add">Додати</string>
|
<string name="add_word_add">Додати</string>
|
||||||
<string name="add_word_blank">Неможливо додати слово.</string>
|
<string name="add_word_blank">Неможливо додати слово.</string>
|
||||||
<string name="add_word_exist">Слово «%1$s» вже є в словнику.</string>
|
<string name="add_word_exist">Слово «%1$s» вже є в словнику.</string>
|
||||||
<string name="add_word_title">Додати слово</string>
|
<string name="add_word_title">Додати слово</string>
|
||||||
|
|
||||||
<string name="pref_category_about">Про додаток</string>
|
<string name="pref_category_about">Про додаток</string>
|
||||||
<string name="pref_help">Допомога</string>
|
<string name="pref_help">Допомога</string>
|
||||||
<string name="pref_dark_theme">Темна тема</string>
|
<string name="pref_dark_theme">Темна тема</string>
|
||||||
<string name="pref_choose_languages">Мови</string>
|
<string name="pref_choose_languages">Мови</string>
|
||||||
<string name="dictionary_truncate_title">Видалити усі</string>
|
<string name="dictionary_truncate_title">Видалити усі</string>
|
||||||
|
|
||||||
<string name="dictionary_cancel_load">Скасувати завантаження</string>
|
<string name="dictionary_cancel_load">Скасувати завантаження</string>
|
||||||
<string name="dictionary_load_error">Помилка завантаження словника для мови «%1$s» (%2$s).</string>
|
<string name="dictionary_load_error">Помилка завантаження словника для мови «%1$s» (%2$s).</string>
|
||||||
<string name="dictionary_loaded">Завантаження словника завершено.</string>
|
<string name="dictionary_loaded">Завантаження словника завершено.</string>
|
||||||
|
|
@ -69,4 +68,5 @@
|
||||||
<string name="key_volume_up">Збільшення гучності</string>
|
<string name="key_volume_up">Збільшення гучності</string>
|
||||||
<string name="key_volume_down">Зменшення гучності</string>
|
<string name="key_volume_down">Зменшення гучності</string>
|
||||||
<string name="dictionary_truncating">Видалення…</string>
|
<string name="dictionary_truncating">Видалення…</string>
|
||||||
|
<string name="error">Помилка</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,11 @@
|
||||||
<string name="app_name_short" translatable="false">TT9</string>
|
<string name="app_name_short" translatable="false">TT9</string>
|
||||||
<string name="app_settings">TT9 Settings</string>
|
<string name="app_settings">TT9 Settings</string>
|
||||||
<string name="completed">Completed</string>
|
<string name="completed">Completed</string>
|
||||||
|
<string name="error">Error</string>
|
||||||
|
<string name="no_language">No Language</string>
|
||||||
|
|
||||||
<string name="error_unexpected">Unexpected error occurred.</string>
|
<string name="error_unexpected">Unexpected error occurred.</string>
|
||||||
|
<string name="failed_loading_language_definitions">Failed loading all language definitions.</string>
|
||||||
|
|
||||||
<string name="add_word_add">Add</string>
|
<string name="add_word_add">Add</string>
|
||||||
<string name="add_word_blank">Blank word not added.</string>
|
<string name="add_word_blank">Blank word not added.</string>
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,41 @@
|
||||||
package io.github.sspanak.tt9.db.migrations;
|
package io.github.sspanak.tt9.db.migrations;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.room.migration.Migration;
|
import androidx.room.migration.Migration;
|
||||||
import androidx.sqlite.db.SupportSQLiteDatabase;
|
import androidx.sqlite.db.SupportSQLiteDatabase;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
import io.github.sspanak.tt9.Logger;
|
import io.github.sspanak.tt9.Logger;
|
||||||
import io.github.sspanak.tt9.languages.definitions.Dutch;
|
import io.github.sspanak.tt9.languages.Language;
|
||||||
import io.github.sspanak.tt9.languages.definitions.English;
|
import io.github.sspanak.tt9.languages.LanguageCollection;
|
||||||
|
|
||||||
public class DB11 {
|
public class DB11 {
|
||||||
public static final Migration MIGRATION = new Migration(10, 11) {
|
private Context ctx;
|
||||||
|
|
||||||
|
public Migration getMigration(Context context) {
|
||||||
|
ctx = context;
|
||||||
|
return MIGRATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Migration MIGRATION = new Migration(10, 11) {
|
||||||
@Override
|
@Override
|
||||||
public void migrate(@NonNull SupportSQLiteDatabase database) {
|
public void migrate(@NonNull SupportSQLiteDatabase database) {
|
||||||
final String enWords = "'I''d','I''m','d''annunzio','I''ll','I''ve','prud''hon','an''t','bo''s''n','bo''s''ns','bo''sun','bo''suns','bos''n','bos''ns','br''er','ca''canny','could''ve','d''arezzo','d''estaing','e''en','e''er','fo''c''s''le','fo''c''s''les','fo''c''sle','fo''c''sles','ha''penny','he''d','he''ll','how''d','how''re','howe''er','it''d','it''ll','might''ve','must''ve','n''importe','ne''er','nor''easter','nor''wester','o''er','rec''d','sec''y','she''d','she''ll','should''ve','sou''wester','ta''en','that''d','that''ll','they''d','they''ll','they''re','they''ve','we''d','we''ll','we''re','we''ve','whate''er','whatsoe''er','whene''er','where''er','who''d','who''ll','who''re','who''ve','why''d','would''ve','you''d','you''ll','you''re','you''ve','Ch''in','L''Amour','L''Enfant','L''Oreal','L''Ouverture','T''ang','Xi''an'";
|
final String enWords = "'I''d','I''m','d''annunzio','I''ll','I''ve','prud''hon','an''t','bo''s''n','bo''s''ns','bo''sun','bo''suns','bos''n','bos''ns','br''er','ca''canny','could''ve','d''arezzo','d''estaing','e''en','e''er','fo''c''s''le','fo''c''s''les','fo''c''sle','fo''c''sles','ha''penny','he''d','he''ll','how''d','how''re','howe''er','it''d','it''ll','might''ve','must''ve','n''importe','ne''er','nor''easter','nor''wester','o''er','rec''d','sec''y','she''d','she''ll','should''ve','sou''wester','ta''en','that''d','that''ll','they''d','they''ll','they''re','they''ve','we''d','we''ll','we''re','we''ve','whate''er','whatsoe''er','whene''er','where''er','who''d','who''ll','who''re','who''ve','why''d','would''ve','you''d','you''ll','you''re','you''ve','Ch''in','L''Amour','L''Enfant','L''Oreal','L''Ouverture','T''ang','Xi''an'";
|
||||||
final String nlWords = "'''s-Graveland','''s-Gravendeel','''s-Gravenhaags','''s-Gravenhage','''s-Gravenhagenaar','''s-Gravenmoer','''s-Gravenzande','''s-Gravenzander','''s-Gravenzands','''s-Hertogenbosch','''t','A.D.','az.','chin.','d.v.','h.k.h.','h.m.','l.b.','mgr.','n.b.','n.h.','n.n.','n.o.','n.v.','n.w.','ned.','o.l.v.','openoffice.org','r.i.p.','st.-eustatius','st.-maarten','stct.','w.','w.v.str.','z.h.','z.k.h.','a.d.h.v.','a.g.v.','a.h.w.','a.j.b.','a.m.','a.s.','a.u.b.','aanw.','afb.','afd.','afz.','an.','arr.','b.d.','b.g.g.','b.v.d.','bc.','bett.','bijl.','bijv.','blz.','bv.','bw.','c.q.','c.s.','ca.','d.d.','d.i.','d.m.v.','d.w.z.','dd.','dhr.','div.','dr.','dra.','drs.','drs.-titel','ds.','e.a.','e.d.','e.e.a.','e.o.','e.v.','e.v.a.','enz.','etc.','evt.','excl.','fa.','fam.','fig.','fr.','g.g.d.','geb.','gem.','get.','i.c.','i.c.m.','i.e.','i.h.a.','i.h.b.','i.m.','i.o.','i.o.v.','i.p.v.','i.s.m.','i.t.t.','i.v.m.','i.z.g.st.','incl.','ing.','ir.','jhr.','jkvr.','jl.','jr.','k.k.','lic.','m.','m.a.w.','m.b.t.','m.b.v.','m.i.','m.i.v.','m.m.','m.m.v.','m.n.','m.u.v.','max.','mevr.','min.','mld.','mln.','mr.','mw.','n.a.v.','n.o.t.k.','n.v.t.','nl.','nl.openoffice.org','no.','nr.','nrs.','o.a.','o.b.v.','o.i.','o.i.d.','o.m.','o.t.t.','o.v.t.','o.v.v.','ong.','p.','p.a.','p.m.','p.o.','p.p.','p.w.','pag.','plm.','plv.','prof.','q.e.d.','q.q.','r.-k.','red.','resp.','s.j.','s.v.p.','sr.','t.a.v.','t.b.v.','t.g.v.','t.h.t.','t.h.v.','t.n.v.','t.o.v.','t.w.','t.w.v.','t.z.t.','v.','v.chr.','v.d.','v.h.','v.l.n.r.','v.r.n.l.','v.t.t.','v.v.','v.v.t.','v.w.b.','verg.','vgl.','vnl.','vnw.','voorz.','vs.','w.o.','w.v.t.t.k.','ww.','z.g.','z.g.a.n.','z.i.','z.o.z.','z.s.m.','zgn.'";
|
final String nlWords = "'''s-Graveland','''s-Gravendeel','''s-Gravenhaags','''s-Gravenhage','''s-Gravenhagenaar','''s-Gravenmoer','''s-Gravenzande','''s-Gravenzander','''s-Gravenzands','''s-Hertogenbosch','''t','A.D.','az.','chin.','d.v.','h.k.h.','h.m.','l.b.','mgr.','n.b.','n.h.','n.n.','n.o.','n.v.','n.w.','ned.','o.l.v.','openoffice.org','r.i.p.','st.-eustatius','st.-maarten','stct.','w.','w.v.str.','z.h.','z.k.h.','a.d.h.v.','a.g.v.','a.h.w.','a.j.b.','a.m.','a.s.','a.u.b.','aanw.','afb.','afd.','afz.','an.','arr.','b.d.','b.g.g.','b.v.d.','bc.','bett.','bijl.','bijv.','blz.','bv.','bw.','c.q.','c.s.','ca.','d.d.','d.i.','d.m.v.','d.w.z.','dd.','dhr.','div.','dr.','dra.','drs.','drs.-titel','ds.','e.a.','e.d.','e.e.a.','e.o.','e.v.','e.v.a.','enz.','etc.','evt.','excl.','fa.','fam.','fig.','fr.','g.g.d.','geb.','gem.','get.','i.c.','i.c.m.','i.e.','i.h.a.','i.h.b.','i.m.','i.o.','i.o.v.','i.p.v.','i.s.m.','i.t.t.','i.v.m.','i.z.g.st.','incl.','ing.','ir.','jhr.','jkvr.','jl.','jr.','k.k.','lic.','m.','m.a.w.','m.b.t.','m.b.v.','m.i.','m.i.v.','m.m.','m.m.v.','m.n.','m.u.v.','max.','mevr.','min.','mld.','mln.','mr.','mw.','n.a.v.','n.o.t.k.','n.v.t.','nl.','nl.openoffice.org','no.','nr.','nrs.','o.a.','o.b.v.','o.i.','o.i.d.','o.m.','o.t.t.','o.v.t.','o.v.v.','ong.','p.','p.a.','p.m.','p.o.','p.p.','p.w.','pag.','plm.','plv.','prof.','q.e.d.','q.q.','r.-k.','red.','resp.','s.j.','s.v.p.','sr.','t.a.v.','t.b.v.','t.g.v.','t.h.t.','t.h.v.','t.n.v.','t.o.v.','t.w.','t.w.v.','t.z.t.','v.','v.chr.','v.d.','v.h.','v.l.n.r.','v.r.n.l.','v.t.t.','v.v.','v.v.t.','v.w.b.','verg.','vgl.','vnl.','vnw.','voorz.','vs.','w.o.','w.v.t.t.k.','ww.','z.g.','z.g.a.n.','z.i.','z.o.z.','z.s.m.','zgn.'";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
Language English = LanguageCollection.getByLocale(ctx, Locale.ENGLISH.toString());
|
||||||
|
Language Dutch = LanguageCollection.getByLocale(ctx, "nl_NL");
|
||||||
|
assert English != null;
|
||||||
|
assert Dutch != null;
|
||||||
|
|
||||||
database.beginTransaction();
|
database.beginTransaction();
|
||||||
database.execSQL(getDeleteEnglishSwordsQuery());
|
database.execSQL(getDeleteEnglishSwordsQuery(English));
|
||||||
database.execSQL(getDeleteWordsQuery(new English().getId(), enWords));
|
database.execSQL(getDeleteWordsQuery(English.getId(), enWords));
|
||||||
database.execSQL(getDeleteWordsQuery(new Dutch().getId(), nlWords));
|
database.execSQL(getDeleteWordsQuery(Dutch.getId(), nlWords));
|
||||||
database.setTransactionSuccessful();
|
database.setTransactionSuccessful();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Logger.e("Migrate to DB11", "Migration failed. " + e.getMessage());
|
Logger.e("Migrate to DB11", "Migration failed. " + e.getMessage());
|
||||||
|
|
@ -29,11 +45,11 @@ public class DB11 {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private static String getDeleteEnglishSwordsQuery() {
|
private String getDeleteEnglishSwordsQuery(Language English) {
|
||||||
return "DELETE FROM words WHERE lang=" + new English().getId() + " AND word LIKE '%''s'";
|
return "DELETE FROM words WHERE lang=" + English.getId() + " AND word LIKE '%''s'";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getDeleteWordsQuery(int langId, String wordList) {
|
private String getDeleteWordsQuery(int langId, String wordList) {
|
||||||
return "DELETE FROM words WHERE lang=" + langId + " AND word IN(" + wordList + ")";
|
return "DELETE FROM words WHERE lang=" + langId + " AND word IN(" + wordList + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,16 +7,10 @@ import androidx.room.migration.Migration;
|
||||||
import androidx.sqlite.db.SupportSQLiteDatabase;
|
import androidx.sqlite.db.SupportSQLiteDatabase;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
import io.github.sspanak.tt9.languages.definitions.Bulgarian;
|
import io.github.sspanak.tt9.languages.Language;
|
||||||
import io.github.sspanak.tt9.languages.definitions.Dutch;
|
import io.github.sspanak.tt9.languages.LanguageCollection;
|
||||||
import io.github.sspanak.tt9.languages.definitions.English;
|
|
||||||
import io.github.sspanak.tt9.languages.definitions.French;
|
|
||||||
import io.github.sspanak.tt9.languages.definitions.German;
|
|
||||||
import io.github.sspanak.tt9.languages.definitions.Italian;
|
|
||||||
import io.github.sspanak.tt9.languages.definitions.Russian;
|
|
||||||
import io.github.sspanak.tt9.languages.definitions.Spanish;
|
|
||||||
import io.github.sspanak.tt9.languages.definitions.Ukrainian;
|
|
||||||
import io.github.sspanak.tt9.preferences.SettingsStore;
|
import io.github.sspanak.tt9.preferences.SettingsStore;
|
||||||
|
|
||||||
public class DB7 {
|
public class DB7 {
|
||||||
|
|
@ -28,28 +22,41 @@ public class DB7 {
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getNewLanguageId(int oldId) {
|
private int getNewLanguageId(int oldId) {
|
||||||
|
Language language;
|
||||||
|
|
||||||
switch (oldId) {
|
switch (oldId) {
|
||||||
default:
|
default:
|
||||||
return oldId;
|
return oldId;
|
||||||
case 1:
|
case 1:
|
||||||
return new English().getId();
|
language = LanguageCollection.getByLocale(ctx, Locale.ENGLISH.toString());
|
||||||
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
return new Russian().getId();
|
language = LanguageCollection.getByLocale(ctx, "ru_RU");
|
||||||
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
return new German().getId();
|
language = LanguageCollection.getByLocale(ctx, Locale.GERMAN.toString());
|
||||||
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
return new French().getId();
|
language = LanguageCollection.getByLocale(ctx, Locale.FRENCH.toString());
|
||||||
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
return new Italian().getId();
|
language = LanguageCollection.getByLocale(ctx, Locale.ITALIAN.toString());
|
||||||
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
return new Ukrainian().getId();
|
language = LanguageCollection.getByLocale(ctx, "uk_UA");
|
||||||
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
return new Bulgarian().getId();
|
language = LanguageCollection.getByLocale(ctx, "bg_BG");
|
||||||
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
return new Dutch().getId();
|
language = LanguageCollection.getByLocale(ctx, "nl_NL");
|
||||||
|
break;
|
||||||
case 9:
|
case 9:
|
||||||
return new Spanish().getId();
|
language = LanguageCollection.getByLocale(ctx, "es_ES");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return language != null ? language.getId() : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Migration migration = new Migration(6, 7) {
|
private final Migration migration = new Migration(6, 7) {
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ public abstract class TT9Room extends RoomDatabase {
|
||||||
DB8.MIGRATION,
|
DB8.MIGRATION,
|
||||||
DB9.MIGRATION,
|
DB9.MIGRATION,
|
||||||
DB10.MIGRATION,
|
DB10.MIGRATION,
|
||||||
DB11.MIGRATION
|
new DB11().getMigration(context)
|
||||||
)
|
)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ public class EmptyDatabaseWarning {
|
||||||
public EmptyDatabaseWarning(SettingsStore settings) {
|
public EmptyDatabaseWarning(SettingsStore settings) {
|
||||||
WARNING_INTERVAL = settings.getDictionaryMissingWarningInterval();
|
WARNING_INTERVAL = settings.getDictionaryMissingWarningInterval();
|
||||||
|
|
||||||
for (Language lang : LanguageCollection.getAll()) {
|
for (Language lang : LanguageCollection.getAll(context)) {
|
||||||
if (!warningDisplayedTime.containsKey(lang.getId())) {
|
if (!warningDisplayedTime.containsKey(lang.getId())) {
|
||||||
warningDisplayedTime.put(lang.getId(), 0L);
|
warningDisplayedTime.put(lang.getId(), 0L);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ public class TraditionalT9 extends KeyPadHandler {
|
||||||
|
|
||||||
|
|
||||||
private void loadSettings() {
|
private void loadSettings() {
|
||||||
mLanguage = LanguageCollection.getLanguage(settings.getInputLanguage());
|
mLanguage = LanguageCollection.getLanguage(getMainContext(), settings.getInputLanguage());
|
||||||
mEnabledLanguages = settings.getEnabledLanguageIds();
|
mEnabledLanguages = settings.getEnabledLanguageIds();
|
||||||
validateLanguages();
|
validateLanguages();
|
||||||
|
|
||||||
|
|
@ -79,8 +79,8 @@ public class TraditionalT9 extends KeyPadHandler {
|
||||||
|
|
||||||
|
|
||||||
private void validateLanguages() {
|
private void validateLanguages() {
|
||||||
mEnabledLanguages = InputModeValidator.validateEnabledLanguages(mEnabledLanguages);
|
mEnabledLanguages = InputModeValidator.validateEnabledLanguages(getMainContext(), mEnabledLanguages);
|
||||||
mLanguage = InputModeValidator.validateLanguage(mLanguage, mEnabledLanguages);
|
mLanguage = InputModeValidator.validateLanguage(getMainContext(), mLanguage, mEnabledLanguages);
|
||||||
|
|
||||||
settings.saveEnabledLanguageIds(mEnabledLanguages);
|
settings.saveEnabledLanguageIds(mEnabledLanguages);
|
||||||
settings.saveInputLanguage(mLanguage.getId());
|
settings.saveInputLanguage(mLanguage.getId());
|
||||||
|
|
@ -689,7 +689,7 @@ public class TraditionalT9 extends KeyPadHandler {
|
||||||
// select the next language
|
// select the next language
|
||||||
int previous = mEnabledLanguages.indexOf(mLanguage.getId());
|
int previous = mEnabledLanguages.indexOf(mLanguage.getId());
|
||||||
int next = (previous + 1) % mEnabledLanguages.size();
|
int next = (previous + 1) % mEnabledLanguages.size();
|
||||||
mLanguage = LanguageCollection.getLanguage(mEnabledLanguages.get(next));
|
mLanguage = LanguageCollection.getLanguage(getMainContext(), mEnabledLanguages.get(next));
|
||||||
|
|
||||||
validateLanguages();
|
validateLanguages();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package io.github.sspanak.tt9.ime.helpers;
|
package io.github.sspanak.tt9.ime.helpers;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import io.github.sspanak.tt9.Logger;
|
import io.github.sspanak.tt9.Logger;
|
||||||
|
|
@ -8,29 +10,29 @@ import io.github.sspanak.tt9.languages.Language;
|
||||||
import io.github.sspanak.tt9.languages.LanguageCollection;
|
import io.github.sspanak.tt9.languages.LanguageCollection;
|
||||||
|
|
||||||
public class InputModeValidator {
|
public class InputModeValidator {
|
||||||
public static ArrayList<Integer> validateEnabledLanguages(ArrayList<Integer> enabledLanguageIds) {
|
public static ArrayList<Integer> validateEnabledLanguages(Context context, ArrayList<Integer> enabledLanguageIds) {
|
||||||
ArrayList<Language> validLanguages = LanguageCollection.getAll(enabledLanguageIds);
|
ArrayList<Language> validLanguages = LanguageCollection.getAll(context, enabledLanguageIds);
|
||||||
ArrayList<Integer> validLanguageIds = new ArrayList<>();
|
ArrayList<Integer> validLanguageIds = new ArrayList<>();
|
||||||
for (Language lang : validLanguages) {
|
for (Language lang : validLanguages) {
|
||||||
validLanguageIds.add(lang.getId());
|
validLanguageIds.add(lang.getId());
|
||||||
}
|
}
|
||||||
if (validLanguageIds.size() == 0) {
|
if (validLanguageIds.size() == 0) {
|
||||||
validLanguageIds.add(LanguageCollection.getDefault().getId());
|
validLanguageIds.add(LanguageCollection.getDefault(context).getId());
|
||||||
Logger.e("tt9/validateEnabledLanguages", "The language list seems to be corrupted. Resetting to first language only.");
|
Logger.e("tt9/validateEnabledLanguages", "The language list seems to be corrupted. Resetting to first language only.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return validLanguageIds;
|
return validLanguageIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Language validateLanguage(Language language, ArrayList<Integer> validLanguageIds) {
|
public static Language validateLanguage(Context context, Language language, ArrayList<Integer> validLanguageIds) {
|
||||||
if (language != null && validLanguageIds.contains(language.getId())) {
|
if (language != null && validLanguageIds.contains(language.getId())) {
|
||||||
return language;
|
return language;
|
||||||
}
|
}
|
||||||
|
|
||||||
String error = language != null ? "Language: " + language.getId() + " is not enabled." : "Invalid language.";
|
String error = language != null ? "Language: " + language.getId() + " is not enabled." : "Invalid language.";
|
||||||
|
|
||||||
Language validLanguage = LanguageCollection.getLanguage(validLanguageIds.get(0));
|
Language validLanguage = LanguageCollection.getLanguage(context, validLanguageIds.get(0));
|
||||||
validLanguage = validLanguage != null ? validLanguage : LanguageCollection.getDefault();
|
validLanguage = validLanguage != null ? validLanguage : LanguageCollection.getDefault(context);
|
||||||
|
|
||||||
Logger.w("tt9/validateLanguage", error + " Enforcing language: " + validLanguage.getId());
|
Logger.w("tt9/validateLanguage", error + " Enforcing language: " + validLanguage.getId());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,8 @@ public class ModeABC extends InputMode {
|
||||||
}
|
}
|
||||||
|
|
||||||
String langCode = language.getLocale().getCountry();
|
String langCode = language.getLocale().getCountry();
|
||||||
langCode = langCode.length() == 0 ? language.getLocale().getLanguage() : langCode;
|
langCode = langCode.isEmpty() ? language.getLocale().getLanguage() : langCode;
|
||||||
|
langCode = langCode.isEmpty() ? language.getName() : langCode;
|
||||||
|
|
||||||
String modeString = language.getAbcString() + " / " + langCode.toUpperCase();
|
String modeString = language.getAbcString() + " / " + langCode.toUpperCase();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,82 @@ public class Language {
|
||||||
protected Locale locale;
|
protected Locale locale;
|
||||||
protected String dictionaryFile;
|
protected String dictionaryFile;
|
||||||
protected String abcString;
|
protected String abcString;
|
||||||
protected ArrayList<ArrayList<String>> characterMap = new ArrayList<>();
|
protected final ArrayList<ArrayList<String>> layout = new ArrayList<>();
|
||||||
private final HashMap<Character, String> reverseCharacterMap = new HashMap<>();
|
private final HashMap<Character, String> characterKeyMap = new HashMap<>();
|
||||||
|
|
||||||
// settings
|
// settings
|
||||||
protected boolean hasUpperCase = true;
|
protected boolean hasUpperCase = true;
|
||||||
|
|
||||||
|
|
||||||
|
public static Language fromDefinition(LanguageDefinition definition) throws Exception {
|
||||||
|
if (definition.dictionaryFile.isEmpty()) {
|
||||||
|
throw new Exception("Invalid definition. Dictionary file must be set.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (definition.locale.isEmpty()) {
|
||||||
|
throw new Exception("Invalid definition. Locale cannot be empty.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Locale definitionLocale;
|
||||||
|
switch (definition.locale) {
|
||||||
|
case "de":
|
||||||
|
definitionLocale = Locale.GERMAN;
|
||||||
|
break;
|
||||||
|
case "en":
|
||||||
|
definitionLocale = Locale.ENGLISH;
|
||||||
|
break;
|
||||||
|
case "fr":
|
||||||
|
definitionLocale = Locale.FRENCH;
|
||||||
|
break;
|
||||||
|
case "it":
|
||||||
|
definitionLocale = Locale.ITALIAN;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
String[] parts = definition.locale.split("-", 2);
|
||||||
|
if (parts.length == 2) {
|
||||||
|
definitionLocale = new Locale(parts[0], parts[1]);
|
||||||
|
} else if (parts.length == 1) {
|
||||||
|
definitionLocale = new Locale(parts[0]);
|
||||||
|
} else {
|
||||||
|
throw new Exception("Unrecognized locale format: '" + definition.locale + "'.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Language lang = new Language();
|
||||||
|
lang.abcString = definition.abcString.isEmpty() ? lang.abcString : definition.abcString;
|
||||||
|
lang.dictionaryFile = definition.getDictionaryFile();
|
||||||
|
lang.hasUpperCase = definition.hasUpperCase;
|
||||||
|
lang.locale = definitionLocale;
|
||||||
|
lang.name = definition.name.isEmpty() ? lang.name : definition.name;
|
||||||
|
|
||||||
|
for (int key = 0; key <= 9 || key < definition.layout.size(); key++) {
|
||||||
|
lang.layout.add(keyCharsFromDefinition(key, definition.layout.get(key)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return lang;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static ArrayList<String> keyCharsFromDefinition(int key, ArrayList<String> definitionChars) {
|
||||||
|
final String defaultCharsPlaceholder = "DEFAULT";
|
||||||
|
|
||||||
|
if (key > 1 || !definitionChars.contains(defaultCharsPlaceholder)) {
|
||||||
|
return definitionChars;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList<String> keyChars = new ArrayList<>();
|
||||||
|
for (String defChar : definitionChars) {
|
||||||
|
if (defChar.equals(defaultCharsPlaceholder)) {
|
||||||
|
keyChars.addAll(key == 0 ? Characters.Special : Characters.Sentence);
|
||||||
|
} else {
|
||||||
|
keyChars.add(defChar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return keyChars;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
final public int getId() {
|
final public int getId() {
|
||||||
if (id == 0) {
|
if (id == 0) {
|
||||||
id = generateId();
|
id = generateId();
|
||||||
|
|
@ -95,11 +165,11 @@ public class Language {
|
||||||
return idInt;
|
return idInt;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateReverseCharacterMap() {
|
private void generateCharacterKeyMap() {
|
||||||
reverseCharacterMap.clear();
|
characterKeyMap.clear();
|
||||||
for (int digit = 0; digit <= 9; digit++) {
|
for (int digit = 0; digit <= 9; digit++) {
|
||||||
for (String keyChar : getKeyCharacters(digit)) {
|
for (String keyChar : getKeyCharacters(digit)) {
|
||||||
reverseCharacterMap.put(keyChar.charAt(0), String.valueOf(digit));
|
characterKeyMap.put(keyChar.charAt(0), String.valueOf(digit));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -131,11 +201,11 @@ public class Language {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<String> getKeyCharacters(int key, boolean includeDigit) {
|
public ArrayList<String> getKeyCharacters(int key, boolean includeDigit) {
|
||||||
if (key < 0 || key >= characterMap.size()) {
|
if (key < 0 || key >= layout.size()) {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayList<String> chars = new ArrayList<>(characterMap.get(key));
|
ArrayList<String> chars = new ArrayList<>(layout.get(key));
|
||||||
if (includeDigit && chars.size() > 0) {
|
if (includeDigit && chars.size() > 0) {
|
||||||
chars.add(String.valueOf(key));
|
chars.add(String.valueOf(key));
|
||||||
}
|
}
|
||||||
|
|
@ -151,17 +221,17 @@ public class Language {
|
||||||
StringBuilder sequence = new StringBuilder();
|
StringBuilder sequence = new StringBuilder();
|
||||||
String lowerCaseWord = word.toLowerCase(locale);
|
String lowerCaseWord = word.toLowerCase(locale);
|
||||||
|
|
||||||
if (reverseCharacterMap.isEmpty()) {
|
if (characterKeyMap.isEmpty()) {
|
||||||
generateReverseCharacterMap();
|
generateCharacterKeyMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < lowerCaseWord.length(); i++) {
|
for (int i = 0; i < lowerCaseWord.length(); i++) {
|
||||||
char letter = lowerCaseWord.charAt(i);
|
char letter = lowerCaseWord.charAt(i);
|
||||||
if (!reverseCharacterMap.containsKey(letter)) {
|
if (!characterKeyMap.containsKey(letter)) {
|
||||||
throw new InvalidLanguageCharactersException(this, "Failed generating digit sequence for word: '" + word);
|
throw new InvalidLanguageCharactersException(this, "Failed generating digit sequence for word: '" + word);
|
||||||
}
|
}
|
||||||
|
|
||||||
sequence.append(reverseCharacterMap.get(letter));
|
sequence.append(characterKeyMap.get(letter));
|
||||||
}
|
}
|
||||||
|
|
||||||
return sequence.toString();
|
return sequence.toString();
|
||||||
|
|
|
||||||
|
|
@ -1,84 +1,70 @@
|
||||||
package io.github.sspanak.tt9.languages;
|
package io.github.sspanak.tt9.languages;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import io.github.sspanak.tt9.Logger;
|
import io.github.sspanak.tt9.Logger;
|
||||||
import io.github.sspanak.tt9.languages.definitions.*;
|
|
||||||
|
|
||||||
public class LanguageCollection {
|
public class LanguageCollection {
|
||||||
private static LanguageCollection self;
|
private static LanguageCollection self;
|
||||||
|
|
||||||
private final Language defaultLanguage = new English();
|
|
||||||
private final HashMap<Integer, Language> languages = new HashMap<>();
|
private final HashMap<Integer, Language> languages = new HashMap<>();
|
||||||
|
|
||||||
private LanguageCollection() {
|
private LanguageCollection(Context context) {
|
||||||
List<Class<? extends Language>> languageList = Arrays.asList(
|
for (String file : LanguageDefinition.getAllFiles(context.getAssets())) {
|
||||||
// Add languages here, to enable them in the UI and
|
|
||||||
// please, maintain the alphabetical order.
|
|
||||||
BrazilianPortuguese.class,
|
|
||||||
Bulgarian.class,
|
|
||||||
Dutch.class,
|
|
||||||
English.class,
|
|
||||||
Finnish.class,
|
|
||||||
French.class,
|
|
||||||
German.class,
|
|
||||||
Hebrew.class,
|
|
||||||
Indonesian.class,
|
|
||||||
Italian.class,
|
|
||||||
Norwegian.class,
|
|
||||||
Polish.class,
|
|
||||||
Russian.class,
|
|
||||||
Spanish.class,
|
|
||||||
Swedish.class,
|
|
||||||
Ukrainian.class,
|
|
||||||
Yiddish.class
|
|
||||||
);
|
|
||||||
|
|
||||||
// initialize the language objects from the class list above
|
|
||||||
for (Class<? extends Language> languageClass : languageList) {
|
|
||||||
try {
|
try {
|
||||||
Language lang = languageClass.newInstance();
|
Language lang = Language.fromDefinition(LanguageDefinition.fromFile(context.getAssets(), file));
|
||||||
if (languages.containsKey(lang.getId())) {
|
|
||||||
throw new Exception("Duplicate language ID: " + lang.getId() + " for language: " + lang.getName());
|
|
||||||
}
|
|
||||||
languages.put(lang.getId(), lang);
|
languages.put(lang.getId(), lang);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Logger.e("tt9.LanguageCollection", "Skipping an invalid language. " + e.getMessage());
|
Logger.e("tt9.LanguageCollection", "Skipping invalid language: '" + file + "'. " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LanguageCollection getInstance() {
|
|
||||||
|
public static LanguageCollection getInstance(Context context) {
|
||||||
if (self == null) {
|
if (self == null) {
|
||||||
self = new LanguageCollection();
|
self = new LanguageCollection(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Language getLanguage(int langId) {
|
public static Language getLanguage(Context context, int langId) {
|
||||||
if (getInstance().languages.containsKey(langId)) {
|
if (getInstance(context).languages.containsKey(langId)) {
|
||||||
return getInstance().languages.get(langId);
|
return getInstance(context).languages.get(langId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Language getDefault() {
|
public static Language getDefault(Context context) {
|
||||||
return getInstance().defaultLanguage;
|
Language language = getByLocale(context, "en");
|
||||||
|
return language == null ? new NullLanguage(context) : language;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ArrayList<Language> getAll(ArrayList<Integer> languageIds, boolean sort) {
|
@Nullable
|
||||||
|
public static Language getByLocale(Context context, String locale) {
|
||||||
|
for (Language lang : getInstance(context).languages.values()) {
|
||||||
|
if (lang.getLocale().toString().equals(locale)) {
|
||||||
|
return lang;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ArrayList<Language> getAll(Context context, ArrayList<Integer> languageIds, boolean sort) {
|
||||||
ArrayList<Language> langList = new ArrayList<>();
|
ArrayList<Language> langList = new ArrayList<>();
|
||||||
|
|
||||||
for (int languageId : languageIds) {
|
for (int languageId : languageIds) {
|
||||||
Language lang = getLanguage(languageId);
|
Language lang = getLanguage(context, languageId);
|
||||||
if (lang != null) {
|
if (lang != null) {
|
||||||
langList.add(lang);
|
langList.add(lang);
|
||||||
}
|
}
|
||||||
|
|
@ -91,12 +77,12 @@ public class LanguageCollection {
|
||||||
return langList;
|
return langList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ArrayList<Language> getAll(ArrayList<Integer> languageIds) {
|
public static ArrayList<Language> getAll(Context context, ArrayList<Integer> languageIds) {
|
||||||
return getAll(languageIds, false);
|
return getAll(context, languageIds, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ArrayList<Language> getAll(boolean sort) {
|
public static ArrayList<Language> getAll(Context context, boolean sort) {
|
||||||
ArrayList<Language> langList = new ArrayList<>(getInstance().languages.values());
|
ArrayList<Language> langList = new ArrayList<>(getInstance(context).languages.values());
|
||||||
|
|
||||||
if (sort && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
if (sort && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
langList.sort(Comparator.comparing(l -> l.getLocale().toString()));
|
langList.sort(Comparator.comparing(l -> l.getLocale().toString()));
|
||||||
|
|
@ -105,8 +91,8 @@ public class LanguageCollection {
|
||||||
return langList;
|
return langList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ArrayList<Language> getAll() {
|
public static ArrayList<Language> getAll(Context context) {
|
||||||
return getAll(false);
|
return getAll(context,false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
47
src/io/github/sspanak/tt9/languages/LanguageDefinition.java
Normal file
47
src/io/github/sspanak/tt9/languages/LanguageDefinition.java
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
package io.github.sspanak.tt9.languages;
|
||||||
|
|
||||||
|
import android.content.res.AssetManager;
|
||||||
|
|
||||||
|
import org.yaml.snakeyaml.Yaml;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import io.github.sspanak.tt9.Logger;
|
||||||
|
|
||||||
|
public class LanguageDefinition {
|
||||||
|
private static final String languagesDir = "languages";
|
||||||
|
private static final String definitionsDir = languagesDir + "/definitions";
|
||||||
|
|
||||||
|
public String abcString = "";
|
||||||
|
public String dictionaryFile = "";
|
||||||
|
public boolean hasUpperCase = true;
|
||||||
|
public ArrayList<ArrayList<String>> layout = new ArrayList<>();
|
||||||
|
public String locale = "";
|
||||||
|
public String name = "";
|
||||||
|
|
||||||
|
public static ArrayList<String> getAllFiles(AssetManager assets) {
|
||||||
|
ArrayList<String> files = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
for (String file : assets.list(definitionsDir)) {
|
||||||
|
files.add(definitionsDir + "/" + file);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
Logger.e("tt9.LanguageDefinition", "Failed reading language definitions from: '" + definitionsDir + "'. " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LanguageDefinition fromFile(AssetManager assets, String definitionFile) throws IOException {
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(assets.open(definitionFile), StandardCharsets.UTF_8));
|
||||||
|
return new Yaml().loadAs(reader, LanguageDefinition.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDictionaryFile() {
|
||||||
|
return languagesDir + "/dictionaries/" + dictionaryFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
15
src/io/github/sspanak/tt9/languages/NullLanguage.java
Normal file
15
src/io/github/sspanak/tt9/languages/NullLanguage.java
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
package io.github.sspanak.tt9.languages;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import io.github.sspanak.tt9.R;
|
||||||
|
|
||||||
|
public class NullLanguage extends Language {
|
||||||
|
public NullLanguage(Context context) {
|
||||||
|
locale = Locale.ROOT;
|
||||||
|
name = context.getString(R.string.no_language);
|
||||||
|
abcString = "abc";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
package io.github.sspanak.tt9.languages.definitions;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
public class BrazilianPortuguese extends English {
|
|
||||||
public BrazilianPortuguese() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
name = "Português brasileiro";
|
|
||||||
locale = new Locale("pt","BR");
|
|
||||||
dictionaryFile = "pt-BR-utf8.csv";
|
|
||||||
|
|
||||||
characterMap.get(2).addAll(Arrays.asList("ç", "á", "â", "ã", "à"));
|
|
||||||
characterMap.get(3).addAll(Arrays.asList("é", "ê", "è"));
|
|
||||||
characterMap.get(4).add("í");
|
|
||||||
characterMap.get(6).addAll(Arrays.asList("ó", "ô", "õ"));
|
|
||||||
characterMap.get(8).add("ú");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
package io.github.sspanak.tt9.languages.definitions;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import io.github.sspanak.tt9.languages.Language;
|
|
||||||
import io.github.sspanak.tt9.languages.Characters;
|
|
||||||
|
|
||||||
public class Bulgarian extends Language {
|
|
||||||
public Bulgarian() {
|
|
||||||
locale = new Locale("bg","BG");
|
|
||||||
dictionaryFile = "bg-utf8.csv";
|
|
||||||
|
|
||||||
characterMap = new ArrayList<>(Arrays.asList(
|
|
||||||
Characters.Special, // 0
|
|
||||||
Characters.Sentence, // 1
|
|
||||||
new ArrayList<>(Arrays.asList("а", "б", "в", "г")), // 2
|
|
||||||
new ArrayList<>(Arrays.asList("д", "е", "ж", "з")), // 3
|
|
||||||
new ArrayList<>(Arrays.asList("и", "й", "к", "л", "ѝ")), // 4
|
|
||||||
new ArrayList<>(Arrays.asList("м", "н", "о", "п")), // 5
|
|
||||||
new ArrayList<>(Arrays.asList("р", "с", "т", "у")), // 6
|
|
||||||
new ArrayList<>(Arrays.asList("ф", "х", "ц", "ч")), // 7
|
|
||||||
new ArrayList<>(Arrays.asList("ш", "щ", "ъ")), // 8
|
|
||||||
new ArrayList<>(Arrays.asList("ь", "ю", "я")) // 9
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
package io.github.sspanak.tt9.languages.definitions;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
public class Dutch extends English {
|
|
||||||
public Dutch() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
locale = new Locale("nl","NL");
|
|
||||||
dictionaryFile = "nl-utf8.csv";
|
|
||||||
|
|
||||||
characterMap.get(2).addAll(Arrays.asList("à", "ä", "ç"));
|
|
||||||
characterMap.get(3).addAll(Arrays.asList("é", "è", "ê", "ë"));
|
|
||||||
characterMap.get(4).addAll(Arrays.asList("î", "ï"));
|
|
||||||
characterMap.get(6).add("ö");
|
|
||||||
characterMap.get(8).addAll(Arrays.asList("û", "ü"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
package io.github.sspanak.tt9.languages.definitions;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import io.github.sspanak.tt9.languages.Characters;
|
|
||||||
import io.github.sspanak.tt9.languages.Language;
|
|
||||||
|
|
||||||
public class English extends Language {
|
|
||||||
public English() {
|
|
||||||
locale = Locale.ENGLISH;
|
|
||||||
dictionaryFile = "en-utf8.csv";
|
|
||||||
|
|
||||||
characterMap = new ArrayList<>(Arrays.asList(
|
|
||||||
Characters.Special, // 0
|
|
||||||
Characters.Sentence, // 1
|
|
||||||
new ArrayList<>(Arrays.asList("a", "b", "c")), // 2
|
|
||||||
new ArrayList<>(Arrays.asList("d", "e", "f")), // 3
|
|
||||||
new ArrayList<>(Arrays.asList("g", "h", "i")), // 4
|
|
||||||
new ArrayList<>(Arrays.asList("j", "k", "l")), // 5
|
|
||||||
new ArrayList<>(Arrays.asList("m", "n", "o")), // 6
|
|
||||||
new ArrayList<>(Arrays.asList("p", "q", "r", "s")), // 7
|
|
||||||
new ArrayList<>(Arrays.asList("t", "u", "v")), // 8
|
|
||||||
new ArrayList<>(Arrays.asList("w", "x", "y", "z")) // 9
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
package io.github.sspanak.tt9.languages.definitions;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
public class Finnish extends English {
|
|
||||||
public Finnish() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
locale = new Locale("fi","FI");
|
|
||||||
dictionaryFile = "fi-utf8.csv";
|
|
||||||
|
|
||||||
characterMap.get(2).addAll(Arrays.asList("ä", "å"));
|
|
||||||
characterMap.get(6).add("ö");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
package io.github.sspanak.tt9.languages.definitions;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
public class French extends English {
|
|
||||||
public French() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
locale = Locale.FRENCH;
|
|
||||||
dictionaryFile = "fr-utf8.csv";
|
|
||||||
|
|
||||||
characterMap.get(2).addAll(Arrays.asList("à", "â", "æ", "ç"));
|
|
||||||
characterMap.get(3).addAll(Arrays.asList("é", "è", "ê", "ë"));
|
|
||||||
characterMap.get(4).addAll(Arrays.asList("î", "ï"));
|
|
||||||
characterMap.get(6).addAll(Arrays.asList("ô", "œ"));
|
|
||||||
characterMap.get(8).addAll(Arrays.asList("ù", "û", "ü"));
|
|
||||||
characterMap.get(9).add("ÿ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
package io.github.sspanak.tt9.languages.definitions;
|
|
||||||
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
public class German extends English {
|
|
||||||
public German() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
locale = Locale.GERMAN;
|
|
||||||
dictionaryFile = "de-utf8.csv";
|
|
||||||
|
|
||||||
characterMap.get(2).add("ä");
|
|
||||||
characterMap.get(6).add("ö");
|
|
||||||
characterMap.get(7).add("ß");
|
|
||||||
characterMap.get(8).add("ü");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
package io.github.sspanak.tt9.languages.definitions;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import io.github.sspanak.tt9.languages.Characters;
|
|
||||||
import io.github.sspanak.tt9.languages.Language;
|
|
||||||
|
|
||||||
public class Hebrew extends Language {
|
|
||||||
public Hebrew() {
|
|
||||||
locale = new Locale("iw","IL");
|
|
||||||
dictionaryFile = "he-utf8.csv";
|
|
||||||
abcString = "אבג";
|
|
||||||
|
|
||||||
hasUpperCase = false;
|
|
||||||
|
|
||||||
characterMap = new ArrayList<>(Arrays.asList(
|
|
||||||
Characters.Special, // 0
|
|
||||||
Characters.Sentence, // 1
|
|
||||||
new ArrayList<>(Arrays.asList("ד", "ה", "ו")), // 2
|
|
||||||
new ArrayList<>(Arrays.asList("א", "ב", "ג")), // 3
|
|
||||||
new ArrayList<>(Arrays.asList("מ", "ם", "נ", "ן")), // 4
|
|
||||||
new ArrayList<>(Arrays.asList("י", "כ", "ך", "ל")), // 5
|
|
||||||
new ArrayList<>(Arrays.asList("ז", "ח", "ט")), // 6
|
|
||||||
new ArrayList<>(Arrays.asList("ר", "ש", "ת")), // 7
|
|
||||||
new ArrayList<>(Arrays.asList("צ", "ץ", "ק")), // 8
|
|
||||||
new ArrayList<>(Arrays.asList("ס", "ע", "פ", "ף")) // 9
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
package io.github.sspanak.tt9.languages.definitions;
|
|
||||||
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
public class Indonesian extends English {
|
|
||||||
public Indonesian() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
name = "Bahasa Indonesia";
|
|
||||||
locale = new Locale("in", "ID");
|
|
||||||
dictionaryFile = "id-utf8.csv";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
package io.github.sspanak.tt9.languages.definitions;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
public class Italian extends English {
|
|
||||||
public Italian() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
locale = Locale.ITALIAN;
|
|
||||||
dictionaryFile = "it-utf8.csv";
|
|
||||||
|
|
||||||
characterMap.get(2).add("à");
|
|
||||||
characterMap.get(3).addAll(Arrays.asList("é", "è"));
|
|
||||||
characterMap.get(4).addAll(Arrays.asList("ì", "í", "î"));
|
|
||||||
characterMap.get(6).addAll(Arrays.asList("ò", "ó"));
|
|
||||||
characterMap.get(8).addAll(Arrays.asList("ù", "ú"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
package io.github.sspanak.tt9.languages.definitions;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
public class Norwegian extends English {
|
|
||||||
public Norwegian() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
locale = new Locale("nb","NO");
|
|
||||||
dictionaryFile = "nb-utf8.csv";
|
|
||||||
|
|
||||||
characterMap.get(2).addAll(Arrays.asList("æ", "å"));
|
|
||||||
characterMap.get(3).addAll(Arrays.asList("é", "è"));
|
|
||||||
characterMap.get(6).addAll(Arrays.asList("ø", "ó", "ò", "ô"));
|
|
||||||
characterMap.get(8).add("ü");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
package io.github.sspanak.tt9.languages.definitions;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
public class Polish extends English {
|
|
||||||
public Polish() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
locale = new Locale("pl","PL");
|
|
||||||
dictionaryFile = "pl-utf8.csv";
|
|
||||||
|
|
||||||
characterMap.get(2).addAll(Arrays.asList("ą", "ć"));
|
|
||||||
characterMap.get(3).add("ę");
|
|
||||||
characterMap.get(5).add("ł");
|
|
||||||
characterMap.get(6).addAll(Arrays.asList("ó", "ń"));
|
|
||||||
characterMap.get(7).add("ś");
|
|
||||||
characterMap.get(9).addAll(Arrays.asList("ź", "ż"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
package io.github.sspanak.tt9.languages.definitions;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import io.github.sspanak.tt9.languages.Characters;
|
|
||||||
import io.github.sspanak.tt9.languages.Language;
|
|
||||||
|
|
||||||
public class Russian extends Language {
|
|
||||||
public Russian() {
|
|
||||||
locale = new Locale("ru","RU");
|
|
||||||
dictionaryFile = "ru-utf8.csv";
|
|
||||||
|
|
||||||
characterMap = new ArrayList<>(Arrays.asList(
|
|
||||||
Characters.Special, // 0
|
|
||||||
Characters.Sentence, // 1
|
|
||||||
new ArrayList<>(Arrays.asList("а", "б", "в", "г")), // 2
|
|
||||||
new ArrayList<>(Arrays.asList("д", "е", "ё", "ж", "з")), // 3
|
|
||||||
new ArrayList<>(Arrays.asList("и", "й", "к", "л")), // 4
|
|
||||||
new ArrayList<>(Arrays.asList("м", "н", "о", "п")), // 5
|
|
||||||
new ArrayList<>(Arrays.asList("р", "с", "т", "у")), // 6
|
|
||||||
new ArrayList<>(Arrays.asList("ф", "х", "ц", "ч")), // 7
|
|
||||||
new ArrayList<>(Arrays.asList("ш", "щ", "ъ", "ы")), // 8
|
|
||||||
new ArrayList<>(Arrays.asList("ь", "э", "ю", "я")) // 9
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
package io.github.sspanak.tt9.languages.definitions;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import io.github.sspanak.tt9.languages.Characters;
|
|
||||||
|
|
||||||
public class Spanish extends English {
|
|
||||||
public Spanish() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
locale = new Locale("es", "ES");
|
|
||||||
dictionaryFile = "es-utf8.csv";
|
|
||||||
|
|
||||||
characterMap.set(1, new ArrayList<>(Characters.Sentence));
|
|
||||||
characterMap.get(1).addAll(Arrays.asList("¡", "¿"));
|
|
||||||
|
|
||||||
characterMap.get(2).add("á");
|
|
||||||
characterMap.get(3).add("é");
|
|
||||||
characterMap.get(4).add("í");
|
|
||||||
characterMap.set(6, new ArrayList<>(Arrays.asList("m", "n", "ñ", "o", "ó")));
|
|
||||||
characterMap.get(8).addAll(Arrays.asList("ú", "ü"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
package io.github.sspanak.tt9.languages.definitions;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
public class Swedish extends English {
|
|
||||||
public Swedish() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
locale = new Locale("sv","SE");
|
|
||||||
dictionaryFile = "sv-utf8.csv";
|
|
||||||
|
|
||||||
characterMap.get(2).addAll(Arrays.asList("å", "ä"));
|
|
||||||
characterMap.get(3).add("é");
|
|
||||||
characterMap.get(6).add("ö");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
package io.github.sspanak.tt9.languages.definitions;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import io.github.sspanak.tt9.languages.Characters;
|
|
||||||
import io.github.sspanak.tt9.languages.Language;
|
|
||||||
|
|
||||||
public class Ukrainian extends Language {
|
|
||||||
public Ukrainian() {
|
|
||||||
locale = new Locale("uk","UA");
|
|
||||||
dictionaryFile = "uk-utf8.csv";
|
|
||||||
|
|
||||||
characterMap = new ArrayList<>(Arrays.asList(
|
|
||||||
Characters.Special, // 0
|
|
||||||
Characters.Sentence, // 1
|
|
||||||
new ArrayList<>(Arrays.asList("а", "б", "в", "г", "ґ")), // 2
|
|
||||||
new ArrayList<>(Arrays.asList("д", "е", "є", "ж", "з")), // 3
|
|
||||||
new ArrayList<>(Arrays.asList("и", "і", "ї", "й", "к", "л")), // 4
|
|
||||||
new ArrayList<>(Arrays.asList("м", "н", "о", "п")), // 5
|
|
||||||
new ArrayList<>(Arrays.asList("р", "с", "т", "у")), // 6
|
|
||||||
new ArrayList<>(Arrays.asList("ф", "х", "ц", "ч")), // 7
|
|
||||||
new ArrayList<>(Arrays.asList("ш", "щ")), // 8
|
|
||||||
new ArrayList<>(Arrays.asList("ь", "ю", "я")) // 9
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
package io.github.sspanak.tt9.languages.definitions;
|
|
||||||
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
public class Yiddish extends Hebrew {
|
|
||||||
public Yiddish() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
locale = new Locale("ji","JI");
|
|
||||||
dictionaryFile = "ji-utf8.csv";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -41,7 +41,7 @@ public class PreferencesActivity extends AppCompatActivity implements Preference
|
||||||
DictionaryDb.init(this);
|
DictionaryDb.init(this);
|
||||||
DictionaryDb.normalizeWordFrequencies(settings);
|
DictionaryDb.normalizeWordFrequencies(settings);
|
||||||
|
|
||||||
InputModeValidator.validateEnabledLanguages(settings.getEnabledLanguageIds());
|
InputModeValidator.validateEnabledLanguages(this, settings.getEnabledLanguageIds());
|
||||||
validateFunctionKeys();
|
validateFunctionKeys();
|
||||||
|
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,13 @@ import io.github.sspanak.tt9.preferences.items.SectionKeymap;
|
||||||
|
|
||||||
public class SettingsStore {
|
public class SettingsStore {
|
||||||
|
|
||||||
|
private final Context context;
|
||||||
private final SharedPreferences prefs;
|
private final SharedPreferences prefs;
|
||||||
private final SharedPreferences.Editor prefsEditor;
|
private final SharedPreferences.Editor prefsEditor;
|
||||||
|
|
||||||
|
|
||||||
public SettingsStore(Context context) {
|
public SettingsStore(Context context) {
|
||||||
|
this.context = context;
|
||||||
prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
prefsEditor = prefs.edit();
|
prefsEditor = prefs.edit();
|
||||||
}
|
}
|
||||||
|
|
@ -32,7 +34,7 @@ public class SettingsStore {
|
||||||
/************* validators *************/
|
/************* validators *************/
|
||||||
|
|
||||||
private boolean doesLanguageExist(int langId) {
|
private boolean doesLanguageExist(int langId) {
|
||||||
return LanguageCollection.getLanguage(langId) != null;
|
return LanguageCollection.getLanguage(context, langId) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean validateSavedLanguage(int langId, String logTag) {
|
private boolean validateSavedLanguage(int langId, String logTag) {
|
||||||
|
|
@ -70,7 +72,7 @@ public class SettingsStore {
|
||||||
|
|
||||||
public Set<String> getEnabledLanguagesIdsAsStrings() {
|
public Set<String> getEnabledLanguagesIdsAsStrings() {
|
||||||
return prefs.getStringSet("pref_languages", new HashSet<>(Collections.singletonList(
|
return prefs.getStringSet("pref_languages", new HashSet<>(Collections.singletonList(
|
||||||
String.valueOf(LanguageCollection.getDefault().getId())
|
String.valueOf(LanguageCollection.getDefault(context).getId())
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -124,7 +126,7 @@ public class SettingsStore {
|
||||||
|
|
||||||
|
|
||||||
public int getInputLanguage() {
|
public int getInputLanguage() {
|
||||||
return prefs.getInt("pref_input_language", LanguageCollection.getDefault().getId());
|
return prefs.getInt("pref_input_language", LanguageCollection.getDefault(context).getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void saveInputLanguage(int language) {
|
public void saveInputLanguage(int language) {
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ abstract class ItemClickable {
|
||||||
*
|
*
|
||||||
* My smashed Qin F21 Pro+ occasionally does this, if I press the keys hard.
|
* My smashed Qin F21 Pro+ occasionally does this, if I press the keys hard.
|
||||||
* There were reports the same happens on Kyocera KYF31, causing absolutely undesirable side effects.
|
* There were reports the same happens on Kyocera KYF31, causing absolutely undesirable side effects.
|
||||||
* @see: <a href="https://github.com/sspanak/tt9/issues/117">...</a>
|
* See: <a href="https://github.com/sspanak/tt9/issues/117">...</a>
|
||||||
*/
|
*/
|
||||||
protected boolean debounceClick(Preference p) {
|
protected boolean debounceClick(Preference p) {
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ public class ItemLoadDictionary extends ItemClickable {
|
||||||
|
|
||||||
|
|
||||||
private void onLoadingStatusChange(Bundle status) {
|
private void onLoadingStatusChange(Bundle status) {
|
||||||
progressBar.show(status);
|
progressBar.show(context, status);
|
||||||
item.setSummary(progressBar.getTitle() + " " + progressBar.getMessage());
|
item.setSummary(progressBar.getTitle() + " " + progressBar.getMessage());
|
||||||
|
|
||||||
if (progressBar.isCancelled()) {
|
if (progressBar.isCancelled()) {
|
||||||
|
|
@ -62,7 +62,7 @@ public class ItemLoadDictionary extends ItemClickable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean onClick(Preference p) {
|
protected boolean onClick(Preference p) {
|
||||||
ArrayList<Language> languages = LanguageCollection.getAll(settings.getEnabledLanguageIds());
|
ArrayList<Language> languages = LanguageCollection.getAll(context, settings.getEnabledLanguageIds());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
loader.load(languages);
|
loader.load(languages);
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,27 @@
|
||||||
package io.github.sspanak.tt9.preferences.items;
|
package io.github.sspanak.tt9.preferences.items;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
import androidx.preference.MultiSelectListPreference;
|
import androidx.preference.MultiSelectListPreference;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
import io.github.sspanak.tt9.R;
|
||||||
import io.github.sspanak.tt9.languages.Language;
|
import io.github.sspanak.tt9.languages.Language;
|
||||||
import io.github.sspanak.tt9.languages.LanguageCollection;
|
import io.github.sspanak.tt9.languages.LanguageCollection;
|
||||||
import io.github.sspanak.tt9.preferences.SettingsStore;
|
import io.github.sspanak.tt9.preferences.SettingsStore;
|
||||||
|
import io.github.sspanak.tt9.ui.UI;
|
||||||
|
|
||||||
public class ItemSelectLanguage {
|
public class ItemSelectLanguage {
|
||||||
public static final String NAME = "pref_languages";
|
public static final String NAME = "pref_languages";
|
||||||
|
|
||||||
|
private final Context context;
|
||||||
private final SettingsStore settings;
|
private final SettingsStore settings;
|
||||||
private final MultiSelectListPreference item;
|
private final MultiSelectListPreference item;
|
||||||
|
|
||||||
public ItemSelectLanguage(MultiSelectListPreference multiSelect, SettingsStore settings) {
|
public ItemSelectLanguage(Context context, MultiSelectListPreference multiSelect, SettingsStore settings) {
|
||||||
|
this.context = context;
|
||||||
this.item = multiSelect;
|
this.item = multiSelect;
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
}
|
}
|
||||||
|
|
@ -25,7 +31,11 @@ public class ItemSelectLanguage {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayList<Language> languages = LanguageCollection.getAll(true);
|
ArrayList<Language> languages = LanguageCollection.getAll(context, true);
|
||||||
|
if (languages.isEmpty()) {
|
||||||
|
UI.alert(context, R.string.error, R.string.failed_loading_language_definitions);
|
||||||
|
// do not return, the MultiSelect component requires arrays, even if empty, otherwise it crashes
|
||||||
|
}
|
||||||
|
|
||||||
ArrayList<CharSequence> values = new ArrayList<>();
|
ArrayList<CharSequence> values = new ArrayList<>();
|
||||||
for (Language l : languages) {
|
for (Language l : languages) {
|
||||||
|
|
@ -70,7 +80,7 @@ public class ItemSelectLanguage {
|
||||||
|
|
||||||
private void previewSelection() {
|
private void previewSelection() {
|
||||||
item.setSummary(
|
item.setSummary(
|
||||||
LanguageCollection.toString(LanguageCollection.getAll(settings.getEnabledLanguageIds(), true))
|
LanguageCollection.toString(LanguageCollection.getAll(context, settings.getEnabledLanguageIds(), true))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ public class ItemTruncateUnselected extends ItemTruncateAll {
|
||||||
|
|
||||||
ArrayList<Integer> unselectedLanguageIds = new ArrayList<>();
|
ArrayList<Integer> unselectedLanguageIds = new ArrayList<>();
|
||||||
ArrayList<Integer> selectedLanguageIds = settings.getEnabledLanguageIds();
|
ArrayList<Integer> selectedLanguageIds = settings.getEnabledLanguageIds();
|
||||||
for (Language lang : LanguageCollection.getAll(false)) {
|
for (Language lang : LanguageCollection.getAll(activity, false)) {
|
||||||
if (!selectedLanguageIds.contains(lang.getId())) {
|
if (!selectedLanguageIds.contains(lang.getId())) {
|
||||||
unselectedLanguageIds.add(lang.getId());
|
unselectedLanguageIds.add(lang.getId());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ public class DictionariesScreen extends BaseScreenFragment {
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate() {
|
protected void onCreate() {
|
||||||
ItemSelectLanguage multiSelect = new ItemSelectLanguage(
|
ItemSelectLanguage multiSelect = new ItemSelectLanguage(
|
||||||
|
activity,
|
||||||
findPreference(ItemSelectLanguage.NAME),
|
findPreference(ItemSelectLanguage.NAME),
|
||||||
activity.settings
|
activity.settings
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ public class AddWordAct extends AppCompatActivity {
|
||||||
word = ((EditText) main.findViewById(R.id.add_word_text)).getText().toString();
|
word = ((EditText) main.findViewById(R.id.add_word_text)).getText().toString();
|
||||||
Logger.d("addWord", "Attempting to add word: '" + word + "'...");
|
Logger.d("addWord", "Attempting to add word: '" + word + "'...");
|
||||||
|
|
||||||
DictionaryDb.insertWord(this::onAddedWord, LanguageCollection.getLanguage(lang), word);
|
DictionaryDb.insertWord(this::onAddedWord, LanguageCollection.getLanguage(this, lang), word);
|
||||||
} catch (InsertBlankWordException e) {
|
} catch (InsertBlankWordException e) {
|
||||||
Logger.e("AddWordAct.addWord", e.getMessage());
|
Logger.e("AddWordAct.addWord", e.getMessage());
|
||||||
UI.toastLong(this, R.string.add_word_blank);
|
UI.toastLong(this, R.string.add_word_blank);
|
||||||
|
|
|
||||||
|
|
@ -103,13 +103,14 @@ public class DictionaryLoadingBar {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void show(Bundle data) {
|
public void show(Context context, Bundle data) {
|
||||||
String error = data.getString("error", null);
|
String error = data.getString("error", null);
|
||||||
int fileCount = data.getInt("fileCount", -1);
|
int fileCount = data.getInt("fileCount", -1);
|
||||||
|
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
hasFailed = true;
|
hasFailed = true;
|
||||||
showError(
|
showError(
|
||||||
|
context,
|
||||||
error,
|
error,
|
||||||
data.getInt("languageId", -1),
|
data.getInt("languageId", -1),
|
||||||
data.getLong("fileLine", -1),
|
data.getLong("fileLine", -1),
|
||||||
|
|
@ -120,6 +121,7 @@ public class DictionaryLoadingBar {
|
||||||
} else {
|
} else {
|
||||||
hasFailed = false;
|
hasFailed = false;
|
||||||
showProgress(
|
showProgress(
|
||||||
|
context,
|
||||||
data.getLong("time", 0),
|
data.getLong("time", 0),
|
||||||
data.getInt("currentFile", 0),
|
data.getInt("currentFile", 0),
|
||||||
data.getInt("progress", 0),
|
data.getInt("progress", 0),
|
||||||
|
|
@ -129,8 +131,8 @@ public class DictionaryLoadingBar {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private String generateTitle(int languageId) {
|
private String generateTitle(Context context, int languageId) {
|
||||||
Language lang = LanguageCollection.getLanguage(languageId);
|
Language lang = LanguageCollection.getLanguage(context, languageId);
|
||||||
|
|
||||||
if (lang != null) {
|
if (lang != null) {
|
||||||
return resources.getString(R.string.dictionary_loading, lang.getName());
|
return resources.getString(R.string.dictionary_loading, lang.getName());
|
||||||
|
|
@ -140,7 +142,7 @@ public class DictionaryLoadingBar {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void showProgress(long time, int currentFile, int currentFileProgress, int languageId) {
|
private void showProgress(Context context, long time, int currentFile, int currentFileProgress, int languageId) {
|
||||||
if (currentFileProgress < 0) {
|
if (currentFileProgress < 0) {
|
||||||
hide();
|
hide();
|
||||||
isStopped = true;
|
isStopped = true;
|
||||||
|
|
@ -154,12 +156,12 @@ public class DictionaryLoadingBar {
|
||||||
|
|
||||||
if (progress >= maxProgress) {
|
if (progress >= maxProgress) {
|
||||||
progress = maxProgress = 0;
|
progress = maxProgress = 0;
|
||||||
title = generateTitle(-1);
|
title = generateTitle(context, -1);
|
||||||
|
|
||||||
String timeFormat = time > 60000 ? " (%1.0fs)" : " (%1.1fs)";
|
String timeFormat = time > 60000 ? " (%1.0fs)" : " (%1.1fs)";
|
||||||
message = resources.getString(R.string.completed) + String.format(Locale.ENGLISH, timeFormat, time / 1000.0);
|
message = resources.getString(R.string.completed) + String.format(Locale.ENGLISH, timeFormat, time / 1000.0);
|
||||||
} else {
|
} else {
|
||||||
title = generateTitle(languageId);
|
title = generateTitle(context, languageId);
|
||||||
message = currentFileProgress + "%";
|
message = currentFileProgress + "%";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -167,8 +169,8 @@ public class DictionaryLoadingBar {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void showError(String errorType, int langId, long line, String word) {
|
private void showError(Context context, String errorType, int langId, long line, String word) {
|
||||||
Language lang = LanguageCollection.getLanguage(langId);
|
Language lang = LanguageCollection.getLanguage(context, langId);
|
||||||
|
|
||||||
if (lang == null || errorType.equals(InvalidLanguageException.class.getSimpleName())) {
|
if (lang == null || errorType.equals(InvalidLanguageException.class.getSimpleName())) {
|
||||||
message = resources.getString(R.string.add_word_invalid_language);
|
message = resources.getString(R.string.add_word_invalid_language);
|
||||||
|
|
@ -180,7 +182,7 @@ public class DictionaryLoadingBar {
|
||||||
message = resources.getString(R.string.dictionary_load_error, lang.getName(), errorType);
|
message = resources.getString(R.string.dictionary_load_error, lang.getName(), errorType);
|
||||||
}
|
}
|
||||||
|
|
||||||
title = generateTitle(-1);
|
title = generateTitle(context, -1);
|
||||||
progress = maxProgress = 0;
|
progress = maxProgress = 0;
|
||||||
|
|
||||||
renderError();
|
renderError();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package io.github.sspanak.tt9.ui;
|
package io.github.sspanak.tt9.ui;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
|
@ -27,6 +28,15 @@ public class UI {
|
||||||
tt9.startActivity(prefIntent);
|
tt9.startActivity(prefIntent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void alert(Context context, int titleResource, int messageResource) {
|
||||||
|
new AlertDialog.Builder(context)
|
||||||
|
.setTitle(titleResource)
|
||||||
|
.setMessage(messageResource)
|
||||||
|
.setCancelable(false)
|
||||||
|
.setPositiveButton(android.R.string.ok, (dialog, which) -> dialog.cancel())
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
|
||||||
public static void toast(Context context, CharSequence msg) {
|
public static void toast(Context context, CharSequence msg) {
|
||||||
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
|
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ public class SoftNumberKey extends SoftKey {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2-9
|
// 2-9
|
||||||
Language language = LanguageCollection.getLanguage(tt9.getSettings().getInputLanguage());
|
Language language = LanguageCollection.getLanguage(tt9.getApplicationContext(), tt9.getSettings().getInputLanguage());
|
||||||
if (language == null) {
|
if (language == null) {
|
||||||
Logger.d("SoftNumberKey.getLabel", "Cannot generate a label when the language is NULL.");
|
Logger.d("SoftNumberKey.getLabel", "Cannot generate a label when the language is NULL.");
|
||||||
return "";
|
return "";
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue