New dictionary loader (#89)
* new, simpler (and hopefully, more efficient) dictionary loader * no more dict.properties * dictionaries are now validated during the build process * TraditionalT9Settings code cleanup and code style improvements * removed English, French, Italian, Russian repeating words * removed invalid and repeating German words
This commit is contained in:
parent
0ac7ec1790
commit
10099f1c37
24 changed files with 534 additions and 1855 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -24,7 +24,6 @@ local.properties
|
||||||
*.log
|
*.log
|
||||||
|
|
||||||
#Other
|
#Other
|
||||||
assets/dict.properties
|
|
||||||
t9build.properties
|
t9build.properties
|
||||||
*.keystore
|
*.keystore
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -25,7 +25,6 @@ ma
|
||||||
md
|
md
|
||||||
mi
|
mi
|
||||||
mo
|
mo
|
||||||
ms
|
|
||||||
may
|
may
|
||||||
mr
|
mr
|
||||||
mrs
|
mrs
|
||||||
|
|
@ -145,7 +144,6 @@ cow
|
||||||
cox
|
cox
|
||||||
coy
|
coy
|
||||||
cry
|
cry
|
||||||
cs
|
|
||||||
cub
|
cub
|
||||||
cue
|
cue
|
||||||
cum
|
cum
|
||||||
|
|
@ -236,7 +234,6 @@ gin
|
||||||
gnu
|
gnu
|
||||||
go
|
go
|
||||||
gob
|
gob
|
||||||
god
|
|
||||||
goo
|
goo
|
||||||
got
|
got
|
||||||
gum
|
gum
|
||||||
|
|
@ -278,7 +275,6 @@ hum
|
||||||
hut
|
hut
|
||||||
ice
|
ice
|
||||||
icy
|
icy
|
||||||
id
|
|
||||||
if
|
if
|
||||||
ifs
|
ifs
|
||||||
ilk
|
ilk
|
||||||
|
|
@ -336,14 +332,12 @@ lot
|
||||||
low
|
low
|
||||||
lug
|
lug
|
||||||
lye
|
lye
|
||||||
ma
|
|
||||||
mad
|
mad
|
||||||
man
|
man
|
||||||
map
|
map
|
||||||
mar
|
mar
|
||||||
mas
|
mas
|
||||||
mat
|
mat
|
||||||
may
|
|
||||||
me
|
me
|
||||||
men
|
men
|
||||||
mes
|
mes
|
||||||
|
|
@ -356,7 +350,6 @@ mom
|
||||||
moo
|
moo
|
||||||
mop
|
mop
|
||||||
mow
|
mow
|
||||||
ms
|
|
||||||
mu
|
mu
|
||||||
mud
|
mud
|
||||||
mug
|
mug
|
||||||
|
|
@ -396,7 +389,6 @@ old
|
||||||
on
|
on
|
||||||
one
|
one
|
||||||
opt
|
opt
|
||||||
or
|
|
||||||
ore
|
ore
|
||||||
our
|
our
|
||||||
out
|
out
|
||||||
|
|
@ -405,7 +397,6 @@ owe
|
||||||
owl
|
owl
|
||||||
own
|
own
|
||||||
ox
|
ox
|
||||||
pa
|
|
||||||
pad
|
pad
|
||||||
pal
|
pal
|
||||||
pan
|
pan
|
||||||
|
|
|
||||||
|
|
@ -141541,9 +141541,7 @@ esquilles
|
||||||
Esquimau
|
Esquimau
|
||||||
esquimaud
|
esquimaud
|
||||||
esquimaude
|
esquimaude
|
||||||
Esquimaude
|
|
||||||
esquimaudes
|
esquimaudes
|
||||||
Esquimaudes
|
|
||||||
esquimauds
|
esquimauds
|
||||||
esquimautage
|
esquimautage
|
||||||
esquimautages
|
esquimautages
|
||||||
|
|
@ -186709,7 +186707,6 @@ interneront
|
||||||
internes
|
internes
|
||||||
internés
|
internés
|
||||||
internet
|
internet
|
||||||
Internet
|
|
||||||
internez
|
internez
|
||||||
interniez
|
interniez
|
||||||
internions
|
internions
|
||||||
|
|
@ -215758,7 +215755,6 @@ naphtes
|
||||||
naphtol
|
naphtol
|
||||||
naphtols
|
naphtols
|
||||||
napoléon
|
napoléon
|
||||||
Napoléon
|
|
||||||
napoléonien
|
napoléonien
|
||||||
napoléonienne
|
napoléonienne
|
||||||
napoléoniennes
|
napoléoniennes
|
||||||
|
|
|
||||||
|
|
@ -1707,7 +1707,6 @@ Courmayeur
|
||||||
Cremona
|
Cremona
|
||||||
Cristina
|
Cristina
|
||||||
Cristoforo
|
Cristoforo
|
||||||
DOS
|
|
||||||
DVI
|
DVI
|
||||||
Daniele
|
Daniele
|
||||||
Dante
|
Dante
|
||||||
|
|
@ -1740,7 +1739,6 @@ Euripide
|
||||||
Europa
|
Europa
|
||||||
Eusebio
|
Eusebio
|
||||||
Eva
|
Eva
|
||||||
FAQ
|
|
||||||
FSF
|
FSF
|
||||||
Fabio
|
Fabio
|
||||||
Faenza
|
Faenza
|
||||||
|
|
@ -102310,7 +102308,6 @@ tosavano
|
||||||
tosavate
|
tosavate
|
||||||
tosavi
|
tosavi
|
||||||
tosavo
|
tosavo
|
||||||
toscana
|
|
||||||
toscane
|
toscane
|
||||||
toscani
|
toscani
|
||||||
toscano
|
toscano
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,25 @@
|
||||||
и
|
|
||||||
в
|
|
||||||
не
|
не
|
||||||
на
|
на
|
||||||
я
|
|
||||||
что
|
что
|
||||||
быть
|
быть
|
||||||
с
|
|
||||||
он
|
он
|
||||||
а
|
|
||||||
это
|
это
|
||||||
как
|
как
|
||||||
то
|
то
|
||||||
этот
|
этот
|
||||||
по
|
по
|
||||||
к
|
|
||||||
но
|
но
|
||||||
они
|
они
|
||||||
мы
|
мы
|
||||||
она
|
она
|
||||||
который
|
который
|
||||||
из
|
из
|
||||||
у
|
|
||||||
свой
|
свой
|
||||||
вы
|
вы
|
||||||
весь
|
весь
|
||||||
за
|
за
|
||||||
для
|
для
|
||||||
от
|
от
|
||||||
о
|
|
||||||
так
|
так
|
||||||
мочь
|
мочь
|
||||||
все
|
все
|
||||||
|
|
@ -167,7 +159,6 @@
|
||||||
поэтому
|
поэтому
|
||||||
почему
|
почему
|
||||||
понимать
|
понимать
|
||||||
москва
|
|
||||||
любой
|
любой
|
||||||
однако
|
однако
|
||||||
хорошо
|
хорошо
|
||||||
|
|
@ -351,7 +342,6 @@
|
||||||
появиться
|
появиться
|
||||||
хотеться
|
хотеться
|
||||||
нельзя
|
нельзя
|
||||||
д
|
|
||||||
белый
|
белый
|
||||||
центр
|
центр
|
||||||
опять
|
опять
|
||||||
|
|
@ -400,7 +390,6 @@
|
||||||
быстро
|
быстро
|
||||||
черный
|
черный
|
||||||
сильный
|
сильный
|
||||||
н
|
|
||||||
порядок
|
порядок
|
||||||
чувствовать
|
чувствовать
|
||||||
создать
|
создать
|
||||||
|
|
@ -487,7 +476,6 @@
|
||||||
возможно
|
возможно
|
||||||
принимать
|
принимать
|
||||||
рубль
|
рубль
|
||||||
б
|
|
||||||
миллион
|
миллион
|
||||||
целый
|
целый
|
||||||
приходить
|
приходить
|
||||||
|
|
@ -529,7 +517,6 @@
|
||||||
пара
|
пара
|
||||||
квартира
|
квартира
|
||||||
забыть
|
забыть
|
||||||
е
|
|
||||||
значение
|
значение
|
||||||
внутренний
|
внутренний
|
||||||
связать
|
связать
|
||||||
|
|
@ -577,7 +564,6 @@
|
||||||
команда
|
команда
|
||||||
добрый
|
добрый
|
||||||
поле
|
поле
|
||||||
г
|
|
||||||
сша
|
сша
|
||||||
исследование
|
исследование
|
||||||
общественный
|
общественный
|
||||||
|
|
@ -591,7 +577,6 @@
|
||||||
сон
|
сон
|
||||||
уходить
|
уходить
|
||||||
служба
|
служба
|
||||||
ж
|
|
||||||
население
|
население
|
||||||
воздух
|
воздух
|
||||||
словно
|
словно
|
||||||
|
|
@ -616,7 +601,6 @@
|
||||||
орган
|
орган
|
||||||
доллар
|
доллар
|
||||||
держать
|
держать
|
||||||
т
|
|
||||||
название
|
название
|
||||||
похожий
|
похожий
|
||||||
дорогой
|
дорогой
|
||||||
|
|
@ -703,7 +687,6 @@
|
||||||
поздний
|
поздний
|
||||||
песня
|
песня
|
||||||
лучше
|
лучше
|
||||||
п
|
|
||||||
случиться
|
случиться
|
||||||
ум
|
ум
|
||||||
выбор
|
выбор
|
||||||
|
|
@ -785,7 +768,6 @@
|
||||||
чтоб
|
чтоб
|
||||||
прошлый
|
прошлый
|
||||||
столько
|
столько
|
||||||
л
|
|
||||||
понятие
|
понятие
|
||||||
длинный
|
длинный
|
||||||
поддержка
|
поддержка
|
||||||
|
|
@ -963,7 +945,6 @@
|
||||||
хватать
|
хватать
|
||||||
вчера
|
вчера
|
||||||
режим
|
режим
|
||||||
р
|
|
||||||
очередной
|
очередной
|
||||||
отдать
|
отдать
|
||||||
здоровье
|
здоровье
|
||||||
|
|
@ -1145,7 +1126,6 @@
|
||||||
утверждать
|
утверждать
|
||||||
позвонить
|
позвонить
|
||||||
реклама
|
реклама
|
||||||
николай
|
|
||||||
революция
|
революция
|
||||||
явление
|
явление
|
||||||
отдел
|
отдел
|
||||||
|
|
@ -1405,7 +1385,6 @@
|
||||||
бедный
|
бедный
|
||||||
появление
|
появление
|
||||||
издание
|
издание
|
||||||
э
|
|
||||||
резко
|
резко
|
||||||
поговорить
|
поговорить
|
||||||
еврей
|
еврей
|
||||||
|
|
@ -1436,7 +1415,6 @@
|
||||||
достигнуть
|
достигнуть
|
||||||
сохранить
|
сохранить
|
||||||
встретиться
|
встретиться
|
||||||
ю
|
|
||||||
предполагать
|
предполагать
|
||||||
глубина
|
глубина
|
||||||
приказ
|
приказ
|
||||||
|
|
@ -1552,7 +1530,6 @@
|
||||||
понятно
|
понятно
|
||||||
уважение
|
уважение
|
||||||
последствие
|
последствие
|
||||||
ф
|
|
||||||
буква
|
буква
|
||||||
изображение
|
изображение
|
||||||
творческий
|
творческий
|
||||||
|
|
@ -1595,7 +1572,6 @@
|
||||||
обед
|
обед
|
||||||
переходить
|
переходить
|
||||||
изучение
|
изучение
|
||||||
олег
|
|
||||||
обеспечивать
|
обеспечивать
|
||||||
заставлять
|
заставлять
|
||||||
подниматься
|
подниматься
|
||||||
|
|
@ -1826,7 +1802,6 @@
|
||||||
публикация
|
публикация
|
||||||
кивнуть
|
кивнуть
|
||||||
обсуждать
|
обсуждать
|
||||||
х
|
|
||||||
наверняка
|
наверняка
|
||||||
напомнить
|
напомнить
|
||||||
логика
|
логика
|
||||||
|
|
@ -1865,7 +1840,6 @@
|
||||||
кошка
|
кошка
|
||||||
саша
|
саша
|
||||||
характерный
|
характерный
|
||||||
мария
|
|
||||||
толстый
|
толстый
|
||||||
общаться
|
общаться
|
||||||
пятый
|
пятый
|
||||||
|
|
@ -2591,7 +2565,6 @@
|
||||||
набрать
|
набрать
|
||||||
защитить
|
защитить
|
||||||
остановка
|
остановка
|
||||||
з
|
|
||||||
дорого
|
дорого
|
||||||
какую-то
|
какую-то
|
||||||
жестокий
|
жестокий
|
||||||
|
|
@ -2779,7 +2752,6 @@
|
||||||
разнообразный
|
разнообразный
|
||||||
отойти
|
отойти
|
||||||
разделить
|
разделить
|
||||||
ы
|
|
||||||
сборник
|
сборник
|
||||||
глобальный
|
глобальный
|
||||||
кафе
|
кафе
|
||||||
|
|
@ -2816,7 +2788,6 @@
|
||||||
великолепный
|
великолепный
|
||||||
доходить
|
доходить
|
||||||
образовать
|
образовать
|
||||||
наталья
|
|
||||||
разрушить
|
разрушить
|
||||||
отражать
|
отражать
|
||||||
лезть
|
лезть
|
||||||
|
|
@ -3781,10 +3752,8 @@
|
||||||
симпатичный
|
симпатичный
|
||||||
сделаться
|
сделаться
|
||||||
продаваться
|
продаваться
|
||||||
ш
|
|
||||||
направляться
|
направляться
|
||||||
предупреждать
|
предупреждать
|
||||||
ч
|
|
||||||
благоприятный
|
благоприятный
|
||||||
палка
|
палка
|
||||||
выдающийся
|
выдающийся
|
||||||
|
|
@ -4016,7 +3985,6 @@
|
||||||
рыцарь
|
рыцарь
|
||||||
дежурный
|
дежурный
|
||||||
отрицать
|
отрицать
|
||||||
светлана
|
|
||||||
выделяться
|
выделяться
|
||||||
частица
|
частица
|
||||||
динамика
|
динамика
|
||||||
|
|
@ -4276,7 +4244,6 @@
|
||||||
рецепт
|
рецепт
|
||||||
сан
|
сан
|
||||||
махнуть
|
махнуть
|
||||||
соня
|
|
||||||
смесь
|
смесь
|
||||||
творение
|
творение
|
||||||
кредитный
|
кредитный
|
||||||
|
|
@ -4967,7 +4934,6 @@
|
||||||
привязать
|
привязать
|
||||||
издатель
|
издатель
|
||||||
предать
|
предать
|
||||||
й
|
|
||||||
отставка
|
отставка
|
||||||
заголовок
|
заголовок
|
||||||
отступать
|
отступать
|
||||||
|
|
@ -5538,7 +5504,6 @@
|
||||||
как-нибудь
|
как-нибудь
|
||||||
превосходство
|
превосходство
|
||||||
конфета
|
конфета
|
||||||
ь
|
|
||||||
преподавать
|
преподавать
|
||||||
ла
|
ла
|
||||||
грамотный
|
грамотный
|
||||||
|
|
@ -6238,7 +6203,6 @@
|
||||||
даша
|
даша
|
||||||
армянский
|
армянский
|
||||||
замерзнуть
|
замерзнуть
|
||||||
вячеслав
|
|
||||||
фракция
|
фракция
|
||||||
разноцветный
|
разноцветный
|
||||||
гроза
|
гроза
|
||||||
|
|
@ -6250,7 +6214,6 @@
|
||||||
хрупкий
|
хрупкий
|
||||||
выпивать
|
выпивать
|
||||||
напиться
|
напиться
|
||||||
будда
|
|
||||||
октябрьский
|
октябрьский
|
||||||
невыносимый
|
невыносимый
|
||||||
сертификат
|
сертификат
|
||||||
|
|
@ -6601,7 +6564,6 @@
|
||||||
грант
|
грант
|
||||||
выраженный
|
выраженный
|
||||||
слушаться
|
слушаться
|
||||||
ц
|
|
||||||
расстроить
|
расстроить
|
||||||
веселье
|
веселье
|
||||||
жюри
|
жюри
|
||||||
|
|
@ -7004,7 +6966,6 @@
|
||||||
алена
|
алена
|
||||||
подсчет
|
подсчет
|
||||||
профессионально
|
профессионально
|
||||||
оксана
|
|
||||||
погладить
|
погладить
|
||||||
рассыпаться
|
рассыпаться
|
||||||
перебирать
|
перебирать
|
||||||
|
|
@ -7631,7 +7592,6 @@
|
||||||
несомненный
|
несомненный
|
||||||
многократно
|
многократно
|
||||||
выгодно
|
выгодно
|
||||||
санкт-петербург
|
|
||||||
украинец
|
украинец
|
||||||
коварный
|
коварный
|
||||||
аккумулятор
|
аккумулятор
|
||||||
|
|
@ -8657,7 +8617,6 @@
|
||||||
авраам
|
авраам
|
||||||
мэрия
|
мэрия
|
||||||
фуражка
|
фуражка
|
||||||
ё
|
|
||||||
прикол
|
прикол
|
||||||
минуть
|
минуть
|
||||||
яростно
|
яростно
|
||||||
|
|
@ -11523,7 +11482,6 @@
|
||||||
кабинка
|
кабинка
|
||||||
сатурн
|
сатурн
|
||||||
байт
|
байт
|
||||||
м
|
|
||||||
прямоугольный
|
прямоугольный
|
||||||
остыть
|
остыть
|
||||||
смягчить
|
смягчить
|
||||||
|
|
@ -12768,7 +12726,6 @@
|
||||||
разделяться
|
разделяться
|
||||||
конфликтный
|
конфликтный
|
||||||
лыжи
|
лыжи
|
||||||
ванька
|
|
||||||
обосноваться
|
обосноваться
|
||||||
активизация
|
активизация
|
||||||
основополагающий
|
основополагающий
|
||||||
|
|
@ -13204,7 +13161,6 @@
|
||||||
затащить
|
затащить
|
||||||
терапевтический
|
терапевтический
|
||||||
чернокожий
|
чернокожий
|
||||||
ъ
|
|
||||||
челнок
|
челнок
|
||||||
моделировать
|
моделировать
|
||||||
ограбление
|
ограбление
|
||||||
|
|
@ -13526,7 +13482,6 @@
|
||||||
видеокарта
|
видеокарта
|
||||||
выключатель
|
выключатель
|
||||||
росток
|
росток
|
||||||
щ
|
|
||||||
ослаблять
|
ослаблять
|
||||||
безошибочно
|
безошибочно
|
||||||
заикаться
|
заикаться
|
||||||
|
|
@ -14528,7 +14483,6 @@
|
||||||
акцентировать
|
акцентировать
|
||||||
высокотехнологичный
|
высокотехнологичный
|
||||||
невозмутимый
|
невозмутимый
|
||||||
Нина
|
|
||||||
железнодорожник
|
железнодорожник
|
||||||
амулет
|
амулет
|
||||||
дилемма
|
дилемма
|
||||||
|
|
@ -15852,7 +15806,6 @@
|
||||||
никитич
|
никитич
|
||||||
заманить
|
заманить
|
||||||
вмещать
|
вмещать
|
||||||
жигули
|
|
||||||
цыганский
|
цыганский
|
||||||
поразиться
|
поразиться
|
||||||
обсерватория
|
обсерватория
|
||||||
|
|
@ -22020,7 +21973,6 @@
|
||||||
лицезреть
|
лицезреть
|
||||||
никулин
|
никулин
|
||||||
неукоснительно
|
неукоснительно
|
||||||
нельсон
|
|
||||||
понапрасну
|
понапрасну
|
||||||
фанатичный
|
фанатичный
|
||||||
модернизм
|
модернизм
|
||||||
|
|
@ -22864,7 +22816,6 @@
|
||||||
гадина
|
гадина
|
||||||
провиант
|
провиант
|
||||||
лещ
|
лещ
|
||||||
мекка
|
|
||||||
флагманский
|
флагманский
|
||||||
адресоваться
|
адресоваться
|
||||||
внешнеторговый
|
внешнеторговый
|
||||||
|
|
@ -32494,7 +32445,6 @@
|
||||||
холодить
|
холодить
|
||||||
исцелиться
|
исцелиться
|
||||||
дарвиновский
|
дарвиновский
|
||||||
оКсана
|
|
||||||
шайтан
|
шайтан
|
||||||
алешин
|
алешин
|
||||||
объёме
|
объёме
|
||||||
|
|
@ -32893,7 +32843,6 @@
|
||||||
аркадьевна
|
аркадьевна
|
||||||
овсяный
|
овсяный
|
||||||
обвешать
|
обвешать
|
||||||
мАксвелл
|
|
||||||
сплетничать
|
сплетничать
|
||||||
узнаваемость
|
узнаваемость
|
||||||
улать
|
улать
|
||||||
|
|
@ -32995,7 +32944,6 @@
|
||||||
сомать
|
сомать
|
||||||
пунктуальный
|
пунктуальный
|
||||||
фотокорреспондент
|
фотокорреспондент
|
||||||
бояРин
|
|
||||||
отвержение
|
отвержение
|
||||||
философствование
|
философствование
|
||||||
дыгать
|
дыгать
|
||||||
|
|
@ -38746,7 +38694,6 @@
|
||||||
мет
|
мет
|
||||||
кинохроника
|
кинохроника
|
||||||
подложка
|
подложка
|
||||||
бойфренд
|
|
||||||
очиститель
|
очиститель
|
||||||
лёгкостью
|
лёгкостью
|
||||||
голубовато
|
голубовато
|
||||||
|
|
@ -38934,7 +38881,6 @@
|
||||||
петраков
|
петраков
|
||||||
трип
|
трип
|
||||||
маттиас
|
маттиас
|
||||||
кондрат
|
|
||||||
пинг
|
пинг
|
||||||
отписка
|
отписка
|
||||||
фукс
|
фукс
|
||||||
|
|
@ -40162,7 +40108,6 @@
|
||||||
апример
|
апример
|
||||||
чейни
|
чейни
|
||||||
отшатываться
|
отшатываться
|
||||||
серБия
|
|
||||||
столыпинский
|
столыпинский
|
||||||
смердеть
|
смердеть
|
||||||
физкультурник
|
физкультурник
|
||||||
|
|
@ -40898,7 +40843,6 @@
|
||||||
сворачивание
|
сворачивание
|
||||||
дикобраз
|
дикобраз
|
||||||
родин
|
родин
|
||||||
Макар
|
|
||||||
переговорщик
|
переговорщик
|
||||||
чметр
|
чметр
|
||||||
валуй
|
валуй
|
||||||
|
|
@ -41894,7 +41838,6 @@
|
||||||
просечь
|
просечь
|
||||||
ярик
|
ярик
|
||||||
генуэзский
|
генуэзский
|
||||||
Стеб
|
|
||||||
глазастый
|
глазастый
|
||||||
рпг
|
рпг
|
||||||
цыганов
|
цыганов
|
||||||
|
|
@ -44210,7 +44153,6 @@
|
||||||
шпангоут
|
шпангоут
|
||||||
плебисцит
|
плебисцит
|
||||||
наркомафия
|
наркомафия
|
||||||
Бойфренд
|
|
||||||
лавчонка
|
лавчонка
|
||||||
джеми
|
джеми
|
||||||
проверенный
|
проверенный
|
||||||
|
|
@ -45721,7 +45663,6 @@
|
||||||
стройно
|
стройно
|
||||||
неход
|
неход
|
||||||
несоизмеримый
|
несоизмеримый
|
||||||
Спорткомплекс
|
|
||||||
усреднение
|
усреднение
|
||||||
конвульсии
|
конвульсии
|
||||||
саров
|
саров
|
||||||
|
|
@ -45832,7 +45773,6 @@
|
||||||
авитаминоз
|
авитаминоз
|
||||||
прополоскать
|
прополоскать
|
||||||
порыбачить
|
порыбачить
|
||||||
Понт
|
|
||||||
топологический
|
топологический
|
||||||
хромовый
|
хромовый
|
||||||
аутотренинг
|
аутотренинг
|
||||||
|
|
@ -47174,7 +47114,6 @@
|
||||||
пятикратный
|
пятикратный
|
||||||
интеллектуальность
|
интеллектуальность
|
||||||
пва
|
пва
|
||||||
евроремонт
|
|
||||||
маканин
|
маканин
|
||||||
окопчик
|
окопчик
|
||||||
твердышев
|
твердышев
|
||||||
|
|
@ -54281,7 +54220,6 @@
|
||||||
карканье
|
карканье
|
||||||
пасторский
|
пасторский
|
||||||
виан
|
виан
|
||||||
перегРин
|
|
||||||
тоить
|
тоить
|
||||||
окунев
|
окунев
|
||||||
юхан
|
юхан
|
||||||
|
|
@ -54906,7 +54844,6 @@
|
||||||
измор
|
измор
|
||||||
трый
|
трый
|
||||||
шляхетский
|
шляхетский
|
||||||
бРин
|
|
||||||
лима
|
лима
|
||||||
нестроевой
|
нестроевой
|
||||||
суннитский
|
суннитский
|
||||||
|
|
@ -55758,7 +55695,6 @@
|
||||||
пиноккио
|
пиноккио
|
||||||
идиотический
|
идиотический
|
||||||
ереть
|
ереть
|
||||||
Клава
|
|
||||||
послепродажный
|
послепродажный
|
||||||
бревна
|
бревна
|
||||||
несомнить
|
несомнить
|
||||||
|
|
@ -56484,7 +56420,6 @@
|
||||||
жосслить
|
жосслить
|
||||||
полтонна
|
полтонна
|
||||||
комбо
|
комбо
|
||||||
Метрострой
|
|
||||||
мелеть
|
мелеть
|
||||||
руга
|
руга
|
||||||
антропософия
|
антропософия
|
||||||
|
|
@ -59199,7 +59134,6 @@
|
||||||
зульфия
|
зульфия
|
||||||
фотокросс
|
фотокросс
|
||||||
провинциализм
|
провинциализм
|
||||||
кордицеПС
|
|
||||||
комендантша
|
комендантша
|
||||||
луковский
|
луковский
|
||||||
аудить
|
аудить
|
||||||
|
|
@ -61891,7 +61825,6 @@
|
||||||
хайти
|
хайти
|
||||||
кворт
|
кворт
|
||||||
пупка
|
пупка
|
||||||
Таврия
|
|
||||||
мирье
|
мирье
|
||||||
исподний
|
исподний
|
||||||
видеопрокат
|
видеопрокат
|
||||||
|
|
@ -63203,7 +63136,7 @@
|
||||||
флорентино
|
флорентино
|
||||||
сагитировать
|
сагитировать
|
||||||
долан
|
долан
|
||||||
санкт-Петербург
|
Санкт-Петербург
|
||||||
салаг
|
салаг
|
||||||
засека
|
засека
|
||||||
батюшок
|
батюшок
|
||||||
|
|
@ -63405,7 +63338,6 @@
|
||||||
пакля
|
пакля
|
||||||
заартачиться
|
заартачиться
|
||||||
лайдекер
|
лайдекер
|
||||||
гРин
|
|
||||||
агатовый
|
агатовый
|
||||||
микросекунда
|
микросекунда
|
||||||
брыззать
|
брыззать
|
||||||
|
|
@ -63460,7 +63392,6 @@
|
||||||
субара
|
субара
|
||||||
пожестче
|
пожестче
|
||||||
омоним
|
омоним
|
||||||
Евроремонт
|
|
||||||
амбиз
|
амбиз
|
||||||
йцукен
|
йцукен
|
||||||
долби
|
долби
|
||||||
|
|
@ -69811,7 +69742,6 @@
|
||||||
еврисфей
|
еврисфей
|
||||||
браунли
|
браунли
|
||||||
возьаться
|
возьаться
|
||||||
Казанцев
|
|
||||||
задержки
|
задержки
|
||||||
портфельчик
|
портфельчик
|
||||||
неумолимость
|
неумолимость
|
||||||
|
|
@ -74213,7 +74143,6 @@
|
||||||
социобиология
|
социобиология
|
||||||
взбрыкивать
|
взбрыкивать
|
||||||
чёткость
|
чёткость
|
||||||
Экспоцентр
|
|
||||||
засекречивание
|
засекречивание
|
||||||
бомжик
|
бомжик
|
||||||
хамар
|
хамар
|
||||||
|
|
@ -78233,7 +78162,6 @@
|
||||||
войт
|
войт
|
||||||
эндорэ
|
эндорэ
|
||||||
окк
|
окк
|
||||||
Автосервис
|
|
||||||
бандеровский
|
бандеровский
|
||||||
правдин
|
правдин
|
||||||
обрисовываться
|
обрисовываться
|
||||||
|
|
@ -81985,7 +81913,6 @@
|
||||||
цаостров
|
цаостров
|
||||||
гафгарьон
|
гафгарьон
|
||||||
астрорунет
|
астрорунет
|
||||||
мэйРин
|
|
||||||
промаркировать
|
промаркировать
|
||||||
дегтяренко
|
дегтяренко
|
||||||
четвёрки
|
четвёрки
|
||||||
|
|
@ -84423,7 +84350,6 @@
|
||||||
оршанский
|
оршанский
|
||||||
карачевский
|
карачевский
|
||||||
неизменять
|
неизменять
|
||||||
Минздрав
|
|
||||||
чулка
|
чулка
|
||||||
трехосный
|
трехосный
|
||||||
четать
|
четать
|
||||||
|
|
|
||||||
41
build.gradle
41
build.gradle
|
|
@ -106,20 +106,47 @@ android {
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
task getDictSizes {
|
task validateDictionaries {
|
||||||
inputs.dir fileTree(dir:'assets', excludes:['dict.properties'])
|
inputs.dir fileTree(dir:'assets', excludes:['dict.properties'])
|
||||||
outputs.file "t9build.properties"
|
outputs.file "t9build.properties"
|
||||||
doLast {
|
doLast {
|
||||||
println "Calculating dict size..."
|
String errors = "";
|
||||||
|
|
||||||
inputs.getFiles().each {File file ->
|
inputs.getFiles().each {File file ->
|
||||||
println "dict: "+ file.name
|
println "Validating dictionary: " + file.name
|
||||||
ant.propertyfile(file:"assets/dict.properties") {
|
|
||||||
entry(key: "size."+ file.name, value: file.length())
|
def geographicalName = ~"[A-Z]\\w+-[^\\n]+"
|
||||||
|
def uniqueWords = [:]
|
||||||
|
|
||||||
|
int lineNumber = 0
|
||||||
|
file.eachLine {line ->
|
||||||
|
lineNumber++
|
||||||
|
if (line.matches("\\d")) {
|
||||||
|
errors += "Dictionary '" + file.name + "' is invalid. Found numbers on line " + lineNumber + ". Please, remove all numbers.\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (line.matches("^\\P{L}+\$")) {
|
||||||
|
errors += "Dictionary '" + file.name + "' is invalid. Found a garbage word: '" + line + "' on line " + lineNumber + ".\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.matches("^.\$")) {
|
||||||
|
errors += "Dictionary '" + file.name + "' is invalid. Found a single letter: '" + line + "' on line " + lineNumber + ". Remove all single letters. The alphabet will be added automatically.\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
String uniqueWordKey = line ==~ geographicalName ? line : line.toLowerCase()
|
||||||
|
if (uniqueWords[uniqueWordKey] != null && uniqueWords[uniqueWordKey] == true) {
|
||||||
|
errors += "Dictionary '" + file.name + "' is invalid. Found a repeating word: '" + line + "' on line " + lineNumber + ". Ensure all words appear only once.\n"
|
||||||
|
} else {
|
||||||
|
uniqueWords[uniqueWordKey] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
preBuild.dependsOn getDictSizes
|
if (errors != "") {
|
||||||
preBuild.mustRunAfter getDictSizes
|
throw new GradleException(errors)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
preBuild.dependsOn validateDictionaries
|
||||||
|
preBuild.mustRunAfter validateDictionaries
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,11 @@
|
||||||
<string name="pref_loaduserdict">Зареди свой речник</string>
|
<string name="pref_loaduserdict">Зареди свой речник</string>
|
||||||
<string name="pref_truncatedict">Изтрий речник</string>
|
<string name="pref_truncatedict">Изтрий речник</string>
|
||||||
|
|
||||||
<string name="dictionary_loading">Зареждане на речник…</string>
|
<string name="dictionary_import_bad_char">Неуспешно зареждане. Невалидна дума \"%1$s\" на ред %2$d за език \"%3$s\".</string>
|
||||||
|
<string name="dictionary_import_error">Несупешно зареждане на речник за език \"%1$s\" (%2$s).</string>
|
||||||
|
<string name="dictionary_loading">Зареждане на речник (%1$s)…</string>
|
||||||
<string name="dictionary_loading_user_dict">Зареждане на вашия речник…</string>
|
<string name="dictionary_loading_user_dict">Зареждане на вашия речник…</string>
|
||||||
<string name="dictionary_load_title">Зареди речник</string>
|
<string name="dictionary_load_title">Зареждане на речник</string>
|
||||||
<string name="dictionary_not_found">Неуспешно зареждане. Липсва речник за %1$s.</string>
|
<string name="dictionary_not_found">Неуспешно зареждане. Липсва речник за \"%1$s\".</string>
|
||||||
<string name="dictionary_truncated">Речникът е изтрит успешно</string>
|
<string name="dictionary_truncated">Речникът е изтрит успешно</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,10 @@
|
||||||
<string name="pref_choose_languages">Sprachen</string>
|
<string name="pref_choose_languages">Sprachen</string>
|
||||||
<string name="pref_loaddict">Wörterbuch laden</string>
|
<string name="pref_loaddict">Wörterbuch laden</string>
|
||||||
<string name="pref_loaduserdict">Benutzerwörterbuch laden</string>
|
<string name="pref_loaduserdict">Benutzerwörterbuch laden</string>
|
||||||
|
<string name="pref_truncatedict">Wörterbuch löschen</string>
|
||||||
|
|
||||||
<string name="dictionary_loading">Lade Wörterbuch…</string>
|
<string name="dictionary_loading">Lade Wörterbuch (%1$s)…</string>
|
||||||
<string name="dictionary_loading_user_dict">Lade Benutzerwörterbuch…</string>
|
<string name="dictionary_loading_user_dict">Lade Benutzerwörterbuch…</string>
|
||||||
<string name="dictionary_load_title">Wörterbuch laden</string>
|
<string name="dictionary_load_title">Wörterbuch laden</string>
|
||||||
<string name="dictionary_not_found">Wird nicht geladen. Wörterbuch für %1$s nicht gefunden.</string>
|
<string name="dictionary_not_found">Wird nicht geladen. Wörterbuch für \"%1$s\" nicht gefunden.</string>
|
||||||
<string name="pref_truncatedict">Wörterbuch löschen</string>
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,11 @@
|
||||||
<string name="pref_choose_languages">Choisir langues</string>
|
<string name="pref_choose_languages">Choisir langues</string>
|
||||||
<string name="pref_loaddict">Charger le dictionnaire</string>
|
<string name="pref_loaddict">Charger le dictionnaire</string>
|
||||||
<string name="pref_loaduserdict">Charger le dictionnaire utilisateur</string>
|
<string name="pref_loaduserdict">Charger le dictionnaire utilisateur</string>
|
||||||
|
<string name="pref_truncatedict">Supprimer le dictionaire</string>
|
||||||
|
|
||||||
<string name="dictionary_loading">Chargement du dictionnaire…</string>
|
<string name="dictionary_import_error">Echec du chargement de dictionnaire pour langue «%1$s» (%2$s).</string>
|
||||||
|
<string name="dictionary_loading">Chargement du dictionnaire (%1$s)…</string>
|
||||||
<string name="dictionary_loading_user_dict">Chargement du dictionnaire utilisateur…</string>
|
<string name="dictionary_loading_user_dict">Chargement du dictionnaire utilisateur…</string>
|
||||||
<string name="dictionary_load_title">Charger le dictionnaire</string>
|
<string name="dictionary_load_title">Charger le dictionnaire</string>
|
||||||
<string name="dictionary_not_found">Echec du chargement. Dictionnaire %1$s introuvable.</string>
|
<string name="dictionary_not_found">Echec du chargement. Dictionnaire «%1$s» introuvable.</string>
|
||||||
<string name="pref_truncatedict">Supprimer le dictionaire</string>
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,11 @@
|
||||||
<string name="pref_choose_languages">Le lingue</string>
|
<string name="pref_choose_languages">Le lingue</string>
|
||||||
<string name="pref_loaddict">Carica dizionario</string>
|
<string name="pref_loaddict">Carica dizionario</string>
|
||||||
<string name="pref_loaduserdict">Carica dizionario utente</string>
|
<string name="pref_loaduserdict">Carica dizionario utente</string>
|
||||||
|
<string name="pref_truncatedict">Eliminare il dizionario</string>
|
||||||
|
|
||||||
<string name="dictionary_loading">Caricamento dizionario…</string>
|
<string name="dictionary_loading">Caricamento dizionario (%1$s)…</string>
|
||||||
<string name="dictionary_loading_user_dict">Caricamento dizionario utente…</string>
|
<string name="dictionary_loading_user_dict">Caricamento dizionario utente…</string>
|
||||||
<string name="dictionary_load_title">Caricamento dizionario</string>
|
<string name="dictionary_load_title">Caricamento dizionario</string>
|
||||||
<string name="dictionary_not_found">Impossibile caricare. Dizionario per %1$s non trovato.</string>
|
<string name="dictionary_not_found">Impossibile caricare. Dizionario per “%1$s” non trovato.</string>
|
||||||
<string name="pref_truncatedict">Eliminare il dizionario</string>
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,10 @@
|
||||||
<string name="pref_loaduserdict">Загрузить свой словарь</string>
|
<string name="pref_loaduserdict">Загрузить свой словарь</string>
|
||||||
<string name="pref_truncatedict">Очистить словарь</string>
|
<string name="pref_truncatedict">Очистить словарь</string>
|
||||||
|
|
||||||
<string name="dictionary_loading">Загрузка словаря…</string>
|
<string name="dictionary_import_error">Ошибка загрузки словаря для языка «%1$s» (%2$s).</string>
|
||||||
|
<string name="dictionary_loading">Загрузка словаря (%1$s)…</string>
|
||||||
<string name="dictionary_loading_user_dict">Загрузка пользовательского словаря…</string>
|
<string name="dictionary_loading_user_dict">Загрузка пользовательского словаря…</string>
|
||||||
<string name="dictionary_load_title">Загрузить словарь</string>
|
<string name="dictionary_load_title">Загрузить словарь</string>
|
||||||
<string name="dictionary_not_found">Ошибка загрузки. Словарь %1$s не найден.</string>
|
<string name="dictionary_not_found">Ошибка загрузки. Словарь «%1$s» не найден.</string>
|
||||||
<string name="dictionary_truncated">Словарь успешно очищен.</string>
|
<string name="dictionary_truncated">Словарь успешно очищен.</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,11 @@
|
||||||
<string name="pref_choose_languages">Вибір мови</string>
|
<string name="pref_choose_languages">Вибір мови</string>
|
||||||
<string name="pref_loaddict">Завантажити словник</string>
|
<string name="pref_loaddict">Завантажити словник</string>
|
||||||
<string name="pref_loaduserdict">Завантажити свій словник</string>
|
<string name="pref_loaduserdict">Завантажити свій словник</string>
|
||||||
|
<string name="pref_truncatedict">Очистити словник</string>
|
||||||
|
|
||||||
<string name="dictionary_loading">Завантаження словника…</string>
|
<string name="dictionary_import_error">Помилка завантаження словника для мови «%1$s» (%2$s).</string>
|
||||||
|
<string name="dictionary_loading">Завантаження словника (%1$s)…</string>
|
||||||
<string name="dictionary_loading_user_dict">Завантаження словника користувача…</string>
|
<string name="dictionary_loading_user_dict">Завантаження словника користувача…</string>
|
||||||
<string name="dictionary_load_title">Завантажити словник</string>
|
<string name="dictionary_load_title">Завантажити словник</string>
|
||||||
<string name="dictionary_not_found">Помилка завантаження. Словник %1$s не знайдено.</string>
|
<string name="dictionary_not_found">Помилка завантаження. Словник «%1$s» не знайдено.</string>
|
||||||
<string name="pref_truncatedict">Очистити словник</string>
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,11 @@
|
||||||
<string translatable="false" name="pref_loaduserdictdesc">SDcard/traditionalt9/user.lang.dict (lang: en/ru/de/fr)</string>
|
<string translatable="false" name="pref_loaduserdictdesc">SDcard/traditionalt9/user.lang.dict (lang: en/ru/de/fr)</string>
|
||||||
<string name="pref_truncatedict">Clear dictionary</string>
|
<string name="pref_truncatedict">Clear dictionary</string>
|
||||||
|
|
||||||
<string name="dictionary_loading">Loading dictionary…</string>
|
<string name="dictionary_import_bad_char">Loading failed. Invalid word \"%1$s\" on line %2$d of language \"%3$s\".</string>
|
||||||
|
<string name="dictionary_import_error">Failed importing dictionary for language \"%1$s\" (%2$s).</string>
|
||||||
|
<string name="dictionary_loading">Loading dictionary (%1$s)…</string>
|
||||||
<string name="dictionary_loading_user_dict">Loading user dictionary…</string>
|
<string name="dictionary_loading_user_dict">Loading user dictionary…</string>
|
||||||
<string name="dictionary_load_title">Load dictionary</string>
|
<string name="dictionary_load_title">Load dictionary</string>
|
||||||
<string name="dictionary_not_found">Loading failed. Dictionary for %1$s not found.</string>
|
<string name="dictionary_not_found">Loading failed. Dictionary for \"%1$s\" not found.</string>
|
||||||
<string name="dictionary_truncated">Dictionary successfully cleared.</string>
|
<string name="dictionary_truncated">Dictionary successfully cleared.</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ const { basename } = require('path');
|
||||||
const { createReadStream, existsSync } = require('fs');
|
const { createReadStream, existsSync } = require('fs');
|
||||||
|
|
||||||
|
|
||||||
|
const GEO_NAME = /[A-Z]\w+\-[^\n]+/;
|
||||||
|
|
||||||
|
|
||||||
function printHelp() {
|
function printHelp() {
|
||||||
console.log(`Usage ${basename(process.argv[1])} LOCALE FILENAME.txt `);
|
console.log(`Usage ${basename(process.argv[1])} LOCALE FILENAME.txt `);
|
||||||
|
|
@ -28,17 +30,44 @@ function validateInput() {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function getRegularWordKey(locale, word) {
|
||||||
|
if (typeof word !== 'string' || word.length === 0) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return GEO_NAME.test(word) ? word : word.toLocaleLowerCase(locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function getWordKeyPreservingCaptialization(locale, word, wordMap) {
|
||||||
|
if (typeof word !== 'string' || word.length === 0 || typeof wordMap !== 'object') {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
let wordKey = word.toLocaleLowerCase(locale);
|
||||||
|
|
||||||
|
if (GEO_NAME.test(word) || word.toLocaleLowerCase(locale) !== word) {
|
||||||
|
wordKey = word;
|
||||||
|
if (wordMap[word.toLocaleLowerCase(locale)]) {
|
||||||
|
delete wordMap[word.toLocaleLowerCase(locale)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return wordKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async function removeRepeatingWords({ fileName, locale }) {
|
async function removeRepeatingWords({ fileName, locale }) {
|
||||||
const lineReader = require('readline').createInterface({
|
const lineReader = require('readline').createInterface({
|
||||||
input: createReadStream(fileName)
|
input: createReadStream(fileName)
|
||||||
});
|
});
|
||||||
|
|
||||||
const geographicalName = /[A-Z]\w+\-[^\n]+/;
|
|
||||||
const wordMap = {};
|
const wordMap = {};
|
||||||
|
|
||||||
for await (const line of lineReader) {
|
for await (const line of lineReader) {
|
||||||
const wordKey = geographicalName.test(line) ? line : line.toLocaleLowerCase(locale);
|
wordMap[getWordKeyPreservingCaptialization(locale, line, wordMap)] = true;
|
||||||
wordMap[wordKey] = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Object.keys(wordMap);
|
return Object.keys(wordMap);
|
||||||
|
|
@ -57,4 +86,6 @@ function printWords(wordList) {
|
||||||
|
|
||||||
|
|
||||||
/** main **/
|
/** main **/
|
||||||
removeRepeatingWords(validateInput()).then(words => printWords(words));
|
removeRepeatingWords(validateInput())
|
||||||
|
.then(words => printWords(words))
|
||||||
|
.catch(e => console.error(e));
|
||||||
|
|
|
||||||
|
|
@ -1,315 +0,0 @@
|
||||||
/* ____________________________________________________________________________
|
|
||||||
*
|
|
||||||
* File: UnicodeBOMInputStream.java
|
|
||||||
* Author: Gregory Pakosz.
|
|
||||||
* Date: 02 - November - 2005
|
|
||||||
* ____________________________________________________________________________
|
|
||||||
*/
|
|
||||||
package com.stackoverflow.answer;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.PushbackInputStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The <code>UnicodeBOMInputStream</code> class wraps any
|
|
||||||
* <code>InputStream</code> and detects the presence of any Unicode BOM
|
|
||||||
* (Byte Order Mark) at its beginning, as defined by
|
|
||||||
* <a href="http://www.faqs.org/rfcs/rfc3629.html">RFC 3629 - UTF-8, a transformation format of ISO 10646</a>
|
|
||||||
*
|
|
||||||
* <p>The
|
|
||||||
* <a href="http://www.unicode.org/unicode/faq/utf_bom.html">Unicode FAQ</a>
|
|
||||||
* defines 5 types of BOMs:<ul>
|
|
||||||
* <li><pre>00 00 FE FF = UTF-32, big-endian</pre></li>
|
|
||||||
* <li><pre>FF FE 00 00 = UTF-32, little-endian</pre></li>
|
|
||||||
* <li><pre>FE FF = UTF-16, big-endian</pre></li>
|
|
||||||
* <li><pre>FF FE = UTF-16, little-endian</pre></li>
|
|
||||||
* <li><pre>EF BB BF = UTF-8</pre></li>
|
|
||||||
* </ul></p>
|
|
||||||
*
|
|
||||||
* <p>Use the {@link #getBOM()} method to know whether a BOM has been detected
|
|
||||||
* or not.
|
|
||||||
* </p>
|
|
||||||
* <p>Use the {@link #skipBOM()} method to remove the detected BOM from the
|
|
||||||
* wrapped <code>InputStream</code> object.</p>
|
|
||||||
*/
|
|
||||||
public class UnicodeBOMInputStream extends InputStream
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Type safe enumeration class that describes the different types of Unicode
|
|
||||||
* BOMs.
|
|
||||||
*/
|
|
||||||
public static final class BOM
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* NONE.
|
|
||||||
*/
|
|
||||||
public static final BOM NONE = new BOM(new byte[]{},"NONE");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UTF-8 BOM (EF BB BF).
|
|
||||||
*/
|
|
||||||
public static final BOM UTF_8 = new BOM(new byte[]{(byte)0xEF,
|
|
||||||
(byte)0xBB,
|
|
||||||
(byte)0xBF},
|
|
||||||
"UTF-8");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UTF-16, little-endian (FF FE).
|
|
||||||
*/
|
|
||||||
public static final BOM UTF_16_LE = new BOM(new byte[]{ (byte)0xFF,
|
|
||||||
(byte)0xFE},
|
|
||||||
"UTF-16 little-endian");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UTF-16, big-endian (FE FF).
|
|
||||||
*/
|
|
||||||
public static final BOM UTF_16_BE = new BOM(new byte[]{ (byte)0xFE,
|
|
||||||
(byte)0xFF},
|
|
||||||
"UTF-16 big-endian");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UTF-32, little-endian (FF FE 00 00).
|
|
||||||
*/
|
|
||||||
public static final BOM UTF_32_LE = new BOM(new byte[]{ (byte)0xFF,
|
|
||||||
(byte)0xFE,
|
|
||||||
(byte)0x00,
|
|
||||||
(byte)0x00},
|
|
||||||
"UTF-32 little-endian");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UTF-32, big-endian (00 00 FE FF).
|
|
||||||
*/
|
|
||||||
public static final BOM UTF_32_BE = new BOM(new byte[]{ (byte)0x00,
|
|
||||||
(byte)0x00,
|
|
||||||
(byte)0xFE,
|
|
||||||
(byte)0xFF},
|
|
||||||
"UTF-32 big-endian");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a <code>String</code> representation of this <code>BOM</code>
|
|
||||||
* value.
|
|
||||||
*/
|
|
||||||
public final String toString()
|
|
||||||
{
|
|
||||||
return description;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the bytes corresponding to this <code>BOM</code> value.
|
|
||||||
*/
|
|
||||||
public final byte[] getBytes()
|
|
||||||
{
|
|
||||||
final int length = bytes.length;
|
|
||||||
final byte[] result = new byte[length];
|
|
||||||
|
|
||||||
// Make a defensive copy
|
|
||||||
System.arraycopy(bytes,0,result,0,length);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private BOM(final byte bom[], final String description)
|
|
||||||
{
|
|
||||||
assert(bom != null) : "invalid BOM: null is not allowed";
|
|
||||||
assert(description != null) : "invalid description: null is not allowed";
|
|
||||||
assert(description.length() != 0) : "invalid description: empty string is not allowed";
|
|
||||||
|
|
||||||
this.bytes = bom;
|
|
||||||
this.description = description;
|
|
||||||
}
|
|
||||||
|
|
||||||
final byte bytes[];
|
|
||||||
private final String description;
|
|
||||||
|
|
||||||
} // BOM
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a new <code>UnicodeBOMInputStream</code> that wraps the
|
|
||||||
* specified <code>InputStream</code>.
|
|
||||||
*
|
|
||||||
* @param inputStream an <code>InputStream</code>.
|
|
||||||
*
|
|
||||||
* @throws NullPointerException when <code>inputStream</code> is
|
|
||||||
* <code>null</code>.
|
|
||||||
* @throws IOException on reading from the specified <code>InputStream</code>
|
|
||||||
* when trying to detect the Unicode BOM.
|
|
||||||
*/
|
|
||||||
public UnicodeBOMInputStream(final InputStream inputStream) throws NullPointerException,
|
|
||||||
IOException
|
|
||||||
|
|
||||||
{
|
|
||||||
if (inputStream == null)
|
|
||||||
throw new NullPointerException("invalid input stream: null is not allowed");
|
|
||||||
|
|
||||||
in = new PushbackInputStream(inputStream,4);
|
|
||||||
|
|
||||||
final byte bom[] = new byte[4];
|
|
||||||
final int read = in.read(bom);
|
|
||||||
|
|
||||||
switch(read)
|
|
||||||
{
|
|
||||||
case 4:
|
|
||||||
if ((bom[0] == (byte)0xFF) &&
|
|
||||||
(bom[1] == (byte)0xFE) &&
|
|
||||||
(bom[2] == (byte)0x00) &&
|
|
||||||
(bom[3] == (byte)0x00))
|
|
||||||
{
|
|
||||||
this.bom = BOM.UTF_32_LE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if ((bom[0] == (byte)0x00) &&
|
|
||||||
(bom[1] == (byte)0x00) &&
|
|
||||||
(bom[2] == (byte)0xFE) &&
|
|
||||||
(bom[3] == (byte)0xFF))
|
|
||||||
{
|
|
||||||
this.bom = BOM.UTF_32_BE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
if ((bom[0] == (byte)0xEF) &&
|
|
||||||
(bom[1] == (byte)0xBB) &&
|
|
||||||
(bom[2] == (byte)0xBF))
|
|
||||||
{
|
|
||||||
this.bom = BOM.UTF_8;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
if ((bom[0] == (byte)0xFF) &&
|
|
||||||
(bom[1] == (byte)0xFE))
|
|
||||||
{
|
|
||||||
this.bom = BOM.UTF_16_LE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if ((bom[0] == (byte)0xFE) &&
|
|
||||||
(bom[1] == (byte)0xFF))
|
|
||||||
{
|
|
||||||
this.bom = BOM.UTF_16_BE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
this.bom = BOM.NONE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (read > 0)
|
|
||||||
in.unread(bom,0,read);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the <code>BOM</code> that was detected in the wrapped
|
|
||||||
* <code>InputStream</code> object.
|
|
||||||
*
|
|
||||||
* @return a <code>BOM</code> value.
|
|
||||||
*/
|
|
||||||
public final BOM getBOM()
|
|
||||||
{
|
|
||||||
// BOM type is immutable.
|
|
||||||
return bom;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Skips the <code>BOM</code> that was found in the wrapped
|
|
||||||
* <code>InputStream</code> object.
|
|
||||||
*
|
|
||||||
* @return this <code>UnicodeBOMInputStream</code>.
|
|
||||||
*
|
|
||||||
* @throws IOException when trying to skip the BOM from the wrapped
|
|
||||||
* <code>InputStream</code> object.
|
|
||||||
*/
|
|
||||||
public final synchronized UnicodeBOMInputStream skipBOM() throws IOException
|
|
||||||
{
|
|
||||||
if (!skipped)
|
|
||||||
{
|
|
||||||
in.skip(bom.bytes.length);
|
|
||||||
skipped = true;
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public int read() throws IOException
|
|
||||||
{
|
|
||||||
return in.read();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public int read(final byte b[]) throws IOException,
|
|
||||||
NullPointerException
|
|
||||||
{
|
|
||||||
return in.read(b,0,b.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public int read(final byte b[],
|
|
||||||
final int off,
|
|
||||||
final int len) throws IOException,
|
|
||||||
NullPointerException
|
|
||||||
{
|
|
||||||
return in.read(b,off,len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public long skip(final long n) throws IOException
|
|
||||||
{
|
|
||||||
return in.skip(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public int available() throws IOException
|
|
||||||
{
|
|
||||||
return in.available();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public void close() throws IOException
|
|
||||||
{
|
|
||||||
in.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public synchronized void mark(final int readlimit)
|
|
||||||
{
|
|
||||||
in.mark(readlimit);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public synchronized void reset() throws IOException
|
|
||||||
{
|
|
||||||
in.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public boolean markSupported()
|
|
||||||
{
|
|
||||||
return in.markSupported();
|
|
||||||
}
|
|
||||||
|
|
||||||
private final PushbackInputStream in;
|
|
||||||
private final BOM bom;
|
|
||||||
private boolean skipped = false;
|
|
||||||
|
|
||||||
} // UnicodeBOMInputStream
|
|
||||||
|
|
@ -59,16 +59,8 @@ public class DictionaryDb {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void beginTransaction() {
|
public static void runInTransaction(Runnable r) {
|
||||||
getInstance().beginTransaction();
|
getInstance().runInTransaction(r);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static void endTransaction(boolean success) {
|
|
||||||
if (success) {
|
|
||||||
getInstance().setTransactionSuccessful();
|
|
||||||
}
|
|
||||||
getInstance().endTransaction();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
package io.github.sspanak.tt9.db;
|
||||||
|
|
||||||
|
public class DictionaryImportAbortedException extends Exception{
|
||||||
|
public DictionaryImportAbortedException() {
|
||||||
|
super("Dictionary import stopped by request.");
|
||||||
|
}
|
||||||
|
}
|
||||||
14
src/io/github/sspanak/tt9/db/DictionaryImportException.java
Normal file
14
src/io/github/sspanak/tt9/db/DictionaryImportException.java
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
package io.github.sspanak.tt9.db;
|
||||||
|
|
||||||
|
public class DictionaryImportException extends Exception {
|
||||||
|
public final String file;
|
||||||
|
public final String word;
|
||||||
|
public final long line;
|
||||||
|
|
||||||
|
DictionaryImportException(String file, String word, long line) {
|
||||||
|
super("Dictionary import failed");
|
||||||
|
this.file = file;
|
||||||
|
this.word = word;
|
||||||
|
this.line = line;
|
||||||
|
}
|
||||||
|
}
|
||||||
259
src/io/github/sspanak/tt9/db/DictionaryLoader.java
Normal file
259
src/io/github/sspanak/tt9/db/DictionaryLoader.java
Normal file
|
|
@ -0,0 +1,259 @@
|
||||||
|
package io.github.sspanak.tt9.db;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.AssetManager;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.LineNumberReader;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import io.github.sspanak.tt9.Logger;
|
||||||
|
import io.github.sspanak.tt9.languages.InvalidLanguageCharactersException;
|
||||||
|
import io.github.sspanak.tt9.languages.InvalidLanguageException;
|
||||||
|
import io.github.sspanak.tt9.languages.Language;
|
||||||
|
import io.github.sspanak.tt9.preferences.T9Preferences;
|
||||||
|
|
||||||
|
public class DictionaryLoader {
|
||||||
|
private final AssetManager assets;
|
||||||
|
private final T9Preferences prefs;
|
||||||
|
|
||||||
|
private boolean isStopped = true;
|
||||||
|
private int currentFile = 0;
|
||||||
|
private long lastProgressUpdate = 0;
|
||||||
|
|
||||||
|
private final Pattern containsPunctuation = Pattern.compile("\\p{Punct}(?<!-)");
|
||||||
|
|
||||||
|
public DictionaryLoader(Context context) {
|
||||||
|
assets = context.getAssets();
|
||||||
|
prefs = T9Preferences.getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void load(Handler handler, ArrayList<Language> languages) {
|
||||||
|
new Thread() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
currentFile = 0;
|
||||||
|
isStopped = false;
|
||||||
|
// SQLite does not support parallel queries, so let's import them one by one
|
||||||
|
for (Language lang : languages) {
|
||||||
|
if (isStopped) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
importAll(handler, lang);
|
||||||
|
currentFile++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
isStopped = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void importAll(Handler handler, Language language) {
|
||||||
|
final String logTag = "tt9.DictionaryLoader.importAll";
|
||||||
|
|
||||||
|
if (language == null) {
|
||||||
|
Logger.e(logTag, "Failed loading a dictionary for NULL language.");
|
||||||
|
sendError(handler, InvalidLanguageException.class.getSimpleName(), -1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DictionaryDb.runInTransaction(() -> {
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
importLetters(language);
|
||||||
|
Logger.i(
|
||||||
|
logTag,
|
||||||
|
"Loaded letters for '" + language.getName() + "' language in: " + (System.currentTimeMillis() - start) + " ms"
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
start = System.currentTimeMillis();
|
||||||
|
importWords(handler, language);
|
||||||
|
Logger.i(
|
||||||
|
logTag,
|
||||||
|
"Dictionary: '" + language.getDictionaryFile() + "'" +
|
||||||
|
" processing time: " + (System.currentTimeMillis() - start) + " ms"
|
||||||
|
);
|
||||||
|
} catch (DictionaryImportAbortedException e) {
|
||||||
|
stop();
|
||||||
|
|
||||||
|
Logger.i(
|
||||||
|
logTag,
|
||||||
|
e.getMessage() + ". File '" + language.getDictionaryFile() + "' not imported."
|
||||||
|
);
|
||||||
|
} catch (DictionaryImportException e) {
|
||||||
|
stop();
|
||||||
|
sendImportError(handler, DictionaryImportException.class.getSimpleName(), language.getId(), e.line, e.word);
|
||||||
|
|
||||||
|
Logger.e(
|
||||||
|
logTag,
|
||||||
|
" Invalid word: '" + e.word
|
||||||
|
+ "' in dictionary: '" + language.getDictionaryFile() + "'"
|
||||||
|
+ " on line " + e.line
|
||||||
|
+ " of language '" + language.getName() + "'. "
|
||||||
|
+ e.getMessage()
|
||||||
|
);
|
||||||
|
} catch (Exception e) {
|
||||||
|
stop();
|
||||||
|
sendError(handler, e.getClass().getSimpleName(), language.getId());
|
||||||
|
|
||||||
|
Logger.e(
|
||||||
|
logTag,
|
||||||
|
"Failed loading dictionary: " + language.getDictionaryFile() +
|
||||||
|
" for language '" + language.getName() + "'. "
|
||||||
|
+ e.getMessage()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void importLetters(Language language) {
|
||||||
|
ArrayList<Word> letters = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int key = 0; key <= 9; key++) {
|
||||||
|
for (String langChar : language.getKeyCharacters(key)) {
|
||||||
|
if (langChar.length() == 1 && langChar.charAt(0) >= '0' && langChar.charAt(0) <= '9') {
|
||||||
|
// We do not want 0-9 as "word suggestions" in Predictive mode. It looks confusing
|
||||||
|
// when trying to type a word and also, one can type them by holding the respective
|
||||||
|
// key.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Word word = new Word();
|
||||||
|
word.langId = language.getId();
|
||||||
|
word.frequency = 0;
|
||||||
|
word.sequence = String.valueOf(key);
|
||||||
|
word.word = langChar;
|
||||||
|
|
||||||
|
letters.add(word);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DictionaryDb.insertWordsSync(letters);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void importWords(Handler handler, Language language) throws Exception {
|
||||||
|
importWords(handler, language, language.getDictionaryFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void importWords(Handler handler, Language language, String dictionaryFile) throws Exception {
|
||||||
|
long totalWords = countWords(dictionaryFile);
|
||||||
|
|
||||||
|
BufferedReader br = new BufferedReader(new InputStreamReader(assets.open(dictionaryFile), StandardCharsets.UTF_8));
|
||||||
|
|
||||||
|
ArrayList<Word> dbWords = new ArrayList<>();
|
||||||
|
long line = 0;
|
||||||
|
|
||||||
|
sendProgressMessage(handler, language, 0, 0);
|
||||||
|
|
||||||
|
for (String word; (word = br.readLine()) != null; line++) {
|
||||||
|
if (isStopped) {
|
||||||
|
br.close();
|
||||||
|
sendProgressMessage(handler, language, 0, 0);
|
||||||
|
throw new DictionaryImportAbortedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
validateWord(language, word, line);
|
||||||
|
dbWords.add(stringToWord(language, word));
|
||||||
|
|
||||||
|
if (line % prefs.getDictionaryImportWordChunkSize() == 0) {
|
||||||
|
DictionaryDb.insertWordsSync(dbWords);
|
||||||
|
dbWords.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (totalWords > 0) {
|
||||||
|
int progress = (int) Math.floor(100.0 * line / totalWords);
|
||||||
|
sendProgressMessage(handler, language, progress, prefs.getDictionaryImportProgressUpdateInterval());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
br.close();
|
||||||
|
sendProgressMessage(handler, language, 100, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private long countWords(String filename) {
|
||||||
|
try (LineNumberReader reader = new LineNumberReader(new InputStreamReader(assets.open(filename), StandardCharsets.UTF_8))) {
|
||||||
|
//noinspection ResultOfMethodCallIgnored
|
||||||
|
reader.skip(Long.MAX_VALUE);
|
||||||
|
long lines = reader.getLineNumber();
|
||||||
|
reader.close();
|
||||||
|
|
||||||
|
return lines;
|
||||||
|
} catch (Exception e) {
|
||||||
|
Logger.w("DictionaryLoader.countWords", "Could not count the lines of file: " + filename + ". " + e.getMessage());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void validateWord(Language language, String word, long line) throws DictionaryImportException {
|
||||||
|
if (!language.isPunctuationPartOfWords() && containsPunctuation.matcher(word).find()) {
|
||||||
|
throw new DictionaryImportException(language.getDictionaryFile(), word, line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Word stringToWord(Language language, String word) throws InvalidLanguageCharactersException {
|
||||||
|
Word dbWord = new Word();
|
||||||
|
dbWord.langId = language.getId();
|
||||||
|
dbWord.frequency = 0;
|
||||||
|
dbWord.sequence = language.getDigitSequenceForWord(word);
|
||||||
|
dbWord.word = word;
|
||||||
|
|
||||||
|
return dbWord;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void sendProgressMessage(Handler handler, Language language, int progress, int progressUpdateInterval) {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
if (now - lastProgressUpdate < progressUpdateInterval) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastProgressUpdate = now;
|
||||||
|
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putInt("languageId", language.getId());
|
||||||
|
bundle.putInt("progress", progress);
|
||||||
|
bundle.putInt("currentFile", currentFile);
|
||||||
|
Message msg = new Message();
|
||||||
|
msg.setData(bundle);
|
||||||
|
handler.sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void sendError(Handler handler, String message, int langId) {
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putString("error", message);
|
||||||
|
bundle.putInt("languageId", langId);
|
||||||
|
Message msg = new Message();
|
||||||
|
msg.setData(bundle);
|
||||||
|
handler.sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void sendImportError(Handler handler, String message, int langId, long fileLine, String word) {
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putString("error", message);
|
||||||
|
bundle.putLong("fileLine", fileLine);
|
||||||
|
bundle.putInt("languageId", langId);
|
||||||
|
bundle.putString("word", word);
|
||||||
|
Message msg = new Message();
|
||||||
|
msg.setData(bundle);
|
||||||
|
handler.sendMessage(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
package io.github.sspanak.tt9.languages;
|
||||||
|
|
||||||
|
public class InvalidLanguageCharactersException extends Exception {
|
||||||
|
private Language language;
|
||||||
|
|
||||||
|
public InvalidLanguageCharactersException(Language language, String extraMessage) {
|
||||||
|
super("Some characters are not supported in language: " + language.getName() + ". " + extraMessage);
|
||||||
|
this.language = language;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Language getLanguage() {
|
||||||
|
return language;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -70,7 +70,7 @@ public class Language {
|
||||||
return chars;
|
return chars;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDigitSequenceForWord(String word) throws Exception {
|
public String getDigitSequenceForWord(String word) throws InvalidLanguageCharactersException {
|
||||||
StringBuilder sequence = new StringBuilder();
|
StringBuilder sequence = new StringBuilder();
|
||||||
String lowerCaseWord = word.toLowerCase(locale);
|
String lowerCaseWord = word.toLowerCase(locale);
|
||||||
|
|
||||||
|
|
@ -83,9 +83,7 @@ public class Language {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (word.length() != sequence.length()) {
|
if (word.length() != sequence.length()) {
|
||||||
throw new Exception(
|
throw new InvalidLanguageCharactersException(this, "Failed generating digit sequence for word: '" + word);
|
||||||
"Failed generating digit sequence for word: '" + word + "'. Some characters are not supported in language: " + name
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return sequence.toString();
|
return sequence.toString();
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,10 @@ package io.github.sspanak.tt9.preferences;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import androidx.preference.PreferenceManager;
|
|
||||||
|
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
|
|
||||||
|
import androidx.preference.PreferenceManager;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
|
@ -23,11 +23,13 @@ public class T9Preferences {
|
||||||
private final SharedPreferences prefs;
|
private final SharedPreferences prefs;
|
||||||
private final SharedPreferences.Editor prefsEditor;
|
private final SharedPreferences.Editor prefsEditor;
|
||||||
|
|
||||||
|
|
||||||
public T9Preferences (Context context) {
|
public T9Preferences (Context context) {
|
||||||
prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
prefsEditor = prefs.edit();
|
prefsEditor = prefs.edit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static T9Preferences getInstance() {
|
public static T9Preferences getInstance() {
|
||||||
if (self == null) {
|
if (self == null) {
|
||||||
self = new T9Preferences(TraditionalT9.getMainContext());
|
self = new T9Preferences(TraditionalT9.getMainContext());
|
||||||
|
|
@ -36,7 +38,8 @@ public class T9Preferences {
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************* VALIDATORS *************/
|
|
||||||
|
/************* validators *************/
|
||||||
|
|
||||||
private boolean doesLanguageExist(int langId) {
|
private boolean doesLanguageExist(int langId) {
|
||||||
return LanguageCollection.getLanguage(langId) != null;
|
return LanguageCollection.getLanguage(langId) != null;
|
||||||
|
|
@ -70,7 +73,7 @@ public class T9Preferences {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/************* PREFERENCES OPERATIONS *************/
|
/************* input settings *************/
|
||||||
|
|
||||||
public ArrayList<Integer> getEnabledLanguages() {
|
public ArrayList<Integer> getEnabledLanguages() {
|
||||||
int languageMask = prefs.getInt("pref_enabled_languages", 1);
|
int languageMask = prefs.getInt("pref_enabled_languages", 1);
|
||||||
|
|
@ -101,6 +104,7 @@ public class T9Preferences {
|
||||||
prefsEditor.apply();
|
prefsEditor.apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int getTextCase() {
|
public int getTextCase() {
|
||||||
return prefs.getInt("pref_text_case", InputMode.CASE_LOWER);
|
return prefs.getInt("pref_text_case", InputMode.CASE_LOWER);
|
||||||
}
|
}
|
||||||
|
|
@ -131,6 +135,7 @@ public class T9Preferences {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int getInputMode() {
|
public int getInputMode() {
|
||||||
return prefs.getInt("pref_input_mode", InputMode.MODE_PREDICTIVE);
|
return prefs.getInt("pref_input_mode", InputMode.MODE_PREDICTIVE);
|
||||||
}
|
}
|
||||||
|
|
@ -146,18 +151,24 @@ public class T9Preferences {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/************* hotkey settings *************/
|
||||||
|
|
||||||
public int getKeyBackspace() {
|
public int getKeyBackspace() {
|
||||||
return prefs.getInt("pref_key_backspace", KeyEvent.KEYCODE_BACK);
|
return prefs.getInt("pref_key_backspace", KeyEvent.KEYCODE_BACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getKeyInputMode() { return prefs.getInt("pref_key_input_mode", KeyEvent.KEYCODE_POUND); }
|
public int getKeyInputMode() { return prefs.getInt("pref_key_input_mode", KeyEvent.KEYCODE_POUND); }
|
||||||
|
|
||||||
public int getKeyOtherActions() { return prefs.getInt("pref_key_other_actions", KeyEvent.KEYCODE_STAR); }
|
public int getKeyOtherActions() { return prefs.getInt("pref_key_other_actions", KeyEvent.KEYCODE_STAR); }
|
||||||
|
|
||||||
|
|
||||||
public int getSuggestionsMin() { return 8; }
|
/************* internal settings *************/
|
||||||
public int getSuggestionsMax() { return 20; }
|
|
||||||
|
|
||||||
|
public int getDictionaryImportProgressUpdateInterval() { return 100; /* ms */ }
|
||||||
|
public int getDictionaryImportWordChunkSize() { return 1000; /* words */ }
|
||||||
|
public int getSuggestionsMax() { return 20; }
|
||||||
|
public int getSuggestionsMin() { return 8; }
|
||||||
|
|
||||||
|
|
||||||
|
/************* add word, last word *************/
|
||||||
|
|
||||||
public String getLastWord() {
|
public String getLastWord() {
|
||||||
return prefs.getString("last_word", "");
|
return prefs.getString("last_word", "");
|
||||||
|
|
@ -173,5 +184,4 @@ public class T9Preferences {
|
||||||
public void clearLastWord() {
|
public void clearLastWord() {
|
||||||
this.saveLastWord("");
|
this.saveLastWord("");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
package io.github.sspanak.tt9.ui;
|
package io.github.sspanak.tt9.ui;
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.ListActivity;
|
import android.app.ListActivity;
|
||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
|
|
@ -8,38 +7,24 @@ import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Environment;
|
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.SystemClock;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ListAdapter;
|
import android.widget.ListAdapter;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
|
|
||||||
import com.stackoverflow.answer.UnicodeBOMInputStream;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.Closeable;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import io.github.sspanak.tt9.Logger;
|
|
||||||
import io.github.sspanak.tt9.R;
|
import io.github.sspanak.tt9.R;
|
||||||
import io.github.sspanak.tt9.db.DictionaryDb;
|
import io.github.sspanak.tt9.db.DictionaryDb;
|
||||||
import io.github.sspanak.tt9.db.Word;
|
import io.github.sspanak.tt9.db.DictionaryImportException;
|
||||||
|
import io.github.sspanak.tt9.db.DictionaryLoader;
|
||||||
|
import io.github.sspanak.tt9.languages.InvalidLanguageCharactersException;
|
||||||
|
import io.github.sspanak.tt9.languages.InvalidLanguageException;
|
||||||
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.T9Preferences;
|
import io.github.sspanak.tt9.preferences.T9Preferences;
|
||||||
|
|
@ -49,365 +34,11 @@ import io.github.sspanak.tt9.settings_legacy.SettingAdapter;
|
||||||
|
|
||||||
public class TraditionalT9Settings extends ListActivity implements DialogInterface.OnCancelListener {
|
public class TraditionalT9Settings extends ListActivity implements DialogInterface.OnCancelListener {
|
||||||
|
|
||||||
AsyncTask<String, Integer, Reply> task = null;
|
private DictionaryLoader loader;
|
||||||
final static String userdictname = "user.%s.dict";
|
ProgressDialog progressDialog;
|
||||||
final static String sddir = "tt9";
|
|
||||||
|
|
||||||
Context mContext = null;
|
Context mContext = null;
|
||||||
|
|
||||||
public static class LoadException extends Exception {
|
|
||||||
private static final long serialVersionUID = 3323913652550046354L;
|
|
||||||
|
|
||||||
public LoadException() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class Reply {
|
|
||||||
public boolean status;
|
|
||||||
private final List<String> msgs;
|
|
||||||
|
|
||||||
protected Reply() {
|
|
||||||
this.status = true;
|
|
||||||
this.msgs = new ArrayList<>(4);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void addMsg(String msg) throws LoadException {
|
|
||||||
msgs.add(msg);
|
|
||||||
if (msgs.size() > 6) {
|
|
||||||
msgs.add("Too many errors, bailing.");
|
|
||||||
throw new LoadException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
protected void forceMsg(String msg) {
|
|
||||||
msgs.add(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void finishAndShowError(ProgressDialog pd, Reply result, int title){
|
|
||||||
if (pd != null) {
|
|
||||||
// Logger.d("onPostExecute", "pd");
|
|
||||||
if (pd.isShowing()) {
|
|
||||||
pd.dismiss();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (result == null) {
|
|
||||||
// bad thing happened
|
|
||||||
Logger.e("onPostExecute", "Bad things happen?");
|
|
||||||
} else {
|
|
||||||
String msg = TextUtils.join("\n", result.msgs);
|
|
||||||
Logger.d("onPostExecute", "Result: " + result.status + " " + msg);
|
|
||||||
if (!result.status) {
|
|
||||||
showErrorDialog(getResources().getString(title), msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void closeStream(Closeable is, Reply reply) {
|
|
||||||
if (is == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
is.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
reply.forceMsg("Couldn't close stream: " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class LoadDictTask extends AsyncTask<String, Integer, Reply> {
|
|
||||||
/**
|
|
||||||
* The system calls this to perform work in a worker thread and delivers
|
|
||||||
* it the parameters given to AsyncTask.execute()
|
|
||||||
*/
|
|
||||||
ProgressDialog pd;
|
|
||||||
long size;
|
|
||||||
long pos;
|
|
||||||
boolean internal;
|
|
||||||
String[] dicts;
|
|
||||||
ArrayList<Language> mSupportedLanguages;
|
|
||||||
|
|
||||||
LoadDictTask(int msgid, boolean intern, ArrayList<Language> supportedLanguages) {
|
|
||||||
internal = intern;
|
|
||||||
|
|
||||||
dicts = new String[supportedLanguages.size()];
|
|
||||||
int x = 0;
|
|
||||||
for (Language language : supportedLanguages) {
|
|
||||||
if (intern) {
|
|
||||||
dicts[x++] = language.getDictionaryFile();
|
|
||||||
} else {
|
|
||||||
dicts[x++] = String.format(userdictname, language.getName().toLowerCase(Locale.ENGLISH));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mSupportedLanguages = supportedLanguages;
|
|
||||||
|
|
||||||
pd = new ProgressDialog(TraditionalT9Settings.this);
|
|
||||||
pd.setMessage(getResources().getString(msgid));
|
|
||||||
pd.setOnCancelListener(TraditionalT9Settings.this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private long getDictSizes(boolean internal, String[] dicts) {
|
|
||||||
if (internal) {
|
|
||||||
InputStream input;
|
|
||||||
Properties props = new Properties();
|
|
||||||
try {
|
|
||||||
input = getAssets().open("dict.properties");
|
|
||||||
props.load(input);
|
|
||||||
long total = 0;
|
|
||||||
for (String dict : dicts) {
|
|
||||||
total += Long.parseLong(props.getProperty("size." + dict));
|
|
||||||
}
|
|
||||||
return total;
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
|
||||||
Logger.e("getDictSizes", "Unable to get dict sizes");
|
|
||||||
e.printStackTrace();
|
|
||||||
return -1;
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
Logger.e("getDictSizes", "Unable to parse sizes");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
File backupfile = new File(Environment.getExternalStorageDirectory(), sddir);
|
|
||||||
long total = 0;
|
|
||||||
File f;
|
|
||||||
for (String dict : dicts) {
|
|
||||||
f = new File(backupfile, dict);
|
|
||||||
if (f.exists() && f.isFile()) {
|
|
||||||
total = total + f.length();
|
|
||||||
} else {
|
|
||||||
total = total + 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override protected void onPreExecute() {
|
|
||||||
size = getDictSizes(internal, dicts);
|
|
||||||
pos = 0;
|
|
||||||
if ( size >= 0 ) {
|
|
||||||
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
|
|
||||||
pd.setMax(10000);
|
|
||||||
} else {
|
|
||||||
pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
|
|
||||||
}
|
|
||||||
pd.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Reply doInBackground(String... mode) {
|
|
||||||
Reply reply = new Reply();
|
|
||||||
|
|
||||||
long startnow, endnow;
|
|
||||||
startnow = SystemClock.uptimeMillis();
|
|
||||||
|
|
||||||
// add characters first, then dictionary:
|
|
||||||
Logger.d("doInBackground", "Adding characters...");
|
|
||||||
processChars(mSupportedLanguages);
|
|
||||||
Logger.d("doInBackground", "Characters added.");
|
|
||||||
|
|
||||||
Logger.d("doInBackground", "Adding dict(s)...");
|
|
||||||
|
|
||||||
InputStream dictstream = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
for (int x=0; x<dicts.length; x++) {
|
|
||||||
if (internal) {
|
|
||||||
try {
|
|
||||||
dictstream = getAssets().open(dicts[x]);
|
|
||||||
reply = processFile(dictstream, reply, mSupportedLanguages.get(x), dicts[x]);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
reply.status = false;
|
|
||||||
reply.forceMsg("IO Error: " + e.getMessage());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
dictstream = new FileInputStream(new File(
|
|
||||||
new File(Environment.getExternalStorageDirectory(), sddir), dicts[x]));
|
|
||||||
reply = processFile(dictstream, reply, mSupportedLanguages.get(x), dicts[x]);
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
reply.status = false;
|
|
||||||
reply.forceMsg("File not found: " + e.getMessage());
|
|
||||||
final String msg = mContext.getString(R.string.dictionary_not_found, dicts[x]);
|
|
||||||
//Logger.d("T9Setting.load", "Built string. Calling Toast.");
|
|
||||||
((Activity) mContext).runOnUiThread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
UI.toast(mContext, msg);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
closeStream(dictstream, reply); // this is silly but it
|
|
||||||
// stops IDE nagging at me.
|
|
||||||
} catch (IOException e) {
|
|
||||||
reply.status = false;
|
|
||||||
reply.forceMsg("IO Error: " + e.getMessage());
|
|
||||||
closeStream(dictstream, reply); // this is silly but it
|
|
||||||
return reply; // stops IDE nagging at me.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
closeStream(dictstream, reply);
|
|
||||||
}
|
|
||||||
} catch (LoadException e) {
|
|
||||||
// too many errors, bail
|
|
||||||
closeStream(dictstream, reply);
|
|
||||||
}
|
|
||||||
endnow = SystemClock.uptimeMillis();
|
|
||||||
Logger.d("TIMING", "Execution time: " + (endnow - startnow) + " ms");
|
|
||||||
return reply;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* processChars
|
|
||||||
* Inserts single characters.
|
|
||||||
*/
|
|
||||||
private void processChars(List<Language> allLanguages) {
|
|
||||||
ArrayList<Word> list = new ArrayList<>();
|
|
||||||
|
|
||||||
try {
|
|
||||||
for (Language lang : allLanguages) {
|
|
||||||
for (int key = 0; key <= 9; key++) {
|
|
||||||
for (String langChar : lang.getKeyCharacters(key)) {
|
|
||||||
if (langChar.length() == 1 && langChar.charAt(0) >= '0' && langChar.charAt(0) <= '9') {
|
|
||||||
// We do not want 0-9 as "word suggestions" in Predictive mode. It looks confusing
|
|
||||||
// when trying to type a word and also, one can type them by holding the respective
|
|
||||||
// key.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Word word = new Word();
|
|
||||||
word.langId = lang.getId();
|
|
||||||
word.sequence = String.valueOf(key);
|
|
||||||
word.word = langChar;
|
|
||||||
word.frequency = 0;
|
|
||||||
|
|
||||||
list.add(word);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DictionaryDb.insertWordsSync(list);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Logger.e("processChars", e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getLine(BufferedReader br, Reply rpl, String fname) throws LoadException {
|
|
||||||
try {
|
|
||||||
return br.readLine();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
rpl.status = false;
|
|
||||||
rpl.addMsg("IO Error ("+fname+"): " + e.getMessage());
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Reply processFile(InputStream is, Reply rpl, Language lang, String fname)
|
|
||||||
throws LoadException, IOException {
|
|
||||||
long start = System.currentTimeMillis();
|
|
||||||
|
|
||||||
UnicodeBOMInputStream ubis = new UnicodeBOMInputStream(is);
|
|
||||||
|
|
||||||
BufferedReader br = new BufferedReader(new InputStreamReader(ubis));
|
|
||||||
ubis.skipBOM();
|
|
||||||
|
|
||||||
int freq;
|
|
||||||
String seq;
|
|
||||||
int linecount = 1;
|
|
||||||
int wordlen;
|
|
||||||
String fileWord = getLine(br, rpl, fname);
|
|
||||||
ArrayList<Word> dbWords = new ArrayList<>();
|
|
||||||
int insertChunkSize = 1000;
|
|
||||||
int progressUpdateInterval = 100; // ms
|
|
||||||
long lastProgressUpdate = 0;
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
DictionaryDb.beginTransaction();
|
|
||||||
|
|
||||||
while (fileWord != null) {
|
|
||||||
if (isCancelled()) {
|
|
||||||
rpl.status = false;
|
|
||||||
rpl.addMsg("User cancelled.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (fileWord.contains(" ")) {
|
|
||||||
rpl.status = false;
|
|
||||||
rpl.addMsg("Cannot parse word with spaces: " + fileWord);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
freq = 0;
|
|
||||||
wordlen = fileWord.getBytes(StandardCharsets.UTF_8).length;
|
|
||||||
pos += wordlen;
|
|
||||||
// replace junk characters:
|
|
||||||
fileWord = fileWord.replace("\uFEFF", "");
|
|
||||||
try {
|
|
||||||
seq = lang.getDigitSequenceForWord(fileWord);
|
|
||||||
} catch (Exception e) {
|
|
||||||
rpl.status = false;
|
|
||||||
rpl.addMsg("Error on word ("+fileWord+") line "+
|
|
||||||
linecount+" in (" + fname+"): "+
|
|
||||||
getResources().getString(R.string.add_word_badchar, lang.getName(), fileWord));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
linecount++;
|
|
||||||
|
|
||||||
Word word = new Word();
|
|
||||||
word.sequence = seq;
|
|
||||||
word.langId = lang.getId();
|
|
||||||
word.word = fileWord;
|
|
||||||
word.frequency = freq;
|
|
||||||
dbWords.add(word);
|
|
||||||
|
|
||||||
if (linecount % insertChunkSize == 0) {
|
|
||||||
DictionaryDb.insertWordsSync(dbWords);
|
|
||||||
dbWords.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size >= 0 && System.currentTimeMillis() - lastProgressUpdate > progressUpdateInterval) {
|
|
||||||
publishProgress((int) ((float) pos / size * 10000));
|
|
||||||
lastProgressUpdate = System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
fileWord = getLine(br, rpl, fname);
|
|
||||||
}
|
|
||||||
|
|
||||||
DictionaryDb.insertWordsSync(dbWords);
|
|
||||||
DictionaryDb.endTransaction(true);
|
|
||||||
dbWords.clear();
|
|
||||||
|
|
||||||
publishProgress((int) ((float) pos / size * 10000));
|
|
||||||
} catch (Exception e) {
|
|
||||||
DictionaryDb.endTransaction(false);
|
|
||||||
Logger.e("processFile", e.getMessage());
|
|
||||||
} finally {
|
|
||||||
br.close();
|
|
||||||
is.close();
|
|
||||||
ubis.close();
|
|
||||||
is.close();
|
|
||||||
|
|
||||||
Logger.d("processFile", "Inserted: " + fname + " in: " + (System.currentTimeMillis() - start) + "ms");
|
|
||||||
}
|
|
||||||
return rpl;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onProgressUpdate(Integer... progress) {
|
|
||||||
if (pd.isShowing()) {
|
|
||||||
pd.setProgress(progress[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(Reply result) {
|
|
||||||
finishAndShowError(pd, result, R.string.dictionary_load_title);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
@ -433,21 +64,32 @@ public class TraditionalT9Settings extends ListActivity implements DialogInterfa
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCancel(DialogInterface dint) {
|
||||||
|
if (loader != null) {
|
||||||
|
loader.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onListItemClick(ListView l, View v, int position, long id) {
|
protected void onListItemClick(ListView l, View v, int position, long id) {
|
||||||
Setting s = (Setting)getListView().getItemAtPosition(position);
|
Setting s = (Setting)getListView().getItemAtPosition(position);
|
||||||
if (s.id.equals("help"))
|
switch (s.id) {
|
||||||
|
case "help":
|
||||||
openHelp();
|
openHelp();
|
||||||
else if (s.id.equals("loaddict"))
|
break;
|
||||||
preloader(R.string.dictionary_loading, true);
|
case "loaddict":
|
||||||
else if (s.id.equals("truncatedict")) {
|
loadDictionaries();
|
||||||
|
break;
|
||||||
|
case "truncatedict":
|
||||||
truncateWords();
|
truncateWords();
|
||||||
}
|
break;
|
||||||
else if (s.id.equals("loaduserdict"))
|
default:
|
||||||
preloader(R.string.dictionary_loading_user_dict, false);
|
|
||||||
else
|
|
||||||
s.clicked(mContext);
|
s.clicked(mContext);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void openHelp() {
|
private void openHelp() {
|
||||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||||
|
|
@ -465,50 +107,106 @@ public class TraditionalT9Settings extends ListActivity implements DialogInterfa
|
||||||
DictionaryDb.truncateWords(afterTruncate);
|
DictionaryDb.truncateWords(afterTruncate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void loadDictionaries() {
|
||||||
|
ArrayList<Language> languages = LanguageCollection.getAll(T9Preferences.getInstance().getEnabledLanguages());
|
||||||
|
initProgress(100 * languages.size());
|
||||||
|
|
||||||
private void preloader(int msgid, boolean internal) {
|
Handler loadHandler = new Handler(Looper.getMainLooper()) {
|
||||||
|
@Override
|
||||||
|
public void handleMessage(Message msg) {
|
||||||
|
String error = msg.getData().getString("error", null);
|
||||||
|
|
||||||
|
if (error != null) {
|
||||||
task = new LoadDictTask(
|
hideProgress();
|
||||||
msgid,
|
handleError(
|
||||||
internal,
|
error,
|
||||||
LanguageCollection.getAll(T9Preferences.getInstance().getEnabledLanguages())
|
msg.getData().getInt("languageId", -1),
|
||||||
|
msg.getData().getLong("fileLine", -1),
|
||||||
|
msg.getData().getString("word", "")
|
||||||
);
|
);
|
||||||
task.execute();
|
} else {
|
||||||
|
int langId = msg.getData().getInt("languageId", -1);
|
||||||
|
Language lang = LanguageCollection.getLanguage(langId);
|
||||||
|
String langName = lang != null ? lang.getName() : "???";
|
||||||
|
|
||||||
|
String title = getResources().getString(R.string.dictionary_loading, langName);
|
||||||
|
showProgress(
|
||||||
|
msg.getData().getInt("currentFile", 0),
|
||||||
|
msg.getData().getInt("progress", 0),
|
||||||
|
title
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
loader = new DictionaryLoader(this);
|
||||||
|
loader.load(loadHandler, languages);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void initProgress(int max) {
|
||||||
|
if (progressDialog == null) {
|
||||||
|
progressDialog = new ProgressDialog(this);
|
||||||
|
progressDialog.setOnCancelListener(TraditionalT9Settings.this);
|
||||||
|
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
progressDialog.setMax(max);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showProgress(int currentFile, int currentFileProgress, String title) {
|
||||||
|
if (progressDialog == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (title != null) {
|
||||||
|
progressDialog.setMessage(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
int totalProgress = 100 * currentFile + currentFileProgress;
|
||||||
|
if (totalProgress <= 0 || totalProgress >= progressDialog.getMax()) {
|
||||||
|
progressDialog.dismiss();
|
||||||
|
} else {
|
||||||
|
progressDialog.setProgress(totalProgress);
|
||||||
|
if (!progressDialog.isShowing()) {
|
||||||
|
progressDialog.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hideProgress() {
|
||||||
|
if (progressDialog != null) {
|
||||||
|
progressDialog.dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleError(String errorType, int langId, long line, String word) {
|
||||||
|
Language lang = LanguageCollection.getLanguage(langId);
|
||||||
|
String message;
|
||||||
|
|
||||||
|
if (lang == null || errorType.equals(InvalidLanguageException.class.getSimpleName())) {
|
||||||
|
message = getString(R.string.add_word_invalid_language);
|
||||||
|
} else if (errorType.equals(DictionaryImportException.class.getSimpleName()) || errorType.equals(InvalidLanguageCharactersException.class.getSimpleName())) {
|
||||||
|
String languageName = lang.getName();
|
||||||
|
message = getString(R.string.dictionary_import_bad_char, word, line, languageName);
|
||||||
|
} else if (errorType.equals(IOException.class.getSimpleName()) || errorType.equals(FileNotFoundException.class.getSimpleName())) {
|
||||||
|
String languageName = lang.getName();
|
||||||
|
message = getString(R.string.dictionary_not_found, languageName);
|
||||||
|
} else {
|
||||||
|
String languageName = lang.getName();
|
||||||
|
message = getString(R.string.dictionary_import_error, languageName, errorType);
|
||||||
|
}
|
||||||
|
|
||||||
|
showErrorDialog(getString(R.string.dictionary_load_title), message);
|
||||||
|
}
|
||||||
|
|
||||||
private void showErrorDialog(CharSequence title, CharSequence msg) {
|
private void showErrorDialog(CharSequence title, CharSequence msg) {
|
||||||
showErrorDialog(new AlertDialog.Builder(this), title, msg);
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
}
|
builder
|
||||||
|
.setMessage(msg)
|
||||||
private void showErrorDialog(AlertDialog.Builder builder, CharSequence title, CharSequence msg) {
|
.setTitle(title)
|
||||||
builder.setMessage(msg).setTitle(title)
|
.setNeutralButton(android.R.string.ok, (dialog, id) -> dialog.dismiss());
|
||||||
.setNeutralButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
|
||||||
dialog.dismiss();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
AlertDialog dialog = builder.create();
|
AlertDialog dialog = builder.create();
|
||||||
dialog.show();
|
dialog.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showErrorDialogID(AlertDialog.Builder builder, int titleid, int msgid) {
|
|
||||||
builder.setMessage(msgid).setTitle(titleid)
|
|
||||||
.setNeutralButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
|
||||||
dialog.dismiss();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
AlertDialog dialog = builder.create();
|
|
||||||
dialog.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCancel(DialogInterface dint) {
|
|
||||||
task.cancel(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue