From dc99ba52ae1ac0d69e934f369153bc228686c2f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20M=C3=B3=C5=BCd=C5=BCy=C5=84ski?= Date: Thu, 10 Dec 2020 11:11:47 +0100 Subject: [PATCH] [EGD-4590] Change KBD parser to JSON for input keyboard files Changed keyboard input language parser to parse JSON files. Removed all KPROF files and added JSON. Added unit tests for new parser. Modified document about adding languages. --- changelog.md | 4 + doc/i18n.md | 57 +++-- image/assets/lang/Deutsch.json | 4 +- image/assets/lang/English.json | 5 +- image/assets/lang/Espanol.json | 4 +- image/assets/lang/Francais.json | 4 +- image/assets/lang/Polski.json | 4 +- image/assets/profiles/Deutsch_lower.json | 15 ++ image/assets/profiles/Deutsch_upper.json | 15 ++ image/assets/profiles/English_lower.json | 15 ++ image/assets/profiles/English_upper.json | 15 ++ image/assets/profiles/Espanol_lower.json | 15 ++ image/assets/profiles/Espanol_upper.json | 15 ++ image/assets/profiles/Francais_lower.json | 15 ++ image/assets/profiles/Francais_upper.json | 15 ++ image/assets/profiles/Polski_lower.json | 15 ++ image/assets/profiles/Polski_upper.json | 15 ++ image/assets/profiles/lang_de_lower.kprof | 99 ------- image/assets/profiles/lang_de_upper.kprof | 99 ------- image/assets/profiles/lang_eng_lower.kprof | 99 ------- image/assets/profiles/lang_eng_upper.kprof | 99 ------- image/assets/profiles/lang_fr_lower.kprof | 99 ------- image/assets/profiles/lang_fr_upper.kprof | 99 ------- image/assets/profiles/lang_pl_lower.kprof | 99 ------- image/assets/profiles/lang_pl_upper.kprof | 99 ------- image/assets/profiles/lang_sp_lower.kprof | 99 ------- image/assets/profiles/lang_sp_upper.kprof | 99 ------- image/assets/profiles/numeric.json | 21 ++ image/assets/profiles/numeric.kprof | 99 ------- image/assets/profiles/phone.json | 22 ++ image/assets/profiles/phone.kprof | 103 -------- image/assets/profiles/template.kprof | 84 ------ .../windows/PhonebookMainWindow.cpp | 2 +- module-gui/gui/input/Profile.cpp | 241 ++---------------- module-gui/gui/input/Profile.hpp | 40 +-- module-gui/gui/input/Translator.cpp | 49 ++-- module-gui/gui/input/Translator.hpp | 37 ++- module-gui/gui/widgets/Text.cpp | 2 +- module-gui/test/test-catch/CMakeLists.txt | 1 + .../test-catch/test-language-input-parser.cpp | 100 ++++++++ 40 files changed, 430 insertions(+), 1593 deletions(-) create mode 100644 image/assets/profiles/Deutsch_lower.json create mode 100644 image/assets/profiles/Deutsch_upper.json create mode 100644 image/assets/profiles/English_lower.json create mode 100644 image/assets/profiles/English_upper.json create mode 100644 image/assets/profiles/Espanol_lower.json create mode 100644 image/assets/profiles/Espanol_upper.json create mode 100644 image/assets/profiles/Francais_lower.json create mode 100644 image/assets/profiles/Francais_upper.json create mode 100644 image/assets/profiles/Polski_lower.json create mode 100644 image/assets/profiles/Polski_upper.json delete mode 100644 image/assets/profiles/lang_de_lower.kprof delete mode 100644 image/assets/profiles/lang_de_upper.kprof delete mode 100644 image/assets/profiles/lang_eng_lower.kprof delete mode 100644 image/assets/profiles/lang_eng_upper.kprof delete mode 100644 image/assets/profiles/lang_fr_lower.kprof delete mode 100644 image/assets/profiles/lang_fr_upper.kprof delete mode 100644 image/assets/profiles/lang_pl_lower.kprof delete mode 100644 image/assets/profiles/lang_pl_upper.kprof delete mode 100644 image/assets/profiles/lang_sp_lower.kprof delete mode 100644 image/assets/profiles/lang_sp_upper.kprof create mode 100644 image/assets/profiles/numeric.json delete mode 100644 image/assets/profiles/numeric.kprof create mode 100644 image/assets/profiles/phone.json delete mode 100644 image/assets/profiles/phone.kprof delete mode 100644 image/assets/profiles/template.kprof create mode 100644 module-gui/test/test-catch/test-language-input-parser.cpp diff --git a/changelog.md b/changelog.md index 4f39a1e54ee0d6f2e78eddfbc7c0a667d75648df..53903dc10201a9a30be596f4acf2bfb5b5e2713f 100644 --- a/changelog.md +++ b/changelog.md @@ -4,6 +4,10 @@ ### Added * Battery Brownout detection + +### Changed + +* Input keyboard language files parser from KBD to JSON. ## [0.52.1 2020-12-23] ### Added diff --git a/doc/i18n.md b/doc/i18n.md index 4ca1fa43c499fba8a131a07d77eda5c5235923ff..f3473721bc245d7185742acbd0224bda8a693b5b 100644 --- a/doc/i18n.md +++ b/doc/i18n.md @@ -26,35 +26,50 @@ The keys on the left side refer to the values on the right side. These values ar The first four values of JSON language files tell MuditaOS, which keyboard input language is the specific language setting using: ```c++ -"common_kbd_lower": "lang_eng_lower", -"common_kbd_upper": "lang_eng_upper", +"common_kbd_lower": "English_lower", +"common_kbd_upper": "English_upper", "common_kbd_numeric": "numeric", "common_kbd_phone": "phone", (...) ``` -These values are names of KPROF files, which are located in [the image/assets/profiles folder](../image/assets/profiles/). +These values are names of JSON files, which are located in [the image/assets/profiles folder](../image/assets/profiles/). -Every language has its own files for upper and lower letters. Here's an example of a working implementation of buttons 2 and 3 in the `lang_eng_lower` file: +Every language has its own files for upper and lower letters. Here's an example of a working JSON file for `English_lower.json`: ```c++ -(...) -#NumericKey2 = 32, -32 -true -'a','b','c' -0,0,0 -#NumericKey3 = 33, -33 -true -'d','e','f' -0,0,0 -(...) +{ + "filetype": "normal", + "31": ".,_:;)(?!#/*+", + "32": "abc", + "33": "def", + "41": "ghi", + "42": "jkl", + "43": "mno", + "51": "pqrs", + "52": "tuv", + "53": "wxyz", + "61": "0x0A", + "62": " ", + "63": "0x08" +} ``` -Values explanation: -- The first value is the number of the button (31 means button "1", 32 means button "2" etc.) -- The second value is true if the key is cyclic or false otherwise -- The third line is a list of values that would be available by clicking this button -- The last line includes zeros written as many times as there are characters available under the button +The first value declares the type of this file: +- `normal` - they are shown in input language settings, user can change it through GUI (e.g. from English to Polish). +- `special` - they won't show in input language settings, they can be modified only in code (e.g. numeric keyboard). + +Normal-type files will be displayed in settings by their filename (e.g. English_lower will be shown as English). When you add a new input language you should always include files for lower and upper letters for it. + +Next key-value pairs includes code of the key (key) and characters available under this key (value). + +Files naming pattern should be: `_`, eg. correct implementation of Rodian input language should consist of two files: `Rodian_lower.json` and `Rodian_upper.json`. + +We also distinguish two types of button presses: +- `shortpress` - they are used to write letters taken from loaded input language file. +- `longpress` - this type of button press is used, when user keeps button pressed for at least 2 seconds and then releases. In text it is used to write numbers. + +Example: If you are using English keyboard language for lower letters and press `1` button (keycode `31`) and quickly release it, then in SMS textbox `a` letter will appear. But if you hold this button pressed for at least 2 seconds and then release it, `1` number will appear. + +Definition for every key code used in the phone is in [the key_codes.hpp file (KeyCodes enum)](../module-bsp/bsp/keyboard/key_codes.hpp) ### Date and time diff --git a/image/assets/lang/Deutsch.json b/image/assets/lang/Deutsch.json index 0cfa51b3afa3dfbb25bf5ded7d6b212fa3c813df..8a00dbd8c2d800055218db32f02d95d5989ba10f 100644 --- a/image/assets/lang/Deutsch.json +++ b/image/assets/lang/Deutsch.json @@ -1,6 +1,6 @@ { - "common_kbd_lower": "lang_de_lower", - "common_kbd_upper": "lang_de_upper", + "common_kbd_lower": "Deutsch_lower", + "common_kbd_upper": "Deutsch_upper", "common_kbd_numeric": "numeric", "common_add": "ADD", "common_open": "OPEN", diff --git a/image/assets/lang/English.json b/image/assets/lang/English.json index 8e76a76c7e944ddee4dc5da31b7e5a96eda93070..a7b2cfe541e9355541f7e19697c8f40d6dcc44a3 100644 --- a/image/assets/lang/English.json +++ b/image/assets/lang/English.json @@ -1,9 +1,8 @@ { - "common_kbd_lower": "lang_eng_lower", - "common_kbd_upper": "lang_eng_upper", + "common_kbd_lower": "English_lower", + "common_kbd_upper": "English_upper", "common_kbd_numeric": "numeric", "common_kbd_phone": "phone", - "common_add": "ADD", "common_open": "OPEN", "common_call": "CALL", diff --git a/image/assets/lang/Espanol.json b/image/assets/lang/Espanol.json index 3bd847f72b69edbe88e9d866ba926e0e6a9857b9..96263fa684851adace56ff3c8e578e0098d6634f 100644 --- a/image/assets/lang/Espanol.json +++ b/image/assets/lang/Espanol.json @@ -1,6 +1,6 @@ { - "common_kbd_lower": "lang_sp_lower", - "common_kbd_upper": "lang_sp_upper", + "common_kbd_lower": "Espanol_lower", + "common_kbd_upper": "Espanol_upper", "common_kbd_numeric": "numeric", "common_add": "ADD", "common_open": "ABIERTA", diff --git a/image/assets/lang/Francais.json b/image/assets/lang/Francais.json index 9397ec472f3b5dd6ba59618a085b0ccca4c25c35..9a32320baee29322bc77af4038c22292cfcaaad6 100644 --- a/image/assets/lang/Francais.json +++ b/image/assets/lang/Francais.json @@ -1,6 +1,6 @@ { - "common_kbd_lower": "lang_fr_lower", - "common_kbd_upper": "lang_fr_upper", + "common_kbd_lower": "Francais_lower", + "common_kbd_upper": "Francais_upper", "common_kbd_numeric": "numeric", "common_add": "ADD", "common_open": "OPEN", diff --git a/image/assets/lang/Polski.json b/image/assets/lang/Polski.json index 7324b17dd1a5681b0b652ccbfa97eb42ee95479a..1a17d37baa993c143084a1701abb9a6fe8f0aca9 100644 --- a/image/assets/lang/Polski.json +++ b/image/assets/lang/Polski.json @@ -1,6 +1,6 @@ { - "common_kbd_lower": "lang_pl_lower", - "common_kbd_upper": "lang_pl_upper", + "common_kbd_lower": "Polski_lower", + "common_kbd_upper": "Polski_upper", "common_kbd_numeric": "numeric", "common_add": "DODAJ", "common_open": "OTWÓRZ", diff --git a/image/assets/profiles/Deutsch_lower.json b/image/assets/profiles/Deutsch_lower.json new file mode 100644 index 0000000000000000000000000000000000000000..2dd9ed876b6e5024006f96108787d04d4cca477a --- /dev/null +++ b/image/assets/profiles/Deutsch_lower.json @@ -0,0 +1,15 @@ +{ + "filetype": "normal", + "31": ".,_:;)(?!#/*+", + "32": "abcä", + "33": "def", + "41": "ghi", + "42": "jkl", + "43": "mnoö", + "51": "pqrsß", + "52": "tuvü", + "53": "wxyz", + "61": "0x0A", + "62": " ", + "63": "0x08" +} diff --git a/image/assets/profiles/Deutsch_upper.json b/image/assets/profiles/Deutsch_upper.json new file mode 100644 index 0000000000000000000000000000000000000000..ce655ed724ddcec5af56e4854f4d4a0d88230790 --- /dev/null +++ b/image/assets/profiles/Deutsch_upper.json @@ -0,0 +1,15 @@ +{ + "filetype": "normal", + "31": ".,_:;)(?!#/*+", + "32": "ABCÄ", + "33": "DEF", + "41": "GHI", + "42": "JKL", + "43": "MNOÖ", + "51": "PQRSß", + "52": "TUVÜ", + "53": "WXYZ", + "61": "0x0A", + "62": " ", + "63": "0x08" +} diff --git a/image/assets/profiles/English_lower.json b/image/assets/profiles/English_lower.json new file mode 100644 index 0000000000000000000000000000000000000000..7f60c07cb41ca1aa67ff64b68586bce4ed635a9e --- /dev/null +++ b/image/assets/profiles/English_lower.json @@ -0,0 +1,15 @@ +{ + "filetype": "normal", + "31": ".,_:;)(?!#/*+", + "32": "abc", + "33": "def", + "41": "ghi", + "42": "jkl", + "43": "mno", + "51": "pqrs", + "52": "tuv", + "53": "wxyz", + "61": "0x0A", + "62": " ", + "63": "0x08" +} diff --git a/image/assets/profiles/English_upper.json b/image/assets/profiles/English_upper.json new file mode 100644 index 0000000000000000000000000000000000000000..6094c0eb98c6d046e4a2f4f9f9f61f0c99df097d --- /dev/null +++ b/image/assets/profiles/English_upper.json @@ -0,0 +1,15 @@ +{ + "filetype": "normal", + "31": ".,_:;)(?!#/*+", + "32": "ABC", + "33": "DEF", + "41": "GHI", + "42": "JKL", + "43": "MNO", + "51": "PQRS", + "52": "TUV", + "53": "WXYZ", + "61": "0x0A", + "62": " ", + "63": "0x08" +} diff --git a/image/assets/profiles/Espanol_lower.json b/image/assets/profiles/Espanol_lower.json new file mode 100644 index 0000000000000000000000000000000000000000..fdbcc56908071cc049e2f8e01d7dcb46583984e0 --- /dev/null +++ b/image/assets/profiles/Espanol_lower.json @@ -0,0 +1,15 @@ +{ + "filetype": "normal", + "31": ".,_:;)(?!#/*+", + "32": "abcá", + "33": "defé", + "41": "ghií", + "42": "jkl", + "43": "mnoóñ", + "51": "pqrs", + "52": "tuvúü", + "53": "wxyz", + "61": "0x0A", + "62": " ", + "63": "0x08" +} diff --git a/image/assets/profiles/Espanol_upper.json b/image/assets/profiles/Espanol_upper.json new file mode 100644 index 0000000000000000000000000000000000000000..4388022dd345b588ff4061c7f4c83bae929f3f70 --- /dev/null +++ b/image/assets/profiles/Espanol_upper.json @@ -0,0 +1,15 @@ +{ + "filetype": "normal", + "31": ".,_:;)(?!#/*+", + "32": "ABCÁ", + "33": "DEFÉ", + "41": "GHIÍ", + "42": "JKL", + "43": "MNOÓÑ", + "51": "PQRS", + "52": "TUVÚÜ", + "53": "WXYZ", + "61": "0x0A", + "62": " ", + "63": "0x08" +} diff --git a/image/assets/profiles/Francais_lower.json b/image/assets/profiles/Francais_lower.json new file mode 100644 index 0000000000000000000000000000000000000000..51e17b530d1daf6e009a637661b183aea576e095 --- /dev/null +++ b/image/assets/profiles/Francais_lower.json @@ -0,0 +1,15 @@ +{ + "filetype": "normal", + "31": ".,_:;)(?!#/*+", + "32": "abcàâç", + "33": "deféèêë", + "41": "ghiîï", + "42": "jkl", + "43": "mnoô", + "51": "pqrs", + "52": "tuvûùü", + "53": "wxyzÿ", + "61": "0x0A", + "62": " ", + "63": "0x08" +} diff --git a/image/assets/profiles/Francais_upper.json b/image/assets/profiles/Francais_upper.json new file mode 100644 index 0000000000000000000000000000000000000000..3492f0b793b00f0722238b74ad96dd30167467d0 --- /dev/null +++ b/image/assets/profiles/Francais_upper.json @@ -0,0 +1,15 @@ +{ + "filetype": "normal", + "31": ".,_:;)(?!#/*+", + "32": "ABCÀÂÇ", + "33": "DEFÉÈÊË", + "41": "GHIÎÏ", + "42": "JKL", + "43": "MNOÔ", + "51": "PQRS", + "52": "TUVÛÙÜ", + "53": "WXYZŸ", + "61": "0x0A", + "62": " ", + "63": "0x08" +} diff --git a/image/assets/profiles/Polski_lower.json b/image/assets/profiles/Polski_lower.json new file mode 100644 index 0000000000000000000000000000000000000000..f207dfadc9bccd29c0f224fb7bc1787346397512 --- /dev/null +++ b/image/assets/profiles/Polski_lower.json @@ -0,0 +1,15 @@ +{ + "filetype": "normal", + "31": ".,_:;)(?!#/*+", + "32": "abcąć", + "33": "defę", + "41": "ghi", + "42": "jklł", + "43": "mnońó", + "51": "pqrsś", + "52": "tuv", + "53": "wxyzźż", + "61": "0x0A", + "62": " ", + "63": "0x08" +} diff --git a/image/assets/profiles/Polski_upper.json b/image/assets/profiles/Polski_upper.json new file mode 100644 index 0000000000000000000000000000000000000000..f94ad7568bf4f382bac8d9e6e8ac5c79a752f4f6 --- /dev/null +++ b/image/assets/profiles/Polski_upper.json @@ -0,0 +1,15 @@ +{ + "filetype": "normal", + "31": ".,_:;)(?!#/*+", + "32": "ABCĄĆ", + "33": "DEFĘ", + "41": "GHI", + "42": "JKLŁ", + "43": "MNOŃÓ", + "51": "PQRSŚ", + "52": "TUV", + "53": "WXYZŹŻ", + "61": "0x0A", + "62": " ", + "63": "0x08" +} diff --git a/image/assets/profiles/lang_de_lower.kprof b/image/assets/profiles/lang_de_lower.kprof deleted file mode 100644 index f622446d4c2ff13b8093e55d3fdd30d85092994c..0000000000000000000000000000000000000000 --- a/image/assets/profiles/lang_de_lower.kprof +++ /dev/null @@ -1,99 +0,0 @@ -#name of the profile -lang_de_lower -#NumericKey1 = 31, -31 -true -'.',',','_',':',';',')','(','?','!','#','/','*','+' -0,0,0,0,0,0,0,0,0,0,0,0,0 -#NumericKey2 = 32, -32 -true -'a','b','c','ä' -0,0,0,0 -#NumericKey3 = 33, -33 -true -'d','e','f' -0,0,0 -#NumericKey4 = 41, -41 -true -'g','h','i' -0,0,0 -#NumericKey5 = 42, -42 -true -'j','k','l' -0,0,0 -#NumericKey6 = 43, -43 -true -'m','n','o','ö' -0,0,0,0 -#NumericKey7 = 51, -51 -true -'p','q','r','s','ß' -0,0,0,0,0 -#NumericKey8 = 52, -52 -true -'t','u','v','ü' -0,0,0,0 -#NumericKey9 = 53, -53 -true -'w','x','y','z' -0,0,0,0 -#NumericKey0 = 62, -62 -false -' ' -0 -#NumericKeyAst = 61, -61 -false -0x08 -0 -#NumericKeyPnd = 63, -63 -false -0x0A -0 -#JoystickLeft = 11, -11 -false -'' -0 -#JoystickRight = 13, -13 -false -'' -0 -#JoystickUp = 2, -2 -false -'' -0 -#JoystickDown = 22, -22 -false -'' -0 -#JoystickEnter = 12, -12 -false -'' -0 -#FnLeft = 21,//1, -#FnRight = 23,//3, -23 -false -'' -2000 -#VolUp = 4, -#VolDown = 14, -#Torch = 24, -#SSwitchUp = 34, -#SSwitchDown = 54, -#SSwitchMid = 44 diff --git a/image/assets/profiles/lang_de_upper.kprof b/image/assets/profiles/lang_de_upper.kprof deleted file mode 100644 index c974546a1159bc0d01f9cb4eb103f52d08df0b64..0000000000000000000000000000000000000000 --- a/image/assets/profiles/lang_de_upper.kprof +++ /dev/null @@ -1,99 +0,0 @@ -#name of the profile -lang_de_upper -#NumericKey1 = 31, -31 -true -'.',',','_',':',';',')','(','?','!','#','/','*','+' -0,0,0,0,0,0,0,0,0,0,0,0,0 -#NumericKey2 = 32, -32 -true -'A','B','C','Ä' -0,0,0,0 -#NumericKey3 = 33, -33 -true -'D','E','F' -0,0,0 -#NumericKey4 = 41, -41 -true -'G','H','I' -0,0,0 -#NumericKey5 = 42, -42 -true -'J','K','L' -0,0,0 -#NumericKey6 = 43, -43 -true -'M','N','O','Ö' -0,0,0,0 -#NumericKey7 = 51, -51 -true -'P','Q','R','S','ß' -0,0,0,0,0 -#NumericKey8 = 52, -52 -true -'T','U','V','Ü' -0,0,0,0 -#NumericKey9 = 53, -53 -true -'W','X','Y','Z' -0,0,0,0 -#NumericKey0 = 62, -62 -false -' ' -0 -#NumericKeyAst = 61, -61 -false -0x08 -0 -#NumericKeyPnd = 63, -63 -false -0x0A -0 -#JoystickLeft = 11, -11 -false -'' -0 -#JoystickRight = 13, -13 -false -'' -0 -#JoystickUp = 2, -2 -false -'' -0 -#JoystickDown = 22, -22 -false -'' -0 -#JoystickEnter = 12, -12 -false -'' -0 -#FnLeft = 21,//1, -#FnRight = 23,//3, -23 -false -'' -2000 -#VolUp = 4, -#VolDown = 14, -#Torch = 24, -#SSwitchUp = 34, -#SSwitchDown = 54, -#SSwitchMid = 44 diff --git a/image/assets/profiles/lang_eng_lower.kprof b/image/assets/profiles/lang_eng_lower.kprof deleted file mode 100644 index f187f0a0aa1b9dc8db53fb6aba009f5b55042ccf..0000000000000000000000000000000000000000 --- a/image/assets/profiles/lang_eng_lower.kprof +++ /dev/null @@ -1,99 +0,0 @@ -#name of the profile -lang_eng_lower -#NumericKey1 = 31, -31 -true -'.',',','_',':',';',')','(','?','!','#','/','*','+' -0,0,0,0,0,0,0,0,0,0,0,0,0 -#NumericKey2 = 32, -32 -true -'a','b','c' -0,0,0 -#NumericKey3 = 33, -33 -true -'d','e','f' -0,0,0 -#NumericKey4 = 41, -41 -true -'g','h','i' -0,0,0 -#NumericKey5 = 42, -42 -true -'j','k','l' -0,0,0 -#NumericKey6 = 43, -43 -true -'m','n','o' -0,0,0 -#NumericKey7 = 51, -51 -true -'p','q','r','s' -0,0,0,0 -#NumericKey8 = 52, -52 -true -'t','u','v' -0,0,0 -#NumericKey9 = 53, -53 -true -'w','x','y','z' -0,0,0,0 -#NumericKey0 = 62, -62 -false -' ' -0 -#NumericKeyAst = 61, -61 -false -0x0A -0 -#NumericKeyPnd = 63, -63 -false -0x08 -0 -#JoystickLeft = 11, -11 -false -'' -0 -#JoystickRight = 13, -13 -false -'' -0 -#JoystickUp = 2, -2 -false -'' -0 -#JoystickDown = 22, -22 -false -'' -0 -#JoystickEnter = 12, -12 -false -'' -0 -#FnLeft = 21,//1, -#FnRight = 23,//3, -23 -false -'' -2000 -#VolUp = 4, -#VolDown = 14, -#Torch = 24, -#SSwitchUp = 34, -#SSwitchDown = 54, -#SSwitchMid = 44 diff --git a/image/assets/profiles/lang_eng_upper.kprof b/image/assets/profiles/lang_eng_upper.kprof deleted file mode 100644 index 8fa896d82649684c50829ad79222d23554ab72c8..0000000000000000000000000000000000000000 --- a/image/assets/profiles/lang_eng_upper.kprof +++ /dev/null @@ -1,99 +0,0 @@ -#name of the profile -lang_eng_upper -#NumericKey1 = 31, -31 -true -'.',',','_',':',';',')','(','?','!','#','/','*','+' -0,0,0,0,0,0,0,0,0,0,0,0,0 -#NumericKey2 = 32, -32 -true -'A','B','C' -0,0,0 -#NumericKey3 = 33, -33 -true -'D','E','F' -0,0,0 -#NumericKey4 = 41, -41 -true -'G','H','I' -0,0,0 -#NumericKey5 = 42, -42 -true -'J','K','L' -0,0,0 -#NumericKey6 = 43, -43 -true -'M','N','O' -0,0,0 -#NumericKey7 = 51, -51 -true -'P','Q','R','S' -0,0,0,0 -#NumericKey8 = 52, -52 -true -'T','U','V' -0,0,0 -#NumericKey9 = 53, -53 -true -'W','X','Y','Z' -0,0,0,0 -#NumericKey0 = 62, -62 -false -' ' -0 -#NumericKeyAst = 61, -61 -false -0x0A -0 -#NumericKeyPnd = 63, -63 -false -0x08 -0 -#JoystickLeft = 11, -11 -false -'' -0 -#JoystickRight = 13, -13 -false -'' -0 -#JoystickUp = 2, -2 -false -'' -0 -#JoystickDown = 22, -22 -false -'' -0 -#JoystickEnter = 12, -12 -false -'' -0 -#FnLeft = 21,//1, -#FnRight = 23,//3, -23 -false -'' -2000 -#VolUp = 4, -#VolDown = 14, -#Torch = 24, -#SSwitchUp = 34, -#SSwitchDown = 54, -#SSwitchMid = 44 diff --git a/image/assets/profiles/lang_fr_lower.kprof b/image/assets/profiles/lang_fr_lower.kprof deleted file mode 100644 index 5e9cefbb3964f4c0fa84d2117757fd80e4768559..0000000000000000000000000000000000000000 --- a/image/assets/profiles/lang_fr_lower.kprof +++ /dev/null @@ -1,99 +0,0 @@ -#name of the profile -lang_fr_lower -#NumericKey1 = 31, -31 -true -'.',',','_',':',';',')','(','?','!','#','/','*','+' -0,0,0,0,0,0,0,0,0,0,0,0,0 -#NumericKey2 = 32, -32 -true -'a','b','c','à','â','ç' -0,0,0,0,0,0 -#NumericKey3 = 33, -33 -true -'d','e','f','é','è','ê','ë' -0,0,0,0,0,0,0 -#NumericKey4 = 41, -41 -true -'g','h','i','î','ï' -0,0,0,0,0 -#NumericKey5 = 42, -42 -true -'j','k','l' -0,0,0 -#NumericKey6 = 43, -43 -true -'m','n','o','ô' -0,0,0,0 -#NumericKey7 = 51, -51 -true -'p','q','r','s' -0,0,0,0 -#NumericKey8 = 52, -52 -true -'t','u','v','û','ù','ü' -0,0,0,0,0,0 -#NumericKey9 = 53, -53 -true -'w','x','y','z','ÿ' -0,0,0,0,0 -#NumericKey0 = 62, -62 -false -' ' -0 -#NumericKeyAst = 61, -61 -false -0x0A -0 -#NumericKeyPnd = 63, -63 -false -0x08 -0 -#JoystickLeft = 11, -11 -false -'' -0 -#JoystickRight = 13, -13 -false -'' -0 -#JoystickUp = 2, -2 -false -'' -0 -#JoystickDown = 22, -22 -false -'' -0 -#JoystickEnter = 12, -12 -false -'' -0 -#FnLeft = 21,//1, -#FnRight = 23,//3, -23 -false -'' -2000 -#VolUp = 4, -#VolDown = 14, -#Torch = 24, -#SSwitchUp = 34, -#SSwitchDown = 54, -#SSwitchMid = 44 diff --git a/image/assets/profiles/lang_fr_upper.kprof b/image/assets/profiles/lang_fr_upper.kprof deleted file mode 100644 index 810d6ce2b1279ff06ee8e8afdb67205de8a2cf6d..0000000000000000000000000000000000000000 --- a/image/assets/profiles/lang_fr_upper.kprof +++ /dev/null @@ -1,99 +0,0 @@ -#name of the profile -lang_fr_upper -#NumericKey1 = 31, -31 -true -'.',',','_',':',';',')','(','?','!','#','/','*','+' -0,0,0,0,0,0,0,0,0,0,0,0,0 -#NumericKey2 = 32, -32 -true -'A','B','C','À','Â','Ç' -0,0,0,0,0,0 -#NumericKey3 = 33, -33 -true -'D','E','F','É','È','Ê','Ë' -0,0,0,0,0,0,0 -#NumericKey4 = 41, -41 -true -'G','H','I','Î','Ï' -0,0,0,0,0 -#NumericKey5 = 42, -42 -true -'J','K','L' -0,0,0 -#NumericKey6 = 43, -43 -true -'M','N','O','Ô' -0,0,0,0 -#NumericKey7 = 51, -51 -true -'P','Q','R','S' -0,0,0,0 -#NumericKey8 = 52, -52 -true -'T','U','V','Û','Ù','Ü' -0,0,0,0,0,0 -#NumericKey9 = 53, -53 -true -'W','X','Y','Z','Ÿ' -0,0,0,0,0 -#NumericKey0 = 62, -62 -false -' ' -0 -#NumericKeyAst = 61, -61 -false -0x0A -0 -#NumericKeyPnd = 63, -63 -false -0x08 -0 -#JoystickLeft = 11, -11 -false -'' -0 -#JoystickRight = 13, -13 -false -'' -0 -#JoystickUp = 2, -2 -false -'' -0 -#JoystickDown = 22, -22 -false -'' -0 -#JoystickEnter = 12, -12 -false -'' -0 -#FnLeft = 21,//1, -#FnRight = 23,//3, -23 -false -'' -2000 -#VolUp = 4, -#VolDown = 14, -#Torch = 24, -#SSwitchUp = 34, -#SSwitchDown = 54, -#SSwitchMid = 44 diff --git a/image/assets/profiles/lang_pl_lower.kprof b/image/assets/profiles/lang_pl_lower.kprof deleted file mode 100644 index 6516e1864b7bf6baccd76e1aec1b591eadcfc575..0000000000000000000000000000000000000000 --- a/image/assets/profiles/lang_pl_lower.kprof +++ /dev/null @@ -1,99 +0,0 @@ -#name of the profile -lang_pl_lower -#NumericKey1 = 31, -31 -true -'.',',','_',':',';',')','(','?','!','#','/','*','+' -0,0,0,0,0,0,0,0,0,0,0,0,0 -#NumericKey2 = 32, -32 -true -'a','b','c','ą','ć' -0,0,0,0,0 -#NumericKey3 = 33, -33 -true -'d','e','f','ę' -0,0,0,0 -#NumericKey4 = 41, -41 -true -'g','h','i' -0,0,0 -#NumericKey5 = 42, -42 -true -'j','k','l','ł' -0,0,0,0 -#NumericKey6 = 43, -43 -true -'m','n','o','ń','ó' -0,0,0,0,0 -#NumericKey7 = 51, -51 -true -'p','q','r','s','ś' -0,0,0,0,0 -#NumericKey8 = 52, -52 -true -'t','u','v' -0,0,0 -#NumericKey9 = 53, -53 -true -'w','x','y','z','ź','ż' -0,0,0,0,0,0 -#NumericKey0 = 62, -62 -false -' ' -0 -#NumericKeyAst = 61, -61 -false -0x08 -0 -#NumericKeyPnd = 63, -63 -false -0x0A -0 -#JoystickLeft = 11, -11 -false -'' -0 -#JoystickRight = 13, -13 -false -'' -0 -#JoystickUp = 2, -2 -false -'' -0 -#JoystickDown = 22, -22 -false -'' -0 -#JoystickEnter = 12, -12 -false -'' -0 -#FnLeft = 21,//1, -#FnRight = 23,//3, -23 -false -'' -2000 -#VolUp = 4, -#VolDown = 14, -#Torch = 24, -#SSwitchUp = 34, -#SSwitchDown = 54, -#SSwitchMid = 44 diff --git a/image/assets/profiles/lang_pl_upper.kprof b/image/assets/profiles/lang_pl_upper.kprof deleted file mode 100644 index 06286fbad164a81da2d94bc9cad31f5e10ab1a2c..0000000000000000000000000000000000000000 --- a/image/assets/profiles/lang_pl_upper.kprof +++ /dev/null @@ -1,99 +0,0 @@ -#name of the profile -lang_pl_upper -#NumericKey1 = 31, -31 -true -'.',',','_',':',';',')','(','?','!','#','/','*','+' -0,0,0,0,0,0,0,0,0,0,0,0,0 -#NumericKey2 = 32, -32 -true -'A','B','C','Ą','Ć' -0,0,0,0,0 -#NumericKey3 = 33, -33 -true -'D','E','F','Ę' -0,0,0,0 -#NumericKey4 = 41, -41 -true -'G','H','I' -0,0,0 -#NumericKey5 = 42, -42 -true -'J','K','L','Ł' -0,0,0,0 -#NumericKey6 = 43, -43 -true -'M','N','O','Ń','Ó' -0,0,0,0,0 -#NumericKey7 = 51, -51 -true -'P','Q','R','S','Ś' -0,0,0,0,0 -#NumericKey8 = 52, -52 -true -'T','U','V' -0,0,0 -#NumericKey9 = 53, -53 -true -'W','X','Y','Z','Ź','Ż' -0,0,0,0,0,0 -#NumericKey0 = 62, -62 -false -' ' -0 -#NumericKeyAst = 61, -61 -false -0x08 -0 -#NumericKeyPnd = 63, -63 -false -0x0A -0 -#JoystickLeft = 11, -11 -false -'' -0 -#JoystickRight = 13, -13 -false -'' -0 -#JoystickUp = 2, -2 -false -'' -0 -#JoystickDown = 22, -22 -false -'' -0 -#JoystickEnter = 12, -12 -false -'' -0 -#FnLeft = 21,//1, -#FnRight = 23,//3, -23 -false -'' -2000 -#VolUp = 4, -#VolDown = 14, -#Torch = 24, -#SSwitchUp = 34, -#SSwitchDown = 54, -#SSwitchMid = 44 diff --git a/image/assets/profiles/lang_sp_lower.kprof b/image/assets/profiles/lang_sp_lower.kprof deleted file mode 100644 index 206f1dffaca859879d943fdecdf3a8a1dc6dabb6..0000000000000000000000000000000000000000 --- a/image/assets/profiles/lang_sp_lower.kprof +++ /dev/null @@ -1,99 +0,0 @@ -#name of the profile -lang_sp_lower -#NumericKey1 = 31, -31 -true -'.',',','_',':',';',')','(','?','!','#','/','*','+' -0,0,0,0,0,0,0,0,0,0,0,0,0 -#NumericKey2 = 32, -32 -true -'a','b','c','á' -0,0,0,0 -#NumericKey3 = 33, -33 -true -'d','e','f','é' -0,0,0,0 -#NumericKey4 = 41, -41 -true -'g','h','i','í' -0,0,0,0 -#NumericKey5 = 42, -42 -true -'j','k','l' -0,0,0 -#NumericKey6 = 43, -43 -true -'m','n','o','ó','ñ' -0,0,0,0,0 -#NumericKey7 = 51, -51 -true -'p','q','r','s' -0,0,0,0 -#NumericKey8 = 52, -52 -true -'t','u','v','ú','ü' -0,0,0,0,0 -#NumericKey9 = 53, -53 -true -'w','x','y','z' -0,0,0,0 -#NumericKey0 = 62, -62 -false -' ' -0 -#NumericKeyAst = 61, -61 -false -0x08 -0 -#NumericKeyPnd = 63, -63 -false -0x0A -0 -#JoystickLeft = 11, -11 -false -'' -0 -#JoystickRight = 13, -13 -false -'' -0 -#JoystickUp = 2, -2 -false -'' -0 -#JoystickDown = 22, -22 -false -'' -0 -#JoystickEnter = 12, -12 -false -'' -0 -#FnLeft = 21,//1, -#FnRight = 23,//3, -23 -false -'' -2000 -#VolUp = 4, -#VolDown = 14, -#Torch = 24, -#SSwitchUp = 34, -#SSwitchDown = 54, -#SSwitchMid = 44 diff --git a/image/assets/profiles/lang_sp_upper.kprof b/image/assets/profiles/lang_sp_upper.kprof deleted file mode 100644 index 1f8b88ae051cb6f160ed863259d8937d4cd66c89..0000000000000000000000000000000000000000 --- a/image/assets/profiles/lang_sp_upper.kprof +++ /dev/null @@ -1,99 +0,0 @@ -#name of the profile -lang_sp_upper -#NumericKey1 = 31, -31 -true -'.',',','_',':',';',')','(','?','!','#','/','*','+' -0,0,0,0,0,0,0,0,0,0,0,0,0 -#NumericKey2 = 32, -32 -true -'A','B','C','Á' -0,0,0,0 -#NumericKey3 = 33, -33 -true -'D','E','F','É' -0,0,0,0 -#NumericKey4 = 41, -41 -true -'G','H','I','Í' -0,0,0,0 -#NumericKey5 = 42, -42 -true -'J','K','L' -0,0,0 -#NumericKey6 = 43, -43 -true -'M','N','O','Ó','Ñ' -0,0,0,0,0 -#NumericKey7 = 51, -51 -true -'P','Q','R','S' -0,0,0,0 -#NumericKey8 = 52, -52 -true -'T','U','V','Ú','Ü' -0,0,0,0,0 -#NumericKey9 = 53, -53 -true -'W','X','Y','Z' -0,0,0,0 -#NumericKey0 = 62, -62 -false -' ' -0 -#NumericKeyAst = 61, -61 -false -0x08 -0 -#NumericKeyPnd = 63, -63 -false -0x0A -0 -#JoystickLeft = 11, -11 -false -'' -0 -#JoystickRight = 13, -13 -false -'' -0 -#JoystickUp = 2, -2 -false -'' -0 -#JoystickDown = 22, -22 -false -'' -0 -#JoystickEnter = 12, -12 -false -'' -0 -#FnLeft = 21,//1, -#FnRight = 23,//3, -23 -false -'' -2000 -#VolUp = 4, -#VolDown = 14, -#Torch = 24, -#SSwitchUp = 34, -#SSwitchDown = 54, -#SSwitchMid = 44 diff --git a/image/assets/profiles/numeric.json b/image/assets/profiles/numeric.json new file mode 100644 index 0000000000000000000000000000000000000000..54bc1c114d9204d0d6c71288a9253cacfd6233ee --- /dev/null +++ b/image/assets/profiles/numeric.json @@ -0,0 +1,21 @@ +{ + "filetype": "special", + "31": "1", + "32": "2", + "33": "3", + "41": "4", + "42": "5", + "43": "6", + "51": "7", + "52": "8", + "53": "9", + "61": "0x08", + "62": "0", + "63": "*#", + "11": "", + "13": "", + "2": "", + "22": "", + "12": "", + "23": "" +} diff --git a/image/assets/profiles/numeric.kprof b/image/assets/profiles/numeric.kprof deleted file mode 100644 index e740e0f7601e61a5376cfb4155a2bb9f9943b7c7..0000000000000000000000000000000000000000 --- a/image/assets/profiles/numeric.kprof +++ /dev/null @@ -1,99 +0,0 @@ -#name of the profile -numeric -#NumericKey1 = 31, -31 -false -'1' -0 -#NumericKey2 = 32, -32 -false -'2' -0 -#NumericKey3 = 33, -33 -false -'3' -0 -#NumericKey4 = 41, -41 -false -'4' -0 -#NumericKey5 = 42, -42 -false -'5' -0 -#NumericKey6 = 43, -43 -false -'6' -0 -#NumericKey7 = 51, -51 -false -'7' -0 -#NumericKey8 = 52, -52 -false -'8' -0 -#NumericKey9 = 53, -53 -false -'9' -0 -#NumericKey0 = 62, -62 -false -'0' -0 -#NumericKeyAst = 61, -61 -false -0x08 -0 -#NumericKeyPnd = 63, -63 -false -'*','#' -0,0 -#JoystickLeft = 11, -11 -false -'' -0 -#JoystickRight = 13, -13 -false -'' -0 -#JoystickUp = 2, -2 -false -'' -0 -#JoystickDown = 22, -22 -false -'' -0 -#JoystickEnter = 12, -12 -false -'' -0 -#FnLeft = 21,//1, -#FnRight = 23,//3, -23 -false -'' -3000 -#VolUp = 4, -#VolDown = 14, -#Torch = 24, -#SSwitchUp = 34, -#SSwitchDown = 54, -#SSwitchMid = 44 diff --git a/image/assets/profiles/phone.json b/image/assets/profiles/phone.json new file mode 100644 index 0000000000000000000000000000000000000000..bd860db9fe34ececadb86d2ccbe8a08ea6992237 --- /dev/null +++ b/image/assets/profiles/phone.json @@ -0,0 +1,22 @@ +{ + "filetype": "special", + "31": "1", + "32": "2", + "33": "3", + "41": "4", + "42": "5", + "43": "6", + "51": "7", + "52": "8", + "53": "9", + "61": "*", + "62": "0", + "63": "#", + "11": "", + "13": "", + "2": "", + "22": "", + "12": "", + "23": "" +} + diff --git a/image/assets/profiles/phone.kprof b/image/assets/profiles/phone.kprof deleted file mode 100644 index 8c6342b4fd0d31f70aecf04bc074bf22a1fffd05..0000000000000000000000000000000000000000 --- a/image/assets/profiles/phone.kprof +++ /dev/null @@ -1,103 +0,0 @@ -#name of the profile -phone -#NumericKey1 = 31, -31 -false -'1' -0 -#NumericKey2 = 32, -32 -false -'2' -0 -#NumericKey3 = 33, -33 -false -'3' -0 -#NumericKey4 = 41, -41 -false -'4' -0 -#NumericKey5 = 42, -42 -false -'5' -0 -#NumericKey6 = 43, -43 -false -'6' -0 -#NumericKey7 = 51, -51 -false -'7' -0 -#NumericKey8 = 52, -52 -false -'8' -0 -#NumericKey9 = 53, -53 -false -'9' -0 -#NumericKey0 = 62, -62 -false -'0' -0 -#NumericKeyAst = 61, -61 -false -'*' -0 -#NumericKeyPnd = 63, -63 -false -'#' -3000 -#JoystickLeft = 11, -11 -false -'' -0 -#JoystickRight = 13, -13 -false -'' -0 -#JoystickUp = 2, -2 -false -'' -0 -#JoystickDown = 22, -22 -false -'' -0 -#JoystickEnter = 12, -12 -false -'' -0 -#FnLeft = 21,//1, -21 -false -'' -0 -#FnRight = 23,//3, -23 -false -'' -3000 -#VolUp = 4, -#VolDown = 14, -#Torch = 24, -#SSwitchUp = 34, -#SSwitchDown = 54, -#SSwitchMid = 44 \ No newline at end of file diff --git a/image/assets/profiles/template.kprof b/image/assets/profiles/template.kprof deleted file mode 100644 index 4c90964ecbc35e6e060831f22d917cd2940a8d8d..0000000000000000000000000000000000000000 --- a/image/assets/profiles/template.kprof +++ /dev/null @@ -1,84 +0,0 @@ -#name of the profile -example_profile -#for each key following 4 variables must be defined -#key code, in example 31 -#true if key is cyclic or false otherwise -#characters assigned to the key -#timeouts for each of the characters. 0 means that there is no timeout -#NumericKey1 = 31, -31 -false -'' -0 -#NumericKey2 = 32, -32 -true -'a','b','c' -0,0,0 -#NumericKey3 = 33, -33 -true -'d','e','f' -0,0,0 -#NumericKey4 = 41, -41 -true -'g','h','i' -0,0,0 -#NumericKey5 = 42, -42 -true -'j','k','l' -0,0,0 -#NumericKey6 = 43, -43 -true -'m','n','o' -0,0,0 -#NumericKey7 = 51, -51 -true -'p','q','r','s' -0,0,0,0 -#NumericKey8 = 52, -52 -true -'t','u','v' -0,0,0 -#NumericKey9 = 53, -53 -true -'w','x','y','z' -0,0,0,0 -#NumericKey0 = 62, -62 -false -' ' -0 -#NumericKeyAst = 61, -61 -false -0x08 -0 -#NumericKeyPnd = 63, -63 -false -0x0A -0 -#JoystickLeft = 11, -#JoystickRight = 13, -#JoystickUp = 2, -#JoystickDown = 22, -#JoystickEnter = 12, -#FnLeft = 21, -#FnRight = 23 -23 -false -'' -2000 -#VolUp = 4, -#VolDown = 14, -#Torch = 24, -#SSwitchUp = 34, -#SSwitchDown = 54, -#SSwitchMid = 44 \ No newline at end of file diff --git a/module-apps/application-phonebook/windows/PhonebookMainWindow.cpp b/module-apps/application-phonebook/windows/PhonebookMainWindow.cpp index d864896be28e7fb0822762968f886230415a05a1..c63b22684a7c29bcc36b6a6069cfa5df1679d5ff 100644 --- a/module-apps/application-phonebook/windows/PhonebookMainWindow.cpp +++ b/module-apps/application-phonebook/windows/PhonebookMainWindow.cpp @@ -119,7 +119,7 @@ namespace gui void PhonebookMainWindow::HandleFilteringByLetter(const InputEvent &inputEvent) { auto code = translator.handle(inputEvent.key, inputMode ? inputMode->get() : ""); - if (code != KeyProfile::none_key) { + if (code != Profile::none_key) { LOG_INFO("char=' %c'", static_cast(code)); char letter = static_cast(code); std::string filterLetter; diff --git a/module-gui/gui/input/Profile.cpp b/module-gui/gui/input/Profile.cpp index 59610003abcb076e73e60c040e5fa2617e76246c..72cc71e62254be8c2243113a3f111d7b2f3777f1 100644 --- a/module-gui/gui/input/Profile.cpp +++ b/module-gui/gui/input/Profile.cpp @@ -1,249 +1,60 @@ // Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md -#include -#include -#include -#include #include "log/log.hpp" #include "utf8/UTF8.hpp" #include "Profile.hpp" #include +#include namespace gui { - const uint32_t KeyProfile::none_key = 0; + Profile::Profile(const std::string &filepath) : name(filepath), inputChars(createJson(filepath)) + {} - Profile::Profile(const std::string &name) - { - LOG_INFO("Create!"); - load(name); - } - - Profile::Profile(Profile &&p) - { - this->name = p.name; - this->keys = p.keys; - // this is important, we need to assure that moved Profile doesn't clean up our memory again - p.clear(); - } - - Profile::~Profile() - { - for (auto it = keys.begin(); it != keys.end(); it++) { - delete it->second; - } - keys.clear(); - } - - static inline std::string trim(const std::string &s) - { - auto wsfront = std::find_if_not(s.begin(), s.end(), [](int c) { return std::isspace(c); }); - return std::string(wsfront, - std::find_if_not(s.rbegin(), std::string::const_reverse_iterator(wsfront), [](int c) { - return std::isspace(c); - }).base()); - } - - template void split(const std::string &s, char delim, Out result) - { - std::stringstream ss(s); - std::string item; - while (std::getline(ss, item, delim)) { - *(result++) = item; - } - } - - static std::vector split(const std::string &s, char delim) - { - std::vector elems; - split(s, delim, std::back_inserter(elems)); - return elems; - } - - void Profile::clear() - { - keys.clear(); - } - - std::string Profile::getName() const noexcept + const std::string &Profile::getName() noexcept { return name; } - bool Profile::load(const std::string &filename) + const json11::Json Profile::createJson(const std::string &filepath) { - auto file = std::fopen(filename.c_str(), "rb"); + auto fd = std::fopen(filepath.c_str(), "r"); - if (file == nullptr) { - LOG_FATAL("no KeyProfile file: %s", filename.c_str()); - return false; + if (fd == nullptr) { + LOG_FATAL("Error during opening file %s", filepath.c_str()); + return json11::Json(); } - enum class LineType - { - KEY_CODE = 0, - CYCLIC, - CHARACTERS, - TIMEOUTS - }; + uint32_t fsize = utils::filesystem::filelength(fd); - LineType lineType = LineType::KEY_CODE; - bool name = false; + auto stream = std::make_unique(fsize + 1); - KeyProfile *pk = nullptr; - KeyProfile tmp; - while (std::feof(file) != true) { - const auto line = trim(utils::filesystem::getline(file)); - if ((line[0] == '#') || (line.empty())) { - continue; - } - else { + memset(stream.get(), 0, fsize + 1); - // first not commented line is a name of profile - if (name == false) { - LOG_INFO("profile name: %s", line.c_str()); - setName(line); - name = true; - } - else { - // new structure, create profile key and read the keyboard's key code - if (lineType == LineType::KEY_CODE) { - uint32_t keyCode; - std::stringstream(line) >> keyCode; - pk = new KeyProfile(); - pk->keyCode = keyCode; - lineType = LineType::CYCLIC; - } - else if (lineType == LineType::CYCLIC) { - pk->cyclic = (line.compare("true") == 0); - lineType = LineType::CHARACTERS; - } - else if (lineType == LineType::CHARACTERS) { - addCharacters(pk, line); - lineType = LineType::TIMEOUTS; - } - else if (lineType == LineType::TIMEOUTS) { - addTimeouts(pk, line); - if ((pk->chars.size() == pk->timeouts.size()) && (keys.find(pk->keyCode) == keys.end())) { - addKeyProfile(pk); - } - else { - LOG_FATAL("Incorrect number of chars or key code duplicate key code: [%" PRIu32 "]", - pk->keyCode); - delete pk; - pk = nullptr; - } + std::fread(stream.get(), 1, fsize, fd); - lineType = LineType::KEY_CODE; - } - else { - LOG_FATAL("invalid line: [%s]", line.c_str()); - } - } - } - } + std::string err; + json11::Json parsedJson = json11::Json::parse(stream.get(), err); - std::fclose(file); + auto _ = gsl::finally([fd] { std::fclose(fd); }); - return true; - } - - int is_utf8_character(unsigned char c) - { - if ((c >> 7) == 0b1) { - if ((c >> 6) == 0b10) { - return 2; // 2nd, 3rd or 4th byte of a utf-8 character - } - else { - return 1; // 1st byte of a utf-8 character - } - } - else { - return 0; // a single byte character - } - } - - static std::vector split_str(const std::string &s, int chars_number, int start_pos) - { - int pos = start_pos, char_pos, bytes_to_write; - std::vector elems; - while (pos < (int)s.length()) { - bytes_to_write = chars_number; - char_pos = pos + 1; - if (is_utf8_character(s[char_pos]) > 0) { - bytes_to_write = bytes_to_write + 1; - } - elems.push_back(s.substr(pos, bytes_to_write)); - pos = pos + bytes_to_write + 1; - } - return elems; - } - - void Profile::addCharacters(KeyProfile *pk, const std::string &s) const - { - - uint32_t charKey; - std::vector vec = split_str(s, 3, 0); - for (std::string s : vec) { - std::string ts = trim(s); - if (ts[0] == '\'') { - // empty character - no character - if (s.size() == 2) { - pk->chars.push_back(0); - break; - } - ts = s.substr(1, s.size() - 1); - UTF8 utf = UTF8(ts); - charKey = utf[0]; - pk->chars.push_back(charKey); - } - else if (ts.substr(0, 2) == "0x") { - std::stringstream ss; - ss << std::hex << ts; - ss >> charKey; - pk->chars.push_back(charKey); - } + if (err.length() != 0) { + LOG_FATAL("%s", err.c_str()); + return json11::Json(); } - } - void Profile::addTimeouts(KeyProfile *pk, const std::string &s) const - { - uint32_t timeout; - std::vector vec = split(s, ','); - for (std::string s : vec) { - std::stringstream(trim(s)) >> timeout; - pk->timeouts.push_back(timeout); - } - } - - void Profile::addKeyProfile(KeyProfile *pk) - { - if (pk != nullptr) - keys.insert(std::pair(pk->keyCode, pk)); - } - - void Profile::setName(const std::string &name) - { - this->name = name; - } - - const KeyProfile *Profile::getKeyProfile(uint32_t keyCode) const - { - auto key = keys.find(keyCode); - if (key != keys.end()) - return key->second; - return nullptr; + return parsedJson; } - uint32_t Profile::get(bsp::KeyCodes code, uint32_t times) + uint32_t Profile::getCharKey(bsp::KeyCodes code, uint32_t times) { - const KeyProfile *p = getKeyProfile(static_cast(code)); - if (p == nullptr) { - LOG_DEBUG("KeyProfile for key: %" PRIu32 " not found", static_cast(code)); - return 0; + std::string ts = inputChars[utils::to_string(static_cast(code))].string_value(); + UTF8 utf = UTF8(ts); + if (ts.size() > 0) { + return utf[times % utf.length()]; } - return p->chars[times % p->chars.size()]; + return utf[0]; } } /* namespace gui */ diff --git a/module-gui/gui/input/Profile.hpp b/module-gui/gui/input/Profile.hpp index 43acde04d925991713261cd892580813f4adffd4..d0f9184d38e96655497a1208554335ae5393fbcf 100644 --- a/module-gui/gui/input/Profile.hpp +++ b/module-gui/gui/input/Profile.hpp @@ -6,46 +6,26 @@ #include #include #include +#include "json/json11.hpp" + namespace gui { - class KeyProfile - { - public: - static const uint32_t none_key; /// defaults to 0 - uint32_t keyCode = none_key; - bool cyclic = false; - std::vector chars; - std::vector timeouts; - - virtual ~KeyProfile() = default; - - void addCharacters(const std::string &s); - void addTimeouts(const std::string &s); - }; - class Profile { + private: std::string name; - std::map keys = {}; + json11::Json inputChars; - void addCharacters(KeyProfile *pk, const std::string &s) const; - void addTimeouts(KeyProfile *pk, const std::string &s) const; - void addKeyProfile(KeyProfile *pk); - void setName(const std::string &name); - const KeyProfile *getKeyProfile(uint32_t keyCode) const; + const json11::Json createJson(const std::string &filepath); public: - void clear(); - Profile() = default; - Profile(const std::string &name); - Profile(Profile &&p); - virtual ~Profile(); - - [[nodiscard]] std::string getName() const noexcept; - bool load(const std::string &filename); + static constexpr uint32_t none_key = 0; + Profile() = default; + explicit Profile(const std::string &filepath); - uint32_t get(bsp::KeyCodes code, uint32_t times); + [[nodiscard]] const std::string &getName() noexcept; + [[nodiscard]] uint32_t getCharKey(bsp::KeyCodes code, uint32_t times); }; } /* namespace gui */ diff --git a/module-gui/gui/input/Translator.cpp b/module-gui/gui/input/Translator.cpp index 022563fde606b3e7bc85e8ac13fc8011b6a7df8c..ccbb5e551e7acbae507c8d1279b26ac01f1ac6e9 100644 --- a/module-gui/gui/input/Translator.cpp +++ b/module-gui/gui/input/Translator.cpp @@ -9,6 +9,11 @@ namespace gui { + namespace + { + constexpr auto profilesFolder = "assets/profiles"; + constexpr auto extension = ".json"; + } // namespace void recon_long_press(InputEvent &evt, const RawKey &key, const RawKey &prev_key_press, uint32_t time) { @@ -180,26 +185,30 @@ namespace gui if (key.state == RawKey::State::Released) { prev_key_press = key; } - return Profiles::get(keymap).get(key.key_code, times); + return profiles.get(keymap).getCharKey(key.key_code, times); + } + + uint32_t KeyInputMappedTranslation::getTimes() const noexcept + { + return times; } void Profiles::loadProfile(const std::string &filepath) { LOG_INFO("Load profile: %s", filepath.c_str()); auto p = Profile(filepath); - if (p.getName() != std::string()) { - profiles.insert({p.getName(), std::move(p)}); + if (auto name = p.getName(); !name.empty()) { + profilesList.insert({p.getName(), std::move(p)}); } } - std::vector Profiles::getProfilesList(std::string ext) + + std::vector Profiles::getProfilesPaths() { std::vector profileFiles; - LOG_INFO("Scanning %s profiles folder: %s", ext.c_str(), profilesFolder); + LOG_INFO("Scanning %s profiles folder: %s", extension, profilesFolder); for (const auto &entry : std::filesystem::directory_iterator(profilesFolder)) { - if (!std::filesystem::is_directory(entry) && entry.path().extension().string() == ext) { - profileFiles.push_back(entry.path().string()); - } + profileFiles.push_back(std::filesystem::path(entry.path())); } LOG_INFO("Total number of profiles: %u", static_cast(profileFiles.size())); @@ -208,16 +217,17 @@ namespace gui void Profiles::init() { - std::vector profileFiles = getProfilesList(".kprof"); - for (std::string mapName : profileFiles) { - if (std::size(mapName)) { - loadProfile(mapName); + std::vector profileFilesPaths = getProfilesPaths(); + for (std::string filePath : profileFilesPaths) { + if (std::size(filePath)) { + loadProfile(filePath); } } - if (std::size(profiles) == 0) { + if (std::size(profilesList) == 0) { LOG_ERROR("No keyboard profiles loaded"); } } + Profiles &Profiles::get() { static Profiles *p; @@ -227,16 +237,19 @@ namespace gui } return *p; } + Profile &Profiles::get(const std::string &name) { + auto filepath = std::string(profilesFolder) + "/" + name + extension; // if profile not in profile map -> load - if (std::size(name) == 0) { - LOG_ERROR("Request for non existend profile: %s", name.c_str()); + if (std::size(filepath) == 0) { + LOG_ERROR("Request for nonexistent profile: %s", filepath.c_str()); return get().empty; } - if (get().profiles.find(name) == get().profiles.end()) { - get().loadProfile(name); + if (get().profilesList.find(filepath) == get().profilesList.end()) { + get().loadProfile(filepath); } - return get().profiles[name]; + return get().profilesList[filepath]; } + } /* namespace gui */ diff --git a/module-gui/gui/input/Translator.hpp b/module-gui/gui/input/Translator.hpp index bd761fa0d40657e129c0f8473c0b6a04ff3b2b9a..1162e7efad58d3f01749b56c36cb2ebca718c137 100644 --- a/module-gui/gui/input/Translator.hpp +++ b/module-gui/gui/input/Translator.hpp @@ -50,35 +50,32 @@ namespace gui InputEvent translate(uint32_t timeout); }; - /// translator using & switching KeyMaps for use per widget basis ,called for selected widget, per widget basis - class KeyInputMappedTranslation : public KeyBaseTranslation - { - uint32_t times = 0; - - public: - bool setProfile(std::string profileName); - uint32_t handle(RawKey key, const std::string &keymap); - uint32_t getTimes() - { - return times; - } - }; - /// profiles cache - load once for all class Profiles { private: - const char *profilesFolder = "assets/profiles"; - std::map profiles = {}; - Profile empty; + std::map profilesList = {}; void loadProfile(const std::string &filepath); - std::vector getProfilesList(std::string ext); + std::vector getProfilesPaths(); void init(); + Profile empty; - public: static Profiles &get(); - static Profile &get(const std::string &name); + + public: + Profile &get(const std::string &name); + }; + + /// translator using & switching KeyMaps for use per widget basis ,called for selected widget, per widget basis + class KeyInputMappedTranslation : public KeyBaseTranslation + { + uint32_t times = 0; + Profiles profiles; + + public: + uint32_t handle(RawKey key, const std::string &keymap); + uint32_t getTimes() const noexcept; }; } /* namespace gui */ diff --git a/module-gui/gui/widgets/Text.cpp b/module-gui/gui/widgets/Text.cpp index 2cc05a3d30ea0f46dc4d2f74a9b7f557d1a84550..83db9551930317871407b0cf60a4d63e7bf473aa 100644 --- a/module-gui/gui/widgets/Text.cpp +++ b/module-gui/gui/widgets/Text.cpp @@ -545,7 +545,7 @@ namespace gui auto code = translator.handle(inputEvent.key, mode ? mode->get() : ""); - if (code != KeyProfile::none_key && checkAdditionBounds(code) == AdditionBound::CanAddAll) { + if (code != Profile::none_key && checkAdditionBounds(code) == AdditionBound::CanAddAll) { setCursorStartPosition(CursorStartPosition::Offset); diff --git a/module-gui/test/test-catch/CMakeLists.txt b/module-gui/test/test-catch/CMakeLists.txt index 5c7f327dcf059801d26072472c5f6375bdf0e1df..6ffc1d2c9db4781901e06bc20387c211d8256fc7 100644 --- a/module-gui/test/test-catch/CMakeLists.txt +++ b/module-gui/test/test-catch/CMakeLists.txt @@ -9,6 +9,7 @@ add_catch2_executable( test-gui-resizes.cpp ../mock/TestWindow.cpp ../mock/InitializedFontManager.cpp + test-language-input-parser.cpp INCLUDE .. LIBS diff --git a/module-gui/test/test-catch/test-language-input-parser.cpp b/module-gui/test/test-catch/test-language-input-parser.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6f5f17ddcb2787c7692c348e8324d150936468a5 --- /dev/null +++ b/module-gui/test/test-catch/test-language-input-parser.cpp @@ -0,0 +1,100 @@ +// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include +#include + +TEST_CASE("Parsing English input language") +{ + + gui::KeyInputMappedTranslation translator; + RawKey key; + + SECTION("Getting charKey from lower letters") + { + key.key_code = bsp::KeyCodes::NumericKey1; + REQUIRE(translator.handle(key, "English_lower") == 46); + key.key_code = bsp::KeyCodes::NumericKey2; + REQUIRE(translator.handle(key, "English_lower") == 97); + key.key_code = bsp::KeyCodes::NumericKey3; + REQUIRE(translator.handle(key, "English_lower") == 100); + key.key_code = bsp::KeyCodes::NumericKey4; + REQUIRE(translator.handle(key, "English_lower") == 103); + key.key_code = bsp::KeyCodes::NumericKey5; + REQUIRE(translator.handle(key, "English_lower") == 106); + key.key_code = bsp::KeyCodes::NumericKey6; + REQUIRE(translator.handle(key, "English_lower") == 109); + key.key_code = bsp::KeyCodes::NumericKey7; + REQUIRE(translator.handle(key, "English_lower") == 112); + key.key_code = bsp::KeyCodes::NumericKey8; + REQUIRE(translator.handle(key, "English_lower") == 116); + key.key_code = bsp::KeyCodes::NumericKey9; + REQUIRE(translator.handle(key, "English_lower") == 119); + key.key_code = bsp::KeyCodes::NumericKey0; + REQUIRE(translator.handle(key, "English_lower") == 32); + } + + SECTION("Getting charKey from upper letters") + { + key.key_code = bsp::KeyCodes::NumericKey1; + REQUIRE(translator.handle(key, "English_upper") == 46); + key.key_code = bsp::KeyCodes::NumericKey2; + REQUIRE(translator.handle(key, "English_upper") == 65); + key.key_code = bsp::KeyCodes::NumericKey3; + REQUIRE(translator.handle(key, "English_upper") == 68); + key.key_code = bsp::KeyCodes::NumericKey4; + REQUIRE(translator.handle(key, "English_upper") == 71); + key.key_code = bsp::KeyCodes::NumericKey5; + REQUIRE(translator.handle(key, "English_upper") == 74); + key.key_code = bsp::KeyCodes::NumericKey6; + REQUIRE(translator.handle(key, "English_upper") == 77); + key.key_code = bsp::KeyCodes::NumericKey7; + REQUIRE(translator.handle(key, "English_upper") == 80); + key.key_code = bsp::KeyCodes::NumericKey8; + REQUIRE(translator.handle(key, "English_upper") == 84); + key.key_code = bsp::KeyCodes::NumericKey9; + REQUIRE(translator.handle(key, "English_upper") == 87); + key.key_code = bsp::KeyCodes::NumericKey0; + REQUIRE(translator.handle(key, "English_upper") == 32); + } +} + +TEST_CASE("Parsing numeric keyboard") +{ + gui::KeyInputMappedTranslation translator; + RawKey key; + + key.key_code = bsp::KeyCodes::NumericKey1; + REQUIRE(translator.handle(key, "numeric") == 49); + key.key_code = bsp::KeyCodes::NumericKey2; + REQUIRE(translator.handle(key, "numeric") == 50); + key.key_code = bsp::KeyCodes::NumericKey3; + REQUIRE(translator.handle(key, "numeric") == 51); + key.key_code = bsp::KeyCodes::NumericKey4; + REQUIRE(translator.handle(key, "numeric") == 52); + key.key_code = bsp::KeyCodes::NumericKey5; + REQUIRE(translator.handle(key, "numeric") == 53); + key.key_code = bsp::KeyCodes::NumericKey6; + REQUIRE(translator.handle(key, "numeric") == 54); + key.key_code = bsp::KeyCodes::NumericKey7; + REQUIRE(translator.handle(key, "numeric") == 55); + key.key_code = bsp::KeyCodes::NumericKey8; + REQUIRE(translator.handle(key, "numeric") == 56); + key.key_code = bsp::KeyCodes::NumericKey9; + REQUIRE(translator.handle(key, "numeric") == 57); + key.key_code = bsp::KeyCodes::NumericKey0; + REQUIRE(translator.handle(key, "numeric") == 48); +} + +TEST_CASE("Getting charKey after clicking button twice") +{ + gui::KeyInputMappedTranslation translator; + gui::KeyBaseTranslation baseTranslation; + RawKey key; + + key.key_code = bsp::KeyCodes::NumericKey2; + key.state = RawKey::State::Released; + baseTranslation.prev_key_press = key; + translator.handle(key, "English_lower"); + REQUIRE(translator.handle(key, "English_lower") == 98); +}