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
|
||||
- name: Validate Dictionaries
|
||||
run: ./gradlew validateDictionaries
|
||||
run: ./gradlew validateLanguages
|
||||
- name: Lint
|
||||
run: ./gradlew lint
|
||||
- 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
|
||||
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.
|
||||
- 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).
|
||||
- `dictionaryFile` is the name of the dictionary in `assets/` folder.
|
||||
- `characterMap` contains the letters and punctuation marks associated with each key.
|
||||
- `dictionaryFile` is the name of the dictionary in `assets/languages/dictionaries/` folder.
|
||||
- `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.
|
||||
- `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.
|
||||
- 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
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# 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-.
|
||||
|
||||
|
|
@ -36,7 +36,7 @@ If you like Traditional T9, buy me a beer. Donations are currently accepted on [
|
|||
|
||||
## License
|
||||
- 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)
|
||||
- "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 {
|
||||
mavenCentral()
|
||||
google()
|
||||
maven {
|
||||
url "https://plugins.gradle.org/m2/"
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
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: 'at.zierler.yamlvalidator'
|
||||
|
||||
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
|
||||
// see: https://stackoverflow.com/questions/75274720/a-failure-occurred-while-executing-appcheckdebugduplicateclasses/75315276#75315276
|
||||
exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-jdk8'
|
||||
|
||||
yamlValidator {
|
||||
searchPaths = ['assets/languages/definitions']
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
|
@ -20,11 +29,15 @@ dependencies {
|
|||
implementation 'androidx.preference:preference:1.2.0'
|
||||
implementation 'androidx.room:room-runtime:2.5.1'
|
||||
annotationProcessor 'androidx.room:room-compiler:2.5.1'
|
||||
implementation 'org.yaml:snakeyaml:2.0'
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
google()
|
||||
maven {
|
||||
url "https://plugins.gradle.org/m2/"
|
||||
}
|
||||
}
|
||||
|
||||
def execThing ( String cmdStr ) {
|
||||
|
|
@ -86,9 +99,13 @@ def getReleaseVersion = { ->
|
|||
return "${getVersionName()} (${getCurrentGitHash()})"
|
||||
}
|
||||
|
||||
task validateDictionaries {
|
||||
inputs.dir fileTree(dir:'assets', excludes:['dict.properties'])
|
||||
outputs.file "${project.buildDir}/dict.validation.txt"
|
||||
task validateLanguages {
|
||||
final baseDir = "${project.rootDir}/assets/languages"
|
||||
final definitionsDir = "${baseDir}/definitions"
|
||||
final dictionariesDir = "${baseDir}/dictionaries"
|
||||
|
||||
inputs.dir fileTree(dir:baseDir, excludes:['dict.properties'])
|
||||
outputs.file "${project.buildDir}/lang.validation.txt"
|
||||
|
||||
doLast {
|
||||
final String CSV_DELIMITER = ' ' // TAB
|
||||
|
|
@ -100,19 +117,86 @@ task validateDictionaries {
|
|||
|
||||
outputs.files.singleFile.text = ""
|
||||
|
||||
inputs.getFiles().each {File file ->
|
||||
fileTree(definitionsDir).getFiles().each { File languageFile ->
|
||||
if (errorCount >= MAX_ERRORS) {
|
||||
return
|
||||
}
|
||||
|
||||
println "Validating dictionary: " + file.name
|
||||
println "Validating language: ${languageFile.name}"
|
||||
|
||||
def uniqueWords = [:]
|
||||
|
||||
int lineNumber = 0
|
||||
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) {
|
||||
return
|
||||
}
|
||||
|
|
@ -122,14 +206,14 @@ task validateDictionaries {
|
|||
if (line == "") {
|
||||
isFileValid = false
|
||||
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
|
||||
}
|
||||
|
||||
if (line.contains(" ")) {
|
||||
isFileValid = false
|
||||
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
|
||||
}
|
||||
|
||||
|
|
@ -140,32 +224,32 @@ task validateDictionaries {
|
|||
if (frequency.length() > 0 && !frequency.matches("^\\d+\$")) {
|
||||
isFileValid = false
|
||||
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)")) {
|
||||
isFileValid = false
|
||||
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}+\$")) {
|
||||
isFileValid = false
|
||||
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))) {
|
||||
isFileValid = false
|
||||
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()
|
||||
if (uniqueWords[uniqueWordKey] != null && uniqueWords[uniqueWordKey] == true) {
|
||||
isFileValid = false
|
||||
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 {
|
||||
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 != "") {
|
||||
|
|
@ -239,7 +323,10 @@ android {
|
|||
aidl true
|
||||
}
|
||||
|
||||
|
||||
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 *;
|
||||
#}
|
||||
|
||||
-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>
|
||||
<string name="app_settings">Настройки на TT9</string>
|
||||
<string name="completed">Завършено</string>
|
||||
<string name="no_language">Няма език</string>
|
||||
<string name="error_unexpected">Възникна неочаквана грешка.</string>
|
||||
|
||||
<string name="failed_loading_language_definitions">Не може да се заредят езиковите дефиниции.</string>
|
||||
<string name="add_word_add">Добави</string>
|
||||
<string name="add_word_blank">Не може да се въведе празна дума.</string>
|
||||
<string name="add_word_exist">Думата „%1$s“ е вече речника.</string>
|
||||
<string name="add_word_title">Добавяне на дума</string>
|
||||
|
||||
<string name="pref_category_about">За приложението</string>
|
||||
<string name="pref_help">Помощ</string>
|
||||
<string name="pref_dark_theme">Тъмен облик</string>
|
||||
<string name="pref_choose_languages">Езици</string>
|
||||
<string name="dictionary_truncate_title">Изтрий всички</string>
|
||||
|
||||
<string name="dictionary_cancel_load">Отмени зареждането</string>
|
||||
<string name="dictionary_load_bad_char">Неуспешно зареждане. Невалидна дума „%1$s“ на ред %2$d за език „%3$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_up">Усилване на звук</string>
|
||||
<string name="dictionary_truncating">Изтриване…</string>
|
||||
<string name="error">Грешка</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_settings">TT9 Einstellungen</string>
|
||||
<string name="no_language">Keine Sprache</string>
|
||||
<string name="error_unexpected">Unerwarteter Fehler aufgetreten.</string>
|
||||
|
||||
<string name="add_word_add">Hinzufügen</string>
|
||||
|
|
@ -21,4 +22,5 @@
|
|||
<string name="char_space">Leerzeichen</string>
|
||||
<string name="char_newline">Neue Zeile</string>
|
||||
<string name="pref_category_setup">Ersteinrichtung</string>
|
||||
<string name="error">Fehler</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
<string name="add_word_blank">Palabra en blanco no agregada.</string>
|
||||
<string name="pref_help">Ayuda</string>
|
||||
<string name="completed">Acabado</string>
|
||||
<string name="no_language">Sin idioma</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_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_category_setup">Configuración inicial</string>
|
||||
<string name="pref_show_soft_numpad">Teclado numérico en pantalla</string>
|
||||
<string name="error">Error</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -2,19 +2,18 @@
|
|||
<resources>
|
||||
<string name="app_settings">Paramètres de TT9</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="failed_loading_language_definitions">Impossible de charger aucune définition de langue</string>
|
||||
<string name="add_word_add">Ajouter</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_title">Ajouter un mot</string>
|
||||
|
||||
<string name="pref_category_about">À propos de l\'application</string>
|
||||
<string name="pref_help">Aide</string>
|
||||
<string name="pref_dark_theme">Thème sombre</string>
|
||||
<string name="pref_choose_languages">Langues</string>
|
||||
<string name="dictionary_truncate_title">Supprimer tous</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_loaded">Chargement du dictionnaire terminé.</string>
|
||||
|
|
@ -64,4 +63,5 @@
|
|||
<string name="pref_category_setup">Configuration initiale</string>
|
||||
<string name="pref_show_soft_numpad">Pavé numérique à l\'écran</string>
|
||||
<string name="dictionary_truncating">Suppression…</string>
|
||||
<string name="error">Erreur</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
<resources>
|
||||
<string name="app_settings">TT9 Impostazioni</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="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_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="error">Errore</string>
|
||||
</resources>
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
<resources>
|
||||
<string name="app_settings">TT9 הגדרות</string>
|
||||
<string name="completed">הסתיים</string>
|
||||
<string name="no_language">אין שפה</string>
|
||||
<string name="error_unexpected">אירעה שגיאה לא צפויה.</string>
|
||||
|
||||
<string name="add_word_add">הוסף</string>
|
||||
|
|
@ -53,4 +54,5 @@
|
|||
|
||||
<string name="char_newline">שורה חדשה</string>
|
||||
<string name="char_space">רווח</string>
|
||||
<string name="error">טעות</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<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="add_word_add">Toevoegen</string>
|
||||
|
|
@ -21,4 +22,5 @@
|
|||
<string name="char_newline">Nieuwe regel</string>
|
||||
<string name="pref_category_setup">Initiële setup</string>
|
||||
<string name="dictionary_truncating">Verwijderen…</string>
|
||||
<string name="error">Fout</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
<resources>
|
||||
<string name="app_settings">Configurações do Teclado</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="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">Inverter Ordem das Teclas</string>
|
||||
<string name="dictionary_truncate_unselected">Limpar Não Selecionados</string>
|
||||
<string name="error">Erro</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -2,19 +2,18 @@
|
|||
<resources>
|
||||
<string name="app_settings">TT9 настройки</string>
|
||||
<string name="completed">Выполнено</string>
|
||||
<string name="no_language">Нет языка</string>
|
||||
<string name="error_unexpected">Произошла непредвиденная ошибка.</string>
|
||||
|
||||
<string name="failed_loading_language_definitions">Не удалось загрузить какое-либо определение языка.</string>
|
||||
<string name="add_word_add">Добавить</string>
|
||||
<string name="add_word_blank">Невозможно добавить слово.</string>
|
||||
<string name="add_word_exist">Слово «%1$s» уже есть в словаре.</string>
|
||||
<string name="add_word_title">Добавить слово</string>
|
||||
|
||||
<string name="pref_category_about">О приложении</string>
|
||||
<string name="pref_help">Помощь</string>
|
||||
<string name="pref_dark_theme">Темная тема</string>
|
||||
<string name="pref_choose_languages">Языки</string>
|
||||
<string name="dictionary_truncate_title">Удалить все</string>
|
||||
|
||||
<string name="dictionary_cancel_load">Отменить загрузку</string>
|
||||
<string name="dictionary_load_error">Ошибка загрузки словаря для языка «%1$s» (%2$s).</string>
|
||||
<string name="dictionary_loaded">Загрузка словаря завершена.</string>
|
||||
|
|
@ -69,4 +68,5 @@
|
|||
<string name="key_volume_down">Уменьшить громкости</string>
|
||||
<string name="key_volume_up">Увеличить громкости</string>
|
||||
<string name="dictionary_truncating">Удаление…</string>
|
||||
<string name="error">Ошибка</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -2,19 +2,18 @@
|
|||
<resources>
|
||||
<string name="app_settings">Налаштування TT9</string>
|
||||
<string name="completed">Зроблено</string>
|
||||
<string name="no_language">Немає мови</string>
|
||||
<string name="error_unexpected">Сталася неочікувана помилка.</string>
|
||||
|
||||
<string name="failed_loading_language_definitions">Не вдалося завантажити всі визначення мови.</string>
|
||||
<string name="add_word_add">Додати</string>
|
||||
<string name="add_word_blank">Неможливо додати слово.</string>
|
||||
<string name="add_word_exist">Слово «%1$s» вже є в словнику.</string>
|
||||
<string name="add_word_title">Додати слово</string>
|
||||
|
||||
<string name="pref_category_about">Про додаток</string>
|
||||
<string name="pref_help">Допомога</string>
|
||||
<string name="pref_dark_theme">Темна тема</string>
|
||||
<string name="pref_choose_languages">Мови</string>
|
||||
<string name="dictionary_truncate_title">Видалити усі</string>
|
||||
|
||||
<string name="dictionary_cancel_load">Скасувати завантаження</string>
|
||||
<string name="dictionary_load_error">Помилка завантаження словника для мови «%1$s» (%2$s).</string>
|
||||
<string name="dictionary_loaded">Завантаження словника завершено.</string>
|
||||
|
|
@ -69,4 +68,5 @@
|
|||
<string name="key_volume_up">Збільшення гучності</string>
|
||||
<string name="key_volume_down">Зменшення гучності</string>
|
||||
<string name="dictionary_truncating">Видалення…</string>
|
||||
<string name="error">Помилка</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,11 @@
|
|||
<string name="app_name_short" translatable="false">TT9</string>
|
||||
<string name="app_settings">TT9 Settings</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="failed_loading_language_definitions">Failed loading all language definitions.</string>
|
||||
|
||||
<string name="add_word_add">Add</string>
|
||||
<string name="add_word_blank">Blank word not added.</string>
|
||||
|
|
|
|||
|
|
@ -1,25 +1,41 @@
|
|||
package io.github.sspanak.tt9.db.migrations;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.room.migration.Migration;
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import io.github.sspanak.tt9.Logger;
|
||||
import io.github.sspanak.tt9.languages.definitions.Dutch;
|
||||
import io.github.sspanak.tt9.languages.definitions.English;
|
||||
import io.github.sspanak.tt9.languages.Language;
|
||||
import io.github.sspanak.tt9.languages.LanguageCollection;
|
||||
|
||||
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
|
||||
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 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 {
|
||||
Language English = LanguageCollection.getByLocale(ctx, Locale.ENGLISH.toString());
|
||||
Language Dutch = LanguageCollection.getByLocale(ctx, "nl_NL");
|
||||
assert English != null;
|
||||
assert Dutch != null;
|
||||
|
||||
database.beginTransaction();
|
||||
database.execSQL(getDeleteEnglishSwordsQuery());
|
||||
database.execSQL(getDeleteWordsQuery(new English().getId(), enWords));
|
||||
database.execSQL(getDeleteWordsQuery(new Dutch().getId(), nlWords));
|
||||
database.execSQL(getDeleteEnglishSwordsQuery(English));
|
||||
database.execSQL(getDeleteWordsQuery(English.getId(), enWords));
|
||||
database.execSQL(getDeleteWordsQuery(Dutch.getId(), nlWords));
|
||||
database.setTransactionSuccessful();
|
||||
} catch (Exception e) {
|
||||
Logger.e("Migrate to DB11", "Migration failed. " + e.getMessage());
|
||||
|
|
@ -29,11 +45,11 @@ public class DB11 {
|
|||
}
|
||||
};
|
||||
|
||||
private static String getDeleteEnglishSwordsQuery() {
|
||||
return "DELETE FROM words WHERE lang=" + new English().getId() + " AND word LIKE '%''s'";
|
||||
private String getDeleteEnglishSwordsQuery(Language English) {
|
||||
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 + ")";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,16 +7,10 @@ import androidx.room.migration.Migration;
|
|||
import androidx.sqlite.db.SupportSQLiteDatabase;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
|
||||
import io.github.sspanak.tt9.languages.definitions.Bulgarian;
|
||||
import io.github.sspanak.tt9.languages.definitions.Dutch;
|
||||
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.languages.Language;
|
||||
import io.github.sspanak.tt9.languages.LanguageCollection;
|
||||
import io.github.sspanak.tt9.preferences.SettingsStore;
|
||||
|
||||
public class DB7 {
|
||||
|
|
@ -28,28 +22,41 @@ public class DB7 {
|
|||
}
|
||||
|
||||
private int getNewLanguageId(int oldId) {
|
||||
Language language;
|
||||
|
||||
switch (oldId) {
|
||||
default:
|
||||
return oldId;
|
||||
case 1:
|
||||
return new English().getId();
|
||||
language = LanguageCollection.getByLocale(ctx, Locale.ENGLISH.toString());
|
||||
break;
|
||||
case 2:
|
||||
return new Russian().getId();
|
||||
language = LanguageCollection.getByLocale(ctx, "ru_RU");
|
||||
break;
|
||||
case 3:
|
||||
return new German().getId();
|
||||
language = LanguageCollection.getByLocale(ctx, Locale.GERMAN.toString());
|
||||
break;
|
||||
case 4:
|
||||
return new French().getId();
|
||||
language = LanguageCollection.getByLocale(ctx, Locale.FRENCH.toString());
|
||||
break;
|
||||
case 5:
|
||||
return new Italian().getId();
|
||||
language = LanguageCollection.getByLocale(ctx, Locale.ITALIAN.toString());
|
||||
break;
|
||||
case 6:
|
||||
return new Ukrainian().getId();
|
||||
language = LanguageCollection.getByLocale(ctx, "uk_UA");
|
||||
break;
|
||||
case 7:
|
||||
return new Bulgarian().getId();
|
||||
language = LanguageCollection.getByLocale(ctx, "bg_BG");
|
||||
break;
|
||||
case 8:
|
||||
return new Dutch().getId();
|
||||
language = LanguageCollection.getByLocale(ctx, "nl_NL");
|
||||
break;
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ public abstract class TT9Room extends RoomDatabase {
|
|||
DB8.MIGRATION,
|
||||
DB9.MIGRATION,
|
||||
DB10.MIGRATION,
|
||||
DB11.MIGRATION
|
||||
new DB11().getMigration(context)
|
||||
)
|
||||
.build();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ public class EmptyDatabaseWarning {
|
|||
public EmptyDatabaseWarning(SettingsStore settings) {
|
||||
WARNING_INTERVAL = settings.getDictionaryMissingWarningInterval();
|
||||
|
||||
for (Language lang : LanguageCollection.getAll()) {
|
||||
for (Language lang : LanguageCollection.getAll(context)) {
|
||||
if (!warningDisplayedTime.containsKey(lang.getId())) {
|
||||
warningDisplayedTime.put(lang.getId(), 0L);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ public class TraditionalT9 extends KeyPadHandler {
|
|||
|
||||
|
||||
private void loadSettings() {
|
||||
mLanguage = LanguageCollection.getLanguage(settings.getInputLanguage());
|
||||
mLanguage = LanguageCollection.getLanguage(getMainContext(), settings.getInputLanguage());
|
||||
mEnabledLanguages = settings.getEnabledLanguageIds();
|
||||
validateLanguages();
|
||||
|
||||
|
|
@ -79,8 +79,8 @@ public class TraditionalT9 extends KeyPadHandler {
|
|||
|
||||
|
||||
private void validateLanguages() {
|
||||
mEnabledLanguages = InputModeValidator.validateEnabledLanguages(mEnabledLanguages);
|
||||
mLanguage = InputModeValidator.validateLanguage(mLanguage, mEnabledLanguages);
|
||||
mEnabledLanguages = InputModeValidator.validateEnabledLanguages(getMainContext(), mEnabledLanguages);
|
||||
mLanguage = InputModeValidator.validateLanguage(getMainContext(), mLanguage, mEnabledLanguages);
|
||||
|
||||
settings.saveEnabledLanguageIds(mEnabledLanguages);
|
||||
settings.saveInputLanguage(mLanguage.getId());
|
||||
|
|
@ -689,7 +689,7 @@ public class TraditionalT9 extends KeyPadHandler {
|
|||
// select the next language
|
||||
int previous = mEnabledLanguages.indexOf(mLanguage.getId());
|
||||
int next = (previous + 1) % mEnabledLanguages.size();
|
||||
mLanguage = LanguageCollection.getLanguage(mEnabledLanguages.get(next));
|
||||
mLanguage = LanguageCollection.getLanguage(getMainContext(), mEnabledLanguages.get(next));
|
||||
|
||||
validateLanguages();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package io.github.sspanak.tt9.ime.helpers;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import io.github.sspanak.tt9.Logger;
|
||||
|
|
@ -8,29 +10,29 @@ import io.github.sspanak.tt9.languages.Language;
|
|||
import io.github.sspanak.tt9.languages.LanguageCollection;
|
||||
|
||||
public class InputModeValidator {
|
||||
public static ArrayList<Integer> validateEnabledLanguages(ArrayList<Integer> enabledLanguageIds) {
|
||||
ArrayList<Language> validLanguages = LanguageCollection.getAll(enabledLanguageIds);
|
||||
public static ArrayList<Integer> validateEnabledLanguages(Context context, ArrayList<Integer> enabledLanguageIds) {
|
||||
ArrayList<Language> validLanguages = LanguageCollection.getAll(context, enabledLanguageIds);
|
||||
ArrayList<Integer> validLanguageIds = new ArrayList<>();
|
||||
for (Language lang : validLanguages) {
|
||||
validLanguageIds.add(lang.getId());
|
||||
}
|
||||
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.");
|
||||
}
|
||||
|
||||
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())) {
|
||||
return language;
|
||||
}
|
||||
|
||||
String error = language != null ? "Language: " + language.getId() + " is not enabled." : "Invalid language.";
|
||||
|
||||
Language validLanguage = LanguageCollection.getLanguage(validLanguageIds.get(0));
|
||||
validLanguage = validLanguage != null ? validLanguage : LanguageCollection.getDefault();
|
||||
Language validLanguage = LanguageCollection.getLanguage(context, validLanguageIds.get(0));
|
||||
validLanguage = validLanguage != null ? validLanguage : LanguageCollection.getDefault(context);
|
||||
|
||||
Logger.w("tt9/validateLanguage", error + " Enforcing language: " + validLanguage.getId());
|
||||
|
||||
|
|
|
|||
|
|
@ -91,7 +91,8 @@ public class ModeABC extends InputMode {
|
|||
}
|
||||
|
||||
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();
|
||||
|
||||
|
|
|
|||
|
|
@ -13,12 +13,82 @@ public class Language {
|
|||
protected Locale locale;
|
||||
protected String dictionaryFile;
|
||||
protected String abcString;
|
||||
protected ArrayList<ArrayList<String>> characterMap = new ArrayList<>();
|
||||
private final HashMap<Character, String> reverseCharacterMap = new HashMap<>();
|
||||
protected final ArrayList<ArrayList<String>> layout = new ArrayList<>();
|
||||
private final HashMap<Character, String> characterKeyMap = new HashMap<>();
|
||||
|
||||
// settings
|
||||
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() {
|
||||
if (id == 0) {
|
||||
id = generateId();
|
||||
|
|
@ -95,11 +165,11 @@ public class Language {
|
|||
return idInt;
|
||||
}
|
||||
|
||||
private void generateReverseCharacterMap() {
|
||||
reverseCharacterMap.clear();
|
||||
private void generateCharacterKeyMap() {
|
||||
characterKeyMap.clear();
|
||||
for (int digit = 0; digit <= 9; 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) {
|
||||
if (key < 0 || key >= characterMap.size()) {
|
||||
if (key < 0 || key >= layout.size()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
ArrayList<String> chars = new ArrayList<>(characterMap.get(key));
|
||||
ArrayList<String> chars = new ArrayList<>(layout.get(key));
|
||||
if (includeDigit && chars.size() > 0) {
|
||||
chars.add(String.valueOf(key));
|
||||
}
|
||||
|
|
@ -151,17 +221,17 @@ public class Language {
|
|||
StringBuilder sequence = new StringBuilder();
|
||||
String lowerCaseWord = word.toLowerCase(locale);
|
||||
|
||||
if (reverseCharacterMap.isEmpty()) {
|
||||
generateReverseCharacterMap();
|
||||
if (characterKeyMap.isEmpty()) {
|
||||
generateCharacterKeyMap();
|
||||
}
|
||||
|
||||
for (int i = 0; i < lowerCaseWord.length(); 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);
|
||||
}
|
||||
|
||||
sequence.append(reverseCharacterMap.get(letter));
|
||||
sequence.append(characterKeyMap.get(letter));
|
||||
}
|
||||
|
||||
return sequence.toString();
|
||||
|
|
|
|||
|
|
@ -1,84 +1,70 @@
|
|||
package io.github.sspanak.tt9.languages;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import io.github.sspanak.tt9.Logger;
|
||||
import io.github.sspanak.tt9.languages.definitions.*;
|
||||
|
||||
public class LanguageCollection {
|
||||
private static LanguageCollection self;
|
||||
|
||||
private final Language defaultLanguage = new English();
|
||||
private final HashMap<Integer, Language> languages = new HashMap<>();
|
||||
|
||||
private LanguageCollection() {
|
||||
List<Class<? extends Language>> languageList = Arrays.asList(
|
||||
// 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) {
|
||||
private LanguageCollection(Context context) {
|
||||
for (String file : LanguageDefinition.getAllFiles(context.getAssets())) {
|
||||
try {
|
||||
Language lang = languageClass.newInstance();
|
||||
if (languages.containsKey(lang.getId())) {
|
||||
throw new Exception("Duplicate language ID: " + lang.getId() + " for language: " + lang.getName());
|
||||
}
|
||||
Language lang = Language.fromDefinition(LanguageDefinition.fromFile(context.getAssets(), file));
|
||||
languages.put(lang.getId(), lang);
|
||||
} 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) {
|
||||
self = new LanguageCollection();
|
||||
self = new LanguageCollection(context);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
public static Language getLanguage(int langId) {
|
||||
if (getInstance().languages.containsKey(langId)) {
|
||||
return getInstance().languages.get(langId);
|
||||
public static Language getLanguage(Context context, int langId) {
|
||||
if (getInstance(context).languages.containsKey(langId)) {
|
||||
return getInstance(context).languages.get(langId);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Language getDefault() {
|
||||
return getInstance().defaultLanguage;
|
||||
public static Language getDefault(Context context) {
|
||||
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<>();
|
||||
|
||||
for (int languageId : languageIds) {
|
||||
Language lang = getLanguage(languageId);
|
||||
Language lang = getLanguage(context, languageId);
|
||||
if (lang != null) {
|
||||
langList.add(lang);
|
||||
}
|
||||
|
|
@ -91,12 +77,12 @@ public class LanguageCollection {
|
|||
return langList;
|
||||
}
|
||||
|
||||
public static ArrayList<Language> getAll(ArrayList<Integer> languageIds) {
|
||||
return getAll(languageIds, false);
|
||||
public static ArrayList<Language> getAll(Context context, ArrayList<Integer> languageIds) {
|
||||
return getAll(context, languageIds, false);
|
||||
}
|
||||
|
||||
public static ArrayList<Language> getAll(boolean sort) {
|
||||
ArrayList<Language> langList = new ArrayList<>(getInstance().languages.values());
|
||||
public static ArrayList<Language> getAll(Context context, boolean sort) {
|
||||
ArrayList<Language> langList = new ArrayList<>(getInstance(context).languages.values());
|
||||
|
||||
if (sort && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
langList.sort(Comparator.comparing(l -> l.getLocale().toString()));
|
||||
|
|
@ -105,8 +91,8 @@ public class LanguageCollection {
|
|||
return langList;
|
||||
}
|
||||
|
||||
public static ArrayList<Language> getAll() {
|
||||
return getAll(false);
|
||||
public static ArrayList<Language> getAll(Context context) {
|
||||
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.normalizeWordFrequencies(settings);
|
||||
|
||||
InputModeValidator.validateEnabledLanguages(settings.getEnabledLanguageIds());
|
||||
InputModeValidator.validateEnabledLanguages(this, settings.getEnabledLanguageIds());
|
||||
validateFunctionKeys();
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
|
|
|||
|
|
@ -19,11 +19,13 @@ import io.github.sspanak.tt9.preferences.items.SectionKeymap;
|
|||
|
||||
public class SettingsStore {
|
||||
|
||||
private final Context context;
|
||||
private final SharedPreferences prefs;
|
||||
private final SharedPreferences.Editor prefsEditor;
|
||||
|
||||
|
||||
public SettingsStore(Context context) {
|
||||
this.context = context;
|
||||
prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
prefsEditor = prefs.edit();
|
||||
}
|
||||
|
|
@ -32,7 +34,7 @@ public class SettingsStore {
|
|||
/************* validators *************/
|
||||
|
||||
private boolean doesLanguageExist(int langId) {
|
||||
return LanguageCollection.getLanguage(langId) != null;
|
||||
return LanguageCollection.getLanguage(context, langId) != null;
|
||||
}
|
||||
|
||||
private boolean validateSavedLanguage(int langId, String logTag) {
|
||||
|
|
@ -70,7 +72,7 @@ public class SettingsStore {
|
|||
|
||||
public Set<String> getEnabledLanguagesIdsAsStrings() {
|
||||
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() {
|
||||
return prefs.getInt("pref_input_language", LanguageCollection.getDefault().getId());
|
||||
return prefs.getInt("pref_input_language", LanguageCollection.getDefault(context).getId());
|
||||
}
|
||||
|
||||
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.
|
||||
* 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) {
|
||||
long now = System.currentTimeMillis();
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ public class ItemLoadDictionary extends ItemClickable {
|
|||
|
||||
|
||||
private void onLoadingStatusChange(Bundle status) {
|
||||
progressBar.show(status);
|
||||
progressBar.show(context, status);
|
||||
item.setSummary(progressBar.getTitle() + " " + progressBar.getMessage());
|
||||
|
||||
if (progressBar.isCancelled()) {
|
||||
|
|
@ -62,7 +62,7 @@ public class ItemLoadDictionary extends ItemClickable {
|
|||
|
||||
@Override
|
||||
protected boolean onClick(Preference p) {
|
||||
ArrayList<Language> languages = LanguageCollection.getAll(settings.getEnabledLanguageIds());
|
||||
ArrayList<Language> languages = LanguageCollection.getAll(context, settings.getEnabledLanguageIds());
|
||||
|
||||
try {
|
||||
loader.load(languages);
|
||||
|
|
|
|||
|
|
@ -1,21 +1,27 @@
|
|||
package io.github.sspanak.tt9.preferences.items;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.preference.MultiSelectListPreference;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
|
||||
import io.github.sspanak.tt9.R;
|
||||
import io.github.sspanak.tt9.languages.Language;
|
||||
import io.github.sspanak.tt9.languages.LanguageCollection;
|
||||
import io.github.sspanak.tt9.preferences.SettingsStore;
|
||||
import io.github.sspanak.tt9.ui.UI;
|
||||
|
||||
public class ItemSelectLanguage {
|
||||
public static final String NAME = "pref_languages";
|
||||
|
||||
private final Context context;
|
||||
private final SettingsStore settings;
|
||||
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.settings = settings;
|
||||
}
|
||||
|
|
@ -25,7 +31,11 @@ public class ItemSelectLanguage {
|
|||
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<>();
|
||||
for (Language l : languages) {
|
||||
|
|
@ -70,7 +80,7 @@ public class ItemSelectLanguage {
|
|||
|
||||
private void previewSelection() {
|
||||
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> selectedLanguageIds = settings.getEnabledLanguageIds();
|
||||
for (Language lang : LanguageCollection.getAll(false)) {
|
||||
for (Language lang : LanguageCollection.getAll(activity, false)) {
|
||||
if (!selectedLanguageIds.contains(lang.getId())) {
|
||||
unselectedLanguageIds.add(lang.getId());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ public class DictionariesScreen extends BaseScreenFragment {
|
|||
@Override
|
||||
protected void onCreate() {
|
||||
ItemSelectLanguage multiSelect = new ItemSelectLanguage(
|
||||
activity,
|
||||
findPreference(ItemSelectLanguage.NAME),
|
||||
activity.settings
|
||||
);
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ public class AddWordAct extends AppCompatActivity {
|
|||
word = ((EditText) main.findViewById(R.id.add_word_text)).getText().toString();
|
||||
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) {
|
||||
Logger.e("AddWordAct.addWord", e.getMessage());
|
||||
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);
|
||||
int fileCount = data.getInt("fileCount", -1);
|
||||
|
||||
if (error != null) {
|
||||
hasFailed = true;
|
||||
showError(
|
||||
context,
|
||||
error,
|
||||
data.getInt("languageId", -1),
|
||||
data.getLong("fileLine", -1),
|
||||
|
|
@ -120,6 +121,7 @@ public class DictionaryLoadingBar {
|
|||
} else {
|
||||
hasFailed = false;
|
||||
showProgress(
|
||||
context,
|
||||
data.getLong("time", 0),
|
||||
data.getInt("currentFile", 0),
|
||||
data.getInt("progress", 0),
|
||||
|
|
@ -129,8 +131,8 @@ public class DictionaryLoadingBar {
|
|||
}
|
||||
|
||||
|
||||
private String generateTitle(int languageId) {
|
||||
Language lang = LanguageCollection.getLanguage(languageId);
|
||||
private String generateTitle(Context context, int languageId) {
|
||||
Language lang = LanguageCollection.getLanguage(context, languageId);
|
||||
|
||||
if (lang != null) {
|
||||
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) {
|
||||
hide();
|
||||
isStopped = true;
|
||||
|
|
@ -154,12 +156,12 @@ public class DictionaryLoadingBar {
|
|||
|
||||
if (progress >= maxProgress) {
|
||||
progress = maxProgress = 0;
|
||||
title = generateTitle(-1);
|
||||
title = generateTitle(context, -1);
|
||||
|
||||
String timeFormat = time > 60000 ? " (%1.0fs)" : " (%1.1fs)";
|
||||
message = resources.getString(R.string.completed) + String.format(Locale.ENGLISH, timeFormat, time / 1000.0);
|
||||
} else {
|
||||
title = generateTitle(languageId);
|
||||
title = generateTitle(context, languageId);
|
||||
message = currentFileProgress + "%";
|
||||
}
|
||||
|
||||
|
|
@ -167,8 +169,8 @@ public class DictionaryLoadingBar {
|
|||
}
|
||||
|
||||
|
||||
private void showError(String errorType, int langId, long line, String word) {
|
||||
Language lang = LanguageCollection.getLanguage(langId);
|
||||
private void showError(Context context, String errorType, int langId, long line, String word) {
|
||||
Language lang = LanguageCollection.getLanguage(context, langId);
|
||||
|
||||
if (lang == null || errorType.equals(InvalidLanguageException.class.getSimpleName())) {
|
||||
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);
|
||||
}
|
||||
|
||||
title = generateTitle(-1);
|
||||
title = generateTitle(context, -1);
|
||||
progress = maxProgress = 0;
|
||||
|
||||
renderError();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package io.github.sspanak.tt9.ui;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Looper;
|
||||
|
|
@ -27,6 +28,15 @@ public class UI {
|
|||
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) {
|
||||
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ public class SoftNumberKey extends SoftKey {
|
|||
}
|
||||
|
||||
// 2-9
|
||||
Language language = LanguageCollection.getLanguage(tt9.getSettings().getInputLanguage());
|
||||
Language language = LanguageCollection.getLanguage(tt9.getApplicationContext(), tt9.getSettings().getInputLanguage());
|
||||
if (language == null) {
|
||||
Logger.d("SoftNumberKey.getLabel", "Cannot generate a label when the language is NULL.");
|
||||
return "";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue