mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-04-22 07:09:10 +00:00
use new parser for symbols layouts
This commit is contained in:
parent
4d0b7915c8
commit
57bf742da0
45 changed files with 574 additions and 136 deletions
10
app/src/main/assets/language_key_texts/ar.txt
Normal file
10
app/src/main/assets/language_key_texts/ar.txt
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
[morekeys]
|
||||||
|
punctuation !fixedColumnOrder!7 ٕ|ٕ ٔ|ٔ ْ|ْ ٍ|ٍ ٌ|ٌ ً|ً ّ|ّ ٖ|ٖ ٰ|ٰ ٓ|ٓ ِ|ِ ُ|ُ َ|َ ـــ|ـ
|
||||||
|
|
||||||
|
[labels]
|
||||||
|
alphabet: أبج
|
||||||
|
symbol: ٣٢١؟
|
||||||
|
comma: ،
|
||||||
|
|
||||||
|
[number_row]
|
||||||
|
١ ٢ ٣ ٤ ٥ ٦ ٧ ٨ ٩ ٠
|
8
app/src/main/assets/language_key_texts/be.txt
Normal file
8
app/src/main/assets/language_key_texts/be.txt
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[morekeys]
|
||||||
|
е ё
|
||||||
|
ь ъ
|
||||||
|
' ’ ‚ ‘
|
||||||
|
" ” „ “
|
||||||
|
|
||||||
|
[labels]
|
||||||
|
alphabet: АБВ
|
5
app/src/main/assets/language_key_texts/bg.txt
Normal file
5
app/src/main/assets/language_key_texts/bg.txt
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[morekeys]
|
||||||
|
" ” „ “
|
||||||
|
|
||||||
|
[labels]
|
||||||
|
alphabet: АБВ
|
10
app/src/main/assets/language_key_texts/bn_bd.txt
Normal file
10
app/src/main/assets/language_key_texts/bn_bd.txt
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
[morekeys]
|
||||||
|
punctuation !autoColumnOrder!8 \, ॥ ? ! !icon/zwnj_key|\u200C !icon/zwj_key|\u200D # @ ( ) / ; : - + \%
|
||||||
|
|
||||||
|
[labels]
|
||||||
|
alphabet: কখগ
|
||||||
|
symbol: ?১২৩
|
||||||
|
period: ।
|
||||||
|
|
||||||
|
[number_row]
|
||||||
|
১ ২ ৩ ৪ ৫ ৬ ৭ ৮ ৯ ০
|
2
app/src/main/assets/language_key_texts/bn_in.txt
Normal file
2
app/src/main/assets/language_key_texts/bn_in.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[labels]
|
||||||
|
alphabet: কখগ
|
2
app/src/main/assets/language_key_texts/el.txt
Normal file
2
app/src/main/assets/language_key_texts/el.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[labels]
|
||||||
|
alphabet: ΑΒΓ
|
10
app/src/main/assets/language_key_texts/fa.txt
Normal file
10
app/src/main/assets/language_key_texts/fa.txt
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
[morekeys]
|
||||||
|
punctuation !fixedColumnOrder!7 ٕ|ٕ ْ|ْ ّ|ّ ٌ|ٌ ٍ|ٍ ً|ً ٔ|ٔ ٖ|ٖ ٰ|ٰ ٓ|ٓ ُ|ُ ِ|ِ َ|َ ـــ|ـ
|
||||||
|
|
||||||
|
[labels]
|
||||||
|
alphabet: ابپ
|
||||||
|
symbol: ۳۲۱؟
|
||||||
|
comma: ،
|
||||||
|
|
||||||
|
[number_row]
|
||||||
|
۱ ۲ ۳ ۴ ۵ ۶ ۷ ۸ ۹ ۰
|
10
app/src/main/assets/language_key_texts/hi.txt
Normal file
10
app/src/main/assets/language_key_texts/hi.txt
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
[morekeys]
|
||||||
|
punctuation !autoColumnOrder!9 \, . ? ! # ) ( / ; ' @ : - " + \% &
|
||||||
|
|
||||||
|
[labels]
|
||||||
|
alphabet: कखग
|
||||||
|
symbol: ?१२३
|
||||||
|
period: ।
|
||||||
|
|
||||||
|
[number_row]
|
||||||
|
१ २ ३ ४ ५ ६ ७ ८ ९ ०
|
8
app/src/main/assets/language_key_texts/hy.txt
Normal file
8
app/src/main/assets/language_key_texts/hy.txt
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[morekeys]
|
||||||
|
punctuation !autoColumnOrder!8 \, ՞ ՜ ․ … ' = / ՝ ՛ ֊ » « ― ) (
|
||||||
|
? ՞ ¿
|
||||||
|
! ՜ ¡
|
||||||
|
|
||||||
|
[labels]
|
||||||
|
alphabet: ԱԲԳ
|
||||||
|
period: ։
|
7
app/src/main/assets/language_key_texts/iw.txt
Normal file
7
app/src/main/assets/language_key_texts/iw.txt
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
[morekeys]
|
||||||
|
' ‘ ’ ‚
|
||||||
|
" “ ” „
|
||||||
|
+ ﬩
|
||||||
|
|
||||||
|
[labels]
|
||||||
|
alphabet: אבג
|
6
app/src/main/assets/language_key_texts/ka.txt
Normal file
6
app/src/main/assets/language_key_texts/ka.txt
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[morekeys]
|
||||||
|
' ’ ‚ ‘
|
||||||
|
" ” „ “
|
||||||
|
|
||||||
|
[labels]
|
||||||
|
alphabet: აბგ
|
12
app/src/main/assets/language_key_texts/kk.txt
Normal file
12
app/src/main/assets/language_key_texts/kk.txt
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
[morekeys]
|
||||||
|
у ү ұ
|
||||||
|
к қ
|
||||||
|
е ё
|
||||||
|
н ң
|
||||||
|
г ғ
|
||||||
|
а ә
|
||||||
|
о ө
|
||||||
|
ь ъ
|
||||||
|
|
||||||
|
[labels]
|
||||||
|
alphabet: АБВ
|
2
app/src/main/assets/language_key_texts/km.txt
Normal file
2
app/src/main/assets/language_key_texts/km.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[labels]
|
||||||
|
alphabet: កខគ
|
2
app/src/main/assets/language_key_texts/kn.txt
Normal file
2
app/src/main/assets/language_key_texts/kn.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[labels]
|
||||||
|
alphabet: ಅಆಇ
|
2
app/src/main/assets/language_key_texts/ko.txt
Normal file
2
app/src/main/assets/language_key_texts/ko.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[labels]
|
||||||
|
alphabet: ㄱㄴㄷ
|
9
app/src/main/assets/language_key_texts/ky.txt
Normal file
9
app/src/main/assets/language_key_texts/ky.txt
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
[morekeys]
|
||||||
|
у ү
|
||||||
|
е ё
|
||||||
|
н ң
|
||||||
|
о ө
|
||||||
|
ь ъ
|
||||||
|
|
||||||
|
[labels]
|
||||||
|
alphabet: АБВ
|
2
app/src/main/assets/language_key_texts/lo.txt
Normal file
2
app/src/main/assets/language_key_texts/lo.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[labels]
|
||||||
|
alphabet: ກຂຄ
|
8
app/src/main/assets/language_key_texts/mk.txt
Normal file
8
app/src/main/assets/language_key_texts/mk.txt
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[morekeys]
|
||||||
|
е ѐ
|
||||||
|
и ѝ
|
||||||
|
' ’ ‚ ‘
|
||||||
|
" ” „ “
|
||||||
|
|
||||||
|
[labels]
|
||||||
|
alphabet: АБВ
|
2
app/src/main/assets/language_key_texts/ml.txt
Normal file
2
app/src/main/assets/language_key_texts/ml.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[labels]
|
||||||
|
alphabet: അ
|
2
app/src/main/assets/language_key_texts/mn.txt
Normal file
2
app/src/main/assets/language_key_texts/mn.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[labels]
|
||||||
|
alphabet: АБВ
|
6
app/src/main/assets/language_key_texts/mr.txt
Normal file
6
app/src/main/assets/language_key_texts/mr.txt
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[labels]
|
||||||
|
alphabet: कखग
|
||||||
|
symbol: ?१२३
|
||||||
|
|
||||||
|
[number_row]
|
||||||
|
१ २ ३ ४ ५ ६ ७ ८ ९ ०
|
6
app/src/main/assets/language_key_texts/my.txt
Normal file
6
app/src/main/assets/language_key_texts/my.txt
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[morekeys]
|
||||||
|
punctuation !autoColumnOrder!9 ၊ . ? ! # ) ( / ; ... ' @ : - " + \% &
|
||||||
|
|
||||||
|
[labels]
|
||||||
|
alphabet: ကခဂ
|
||||||
|
period: ။
|
10
app/src/main/assets/language_key_texts/ne.txt
Normal file
10
app/src/main/assets/language_key_texts/ne.txt
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
[morekeys]
|
||||||
|
punctuation !autoColumnOrder!9 . \, ? ! # ) ( / ; ' @ : - " + \% &
|
||||||
|
|
||||||
|
[labels]
|
||||||
|
alphabet: कखग
|
||||||
|
symbol: ?१२३
|
||||||
|
period: ।
|
||||||
|
|
||||||
|
[number_row]
|
||||||
|
१ २ ३ ४ ५ ६ ७ ८ ९ ०
|
8
app/src/main/assets/language_key_texts/ru.txt
Normal file
8
app/src/main/assets/language_key_texts/ru.txt
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[morekeys]
|
||||||
|
е ё
|
||||||
|
ь ъ
|
||||||
|
' ’ ‚ ‘
|
||||||
|
" ” „ “
|
||||||
|
|
||||||
|
[labels]
|
||||||
|
alphabet: АБВ
|
2
app/src/main/assets/language_key_texts/si.txt
Normal file
2
app/src/main/assets/language_key_texts/si.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[labels]
|
||||||
|
alphabet: අ ආ
|
8
app/src/main/assets/language_key_texts/sr.txt
Normal file
8
app/src/main/assets/language_key_texts/sr.txt
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[morekeys]
|
||||||
|
е ѐ
|
||||||
|
и ѝ
|
||||||
|
' ’ ‚ ‘ › ‹
|
||||||
|
" ” „ “ » «
|
||||||
|
|
||||||
|
[labels]
|
||||||
|
alphabet: АБВ
|
2
app/src/main/assets/language_key_texts/ta_in.txt
Normal file
2
app/src/main/assets/language_key_texts/ta_in.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[labels]
|
||||||
|
alphabet: தமிழ்
|
2
app/src/main/assets/language_key_texts/ta_lk.txt
Normal file
2
app/src/main/assets/language_key_texts/ta_lk.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[labels]
|
||||||
|
alphabet: தமிழ்
|
2
app/src/main/assets/language_key_texts/ta_sg.txt
Normal file
2
app/src/main/assets/language_key_texts/ta_sg.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[labels]
|
||||||
|
alphabet: தமிழ்
|
2
app/src/main/assets/language_key_texts/te.txt
Normal file
2
app/src/main/assets/language_key_texts/te.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[labels]
|
||||||
|
alphabet: అఆఇ
|
2
app/src/main/assets/language_key_texts/th.txt
Normal file
2
app/src/main/assets/language_key_texts/th.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[labels]
|
||||||
|
alphabet: กขค
|
8
app/src/main/assets/language_key_texts/uk.txt
Normal file
8
app/src/main/assets/language_key_texts/uk.txt
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[morekeys]
|
||||||
|
г ґ
|
||||||
|
ь ъ
|
||||||
|
' ’ ‚ ‘
|
||||||
|
" ” „ “
|
||||||
|
|
||||||
|
[labels]
|
||||||
|
alphabet: АБВ
|
11
app/src/main/assets/language_key_texts/ur.txt
Normal file
11
app/src/main/assets/language_key_texts/ur.txt
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[morekeys]
|
||||||
|
punctuation ؟ ، ! . -
|
||||||
|
|
||||||
|
[labels]
|
||||||
|
alphabet: ابپ
|
||||||
|
comma: ،
|
||||||
|
symbol: ۳۲۱؟
|
||||||
|
period: ۔
|
||||||
|
|
||||||
|
[number_row]
|
||||||
|
۱ ۲ ۳ ۴ ۵ ۶ ۷ ۸ ۹ ۰
|
28
app/src/main/assets/layouts/symbols.txt
Normal file
28
app/src/main/assets/layouts/symbols.txt
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
~
|
||||||
|
`
|
||||||
|
|
|
||||||
|
• ♪ ♥ ♠ ♦ ♣
|
||||||
|
√
|
||||||
|
π Π
|
||||||
|
÷
|
||||||
|
×
|
||||||
|
¶ §
|
||||||
|
∆
|
||||||
|
|
||||||
|
@
|
||||||
|
#
|
||||||
|
$$$
|
||||||
|
% ‰
|
||||||
|
&
|
||||||
|
- _ – — ·
|
||||||
|
+ ±
|
||||||
|
( < { [
|
||||||
|
) > } ]
|
||||||
|
|
||||||
|
* † ‡ ★
|
||||||
|
"
|
||||||
|
'
|
||||||
|
:
|
||||||
|
;
|
||||||
|
!
|
||||||
|
?
|
28
app/src/main/assets/layouts/symbols_arabic.txt
Normal file
28
app/src/main/assets/layouts/symbols_arabic.txt
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
~
|
||||||
|
`
|
||||||
|
|
|
||||||
|
• ♪ ♥ ♠ ♦ ♣
|
||||||
|
√
|
||||||
|
π Π
|
||||||
|
÷
|
||||||
|
×
|
||||||
|
¶ §
|
||||||
|
∆
|
||||||
|
|
||||||
|
٬ @
|
||||||
|
٫ #
|
||||||
|
$$$
|
||||||
|
٪ % ‰
|
||||||
|
&
|
||||||
|
- _ – — ·
|
||||||
|
+ ±
|
||||||
|
( ﴾ < { [
|
||||||
|
) ﴿ > } ]
|
||||||
|
|
||||||
|
* ٭ ★ † ‡
|
||||||
|
« „ “ ”
|
||||||
|
» ‚ ‘ ’ ‹ ›
|
||||||
|
:
|
||||||
|
؛ ;
|
||||||
|
!
|
||||||
|
؟ ? ¿
|
28
app/src/main/assets/layouts/symbols_shifted.txt
Normal file
28
app/src/main/assets/layouts/symbols_shifted.txt
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
~
|
||||||
|
`
|
||||||
|
|
|
||||||
|
• ♪ ♥ ♠ ♦ ♣
|
||||||
|
√
|
||||||
|
π Π
|
||||||
|
÷
|
||||||
|
×
|
||||||
|
¶ §
|
||||||
|
∆
|
||||||
|
|
||||||
|
$$$1
|
||||||
|
$$$2
|
||||||
|
$$$3
|
||||||
|
$$$4
|
||||||
|
^ ↑ ↓ ← →
|
||||||
|
° ′ ″
|
||||||
|
= ≠ ≈ ∞
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
\
|
||||||
|
©
|
||||||
|
®
|
||||||
|
™
|
||||||
|
℅
|
||||||
|
[
|
||||||
|
]
|
|
@ -52,12 +52,10 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
||||||
mParams.mId = id
|
mParams.mId = id
|
||||||
addLocaleKeyTextsToParams(mContext, mParams, Settings.getInstance().current.mShowMoreKeys)
|
addLocaleKeyTextsToParams(mContext, mParams, Settings.getInstance().current.mShowMoreKeys)
|
||||||
try {
|
try {
|
||||||
val parser = KeyboardParser.createParserForLayout(mParams, mContext) ?: return null
|
keysInRows = KeyboardParser.parseFromAssets(mParams, mContext) ?: return null
|
||||||
Log.d(TAG, "parsing $id using ${parser::class.simpleName}")
|
|
||||||
keysInRows = parser.parseLayoutFromAssets(id.mSubtype.keyboardLayoutSetName)
|
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
if (DebugFlags.DEBUG_ENABLED || BuildConfig.DEBUG)
|
if (DebugFlags.DEBUG_ENABLED || BuildConfig.DEBUG)
|
||||||
Toast.makeText(mContext, "error loading keyboard: ${e.message}", Toast.LENGTH_LONG).show()
|
Toast.makeText(mContext, "error parsing keyboard: ${e.message}", Toast.LENGTH_LONG).show()
|
||||||
Log.e(TAG, "loading $id from assets failed", e)
|
Log.e(TAG, "loading $id from assets failed", e)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@ -65,8 +63,14 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
||||||
return this
|
return this
|
||||||
|
|
||||||
// todo: further plan
|
// todo: further plan
|
||||||
// migrate symbol layouts to this style
|
// add option for number row (latin first vs locale numbers first
|
||||||
// simplified if possible, but json should be fine too
|
// show only if number row enabled
|
||||||
|
// release next version before continuing
|
||||||
|
// migrate other languages to this style
|
||||||
|
// may be tricky in some cases, like additional row, or no shift key, or pc qwerty layout
|
||||||
|
// also the integrated number row might cause issues, and should be removed / ignored
|
||||||
|
// at least some of these layouts will need more complicated definition
|
||||||
|
// test the zwnj key
|
||||||
// migrate keypad layouts to this style
|
// migrate keypad layouts to this style
|
||||||
// will need more configurable layout definition -> another parser, or do it with compatible jsons
|
// will need more configurable layout definition -> another parser, or do it with compatible jsons
|
||||||
// allow users to define their own layouts (maybe migrate other layouts first?)
|
// allow users to define their own layouts (maybe migrate other layouts first?)
|
||||||
|
@ -105,12 +109,11 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
||||||
// write another parser, it should already consider split
|
// write another parser, it should already consider split
|
||||||
// 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
|
// remove the old parser
|
||||||
// may be difficult in some cases, like additional row, or no shift key, or pc qwerty layout
|
// then finally the spanish/german/swiss/nordic layouts can be removed and replaced by some hasExtraKeys parameter
|
||||||
// also the (integrated) number row might cause issues
|
// also the eo check could then be removed
|
||||||
// at least some of these layouts will need more complicated definition, not just a simple text file
|
// and maybe the language -> layout thing could be moved to assets? and maybe even here the extra keys could be defined...
|
||||||
// some languages also change symbol view, e.g. fa changes symbols row 3
|
// should be either both in method.xml, or both in assets (actually method might be more suitable)
|
||||||
// add more layouts before doing this? or just keep the layout conversion script
|
|
||||||
|
|
||||||
// labelFlags should be set correctly
|
// labelFlags should be set correctly
|
||||||
// alignHintLabelToBottom: on lxx and rounded themes, but did not find what it actually does...
|
// alignHintLabelToBottom: on lxx and rounded themes, but did not find what it actually does...
|
||||||
|
@ -145,7 +148,6 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
|
||||||
|
|
||||||
fun loadFromXml(xmlId: Int, id: KeyboardId): KeyboardBuilder<KP> {
|
fun loadFromXml(xmlId: Int, id: KeyboardId): KeyboardBuilder<KP> {
|
||||||
if (Settings.getInstance().current.mUseNewKeyboardParsing
|
if (Settings.getInstance().current.mUseNewKeyboardParsing
|
||||||
&& id.isAlphabetKeyboard
|
|
||||||
&& this::class == KeyboardBuilder::class // otherwise this will apply to moreKeys and moreSuggestions, and then some parameters are off
|
&& this::class == KeyboardBuilder::class // otherwise this will apply to moreKeys and moreSuggestions, and then some parameters are off
|
||||||
) {
|
) {
|
||||||
if (loadFromAssets(id) != null)
|
if (loadFromAssets(id) != null)
|
||||||
|
|
|
@ -2,7 +2,9 @@ package org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
|
import android.util.Log
|
||||||
import android.view.inputmethod.EditorInfo
|
import android.view.inputmethod.EditorInfo
|
||||||
|
import android.widget.Toast
|
||||||
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
|
||||||
import org.dslul.openboard.inputmethod.keyboard.KeyboardId
|
import org.dslul.openboard.inputmethod.keyboard.KeyboardId
|
||||||
|
@ -12,9 +14,12 @@ import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardParams
|
||||||
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.floris.KeyData
|
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.floris.KeyData
|
||||||
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.floris.toTextKey
|
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.floris.toTextKey
|
||||||
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.splitOnWhitespace
|
import org.dslul.openboard.inputmethod.latin.common.splitOnWhitespace
|
||||||
|
import org.dslul.openboard.inputmethod.latin.define.DebugFlags
|
||||||
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.RunInLocale
|
||||||
|
import org.dslul.openboard.inputmethod.latin.utils.ScriptUtils
|
||||||
import org.dslul.openboard.inputmethod.latin.utils.sumOf
|
import org.dslul.openboard.inputmethod.latin.utils.sumOf
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -29,6 +34,9 @@ import org.dslul.openboard.inputmethod.latin.utils.sumOf
|
||||||
* Currently the number, phone and numpad layouts are not compatible with this parser.
|
* Currently the number, phone and numpad layouts are not compatible with this parser.
|
||||||
*/
|
*/
|
||||||
abstract class KeyboardParser(private val params: KeyboardParams, private val context: Context) {
|
abstract class KeyboardParser(private val params: KeyboardParams, private val context: Context) {
|
||||||
|
private val defaultLabelFlags = if (!params.mId.isAlphabetKeyboard)
|
||||||
|
Key.LABEL_FLAGS_DISABLE_HINT_LABEL // reproduce the no-hints in symbol layouts, todo: add setting
|
||||||
|
else 0
|
||||||
|
|
||||||
protected abstract fun getLayoutFromAssets(layoutName: String): String
|
protected abstract fun getLayoutFromAssets(layoutName: String): String
|
||||||
|
|
||||||
|
@ -42,9 +50,13 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
||||||
val keysInRows = ArrayList<ArrayList<KeyParams>>()
|
val keysInRows = ArrayList<ArrayList<KeyParams>>()
|
||||||
|
|
||||||
val baseKeys: MutableList<List<KeyData>> = parseCoreLayout(layoutContent)
|
val baseKeys: MutableList<List<KeyData>> = parseCoreLayout(layoutContent)
|
||||||
if (!params.mId.mNumberRowEnabled) {
|
if (!params.mId.mNumberRowEnabled && params.mId.mElementId == KeyboardId.ELEMENT_SYMBOLS) {
|
||||||
// todo (non-latin): not all layouts have numbers on first row, so maybe have some layout flag to switch it off (or an option)
|
// replace first symbols row with number row
|
||||||
((1..9) + 0).forEachIndexed { i, n -> baseKeys.first().getOrNull(i)?.popup?.number = n }
|
baseKeys[0] = params.mLocaleKeyTexts.getNumberRow()
|
||||||
|
} else if (!params.mId.mNumberRowEnabled && params.mId.isAlphabetKeyboard) {
|
||||||
|
// add number to the first 10 keys in first row
|
||||||
|
// setting the correct moreKeys is handled in PopupSet
|
||||||
|
baseKeys.first().take(10).forEachIndexed { index, keyData -> keyData.popup.numberIndex = index }
|
||||||
}
|
}
|
||||||
val functionalKeysReversed = parseFunctionalKeys().reversed()
|
val functionalKeysReversed = parseFunctionalKeys().reversed()
|
||||||
|
|
||||||
|
@ -98,7 +110,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
||||||
for (key in row) {
|
for (key in row) {
|
||||||
// todo: maybe autoScale / autoXScale if label has more than 2 characters (exception for emojis?)
|
// todo: maybe autoScale / autoXScale if label has more than 2 characters (exception for emojis?)
|
||||||
// but that could also be determined in toKeyParams
|
// but that could also be determined in toKeyParams
|
||||||
val keyParams = key.compute(params)?.toKeyParams(params, keyWidth) ?: continue
|
val keyParams = key.compute(params)?.toKeyParams(params, keyWidth, defaultLabelFlags) ?: continue
|
||||||
paramsRow.add(keyParams)
|
paramsRow.add(keyParams)
|
||||||
}
|
}
|
||||||
if (spacerWidth != 0f) {
|
if (spacerWidth != 0f) {
|
||||||
|
@ -185,25 +197,25 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
||||||
adjustedKeys?.get(1)?.label ?: "/",
|
adjustedKeys?.get(1)?.label ?: "/",
|
||||||
params,
|
params,
|
||||||
params.mDefaultRelativeKeyWidth,
|
params.mDefaultRelativeKeyWidth,
|
||||||
0,
|
defaultLabelFlags,
|
||||||
Key.BACKGROUND_TYPE_FUNCTIONAL,
|
Key.BACKGROUND_TYPE_FUNCTIONAL,
|
||||||
adjustedKeys?.get(1)?.popup?.toMoreKeys(params)
|
adjustedKeys?.get(1)?.popup?.toMoreKeys(params)
|
||||||
))
|
))
|
||||||
} else if (params.mId.mElementId == KeyboardId.ELEMENT_SYMBOLS_SHIFTED) {
|
} else if (params.mId.mElementId == KeyboardId.ELEMENT_SYMBOLS_SHIFTED) {
|
||||||
bottomRow.add(KeyParams(
|
bottomRow.add(KeyParams(
|
||||||
adjustedKeys?.get(1)?.label ?: "<",
|
(adjustedKeys?.get(1)?.label ?: "<").rtlLabel(params),
|
||||||
params,
|
params,
|
||||||
params.mDefaultRelativeKeyWidth,
|
params.mDefaultRelativeKeyWidth,
|
||||||
0,
|
defaultLabelFlags,
|
||||||
Key.BACKGROUND_TYPE_FUNCTIONAL,
|
Key.BACKGROUND_TYPE_FUNCTIONAL,
|
||||||
adjustedKeys?.get(1)?.popup?.toMoreKeys(params)
|
adjustedKeys?.get(1)?.popup?.toMoreKeys(params)
|
||||||
))
|
))
|
||||||
bottomRow.add(keyParams)
|
bottomRow.add(keyParams)
|
||||||
bottomRow.add(KeyParams(
|
bottomRow.add(KeyParams(
|
||||||
adjustedKeys?.get(2)?.label ?: ">",
|
(adjustedKeys?.get(2)?.label ?: ">").rtlLabel(params),
|
||||||
params,
|
params,
|
||||||
params.mDefaultRelativeKeyWidth,
|
params.mDefaultRelativeKeyWidth,
|
||||||
0,
|
defaultLabelFlags,
|
||||||
Key.BACKGROUND_TYPE_FUNCTIONAL,
|
Key.BACKGROUND_TYPE_FUNCTIONAL,
|
||||||
adjustedKeys?.get(2)?.popup?.toMoreKeys(params)
|
adjustedKeys?.get(2)?.popup?.toMoreKeys(params)
|
||||||
))
|
))
|
||||||
|
@ -214,7 +226,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
||||||
bottomRow.add(getFunctionalKeyParams(FunctionalKey.EMOJI))
|
bottomRow.add(getFunctionalKeyParams(FunctionalKey.EMOJI))
|
||||||
bottomRow.add(keyParams)
|
bottomRow.add(keyParams)
|
||||||
if (params.mId.locale.language in languagesThatNeedZwnjKey)
|
if (params.mId.locale.language in languagesThatNeedZwnjKey)
|
||||||
bottomRow.add(getFunctionalKeyParams(FunctionalKey.ZWNJ)) // todo (non-latin): test it
|
bottomRow.add(getFunctionalKeyParams(FunctionalKey.ZWNJ))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bottomRow.add(keyParams)
|
bottomRow.add(keyParams)
|
||||||
|
@ -226,19 +238,9 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
||||||
return bottomRow
|
return bottomRow
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getNumberRow(): ArrayList<KeyParams> {
|
private fun getNumberRow(): ArrayList<KeyParams> =
|
||||||
val row = ArrayList<KeyParams>()
|
params.mLocaleKeyTexts.getNumberRow().mapTo(ArrayList()) {
|
||||||
((1..9) + 0).forEachIndexed { i, n ->
|
it.toKeyParams(params, labelFlags = Key.LABEL_FLAGS_DISABLE_HINT_LABEL or defaultLabelFlags)
|
||||||
row.add(KeyParams(
|
|
||||||
n.toString(), // todo (non-latin): use language more keys to adjust, possibly in combination with some setting
|
|
||||||
params,
|
|
||||||
params.mDefaultRelativeKeyWidth,
|
|
||||||
Key.LABEL_FLAGS_DISABLE_HINT_LABEL, // todo (later): maybe optional or enable (but then all numbers should have moreKeys)
|
|
||||||
Key.BACKGROUND_TYPE_NORMAL,
|
|
||||||
numbersMoreKeys[i] // todo (non-latin): alternative numbers should be in language more keys, which to put where needs to be decided
|
|
||||||
))
|
|
||||||
}
|
|
||||||
return row
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
|
@ -254,7 +256,17 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
||||||
val width = relativeWidth ?: params.mDefaultRelativeKeyWidth
|
val width = relativeWidth ?: params.mDefaultRelativeKeyWidth
|
||||||
return when (key) {
|
return when (key) {
|
||||||
FunctionalKey.SYMBOL -> KeyParams(
|
FunctionalKey.SYMBOL -> KeyParams(
|
||||||
"${getSymbolLabel()}|!code/key_switch_alpha_symbol", // todo (later): in numpad the code is key_symbolNumpad
|
getToSymbolLabel(),
|
||||||
|
getToSymbolCode(),
|
||||||
|
params,
|
||||||
|
width,
|
||||||
|
Key.LABEL_FLAGS_PRESERVE_CASE or Key.LABEL_FLAGS_FOLLOW_FUNCTIONAL_TEXT_COLOR,
|
||||||
|
Key.BACKGROUND_TYPE_FUNCTIONAL,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
FunctionalKey.ALPHA -> KeyParams(
|
||||||
|
params.mLocaleKeyTexts.labelAlphabet,
|
||||||
|
getToAlphaCode(),
|
||||||
params,
|
params,
|
||||||
width,
|
width,
|
||||||
Key.LABEL_FLAGS_PRESERVE_CASE or Key.LABEL_FLAGS_FOLLOW_FUNCTIONAL_TEXT_COLOR,
|
Key.LABEL_FLAGS_PRESERVE_CASE or Key.LABEL_FLAGS_FOLLOW_FUNCTIONAL_TEXT_COLOR,
|
||||||
|
@ -262,15 +274,23 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
FunctionalKey.COMMA -> KeyParams(
|
FunctionalKey.COMMA -> KeyParams(
|
||||||
label ?: getDefaultCommaLabel(),
|
label ?: getCommaLabel(),
|
||||||
params,
|
params,
|
||||||
width,
|
width,
|
||||||
Key.LABEL_FLAGS_HAS_POPUP_HINT, // previously only if normal comma, but always is more correct
|
Key.LABEL_FLAGS_HAS_POPUP_HINT, // previously only if normal comma, but always is more correct
|
||||||
if (label?.first()
|
if (label?.first()?.isLetter() == true) Key.BACKGROUND_TYPE_NORMAL // mimic behavior of old dvorak and halmak layouts
|
||||||
?.isLetter() == true
|
else Key.BACKGROUND_TYPE_FUNCTIONAL,
|
||||||
) Key.BACKGROUND_TYPE_NORMAL else Key.BACKGROUND_TYPE_FUNCTIONAL,
|
|
||||||
moreKeys?.let { getCommaMoreKeys() + it } ?: getCommaMoreKeys()
|
moreKeys?.let { getCommaMoreKeys() + it } ?: getCommaMoreKeys()
|
||||||
)
|
)
|
||||||
|
FunctionalKey.PERIOD -> KeyParams(
|
||||||
|
label ?: params.mLocaleKeyTexts.labelPeriod,
|
||||||
|
params,
|
||||||
|
width,
|
||||||
|
Key.LABEL_FLAGS_HAS_POPUP_HINT or Key.LABEL_FLAGS_HAS_SHIFTED_LETTER_HINT or defaultLabelFlags, // 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,
|
||||||
|
moreKeys?.let { getPunctuationMoreKeys() + it } ?: getPunctuationMoreKeys()
|
||||||
|
)
|
||||||
FunctionalKey.SPACE -> KeyParams(
|
FunctionalKey.SPACE -> KeyParams(
|
||||||
"!icon/space_key|!code/key_space", // !icon/space_key_for_number_layout in number layout, but not on tablet
|
"!icon/space_key|!code/key_space", // !icon/space_key_for_number_layout in number layout, but not on tablet
|
||||||
params,
|
params,
|
||||||
|
@ -279,16 +299,6 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
||||||
Key.BACKGROUND_TYPE_SPACEBAR,
|
Key.BACKGROUND_TYPE_SPACEBAR,
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
FunctionalKey.PERIOD -> KeyParams(
|
|
||||||
label ?: ".",
|
|
||||||
params,
|
|
||||||
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
|
|
||||||
if (label?.first()
|
|
||||||
?.isLetter() == true
|
|
||||||
) Key.BACKGROUND_TYPE_NORMAL else Key.BACKGROUND_TYPE_FUNCTIONAL,
|
|
||||||
moreKeys?.let { getPunctuationMoreKeys() + it } ?: getPunctuationMoreKeys()
|
|
||||||
)
|
|
||||||
FunctionalKey.ACTION -> KeyParams(
|
FunctionalKey.ACTION -> KeyParams(
|
||||||
"${getActionKeyLabel()}|${getActionKeyCode()}",
|
"${getActionKeyLabel()}|${getActionKeyCode()}",
|
||||||
params,
|
params,
|
||||||
|
@ -348,14 +358,6 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
||||||
Key.BACKGROUND_TYPE_FUNCTIONAL,
|
Key.BACKGROUND_TYPE_FUNCTIONAL,
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
FunctionalKey.ALPHA -> KeyParams(
|
|
||||||
"${getAlphabetLabel()}|!code/key_switch_alpha_symbol", // todo (later): in numpad the code is key_alphaNumpad
|
|
||||||
params,
|
|
||||||
width,
|
|
||||||
Key.LABEL_FLAGS_PRESERVE_CASE or Key.LABEL_FLAGS_FOLLOW_FUNCTIONAL_TEXT_COLOR,
|
|
||||||
Key.BACKGROUND_TYPE_FUNCTIONAL,
|
|
||||||
null
|
|
||||||
)
|
|
||||||
FunctionalKey.NUMPAD -> KeyParams(
|
FunctionalKey.NUMPAD -> KeyParams(
|
||||||
"!icon/numpad_key|!code/key_numpad",
|
"!icon/numpad_key|!code/key_numpad",
|
||||||
params,
|
params,
|
||||||
|
@ -460,34 +462,51 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
||||||
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)
|
||||||
|
if (id == 0) {
|
||||||
|
Log.w(this::class.simpleName, "no resource for label $this")
|
||||||
|
if (DebugFlags.DEBUG_ENABLED)
|
||||||
|
Toast.makeText(context, "no resource for label $this", Toast.LENGTH_LONG).show()
|
||||||
|
return this
|
||||||
|
}
|
||||||
val ril = object : RunInLocale<String>() { // todo (later): simpler way of doing this in a single line?
|
val ril = object : RunInLocale<String>() { // todo (later): simpler way of doing this in a single line?
|
||||||
override fun job(res: Resources) = res.getString(id)
|
override fun job(res: Resources) = res.getString(id)
|
||||||
}
|
}
|
||||||
return ril.runInLocale(context.resources, params.mId.locale)
|
return ril.runInLocale(context.resources, params.mId.locale)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getAlphabetLabel() = params.mLocaleKeyTexts.labelAlphabet
|
private fun getToSymbolLabel() =
|
||||||
|
if (params.mId.mElementId == KeyboardId.ELEMENT_SYMBOLS || params.mId.mElementId == KeyboardId.ELEMENT_SYMBOLS_SHIFTED)
|
||||||
|
params.mLocaleKeyTexts.labelAlphabet
|
||||||
|
else params.mLocaleKeyTexts.labelSymbol
|
||||||
|
|
||||||
private fun getSymbolLabel() = params.mLocaleKeyTexts.labelSymbols
|
private fun getToSymbolCode() =
|
||||||
|
if (params.mId.mElementId == KeyboardId.ELEMENT_NUMPAD)
|
||||||
|
Constants.CODE_SYMBOL_FROM_NUMPAD
|
||||||
|
else Constants.CODE_SWITCH_ALPHA_SYMBOL
|
||||||
|
|
||||||
|
private fun getToAlphaCode() =
|
||||||
|
if (params.mId.mElementId == KeyboardId.ELEMENT_NUMPAD)
|
||||||
|
Constants.CODE_ALPHA_FROM_NUMPAD
|
||||||
|
else Constants.CODE_SWITCH_ALPHA_SYMBOL
|
||||||
|
|
||||||
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 params.mLocaleKeyTexts.labelShiftSymbols
|
return params.mLocaleKeyTexts.labelSymbol
|
||||||
if (elementId == KeyboardId.ELEMENT_SYMBOLS)
|
if (elementId == KeyboardId.ELEMENT_SYMBOLS)
|
||||||
return getSymbolLabel()
|
return params.mLocaleKeyTexts.labelShiftSymbol
|
||||||
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
|
||||||
|| elementId == KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED || elementId == KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED)
|
|| elementId == KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED || elementId == KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED)
|
||||||
return "!icon/shift_key_shifted"
|
return "!icon/shift_key_shifted"
|
||||||
return "!icon/shift_key"
|
return "!icon/shift_key"
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getDefaultCommaLabel(): String {
|
private fun getCommaLabel(): String {
|
||||||
if (params.mId.mMode == KeyboardId.MODE_URL)
|
if (params.mId.mMode == KeyboardId.MODE_URL)
|
||||||
return "/"
|
return "/"
|
||||||
if (params.mId.mMode == KeyboardId.MODE_EMAIL)
|
if (params.mId.mMode == KeyboardId.MODE_EMAIL)
|
||||||
return "\\@"
|
return "\\@"
|
||||||
return ","
|
return params.mLocaleKeyTexts.labelComma
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getCommaMoreKeys(): Array<String> {
|
private fun getCommaMoreKeys(): Array<String> {
|
||||||
|
@ -509,7 +528,6 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
||||||
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("…")
|
||||||
val moreKeys = params.mLocaleKeyTexts.getMoreKeys("punctuation") ?:
|
val moreKeys = params.mLocaleKeyTexts.getMoreKeys("punctuation") ?:
|
||||||
// todo: some (non-latin) languages have different parenthesis keys (maybe rtl has inverted?)
|
|
||||||
arrayOf("${Key.MORE_KEYS_AUTO_COLUMN_ORDER}8", "\\,", "?", "!", "#", ")", "(", "/", ";", "'", "@", ":", "-", "\"", "+", "\\%", "&")
|
arrayOf("${Key.MORE_KEYS_AUTO_COLUMN_ORDER}8", "\\,", "?", "!", "#", ")", "(", "/", ";", "'", "@", ":", "-", "\"", "+", "\\%", "&")
|
||||||
if (context.resources.getInteger(R.integer.config_screen_metrics) >= 3 && moreKeys.contains("!") && moreKeys.contains("?")) {
|
if (context.resources.getInteger(R.integer.config_screen_metrics) >= 3 && moreKeys.contains("!") && moreKeys.contains("?")) {
|
||||||
// we have a tablet, remove ! and ? keys and reduce number in autoColumnOrder
|
// we have a tablet, remove ! and ? keys and reduce number in autoColumnOrder
|
||||||
|
@ -524,19 +542,26 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun createParserForLayout(params: KeyboardParams, context: Context): KeyboardParser? {
|
fun parseFromAssets(params: KeyboardParams, context: Context): ArrayList<ArrayList<KeyParams>>? {
|
||||||
|
val id = params.mId
|
||||||
val layoutName = params.mId.mSubtype.keyboardLayoutSetName
|
val layoutName = params.mId.mSubtype.keyboardLayoutSetName
|
||||||
val layoutFileNames = context.assets.list("layouts") ?: return null
|
val layoutFileNames = context.assets.list("layouts") ?: return null
|
||||||
if (layoutFileNames.contains("$layoutName.json"))
|
return when {
|
||||||
return JsonKeyboardParser(params, context)
|
id.mElementId == KeyboardId.ELEMENT_SYMBOLS && ScriptUtils.getScriptFromSpellCheckerLocale(params.mId.locale) == ScriptUtils.SCRIPT_ARABIC
|
||||||
val simpleLayoutName = getSimpleLayoutName(layoutName)
|
-> SimpleKeyboardParser(params, context).parseLayoutFromAssets("symbols_arabic")
|
||||||
if (layoutFileNames.contains("$simpleLayoutName.txt"))
|
id.mElementId == KeyboardId.ELEMENT_SYMBOLS -> SimpleKeyboardParser(params, context).parseLayoutFromAssets("symbols")
|
||||||
return SimpleKeyboardParser(params, context)
|
id.mElementId == KeyboardId.ELEMENT_SYMBOLS_SHIFTED
|
||||||
return null
|
-> SimpleKeyboardParser(params, context).parseLayoutFromAssets("symbols_shifted")
|
||||||
|
!id.isAlphabetKeyboard -> null
|
||||||
|
layoutFileNames.contains("$layoutName.json") -> JsonKeyboardParser(params, context).parseLayoutFromAssets(layoutName)
|
||||||
|
layoutFileNames.contains("${getSimpleLayoutName(layoutName)}.txt")
|
||||||
|
-> SimpleKeyboardParser(params, context).parseLayoutFromAssets(layoutName)
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic // unsupported without JvmStatic
|
@JvmStatic // unsupported without JvmStatic
|
||||||
protected fun getSimpleLayoutName(layoutName: String)= when (layoutName) {
|
protected fun getSimpleLayoutName(layoutName: String) = when (layoutName) {
|
||||||
"swiss", "german", "serbian_qwertz" -> "qwertz"
|
"swiss", "german", "serbian_qwertz" -> "qwertz"
|
||||||
"nordic", "spanish" -> "qwerty"
|
"nordic", "spanish" -> "qwerty"
|
||||||
else -> layoutName
|
else -> layoutName
|
||||||
|
@ -548,20 +573,29 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// moreKeys for numbers, order is 1-9 and then 0
|
|
||||||
// todo (later): like numbers, for non-latin layouts this depends on language and therefore should not be in the parser
|
fun String.rtlLabel(params: KeyboardParams): String {
|
||||||
private val numbersMoreKeys = arrayOf(
|
if (!params.mId.mSubtype.isRtlSubtype) return this
|
||||||
arrayOf("¹", "½", "⅓","¼", "⅛"),
|
return when (this) {
|
||||||
arrayOf("²", "⅔"),
|
"{" -> "{|}"
|
||||||
arrayOf("³", "¾", "⅜"),
|
"}" -> "}|{"
|
||||||
arrayOf("⁴"),
|
"(" -> "(|)"
|
||||||
arrayOf("⅝"),
|
")" -> ")|("
|
||||||
null,
|
"[" -> "{|]"
|
||||||
arrayOf("⅞"),
|
"]" -> "]|["
|
||||||
null,
|
"<" -> "<|>"
|
||||||
null,
|
">" -> ">|<"
|
||||||
arrayOf("ⁿ", "∅"),
|
"≤" -> "≤|≥"
|
||||||
)
|
"≥" -> "≥|≤"
|
||||||
|
"«" -> "«|»"
|
||||||
|
"»" -> "»|«"
|
||||||
|
"‹" -> "‹|›"
|
||||||
|
"›" -> "›|‹"
|
||||||
|
"﴾" -> "﴾|﴿"
|
||||||
|
"﴿" -> "﴿|﴾"
|
||||||
|
else -> this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// could make arrays right away, but they need to be copied anyway as moreKeys arrays are modified when creating KeyParams
|
// could make arrays right away, but they need to be copied anyway as moreKeys arrays are modified when creating KeyParams
|
||||||
private const val MORE_KEYS_NAVIGATE_PREVIOUS = "!icon/previous_key|!code/key_action_previous,!icon/clipboard_action_key|!code/key_clipboard"
|
private const val MORE_KEYS_NAVIGATE_PREVIOUS = "!icon/previous_key|!code/key_action_previous,!icon/clipboard_action_key|!code/key_clipboard"
|
||||||
|
|
|
@ -11,12 +11,34 @@ import java.io.InputStream
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import kotlin.math.round
|
import kotlin.math.round
|
||||||
|
|
||||||
class LocaleKeyTexts(dataStream: InputStream?) {
|
class LocaleKeyTexts(dataStream: InputStream?, locale: Locale) {
|
||||||
private val moreKeys = hashMapOf<String, Array<String>>()
|
private val moreKeys = hashMapOf<String, Array<String>>()
|
||||||
private val extraKeys = Array<MutableList<KeyData>?>(5) { null }
|
private val extraKeys = Array<MutableList<KeyData>?>(5) { null }
|
||||||
var labelSymbols = "\\?123"
|
var labelSymbol = "\\?123"
|
||||||
|
private set
|
||||||
var labelAlphabet = "ABC"
|
var labelAlphabet = "ABC"
|
||||||
var labelShiftSymbols = "=\\<"
|
private set
|
||||||
|
var labelShiftSymbol = "= \\\\ <"
|
||||||
|
private set
|
||||||
|
var labelComma = ","
|
||||||
|
private set
|
||||||
|
var labelPeriod = "."
|
||||||
|
private set
|
||||||
|
val currencyKey = getCurrencyKey(locale)
|
||||||
|
private var numberKeys = ((1..9) + 0).map { it.toString() }
|
||||||
|
private val numbersMoreKeys = arrayOf(
|
||||||
|
mutableListOf("¹", "½", "⅓","¼", "⅛"),
|
||||||
|
mutableListOf("²", "⅔"),
|
||||||
|
mutableListOf("³", "¾", "⅜"),
|
||||||
|
mutableListOf("⁴"),
|
||||||
|
mutableListOf("⅝"),
|
||||||
|
mutableListOf(),
|
||||||
|
mutableListOf("⅞"),
|
||||||
|
mutableListOf(),
|
||||||
|
mutableListOf(),
|
||||||
|
mutableListOf("ⁿ", "∅"),
|
||||||
|
)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
readStream(dataStream, false)
|
readStream(dataStream, false)
|
||||||
// set default quote moreKeys if necessary
|
// set default quote moreKeys if necessary
|
||||||
|
@ -42,11 +64,13 @@ class LocaleKeyTexts(dataStream: InputStream?) {
|
||||||
"[morekeys]" -> { mode = READER_MODE_MORE_KEYS; return@forEachLine }
|
"[morekeys]" -> { mode = READER_MODE_MORE_KEYS; return@forEachLine }
|
||||||
"[extra_keys]" -> { mode = READER_MODE_EXTRA_KEYS; return@forEachLine }
|
"[extra_keys]" -> { mode = READER_MODE_EXTRA_KEYS; return@forEachLine }
|
||||||
"[labels]" -> { mode = READER_MODE_LABELS; return@forEachLine }
|
"[labels]" -> { mode = READER_MODE_LABELS; return@forEachLine }
|
||||||
|
"[number_row]" -> { mode = READER_MODE_NUMBER_ROW; return@forEachLine }
|
||||||
}
|
}
|
||||||
when (mode) {
|
when (mode) {
|
||||||
READER_MODE_MORE_KEYS -> addMoreKeys(line.splitOnWhitespace())
|
READER_MODE_MORE_KEYS -> addMoreKeys(line.splitOnWhitespace())
|
||||||
READER_MODE_EXTRA_KEYS -> if (!onlyMoreKeys) addExtraKey(line.split(colonSpaceRegex, 2))
|
READER_MODE_EXTRA_KEYS -> if (!onlyMoreKeys) addExtraKey(line.split(colonSpaceRegex, 2))
|
||||||
READER_MODE_LABELS -> if (!onlyMoreKeys) addLabel(line.split(colonSpaceRegex, 2))
|
READER_MODE_LABELS -> if (!onlyMoreKeys) addLabel(line.split(colonSpaceRegex, 2))
|
||||||
|
READER_MODE_NUMBER_ROW -> if (!onlyMoreKeys) setNumberRow(line.splitOnWhitespace())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,6 +79,7 @@ class LocaleKeyTexts(dataStream: InputStream?) {
|
||||||
// need tp provide a copy because some functions like MoreKeySpec.insertAdditionalMoreKeys may modify the array
|
// 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 getMoreKeys(label: String): Array<String>? = moreKeys[label]?.copyOf()
|
||||||
|
|
||||||
|
// used by simple parser only, but could be possible for json as well (if necessary)
|
||||||
fun getExtraKeys(row: Int): List<KeyData>? =
|
fun getExtraKeys(row: Int): List<KeyData>? =
|
||||||
if (row > extraKeys.size) null
|
if (row > extraKeys.size) null
|
||||||
else extraKeys[row]
|
else extraKeys[row]
|
||||||
|
@ -84,11 +109,33 @@ class LocaleKeyTexts(dataStream: InputStream?) {
|
||||||
private fun addLabel(split: List<String>) {
|
private fun addLabel(split: List<String>) {
|
||||||
if (split.size < 2) return
|
if (split.size < 2) return
|
||||||
when (split.first()) {
|
when (split.first()) {
|
||||||
"symbols" -> labelSymbols = split.last()
|
"symbol" -> labelSymbol = split.last()
|
||||||
"alphabet" -> labelAlphabet = split.last()
|
"alphabet" -> labelAlphabet = split.last()
|
||||||
"shift_symbols" -> labelShiftSymbols = split.last()
|
"shift_symbol" -> labelShiftSymbol = split.last() // never used, but could be...
|
||||||
|
"comma" -> labelComma = split.last()
|
||||||
|
"period" -> labelPeriod = split.last()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set number row only, does not affect moreKeys
|
||||||
|
// setting more than 10 number keys will cause crashes, but could actually be implemented at some point
|
||||||
|
private fun setNumberRow(split: List<String>) {
|
||||||
|
if (numberKeys == split) return
|
||||||
|
numberKeys.forEachIndexed { i, n -> numbersMoreKeys[i].add(0, n) }
|
||||||
|
numberKeys = split
|
||||||
|
}
|
||||||
|
|
||||||
|
// get number row including moreKeys
|
||||||
|
fun getNumberRow(): List<KeyData> =
|
||||||
|
numberKeys.mapIndexed { i, label ->
|
||||||
|
label.toTextKey(numbersMoreKeys[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
// get moreKeys with the number itself (as used on alphabet keyboards)
|
||||||
|
fun getNumberMoreKeys(numberIndex: Int?): List<String> {
|
||||||
|
if (numberIndex == null) return emptyList()
|
||||||
|
return listOf(numberKeys[numberIndex]) + numbersMoreKeys[numberIndex]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun mergeMoreKeys(original: Array<String>, added: List<String>): Array<String> {
|
private fun mergeMoreKeys(original: Array<String>, added: List<String>): Array<String> {
|
||||||
|
@ -141,7 +188,7 @@ fun addLocaleKeyTextsToParams(context: Context, params: KeyboardParams, moreKeys
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createLocaleKeyTexts(context: Context, params: KeyboardParams, moreKeysSetting: Int): LocaleKeyTexts {
|
private fun createLocaleKeyTexts(context: Context, params: KeyboardParams, moreKeysSetting: Int): LocaleKeyTexts {
|
||||||
val lkt = LocaleKeyTexts(getStreamForLocale(params.mId.locale, context))
|
val lkt = LocaleKeyTexts(getStreamForLocale(params.mId.locale, context), params.mId.locale)
|
||||||
if (moreKeysSetting == MORE_KEYS_MORE)
|
if (moreKeysSetting == MORE_KEYS_MORE)
|
||||||
lkt.addFile(context.assets.open("$LANGUAGE_TEXTS_FOLDER/all_more_keys.txt"))
|
lkt.addFile(context.assets.open("$LANGUAGE_TEXTS_FOLDER/all_more_keys.txt"))
|
||||||
else if (moreKeysSetting == MORE_KEYS_ALL)
|
else if (moreKeysSetting == MORE_KEYS_ALL)
|
||||||
|
@ -174,16 +221,17 @@ private const val READER_MODE_NONE = 0
|
||||||
private const val READER_MODE_MORE_KEYS = 1
|
private const val READER_MODE_MORE_KEYS = 1
|
||||||
private const val READER_MODE_EXTRA_KEYS = 2
|
private const val READER_MODE_EXTRA_KEYS = 2
|
||||||
private const val READER_MODE_LABELS = 3
|
private const val READER_MODE_LABELS = 3
|
||||||
|
private const val READER_MODE_NUMBER_ROW = 4
|
||||||
|
|
||||||
// probably could be improved and extended, currently this is what's done in key_styles_currency.xml
|
// 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>> {
|
private fun getCurrencyKey(locale: Locale): Pair<String, Array<String>> {
|
||||||
if (locale.country.matches(euroCountries))
|
if (locale.country.matches(euroCountries))
|
||||||
return euro
|
return euro
|
||||||
if (locale.toString().matches(euroLocales))
|
if (locale.toString().matches(euroLocales))
|
||||||
return euro
|
return euro
|
||||||
if (locale.language.matches("ca|eu|lb|mt".toRegex()))
|
if (locale.language.matches("ca|eu|lb|mt".toRegex()))
|
||||||
return euro
|
return euro
|
||||||
if (locale.language.matches("fa|iw|ko|lo|mn|ne|th|uk|vi".toRegex()))
|
if (locale.language.matches("fa|iw|ko|lo|mn|ne|si|th|uk|vi|km".toRegex()))
|
||||||
return genericCurrencyKey(getCurrency(locale))
|
return genericCurrencyKey(getCurrency(locale))
|
||||||
if (locale.language == "hy")
|
if (locale.language == "hy")
|
||||||
return dram
|
return dram
|
||||||
|
@ -193,6 +241,8 @@ fun getCurrencyKey(locale: Locale): Pair<String, Array<String>> {
|
||||||
return ruble
|
return ruble
|
||||||
if (locale.country == "LK" || locale.country == "BD")
|
if (locale.country == "LK" || locale.country == "BD")
|
||||||
return genericCurrencyKey(getCurrency(locale))
|
return genericCurrencyKey(getCurrency(locale))
|
||||||
|
if (locale.country == "IN" && locale.language == "ta")
|
||||||
|
return genericCurrencyKey("௹")
|
||||||
if (locale.country == "IN" || locale.language.matches("hi|kn|ml|mr|ta|te".toRegex()))
|
if (locale.country == "IN" || locale.language.matches("hi|kn|ml|mr|ta|te".toRegex()))
|
||||||
return rupee
|
return rupee
|
||||||
if (locale.country == "GB")
|
if (locale.country == "GB")
|
||||||
|
@ -217,6 +267,7 @@ private fun getCurrency(locale: Locale): String {
|
||||||
"th" -> "฿"
|
"th" -> "฿"
|
||||||
"uk" -> "₴"
|
"uk" -> "₴"
|
||||||
"vi" -> "₫"
|
"vi" -> "₫"
|
||||||
|
"km" -> "៛"
|
||||||
else -> "$"
|
else -> "$"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ import org.dslul.openboard.inputmethod.latin.common.splitOnWhitespace
|
||||||
*/
|
*/
|
||||||
class SimpleKeyboardParser(private val params: KeyboardParams, private val context: Context) : KeyboardParser(params, context) {
|
class SimpleKeyboardParser(private val params: KeyboardParams, private val context: Context) : KeyboardParser(params, context) {
|
||||||
private val addExtraKeys =
|
private val addExtraKeys =
|
||||||
params.mId.locale.language != "eo"
|
params.mId.isAlphabetKeyboard && params.mId.locale.language != "eo"
|
||||||
&& params.mId.mSubtype.keyboardLayoutSetName in listOf("nordic", "spanish", "german", "swiss", "serbian_qwertz")
|
&& params.mId.mSubtype.keyboardLayoutSetName in listOf("nordic", "spanish", "german", "swiss", "serbian_qwertz")
|
||||||
|
|
||||||
override fun getLayoutFromAssets(layoutName: String) =
|
override fun getLayoutFromAssets(layoutName: String) =
|
||||||
|
|
|
@ -11,6 +11,7 @@ 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.KeyboardId
|
import org.dslul.openboard.inputmethod.keyboard.KeyboardId
|
||||||
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardParams
|
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardParams
|
||||||
|
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.rtlLabel
|
||||||
import org.dslul.openboard.inputmethod.latin.common.StringUtils
|
import org.dslul.openboard.inputmethod.latin.common.StringUtils
|
||||||
|
|
||||||
// taken from FlorisBoard, small modifications
|
// taken from FlorisBoard, small modifications
|
||||||
|
@ -113,7 +114,7 @@ interface KeyData : AbstractKeyData {
|
||||||
// code will be determined from label if possible (i.e. label is single code point)
|
// code will be determined from label if possible (i.e. label is single code point)
|
||||||
// but also longer labels should work without issues, also for MultiTextKeyData
|
// but also longer labels should work without issues, also for MultiTextKeyData
|
||||||
KeyParams(
|
KeyParams(
|
||||||
label, // todo (when supported): convert special labels to keySpec
|
label.rtlLabel(params), // todo (when supported): convert special labels to keySpec
|
||||||
params,
|
params,
|
||||||
width,
|
width,
|
||||||
labelFlags, // todo (non-latin): label flags... maybe relevant for some languages
|
labelFlags, // todo (non-latin): label flags... maybe relevant for some languages
|
||||||
|
@ -123,7 +124,7 @@ interface KeyData : AbstractKeyData {
|
||||||
} else {
|
} else {
|
||||||
KeyParams(
|
KeyParams(
|
||||||
label.ifEmpty { StringUtils.newSingleCodePointString(code) },
|
label.ifEmpty { StringUtils.newSingleCodePointString(code) },
|
||||||
code, // todo (when supported): convert codes < 0
|
code, // todo (when supported): convert codes < 0, because florisboard layouts should still be usable
|
||||||
params,
|
params,
|
||||||
width,
|
width,
|
||||||
labelFlags,
|
labelFlags,
|
||||||
|
|
|
@ -6,12 +6,12 @@ package org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.floris
|
||||||
|
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardParams
|
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardParams
|
||||||
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.getCurrencyKey
|
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.rtlLabel
|
||||||
|
|
||||||
// taken from FlorisBoard, small modifications
|
// taken from FlorisBoard, small modifications
|
||||||
// mutable set removed (currently the moreKeys assembly is happening in KeyParams)
|
// mutable set removed (currently the moreKeys assembly is happening in KeyParams)
|
||||||
// toMoreKeys and size added
|
// .toMoreKeys added
|
||||||
// popupKeys not used, but might switch to this later
|
// PopupKeys not used, but might switch to this later
|
||||||
// currently hint would be taken from other, and languageMoreKeys are prioritized
|
// currently hint would be taken from other, and languageMoreKeys are prioritized
|
||||||
/**
|
/**
|
||||||
* A popup set for a single key. This set describes, if the key has a [main] character and other [relevant] popups.
|
* A popup set for a single key. This set describes, if the key has a [main] character and other [relevant] popups.
|
||||||
|
@ -29,23 +29,27 @@ open class PopupSet<T : AbstractKeyData>(
|
||||||
// could make use of PopupKeys, and also provide a hint depending on user choice
|
// could make use of PopupKeys, and also provide a hint depending on user choice
|
||||||
// then language key joining should be done in here too
|
// then language key joining should be done in here too
|
||||||
// also what about getting the moreKeys and key hint from chosen symbol layout?
|
// also what about getting the moreKeys and key hint from chosen symbol layout?
|
||||||
fun toMoreKeys(params: KeyboardParams) = if (isEmpty) null // need null instead of empty array for KeyParams
|
fun toMoreKeys(params: KeyboardParams): Array<String>? {
|
||||||
else (listOfNotNull(number?.toString(), main?.getLabel(params)) + relevant
|
val moreKeys = mutableListOf<String>()
|
||||||
// todo: this is not nice and creates unnecessary intermediate lists
|
// number + main + relevant in this order (label is later taken from first element in resulting array)
|
||||||
// best treat the currency key properly, like florisboard does
|
moreKeys.addAll(params.mLocaleKeyTexts.getNumberMoreKeys(numberIndex))
|
||||||
.map { it.getLabel(params) }).map {
|
main?.getLabel(params)?.let { moreKeys.add(it) }
|
||||||
if (it == "$$$") {
|
moreKeys.addAll(relevant.map {
|
||||||
|
val label = it.getLabel(params)
|
||||||
|
if (label == "$$$") { // currency key
|
||||||
if (params.mId.passwordInput()) "$"
|
if (params.mId.passwordInput()) "$"
|
||||||
else getCurrencyKey(params.mId.locale).first
|
else params.mLocaleKeyTexts.currencyKey.first
|
||||||
|
} else if (params.mId.mSubtype.isRtlSubtype) {
|
||||||
|
label.rtlLabel(params)
|
||||||
|
} else label
|
||||||
|
})
|
||||||
|
return moreKeys.takeIf { it.isNotEmpty() }?.toTypedArray()
|
||||||
}
|
}
|
||||||
else it
|
|
||||||
}.toTypedArray()
|
|
||||||
|
|
||||||
private val popupKeys: PopupKeys<T> by lazy {
|
private val popupKeys: PopupKeys<T> by lazy {
|
||||||
PopupKeys(null, listOfNotNull(main), relevant)
|
PopupKeys(null, listOfNotNull(main), relevant)
|
||||||
}
|
}
|
||||||
var number: Int? = null
|
var numberIndex: Int? = null
|
||||||
val isEmpty get() = main == null && relevant.isEmpty() && number == null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -8,13 +8,12 @@ package org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.floris
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.Transient
|
import kotlinx.serialization.Transient
|
||||||
import org.dslul.openboard.inputmethod.keyboard.Key
|
|
||||||
import org.dslul.openboard.inputmethod.keyboard.Key.KeyParams
|
|
||||||
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardParams
|
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardParams
|
||||||
|
|
||||||
// taken from FlorisBoard, small modifications (see also KeyData)
|
// taken from FlorisBoard, small modifications (see also KeyData)
|
||||||
// internal keys removed (currently no plan to support them)
|
// internal keys removed (currently no plan to support them)
|
||||||
// added String.toTextKey
|
// added String.toTextKey
|
||||||
|
// currency key handling (see todo below...)
|
||||||
/**
|
/**
|
||||||
* Data class which describes a single key and its attributes.
|
* Data class which describes a single key and its attributes.
|
||||||
*
|
*
|
||||||
|
@ -41,6 +40,12 @@ class TextKeyData(
|
||||||
// TextKeyData(type, data.code, data.label, groupId, popup).compute(params)
|
// TextKeyData(type, data.code, data.label, groupId, popup).compute(params)
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
if (label.startsWith("$$$")) { // currency key
|
||||||
|
if (label == "$$$") return params.mLocaleKeyTexts.currencyKey.let { it.first.toTextKey(it.second.toList()) }
|
||||||
|
val n = label.substringAfter("$$$").toIntOrNull()
|
||||||
|
if (n != null && n <= 4)
|
||||||
|
return params.mLocaleKeyTexts.currencyKey.second[n - 1].toTextKey()
|
||||||
|
}
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,8 @@ public class ScriptUtils {
|
||||||
mLanguageCodeToScriptCode = new TreeMap<>();
|
mLanguageCodeToScriptCode = new TreeMap<>();
|
||||||
mLanguageCodeToScriptCode.put("", SCRIPT_LATIN); // default
|
mLanguageCodeToScriptCode.put("", SCRIPT_LATIN); // default
|
||||||
mLanguageCodeToScriptCode.put("ar", SCRIPT_ARABIC);
|
mLanguageCodeToScriptCode.put("ar", SCRIPT_ARABIC);
|
||||||
|
mLanguageCodeToScriptCode.put("ur", SCRIPT_ARABIC);
|
||||||
|
mLanguageCodeToScriptCode.put("fa", SCRIPT_ARABIC);
|
||||||
mLanguageCodeToScriptCode.put("hy", SCRIPT_ARMENIAN);
|
mLanguageCodeToScriptCode.put("hy", SCRIPT_ARMENIAN);
|
||||||
mLanguageCodeToScriptCode.put("bg", SCRIPT_BULGARIAN);
|
mLanguageCodeToScriptCode.put("bg", SCRIPT_BULGARIAN);
|
||||||
mLanguageCodeToScriptCode.put("bn", SCRIPT_BENGALI);
|
mLanguageCodeToScriptCode.put("bn", SCRIPT_BENGALI);
|
||||||
|
|
|
@ -29,6 +29,8 @@ def read_keys(file):
|
||||||
root = ET.parse(file).getroot()
|
root = ET.parse(file).getroot()
|
||||||
morekeys = dict()
|
morekeys = dict()
|
||||||
extra_keys = dict()
|
extra_keys = dict()
|
||||||
|
labels = dict()
|
||||||
|
number_row = dict()
|
||||||
for key in root.iter("resources"):
|
for key in root.iter("resources"):
|
||||||
for string in key.iter("string"):
|
for string in key.iter("string"):
|
||||||
for tag, value in string.items():
|
for tag, value in string.items():
|
||||||
|
@ -41,23 +43,51 @@ def read_keys(file):
|
||||||
text = resolve_text(string.text, file)
|
text = resolve_text(string.text, file)
|
||||||
if "!text/" in text:
|
if "!text/" in text:
|
||||||
raise ValueError(f"can't have !text/ in {text} (from {string.text})")
|
raise ValueError(f"can't have !text/ in {text} (from {string.text})")
|
||||||
if " " in text:
|
if " " in text and "fixedColumnOrder" not in text: # issues with arabic punctuation (more) keys
|
||||||
raise ValueError(f"can't have consecutive spaces in {text} (from {string.text})")
|
raise ValueError(f"can't have consecutive spaces in {text} (from {string.text})")
|
||||||
if value.startswith("keyspec_") and "_row" in value:
|
if value.startswith("keyspec_") and "_row" in value and "slavic" not in value:
|
||||||
# put additional key labels (for nordic, spanish, swiss)
|
# put additional key labels (for nordic, spanish, swiss, german, but not for slavic, because here the keys are not extra)
|
||||||
key = value.split("_row")[1]
|
key = value.split("_row")[1]
|
||||||
d = extra_keys.get(key, dict())
|
d = extra_keys.get(key, dict())
|
||||||
d["label"] = text
|
d["label"] = text
|
||||||
extra_keys[key] = d
|
extra_keys[key] = d
|
||||||
elif value.startswith("morekeys_") and "_row" in value:
|
elif value.startswith("morekeys_") and "_row" in value and "slavic" not in value:
|
||||||
# put additional key morekeys (for nordic, spanish, swiss)
|
# put additional key morekeys (for nordic, spanish, swiss, german, but not for slavic, because here the keys are not extra)
|
||||||
key = value.split("_row")[1]
|
key = value.split("_row")[1]
|
||||||
d = extra_keys.get(key, dict())
|
d = extra_keys.get(key, dict())
|
||||||
d["morekeys"] = text
|
d["morekeys"] = text
|
||||||
extra_keys[key] = d
|
extra_keys[key] = d
|
||||||
elif value.startswith("morekeys_"):
|
elif value.startswith("morekeys_"):
|
||||||
key_label = value.split("morekeys_")[1]
|
key_label = value.split("morekeys_")[1]
|
||||||
|
if key_label == "period":
|
||||||
|
key_label = "punctuation" # used in the same place
|
||||||
if len(key_label) > 1 and key_label != "punctuation":
|
if len(key_label) > 1 and key_label != "punctuation":
|
||||||
|
if key_label.startswith("cyrillic_"):
|
||||||
|
label = key_label.split("cyrillic_")[1]
|
||||||
|
if label == "u":
|
||||||
|
key_label = "у"
|
||||||
|
elif label == "ka":
|
||||||
|
key_label = "к"
|
||||||
|
elif label == "ie":
|
||||||
|
key_label = "е"
|
||||||
|
elif label == "en":
|
||||||
|
key_label = "н"
|
||||||
|
elif label == "ghe":
|
||||||
|
key_label = "г"
|
||||||
|
elif label == "o":
|
||||||
|
key_label = "о"
|
||||||
|
elif label == "soft_sign":
|
||||||
|
key_label = "ь"
|
||||||
|
elif label == "a":
|
||||||
|
key_label = "а"
|
||||||
|
elif label == "i":
|
||||||
|
key_label = "и"
|
||||||
|
else:
|
||||||
|
print(f"ignoring cyrillic long more key: {key_label}: {text}")
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
if key_label not in ["bullet", "star", "left_parenthesis", "right_parenthesis", "less_than", "greater_than", "symbols_semicolon", "symbols_percent"]:
|
||||||
|
# only print for keys that are not already handled
|
||||||
print(f"ignoring long more key: {key_label}: {text}")
|
print(f"ignoring long more key: {key_label}: {text}")
|
||||||
continue
|
continue
|
||||||
morekeys[key_label] = text
|
morekeys[key_label] = text
|
||||||
|
@ -69,19 +99,35 @@ def read_keys(file):
|
||||||
prepend_to_morekeys(morekeys, text, '\"')
|
prepend_to_morekeys(morekeys, text, '\"')
|
||||||
elif value == "double_angle_quotes":
|
elif value == "double_angle_quotes":
|
||||||
append_to_morekeys(morekeys, text, '\"')
|
append_to_morekeys(morekeys, text, '\"')
|
||||||
# todo: labels should be in [labels] and use sth like symbols: ?123
|
elif value == "keylabel_to_alpha":
|
||||||
|
labels["alphabet"] = text
|
||||||
|
elif value == "keylabel_to_symbol":
|
||||||
|
labels["symbol"] = text
|
||||||
|
elif value == "keyspec_comma":
|
||||||
|
labels["comma"] = text
|
||||||
|
elif value == "keyspec_period":
|
||||||
|
labels["period"] = text
|
||||||
|
elif value.startswith("keyspec_symbols_") and len(value.split("keyspec_symbols_")[1]) == 1: # checking whether it's an int would be better, but bah
|
||||||
|
number_row[value.split("keyspec_symbols_")[1]] = text
|
||||||
|
elif "values-ur" in file and value.startswith("additional_morekeys_symbols_"):
|
||||||
|
number_row[value.split("additional_morekeys_symbols_")[1]] = text
|
||||||
|
# for some reason ur has the arabic numbers in moreKeys
|
||||||
|
elif value in ["keyspec_currency", "symbols_semicolon", "symbols_percent"] or value.startswith("additional_morekeys_symbols_") or "_left_" in value or "_right_" in value or "_greater" in value or "_less_" in value:
|
||||||
|
pass # ignore keys handled somewhere else (currency key not yet fully replaced)
|
||||||
else:
|
else:
|
||||||
print(f"ignored tag: {tag}={value}, {text}")
|
print(f"ignored tag: {tag}={value}, {text}")
|
||||||
keys = dict()
|
keys = dict()
|
||||||
keys["morekeys"] = morekeys
|
keys["morekeys"] = morekeys
|
||||||
keys["extra_keys"] = extra_keys
|
keys["extra_keys"] = extra_keys
|
||||||
|
keys["labels"] = labels
|
||||||
|
keys["number_row"] = number_row
|
||||||
return keys
|
return keys
|
||||||
|
|
||||||
|
|
||||||
def resolve_text(text, file):
|
def resolve_text(text, file):
|
||||||
if text.startswith("\"") and text.endswith("\"") and len(text) > 1:
|
if text.startswith("\"") and text.endswith("\"") and len(text) > 1:
|
||||||
text = text[1:-1]
|
text = text[1:-1]
|
||||||
sp = re.split("(?<!\\\\),", text)
|
sp = re.split("(?<!\\\\),", text) # split on comma, but not on escaped comma "\,"
|
||||||
|
|
||||||
if len(sp) > 1: # resolve each entry separately
|
if len(sp) > 1: # resolve each entry separately
|
||||||
result = []
|
result = []
|
||||||
|
@ -121,13 +167,16 @@ def read_locale_from_folder(folder):
|
||||||
def write_keys(outfile, keys, locc=""):
|
def write_keys(outfile, keys, locc=""):
|
||||||
with open(outfile, "w") as f:
|
with open(outfile, "w") as f:
|
||||||
# write section [more_keys], then [extra_keys], skip if empty
|
# write section [more_keys], then [extra_keys], skip if empty
|
||||||
|
has_extra_keys = len(keys["extra_keys"]) > 0
|
||||||
|
has_labels = len(keys["labels"]) > 0
|
||||||
|
has_number_row = len(keys["number_row"]) > 0
|
||||||
if len(keys["morekeys"]) > 0:
|
if len(keys["morekeys"]) > 0:
|
||||||
f.write("[morekeys]\n")
|
f.write("[morekeys]\n")
|
||||||
for k, v in keys["morekeys"].items():
|
for k, v in keys["morekeys"].items():
|
||||||
f.write(f"{k} {v}\n")
|
f.write(f"{k} {v}\n")
|
||||||
if len(keys["extra_keys"]) > 0:
|
if has_labels or has_number_row or has_extra_keys:
|
||||||
f.write("\n")
|
f.write("\n")
|
||||||
if len(keys["extra_keys"]) > 0 and locc != "eo": # eo has the extra key moved into the layout
|
if has_extra_keys and locc != "eo": # eo has the extra key moved into the layout
|
||||||
f.write("[extra_keys]\n")
|
f.write("[extra_keys]\n")
|
||||||
# clarify somewhere that extra keys only apply to default layout (where to get?)
|
# clarify somewhere that extra keys only apply to default layout (where to get?)
|
||||||
for k, v in sorted(keys["extra_keys"].items()):
|
for k, v in sorted(keys["extra_keys"].items()):
|
||||||
|
@ -138,6 +187,24 @@ def write_keys(outfile, keys, locc=""):
|
||||||
f.write(f"{row}: {label}\n")
|
f.write(f"{row}: {label}\n")
|
||||||
else:
|
else:
|
||||||
f.write(f"{row}: {label} {morekeys}\n")
|
f.write(f"{row}: {label} {morekeys}\n")
|
||||||
|
if has_labels or has_number_row:
|
||||||
|
f.write("\n")
|
||||||
|
if has_labels:
|
||||||
|
f.write("[labels]\n")
|
||||||
|
for k, v in keys["labels"].items():
|
||||||
|
f.write(f"{k}: {v}\n")
|
||||||
|
if has_number_row:
|
||||||
|
f.write("\n")
|
||||||
|
if has_number_row:
|
||||||
|
if len(keys["number_row"]) != 10:
|
||||||
|
raise ValueError("number row must have 10 keys")
|
||||||
|
f.write("[number_row]\n")
|
||||||
|
zero = keys["number_row"]["0"]
|
||||||
|
for k, v in sorted(keys["number_row"].items()):
|
||||||
|
if k == "0":
|
||||||
|
continue
|
||||||
|
f.write(f"{v} ")
|
||||||
|
f.write(f"{zero}\n")
|
||||||
|
|
||||||
|
|
||||||
def get_morekeys_texts(write=False):
|
def get_morekeys_texts(write=False):
|
||||||
|
@ -156,7 +223,7 @@ def get_morekeys_texts(write=False):
|
||||||
script = "Latn"
|
script = "Latn"
|
||||||
if script is None:
|
if script is None:
|
||||||
raise ValueError("undefined script")
|
raise ValueError("undefined script")
|
||||||
if script != "Latn":
|
if script == "Latn":
|
||||||
continue # skip non-latin scripts for now
|
continue # skip non-latin scripts for now
|
||||||
print(file)
|
print(file)
|
||||||
keys = read_keys(f"{file}/donottranslate-more-keys.xml")
|
keys = read_keys(f"{file}/donottranslate-more-keys.xml")
|
||||||
|
@ -164,12 +231,14 @@ def get_morekeys_texts(write=False):
|
||||||
if not write:
|
if not write:
|
||||||
continue
|
continue
|
||||||
outfile_name = locc.replace("-r", "_").lower() + ".txt"
|
outfile_name = locc.replace("-r", "_").lower() + ".txt"
|
||||||
outfile = pathlib.Path(out_folder + outfile_name)
|
# outfile = pathlib.Path(out_folder + outfile_name)
|
||||||
|
outfile = out_folder / outfile_name
|
||||||
outfile.parent.mkdir(exist_ok=True, parents=True)
|
outfile.parent.mkdir(exist_ok=True, parents=True)
|
||||||
write_keys(outfile, keys, locc)
|
write_keys(outfile, keys, locc)
|
||||||
return val
|
return val
|
||||||
|
|
||||||
|
|
||||||
|
# write lists of all moreKeys from different languages
|
||||||
def write_combined_lists(keys):
|
def write_combined_lists(keys):
|
||||||
infos_by_letters = dict()
|
infos_by_letters = dict()
|
||||||
for key in keys:
|
for key in keys:
|
||||||
|
@ -198,10 +267,8 @@ def write_combined_lists(keys):
|
||||||
def main():
|
def main():
|
||||||
# k = read_keys(default_file)
|
# k = read_keys(default_file)
|
||||||
# write_keys(pathlib.Path(__file__).parent / f"defaultkeys.txt", k)
|
# write_keys(pathlib.Path(__file__).parent / f"defaultkeys.txt", k)
|
||||||
keys = get_morekeys_texts()
|
keys = get_morekeys_texts(True)
|
||||||
write_combined_lists(keys)
|
# write_combined_lists(keys)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# need to check strings:
|
# need to check strings:
|
||||||
|
|
Loading…
Add table
Reference in a new issue