mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-06-20 16:10:52 +00:00
Switch most latin layouts to use the simple parser (#276)
And do some tweaks so it works better
This commit is contained in:
parent
da6dcece7f
commit
cbfa934721
69 changed files with 1448 additions and 177 deletions
8
app/src/main/assets/language_key_texts/af.txt
Normal file
8
app/src/main/assets/language_key_texts/af.txt
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[morekeys]
|
||||||
|
a á â ä à æ ã å ā
|
||||||
|
e é è ê ë ę ė ē
|
||||||
|
i í ì ï î į ī ij
|
||||||
|
o ó ô ö ò õ œ ø ō
|
||||||
|
u ú û ü ù ū
|
||||||
|
n ñ ń
|
||||||
|
y ý ij
|
24
app/src/main/assets/language_key_texts/all_more_keys.txt
Normal file
24
app/src/main/assets/language_key_texts/all_more_keys.txt
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
[morekeys]
|
||||||
|
a á â ä à æ ã å ā ą ª ă ả ạ ằ ắ ẳ ẵ ặ ầ ấ ẩ ẫ ậ
|
||||||
|
e é è ê ë ę ė ē ə ě ẻ ẽ ẹ ề ế ể ễ ệ ĕ
|
||||||
|
i í ì ï î į ī ij ı ĩ ỉ ị ĭ
|
||||||
|
o ó ô ö ò õ œ ø ō º ő ỏ ọ ồ ố ổ ỗ ộ ơ ờ ớ ở ỡ ợ ŏ
|
||||||
|
u ú û ü ù ū ů ũ ű ų µ ủ ụ ư ừ ứ ử ữ ự ŭ
|
||||||
|
n ñ ń ň ņ ʼn ŋ
|
||||||
|
y ý ij ÿ y ŷ þ ỳ ỷ ỹ ỵ
|
||||||
|
s ş ß ś š ẞ ș ŝ ſ
|
||||||
|
g ğ ġ ģ g\' ĝ
|
||||||
|
c ç ć č ċ ĉ
|
||||||
|
z ž ź ż
|
||||||
|
l l·l ł ĺ ļ ľ ŀ
|
||||||
|
punctuation !autoColumnOrder!9 \, ? ! · # ) ( / ; ' @ : - " + \% & ¡ ¿
|
||||||
|
d ď ð đ
|
||||||
|
r ř ŕ ŗ
|
||||||
|
t ť ț ţ ŧ þ
|
||||||
|
k ķ ĸ
|
||||||
|
v w ŵ
|
||||||
|
h ĥ ħ
|
||||||
|
w w ŵ
|
||||||
|
q q
|
||||||
|
x x
|
||||||
|
j ĵ
|
12
app/src/main/assets/language_key_texts/az.txt
Normal file
12
app/src/main/assets/language_key_texts/az.txt
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
[morekeys]
|
||||||
|
a â ä á
|
||||||
|
e ə é
|
||||||
|
i ı î ï ì í į ī
|
||||||
|
o ö ô œ ò ó õ ø ō
|
||||||
|
u ü û ù ú ū
|
||||||
|
s ş ß ś š
|
||||||
|
g ğ
|
||||||
|
n ň ñ
|
||||||
|
c ç ć č
|
||||||
|
y ý
|
||||||
|
z ž
|
13
app/src/main/assets/language_key_texts/ca.txt
Normal file
13
app/src/main/assets/language_key_texts/ca.txt
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
[morekeys]
|
||||||
|
a à á ä â ã å ą æ ā ª
|
||||||
|
e è é ë ê ę ė ē
|
||||||
|
i í ï ì î į ī
|
||||||
|
o ò ó ö ô õ ø œ ō º
|
||||||
|
u ú ü ù û ū
|
||||||
|
n ñ ń
|
||||||
|
c ç ć č
|
||||||
|
l l·l ł
|
||||||
|
punctuation !autoColumnOrder!9 \, ? ! · # ) ( / ; ' @ : - " + \% &
|
||||||
|
|
||||||
|
[extra_keys]
|
||||||
|
2: ç
|
16
app/src/main/assets/language_key_texts/cs.txt
Normal file
16
app/src/main/assets/language_key_texts/cs.txt
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
[morekeys]
|
||||||
|
a á à â ä æ ã å ā
|
||||||
|
e é ě è ê ë ę ė ē
|
||||||
|
i í î ï ì į ī
|
||||||
|
o ó ö ô ò õ œ ø ō
|
||||||
|
u ú ů û ü ù ū
|
||||||
|
s š ß ś
|
||||||
|
n ň ñ ń
|
||||||
|
c č ç ć
|
||||||
|
y ý ÿ
|
||||||
|
d ď
|
||||||
|
r ř
|
||||||
|
t ť
|
||||||
|
z ž ź ż
|
||||||
|
' ’ ‚ ‘ › ‹
|
||||||
|
" ” „ “ » «
|
18
app/src/main/assets/language_key_texts/da.txt
Normal file
18
app/src/main/assets/language_key_texts/da.txt
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
[morekeys]
|
||||||
|
a å æ á ä à â ã ā
|
||||||
|
e é ë
|
||||||
|
i í ï
|
||||||
|
o ø ö ó ô ò õ œ ō
|
||||||
|
u ú ü û ù ū
|
||||||
|
s ß ś š
|
||||||
|
n ñ ń
|
||||||
|
y ý ÿ
|
||||||
|
d ð
|
||||||
|
l ł
|
||||||
|
' ’ ‚ ‘ › ‹
|
||||||
|
" ” „ “ » «
|
||||||
|
|
||||||
|
[extra_keys]
|
||||||
|
1: å
|
||||||
|
2: æ ä
|
||||||
|
2: ø ö
|
14
app/src/main/assets/language_key_texts/de.txt
Normal file
14
app/src/main/assets/language_key_texts/de.txt
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
[morekeys]
|
||||||
|
a ä % â à á æ ã å ā
|
||||||
|
e é è ê ë ė
|
||||||
|
o ö % ô ò ó õ œ ø ō
|
||||||
|
u ü % û ù ú ū
|
||||||
|
s ß % ẞ ś š
|
||||||
|
n ñ ń
|
||||||
|
' ’ ‚ ‘ › ‹
|
||||||
|
" ” „ “ » «
|
||||||
|
|
||||||
|
[extra_keys]
|
||||||
|
1: ü è
|
||||||
|
2: ö é
|
||||||
|
2: ä à
|
14
app/src/main/assets/language_key_texts/de_ch.txt
Normal file
14
app/src/main/assets/language_key_texts/de_ch.txt
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
[morekeys]
|
||||||
|
a ä â à á æ ã å ā
|
||||||
|
e é è ê ë ė
|
||||||
|
o ö ô ò ó õ œ ø ō
|
||||||
|
u ü û ù ú ū
|
||||||
|
s ß % ś š
|
||||||
|
n ñ ń
|
||||||
|
' ’ ‚ ‘ › ‹
|
||||||
|
" ” „ “ » «
|
||||||
|
|
||||||
|
[extra_keys]
|
||||||
|
1: ü è
|
||||||
|
2: ö é
|
||||||
|
2: ä à
|
15
app/src/main/assets/language_key_texts/de_de.txt
Normal file
15
app/src/main/assets/language_key_texts/de_de.txt
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
[morekeys]
|
||||||
|
a ä â à á æ ã å ā
|
||||||
|
e é è ê ë ė
|
||||||
|
o ö ô ò ó õ œ ø ō
|
||||||
|
u ü û ù ú ū
|
||||||
|
s ß % ś š
|
||||||
|
n ñ ń
|
||||||
|
' ’ ‚ ‘ › ‹
|
||||||
|
" ” „ “ » «
|
||||||
|
|
||||||
|
[extra_keys]
|
||||||
|
1: ü è
|
||||||
|
2: ö é
|
||||||
|
2: ä à
|
||||||
|
3: ß
|
9
app/src/main/assets/language_key_texts/en.txt
Normal file
9
app/src/main/assets/language_key_texts/en.txt
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
[morekeys]
|
||||||
|
a à á â ä æ ã å ā
|
||||||
|
e é è ê ë ē
|
||||||
|
i í î ï ī ì
|
||||||
|
o ó ô ö ò œ ø ō õ
|
||||||
|
u ú û ü ù ū
|
||||||
|
s ß
|
||||||
|
n ñ
|
||||||
|
c ç
|
22
app/src/main/assets/language_key_texts/eo.txt
Normal file
22
app/src/main/assets/language_key_texts/eo.txt
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
[morekeys]
|
||||||
|
a á à â ä æ ã å ā ă ą ª
|
||||||
|
e é ě è ê ë ę ė ē
|
||||||
|
i í î ï ĩ ì į ī ı ij
|
||||||
|
o ó ö ô ò õ œ ø ō ő º
|
||||||
|
u ú ů û ü ù ū ũ ű ų µ
|
||||||
|
s ß š ś ș ş
|
||||||
|
n ñ ń ņ ň ʼn ŋ
|
||||||
|
c ć č ç ċ
|
||||||
|
ŭ y ý ŷ ÿ þ
|
||||||
|
d ð ď đ
|
||||||
|
r ř ŕ ŗ
|
||||||
|
t ť ț ţ ŧ
|
||||||
|
z ź ż ž
|
||||||
|
k ķ ĸ
|
||||||
|
l ĺ ļ ľ ŀ ł
|
||||||
|
g ğ ġ ģ
|
||||||
|
v w ŵ
|
||||||
|
h ĥ ħ
|
||||||
|
ĝ w ŵ
|
||||||
|
ŝ q
|
||||||
|
ĉ x
|
12
app/src/main/assets/language_key_texts/es.txt
Normal file
12
app/src/main/assets/language_key_texts/es.txt
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
[morekeys]
|
||||||
|
a á à ä â ã å ą æ ā ª
|
||||||
|
e é è ë ê ę ė ē
|
||||||
|
i í ï ì î į ī
|
||||||
|
o ó ò ö ô õ ø œ ō º
|
||||||
|
u ú ü ù û ū
|
||||||
|
n ñ ń
|
||||||
|
c ç ć č
|
||||||
|
punctuation !autoColumnOrder!9 \, ? ! # ) ( / ; ¡ ' @ : - " + \% & ¿
|
||||||
|
|
||||||
|
[extra_keys]
|
||||||
|
2: ñ
|
24
app/src/main/assets/language_key_texts/et.txt
Normal file
24
app/src/main/assets/language_key_texts/et.txt
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
[morekeys]
|
||||||
|
a ä ā à á â ã å æ ą
|
||||||
|
e ē è ė é ê ë ę ě
|
||||||
|
i ī ì į í î ï ı
|
||||||
|
o ö õ ò ó ô œ ő ø
|
||||||
|
u ü ū ų ù ú û ů ű
|
||||||
|
s š ß ś ş
|
||||||
|
n ņ ñ ń
|
||||||
|
c č ç ć
|
||||||
|
y ý ÿ
|
||||||
|
d ď
|
||||||
|
r ŗ ř ŕ
|
||||||
|
t ţ ť
|
||||||
|
z ž ż ź
|
||||||
|
k ķ
|
||||||
|
l ļ ł ĺ ľ
|
||||||
|
g ģ ğ
|
||||||
|
' ’ ‚ ‘
|
||||||
|
" ” „ “
|
||||||
|
|
||||||
|
[extra_keys]
|
||||||
|
1: ü
|
||||||
|
2: ö õ
|
||||||
|
2: ä
|
11
app/src/main/assets/language_key_texts/eu.txt
Normal file
11
app/src/main/assets/language_key_texts/eu.txt
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[morekeys]
|
||||||
|
a á à ä â ã å ą æ ā ª
|
||||||
|
e é è ë ê ę ė ē
|
||||||
|
i í ï ì î į ī
|
||||||
|
o ó ò ö ô õ ø œ ō º
|
||||||
|
u ú ü ù û ū
|
||||||
|
n ñ ń
|
||||||
|
c ç ć č
|
||||||
|
|
||||||
|
[extra_keys]
|
||||||
|
2: ñ
|
11
app/src/main/assets/language_key_texts/fi.txt
Normal file
11
app/src/main/assets/language_key_texts/fi.txt
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[morekeys]
|
||||||
|
a ä å æ à á â ã ā
|
||||||
|
o ö ø ô ò ó õ œ ō
|
||||||
|
u ü
|
||||||
|
s š ß ś
|
||||||
|
z ž ź ż
|
||||||
|
|
||||||
|
[extra_keys]
|
||||||
|
1: å
|
||||||
|
2: ö ø
|
||||||
|
2: ä æ
|
11
app/src/main/assets/language_key_texts/fil.txt
Normal file
11
app/src/main/assets/language_key_texts/fil.txt
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[morekeys]
|
||||||
|
a á à ä â ã å ą æ ā ª
|
||||||
|
e é è ë ê ę ė ē
|
||||||
|
i í ï ì î į ī
|
||||||
|
o ó ò ö ô õ ø œ ō º
|
||||||
|
u ú ü ù û ū
|
||||||
|
n ñ ń
|
||||||
|
c ç ć č
|
||||||
|
|
||||||
|
[extra_keys]
|
||||||
|
2: ñ
|
13
app/src/main/assets/language_key_texts/fr.txt
Normal file
13
app/src/main/assets/language_key_texts/fr.txt
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
[morekeys]
|
||||||
|
a à â % æ á ä ã å ā ª
|
||||||
|
e é è ê ë % ę ė ē
|
||||||
|
i î % ï ì í į ī
|
||||||
|
o ô œ % ö ò ó õ ø ō º
|
||||||
|
u ù û % ü ú ū
|
||||||
|
c ç % ć č
|
||||||
|
y % ÿ
|
||||||
|
|
||||||
|
[extra_keys]
|
||||||
|
1: è ü
|
||||||
|
2: é ö
|
||||||
|
2: à ä
|
11
app/src/main/assets/language_key_texts/gl.txt
Normal file
11
app/src/main/assets/language_key_texts/gl.txt
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[morekeys]
|
||||||
|
a á à ä â ã å ą æ ā ª
|
||||||
|
e é è ë ê ę ė ē
|
||||||
|
i í ï ì î į ī
|
||||||
|
o ó ò ö ô õ ø œ ō º
|
||||||
|
u ú ü ù û ū
|
||||||
|
n ñ ń
|
||||||
|
c ç ć č
|
||||||
|
|
||||||
|
[extra_keys]
|
||||||
|
2: ñ
|
8
app/src/main/assets/language_key_texts/hr.txt
Normal file
8
app/src/main/assets/language_key_texts/hr.txt
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[morekeys]
|
||||||
|
s š ś ß
|
||||||
|
n ñ ń
|
||||||
|
z ž ź ż
|
||||||
|
c č ć ç
|
||||||
|
d đ
|
||||||
|
' ‘ ‚ ’ › ‹
|
||||||
|
" “ „ ” » «
|
8
app/src/main/assets/language_key_texts/hu.txt
Normal file
8
app/src/main/assets/language_key_texts/hu.txt
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[morekeys]
|
||||||
|
a á
|
||||||
|
e é
|
||||||
|
i í
|
||||||
|
o ó ö ő
|
||||||
|
u ú ü ű
|
||||||
|
' ‘ ‚ ’ › ‹
|
||||||
|
" “ „ ” » «
|
11
app/src/main/assets/language_key_texts/is.txt
Normal file
11
app/src/main/assets/language_key_texts/is.txt
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[morekeys]
|
||||||
|
a á ä æ å à â ã ā
|
||||||
|
e é ë è ê ę ė ē
|
||||||
|
i í ï î ì į ī
|
||||||
|
o ó ö ô ò õ œ ø ō
|
||||||
|
u ú ü û ù ū
|
||||||
|
y ý ÿ
|
||||||
|
d ð
|
||||||
|
t þ
|
||||||
|
' ’ ‚ ‘
|
||||||
|
" ” „ “
|
11
app/src/main/assets/language_key_texts/it.txt
Normal file
11
app/src/main/assets/language_key_texts/it.txt
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[morekeys]
|
||||||
|
a à á â ä æ ã å ā ª
|
||||||
|
e è é ê ë ę ė ē ə
|
||||||
|
i ì í î ï į ī
|
||||||
|
o ò ó ô ö õ œ ø ō º
|
||||||
|
u ù ú û ü ū
|
||||||
|
|
||||||
|
[extra_keys]
|
||||||
|
1: ü è
|
||||||
|
2: ö é
|
||||||
|
2: ä à
|
19
app/src/main/assets/language_key_texts/lt.txt
Normal file
19
app/src/main/assets/language_key_texts/lt.txt
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
[morekeys]
|
||||||
|
a ą ä ā à á â ã å æ
|
||||||
|
e ė ę ē è é ê ë ě
|
||||||
|
i į ī ì í î ï ı
|
||||||
|
o ö õ ò ó ô œ ő ø
|
||||||
|
u ū ų ü ū ù ú û ů ű
|
||||||
|
s š ß ś ş
|
||||||
|
n ņ ñ ń
|
||||||
|
c č ç ć
|
||||||
|
y ý ÿ
|
||||||
|
d ď
|
||||||
|
r ŗ ř ŕ
|
||||||
|
t ţ ť
|
||||||
|
z ž ż ź
|
||||||
|
k ķ
|
||||||
|
l ļ ł ĺ ľ
|
||||||
|
g ģ ğ
|
||||||
|
' ’ ‚ ‘
|
||||||
|
" ” „ “
|
19
app/src/main/assets/language_key_texts/lv.txt
Normal file
19
app/src/main/assets/language_key_texts/lv.txt
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
[morekeys]
|
||||||
|
a ā à á â ã ä å æ ą
|
||||||
|
e ē ė è é ê ë ę ě
|
||||||
|
i ī į ì í î ï ı
|
||||||
|
o ò ó ô õ ö œ ő ø
|
||||||
|
u ū ų ù ú û ü ů ű
|
||||||
|
s š ß ś ş
|
||||||
|
n ņ ñ ń
|
||||||
|
c č ç ć
|
||||||
|
y ý ÿ
|
||||||
|
d ď
|
||||||
|
r ŗ ř ŕ
|
||||||
|
t ţ ť
|
||||||
|
z ž ż ź
|
||||||
|
k ķ
|
||||||
|
l ļ ł ĺ ľ
|
||||||
|
g ģ ğ
|
||||||
|
' ’ ‚ ‘
|
||||||
|
" ” „ “
|
20
app/src/main/assets/language_key_texts/more_more_keys.txt
Normal file
20
app/src/main/assets/language_key_texts/more_more_keys.txt
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
[morekeys]
|
||||||
|
a á â ä à æ ã å ā ą ª ă
|
||||||
|
e é è ê ë ę ė ē ə ě
|
||||||
|
i í ì ï î į ī ij ı ĩ
|
||||||
|
o ó ô ö ò õ œ ø ō º ő
|
||||||
|
u ú û ü ù ū ů ũ ű ų
|
||||||
|
n ñ ń ň ņ ʼn ŋ
|
||||||
|
y ý ij ÿ ŷ
|
||||||
|
s ş ß ś š ș
|
||||||
|
g ğ ġ ģ
|
||||||
|
c ç ć č ċ
|
||||||
|
z ž ź ż
|
||||||
|
l ł ĺ ļ ľ ŀ
|
||||||
|
punctuation !autoColumnOrder!9 \, ? ! # ) ( / ; ' @ : - " + \% &
|
||||||
|
d ď ð đ
|
||||||
|
r ř ŕ ŗ
|
||||||
|
t ť ț ţ ŧ þ
|
||||||
|
k ķ ĸ
|
||||||
|
h ĥ
|
||||||
|
w ŵ
|
12
app/src/main/assets/language_key_texts/nb.txt
Normal file
12
app/src/main/assets/language_key_texts/nb.txt
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
[morekeys]
|
||||||
|
a å æ ä à á â ã ā
|
||||||
|
e é è ê ë ę ė ē
|
||||||
|
o ø ö ô ò ó õ œ ō
|
||||||
|
u ü û ù ú ū
|
||||||
|
' ‘ ‚ ’
|
||||||
|
" “ „ ”
|
||||||
|
|
||||||
|
[extra_keys]
|
||||||
|
1: å
|
||||||
|
2: ø ö
|
||||||
|
2: æ ä
|
10
app/src/main/assets/language_key_texts/nl.txt
Normal file
10
app/src/main/assets/language_key_texts/nl.txt
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
[morekeys]
|
||||||
|
a á ä â à æ ã å ā
|
||||||
|
e é ë ê è ę ė ē
|
||||||
|
i í ï ì î į ī ij
|
||||||
|
o ó ö ô ò õ œ ø ō
|
||||||
|
u ú ü û ù ū
|
||||||
|
n ñ ń
|
||||||
|
y ij
|
||||||
|
' ‘ ‚ ’
|
||||||
|
" “ „ ”
|
11
app/src/main/assets/language_key_texts/pl.txt
Normal file
11
app/src/main/assets/language_key_texts/pl.txt
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[morekeys]
|
||||||
|
a ą á à â ä æ ã å ā
|
||||||
|
e ę è é ê ë ė ē
|
||||||
|
o ó ö ô ò õ œ ø ō
|
||||||
|
s ś ß š
|
||||||
|
n ń ñ
|
||||||
|
c ć ç č
|
||||||
|
z ż ź ž
|
||||||
|
l ł
|
||||||
|
' ‘ ‚ ’
|
||||||
|
" “ „ ”
|
7
app/src/main/assets/language_key_texts/pt.txt
Normal file
7
app/src/main/assets/language_key_texts/pt.txt
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
[morekeys]
|
||||||
|
a á ã à â ä å æ ª
|
||||||
|
e é ê è ę ė ē ë
|
||||||
|
i í î ì ï į ī
|
||||||
|
o ó õ ô ò ö œ ø ō º
|
||||||
|
u ú ü ù û ū
|
||||||
|
c ç č ć
|
2
app/src/main/assets/language_key_texts/rm.txt
Normal file
2
app/src/main/assets/language_key_texts/rm.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[morekeys]
|
||||||
|
o ò ó ö ô õ œ ø
|
7
app/src/main/assets/language_key_texts/ro.txt
Normal file
7
app/src/main/assets/language_key_texts/ro.txt
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
[morekeys]
|
||||||
|
a ă â ã à á ä æ å ā
|
||||||
|
i î ï ì í į ī
|
||||||
|
s ș ß ś š
|
||||||
|
t ț
|
||||||
|
' ‘ ‚ ’
|
||||||
|
" “ „ ”
|
19
app/src/main/assets/language_key_texts/sk.txt
Normal file
19
app/src/main/assets/language_key_texts/sk.txt
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
[morekeys]
|
||||||
|
a á ä ā à â ã å æ ą
|
||||||
|
e é ě ē ė è ê ë ę
|
||||||
|
i í ī į ì î ï ı
|
||||||
|
o ô ó ö ò õ œ ő ø
|
||||||
|
u ú ů ü ū ų ù û ű
|
||||||
|
s š ß ś ş
|
||||||
|
n ň ņ ñ ń
|
||||||
|
c č ç ć
|
||||||
|
y ý ÿ
|
||||||
|
d ď
|
||||||
|
r ŕ ř ŗ
|
||||||
|
t ť ţ
|
||||||
|
z ž ż ź
|
||||||
|
k ķ
|
||||||
|
l ľ ĺ ļ ł
|
||||||
|
g ģ ğ
|
||||||
|
' ’ ‚ ‘ › ‹
|
||||||
|
" ” „ “ » «
|
7
app/src/main/assets/language_key_texts/sl.txt
Normal file
7
app/src/main/assets/language_key_texts/sl.txt
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
[morekeys]
|
||||||
|
s š
|
||||||
|
c č ć
|
||||||
|
d đ
|
||||||
|
z ž
|
||||||
|
' ’ ‚ ‘ › ‹
|
||||||
|
" ” „ “ » «
|
14
app/src/main/assets/language_key_texts/sr_zz.txt
Normal file
14
app/src/main/assets/language_key_texts/sr_zz.txt
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
[morekeys]
|
||||||
|
e è
|
||||||
|
i ì
|
||||||
|
s š %
|
||||||
|
c č ć %
|
||||||
|
d đ %
|
||||||
|
z ž %
|
||||||
|
|
||||||
|
[extra_keys]
|
||||||
|
1: š
|
||||||
|
2: č
|
||||||
|
2: ć
|
||||||
|
3: đ
|
||||||
|
3: ž
|
22
app/src/main/assets/language_key_texts/sv.txt
Normal file
22
app/src/main/assets/language_key_texts/sv.txt
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
[morekeys]
|
||||||
|
a ä å æ á à â ą ã
|
||||||
|
c ç ć č
|
||||||
|
d ð ď
|
||||||
|
e é è ê ë ę
|
||||||
|
i í ì î ï
|
||||||
|
l ł
|
||||||
|
n ń ñ ň
|
||||||
|
o ö ø œ ó ò ô õ ō
|
||||||
|
r ř
|
||||||
|
s ś š ş ß
|
||||||
|
t ť þ
|
||||||
|
u ü ú ù û ū
|
||||||
|
y ý ÿ
|
||||||
|
z ź ž ż
|
||||||
|
' › ‹
|
||||||
|
" » «
|
||||||
|
|
||||||
|
[extra_keys]
|
||||||
|
1: å
|
||||||
|
2: ö ø œ
|
||||||
|
2: ä æ
|
10
app/src/main/assets/language_key_texts/sw.txt
Normal file
10
app/src/main/assets/language_key_texts/sw.txt
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
[morekeys]
|
||||||
|
a à á â ä æ ã å ā
|
||||||
|
e è é ê ë ē
|
||||||
|
i î ï í ī ì
|
||||||
|
o ô ö ò ó œ ø ō õ
|
||||||
|
u û ü ù ú ū
|
||||||
|
s ß
|
||||||
|
n ñ
|
||||||
|
c ç
|
||||||
|
g g\'
|
12
app/src/main/assets/language_key_texts/tr.txt
Normal file
12
app/src/main/assets/language_key_texts/tr.txt
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
[morekeys]
|
||||||
|
a â ä á
|
||||||
|
e ə é
|
||||||
|
i ı î ï ì í į ī
|
||||||
|
o ö ô œ ò ó õ ø ō
|
||||||
|
u ü û ù ú ū
|
||||||
|
s ş ß ś š
|
||||||
|
g ğ
|
||||||
|
n ň ñ
|
||||||
|
c ç ć č
|
||||||
|
y ý
|
||||||
|
z ž
|
12
app/src/main/assets/language_key_texts/uz.txt
Normal file
12
app/src/main/assets/language_key_texts/uz.txt
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
[morekeys]
|
||||||
|
a â ä á
|
||||||
|
e ə é
|
||||||
|
i ı î ï ì í į ī
|
||||||
|
o ö ô œ ò ó õ ø ō
|
||||||
|
u ü û ù ú ū
|
||||||
|
s ş ß ś š
|
||||||
|
g ğ
|
||||||
|
n ň ñ
|
||||||
|
c ç ć č
|
||||||
|
y ý
|
||||||
|
z ž
|
8
app/src/main/assets/language_key_texts/vi.txt
Normal file
8
app/src/main/assets/language_key_texts/vi.txt
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[morekeys]
|
||||||
|
a à á ả ã ạ ă ằ ắ ẳ ẵ ặ â ầ ấ ẩ ẫ ậ
|
||||||
|
e è é ẻ ẽ ẹ ê ề ế ể ễ ệ
|
||||||
|
i ì í ỉ ĩ ị
|
||||||
|
o ò ó ỏ õ ọ ô ồ ố ổ ỗ ộ ơ ờ ớ ở ỡ ợ
|
||||||
|
u ù ú ủ ũ ụ ư ừ ứ ử ữ ự
|
||||||
|
y ỳ ý ỷ ỹ ỵ
|
||||||
|
d đ
|
9
app/src/main/assets/language_key_texts/zu.txt
Normal file
9
app/src/main/assets/language_key_texts/zu.txt
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
[morekeys]
|
||||||
|
a à á â ä æ ã å ā
|
||||||
|
e é è ê ë ē
|
||||||
|
i í î ï ī ì
|
||||||
|
o ó ô ö ò œ ø ō õ
|
||||||
|
u ú û ü ù ū
|
||||||
|
s ß
|
||||||
|
n ñ
|
||||||
|
c ç
|
20
app/src/main/assets/language_key_texts/zz.txt
Normal file
20
app/src/main/assets/language_key_texts/zz.txt
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
[morekeys]
|
||||||
|
a à á â ã ä å æ ā ă ą ª
|
||||||
|
e è é ê ë ē ĕ ė ę ě
|
||||||
|
i ì í î ï ĩ ī ĭ į ı ij
|
||||||
|
o ò ó ô õ ö ø ō ŏ ő œ º
|
||||||
|
u ù ú û ü ũ ū ŭ ů ű ų
|
||||||
|
s ß ś ŝ ş š ſ
|
||||||
|
n ñ ń ņ ň ʼn ŋ
|
||||||
|
c ç ć ĉ ċ č
|
||||||
|
y ý ŷ ÿ ij
|
||||||
|
d ď đ ð
|
||||||
|
r ŕ ŗ ř
|
||||||
|
t þ ţ ť ŧ
|
||||||
|
z ź ż ž
|
||||||
|
k ķ ĸ
|
||||||
|
l ĺ ļ ľ ŀ ł
|
||||||
|
g ĝ ğ ġ ģ
|
||||||
|
h ĥ
|
||||||
|
j ĵ
|
||||||
|
w ŵ
|
29
app/src/main/assets/layouts/bepo.txt
Normal file
29
app/src/main/assets/layouts/bepo.txt
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
b %
|
||||||
|
é \ è
|
||||||
|
p |
|
||||||
|
o =
|
||||||
|
v [
|
||||||
|
d ]
|
||||||
|
l <
|
||||||
|
j >
|
||||||
|
z {
|
||||||
|
w }
|
||||||
|
|
||||||
|
a @
|
||||||
|
u #
|
||||||
|
i $$$
|
||||||
|
e _
|
||||||
|
c &
|
||||||
|
t -
|
||||||
|
s +
|
||||||
|
r (
|
||||||
|
n )
|
||||||
|
m /
|
||||||
|
|
||||||
|
y *
|
||||||
|
x "
|
||||||
|
k '
|
||||||
|
q :
|
||||||
|
g ;
|
||||||
|
h !
|
||||||
|
f ?
|
29
app/src/main/assets/layouts/eo.txt
Normal file
29
app/src/main/assets/layouts/eo.txt
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
ŝ %
|
||||||
|
ĝ \
|
||||||
|
e |
|
||||||
|
r =
|
||||||
|
t [
|
||||||
|
ŭ ]
|
||||||
|
u <
|
||||||
|
i >
|
||||||
|
o {
|
||||||
|
p }
|
||||||
|
|
||||||
|
a @
|
||||||
|
s #
|
||||||
|
d $$$
|
||||||
|
f _
|
||||||
|
g &
|
||||||
|
h -
|
||||||
|
j +
|
||||||
|
k (
|
||||||
|
l )
|
||||||
|
ĵ
|
||||||
|
|
||||||
|
z *
|
||||||
|
ĉ "
|
||||||
|
c '
|
||||||
|
v :
|
||||||
|
b ;
|
||||||
|
n !
|
||||||
|
m ?
|
32
app/src/main/assets/layouts/halmak.txt
Normal file
32
app/src/main/assets/layouts/halmak.txt
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
w %
|
||||||
|
l \
|
||||||
|
r |
|
||||||
|
b =
|
||||||
|
z [
|
||||||
|
; ]
|
||||||
|
q <
|
||||||
|
u >
|
||||||
|
d {
|
||||||
|
j }
|
||||||
|
|
||||||
|
s @
|
||||||
|
h #
|
||||||
|
n $$$
|
||||||
|
t _
|
||||||
|
,
|
||||||
|
.
|
||||||
|
a -
|
||||||
|
e (
|
||||||
|
o )
|
||||||
|
i /
|
||||||
|
|
||||||
|
m *
|
||||||
|
v "
|
||||||
|
c '
|
||||||
|
g :
|
||||||
|
p ;
|
||||||
|
x !
|
||||||
|
k ?
|
||||||
|
|
||||||
|
f
|
||||||
|
y
|
|
@ -11,7 +11,7 @@ p }
|
||||||
|
|
||||||
a @
|
a @
|
||||||
s #
|
s #
|
||||||
d $ €
|
d $$$
|
||||||
f _
|
f _
|
||||||
g &
|
g &
|
||||||
h -
|
h -
|
||||||
|
|
28
app/src/main/assets/layouts/qwertz.txt
Normal file
28
app/src/main/assets/layouts/qwertz.txt
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
q %
|
||||||
|
w \
|
||||||
|
e |
|
||||||
|
r =
|
||||||
|
t [
|
||||||
|
z ]
|
||||||
|
u <
|
||||||
|
i >
|
||||||
|
o {
|
||||||
|
p }
|
||||||
|
|
||||||
|
a @
|
||||||
|
s #
|
||||||
|
d $$$
|
||||||
|
f _
|
||||||
|
g &
|
||||||
|
h -
|
||||||
|
j +
|
||||||
|
k (
|
||||||
|
l )
|
||||||
|
|
||||||
|
y *
|
||||||
|
x "
|
||||||
|
c '
|
||||||
|
v :
|
||||||
|
b ;
|
||||||
|
n !
|
||||||
|
m ?
|
29
app/src/main/assets/layouts/workman.txt
Normal file
29
app/src/main/assets/layouts/workman.txt
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
q %
|
||||||
|
d \
|
||||||
|
r |
|
||||||
|
w =
|
||||||
|
b [
|
||||||
|
j ]
|
||||||
|
f <
|
||||||
|
u >
|
||||||
|
p {
|
||||||
|
; }
|
||||||
|
|
||||||
|
a @
|
||||||
|
s #
|
||||||
|
h $$$
|
||||||
|
t _
|
||||||
|
g &
|
||||||
|
y -
|
||||||
|
n +
|
||||||
|
e (
|
||||||
|
o )
|
||||||
|
i /
|
||||||
|
|
||||||
|
z *
|
||||||
|
x "
|
||||||
|
m '
|
||||||
|
d :
|
||||||
|
v ;
|
||||||
|
k !
|
||||||
|
l ?
|
|
@ -131,7 +131,7 @@ public class Key implements Comparable<Key> {
|
||||||
private static final int MORE_KEYS_FLAGS_NEEDS_DIVIDERS = 0x20000000;
|
private static final int MORE_KEYS_FLAGS_NEEDS_DIVIDERS = 0x20000000;
|
||||||
private static final int MORE_KEYS_FLAGS_NO_PANEL_AUTO_MORE_KEY = 0x10000000;
|
private static final int MORE_KEYS_FLAGS_NO_PANEL_AUTO_MORE_KEY = 0x10000000;
|
||||||
// TODO: Rename these specifiers to !autoOrder! and !fixedOrder! respectively.
|
// TODO: Rename these specifiers to !autoOrder! and !fixedOrder! respectively.
|
||||||
private static final String MORE_KEYS_AUTO_COLUMN_ORDER = "!autoColumnOrder!";
|
public static final String MORE_KEYS_AUTO_COLUMN_ORDER = "!autoColumnOrder!";
|
||||||
private static final String MORE_KEYS_FIXED_COLUMN_ORDER = "!fixedColumnOrder!";
|
private static final String MORE_KEYS_FIXED_COLUMN_ORDER = "!fixedColumnOrder!";
|
||||||
private static final String MORE_KEYS_HAS_LABELS = "!hasLabels!";
|
private static final String MORE_KEYS_HAS_LABELS = "!hasLabels!";
|
||||||
private static final String MORE_KEYS_NEEDS_DIVIDERS = "!needsDividers!";
|
private static final String MORE_KEYS_NEEDS_DIVIDERS = "!needsDividers!";
|
||||||
|
@ -943,7 +943,7 @@ public class Key implements Comparable<Key> {
|
||||||
// for creating keys that might get modified later
|
// for creating keys that might get modified later
|
||||||
public static class KeyParams {
|
public static class KeyParams {
|
||||||
// params for building
|
// params for building
|
||||||
private boolean isSpacer;
|
public boolean isSpacer;
|
||||||
private final KeyboardParams mKeyboardParams; // for reading gaps and keyboard width / height
|
private final KeyboardParams mKeyboardParams; // for reading gaps and keyboard width / height
|
||||||
public float mRelativeWidth;
|
public float mRelativeWidth;
|
||||||
public float mRelativeHeight; // also should allow negative values, indicating absolute height is defined
|
public float mRelativeHeight; // also should allow negative values, indicating absolute height is defined
|
||||||
|
@ -975,8 +975,10 @@ public class Key implements Comparable<Key> {
|
||||||
return keyParams;
|
return keyParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static KeyParams newSpacer(final KeyboardParams params) {
|
public static KeyParams newSpacer(final KeyboardParams params, final float relativeWidth) {
|
||||||
return new KeyParams(params);
|
final KeyParams spacer = new KeyParams(params);
|
||||||
|
spacer.mRelativeWidth = relativeWidth;
|
||||||
|
return spacer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Key createKey() {
|
public Key createKey() {
|
||||||
|
@ -987,7 +989,7 @@ public class Key implements Comparable<Key> {
|
||||||
public void setDimensionsFromRelativeSize(final float newX, final float newY) {
|
public void setDimensionsFromRelativeSize(final float newX, final float newY) {
|
||||||
if (mRelativeHeight == 0)
|
if (mRelativeHeight == 0)
|
||||||
mRelativeHeight = mKeyboardParams.mDefaultRelativeRowHeight;
|
mRelativeHeight = mKeyboardParams.mDefaultRelativeRowHeight;
|
||||||
if (mRelativeWidth == 0)
|
if (!isSpacer && mRelativeWidth == 0)
|
||||||
mRelativeWidth = mKeyboardParams.mDefaultRelativeKeyWidth;
|
mRelativeWidth = mKeyboardParams.mDefaultRelativeKeyWidth;
|
||||||
if (mRelativeHeight < 0)
|
if (mRelativeHeight < 0)
|
||||||
// todo (later): deal with it properly when it needs to be adjusted, i.e. when changing moreKeys or moreSuggestions
|
// todo (later): deal with it properly when it needs to be adjusted, i.e. when changing moreKeys or moreSuggestions
|
||||||
|
@ -998,7 +1000,7 @@ public class Key implements Comparable<Key> {
|
||||||
mFullHeight = mRelativeHeight * mKeyboardParams.mBaseHeight;
|
mFullHeight = mRelativeHeight * mKeyboardParams.mBaseHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getMoreKeysColumnAndFlags(final KeyboardParams params, final String[] moreKeys) {
|
private static int getMoreKeysColumnAndFlagsAndSetNullInArray(final KeyboardParams params, final String[] moreKeys) {
|
||||||
// Get maximum column order number and set a relevant mode value.
|
// Get maximum column order number and set a relevant mode value.
|
||||||
int moreKeysColumnAndFlags = MORE_KEYS_MODE_MAX_COLUMN_WITH_AUTO_ORDER | params.mMaxMoreKeysKeyboardColumn;
|
int moreKeysColumnAndFlags = MORE_KEYS_MODE_MAX_COLUMN_WITH_AUTO_ORDER | params.mMaxMoreKeysKeyboardColumn;
|
||||||
int value;
|
int value;
|
||||||
|
@ -1066,7 +1068,7 @@ public class Key implements Comparable<Key> {
|
||||||
final Locale localeForUpcasing = params.mId.getLocale();
|
final Locale localeForUpcasing = params.mId.getLocale();
|
||||||
int actionFlags = style.getFlags(keyAttr, R.styleable.Keyboard_Key_keyActionFlags);
|
int actionFlags = style.getFlags(keyAttr, R.styleable.Keyboard_Key_keyActionFlags);
|
||||||
String[] moreKeys = style.getStringArray(keyAttr, R.styleable.Keyboard_Key_moreKeys);
|
String[] moreKeys = style.getStringArray(keyAttr, R.styleable.Keyboard_Key_moreKeys);
|
||||||
mMoreKeysColumnAndFlags = getMoreKeysColumnAndFlags(params, moreKeys);
|
mMoreKeysColumnAndFlags = getMoreKeysColumnAndFlagsAndSetNullInArray(params, moreKeys);
|
||||||
|
|
||||||
final String[] additionalMoreKeys;
|
final String[] additionalMoreKeys;
|
||||||
if ((mLabelFlags & LABEL_FLAGS_DISABLE_ADDITIONAL_MORE_KEYS) != 0) {
|
if ((mLabelFlags & LABEL_FLAGS_DISABLE_ADDITIONAL_MORE_KEYS) != 0) {
|
||||||
|
@ -1172,7 +1174,7 @@ public class Key implements Comparable<Key> {
|
||||||
mLabelFlags = labelFlags;
|
mLabelFlags = labelFlags;
|
||||||
mRelativeWidth = relativeWidth;
|
mRelativeWidth = relativeWidth;
|
||||||
mRelativeHeight = params.mDefaultRelativeRowHeight;
|
mRelativeHeight = params.mDefaultRelativeRowHeight;
|
||||||
mMoreKeysColumnAndFlags = getMoreKeysColumnAndFlags(params, layoutMoreKeys);
|
mMoreKeysColumnAndFlags = getMoreKeysColumnAndFlagsAndSetNullInArray(params, layoutMoreKeys);
|
||||||
mIconId = KeySpecParser.getIconId(keySpec);
|
mIconId = KeySpecParser.getIconId(keySpec);
|
||||||
|
|
||||||
final boolean needsToUpcase = needsToUpcase(mLabelFlags, params.mId.mElementId);
|
final boolean needsToUpcase = needsToUpcase(mLabelFlags, params.mId.mElementId);
|
||||||
|
@ -1184,10 +1186,10 @@ public class Key implements Comparable<Key> {
|
||||||
languageMoreKeys = null;
|
languageMoreKeys = null;
|
||||||
} else {
|
} else {
|
||||||
// same style as additionalMoreKeys (i.e. moreKeys with the % placeholder(s))
|
// same style as additionalMoreKeys (i.e. moreKeys with the % placeholder(s))
|
||||||
// todo: read from assets or xml, and cache the results for quick reading again
|
languageMoreKeys = params.mLocaleKeyTexts.getMoreKeys(keySpec);
|
||||||
languageMoreKeys = null; // todo: getLanguageMoreKeys(keySpec, mKeyboardParams.mId.getLocale());
|
|
||||||
}
|
}
|
||||||
final String[] finalMoreKeys = MoreKeySpec.insertAdditionalMoreKeys(languageMoreKeys, layoutMoreKeys);
|
final String[] finalMoreKeys = MoreKeySpec.insertAdditionalMoreKeys(languageMoreKeys, layoutMoreKeys);
|
||||||
|
|
||||||
if (finalMoreKeys != null) {
|
if (finalMoreKeys != null) {
|
||||||
actionFlags |= ACTION_FLAGS_ENABLE_LONG_PRESS;
|
actionFlags |= ACTION_FLAGS_ENABLE_LONG_PRESS;
|
||||||
mMoreKeys = new MoreKeySpec[finalMoreKeys.length];
|
mMoreKeys = new MoreKeySpec[finalMoreKeys.length];
|
||||||
|
@ -1314,7 +1316,7 @@ public class Key implements Comparable<Key> {
|
||||||
|
|
||||||
if (moreKeySpecs != null) {
|
if (moreKeySpecs != null) {
|
||||||
String[] moreKeys = MoreKeySpec.splitKeySpecs(moreKeySpecs);
|
String[] moreKeys = MoreKeySpec.splitKeySpecs(moreKeySpecs);
|
||||||
mMoreKeysColumnAndFlags = getMoreKeysColumnAndFlags(params, moreKeys);
|
mMoreKeysColumnAndFlags = getMoreKeysColumnAndFlagsAndSetNullInArray(params, moreKeys);
|
||||||
|
|
||||||
moreKeys = MoreKeySpec.insertAdditionalMoreKeys(moreKeys, null);
|
moreKeys = MoreKeySpec.insertAdditionalMoreKeys(moreKeys, null);
|
||||||
int actionFlags = 0;
|
int actionFlags = 0;
|
||||||
|
|
|
@ -20,6 +20,7 @@ import android.view.inputmethod.InputMethodSubtype;
|
||||||
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardBuilder;
|
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardBuilder;
|
||||||
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardParams;
|
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardParams;
|
||||||
import org.dslul.openboard.inputmethod.keyboard.internal.UniqueKeysCache;
|
import org.dslul.openboard.inputmethod.keyboard.internal.UniqueKeysCache;
|
||||||
|
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.LocaleKeyTextsKt;
|
||||||
import org.dslul.openboard.inputmethod.latin.InputAttributes;
|
import org.dslul.openboard.inputmethod.latin.InputAttributes;
|
||||||
import org.dslul.openboard.inputmethod.latin.R;
|
import org.dslul.openboard.inputmethod.latin.R;
|
||||||
import org.dslul.openboard.inputmethod.latin.RichInputMethodSubtype;
|
import org.dslul.openboard.inputmethod.latin.RichInputMethodSubtype;
|
||||||
|
@ -127,6 +128,7 @@ public final class KeyboardLayoutSet {
|
||||||
|
|
||||||
public static void onSystemLocaleChanged() {
|
public static void onSystemLocaleChanged() {
|
||||||
clearKeyboardCache();
|
clearKeyboardCache();
|
||||||
|
LocaleKeyTextsKt.clearCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void onKeyboardThemeChanged() {
|
public static void onKeyboardThemeChanged() {
|
||||||
|
|
|
@ -13,8 +13,11 @@ import org.dslul.openboard.inputmethod.keyboard.Key
|
||||||
import org.dslul.openboard.inputmethod.keyboard.Key.KeyParams
|
import org.dslul.openboard.inputmethod.keyboard.Key.KeyParams
|
||||||
import org.dslul.openboard.inputmethod.keyboard.Keyboard
|
import org.dslul.openboard.inputmethod.keyboard.Keyboard
|
||||||
import org.dslul.openboard.inputmethod.keyboard.KeyboardId
|
import org.dslul.openboard.inputmethod.keyboard.KeyboardId
|
||||||
|
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.MORE_KEYS_ALL
|
||||||
|
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.MORE_KEYS_MORE
|
||||||
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.SimpleKeyboardParser
|
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.SimpleKeyboardParser
|
||||||
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.XmlKeyboardParser
|
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.XmlKeyboardParser
|
||||||
|
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.addLocaleKeyTextsToParams
|
||||||
import org.dslul.openboard.inputmethod.latin.R
|
import org.dslul.openboard.inputmethod.latin.R
|
||||||
import org.dslul.openboard.inputmethod.latin.common.Constants
|
import org.dslul.openboard.inputmethod.latin.common.Constants
|
||||||
import org.dslul.openboard.inputmethod.latin.settings.Settings
|
import org.dslul.openboard.inputmethod.latin.settings.Settings
|
||||||
|
@ -46,47 +49,25 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
||||||
|
|
||||||
fun loadSimpleKeyboard(id: KeyboardId): KeyboardBuilder<KP> {
|
fun loadSimpleKeyboard(id: KeyboardId): KeyboardBuilder<KP> {
|
||||||
mParams.mId = id
|
mParams.mId = id
|
||||||
keysInRows = SimpleKeyboardParser(mParams, mContext).parseFromAssets("qwerty")
|
addLocaleKeyTextsToParams(mContext, mParams)
|
||||||
useRelative()
|
when (Settings.getInstance().current.mShowMoreKeys) {
|
||||||
|
MORE_KEYS_ALL -> mParams.mLocaleKeyTexts.addFile(mContext.assets.open("language_key_texts/all_more_keys.txt"))
|
||||||
|
MORE_KEYS_MORE -> mParams.mLocaleKeyTexts.addFile(mContext.assets.open("language_key_texts/more_more_keys.txt"))
|
||||||
|
}
|
||||||
|
keysInRows = SimpleKeyboardParser(mParams, mContext).parseFromAssets(id.mSubtype.keyboardLayoutSetName)
|
||||||
|
determineAbsoluteValues()
|
||||||
|
return this
|
||||||
|
|
||||||
// todo: further plan to make is actually useful
|
// todo: further plan
|
||||||
// create languageMoreKeys list from stuff in keyboard-text tools
|
// add a parser for more complex layouts, and slowly extend it with whatever is needed
|
||||||
// probably use files in assets, and cache them in a weak hash map with localestring as key
|
// initially it's just alternative key for shifted layout
|
||||||
// or better 2 letter code, and join codes when combining languageMoreKeys for multiple locales
|
// so dvorak and azerty and colemak and others can be migrated
|
||||||
// or maybe locale tag, but that's super annoying for api < 24(?)
|
// try to make the format compatible with florisboard
|
||||||
// or no caching if loading and combining is fast anyway (need to test)
|
// migrate symbol layouts to this style
|
||||||
// the locale morekeys then should be a map label -> moreKeys
|
// better before user-defined layouts
|
||||||
// the whole moreKeys map for the current keyboard could be in mParams to simplify access when creating keys
|
// should be straightforward to do
|
||||||
// file format? it's easy to switch, but still... text like above? json?
|
|
||||||
// or use resources? could look like donottranslate-more-keys files
|
|
||||||
// should be possible with configuration and contextThemeWrapper, but probably more complicated than simple files
|
|
||||||
// also would be a bit annoying as it would require to have empty base strings for all possible keys
|
|
||||||
// test first whether something like morekeys_ဂ, or morekeys_ø or better morekeys_ø actually works
|
|
||||||
// if not, definitely don't use resources
|
|
||||||
// consider the % placeholder, this should still be used and documented
|
|
||||||
// though maybe has issues when merging languages?
|
|
||||||
// how to deal with unnecessary moreKeys?
|
|
||||||
// e.g. german should have ö as moreKey on o, but swiss german layout has ö as separate key
|
|
||||||
// still have ö on o (like now), or remove it? or make it optional?
|
|
||||||
// is this handled by KeyboardParams.removeRedundantMoreKeys?
|
|
||||||
// not only moreKeys, also currency key and some labels keys should be translated, though not necessarily in that map
|
|
||||||
// need some placeholder for currency key, like $$$
|
|
||||||
// have an explicit all-more-keys definition, which is created from a script merging all available moreKeys
|
|
||||||
// only letter forms and nothing else, right?
|
|
||||||
// maybe some most-but-not-all? e.g. only all that occur for more than one language
|
|
||||||
// migrate latin layouts to this style (need to make exception for pcqwerty!)
|
|
||||||
// finalize simple layout format
|
|
||||||
// keep like now: nice, because simple and allows defining any number of moreKeys
|
|
||||||
// rows of letters, separated with space: very straightforward, but moreKeys are annoying and only one possible
|
|
||||||
// consider the current layout maybe doesn't have the correct moreKeys
|
|
||||||
// where to actually get the current keyboard layout name, so it can be used to select the correct file?
|
|
||||||
// maybe KeyboardLayoutSet will need to be replaced
|
|
||||||
// need to solve the scaling issue with number row and 5 row keyboards
|
|
||||||
// allow users to switch to old style (keep it until all layouts are switched)
|
|
||||||
// really helps to find differences
|
|
||||||
// add a text that issues / unwanted differences should be reported, as the setting will be removed at some point
|
|
||||||
// label flags to do (top part is for latin!)
|
|
||||||
// allow users to define their own layouts
|
// allow users to define their own layouts
|
||||||
|
// need to solve the scaling issue with number row and 5 row keyboards
|
||||||
// write up how things work for users, also regarding language more keys
|
// write up how things work for users, also regarding language more keys
|
||||||
// readme, maybe also some "help" button in a dialog
|
// readme, maybe also some "help" button in a dialog
|
||||||
// some sort of proper UI, or simply text input?
|
// some sort of proper UI, or simply text input?
|
||||||
|
@ -98,9 +79,22 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
||||||
// need to somehow test for this
|
// need to somehow test for this
|
||||||
// is that autoColumnOrder thing a workaround for that?
|
// is that autoColumnOrder thing a workaround for that?
|
||||||
// still would crash for a single huge label
|
// still would crash for a single huge label
|
||||||
|
// potential keyspec parsing issues:
|
||||||
|
// MoreKeySpec constructor does things like KeySpecParser.getLabel and others
|
||||||
|
// these work with special characters like | and \ doing things depending on their position
|
||||||
|
// if used wrongly, things can crash
|
||||||
|
// -> maybe disable this style of parsing when creating MoreKeySpec of a user-provided layout
|
||||||
|
// or also for the simple layouts, because there is no need to have it in layouts
|
||||||
|
// does the same issue apply to normal key labels?
|
||||||
// popup and (single key) long press preview rescale the label on x only, which may deform emojis
|
// popup and (single key) long press preview rescale the label on x only, which may deform emojis
|
||||||
// migrate symbol layouts to this style
|
// does glide typing work with multiple letters on one key? if not, users should be notified
|
||||||
// maybe allow users to define their own symbol and shift-symbol layouts
|
// maybe allow users to define their own symbol and shift-symbol layouts
|
||||||
|
// allow users to import layouts, which essentially just fills the text from a file
|
||||||
|
// can be json too, but need to have a (close to) final definition first
|
||||||
|
// make the remove duplicate moreKey thing an option?
|
||||||
|
// why is it on for serbian (latin), but not for german (german)?
|
||||||
|
// only nordic and serbian_qwertz layouts have it disabled, default is enabled
|
||||||
|
// -> add the option, but disable it by default for all layouts
|
||||||
// migrate emoji layouts to this style
|
// migrate emoji layouts to this style
|
||||||
// emojis are defined in that string array, should be simple to handle
|
// emojis are defined in that string array, should be simple to handle
|
||||||
// parsing could be done into a single row, which is then split as needed
|
// parsing could be done into a single row, which is then split as needed
|
||||||
|
@ -113,27 +107,23 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
||||||
// migrate keypad layouts to this style
|
// migrate keypad layouts to this style
|
||||||
// will need more configurable layout definition -> another parser
|
// will need more configurable layout definition -> another parser
|
||||||
// migrate moreKeys and moreSuggestions to this style?
|
// migrate moreKeys and moreSuggestions to this style?
|
||||||
// at least they should not make use of the KeyTextsSet/Table and of the XmlKeyboardParser
|
// at least they should not make use of the KeyTextsSet/Table (and of the XmlKeyboardParser?)
|
||||||
// migrate other languages to this style
|
// migrate other languages to this style
|
||||||
// may be difficult in some cases, like additional row, or no shift key, or pc qwerty layout
|
// may be difficult in some cases, like additional row, or no shift key, or pc qwerty layout
|
||||||
// also the (integrated) number row might cause issues
|
// also the (integrated) number row might cause issues
|
||||||
// at least some of these layouts will need more complicated definition, not just a simple text file
|
// at least some of these layouts will need more complicated definition, not just a simple text file
|
||||||
// remove all the keyboard layout related xmls if possible
|
// some languages also change symbol view, e.g. fa changes symbols row 3
|
||||||
// rows_, rowkeys_, row_, kbd_ maybe keyboard_layout_set, keys_, keystyle_, key_
|
// add more layouts before doing this? or just keep the layout conversion script
|
||||||
// and the texts_table and its source tools
|
|
||||||
|
|
||||||
// todo: label flags
|
|
||||||
// alignHintLabelToBottom -> what does it do?
|
|
||||||
// fontNormal -> check / compare turkish layout
|
|
||||||
// fontDefault -> check exclamation and question keys
|
|
||||||
// hasShiftedLetterHint, shiftedLetterActivated -> what is the effect on period key?
|
|
||||||
// labelFlags should be set correctly
|
// labelFlags should be set correctly
|
||||||
// alignHintLabelToBottom: on lxx and rounded themes
|
// alignHintLabelToBottom: on lxx and rounded themes, but did not find what it actually does...
|
||||||
// alignIconToBottom: space_key_for_number_layout
|
// alignIconToBottom: space_key_for_number_layout
|
||||||
// alignLabelOffCenter: number keys in phone layout
|
// alignLabelOffCenter: number keys in phone layout
|
||||||
// fontNormal: turkish (rows 1 and 2 only), .com, emojis, numModeKeyStyle, a bunch of non-latin languages
|
// fontNormal: turkish (rows 1 and 2 only), .com, emojis, numModeKeyStyle, a bunch of non-latin languages
|
||||||
// fontMonoSpace: unused (not really: fontDefault is monospace + normal)
|
// -> switches to normal typeface, only relevant for holo which has bold
|
||||||
|
// fontMonoSpace: unused
|
||||||
// fontDefault: keyExclamationQuestion, a bunch of "normal" keys in fontNormal layouts like thai
|
// fontDefault: keyExclamationQuestion, a bunch of "normal" keys in fontNormal layouts like thai
|
||||||
|
// -> switches to default defined typeface, useful e.g. if row has fontNormal
|
||||||
// followKeyLargeLetterRatio: number keys in number/phone/numpad layouts
|
// followKeyLargeLetterRatio: number keys in number/phone/numpad layouts
|
||||||
// followKeyLetterRatio: mode keys in number layouts, some keys in some non-latin layouts
|
// followKeyLetterRatio: mode keys in number layouts, some keys in some non-latin layouts
|
||||||
// followKeyLabelRatio: enter key, some keys in phone layout (same as followKeyLetterRatio + followKeyLargeLetterRatio)
|
// followKeyLabelRatio: enter key, some keys in phone layout (same as followKeyLetterRatio + followKeyLargeLetterRatio)
|
||||||
|
@ -154,12 +144,18 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
||||||
// maybe remove some of the flags? or keep supporting them?
|
// maybe remove some of the flags? or keep supporting them?
|
||||||
// for pcqwerty: hasShiftedLetterHint -> hasShiftedLetterHint|shiftedLetterActivated when shift is enabled, need to consider if the flag is used
|
// for pcqwerty: hasShiftedLetterHint -> hasShiftedLetterHint|shiftedLetterActivated when shift is enabled, need to consider if the flag is used
|
||||||
// actually period key also has shifted letter hint
|
// actually period key also has shifted letter hint
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadFromXml(xmlId: Int, id: KeyboardId): KeyboardBuilder<KP> {
|
fun loadFromXml(xmlId: Int, id: KeyboardId): KeyboardBuilder<KP> {
|
||||||
mParams.mId = id
|
mParams.mId = id
|
||||||
|
if (Settings.getInstance().current.mUseNewKeyboardParsing
|
||||||
|
&& id.isAlphabetKeyboard
|
||||||
|
&& this::class == KeyboardBuilder::class // otherwise this will apply to moreKeys and moreSuggestions
|
||||||
|
&& SimpleKeyboardParser.hasLayoutFile(mParams.mId.mSubtype.keyboardLayoutSetName)
|
||||||
|
) {
|
||||||
|
loadSimpleKeyboard(id)
|
||||||
|
return this
|
||||||
|
}
|
||||||
// loading a keyboard should set default params like mParams.readAttributes(mContext, attrs);
|
// loading a keyboard should set default params like mParams.readAttributes(mContext, attrs);
|
||||||
// attrs may be null, then default values are used (looks good for "normal" keyboards)
|
// attrs may be null, then default values are used (looks good for "normal" keyboards)
|
||||||
try {
|
try {
|
||||||
|
@ -167,10 +163,10 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
||||||
keysInRows = keyboardParser.parseKeyboard()
|
keysInRows = keyboardParser.parseKeyboard()
|
||||||
}
|
}
|
||||||
} catch (e: XmlPullParserException) {
|
} catch (e: XmlPullParserException) {
|
||||||
Log.w(BUILDER_TAG, "keyboard XML parse error", e)
|
Log.w(TAG, "keyboard XML parse error", e)
|
||||||
throw IllegalArgumentException(e.message, e)
|
throw IllegalArgumentException(e.message, e)
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
Log.w(BUILDER_TAG, "keyboard XML parse error", e)
|
Log.w(TAG, "keyboard XML parse error", e)
|
||||||
throw RuntimeException(e.message, e)
|
throw RuntimeException(e.message, e)
|
||||||
}
|
}
|
||||||
return this
|
return this
|
||||||
|
@ -194,12 +190,11 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
||||||
return Keyboard(mParams)
|
return Keyboard(mParams)
|
||||||
}
|
}
|
||||||
|
|
||||||
// resize keyboard using relative params
|
// determine key size and positions using relative width and height
|
||||||
// ideally this should not change anything
|
// ideally this should not change anything
|
||||||
// but it does a little, depending on how float -> int is done (cast or round, and when to sum up gaps and width)
|
// but it does a little, depending on how float -> int is done (cast or round, and when to sum up gaps and width)
|
||||||
// still should not be more than a pixel difference
|
// still should not be more than a pixel difference
|
||||||
// keep it around for a while, for testing
|
private fun determineAbsoluteValues() {
|
||||||
private fun useRelative() {
|
|
||||||
var currentY = mParams.mTopPadding.toFloat()
|
var currentY = mParams.mTopPadding.toFloat()
|
||||||
for (row in keysInRows) {
|
for (row in keysInRows) {
|
||||||
if (row.isEmpty()) continue
|
if (row.isEmpty()) continue
|
||||||
|
@ -229,10 +224,8 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
||||||
val currentKeyXPos = row[i].xPos
|
val currentKeyXPos = row[i].xPos
|
||||||
if (currentKeyXPos > currentX) {
|
if (currentKeyXPos > currentX) {
|
||||||
// insert spacer
|
// insert spacer
|
||||||
val spacer = KeyParams.newSpacer(mParams)
|
val spacer = KeyParams.newSpacer(mParams, (currentKeyXPos - currentX) / mParams.mBaseWidth)
|
||||||
spacer.mRelativeWidth = (currentKeyXPos - currentX) / mParams.mBaseWidth
|
|
||||||
spacer.yPos = row[i].yPos
|
spacer.yPos = row[i].yPos
|
||||||
spacer.mRelativeHeight = row[i].mRelativeHeight
|
|
||||||
row.add(i, spacer)
|
row.add(i, spacer)
|
||||||
i++
|
i++
|
||||||
currentX += currentKeyXPos - currentX
|
currentX += currentKeyXPos - currentX
|
||||||
|
@ -242,9 +235,7 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
||||||
}
|
}
|
||||||
if (currentX < mParams.mOccupiedWidth) {
|
if (currentX < mParams.mOccupiedWidth) {
|
||||||
// insert spacer
|
// insert spacer
|
||||||
val spacer = KeyParams.newSpacer(mParams)
|
val spacer = KeyParams.newSpacer(mParams, (mParams.mOccupiedWidth - currentX) / mParams.mBaseWidth)
|
||||||
spacer.mRelativeWidth = (mParams.mOccupiedWidth - currentX) / mParams.mBaseWidth
|
|
||||||
spacer.mRelativeHeight = row.last().mRelativeHeight
|
|
||||||
spacer.yPos = row.last().yPos
|
spacer.yPos = row.last().yPos
|
||||||
row.add(spacer)
|
row.add(spacer)
|
||||||
}
|
}
|
||||||
|
@ -253,7 +244,6 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
||||||
private fun addSplit() {
|
private fun addSplit() {
|
||||||
val spacerRelativeWidth = Settings.getInstance().current.mSpacerRelativeWidth
|
val spacerRelativeWidth = Settings.getInstance().current.mSpacerRelativeWidth
|
||||||
// adjust gaps for the whole keyboard, so it's the same for all rows
|
// adjust gaps for the whole keyboard, so it's the same for all rows
|
||||||
// todo: maybe remove? not sure if narrower gaps are desirable
|
|
||||||
mParams.mRelativeHorizontalGap *= 1f / (1f + spacerRelativeWidth)
|
mParams.mRelativeHorizontalGap *= 1f / (1f + spacerRelativeWidth)
|
||||||
mParams.mHorizontalGap = (mParams.mRelativeHorizontalGap * mParams.mId.mWidth).toInt()
|
mParams.mHorizontalGap = (mParams.mRelativeHorizontalGap * mParams.mId.mWidth).toInt()
|
||||||
var maxWidthBeforeSpacer = 0f
|
var maxWidthBeforeSpacer = 0f
|
||||||
|
@ -262,11 +252,9 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
||||||
fillGapsWithSpacers(row)
|
fillGapsWithSpacers(row)
|
||||||
val y = row.first().yPos // all have the same y, so this is fine
|
val y = row.first().yPos // all have the same y, so this is fine
|
||||||
val relativeWidthSum = row.sumOf { it.mRelativeWidth } // sum up relative widths
|
val relativeWidthSum = row.sumOf { it.mRelativeWidth } // sum up relative widths
|
||||||
val spacer = KeyParams.newSpacer(mParams)
|
val spacer = KeyParams.newSpacer(mParams, spacerRelativeWidth)
|
||||||
spacer.mRelativeWidth = spacerRelativeWidth
|
|
||||||
spacer.mRelativeHeight = row.first().mRelativeHeight
|
|
||||||
// insert spacer before first key that starts right of the center (also consider gap)
|
// insert spacer before first key that starts right of the center (also consider gap)
|
||||||
var insertIndex = row.indexOfFirst { it.xPos > mParams.mOccupiedWidth / 2 }
|
var insertIndex = row.indexOfFirst { it.xPos + it.mFullWidth / 3 > mParams.mOccupiedWidth / 2 }
|
||||||
.takeIf { it > -1 } ?: (row.size / 2) // fallback should never be needed, but better than having an error
|
.takeIf { it > -1 } ?: (row.size / 2) // fallback should never be needed, but better than having an error
|
||||||
if (row.any { it.mCode == Constants.CODE_SPACE }) {
|
if (row.any { it.mCode == Constants.CODE_SPACE }) {
|
||||||
val spaceLeft = row.single { it.mCode == Constants.CODE_SPACE }
|
val spaceLeft = row.single { it.mCode == Constants.CODE_SPACE }
|
||||||
|
@ -378,9 +366,6 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
||||||
startRow()
|
startRow()
|
||||||
for (keyParams in row) {
|
for (keyParams in row) {
|
||||||
endKey(keyParams.createKey())
|
endKey(keyParams.createKey())
|
||||||
// todo (later): markAsBottomKey if in bottom row?
|
|
||||||
// this is not done in original parsing style, but why not?
|
|
||||||
// just test it (with different bottom paddings)
|
|
||||||
}
|
}
|
||||||
endRow()
|
endRow()
|
||||||
}
|
}
|
||||||
|
@ -388,6 +373,6 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val BUILDER_TAG = "Keyboard.Builder"
|
private const val TAG = "Keyboard.Builder"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import org.dslul.openboard.inputmethod.keyboard.Key;
|
import org.dslul.openboard.inputmethod.keyboard.Key;
|
||||||
import org.dslul.openboard.inputmethod.keyboard.KeyboardId;
|
import org.dslul.openboard.inputmethod.keyboard.KeyboardId;
|
||||||
|
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.LocaleKeyTexts;
|
||||||
import org.dslul.openboard.inputmethod.latin.R;
|
import org.dslul.openboard.inputmethod.latin.R;
|
||||||
import org.dslul.openboard.inputmethod.latin.common.Constants;
|
import org.dslul.openboard.inputmethod.latin.common.Constants;
|
||||||
import org.dslul.openboard.inputmethod.latin.settings.Settings;
|
import org.dslul.openboard.inputmethod.latin.settings.Settings;
|
||||||
|
@ -84,6 +85,8 @@ public class KeyboardParams {
|
||||||
@NonNull
|
@NonNull
|
||||||
private final UniqueKeysCache mUniqueKeysCache;
|
private final UniqueKeysCache mUniqueKeysCache;
|
||||||
public boolean mAllowRedundantMoreKeys;
|
public boolean mAllowRedundantMoreKeys;
|
||||||
|
@NonNull
|
||||||
|
public LocaleKeyTexts mLocaleKeyTexts;
|
||||||
|
|
||||||
public int mMostCommonKeyHeight = 0;
|
public int mMostCommonKeyHeight = 0;
|
||||||
public int mMostCommonKeyWidth = 0;
|
public int mMostCommonKeyWidth = 0;
|
||||||
|
@ -219,8 +222,10 @@ public class KeyboardParams {
|
||||||
R.styleable.Keyboard_keyboardRightPadding, width, width, 0);
|
R.styleable.Keyboard_keyboardRightPadding, width, width, 0);
|
||||||
|
|
||||||
mBaseWidth = mOccupiedWidth - mLeftPadding - mRightPadding;
|
mBaseWidth = mOccupiedWidth - mLeftPadding - mRightPadding;
|
||||||
|
final float defaultKeyWidthFactor = context.getResources().getInteger(R.integer.config_screen_metrics) > 2
|
||||||
|
? 0.9f : 1f;
|
||||||
mDefaultRelativeKeyWidth = keyAttr.getFraction(R.styleable.Keyboard_Key_keyWidth,
|
mDefaultRelativeKeyWidth = keyAttr.getFraction(R.styleable.Keyboard_Key_keyWidth,
|
||||||
1, 1, 1f / DEFAULT_KEYBOARD_COLUMNS);
|
1, 1, defaultKeyWidthFactor / DEFAULT_KEYBOARD_COLUMNS);
|
||||||
mDefaultKeyWidth = (int) (mDefaultRelativeKeyWidth * mBaseWidth);
|
mDefaultKeyWidth = (int) (mDefaultRelativeKeyWidth * mBaseWidth);
|
||||||
|
|
||||||
// todo: maybe settings should not be accessed from here?
|
// todo: maybe settings should not be accessed from here?
|
||||||
|
|
|
@ -52,7 +52,7 @@ public final class KeyboardTextsSet {
|
||||||
mResourceLocale = SubtypeLocaleUtils.NO_LANGUAGE.equals(locale.toString()) ? null : locale;
|
mResourceLocale = SubtypeLocaleUtils.NO_LANGUAGE.equals(locale.toString()) ? null : locale;
|
||||||
mResourcePackageName = resourcePackageName;
|
mResourcePackageName = resourcePackageName;
|
||||||
mTextsTables.clear();
|
mTextsTables.clear();
|
||||||
if (Settings.getInstance().getCurrent().mShowAllMoreKeys) {
|
if (Settings.getInstance().getCurrent().mShowMoreKeys > 0) {
|
||||||
mTextsTables.add(KeyboardTextsTable.getTextsTable(new Locale(SubtypeLocaleUtils.NO_LANGUAGE)));
|
mTextsTables.add(KeyboardTextsTable.getTextsTable(new Locale(SubtypeLocaleUtils.NO_LANGUAGE)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,228 @@
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
package org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import org.dslul.openboard.inputmethod.keyboard.Key
|
||||||
|
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardParams
|
||||||
|
import org.dslul.openboard.inputmethod.latin.common.splitOnWhitespace
|
||||||
|
import org.dslul.openboard.inputmethod.latin.settings.Settings
|
||||||
|
import java.io.InputStream
|
||||||
|
import java.util.Locale
|
||||||
|
import kotlin.math.round
|
||||||
|
|
||||||
|
class LocaleKeyTexts(dataStream: InputStream?) {
|
||||||
|
private val moreKeys = hashMapOf<String, Array<String>>()
|
||||||
|
private val extraKeys = Array<MutableList<Pair<String, Array<String>?>>?>(5) { null }
|
||||||
|
var labelSymbols = "\\?123"
|
||||||
|
var labelAlphabet = "ABC"
|
||||||
|
var labelShiftSymbols = "=\\<"
|
||||||
|
init {
|
||||||
|
readStream(dataStream, false)
|
||||||
|
// set default quote moreKeys if necessary
|
||||||
|
// should this also be done with punctuation moreKeys??
|
||||||
|
if ("\'" !in moreKeys)
|
||||||
|
moreKeys["\'"] = arrayOf("‚", "‘", "’", "‹", "›")
|
||||||
|
if ("\"" !in moreKeys)
|
||||||
|
moreKeys["\""] = arrayOf("„", "“", "”", "«", "»")
|
||||||
|
if ("!" !in moreKeys)
|
||||||
|
moreKeys["!"] = arrayOf("¡")
|
||||||
|
if ("?" !in moreKeys)
|
||||||
|
moreKeys["?"] = arrayOf("¿")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun readStream(stream: InputStream?, onlyMoreKeys: Boolean) {
|
||||||
|
if (stream == null) return
|
||||||
|
stream.reader().use { reader ->
|
||||||
|
var mode = READER_MODE_NONE
|
||||||
|
val colonSpaceRegex = ":\\s+".toRegex()
|
||||||
|
reader.forEachLine { l ->
|
||||||
|
val line = l.trim()
|
||||||
|
when (line) {
|
||||||
|
"[morekeys]" -> { mode = READER_MODE_MORE_KEYS; return@forEachLine }
|
||||||
|
"[extra_keys]" -> { mode = READER_MODE_EXTRA_KEYS; return@forEachLine }
|
||||||
|
"[labels]" -> { mode = READER_MODE_LABELS; return@forEachLine }
|
||||||
|
}
|
||||||
|
when (mode) {
|
||||||
|
READER_MODE_MORE_KEYS -> addMoreKeys(line.splitOnWhitespace())
|
||||||
|
READER_MODE_EXTRA_KEYS -> if (!onlyMoreKeys) addExtraKey(line.split(colonSpaceRegex, 1))
|
||||||
|
READER_MODE_LABELS -> if (!onlyMoreKeys) addLabel(line.split(colonSpaceRegex, 1))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// need tp provide a copy because some functions like MoreKeySpec.insertAdditionalMoreKeys may modify the array
|
||||||
|
fun getMoreKeys(label: String): Array<String>? = moreKeys[label]?.copyOf()
|
||||||
|
|
||||||
|
fun getExtraKeys(row: Int): List<Pair<String, Array<String>?>>? =
|
||||||
|
if (row > extraKeys.size) null
|
||||||
|
else extraKeys[row]
|
||||||
|
|
||||||
|
fun addFile(dataStream: InputStream?) {
|
||||||
|
readStream(dataStream, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addMoreKeys(split: List<String>) {
|
||||||
|
if (split.size == 1) return
|
||||||
|
val existingMoreKeys = moreKeys[split.first()]
|
||||||
|
if (existingMoreKeys == null)
|
||||||
|
moreKeys[split.first()] = Array(split.size - 1) { split[it + 1] }
|
||||||
|
else
|
||||||
|
moreKeys[split.first()] = mergeMoreKeys(existingMoreKeys, split.drop(1))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addExtraKey(split: List<String>) {
|
||||||
|
if (split.size < 2) return
|
||||||
|
val row = split.first().toIntOrNull() ?: return
|
||||||
|
val keys = split.last().splitOnWhitespace()
|
||||||
|
val morekeys = if (keys.size == 1) null else Array(keys.size - 1) { keys[it + 1] }
|
||||||
|
if (extraKeys[row] == null)
|
||||||
|
extraKeys[row] = mutableListOf()
|
||||||
|
extraKeys[row]?.add(keys.first() to morekeys)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addLabel(split: List<String>) {
|
||||||
|
if (split.size < 2) return
|
||||||
|
when (split.first()) {
|
||||||
|
"symbols" -> labelSymbols = split.last()
|
||||||
|
"alphabet" -> labelAlphabet = split.last()
|
||||||
|
"shift_symbols" -> labelShiftSymbols = split.last()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun mergeMoreKeys(original: Array<String>, added: List<String>): Array<String> {
|
||||||
|
val markerIndexInOriginal = original.indexOf("%")
|
||||||
|
val markerIndexInAddedIndex = added.indexOf("%")
|
||||||
|
val moreKeys = mutableSetOf<String>()
|
||||||
|
if (markerIndexInOriginal != -1 && markerIndexInAddedIndex != -1) {
|
||||||
|
// add original and then added until %
|
||||||
|
original.forEachIndexed { index, s -> if (index < markerIndexInOriginal) moreKeys.add(s) }
|
||||||
|
added.forEachIndexed { index, s -> if (index < markerIndexInAddedIndex) moreKeys.add(s) }
|
||||||
|
// add % and remaining moreKeys
|
||||||
|
original.forEachIndexed { index, s -> if (index >= markerIndexInOriginal) moreKeys.add(s) }
|
||||||
|
added.forEachIndexed { index, s -> if (index > markerIndexInAddedIndex) moreKeys.add(s) }
|
||||||
|
} else if (markerIndexInOriginal != -1) {
|
||||||
|
// add original until %, then added, then remaining original
|
||||||
|
original.forEachIndexed { index, s -> if (index <= markerIndexInOriginal) moreKeys.add(s) }
|
||||||
|
moreKeys.addAll(added)
|
||||||
|
original.forEachIndexed { index, s -> if (index > markerIndexInOriginal) moreKeys.add(s) }
|
||||||
|
} else if (markerIndexInAddedIndex != -1) {
|
||||||
|
// add added until %, then original, then remaining added
|
||||||
|
added.forEachIndexed { index, s -> if (index <= markerIndexInAddedIndex) moreKeys.add(s) }
|
||||||
|
moreKeys.addAll(original)
|
||||||
|
added.forEachIndexed { index, s -> if (index > markerIndexInAddedIndex) moreKeys.add(s) }
|
||||||
|
} else {
|
||||||
|
// use original, then added
|
||||||
|
moreKeys.addAll(original)
|
||||||
|
moreKeys.addAll(added)
|
||||||
|
}
|
||||||
|
// in fact this is only special treatment for the punctuation moreKeys
|
||||||
|
if (moreKeys.any { it.startsWith(Key.MORE_KEYS_AUTO_COLUMN_ORDER) }) {
|
||||||
|
val originalColumnCount = original.firstOrNull { it.startsWith(Key.MORE_KEYS_AUTO_COLUMN_ORDER) }
|
||||||
|
?.substringAfter(Key.MORE_KEYS_AUTO_COLUMN_ORDER)?.toIntOrNull()
|
||||||
|
val l = moreKeys.filterNot { it.startsWith(Key.MORE_KEYS_AUTO_COLUMN_ORDER) }
|
||||||
|
if (originalColumnCount != null && moreKeys.size <= 20 // not for too wide layout
|
||||||
|
&& originalColumnCount == round((original.size - 1 + 0.1f) / 2f).toInt()) { // +0.1 f against rounding issues
|
||||||
|
// we had 2 rows, and want it again
|
||||||
|
return (l + "${Key.MORE_KEYS_AUTO_COLUMN_ORDER}${round(l.size / 2f).toInt()}").toTypedArray()
|
||||||
|
}
|
||||||
|
// just drop autoColumnOrder otherwise (maybe not? depends on arising issues)
|
||||||
|
return l.toTypedArray()
|
||||||
|
}
|
||||||
|
return moreKeys.toTypedArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addLocaleKeyTextsToParams(context: Context, params: KeyboardParams) {
|
||||||
|
val locales = Settings.getInstance().current.mSecondaryLocales + params.mId.locale
|
||||||
|
params.mLocaleKeyTexts = moreKeysAndLabels.getOrPut(locales.joinToString { it.toString() }) {
|
||||||
|
val lkt = LocaleKeyTexts(getStreamForLocale(params.mId.locale, context))
|
||||||
|
locales.forEach { locale ->
|
||||||
|
if (locale == params.mId.locale) return@forEach
|
||||||
|
lkt.addFile(getStreamForLocale(locale, context))
|
||||||
|
}
|
||||||
|
lkt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getStreamForLocale(locale: Locale, context: Context) =
|
||||||
|
try {
|
||||||
|
if (locale.toString() == "zz") context.assets.open("language_key_texts/more_more_keys.txt")
|
||||||
|
else context.assets.open("language_key_texts/${locale.toString().lowercase()}.txt")
|
||||||
|
} catch (_: Exception) {
|
||||||
|
try {
|
||||||
|
context.assets.open("language_key_texts/${locale.language.lowercase()}.txt")
|
||||||
|
} catch (_: Exception) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clearCache() = moreKeysAndLabels.clear()
|
||||||
|
|
||||||
|
// cache the texts, so they don't need to be read over and over
|
||||||
|
private val moreKeysAndLabels = hashMapOf<String, LocaleKeyTexts>()
|
||||||
|
|
||||||
|
private const val READER_MODE_NONE = 0
|
||||||
|
private const val READER_MODE_MORE_KEYS = 1
|
||||||
|
private const val READER_MODE_EXTRA_KEYS = 2
|
||||||
|
private const val READER_MODE_LABELS = 3
|
||||||
|
|
||||||
|
// probably could be improved and extended, currently this is what's done in key_styles_currency.xml
|
||||||
|
fun getCurrencyKey(locale: Locale): Pair<String, Array<String>> {
|
||||||
|
if (locale.country.matches(euroCountries))
|
||||||
|
return euro
|
||||||
|
if (locale.toString().matches(euroLocales))
|
||||||
|
return euro
|
||||||
|
if (locale.language.matches("ca|eu|lb|mt".toRegex()))
|
||||||
|
return euro
|
||||||
|
if (locale.language.matches("fa|iw|ko|lo|mn|ne|th|uk|vi".toRegex()))
|
||||||
|
return genericCurrencyKey(getCurrency(locale))
|
||||||
|
if (locale.language == "hy")
|
||||||
|
return dram
|
||||||
|
if (locale.language == "tr")
|
||||||
|
return lira
|
||||||
|
if (locale.language == "ru")
|
||||||
|
return ruble
|
||||||
|
if (locale.country == "LK" || locale.country == "BD")
|
||||||
|
return genericCurrencyKey(getCurrency(locale))
|
||||||
|
if (locale.country == "IN" || locale.language.matches("hi|kn|ml|mr|ta|te".toRegex()))
|
||||||
|
return rupee
|
||||||
|
if (locale.country == "GB")
|
||||||
|
return pound
|
||||||
|
return genericCurrencyKey("$")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun genericCurrencyKey(currency: String) = currency to genericCurrencyMoreKeys
|
||||||
|
private val genericCurrencyMoreKeys = arrayOf("$", "¢", "£", "€", "¥", "₱")
|
||||||
|
|
||||||
|
private fun getCurrency(locale: Locale): String {
|
||||||
|
if (locale.country == "BD") return "৳"
|
||||||
|
if (locale.country == "LK") return "රු"
|
||||||
|
return when (locale.language) {
|
||||||
|
"fa" -> "﷼"
|
||||||
|
"iw" -> "₪"
|
||||||
|
"ko" -> "₩"
|
||||||
|
"lo" -> "₭"
|
||||||
|
"mn" -> "₮"
|
||||||
|
"ne" -> "रु."
|
||||||
|
"si" -> "රු"
|
||||||
|
"th" -> "฿"
|
||||||
|
"uk" -> "₴"
|
||||||
|
"vi" -> "₫"
|
||||||
|
else -> "$"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// needs at least 4 moreKeys for working shift-symbol keyboard
|
||||||
|
private val euro = "€" to arrayOf("¢", "£", "$", "¥", "₱")
|
||||||
|
private val dram = "֏" to arrayOf("€", "$", "₽", "¥", "£")
|
||||||
|
private val rupee = "₹" to arrayOf("¢", "£", "€", "¥", "₱")
|
||||||
|
private val pound = "£" to arrayOf("¢", "$", "€", "¥", "₱")
|
||||||
|
private val ruble = "₽" to arrayOf("€", "$", "£", "¥")
|
||||||
|
private val lira = "₺" to arrayOf("€", "$", "£", "¥")
|
||||||
|
private val euroCountries = "AD|AT|BE|BG|HR|CY|CZ|DA|EE|FI|FR|DE|GR|HU|IE|IT|XK|LV|LT|LU|MT|MO|ME|NL|PL|PT|RO|SM|SK|SI|ES|VA".toRegex()
|
||||||
|
private val euroLocales = "bg|ca|cs|da|de|el|en|es|et|eu|fi|fr|ga|gl|hr|hu|it|lb|lt|lv|mt|nl|pl|pt|ro|sk|sl|sq|sr|sv".toRegex()
|
||||||
|
|
||||||
|
const val MORE_KEYS_ALL = 2;
|
||||||
|
const val MORE_KEYS_MORE = 1;
|
||||||
|
const val MORE_KEYS_NORMAL = 0;
|
|
@ -2,6 +2,7 @@
|
||||||
package org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser
|
package org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.res.Resources
|
||||||
import android.view.inputmethod.EditorInfo
|
import android.view.inputmethod.EditorInfo
|
||||||
import org.dslul.openboard.inputmethod.keyboard.Key
|
import org.dslul.openboard.inputmethod.keyboard.Key
|
||||||
import org.dslul.openboard.inputmethod.keyboard.Key.KeyParams
|
import org.dslul.openboard.inputmethod.keyboard.Key.KeyParams
|
||||||
|
@ -10,7 +11,9 @@ import org.dslul.openboard.inputmethod.keyboard.KeyboardTheme
|
||||||
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardIconsSet
|
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardIconsSet
|
||||||
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardParams
|
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardParams
|
||||||
import org.dslul.openboard.inputmethod.latin.R
|
import org.dslul.openboard.inputmethod.latin.R
|
||||||
|
import org.dslul.openboard.inputmethod.latin.common.splitOnWhitespace
|
||||||
import org.dslul.openboard.inputmethod.latin.utils.InputTypeUtils
|
import org.dslul.openboard.inputmethod.latin.utils.InputTypeUtils
|
||||||
|
import org.dslul.openboard.inputmethod.latin.utils.RunInLocale
|
||||||
import org.dslul.openboard.inputmethod.latin.utils.sumOf
|
import org.dslul.openboard.inputmethod.latin.utils.sumOf
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,14 +30,25 @@ import org.dslul.openboard.inputmethod.latin.utils.sumOf
|
||||||
*/
|
*/
|
||||||
class SimpleKeyboardParser(private val params: KeyboardParams, private val context: Context) {
|
class SimpleKeyboardParser(private val params: KeyboardParams, private val context: Context) {
|
||||||
|
|
||||||
fun parseFromAssets(layoutName: String) =
|
private var addExtraKeys = false
|
||||||
parse(context.assets.open("layouts/$layoutName.txt").reader().readText())
|
fun parseFromAssets(layoutName: String): ArrayList<ArrayList<KeyParams>> {
|
||||||
|
val layoutFile = when (layoutName) {
|
||||||
|
"nordic" -> { addExtraKeys = true; "qwerty" }
|
||||||
|
"spanish" -> {
|
||||||
|
if (params.mId.locale.language == "eo") "eo" // this behaves a bit different than before, but probably still fine
|
||||||
|
else { addExtraKeys = true; "qwerty" }
|
||||||
|
}
|
||||||
|
"german", "swiss", "serbian_qwertz" -> { addExtraKeys = true; "qwertz" }
|
||||||
|
else -> layoutName
|
||||||
|
}
|
||||||
|
return parse(context.assets.open("layouts/$layoutFile.txt").reader().readText())
|
||||||
|
}
|
||||||
|
|
||||||
fun parse(layoutContent: String): ArrayList<ArrayList<KeyParams>> {
|
fun parse(layoutContent: String): ArrayList<ArrayList<KeyParams>> {
|
||||||
params.readAttributes(context, null)
|
params.readAttributes(context, null)
|
||||||
val keysInRows = ArrayList<ArrayList<KeyParams>>()
|
val keysInRows = ArrayList<ArrayList<KeyParams>>()
|
||||||
|
|
||||||
val baseKeys: MutableList<List<BaseKey>> = parseAdjustablePartOfLayout(layoutContent)
|
val baseKeys: MutableList<List<BaseKey>> = parseCoreLayout(layoutContent)
|
||||||
if (!params.mId.mNumberRowEnabled) {
|
if (!params.mId.mNumberRowEnabled) {
|
||||||
// todo (later): not all layouts have numbers on first row, so maybe have some layout flag to switch it off (or an option)
|
// todo (later): not all layouts have numbers on first row, so maybe have some layout flag to switch it off (or an option)
|
||||||
// but for latin it's fine, so don't care now
|
// but for latin it's fine, so don't care now
|
||||||
|
@ -51,7 +65,14 @@ class SimpleKeyboardParser(private val params: KeyboardParams, private val conte
|
||||||
// are always added to the rows near the bottom
|
// are always added to the rows near the bottom
|
||||||
keysInRows.add(getBottomRowAndAdjustBaseKeys(baseKeys))
|
keysInRows.add(getBottomRowAndAdjustBaseKeys(baseKeys))
|
||||||
|
|
||||||
baseKeys.reversed().forEachIndexed { i, row ->
|
baseKeys.reversed().forEachIndexed { i, it ->
|
||||||
|
val row: List<BaseKey> = if (i == 0) {
|
||||||
|
// add bottom row extra keys
|
||||||
|
it + context.getString(R.string.key_def_extra_bottom_right)
|
||||||
|
.split(",").mapNotNull { if (it.isBlank()) null else BaseKey(it.trim()) }
|
||||||
|
} else {
|
||||||
|
it
|
||||||
|
}
|
||||||
// parse functional keys for this row (if any)
|
// parse functional keys for this row (if any)
|
||||||
val functionalKeysDefs = if (i < functionalKeysReversed.size) functionalKeysReversed[i]
|
val functionalKeysDefs = if (i < functionalKeysReversed.size) functionalKeysReversed[i]
|
||||||
else emptyList<String>() to emptyList()
|
else emptyList<String>() to emptyList()
|
||||||
|
@ -61,38 +82,50 @@ class SimpleKeyboardParser(private val params: KeyboardParams, private val conte
|
||||||
|
|
||||||
// determine key width, maybe scale factor for keys, and spacers to add
|
// determine key width, maybe scale factor for keys, and spacers to add
|
||||||
val usedKeyWidth = params.mDefaultRelativeKeyWidth * row.size
|
val usedKeyWidth = params.mDefaultRelativeKeyWidth * row.size
|
||||||
val availableWidth = 1f - (functionalKeysLeft.sumOf { it.mRelativeWidth }) - (functionalKeysRight.sumOf { it.mRelativeWidth })
|
val functionalKeyWidth = (functionalKeysLeft.sumOf { it.mRelativeWidth }) + (functionalKeysRight.sumOf { it.mRelativeWidth })
|
||||||
val width: Float
|
val availableWidth = 1f - functionalKeyWidth
|
||||||
|
var keyWidth: Float
|
||||||
val spacerWidth: Float
|
val spacerWidth: Float
|
||||||
if (availableWidth - usedKeyWidth > 0.0001f) { // don't add spacers if only a tiny bit is empty
|
if (availableWidth - usedKeyWidth > 0.0001f) { // don't add spacers if only a tiny bit is empty
|
||||||
// width available, add spacer
|
// width available, add spacer
|
||||||
width = params.mDefaultRelativeKeyWidth
|
keyWidth = params.mDefaultRelativeKeyWidth
|
||||||
spacerWidth = (availableWidth - usedKeyWidth) / 2
|
spacerWidth = (availableWidth - usedKeyWidth) / 2
|
||||||
} else {
|
} else {
|
||||||
// need more width, re-scale
|
// need more width, re-scale
|
||||||
spacerWidth = 0f
|
spacerWidth = 0f
|
||||||
width = availableWidth / row.size
|
keyWidth = availableWidth / row.size
|
||||||
}
|
}
|
||||||
if (spacerWidth != 0f) {
|
if (spacerWidth != 0f) {
|
||||||
paramsRow.add(KeyParams.newSpacer(params).apply { mRelativeWidth = spacerWidth })
|
paramsRow.add(KeyParams.newSpacer(params, spacerWidth))
|
||||||
|
}
|
||||||
|
if (keyWidth < params.mDefaultRelativeKeyWidth * 0.82 && spacerWidth == 0f) {
|
||||||
|
// keys are very narrow, also rescale the functional keys to make keys a little wider
|
||||||
|
// 0.82 is just some guess for "too narrow"
|
||||||
|
// todo (maybe): works reasonably well, but actually functional keys could give some more of their width,
|
||||||
|
// as long as they end up above mDefaultRelativeKeyWidth
|
||||||
|
val allKeyScale = 1f / (functionalKeyWidth + row.size * params.mDefaultRelativeKeyWidth)
|
||||||
|
keyWidth = params.mDefaultRelativeKeyWidth * allKeyScale
|
||||||
|
functionalKeysLeft.forEach { it.mRelativeWidth *= allKeyScale }
|
||||||
|
functionalKeysRight.forEach { it.mRelativeWidth *= allKeyScale }
|
||||||
}
|
}
|
||||||
|
|
||||||
for (key in row) {
|
for (key in row) {
|
||||||
paramsRow.add(KeyParams(
|
paramsRow.add(KeyParams(
|
||||||
key.label,
|
key.label,
|
||||||
params,
|
params,
|
||||||
width, // any reasonable way to scale width if there is a long text? might be allowed in user-defined layout
|
keyWidth, // any reasonable way to scale width if there is a long text? might be allowed in user-defined layout
|
||||||
0, // todo: maybe autoScale / autoXScale if label has more than 2 characters (exception for emojis?)
|
0, // todo: maybe autoScale / autoXScale if label has more than 2 characters (exception for emojis?)
|
||||||
Key.BACKGROUND_TYPE_NORMAL,
|
Key.BACKGROUND_TYPE_NORMAL,
|
||||||
key.moreKeys
|
key.moreKeys
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
if (spacerWidth != 0f) {
|
if (spacerWidth != 0f) {
|
||||||
paramsRow.add(KeyParams.newSpacer(params).apply { mRelativeWidth = spacerWidth })
|
paramsRow.add(KeyParams.newSpacer(params, spacerWidth))
|
||||||
}
|
}
|
||||||
functionalKeysRight.forEach { paramsRow.add(it) }
|
functionalKeysRight.forEach { paramsRow.add(it) }
|
||||||
keysInRows.add(0, paramsRow) // we're doing it backwards, so add on top
|
keysInRows.add(0, paramsRow) // we're doing it backwards, so add on top
|
||||||
}
|
}
|
||||||
|
resizeLastNormalRowIfNecessaryForAlignment(keysInRows)
|
||||||
// rescale height if we have more than 4 rows
|
// rescale height if we have more than 4 rows
|
||||||
val heightRescale = if (keysInRows.size > 4) 4f / keysInRows.size else 1f
|
val heightRescale = if (keysInRows.size > 4) 4f / keysInRows.size else 1f
|
||||||
if (params.mId.mNumberRowEnabled)
|
if (params.mId.mNumberRowEnabled)
|
||||||
|
@ -108,13 +141,53 @@ class SimpleKeyboardParser(private val params: KeyboardParams, private val conte
|
||||||
return keysInRows
|
return keysInRows
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseAdjustablePartOfLayout(layoutContent: String) =
|
// resize keys in last row if they are wider than keys in the row above
|
||||||
layoutContent.split("\n\n").mapTo(mutableListOf()) { row -> row.split("\n").mapNotNull {
|
// this is done so the keys align with the keys above
|
||||||
|
// done e.g. for nordic and swiss layouts
|
||||||
|
private fun resizeLastNormalRowIfNecessaryForAlignment(keysInRows: ArrayList<ArrayList<KeyParams>>) {
|
||||||
|
if (keysInRows.size < 3)
|
||||||
|
return
|
||||||
|
val lastNormalRow = keysInRows[keysInRows.lastIndex - 1]
|
||||||
|
val rowAboveLastNormalRow = keysInRows[keysInRows.lastIndex - 2]
|
||||||
|
if (lastNormalRow.any { it.isSpacer } || rowAboveLastNormalRow.any { it.isSpacer })
|
||||||
|
return // annoying to deal with, and probably no resize needed anyway
|
||||||
|
val lastNormalRowKeyWidth = lastNormalRow.first { it.mBackgroundType == Key.BACKGROUND_TYPE_NORMAL }.mRelativeWidth
|
||||||
|
val rowAboveLastNormalRowKeyWidth = rowAboveLastNormalRow.first { it.mBackgroundType == Key.BACKGROUND_TYPE_NORMAL }.mRelativeWidth
|
||||||
|
if (lastNormalRowKeyWidth <= rowAboveLastNormalRowKeyWidth + 0.0001f)
|
||||||
|
return // no need
|
||||||
|
if (lastNormalRow.any { it.mBackgroundType == Key.BACKGROUND_TYPE_NORMAL && it.mRelativeWidth != lastNormalRowKeyWidth })
|
||||||
|
return // normal keys have different width, don't deal with this
|
||||||
|
val numberOfNormalKeys = lastNormalRow.count { it.mBackgroundType == Key.BACKGROUND_TYPE_NORMAL }
|
||||||
|
val widthBefore = numberOfNormalKeys * lastNormalRowKeyWidth
|
||||||
|
val widthAfter = numberOfNormalKeys * rowAboveLastNormalRowKeyWidth
|
||||||
|
val spacerWidth = (widthBefore - widthAfter) / 2
|
||||||
|
// resize keys and add spacers
|
||||||
|
lastNormalRow.forEach { if (it.mBackgroundType == Key.BACKGROUND_TYPE_NORMAL) it.mRelativeWidth = rowAboveLastNormalRowKeyWidth }
|
||||||
|
lastNormalRow.add(lastNormalRow.indexOfFirst { it.mBackgroundType == Key.BACKGROUND_TYPE_NORMAL }, KeyParams.newSpacer(params, spacerWidth))
|
||||||
|
lastNormalRow.add(lastNormalRow.indexOfLast { it.mBackgroundType == Key.BACKGROUND_TYPE_NORMAL } + 1, KeyParams.newSpacer(params, spacerWidth))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun parseCoreLayout(layoutContent: String) =
|
||||||
|
layoutContent.replace("\r\n", "\n").split("\n\n").mapIndexedTo(mutableListOf()) { i, row ->
|
||||||
|
row.split("\n").mapNotNull {
|
||||||
if (it.isBlank()) return@mapNotNull null
|
if (it.isBlank()) return@mapNotNull null
|
||||||
val split = it.split(" ")
|
val split = it.splitOnWhitespace()
|
||||||
val moreKeys = if (split.size == 1) null else Array(split.size - 1) { split[it + 1] }
|
val moreKeys = if (split.size == 1) {
|
||||||
|
null
|
||||||
|
} else if (split.size == 2 && split.last() == "$$$") { // todo: no good reason to ignore it if size > 2
|
||||||
|
// todo (later): could improve handling and show more currency moreKeys, depending on the moreMoreKeys setting
|
||||||
|
if (params.mId.passwordInput())
|
||||||
|
arrayOf("$")
|
||||||
|
else
|
||||||
|
arrayOf(getCurrencyKey(params.mId.locale).first)
|
||||||
|
} else {
|
||||||
|
Array(split.size - 1) { split[it + 1] }
|
||||||
|
}
|
||||||
BaseKey(split.first(), moreKeys)
|
BaseKey(split.first(), moreKeys)
|
||||||
} }
|
} + if (addExtraKeys)
|
||||||
|
(params.mLocaleKeyTexts.getExtraKeys(i + 1)?.let { it.map { BaseKey(it.first, it.second) } } ?: emptyList())
|
||||||
|
else emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
private fun parseFunctionalKeys(): List<Pair<List<String>, List<String>>> =
|
private fun parseFunctionalKeys(): List<Pair<List<String>, List<String>>> =
|
||||||
context.getString(R.string.key_def_functional).split("\n").mapNotNull { line ->
|
context.getString(R.string.key_def_functional).split("\n").mapNotNull { line ->
|
||||||
|
@ -136,7 +209,7 @@ class SimpleKeyboardParser(private val params: KeyboardParams, private val conte
|
||||||
baseKeys.removeLast()
|
baseKeys.removeLast()
|
||||||
val bottomRow = ArrayList<KeyParams>()
|
val bottomRow = ArrayList<KeyParams>()
|
||||||
context.getString(R.string.key_def_bottom_row).split(",").forEach {
|
context.getString(R.string.key_def_bottom_row).split(",").forEach {
|
||||||
val key = it.trim().split(" ").first()
|
val key = it.trim().splitOnWhitespace().first()
|
||||||
val adjustKey = when (key) {
|
val adjustKey = when (key) {
|
||||||
KEY_COMMA -> adjustedKeys?.first()
|
KEY_COMMA -> adjustedKeys?.first()
|
||||||
KEY_PERIOD -> adjustedKeys?.last()
|
KEY_PERIOD -> adjustedKeys?.last()
|
||||||
|
@ -203,7 +276,7 @@ class SimpleKeyboardParser(private val params: KeyboardParams, private val conte
|
||||||
n,
|
n,
|
||||||
params,
|
params,
|
||||||
params.mDefaultRelativeKeyWidth,
|
params.mDefaultRelativeKeyWidth,
|
||||||
Key.LABEL_FLAGS_DISABLE_HINT_LABEL, // todo (later): maybe optional or enable (but then all numbers should have hints)
|
Key.LABEL_FLAGS_DISABLE_HINT_LABEL, // todo (later): maybe optional or enable (but then all numbers should have moreKeys)
|
||||||
Key.BACKGROUND_TYPE_NORMAL,
|
Key.BACKGROUND_TYPE_NORMAL,
|
||||||
numbersMoreKeys[i] // todo (later, non-latin): language may add some (either alt numbers, or latin numbers if they are replaced above, see number todo)
|
numbersMoreKeys[i] // todo (later, non-latin): language may add some (either alt numbers, or latin numbers if they are replaced above, see number todo)
|
||||||
))
|
))
|
||||||
|
@ -213,7 +286,7 @@ class SimpleKeyboardParser(private val params: KeyboardParams, private val conte
|
||||||
|
|
||||||
// for comma and period: label will override default, moreKeys will be appended
|
// for comma and period: label will override default, moreKeys will be appended
|
||||||
private fun getFunctionalKeyParams(def: String, label: String? = null, moreKeys: Array<String>? = null): KeyParams {
|
private fun getFunctionalKeyParams(def: String, label: String? = null, moreKeys: Array<String>? = null): KeyParams {
|
||||||
val split = def.trim().split(" ")
|
val split = def.trim().splitOnWhitespace()
|
||||||
val key = split[0]
|
val key = split[0]
|
||||||
val width = if (split.size == 2) split[1].substringBefore("%").toFloat() / 100f
|
val width = if (split.size == 2) split[1].substringBefore("%").toFloat() / 100f
|
||||||
else params.mDefaultRelativeKeyWidth
|
else params.mDefaultRelativeKeyWidth
|
||||||
|
@ -248,7 +321,7 @@ class SimpleKeyboardParser(private val params: KeyboardParams, private val conte
|
||||||
width,
|
width,
|
||||||
Key.LABEL_FLAGS_HAS_POPUP_HINT or Key.LABEL_FLAGS_HAS_SHIFTED_LETTER_HINT, // todo (later): check what LABEL_FLAGS_HAS_SHIFTED_LETTER_HINT does, maybe remove the flag here
|
Key.LABEL_FLAGS_HAS_POPUP_HINT or Key.LABEL_FLAGS_HAS_SHIFTED_LETTER_HINT, // todo (later): check what LABEL_FLAGS_HAS_SHIFTED_LETTER_HINT does, maybe remove the flag here
|
||||||
if (label?.first()?.isLetter() == true) Key.BACKGROUND_TYPE_NORMAL else Key.BACKGROUND_TYPE_FUNCTIONAL,
|
if (label?.first()?.isLetter() == true) Key.BACKGROUND_TYPE_NORMAL else Key.BACKGROUND_TYPE_FUNCTIONAL,
|
||||||
moreKeys?.let { getPeriodMoreKeys() + it } ?: getPeriodMoreKeys()
|
moreKeys?.let { getPunctuationMoreKeys() + it } ?: getPunctuationMoreKeys()
|
||||||
)
|
)
|
||||||
KEY_ACTION -> KeyParams(
|
KEY_ACTION -> KeyParams(
|
||||||
"${getActionKeyLabel()}|${getActionKeyCode()}",
|
"${getActionKeyLabel()}|${getActionKeyCode()}",
|
||||||
|
@ -293,13 +366,13 @@ class SimpleKeyboardParser(private val params: KeyboardParams, private val conte
|
||||||
KEY_EMOJI_COM -> if (params.mId.mMode == KeyboardId.MODE_URL || params.mId.mMode == KeyboardId.MODE_EMAIL)
|
KEY_EMOJI_COM -> if (params.mId.mMode == KeyboardId.MODE_URL || params.mId.mMode == KeyboardId.MODE_EMAIL)
|
||||||
getFunctionalKeyParams(KEY_COM)
|
getFunctionalKeyParams(KEY_COM)
|
||||||
else getFunctionalKeyParams(KEY_EMOJI)
|
else getFunctionalKeyParams(KEY_EMOJI)
|
||||||
KEY_COM -> KeyParams(
|
KEY_COM -> KeyParams( // todo: label and moreKeys could be in localeKeyTexts
|
||||||
".com", // todo: should depend on language
|
".com",
|
||||||
params,
|
params,
|
||||||
width,
|
width,
|
||||||
Key.LABEL_FLAGS_AUTO_X_SCALE or Key.LABEL_FLAGS_FONT_NORMAL or Key.LABEL_FLAGS_HAS_POPUP_HINT or Key.LABEL_FLAGS_PRESERVE_CASE,
|
Key.LABEL_FLAGS_AUTO_X_SCALE or Key.LABEL_FLAGS_FONT_NORMAL or Key.LABEL_FLAGS_HAS_POPUP_HINT or Key.LABEL_FLAGS_PRESERVE_CASE,
|
||||||
Key.BACKGROUND_TYPE_FUNCTIONAL,
|
Key.BACKGROUND_TYPE_FUNCTIONAL,
|
||||||
arrayOf("!hasLabels!", ".net", ".org", ".gov", ".edu") // todo: maybe should be in languageMoreKeys
|
arrayOf("!hasLabels!", ".net", ".org", ".gov", ".edu")
|
||||||
)
|
)
|
||||||
KEY_LANGUAGE_SWITCH -> KeyParams(
|
KEY_LANGUAGE_SWITCH -> KeyParams(
|
||||||
"!icon/language_switch_key|!code/key_language_switch",
|
"!icon/language_switch_key|!code/key_language_switch",
|
||||||
|
@ -325,22 +398,6 @@ class SimpleKeyboardParser(private val params: KeyboardParams, private val conte
|
||||||
Key.BACKGROUND_TYPE_FUNCTIONAL,
|
Key.BACKGROUND_TYPE_FUNCTIONAL,
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
KEY_EXCLAMATION -> KeyParams(
|
|
||||||
"!",
|
|
||||||
params,
|
|
||||||
width,
|
|
||||||
Key.LABEL_FLAGS_FONT_DEFAULT,
|
|
||||||
Key.BACKGROUND_TYPE_NORMAL,
|
|
||||||
arrayOf("¡") // todo (later) may depend on language
|
|
||||||
)
|
|
||||||
KEY_QUESTION -> KeyParams(
|
|
||||||
"\\?",
|
|
||||||
params,
|
|
||||||
width,
|
|
||||||
Key.LABEL_FLAGS_FONT_DEFAULT,
|
|
||||||
Key.BACKGROUND_TYPE_NORMAL,
|
|
||||||
arrayOf("¿") // todo (later) may depend on language
|
|
||||||
)
|
|
||||||
else -> throw IllegalArgumentException("unknown key definition \"$key\"")
|
else -> throw IllegalArgumentException("unknown key definition \"$key\"")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -370,7 +427,6 @@ class SimpleKeyboardParser(private val params: KeyboardParams, private val conte
|
||||||
"!code/key_shift_enter"
|
"!code/key_shift_enter"
|
||||||
else "!code/key_enter"
|
else "!code/key_enter"
|
||||||
|
|
||||||
|
|
||||||
private fun getActionKeyMoreKeys(): Array<String>? {
|
private fun getActionKeyMoreKeys(): Array<String>? {
|
||||||
val action = params.mId.imeAction()
|
val action = params.mId.imeAction()
|
||||||
val navigatePrev = params.mId.navigatePrevious()
|
val navigatePrev = params.mId.navigatePrevious()
|
||||||
|
@ -431,23 +487,20 @@ class SimpleKeyboardParser(private val params: KeyboardParams, private val conte
|
||||||
private fun String.replaceIconWithLabelIfNoDrawable(): String {
|
private fun String.replaceIconWithLabelIfNoDrawable(): String {
|
||||||
if (params.mIconsSet.getIconDrawable(KeyboardIconsSet.getIconId(this)) != null) return this
|
if (params.mIconsSet.getIconDrawable(KeyboardIconsSet.getIconId(this)) != null) return this
|
||||||
val id = context.resources.getIdentifier("label_$this", "string", context.packageName)
|
val id = context.resources.getIdentifier("label_$this", "string", context.packageName)
|
||||||
return context.getString(id)
|
val ril = object : RunInLocale<String>() { // todo (later): simpler way of doing this in a single line?
|
||||||
|
override fun job(res: Resources) = res.getString(id)
|
||||||
|
}
|
||||||
|
return ril.runInLocale(context.resources, params.mId.locale)
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: may depend on language
|
private fun getAlphabetLabel() = params.mLocaleKeyTexts.labelAlphabet
|
||||||
private fun getAlphabetLabel(): String {
|
|
||||||
return "ABC"
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo: may depend on language
|
private fun getSymbolLabel() = params.mLocaleKeyTexts.labelSymbols
|
||||||
private fun getSymbolLabel(): String {
|
|
||||||
return "\\?123"
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getShiftLabel(): String {
|
private fun getShiftLabel(): String {
|
||||||
val elementId = params.mId.mElementId
|
val elementId = params.mId.mElementId
|
||||||
if (elementId == KeyboardId.ELEMENT_SYMBOLS_SHIFTED)
|
if (elementId == KeyboardId.ELEMENT_SYMBOLS_SHIFTED)
|
||||||
return "=\\<" // todo: may depend on language
|
return params.mLocaleKeyTexts.labelShiftSymbols
|
||||||
if (elementId == KeyboardId.ELEMENT_SYMBOLS)
|
if (elementId == KeyboardId.ELEMENT_SYMBOLS)
|
||||||
return getSymbolLabel()
|
return getSymbolLabel()
|
||||||
if (elementId == KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED || elementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED
|
if (elementId == KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED || elementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED
|
||||||
|
@ -476,16 +529,29 @@ class SimpleKeyboardParser(private val params: KeyboardParams, private val conte
|
||||||
return keys.toTypedArray()
|
return keys.toTypedArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getPeriodMoreKeys(): Array<String> {
|
private fun getPunctuationMoreKeys(): Array<String> {
|
||||||
if (params.mId.mElementId == KeyboardId.ELEMENT_SYMBOLS || params.mId.mElementId == KeyboardId.ELEMENT_SYMBOLS_SHIFTED)
|
if (params.mId.mElementId == KeyboardId.ELEMENT_SYMBOLS || params.mId.mElementId == KeyboardId.ELEMENT_SYMBOLS_SHIFTED)
|
||||||
return arrayOf("…")
|
return arrayOf("…")
|
||||||
// todo: language-dependent, also influences the number after autoColumnOrder
|
val moreKeys = params.mLocaleKeyTexts.getMoreKeys("punctuation") ?:
|
||||||
// there is a weird messup with morekeys_punctuation and morekeys_period
|
// todo: some (non-latin) languages have different parenthesis keys
|
||||||
// by default, morekeys_period is taken from morekeys_punctuation, but some languages override this
|
arrayOf("${Key.MORE_KEYS_AUTO_COLUMN_ORDER}8", "\\,", "?", "!", "#", ")", "(", "/", ";", "'", "@", ":", "-", "\"", "+", "\\%", "&")
|
||||||
// morekeys_period is also changed by some languages
|
if (context.resources.getInteger(R.integer.config_screen_metrics) >= 3 && moreKeys.contains("!") && moreKeys.contains("?")) {
|
||||||
// period key always uses morekeys_period, except for dvorak layout which is the only user of morekeys_punctuation
|
// we have a tablet, remove ! and ? keys and reduce number in autoColumnOrder
|
||||||
// -> clean it up when implementing the language-dependent moreKeys
|
// this makes use of removal of empty moreKeys in MoreKeySpec.insertAdditionalMoreKeys
|
||||||
return arrayOf("!autoColumnOrder!8", "\\,", "?", "!", "#", ")", "(", "/", ";", "'", "@", ":", "-", "\"", "+", "\\%", "&")
|
// todo: maybe do this as part of removing unnecessary moreKeys instead of here?
|
||||||
|
moreKeys[moreKeys.indexOf("!")] = ""
|
||||||
|
moreKeys[moreKeys.indexOf("?")] = ""
|
||||||
|
val columns = moreKeys[0].substringAfter(Key.MORE_KEYS_AUTO_COLUMN_ORDER).toIntOrNull()
|
||||||
|
if (columns != null)
|
||||||
|
moreKeys[0] = "${Key.MORE_KEYS_AUTO_COLUMN_ORDER}${columns - 1}"
|
||||||
|
}
|
||||||
|
return moreKeys
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun hasLayoutFile(layoutName: String) = layoutName in supportedLayouts
|
||||||
|
// todo: adjust when changing layout names, and of course when anything changes...
|
||||||
|
private val supportedLayouts = hashSetOf("qwerty", "qwertz", "halmak", "workman", "bepo", "swiss", "german", "nordic", "spanish", "serbian_qwertz")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -536,5 +602,3 @@ private const val KEY_SHIFT = "shift"
|
||||||
private const val KEY_NUMPAD = "numpad"
|
private const val KEY_NUMPAD = "numpad"
|
||||||
private const val KEY_SYMBOL = "symbol"
|
private const val KEY_SYMBOL = "symbol"
|
||||||
private const val KEY_ALPHA = "alphabet"
|
private const val KEY_ALPHA = "alphabet"
|
||||||
private const val KEY_QUESTION = "question"
|
|
||||||
private const val KEY_EXCLAMATION = "exclamation"
|
|
||||||
|
|
|
@ -609,6 +609,8 @@ public final class StringUtils {
|
||||||
if (label == null || !ScriptUtils.scriptSupportsUppercase(locale)) {
|
if (label == null || !ScriptUtils.scriptSupportsUppercase(locale)) {
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
if (label.equals("ß"))
|
||||||
|
return "ẞ"; // upcasing of standalone ß, SS is not useful as s is on the keyboard anyway
|
||||||
|
|
||||||
return label.toUpperCase(getLocaleUsedForToTitleCase(locale));
|
return label.toUpperCase(getLocaleUsedForToTitleCase(locale));
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -15,8 +15,11 @@ import android.util.Log
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.preference.Preference
|
import androidx.preference.Preference
|
||||||
|
import kotlinx.serialization.encodeToString
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
import org.dslul.openboard.inputmethod.dictionarypack.DictionaryPackConstants
|
import org.dslul.openboard.inputmethod.dictionarypack.DictionaryPackConstants
|
||||||
import org.dslul.openboard.inputmethod.keyboard.KeyboardLayoutSet
|
import org.dslul.openboard.inputmethod.keyboard.KeyboardLayoutSet
|
||||||
|
import org.dslul.openboard.inputmethod.keyboard.KeyboardSwitcher
|
||||||
import org.dslul.openboard.inputmethod.latin.AudioAndHapticFeedbackManager
|
import org.dslul.openboard.inputmethod.latin.AudioAndHapticFeedbackManager
|
||||||
import org.dslul.openboard.inputmethod.latin.BuildConfig
|
import org.dslul.openboard.inputmethod.latin.BuildConfig
|
||||||
import org.dslul.openboard.inputmethod.latin.R
|
import org.dslul.openboard.inputmethod.latin.R
|
||||||
|
@ -24,9 +27,6 @@ import org.dslul.openboard.inputmethod.latin.SystemBroadcastReceiver
|
||||||
import org.dslul.openboard.inputmethod.latin.common.FileUtils
|
import org.dslul.openboard.inputmethod.latin.common.FileUtils
|
||||||
import org.dslul.openboard.inputmethod.latin.define.JniLibName
|
import org.dslul.openboard.inputmethod.latin.define.JniLibName
|
||||||
import org.dslul.openboard.inputmethod.latin.settings.SeekBarDialogPreference.ValueProxy
|
import org.dslul.openboard.inputmethod.latin.settings.SeekBarDialogPreference.ValueProxy
|
||||||
import kotlinx.serialization.encodeToString
|
|
||||||
import kotlinx.serialization.json.Json
|
|
||||||
import org.dslul.openboard.inputmethod.keyboard.KeyboardSwitcher
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileInputStream
|
import java.io.FileInputStream
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
@ -56,8 +56,6 @@ class AdvancedSettingsFragment : SubScreenFragment() {
|
||||||
"userunigram.*/userunigram.*\\.(body|header)".toRegex(),
|
"userunigram.*/userunigram.*\\.(body|header)".toRegex(),
|
||||||
"UserHistoryDictionary.*/UserHistoryDictionary.*\\.(body|header)".toRegex(),
|
"UserHistoryDictionary.*/UserHistoryDictionary.*\\.(body|header)".toRegex(),
|
||||||
"spellcheck_userunigram.*/spellcheck_userunigram.*\\.(body|header)".toRegex(),
|
"spellcheck_userunigram.*/spellcheck_userunigram.*\\.(body|header)".toRegex(),
|
||||||
// todo: found "b.<locale>.dict" folder, where does it come from?
|
|
||||||
// possibly some obfuscation thing that occurred after upgrading to gradle 8?
|
|
||||||
) }
|
) }
|
||||||
|
|
||||||
private val libraryFilePicker = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
private val libraryFilePicker = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||||
|
@ -290,10 +288,9 @@ class AdvancedSettingsFragment : SubScreenFragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSharedPreferenceChanged(prefs: SharedPreferences, key: String?) {
|
override fun onSharedPreferenceChanged(prefs: SharedPreferences, key: String?) {
|
||||||
if (Settings.PREF_SHOW_SETUP_WIZARD_ICON == key) {
|
when (key) {
|
||||||
SystemBroadcastReceiver.toggleAppIcon(requireContext())
|
Settings.PREF_SHOW_SETUP_WIZARD_ICON -> SystemBroadcastReceiver.toggleAppIcon(requireContext())
|
||||||
} else if (Settings.PREF_SHOW_ALL_MORE_KEYS == key) {
|
Settings.PREF_MORE_MORE_KEYS, Settings.PREF_USE_NEW_KEYBOARD_PARSING -> KeyboardLayoutSet.onSystemLocaleChanged()
|
||||||
KeyboardLayoutSet.onKeyboardThemeChanged()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
package org.dslul.openboard.inputmethod.latin.settings
|
package org.dslul.openboard.inputmethod.latin.settings
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
@ -18,6 +17,7 @@ import androidx.core.view.isGone
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.core.view.size
|
import androidx.core.view.size
|
||||||
import org.dslul.openboard.inputmethod.dictionarypack.DictionaryPackConstants
|
import org.dslul.openboard.inputmethod.dictionarypack.DictionaryPackConstants
|
||||||
|
import org.dslul.openboard.inputmethod.keyboard.KeyboardLayoutSet
|
||||||
import org.dslul.openboard.inputmethod.latin.BinaryDictionaryGetter
|
import org.dslul.openboard.inputmethod.latin.BinaryDictionaryGetter
|
||||||
import org.dslul.openboard.inputmethod.latin.R
|
import org.dslul.openboard.inputmethod.latin.R
|
||||||
import org.dslul.openboard.inputmethod.latin.common.LocaleUtils
|
import org.dslul.openboard.inputmethod.latin.common.LocaleUtils
|
||||||
|
@ -182,9 +182,11 @@ class LanguageSettingsDialog(
|
||||||
Settings.setSecondaryLocales(prefs, mainLocaleString, localeStrings - locale.toString())
|
Settings.setSecondaryLocales(prefs, mainLocaleString, localeStrings - locale.toString())
|
||||||
binding.secondaryLocales.removeView(rowBinding.root)
|
binding.secondaryLocales.removeView(rowBinding.root)
|
||||||
reloadSetting()
|
reloadSetting()
|
||||||
|
KeyboardLayoutSet.onSystemLocaleChanged()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
binding.secondaryLocales.addView(rowBinding.root)
|
binding.secondaryLocales.addView(rowBinding.root)
|
||||||
|
KeyboardLayoutSet.onSystemLocaleChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun fillDictionariesView() {
|
private fun fillDictionariesView() {
|
||||||
|
|
|
@ -24,6 +24,7 @@ import androidx.annotation.NonNull;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
import org.dslul.openboard.inputmethod.keyboard.KeyboardTheme;
|
import org.dslul.openboard.inputmethod.keyboard.KeyboardTheme;
|
||||||
|
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.LocaleKeyTextsKt;
|
||||||
import org.dslul.openboard.inputmethod.latin.AudioAndHapticFeedbackManager;
|
import org.dslul.openboard.inputmethod.latin.AudioAndHapticFeedbackManager;
|
||||||
import org.dslul.openboard.inputmethod.latin.InputAttributes;
|
import org.dslul.openboard.inputmethod.latin.InputAttributes;
|
||||||
import org.dslul.openboard.inputmethod.latin.R;
|
import org.dslul.openboard.inputmethod.latin.R;
|
||||||
|
@ -102,6 +103,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
||||||
public static final String PREF_GESTURE_FLOATING_PREVIEW_TEXT = "pref_gesture_floating_preview_text";
|
public static final String PREF_GESTURE_FLOATING_PREVIEW_TEXT = "pref_gesture_floating_preview_text";
|
||||||
public static final String PREF_GESTURE_SPACE_AWARE = "pref_gesture_space_aware";
|
public static final String PREF_GESTURE_SPACE_AWARE = "pref_gesture_space_aware";
|
||||||
public static final String PREF_SHOW_SETUP_WIZARD_ICON = "pref_show_setup_wizard_icon";
|
public static final String PREF_SHOW_SETUP_WIZARD_ICON = "pref_show_setup_wizard_icon";
|
||||||
|
public static final String PREF_USE_NEW_KEYBOARD_PARSING = "pref_use_new_keyboard_parsing"; // todo: remove later
|
||||||
|
|
||||||
public static final String PREF_ONE_HANDED_MODE = "pref_one_handed_mode_enabled";
|
public static final String PREF_ONE_HANDED_MODE = "pref_one_handed_mode_enabled";
|
||||||
public static final String PREF_ONE_HANDED_GRAVITY = "pref_one_handed_mode_gravity";
|
public static final String PREF_ONE_HANDED_GRAVITY = "pref_one_handed_mode_gravity";
|
||||||
|
@ -124,7 +126,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
||||||
public static final String PREF_ENABLED_INPUT_STYLES = "pref_enabled_input_styles";
|
public static final String PREF_ENABLED_INPUT_STYLES = "pref_enabled_input_styles";
|
||||||
public static final String PREF_SELECTED_INPUT_STYLE = "pref_selected_input_style";
|
public static final String PREF_SELECTED_INPUT_STYLE = "pref_selected_input_style";
|
||||||
public static final String PREF_USE_SYSTEM_LOCALES = "pref_use_system_locales";
|
public static final String PREF_USE_SYSTEM_LOCALES = "pref_use_system_locales";
|
||||||
public static final String PREF_SHOW_ALL_MORE_KEYS = "pref_show_all_more_keys";
|
public static final String PREF_MORE_MORE_KEYS = "pref_more_more_keys";
|
||||||
public static final String PREF_URL_DETECTION = "pref_url_detection";
|
public static final String PREF_URL_DETECTION = "pref_url_detection";
|
||||||
|
|
||||||
public static final String PREF_DONT_SHOW_MISSING_DICTIONARY_DIALOG = "pref_dont_show_missing_dict_dialog";
|
public static final String PREF_DONT_SHOW_MISSING_DICTIONARY_DIALOG = "pref_dont_show_missing_dict_dialog";
|
||||||
|
@ -469,6 +471,14 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
||||||
prefs.edit().putString(Settings.PREF_PINNED_KEYS, String.join(";", keys)).apply();
|
prefs.edit().putString(Settings.PREF_PINNED_KEYS, String.join(";", keys)).apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int readMoreMoreKeysPref(final SharedPreferences prefs) {
|
||||||
|
return switch (prefs.getString(Settings.PREF_MORE_MORE_KEYS, "normal")) {
|
||||||
|
case "all" -> LocaleKeyTextsKt.MORE_KEYS_ALL;
|
||||||
|
case "more" -> LocaleKeyTextsKt.MORE_KEYS_MORE;
|
||||||
|
default -> LocaleKeyTextsKt.MORE_KEYS_NORMAL;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public static List<Locale> getSecondaryLocales(final SharedPreferences prefs, final String mainLocaleString) {
|
public static List<Locale> getSecondaryLocales(final SharedPreferences prefs, final String mainLocaleString) {
|
||||||
final String localesString = prefs.getString(PREF_SECONDARY_LOCALES_PREFIX + mainLocaleString.toLowerCase(Locale.ROOT), "");
|
final String localesString = prefs.getString(PREF_SECONDARY_LOCALES_PREFIX + mainLocaleString.toLowerCase(Locale.ROOT), "");
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import org.dslul.openboard.inputmethod.compat.AppWorkaroundsUtils;
|
import org.dslul.openboard.inputmethod.compat.AppWorkaroundsUtils;
|
||||||
|
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.LocaleKeyTextsKt;
|
||||||
import org.dslul.openboard.inputmethod.latin.InputAttributes;
|
import org.dslul.openboard.inputmethod.latin.InputAttributes;
|
||||||
import org.dslul.openboard.inputmethod.latin.R;
|
import org.dslul.openboard.inputmethod.latin.R;
|
||||||
import org.dslul.openboard.inputmethod.latin.RichInputMethodManager;
|
import org.dslul.openboard.inputmethod.latin.RichInputMethodManager;
|
||||||
|
@ -79,7 +80,7 @@ public class SettingsValues {
|
||||||
public final boolean mOneHandedModeEnabled;
|
public final boolean mOneHandedModeEnabled;
|
||||||
public final int mOneHandedModeGravity;
|
public final int mOneHandedModeGravity;
|
||||||
public final boolean mNarrowKeyGaps;
|
public final boolean mNarrowKeyGaps;
|
||||||
public final boolean mShowAllMoreKeys;
|
public final int mShowMoreKeys;
|
||||||
public final List<Locale> mSecondaryLocales;
|
public final List<Locale> mSecondaryLocales;
|
||||||
// Use bigrams to predict the next word when there is no input for it yet
|
// Use bigrams to predict the next word when there is no input for it yet
|
||||||
public final boolean mBigramPredictionEnabled;
|
public final boolean mBigramPredictionEnabled;
|
||||||
|
@ -104,6 +105,7 @@ public class SettingsValues {
|
||||||
public final boolean mUrlDetectionEnabled;
|
public final boolean mUrlDetectionEnabled;
|
||||||
public final List<String> mPinnedKeys;
|
public final List<String> mPinnedKeys;
|
||||||
public final float mBottomPaddingScale;
|
public final float mBottomPaddingScale;
|
||||||
|
public final boolean mUseNewKeyboardParsing;
|
||||||
|
|
||||||
// From the input box
|
// From the input box
|
||||||
@NonNull
|
@NonNull
|
||||||
|
@ -215,7 +217,9 @@ public class SettingsValues {
|
||||||
mOneHandedModeGravity = Settings.readOneHandedModeGravity(prefs);
|
mOneHandedModeGravity = Settings.readOneHandedModeGravity(prefs);
|
||||||
final InputMethodSubtype selectedSubtype = SubtypeSettingsKt.getSelectedSubtype(prefs);
|
final InputMethodSubtype selectedSubtype = SubtypeSettingsKt.getSelectedSubtype(prefs);
|
||||||
mSecondaryLocales = Settings.getSecondaryLocales(prefs, selectedSubtype.getLocale());
|
mSecondaryLocales = Settings.getSecondaryLocales(prefs, selectedSubtype.getLocale());
|
||||||
mShowAllMoreKeys = selectedSubtype.isAsciiCapable() && prefs.getBoolean(Settings.PREF_SHOW_ALL_MORE_KEYS, false);
|
mShowMoreKeys = selectedSubtype.isAsciiCapable()
|
||||||
|
? Settings.readMoreMoreKeysPref(prefs)
|
||||||
|
: LocaleKeyTextsKt.MORE_KEYS_NORMAL;
|
||||||
mColors = Settings.getColorsForCurrentTheme(context, prefs);
|
mColors = Settings.getColorsForCurrentTheme(context, prefs);
|
||||||
|
|
||||||
mAddToPersonalDictionary = prefs.getBoolean(Settings.PREF_ADD_TO_PERSONAL_DICTIONARY, false);
|
mAddToPersonalDictionary = prefs.getBoolean(Settings.PREF_ADD_TO_PERSONAL_DICTIONARY, false);
|
||||||
|
@ -230,6 +234,7 @@ public class SettingsValues {
|
||||||
mPinnedKeys = Settings.readPinnedKeys(prefs);
|
mPinnedKeys = Settings.readPinnedKeys(prefs);
|
||||||
mSpacingAndPunctuations = new SpacingAndPunctuations(res, mUrlDetectionEnabled);
|
mSpacingAndPunctuations = new SpacingAndPunctuations(res, mUrlDetectionEnabled);
|
||||||
mBottomPaddingScale = prefs.getFloat(Settings.PREF_BOTTOM_PADDING_SCALE, DEFAULT_SIZE_SCALE);
|
mBottomPaddingScale = prefs.getFloat(Settings.PREF_BOTTOM_PADDING_SCALE, DEFAULT_SIZE_SCALE);
|
||||||
|
mUseNewKeyboardParsing = prefs.getBoolean(Settings.PREF_USE_NEW_KEYBOARD_PARSING, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isApplicationSpecifiedCompletionsOn() {
|
public boolean isApplicationSpecifiedCompletionsOn() {
|
||||||
|
|
|
@ -89,8 +89,6 @@
|
||||||
<string name="space_trackpad_summary">কার্সর সরানোর জন্য স্পেসবারে সোয়াইপ করুন</string>
|
<string name="space_trackpad_summary">কার্সর সরানোর জন্য স্পেসবারে সোয়াইপ করুন</string>
|
||||||
<string name="autospace_after_punctuation">যতিচিহ্নের পরে স্বয়ংক্রিয় স্পেস</string>
|
<string name="autospace_after_punctuation">যতিচিহ্নের পরে স্বয়ংক্রিয় স্পেস</string>
|
||||||
<string name="autospace_after_punctuation_summary">নতুন শব্দ লেখার সময় যতিচিহ্নের পরে স্বয়ংক্রিয়ভাবে স্পেস বসবে</string>
|
<string name="autospace_after_punctuation_summary">নতুন শব্দ লেখার সময় যতিচিহ্নের পরে স্বয়ংক্রিয়ভাবে স্পেস বসবে</string>
|
||||||
<string name="show_all_more_keys_title">পপআপে সব অক্ষর প্রদর্শন</string>
|
|
||||||
<string name="show_all_more_keys_summary">ল্যাটিন কিবোর্ড ব্যবহারের সময় বোতামে দীর্ঘ চাপে বেশি অক্ষর দেখাবে</string>
|
|
||||||
<string name="url_detection_title">ইউআরএল শনাক্তকরণ</string>
|
<string name="url_detection_title">ইউআরএল শনাক্তকরণ</string>
|
||||||
<string name="url_detection_summary">ইউআরএল এবং অনুরূপ একটি একক শব্দ হিসেবে শনাক্ত করার চেষ্টা করবে</string>
|
<string name="url_detection_summary">ইউআরএল এবং অনুরূপ একটি একক শব্দ হিসেবে শনাক্ত করার চেষ্টা করবে</string>
|
||||||
<string name="prefs_force_incognito_mode">ছদ্মবেশী মোড আরোপ</string>
|
<string name="prefs_force_incognito_mode">ছদ্মবেশী মোড আরোপ</string>
|
||||||
|
|
|
@ -257,8 +257,6 @@ Nouveau dictionnaire:
|
||||||
<string name="subtype_with_layout_bn_BD"><xliff:g id="LANGUAGE_NAME" example="Bangla">%s</xliff:g> (Akkhor)</string>
|
<string name="subtype_with_layout_bn_BD"><xliff:g id="LANGUAGE_NAME" example="Bangla">%s</xliff:g> (Akkhor)</string>
|
||||||
<string name="autospace_after_punctuation">Espace automatique après la ponctuation</string>
|
<string name="autospace_after_punctuation">Espace automatique après la ponctuation</string>
|
||||||
<string name="autospace_after_punctuation_summary">Insertion automatique d\'un espace après la ponctuation lors de la saisie d\'un nouveau mot</string>
|
<string name="autospace_after_punctuation_summary">Insertion automatique d\'un espace après la ponctuation lors de la saisie d\'un nouveau mot</string>
|
||||||
<string name="show_all_more_keys_title">Afficher tous les caractères dans les popups</string>
|
|
||||||
<string name="show_all_more_keys_summary">Lorsque l\'on utilise un clavier latin, un appui long sur une touche permet d\'obtenir davantage de caractères</string>
|
|
||||||
<string name="url_detection_title">Détection d\'URL</string>
|
<string name="url_detection_title">Détection d\'URL</string>
|
||||||
<string name="url_detection_summary">Essaye de détecter les URL et autres éléments similaires comme un seul mot</string>
|
<string name="url_detection_summary">Essaye de détecter les URL et autres éléments similaires comme un seul mot</string>
|
||||||
<string name="use_system_language_to_select_input_method_subtypes">"Utiliser les langues du système"</string>
|
<string name="use_system_language_to_select_input_method_subtypes">"Utiliser les langues du système"</string>
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
<resources>
|
<resources>
|
||||||
<string name="key_def_functional">";delete 10%
|
<string name="key_def_functional">";delete 10%
|
||||||
;action 10%
|
;action 10%
|
||||||
shift 10%; exclamation, question, shift"</string>
|
shift 10%; shift"</string>
|
||||||
|
<string name="key_def_extra_bottom_right">"!, ?"</string>
|
||||||
<string name="key_def_bottom_row">"symbol, comma, space, period, emoji_com"</string>
|
<string name="key_def_bottom_row">"symbol, comma, space, period, emoji_com"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -145,4 +145,14 @@
|
||||||
<item>@string/language_switch_key_switch_input_method</item>
|
<item>@string/language_switch_key_switch_input_method</item>
|
||||||
<item>@string/language_switch_key_switch_both</item>
|
<item>@string/language_switch_key_switch_both</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
<string-array name="show_more_keys_values">
|
||||||
|
<item>normal</item>
|
||||||
|
<item>more</item>
|
||||||
|
<item>all</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="show_more_keys_entries">
|
||||||
|
<item>@string/show_more_keys_normal</item>
|
||||||
|
<item>@string/show_more_keys_more</item>
|
||||||
|
<item>@string/show_more_keys_all</item>
|
||||||
|
</string-array>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -7,6 +7,10 @@
|
||||||
Width (in percent of keyboard width) can be appended to the key name, defaults to default key width
|
Width (in percent of keyboard width) can be appended to the key name, defaults to default key width
|
||||||
-->
|
-->
|
||||||
<string name="key_def_functional" translatable="false">"shift 15%; delete 15%"</string>
|
<string name="key_def_functional" translatable="false">"shift 15%; delete 15%"</string>
|
||||||
|
<!--
|
||||||
|
Extra keys to be inserted at the right side into row above space (only labels, comma-separated)
|
||||||
|
-->
|
||||||
|
<string name="key_def_extra_bottom_right" translatable="false">""</string>
|
||||||
<!--
|
<!--
|
||||||
Bottom row definition is similar to functional key definition, but only one row, and not
|
Bottom row definition is similar to functional key definition, but only one row, and not
|
||||||
split into two groups. Space bar will be adjusted in code for language and emoji keys,
|
split into two groups. Space bar will be adjusted in code for language and emoji keys,
|
||||||
|
|
|
@ -160,6 +160,10 @@
|
||||||
<string name="space_language_slide">Space bar language slide</string>
|
<string name="space_language_slide">Space bar language slide</string>
|
||||||
<!-- Description for "space_language_slide" option. -->
|
<!-- Description for "space_language_slide" option. -->
|
||||||
<string name="space_language_slide_summary">Swipe upwards on the spacebar to change the language</string>
|
<string name="space_language_slide_summary">Swipe upwards on the spacebar to change the language</string>
|
||||||
|
<!-- Preferences item for enabling the simplified keyboard parser and future other parsers (will be removed after some testing) -->
|
||||||
|
<string name="use_new_keyboard_parsing">Use new keyboard parser</string>
|
||||||
|
<!-- Description for "use_new_keyboard_parsing" option (will be removed after some testing) -->
|
||||||
|
<string name="use_new_keyboard_parsing_summary">Use this setting if you encounter issues with changed keyboard layouts (please report the problem). This setting will be removed at some point.</string>
|
||||||
<!-- Preferences item and dialog title for backup and restore -->
|
<!-- Preferences item and dialog title for backup and restore -->
|
||||||
<string name="backup_restore_title">Backup and restore</string>
|
<string name="backup_restore_title">Backup and restore</string>
|
||||||
<!-- Message for backup and restore dialog -->
|
<!-- Message for backup and restore dialog -->
|
||||||
|
@ -189,10 +193,14 @@
|
||||||
<string name="autospace_after_punctuation">Autospace after punctuation</string>
|
<string name="autospace_after_punctuation">Autospace after punctuation</string>
|
||||||
<!-- Description for "insert_more_spaces" option. -->
|
<!-- Description for "insert_more_spaces" option. -->
|
||||||
<string name="autospace_after_punctuation_summary">Automatically insert space after punctuation when typing a new word</string>
|
<string name="autospace_after_punctuation_summary">Automatically insert space after punctuation when typing a new word</string>
|
||||||
<!-- Preferences item for showing all available keys in long-press popup -->
|
<!-- Preferences item for showing more keys in long-press popup -->
|
||||||
<string name="show_all_more_keys_title">Show all keys in popup</string>
|
<string name="show_more_keys_title">Show more letters with diacritics in popup</string>
|
||||||
<!-- Description for "show_all_more_keys" option. -->
|
<!-- Option for showing only letters defined in the current language file in long-press popup -->
|
||||||
<string name="show_all_more_keys_summary">When using a latin keyboard, more characters are available on long-pressing a key</string>
|
<string name="show_more_keys_normal">Show variants defined in keyboard languages (default)</string>
|
||||||
|
<!-- Option for showing letters defined in at least two locales -->
|
||||||
|
<string name="show_more_keys_more">Add common variants</string>
|
||||||
|
<!-- Option for showing letters defined in any locale -->
|
||||||
|
<string name="show_more_keys_all">Add all available variants</string>
|
||||||
<!-- Preferences item for enabling URL detection -->
|
<!-- Preferences item for enabling URL detection -->
|
||||||
<string name="url_detection_title">URL detection</string>
|
<string name="url_detection_title">URL detection</string>
|
||||||
<!-- Description for "url_detection_title" option. -->
|
<!-- Description for "url_detection_title" option. -->
|
||||||
|
|
|
@ -56,6 +56,15 @@
|
||||||
android:defaultValue="true"
|
android:defaultValue="true"
|
||||||
android:persistent="true" />
|
android:persistent="true" />
|
||||||
|
|
||||||
|
<ListPreference
|
||||||
|
android:key="pref_more_more_keys"
|
||||||
|
android:title="@string/show_more_keys_title"
|
||||||
|
android:entries="@array/show_more_keys_entries"
|
||||||
|
android:entryValues="@array/show_more_keys_values"
|
||||||
|
android:defaultValue="normal"
|
||||||
|
android:summary="%s"
|
||||||
|
android:persistent="true" />
|
||||||
|
|
||||||
<Preference
|
<Preference
|
||||||
android:key="pref_backup_restore"
|
android:key="pref_backup_restore"
|
||||||
android:title="@string/backup_restore_title" />
|
android:title="@string/backup_restore_title" />
|
||||||
|
@ -70,18 +79,18 @@
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
android:title="@string/settings_category_experimental">
|
android:title="@string/settings_category_experimental">
|
||||||
|
|
||||||
|
<SwitchPreferenceCompat
|
||||||
|
android:key="pref_use_new_keyboard_parsing"
|
||||||
|
android:title="@string/use_new_keyboard_parsing"
|
||||||
|
android:summary="@string/use_new_keyboard_parsing_summary"
|
||||||
|
android:defaultValue="true" />
|
||||||
|
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
android:key="pref_space_language_slide"
|
android:key="pref_space_language_slide"
|
||||||
android:title="@string/space_language_slide"
|
android:title="@string/space_language_slide"
|
||||||
android:summary="@string/space_language_slide_summary"
|
android:summary="@string/space_language_slide_summary"
|
||||||
android:defaultValue="false" />
|
android:defaultValue="false" />
|
||||||
|
|
||||||
<SwitchPreferenceCompat
|
|
||||||
android:key="pref_show_all_more_keys"
|
|
||||||
android:title="@string/show_all_more_keys_title"
|
|
||||||
android:summary="@string/show_all_more_keys_summary"
|
|
||||||
android:defaultValue="false" />
|
|
||||||
|
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
android:key="pref_url_detection"
|
android:key="pref_url_detection"
|
||||||
android:title="@string/url_detection_title"
|
android:title="@string/url_detection_title"
|
||||||
|
|
9
layouts.md
Normal file
9
layouts.md
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# Layouts
|
||||||
|
|
||||||
|
(WIP) information about the layout format
|
||||||
|
|
||||||
|
## simple
|
||||||
|
One key per line, two consecutive newlines mark a row end.
|
||||||
|
Key format: [label] [moreKeys], all separated by space, e.g. `a 0 + *` will create a key with text a, and the keys `0`, `+`, and `*` on long press. Some characters currently require escape using `\` (todo: add the list, or better add them in code instead of requiring it in the layouts).
|
||||||
|
Special symbols: `%` (only for language-dependent moreKeys, not user defined, also better use sth like `%%%`) acts as placeholder for normal moreKeys. `$$$` will be replaced by currency (or default to `$`).
|
||||||
|
Language-dependent moreKeys should never contain "special" moreKeys, i.e. those starting with `!` (exception for `punctuation`)
|
245
tools/morekeys_reader.py
Normal file
245
tools/morekeys_reader.py
Normal file
|
@ -0,0 +1,245 @@
|
||||||
|
#!/bin/python
|
||||||
|
import pathlib
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
import langcodes
|
||||||
|
import re
|
||||||
|
|
||||||
|
# (WIP) script for reading moreKeys from tools used to create KeyTextsTable while resolving "!text/" references
|
||||||
|
# plan is to create a straightforward moreKeys file per language
|
||||||
|
xml_folder = "make-keyboard-text/src/main/resources/"
|
||||||
|
default_file = pathlib.Path(__file__).parent / f"{xml_folder}/values/donottranslate-more-keys.xml"
|
||||||
|
out_folder = pathlib.Path(__file__).parent / "../app/src/main/assets/language_key_texts/"
|
||||||
|
|
||||||
|
|
||||||
|
def append_to_morekeys(morekeys, text, label):
|
||||||
|
if label in morekeys:
|
||||||
|
morekeys[label] = morekeys[label] + " " + text
|
||||||
|
else:
|
||||||
|
morekeys[label] = text
|
||||||
|
|
||||||
|
|
||||||
|
def prepend_to_morekeys(morekeys, text, label):
|
||||||
|
if label in morekeys:
|
||||||
|
morekeys[label] = text + " " + morekeys[label]
|
||||||
|
else:
|
||||||
|
morekeys[label] = text
|
||||||
|
|
||||||
|
|
||||||
|
def read_keys(file):
|
||||||
|
root = ET.parse(file).getroot()
|
||||||
|
morekeys = dict()
|
||||||
|
extra_keys = dict()
|
||||||
|
for key in root.iter("resources"):
|
||||||
|
for string in key.iter("string"):
|
||||||
|
for tag, value in string.items():
|
||||||
|
if tag != "name":
|
||||||
|
print("ignoring tag " + tag)
|
||||||
|
continue
|
||||||
|
if string.text is None:
|
||||||
|
text = ""
|
||||||
|
else:
|
||||||
|
text = resolve_text(string.text, file)
|
||||||
|
if "!text/" in text:
|
||||||
|
raise ValueError(f"can't have !text/ in {text} (from {string.text})")
|
||||||
|
if " " in text:
|
||||||
|
raise ValueError(f"can't have consecutive spaces in {text} (from {string.text})")
|
||||||
|
if value.startswith("keyspec_") and "_row" in value:
|
||||||
|
# put additional key labels (for nordic, spanish, swiss)
|
||||||
|
key = value.split("_row")[1]
|
||||||
|
d = extra_keys.get(key, dict())
|
||||||
|
d["label"] = text
|
||||||
|
extra_keys[key] = d
|
||||||
|
elif value.startswith("morekeys_") and "_row" in value:
|
||||||
|
# put additional key morekeys (for nordic, spanish, swiss)
|
||||||
|
key = value.split("_row")[1]
|
||||||
|
d = extra_keys.get(key, dict())
|
||||||
|
d["morekeys"] = text
|
||||||
|
extra_keys[key] = d
|
||||||
|
elif value.startswith("morekeys_"):
|
||||||
|
key_label = value.split("morekeys_")[1]
|
||||||
|
if len(key_label) > 1 and key_label != "punctuation":
|
||||||
|
print(f"ignoring long more key: {key_label}: {text}")
|
||||||
|
continue
|
||||||
|
morekeys[key_label] = text
|
||||||
|
elif value == "single_quotes":
|
||||||
|
prepend_to_morekeys(morekeys, text, '\'')
|
||||||
|
elif value == "single_angle_quotes":
|
||||||
|
append_to_morekeys(morekeys, text, '\'')
|
||||||
|
elif value == "double_quotes":
|
||||||
|
prepend_to_morekeys(morekeys, text, '\"')
|
||||||
|
elif value == "double_angle_quotes":
|
||||||
|
append_to_morekeys(morekeys, text, '\"')
|
||||||
|
# todo: labels should be in [labels] and use sth like symbols: ?123
|
||||||
|
else:
|
||||||
|
print(f"ignored tag: {tag}={value}, {text}")
|
||||||
|
keys = dict()
|
||||||
|
keys["morekeys"] = morekeys
|
||||||
|
keys["extra_keys"] = extra_keys
|
||||||
|
return keys
|
||||||
|
|
||||||
|
|
||||||
|
def resolve_text(text, file):
|
||||||
|
if text.startswith("\"") and text.endswith("\"") and len(text) > 1:
|
||||||
|
text = text[1:-1]
|
||||||
|
sp = re.split("(?<!\\\\),", text)
|
||||||
|
|
||||||
|
if len(sp) > 1: # resolve each entry separately
|
||||||
|
result = []
|
||||||
|
for t in sp:
|
||||||
|
resolved = resolve_text(t, file)
|
||||||
|
if text.startswith("\\"): # remove backslash at start, this seems to be happening somewhere in android parsing too
|
||||||
|
result.append(resolved[1:])
|
||||||
|
else:
|
||||||
|
result.append(resolved)
|
||||||
|
return " ".join(result) # join with space, because that doesn't cause issues with comma in moreKeys
|
||||||
|
if "!text/" not in text:
|
||||||
|
if text.startswith("\\"): # see above
|
||||||
|
return text[1:]
|
||||||
|
return text
|
||||||
|
root = ET.parse(file).getroot()
|
||||||
|
sp = text.split("!text/")
|
||||||
|
required = sp[1]
|
||||||
|
for key in root.findall(".//string"):
|
||||||
|
for tag, value in key.items():
|
||||||
|
if tag == "name" and value == required:
|
||||||
|
return resolve_text(key.text, file)
|
||||||
|
# fall back to searching in no-language values
|
||||||
|
root = ET.parse(default_file).getroot()
|
||||||
|
for key in root.findall(".//string"):
|
||||||
|
for tag, value in key.items():
|
||||||
|
if tag == "name" and value == required:
|
||||||
|
return resolve_text(key.text, file)
|
||||||
|
raise LookupError(text + " not found in " + str(file))
|
||||||
|
|
||||||
|
|
||||||
|
def read_locale_from_folder(folder):
|
||||||
|
if folder.startswith("values-"):
|
||||||
|
return folder.split("values-")[1]
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def write_keys(outfile, keys, locc=""):
|
||||||
|
with open(outfile, "w") as f:
|
||||||
|
# write section [more_keys], then [extra_keys], skip if empty
|
||||||
|
if len(keys["morekeys"]) > 0:
|
||||||
|
f.write("[morekeys]\n")
|
||||||
|
for k, v in keys["morekeys"].items():
|
||||||
|
f.write(f"{k} {v}\n")
|
||||||
|
if len(keys["extra_keys"]) > 0:
|
||||||
|
f.write("\n")
|
||||||
|
if len(keys["extra_keys"]) > 0 and locc != "eo": # eo has the extra key moved into the layout
|
||||||
|
f.write("[extra_keys]\n")
|
||||||
|
# clarify somewhere that extra keys only apply to default layout (where to get?)
|
||||||
|
for k, v in sorted(keys["extra_keys"].items()):
|
||||||
|
row = k.split("_")[0]
|
||||||
|
morekeys = v.get("morekeys", "")
|
||||||
|
label = v["label"]
|
||||||
|
if len(morekeys) == 0:
|
||||||
|
f.write(f"{row}: {label}\n")
|
||||||
|
else:
|
||||||
|
f.write(f"{row}: {label} {morekeys}\n")
|
||||||
|
|
||||||
|
|
||||||
|
def get_morekeys_texts(write=False):
|
||||||
|
val = []
|
||||||
|
for file in (pathlib.Path(__file__).parent / xml_folder).iterdir():
|
||||||
|
locc = read_locale_from_folder(file.name)
|
||||||
|
if locc is None:
|
||||||
|
continue
|
||||||
|
loc = langcodes.Language.get(locc)
|
||||||
|
|
||||||
|
script = loc.assume_script().script
|
||||||
|
# some scripts are not detected, fill in the current state of OpenBoard
|
||||||
|
if locc == "sr" or locc == "ky" or locc == "mn":
|
||||||
|
script = "Cyrl"
|
||||||
|
if locc == "sr-rZZ" or locc == "uz" or locc == "zz" or locc == "az" or locc == "tl":
|
||||||
|
script = "Latn"
|
||||||
|
if script is None:
|
||||||
|
raise ValueError("undefined script")
|
||||||
|
if script != "Latn":
|
||||||
|
continue # skip non-latin scripts for now
|
||||||
|
print(file)
|
||||||
|
keys = read_keys(f"{file}/donottranslate-more-keys.xml")
|
||||||
|
val.append(keys)
|
||||||
|
if not write:
|
||||||
|
continue
|
||||||
|
outfile_name = locc.replace("-r", "_").lower() + ".txt"
|
||||||
|
outfile = pathlib.Path(out_folder + outfile_name)
|
||||||
|
outfile.parent.mkdir(exist_ok=True, parents=True)
|
||||||
|
write_keys(outfile, keys, locc)
|
||||||
|
return val
|
||||||
|
|
||||||
|
|
||||||
|
def write_combined_lists(keys):
|
||||||
|
infos_by_letters = dict()
|
||||||
|
for key in keys:
|
||||||
|
for k, v in key["morekeys"].items():
|
||||||
|
infos = infos_by_letters.get(k, dict())
|
||||||
|
for l in v.split(" "):
|
||||||
|
if l == "%":
|
||||||
|
continue
|
||||||
|
infos[l] = infos.get(l, 0) + 1
|
||||||
|
infos_by_letters[k] = infos
|
||||||
|
with open(out_folder + "all_more_keys.txt", 'w') as f:
|
||||||
|
f.write("[morekeys]\n")
|
||||||
|
for letter, info in infos_by_letters.items():
|
||||||
|
f.write(letter + " " + " ".join(info.keys()) + "\n")
|
||||||
|
with open(out_folder + "more_more_keys.txt", 'w') as f:
|
||||||
|
f.write("[morekeys]\n")
|
||||||
|
for letter, info in infos_by_letters.items():
|
||||||
|
morekeys = []
|
||||||
|
for morekey, count in info.items():
|
||||||
|
if count > 1:
|
||||||
|
morekeys.append(morekey)
|
||||||
|
if len(morekeys) > 0:
|
||||||
|
f.write(letter + " " + " ".join(morekeys) + "\n")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# k = read_keys(default_file)
|
||||||
|
# write_keys(pathlib.Path(__file__).parent / f"defaultkeys.txt", k)
|
||||||
|
keys = get_morekeys_texts()
|
||||||
|
write_combined_lists(keys)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# need to check strings:
|
||||||
|
# latin, but only in symbol layout
|
||||||
|
# single_quotes, double_quotes (both used in morekeys of single/double quotes in symbol keyboard)
|
||||||
|
# single_angle_quotes, double_angle_quotes (same place as above -> merge into the same base ' or ")
|
||||||
|
# -> just treat them like morekeys_' and morekeys_"
|
||||||
|
# ... resolving those is really horrible, check different things and maybe include all if not too much?
|
||||||
|
# latin, but for layout and not for moreKeys
|
||||||
|
# keyspec_nordic_row (+swiss and spanish) -> normal keys, what do? really specify a layout? or allow modifying?
|
||||||
|
# keyspec_q + w, y, x (eo only -> hmm, have a separate layout?)
|
||||||
|
# not latin, but cyrillic (and maybe other non-latin)
|
||||||
|
# keyspec_east_slavic_row
|
||||||
|
# keylabel_to_alpha
|
||||||
|
# label_go_key and other keys (hi-rZZ and sr-rZZ -> why here? they should be in app strings, right?)
|
||||||
|
# not in latin (so far)
|
||||||
|
# keyspec_symbols
|
||||||
|
# additional_morekeys_symbols
|
||||||
|
# keyspec_currency
|
||||||
|
# keylabel_to_symbol
|
||||||
|
# keyspec_comma
|
||||||
|
# keyhintlabel_period -> that's with the shifted key hint maybe
|
||||||
|
# keyhintlabel_tablet_period
|
||||||
|
# keyspec_period
|
||||||
|
# keyspec_tablet_period
|
||||||
|
# keyspec_symbols_question
|
||||||
|
# keyspec_symbols_semicolon
|
||||||
|
# keyspec_symbols_percent
|
||||||
|
# keyspec_tablet_comma
|
||||||
|
# keyhintlabel_tablet_comma
|
||||||
|
# keyspec_left_parenthesis + right
|
||||||
|
# keyspec_left_square_bracket + right
|
||||||
|
# keyspec_left_curly_bracket + right
|
||||||
|
# keyspec_less_than + greater
|
||||||
|
# keyspec_less_than_equal + greater
|
||||||
|
# keyspec_left_double_angle_quote + right
|
||||||
|
# keyspec_left_single_angle_quote + right
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
Loading…
Add table
Add a link
Reference in a new issue