aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJarkko Koivikko <jarkko.koivikko@code-q.fi>2021-02-26 13:55:29 +0200
committerJarkko Koivikko <jarkko.koivikko@code-q.fi>2021-06-03 16:36:20 +0300
commit6dec71ba17abdeab3f4554d463ddec9a0ea63ecc (patch)
treeaf0080cd42dff9473139f295a26bd0cab780518c /src
parent44ed5e1e2c35293e34331fa8a629d642a5877a2f (diff)
Add Cerence HWR and Cerence XT9 extension plugins
Cerence SDK enables two extension plugins for the Qt Virtual Keyboard. - Cerence HWR: Handwriting extension know previously as T9 Write - Cerence XT9: Advanced keyboard extension, supporting various languages This commit removes the previous T9 Write extension and reintroduces it as the Cerence HWR extension. This commit also adds the Cerence XT9 as a new feature. The Cerence HWR can also utilize the XT9 for some additional features. Here is a list of changes made to the handwriting extension: - Move the T9 Write extension to the general "cerence" directory, which allows data and code to be shared between T9 Write and XT9. - Update unpack.py to match the latest Cerence SDK. Drop support for legacy delivery rules, as they interfere with the latest SDK. - Alphabetic API was renamed from decuma* to decumaUcr at version number 21 - Add extra parameter to BeginArcAddition and set bMinimizePreProcessing to 1 to avoid defining the parameter. - Do not pass the support lines to engine as they are not supported/needed. For example, the latest CJK SDK returns error when the support lines are defined. - Remove reference to decumaFunctionalSupport.h, which is not part of the official SDK. As a consequence, disable support for recognition interrupt, which is not critical feature anyway. - Fix several compiler warnings. - Enable UCR mode for new languages. - Filter out duplicate candidates (after case formatting) - Use handwriting recognition timeout setting - Check and recover from an init failure when UCR not supported - Use common dictionary management with XT9 - Add user defined search path for HWR db QT_VIRTUALKEYBOARD_T9WRITE_DB_PATH - Use generic dictionary API - Add user dictionary (DLM) - Limit too many simultaneous input - Add support for the latest SDK (removed support from previous versions of the SDK) - Add support for background recognition supported by the engine. This improves latencies and removes delays in certain situations. - Clear old traces from screen after specified delay. Previously, old traces were cleared from the screen based on the information from the engine to identify strokes of the recognized characters. Unfortunately, the engine does not provide this information at the same detail in UCR mode. This change introduces a timer-based approach, where traces are removed after a specified time, calculated from the recognition result. This time can be adjusted in the virtual keyboard settings. - Add auto correction for alphabetic languages - Add predictions from custom dictionary (XT9 Nav) - Fix language id mapping between Qt6 QLocale::Language and Cerence HWR. Change-Id: Iff4daea67cbb8adee1caf2e9513198482da48a38 Reviewed-by: Mitch Curtis <mitch.curtis@qt.io> Reviewed-by: Jarkko Koivikko <jarkko.koivikko@code-q.fi>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/CMakeLists.txt8
-rw-r--r--src/plugins/cerence/.gitignore1
-rw-r--r--src/plugins/cerence/CMakeLists.txt9
-rw-r--r--src/plugins/cerence/cerence-hwr/CMakeLists.txt3
-rw-r--r--src/plugins/cerence/cerence-hwr/plugin/CMakeLists.txt647
-rw-r--r--src/plugins/cerence/cerence-hwr/plugin/cerence_hwr.json (renamed from src/plugins/t9write/plugin/t9write.json)2
-rw-r--r--src/plugins/cerence/cerence-hwr/plugin/cerence_hwr_p.h (renamed from src/plugins/t9write/plugin/t9write_p.h)25
-rw-r--r--src/plugins/cerence/cerence-hwr/plugin/content/layouts/zh_HK/handwriting.qml99
-rw-r--r--src/plugins/cerence/cerence-hwr/plugin/qtvirtualkeyboardcerencehwrplugin.cpp (renamed from src/plugins/t9write/plugin/t9writeplugin.cpp)11
-rw-r--r--src/plugins/cerence/cerence-hwr/plugin/qtvirtualkeyboardcerencehwrplugin.h49
-rw-r--r--src/plugins/cerence/cerence-hwr/plugin/t9writeabstractdictionary_p.h (renamed from src/plugins/t9write/plugin/t9writedictionary_p.h)46
-rw-r--r--src/plugins/cerence/cerence-hwr/plugin/t9writedictionary.cpp307
-rw-r--r--src/plugins/cerence/cerence-hwr/plugin/t9writedictionary_p.h148
-rw-r--r--src/plugins/cerence/cerence-hwr/plugin/t9writeinputmethod.cpp (renamed from src/plugins/t9write/plugin/t9writeinputmethod.cpp)1507
-rw-r--r--src/plugins/cerence/cerence-hwr/plugin/t9writeinputmethod_p.h (renamed from src/plugins/t9write/plugin/t9writeinputmethod_p.h)20
-rw-r--r--src/plugins/cerence/cerence-hwr/plugin/t9writewordcandidate.cpp49
-rw-r--r--src/plugins/cerence/cerence-hwr/plugin/t9writewordcandidate_p.h71
-rw-r--r--src/plugins/cerence/cerence-hwr/plugin/t9writeworker.cpp (renamed from src/plugins/t9write/plugin/t9writeworker.cpp)236
-rw-r--r--src/plugins/cerence/cerence-hwr/plugin/t9writeworker_p.h (renamed from src/plugins/t9write/plugin/t9writeworker_p.h)71
-rw-r--r--src/plugins/cerence/cerencecommon/CMakeLists.txt200
-rw-r--r--src/plugins/cerence/cerencecommon/dummy.txt0
-rw-r--r--src/plugins/cerence/cerencecommon/xt9dbfile.cpp98
-rw-r--r--src/plugins/cerence/cerencecommon/xt9dbfile.h58
-rw-r--r--src/plugins/cerence/cerencecommon/xt9ldbmanager.cpp193
-rw-r--r--src/plugins/cerence/cerencecommon/xt9ldbmanager.h67
-rw-r--r--src/plugins/cerence/unpack.py (renamed from src/plugins/t9write/3rdparty/t9write/unpack.py)248
-rw-r--r--src/plugins/cerence/xt9/CMakeLists.txt4
-rw-r--r--src/plugins/cerence/xt9/plugin/9key_layouts/content/layouts/ja_JP/main.qml694
-rw-r--r--src/plugins/cerence/xt9/plugin/9key_layouts/content/layouts/zh_CN/main.qml188
-rw-r--r--src/plugins/cerence/xt9/plugin/9key_layouts/content/layouts/zh_TW/main.qml184
-rw-r--r--src/plugins/cerence/xt9/plugin/CMakeLists.txt413
-rw-r--r--src/plugins/cerence/xt9/plugin/cerence_xt9.json12
-rw-r--r--src/plugins/cerence/xt9/plugin/content/layouts/ja_JP/main.qml920
-rw-r--r--src/plugins/cerence/xt9/plugin/content/layouts/zh_HK/dialpad.fallback0
-rw-r--r--src/plugins/cerence/xt9/plugin/content/layouts/zh_HK/digits.fallback0
-rw-r--r--src/plugins/cerence/xt9/plugin/content/layouts/zh_HK/main.qml189
-rw-r--r--src/plugins/cerence/xt9/plugin/content/layouts/zh_HK/numbers.fallback0
-rw-r--r--src/plugins/cerence/xt9/plugin/content/layouts/zh_HK/symbols.qml477
-rw-r--r--src/plugins/cerence/xt9/plugin/xt9awinputmethod.cpp329
-rw-r--r--src/plugins/cerence/xt9/plugin/xt9awinputmethod_p.h71
-rw-r--r--src/plugins/cerence/xt9/plugin/xt9awinputmethodprivate.cpp173
-rw-r--r--src/plugins/cerence/xt9/plugin/xt9awinputmethodprivate_p.h81
-rw-r--r--src/plugins/cerence/xt9/plugin/xt9cpinputmethod.cpp179
-rw-r--r--src/plugins/cerence/xt9/plugin/xt9cpinputmethod_p.h65
-rw-r--r--src/plugins/cerence/xt9/plugin/xt9cpinputmethodprivate.cpp160
-rw-r--r--src/plugins/cerence/xt9/plugin/xt9cpinputmethodprivate_p.h70
-rw-r--r--src/plugins/cerence/xt9/plugin/xt9inputmethod.cpp56
-rw-r--r--src/plugins/cerence/xt9/plugin/xt9inputmethod_p.h54
-rw-r--r--src/plugins/cerence/xt9/plugin/xt9inputmethodprivate.cpp576
-rw-r--r--src/plugins/cerence/xt9/plugin/xt9inputmethodprivate_p.h143
-rw-r--r--src/plugins/cerence/xt9/plugin/xt9jinputmethod.cpp130
-rw-r--r--src/plugins/cerence/xt9/plugin/xt9jinputmethod_p.h62
-rw-r--r--src/plugins/cerence/xt9/plugin/xt9jinputmethodprivate.cpp142
-rw-r--r--src/plugins/cerence/xt9/plugin/xt9jinputmethodprivate_p.h70
-rw-r--r--src/plugins/cerence/xt9/plugin/xt9kinputmethod.cpp70
-rw-r--r--src/plugins/cerence/xt9/plugin/xt9kinputmethod_p.h55
-rw-r--r--src/plugins/cerence/xt9/plugin/xt9kinputmethodprivate.cpp54
-rw-r--r--src/plugins/cerence/xt9/plugin/xt9kinputmethodprivate_p.h63
-rw-r--r--src/plugins/cerence/xt9/plugin/xt9plugin.cpp56
-rw-r--r--src/plugins/cerence/xt9/plugin/xt9plugin.h (renamed from src/plugins/t9write/plugin/t9writeplugin.h)10
-rw-r--r--src/plugins/cerence/xt9/plugin/xt9thaiinputmethod.cpp58
-rw-r--r--src/plugins/cerence/xt9/plugin/xt9thaiinputmethod_p.h53
-rw-r--r--src/plugins/cerence/xt9/plugin/xt9thaiinputmethodprivate.cpp41
-rw-r--r--src/plugins/cerence/xt9/plugin/xt9thaiinputmethodprivate_p.h49
-rw-r--r--src/plugins/cerence/xt9/xt9common/CMakeLists.txt141
-rw-r--r--src/plugins/cerence/xt9/xt9common/xt9awime.cpp139
-rw-r--r--src/plugins/cerence/xt9/xt9common/xt9awime.h65
-rw-r--r--src/plugins/cerence/xt9/xt9common/xt9callbacks.h47
-rw-r--r--src/plugins/cerence/xt9/xt9common/xt9cpime.cpp311
-rw-r--r--src/plugins/cerence/xt9/xt9common/xt9cpime.h73
-rw-r--r--src/plugins/cerence/xt9/xt9common/xt9ime.cpp324
-rw-r--r--src/plugins/cerence/xt9/xt9common/xt9ime.h133
-rw-r--r--src/plugins/cerence/xt9/xt9common/xt9jime.cpp68
-rw-r--r--src/plugins/cerence/xt9/xt9common/xt9jime.h47
-rw-r--r--src/plugins/cerence/xt9/xt9common/xt9kdb.cpp51
-rw-r--r--src/plugins/cerence/xt9/xt9common/xt9kdb.h49
-rw-r--r--src/plugins/cerence/xt9/xt9common/xt9kdbarea.cpp47
-rw-r--r--src/plugins/cerence/xt9/xt9common/xt9kdbarea.h51
-rw-r--r--src/plugins/cerence/xt9/xt9common/xt9kdbelement.cpp41
-rw-r--r--src/plugins/cerence/xt9/xt9common/xt9kdbelement.h49
-rw-r--r--src/plugins/cerence/xt9/xt9common/xt9kdbkey.cpp126
-rw-r--r--src/plugins/cerence/xt9/xt9common/xt9kdbkey.h113
-rw-r--r--src/plugins/cerence/xt9/xt9common/xt9kdblayout.cpp66
-rw-r--r--src/plugins/cerence/xt9/xt9common/xt9kdblayout.h57
-rw-r--r--src/plugins/cerence/xt9/xt9common/xt9keyboardgenerator.cpp167
-rw-r--r--src/plugins/cerence/xt9/xt9common/xt9keyboardgenerator.h84
-rw-r--r--src/plugins/cerence/xt9/xt9common/xt9kime.cpp74
-rw-r--r--src/plugins/cerence/xt9/xt9common/xt9kime.h53
-rw-r--r--src/plugins/cerence/xt9/xt9common/xt9languagemap.cpp250
-rw-r--r--src/plugins/cerence/xt9/xt9common/xt9languagemap.h66
-rw-r--r--src/plugins/t9write/3rdparty/t9write/CMakeLists.txt71
-rw-r--r--src/plugins/t9write/CMakeLists.txt4
-rw-r--r--src/plugins/t9write/plugin/CMakeLists.txt264
-rw-r--r--src/plugins/t9write/plugin/t9writedictionary.cpp121
-rw-r--r--src/virtualkeyboard/.prev_configure.cmake101
-rw-r--r--src/virtualkeyboard/CMakeLists.txt7
-rw-r--r--src/virtualkeyboard/configure.cmake109
-rw-r--r--src/virtualkeyboard/configure.json141
-rw-r--r--src/virtualkeyboard/content/layouts/ja_JP/symbols.qml2
-rw-r--r--src/virtualkeyboard/content/layouts/ko_KR/main.qml2
-rw-r--r--src/virtualkeyboard/content/layouts/ko_KR/symbols.qml2
-rw-r--r--src/virtualkeyboard/content/layouts/th_TH/main.qml2
-rw-r--r--src/virtualkeyboard/content/layouts/zh_CN/main.qml2
-rw-r--r--src/virtualkeyboard/content/layouts/zh_CN/symbols.qml2
-rw-r--r--src/virtualkeyboard/content/layouts/zh_TW/symbols.qml2
-rw-r--r--src/virtualkeyboard/doc/src/build.qdoc208
-rw-r--r--src/virtualkeyboard/doc/src/deployment-guide.qdoc29
-rw-r--r--src/virtualkeyboard/doc/src/handwriting.qdoc52
-rw-r--r--src/virtualkeyboard/doc/src/qtvirtualkeyboard-index.qdoc5
-rw-r--r--src/virtualkeyboard/doc/src/xt9.qdoc80
-rw-r--r--src/virtualkeyboard/qt_cmdline.cmake8
111 files changed, 12704 insertions, 1326 deletions
diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt
index 5ac8c73e..b1705c42 100644
--- a/src/plugins/CMakeLists.txt
+++ b/src/plugins/CMakeLists.txt
@@ -1,5 +1,8 @@
# Generated from plugins.pro.
+if(QT_FEATURE_cerence_sdk)
+ add_subdirectory(cerence)
+endif()
if(QT_FEATURE_hangul)
add_subdirectory(hangul)
endif()
@@ -9,12 +12,9 @@ endif()
if(QT_FEATURE_openwnn)
add_subdirectory(openwnn)
endif()
-if(QT_FEATURE_pinyin)
+if(QT_FEATURE_pinyin AND NOT QT_FEATURE_cerence_xt9)
add_subdirectory(pinyin)
endif()
-if(QT_FEATURE_t9write)
- add_subdirectory(t9write)
-endif()
if(QT_FEATURE_tcime)
add_subdirectory(tcime)
endif()
diff --git a/src/plugins/cerence/.gitignore b/src/plugins/cerence/.gitignore
new file mode 100644
index 00000000..5a435361
--- /dev/null
+++ b/src/plugins/cerence/.gitignore
@@ -0,0 +1 @@
+sdk
diff --git a/src/plugins/cerence/CMakeLists.txt b/src/plugins/cerence/CMakeLists.txt
new file mode 100644
index 00000000..e9863e9d
--- /dev/null
+++ b/src/plugins/cerence/CMakeLists.txt
@@ -0,0 +1,9 @@
+# Generated from cerence.pro.
+
+add_subdirectory(cerencecommon)
+if(QT_FEATURE_cerence_hwr)
+ add_subdirectory(cerence-hwr)
+endif()
+if(QT_FEATURE_cerence_xt9)
+ add_subdirectory(xt9)
+endif()
diff --git a/src/plugins/cerence/cerence-hwr/CMakeLists.txt b/src/plugins/cerence/cerence-hwr/CMakeLists.txt
new file mode 100644
index 00000000..472a3475
--- /dev/null
+++ b/src/plugins/cerence/cerence-hwr/CMakeLists.txt
@@ -0,0 +1,3 @@
+# Generated from cerence-hwr.pro.
+
+add_subdirectory(plugin)
diff --git a/src/plugins/cerence/cerence-hwr/plugin/CMakeLists.txt b/src/plugins/cerence/cerence-hwr/plugin/CMakeLists.txt
new file mode 100644
index 00000000..124b1592
--- /dev/null
+++ b/src/plugins/cerence/cerence-hwr/plugin/CMakeLists.txt
@@ -0,0 +1,647 @@
+# Generated from plugin.pro.
+
+#####################################################################
+## QtVirtualKeyboardCerenceHwrPlugin Plugin:
+#####################################################################
+
+qt_internal_add_plugin(QtVirtualKeyboardCerenceHwrPlugin
+ OUTPUT_NAME qtvirtualkeyboard_cerence_hwr
+ TYPE virtualkeyboard
+ SOURCES
+ cerence_hwr_p.h
+ qtvirtualkeyboardcerencehwrplugin.cpp qtvirtualkeyboardcerencehwrplugin.h
+ t9writeabstractdictionary_p.h
+ t9writedictionary.cpp t9writedictionary_p.h
+ t9writeinputmethod.cpp t9writeinputmethod_p.h
+ t9writewordcandidate.cpp t9writewordcandidate_p.h
+ t9writeworker.cpp t9writeworker_p.h
+ DEFINES
+ HAVE_CERENCE_HWR
+ QT_ASCII_CAST_WARNINGS
+ QT_NO_CAST_FROM_ASCII
+ QT_NO_CAST_FROM_BYTEARRAY
+ QT_NO_CAST_TO_ASCII
+ LIBRARIES
+ BundledCerencecommon
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::Gui
+ Qt::Qml
+ Qt::VirtualKeyboardPrivate
+)
+
+# Resources:
+set(qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/fallback/handwriting.qml"
+)
+
+if (QT_FEATURE_vkb_lang_en_GB)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/en_GB/handwriting.fallback"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_en_US)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/en_US/handwriting.fallback"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_ar_AR)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/ar_AR/handwriting.qml"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_bg_BG)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/bg_BG/handwriting.qml"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_cs_CZ)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/cs_CZ/handwriting.qml"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_da_DK)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/da_DK/handwriting.fallback"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_de_DE)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/de_DE/handwriting.fallback"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_el_GR)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/el_GR/handwriting.qml"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_es_ES)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/es_ES/handwriting.qml"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_es_MX)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/es_MX/handwriting.qml"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_et_EE)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/et_EE/handwriting.fallback"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_fa_FA)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/fa_FA/handwriting.qml"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_fi_FI)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/fi_FI/handwriting.fallback"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_fr_FR)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/fr_FR/handwriting.fallback"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_fr_CA)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/fr_CA/handwriting.fallback"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_he_IL)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/he_IL/handwriting.qml"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_hr_HR)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/hr_HR/handwriting.qml"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_hu_HU)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/hu_HU/handwriting.qml"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_id_ID)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/id_ID/handwriting.fallback"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_it_IT)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/it_IT/handwriting.fallback"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_ms_MY)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/ms_MY/handwriting.fallback"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_nb_NO)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/nb_NO/handwriting.fallback"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_nl_NL)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/nl_NL/handwriting.fallback"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_pl_PL)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/pl_PL/handwriting.fallback"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_pt_BR)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/pt_BR/handwriting.fallback"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_pt_PT)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/pt_PT/handwriting.fallback"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_ro_RO)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/ro_RO/handwriting.qml"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_ru_RU)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/ru_RU/handwriting.qml"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_sk_SK)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/sk_SK/handwriting.fallback"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_sl_SI)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/sl_SI/handwriting.fallback"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_sq_AL)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/sq_AL/handwriting.fallback"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_sr_SP)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/sr_SP/handwriting.qml"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_sv_SE)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/sv_SE/handwriting.fallback"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_th_TH)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/th_TH/handwriting.qml"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_tr_TR)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/tr_TR/handwriting.fallback"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_uk_UA)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/uk_UA/handwriting.qml"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_vi_VN)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/vi_VN/handwriting.fallback"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_ja_JP)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/ja_JP/handwriting.qml"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_ko_KR)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/ko_KR/handwriting.qml"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_zh_CN)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/zh_CN/handwriting.qml"
+ )
+endif()
+
+if (QT_FEATURE_vkb_lang_zh_TW)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/zh_TW/handwriting.qml"
+ )
+endif()
+
+qt_internal_add_resource(QtVirtualKeyboardCerenceHwrPlugin "qmake_virtualkeyboard_cerence_hwr_layouts"
+ PREFIX
+ "${VKB_LAYOUTS_PREFIX}"
+ BASE
+ "${VKB_LAYOUTS_BASE}"
+ FILES
+ ${qmake_virtualkeyboard_cerence_hwr_layouts_resource_files}
+)
+
+set(qmake_virtualkeyboard_cerence_hwr_custom_layouts_resource_files)
+if (QT_FEATURE_vkb_lang_zh_HK)
+ list(APPEND qmake_virtualkeyboard_cerence_hwr_custom_layouts_resource_files
+ "${CMAKE_CURRENT_SOURCE_DIR}/content/layouts/zh_HK/handwriting.qml"
+ )
+endif()
+
+qt_internal_add_resource(QtVirtualKeyboardCerenceHwrPlugin "qmake_virtualkeyboard_cerence_hwr_custom_layouts"
+ PREFIX
+ "${VKB_LAYOUTS_PREFIX}"
+ BASE
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ ${qmake_virtualkeyboard_cerence_hwr_custom_layouts_resource_files}
+)
+
+#### Keys ignored in scope 1:.:.:plugin.pro:<TRUE>:
+# DISTFILES = "cerence_hwr.json"
+# OTHER_FILES = "$$LAYOUT_FILES"
+# virtualkeyboard_cerence_hwr_custom_layouts.base = "$$PWD"
+# virtualkeyboard_cerence_hwr_custom_layouts.prefix = "$$LAYOUTS_PREFIX"
+
+## Scopes:
+#####################################################################
+
+qt_internal_extend_target(QtVirtualKeyboardCerenceHwrPlugin CONDITION QT_FEATURE_cerence_xt9
+ DEFINES
+ HAVE_XT9
+ LIBRARIES
+ BundledXt9Common
+)
+
+qt_internal_extend_target(QtVirtualKeyboardCerenceHwrPlugin CONDITION QT_FEATURE_cerence_hwr_alphabetic
+ DEFINES
+ HAVE_CERENCE_HWR_ALPHABETIC
+ LIBRARIES
+ Cerence::HWR::Alphabetic
+)
+
+qt_internal_extend_target(QtVirtualKeyboardCerenceHwrPlugin CONDITION QT_FEATURE_cerence_hwr_cjk
+ DEFINES
+ HAVE_CERENCE_HWR_CJK
+ LIBRARIES
+ Cerence::HWR::CJK
+)
+
+qt_internal_extend_target(QtVirtualKeyboardCerenceHwrPlugin CONDITION FEATURE_vkb_bundle_cerence OR FEATURE_vkb_bundle_cerence_hwr
+ DEFINES
+ HAVE_CERENCE_HWR_RESOURCE
+)
+
+if(FEATURE_vkb_bundle_cerence OR FEATURE_vkb_bundle_cerence_hwr)
+ set(resource_glob_0)
+ if(FEATURE_vkb_lang_ar_AR OR FEATURE_vkb_lang_fa_FA)
+ file(GLOB resource_glob_0 RELATIVE "${CERENCE_HWR_DATAPATH}" "${CERENCE_HWR_DATAPATH}/arabic/*.bin")
+ foreach(file IN LISTS resource_glob_0)
+ set_source_files_properties("${CERENCE_HWR_DATAPATH}/${file}" PROPERTIES QT_RESOURCE_ALIAS "${file}")
+ endforeach()
+ endif()
+
+ set(resource_glob_1)
+ if(FEATURE_vkb_lang_he_IL)
+ file(GLOB resource_glob_1 RELATIVE "${CERENCE_HWR_DATAPATH}" "${CERENCE_HWR_DATAPATH}/hebrew/*.bin")
+ foreach(file IN LISTS resource_glob_1)
+ set_source_files_properties("${CERENCE_HWR_DATAPATH}/${file}" PROPERTIES QT_RESOURCE_ALIAS "${file}")
+ endforeach()
+ endif()
+
+ set(resource_glob_2)
+ if(FEATURE_vkb_lang_th_TH)
+ file(GLOB resource_glob_2 RELATIVE "${CERENCE_HWR_DATAPATH}" "${CERENCE_HWR_DATAPATH}/thai/*.bin")
+ foreach(file IN LISTS resource_glob_2)
+ set_source_files_properties("${CERENCE_HWR_DATAPATH}/${file}" PROPERTIES QT_RESOURCE_ALIAS "${file}")
+ endforeach()
+ endif()
+
+ file(GLOB resource_glob_3 RELATIVE "${CERENCE_HWR_DATAPATH}" "${CERENCE_HWR_DATAPATH}/*.bin")
+ foreach(file IN LISTS resource_glob_3)
+ set_source_files_properties("${CERENCE_HWR_DATAPATH}/${file}" PROPERTIES QT_RESOURCE_ALIAS "${file}")
+ endforeach()
+
+ file(GLOB resource_glob_4 RELATIVE "${CERENCE_HWR_DATAPATH}" "${CERENCE_HWR_DATAPATH}/*.hdb")
+ foreach(file IN LISTS resource_glob_4)
+ set_source_files_properties("${CERENCE_HWR_DATAPATH}/${file}" PROPERTIES QT_RESOURCE_ALIAS "${file}")
+ endforeach()
+
+ file(GLOB resource_glob_5 RELATIVE "${CERENCE_HWR_DATAPATH}" "${CERENCE_HWR_DATAPATH}/*.phd")
+ foreach(file IN LISTS resource_glob_5)
+ set_source_files_properties("${CERENCE_HWR_DATAPATH}/${file}" PROPERTIES QT_RESOURCE_ALIAS "${file}")
+ endforeach()
+
+ # Resources:
+ set(qmake_cerencehwrdata_db_resource_files
+ ${resource_glob_0}
+ ${resource_glob_1}
+ ${resource_glob_2}
+ ${resource_glob_3}
+ ${resource_glob_4}
+ ${resource_glob_5}
+ )
+
+ qt_internal_add_resource(QtVirtualKeyboardCerenceHwrPlugin "qmake_cerencehwrdata_db"
+ PREFIX
+ "/QtQuick/VirtualKeyboard/Cerence/Handwriting"
+ BASE
+ "${CERENCE_HWR_DATAPATH}"
+ FILES
+ ${qmake_cerencehwrdata_db_resource_files}
+ OPTIONS
+ -no-compress
+ )
+else()
+ qt_copy_or_install(
+ DIRECTORY "${CERENCE_HWR_DATAPATH}/"
+ DESTINATION "${VKB_INSTALL_DATA}/cerence/handwriting"
+ )
+endif()
+
+if(QT_FEATURE_cerence_hwr_alphabetic AND NOT FEATURE_vkb_cerence_static)
+ qt_copy_or_install(
+ FILES "${CERENCE_HWR_ALPHABETIC_BINARIES}"
+ DESTINATION "${QT_BUILD_DIR}/${INSTALL_BINDIR}"
+ )
+endif()
+
+if(QT_FEATURE_cerence_hwr_cjk AND NOT FEATURE_vkb_cerence_static)
+ qt_copy_or_install(
+ FILES "${CERENCE_HWR_CJK_BINARIES}"
+ DESTINATION "${QT_BUILD_DIR}/${INSTALL_BINDIR}"
+ )
+endif()
+
+#### Keys ignored in scope 48:.:.:plugin.pro:FEATURE_vkb_bundle_cerence OR FEATURE_vkb_bundle_cerence_hwr:
+# QMAKE_RESOURCE_FLAGS = "-no-compress"
+
+#### Keys ignored in scope 50:.:.:plugin.pro:NOT CERENCE_HWR_ALPHABETIC_BINS_ISEMPTY:
+# INSTALLS = "t9write_alphabetic_bins"
+# t9write_alphabetic_bins.files = "$$CERENCE_HWR_ALPHABETIC_BINS"
+
+#### Keys ignored in scope 51:.:.:plugin.pro:WIN32 OR win64:
+# t9write_alphabetic_bins.path = "$$[QT_INSTALL_BINS]"
+
+#### Keys ignored in scope 52:.:.:plugin.pro:else:
+# t9write_alphabetic_bins.path = "$$[QT_INSTALL_LIBS]"
+
+#### Keys ignored in scope 53:.:.:plugin.pro:NOT prefix_build:
+# COPIES = "t9write_alphabetic_bins"
+
+#### Keys ignored in scope 55:.:.:plugin.pro:NOT CERENCE_HWR_CJK_BINS_ISEMPTY:
+# INSTALLS = "t9write_cjk_bins"
+# t9write_cjk_bins.files = "$$CERENCE_HWR_CJK_BINS"
+
+#### Keys ignored in scope 56:.:.:plugin.pro:WIN32 OR win64:
+# t9write_cjk_bins.path = "$$[QT_INSTALL_BINS]"
+
+#### Keys ignored in scope 57:.:.:plugin.pro:else:
+# t9write_cjk_bins.path = "$$[QT_INSTALL_LIBS]"
+
+#### Keys ignored in scope 58:.:.:plugin.pro:NOT prefix_build:
+# COPIES = "t9write_cjk_bins"
+
+#### Keys ignored in scope 59:.:.:plugin.pro:WIN32:
+# QMAKE_TARGET_DESCRIPTION = "Virtual Keyboard Extension for Qt."
+# QMAKE_TARGET_PRODUCT = "Qt Virtual Keyboard Cerence Handwriting (Qt $$QT_VERSION)"
+
+#### Keys ignored in scope 105:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:MYSCRIPT_PATH_ISEMPTY:
+# MYSCRIPT_PATH = "$$PWD"
+
+#### Keys ignored in scope 106:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:UNIX AND LINUX AND NOT ANDROID:
+# MYSCRIPT_LIB_PREFIX = "lib"
+# MYSCRIPT_LIB_SUFFIX = ".so"
+# MYSCRIPT_VOIM_LIB_NAME = "libvoim.so"
+# MYSCRIPT_VOIM_LIB_PATH = "$$MYSCRIPT_PATH/$$MYSCRIPT_VOIM_PATH/$$MYSCRIPT_VOIM_LIB_NAME"
+
+#### Keys ignored in scope 107:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:QT_ARCH___equals___arm64:
+# MYSCRIPT_ENGINE_PATH = "engine/bin/lin-arm64"
+# MYSCRIPT_VOIM_PATH = "voim/bin/lin-arm64"
+
+#### Keys ignored in scope 109:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:QT_ARCH___equals___arm:
+# MYSCRIPT_ENGINE_PATH = "engine/bin/lin-armv7"
+# MYSCRIPT_VOIM_PATH = "voim/bin/lin-armv7"
+
+#### Keys ignored in scope 111:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:QT_ARCH___equals___x86_64:
+# MYSCRIPT_ENGINE_PATH = "engine/bin/lin-x64"
+# MYSCRIPT_VOIM_PATH = "voim/bin/lin-x64"
+
+#### Keys ignored in scope 113:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:QT_ARCH___equals___x86 OR QT_ARCH___equals___i386:
+# MYSCRIPT_ENGINE_PATH = "engine/bin/lin-x86"
+# MYSCRIPT_VOIM_PATH = "voim/bin/lin-x86"
+
+#### Keys ignored in scope 114:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:else:
+# MYSCRIPT_ENGINE_PATH = "engine/bin/lin-$$QT_ARCH"
+# MYSCRIPT_VOIM_PATH = "voim/bin/lin-$$QT_ARCH"
+
+#### Keys ignored in scope 116:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:WIN32 OR win64:
+# MYSCRIPT_LIB_PREFIX = ""
+# MYSCRIPT_LIB_SUFFIX = ".dll"
+# MYSCRIPT_VOIM_LIB_NAME = "voim.lib"
+# MYSCRIPT_VOIM_LIB_PATH = "$$MYSCRIPT_PATH/voim/api/c/lib/$$MYSCRIPT_VOIM_LIB_NAME"
+
+#### Keys ignored in scope 117:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:QT_ARCH___equals___x86_64:
+# MYSCRIPT_ENGINE_PATH = "engine/bin/win-x64"
+# MYSCRIPT_VOIM_PATH = "voim/bin/win-x64"
+
+#### Keys ignored in scope 118:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:else:
+# MYSCRIPT_ENGINE_PATH = "engine/bin/win-x86"
+# MYSCRIPT_VOIM_PATH = "voim/bin/win-x86"
+
+#### Keys ignored in scope 120:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:EXISTS _ss_MYSCRIPT_VOIM_LIB_PATH:
+# MYSCRIPT_FOUND = "1"
+
+#### Keys ignored in scope 122:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:MYSCRIPT_PATH_ISEMPTY:
+# MYSCRIPT_PATH = "$$PWD"
+
+#### Keys ignored in scope 123:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:UNIX AND LINUX AND NOT ANDROID:
+# MYSCRIPT_LIB_PREFIX = "lib"
+# MYSCRIPT_LIB_SUFFIX = ".so"
+# MYSCRIPT_VOIM_LIB_NAME = "libvoim.so"
+# MYSCRIPT_VOIM_LIB_PATH = "$$MYSCRIPT_PATH/$$MYSCRIPT_VOIM_PATH/$$MYSCRIPT_VOIM_LIB_NAME"
+
+#### Keys ignored in scope 124:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:QT_ARCH___equals___arm64:
+# MYSCRIPT_ENGINE_PATH = "engine/bin/lin-arm64"
+# MYSCRIPT_VOIM_PATH = "voim/bin/lin-arm64"
+
+#### Keys ignored in scope 126:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:QT_ARCH___equals___arm:
+# MYSCRIPT_ENGINE_PATH = "engine/bin/lin-armv7"
+# MYSCRIPT_VOIM_PATH = "voim/bin/lin-armv7"
+
+#### Keys ignored in scope 128:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:QT_ARCH___equals___x86_64:
+# MYSCRIPT_ENGINE_PATH = "engine/bin/lin-x64"
+# MYSCRIPT_VOIM_PATH = "voim/bin/lin-x64"
+
+#### Keys ignored in scope 130:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:QT_ARCH___equals___x86 OR QT_ARCH___equals___i386:
+# MYSCRIPT_ENGINE_PATH = "engine/bin/lin-x86"
+# MYSCRIPT_VOIM_PATH = "voim/bin/lin-x86"
+
+#### Keys ignored in scope 131:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:else:
+# MYSCRIPT_ENGINE_PATH = "engine/bin/lin-$$QT_ARCH"
+# MYSCRIPT_VOIM_PATH = "voim/bin/lin-$$QT_ARCH"
+
+#### Keys ignored in scope 133:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:WIN32 OR win64:
+# MYSCRIPT_LIB_PREFIX = ""
+# MYSCRIPT_LIB_SUFFIX = ".dll"
+# MYSCRIPT_VOIM_LIB_NAME = "voim.lib"
+# MYSCRIPT_VOIM_LIB_PATH = "$$MYSCRIPT_PATH/voim/api/c/lib/$$MYSCRIPT_VOIM_LIB_NAME"
+
+#### Keys ignored in scope 134:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:QT_ARCH___equals___x86_64:
+# MYSCRIPT_ENGINE_PATH = "engine/bin/win-x64"
+# MYSCRIPT_VOIM_PATH = "voim/bin/win-x64"
+
+#### Keys ignored in scope 135:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:else:
+# MYSCRIPT_ENGINE_PATH = "engine/bin/win-x86"
+# MYSCRIPT_VOIM_PATH = "voim/bin/win-x86"
+
+#### Keys ignored in scope 137:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:EXISTS _ss_MYSCRIPT_VOIM_LIB_PATH:
+# MYSCRIPT_FOUND = "1"
+
+#### Keys ignored in scope 139:.:../../../../plugins/cerence:../../../../plugins/cerence/cerence.pri:CERENCE_SDK_ROOT_ISEMPTY:
+# EXT_CERENCE_SDK_ROOT = "$$(CERENCE_SDK_ROOT)"
+
+#### Keys ignored in scope 140:.:../../../../plugins/cerence:../../../../plugins/cerence/cerence.pri:NOT EXT_CERENCE_SDK_ROOT_ISEMPTY:
+# CERENCE_SDK_ROOT = "$$EXT_CERENCE_SDK_ROOT"
+
+#### Keys ignored in scope 142:.:../../../../plugins/cerence:../../../../plugins/cerence/cerence.pri:CERENCE_SDK_ROOT_ISEMPTY:
+# CERENCE_SDK_ROOT = "$$PWD/sdk"
+
+#### Keys ignored in scope 145:.:../../../../plugins/cerence:../../../../plugins/cerence/cerence.pri:QT_ARCH___equals___arm:
+# CERENCE_SHARED_LIB_PATH = "lib/linux/arm/shared"
+# CERENCE_STATIC_LIB_PATH = "lib/linux/arm/static"
+
+#### Keys ignored in scope 147:.:../../../../plugins/cerence:../../../../plugins/cerence/cerence.pri:QT_ARCH___equals___arm64:
+# CERENCE_SHARED_LIB_PATH = "lib/linux/arm64/shared"
+# CERENCE_STATIC_LIB_PATH = "lib/linux/arm64/static"
+
+#### Keys ignored in scope 149:.:../../../../plugins/cerence:../../../../plugins/cerence/cerence.pri:QT_ARCH___equals___x86_64:
+# CERENCE_SHARED_LIB_PATH = "lib/linux/x86_64/shared"
+# CERENCE_STATIC_LIB_PATH = "lib/linux/x86_64/static"
+
+#### Keys ignored in scope 151:.:../../../../plugins/cerence:../../../../plugins/cerence/cerence.pri:QT_ARCH___equals___x86 OR QT_ARCH___equals___i386:
+# CERENCE_SHARED_LIB_PATH = "lib/linux/x86/shared"
+# CERENCE_STATIC_LIB_PATH = "lib/linux/x86/static"
+
+#### Keys ignored in scope 154:.:../../../../plugins/cerence:../../../../plugins/cerence/cerence.pri:QT_ARCH___equals___x86_64:
+# CERENCE_SHARED_LIB_PATH = "lib/win32/x86_64/shared"
+# CERENCE_STATIC_LIB_PATH = "lib/win32/x86_64/static"
+
+#### Keys ignored in scope 155:.:../../../../plugins/cerence:../../../../plugins/cerence/cerence.pri:else:
+# CERENCE_SHARED_LIB_PATH = "lib/win32/x86/shared"
+# CERENCE_STATIC_LIB_PATH = "lib/win32/x86/static"
+
+#### Keys ignored in scope 157:.:../../../../plugins/cerence:../../../../plugins/cerence/cerence.pri:WIN32:
+# result = "$$1/*.obj"
+
+#### Keys ignored in scope 158:.:../../../../plugins/cerence:../../../../plugins/cerence/cerence.pri:result_ISEMPTY:
+# result = "$$1/*.lib"
+
+#### Keys ignored in scope 159:.:../../../../plugins/cerence:../../../../plugins/cerence/cerence.pri:else:
+# result = "$$1/*.o"
+
+#### Keys ignored in scope 160:.:../../../../plugins/cerence:../../../../plugins/cerence/cerence.pri:result_ISEMPTY:
+# result = "$$1/*.a"
+
+#### Keys ignored in scope 162:.:../../../../plugins/cerence:../../../../plugins/cerence/cerence.pri:WIN32:
+# result = "$$1/*.lib"
+
+#### Keys ignored in scope 163:.:../../../../plugins/cerence:../../../../plugins/cerence/cerence.pri:else:
+# result = "$$1/*.so"
+
+#### Keys ignored in scope 165:.:../../../../plugins/cerence:../../../../plugins/cerence/cerence.pri:WIN32:
+# result = "$$1/*.dll"
+
+#### Keys ignored in scope 166:.:../../../../plugins/cerence:../../../../plugins/cerence/cerence.pri:else:
+# result = "$$1/*.so"
+
+#### Keys ignored in scope 167:.:../../../../plugins/cerence:../../../../plugins/cerence/cerence.pri:EXISTS _ss_CERENCE_HWR_INCLUDEPATH/decuma_hwr.h:
+# CERENCE_HWR_ALPHABETIC_FOUND = "1"
+
+#### Keys ignored in scope 168:.:../../../../plugins/cerence:../../../../plugins/cerence/cerence.pri:EXISTS _ss_CERENCE_HWR_INCLUDEPATH/decuma_hwr_cjk.h:
+# CERENCE_HWR_CJK_FOUND = "1"
+
+#### Keys ignored in scope 171:.:../../../../plugins/cerence:../../../../plugins/cerence/cerence.pri:NOT cerence-hwr-static:
+# CERENCE_HWR_ALPHABETIC_LIBS = "$$findSharedLibrary($$CERENCE_SDK_ROOT/t9write/$$CERENCE_SHARED_LIB_PATH/alphabetic)"
+
+#### Keys ignored in scope 172:.:../../../../plugins/cerence:../../../../plugins/cerence/cerence.pri:NOT CERENCE_HWR_ALPHABETIC_LIBS_ISEMPTY:
+# CERENCE_HWR_ALPHABETIC_BINS = "$$findSharedBinary($$CERENCE_SDK_ROOT/t9write/$$CERENCE_SHARED_LIB_PATH/alphabetic)"
+
+#### Keys ignored in scope 173:.:../../../../plugins/cerence:../../../../plugins/cerence/cerence.pri:else:
+# CERENCE_HWR_ALPHABETIC_LIBS = "$$findStaticLibrary($$CERENCE_SDK_ROOT/t9write/$$CERENCE_STATIC_LIB_PATH/alphabetic)"
+
+#### Keys ignored in scope 175:.:../../../../plugins/cerence:../../../../plugins/cerence/cerence.pri:NOT cerence-hwr-static:
+# CERENCE_HWR_CJK_LIBS = "$$findSharedLibrary($$CERENCE_SDK_ROOT/t9write/$$CERENCE_SHARED_LIB_PATH/cjk)"
+
+#### Keys ignored in scope 176:.:../../../../plugins/cerence:../../../../plugins/cerence/cerence.pri:NOT CERENCE_HWR_CJK_LIBS_ISEMPTY:
+# CERENCE_HWR_CJK_BINS = "$$findSharedBinary($$CERENCE_SDK_ROOT/t9write/$$CERENCE_SHARED_LIB_PATH/cjk)"
+
+#### Keys ignored in scope 177:.:../../../../plugins/cerence:../../../../plugins/cerence/cerence.pri:else:
+# CERENCE_HWR_CJK_LIBS = "$$findStaticLibrary($$CERENCE_SDK_ROOT/t9write/$$CERENCE_STATIC_LIB_PATH/cjk)"
+
+#### Keys ignored in scope 178:.:../../../../plugins/cerence:../../../../plugins/cerence/cerence.pri:(CERENCE_HWR_ALPHABETIC_FOUND EQUAL 1) AND NOT CERENCE_HWR_ALPHABETIC_LIBS_ISEMPTY:
+# CERENCE_HWR_FOUND = "1"
+
+#### Keys ignored in scope 179:.:../../../../plugins/cerence:../../../../plugins/cerence/cerence.pri:(CERENCE_HWR_CJK_FOUND EQUAL 1) AND NOT CERENCE_HWR_CJK_LIBS_ISEMPTY:
+# CERENCE_HWR_FOUND = "1"
+
+#### Keys ignored in scope 180:.:../../../../plugins/cerence:../../../../plugins/cerence/cerence.pri:EXISTS _ss_XT9_INCLUDEPATH/et9api.h:
+# XT9_FOUND = "1"
+
+#### Keys ignored in scope 182:.:../../../../plugins/cerence:../../../../plugins/cerence/cerence.pri:NOT QT_FEATURE_xt9_static:
+# XT9_LIBS = "$$findSharedLibrary($$CERENCE_SDK_ROOT/xt9/$$CERENCE_SHARED_LIB_PATH)"
+
+#### Keys ignored in scope 183:.:../../../../plugins/cerence:../../../../plugins/cerence/cerence.pri:NOT XT9_LIBS_ISEMPTY:
+# XT9_BINS = "$$findSharedBinary($$CERENCE_SDK_ROOT/xt9/$$CERENCE_SHARED_LIB_PATH)"
+
+#### Keys ignored in scope 184:.:../../../../plugins/cerence:../../../../plugins/cerence/cerence.pri:else:
+# XT9_LIBS = "$$findStaticLibrary($$CERENCE_SDK_ROOT/xt9/$$CERENCE_STATIC_LIB_PATH)"
diff --git a/src/plugins/t9write/plugin/t9write.json b/src/plugins/cerence/cerence-hwr/plugin/cerence_hwr.json
index ac71f7cc..d0970d3a 100644
--- a/src/plugins/t9write/plugin/t9write.json
+++ b/src/plugins/cerence/cerence-hwr/plugin/cerence_hwr.json
@@ -1,6 +1,6 @@
{
"Name": "handwriting",
- "Provider": "Qt T9 Write Extension",
+ "Provider": "Qt Cerence Handwriting Extension",
"InputMethod": "HandwritingInputMethod",
"Version": 200
}
diff --git a/src/plugins/t9write/plugin/t9write_p.h b/src/plugins/cerence/cerence-hwr/plugin/cerence_hwr_p.h
index 5e85b19c..935b3007 100644
--- a/src/plugins/t9write/plugin/t9write_p.h
+++ b/src/plugins/cerence/cerence-hwr/plugin/cerence_hwr_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
@@ -27,8 +27,8 @@
**
****************************************************************************/
-#ifndef T9WRITE_P_H
-#define T9WRITE_P_H
+#ifndef CERENCE_HWR_P_H
+#define CERENCE_HWR_P_H
//
// W A R N I N G
@@ -43,21 +43,20 @@
#include <QtVirtualKeyboard/private/qvirtualkeyboard_global_p.h>
-#include "t9write_api_version.h"
-#if QT_CONFIG(t9write_alphabetic)
+#include "cerence_handwriting_api_version.h"
+#if QT_CONFIG(cerence_hwr_alphabetic)
#include "decuma_hwr.h"
#endif
-#if QT_CONFIG(t9write_cjk)
+#if QT_CONFIG(cerence_hwr_cjk)
#include "decuma_hwr_cjk.h"
#endif
-#include "decumaFunctionalSupport.h"
-#if defined(HAVE_T9WRITE_CJK) && defined(HAVE_T9WRITE_ALPHABETIC)
-#define DECUMA_API(FUNC_NAME) (cjk ? decumaCJK ## FUNC_NAME : decuma ## FUNC_NAME)
-#elif defined(HAVE_T9WRITE_CJK)
+#if QT_CONFIG(cerence_hwr_cjk) && QT_CONFIG(cerence_hwr_alphabetic)
+#define DECUMA_API(FUNC_NAME) (cjk ? decumaCJK ## FUNC_NAME : decumaUcr ## FUNC_NAME)
+#elif QT_CONFIG(cerence_hwr_cjk)
#define DECUMA_API(FUNC_NAME) (decumaCJK ## FUNC_NAME)
-#else // defined(HAVE_T9WRITE_ALPHABETIC)
-#define DECUMA_API(FUNC_NAME) (decuma ## FUNC_NAME)
+#else // QT_CONFIG(cerence_hwr_alphabetic)
+#define DECUMA_API(FUNC_NAME) (decumaUcr ## FUNC_NAME)
#endif
-#endif // T9WRITE_P_H
+#endif // CERENCE_HWR_P_H
diff --git a/src/plugins/cerence/cerence-hwr/plugin/content/layouts/zh_HK/handwriting.qml b/src/plugins/cerence/cerence-hwr/plugin/content/layouts/zh_HK/handwriting.qml
new file mode 100644
index 00000000..7650b026
--- /dev/null
+++ b/src/plugins/cerence/cerence-hwr/plugin/content/layouts/zh_HK/handwriting.qml
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick
+import QtQuick.Layouts
+import QtQuick.VirtualKeyboard
+
+KeyboardLayout {
+ function createInputMethod() {
+ return Qt.createQmlObject('import QtQuick; import QtQuick.VirtualKeyboard.Plugins; HandwritingInputMethod {}', parent)
+ }
+ sharedLayouts: ['symbols']
+ inputMode: preferredInputMode()
+
+ Connections {
+ target: InputContext
+ function onInputMethodHintsChanged() {
+ var newInputMode = preferredInputMode()
+ if (InputContext.inputEngine.inputModes.indexOf(newInputMode) !== -1)
+ InputContext.inputEngine.inputMode = newInputMode
+ }
+ }
+
+ function preferredInputMode() {
+ return InputContext.inputMethodHints &
+ (Qt.ImhPreferLatin | Qt.ImhEmailCharactersOnly | Qt.ImhUrlCharactersOnly |
+ Qt.ImhLatinOnly) ? InputEngine.InputMode.Latin : InputEngine.InputMode.ChineseHandwriting
+ }
+
+ KeyboardRow {
+ Layout.preferredHeight: 3
+ TraceInputKey {
+ objectName: "hwrInputArea"
+ patternRecognitionMode: InputEngine.PatternRecognitionMode.Handwriting
+ horizontalRulers:
+ InputContext.inputEngine.inputMode !== InputEngine.InputMode.ChineseHandwriting ? [] :
+ [Math.round(boundingBox.height / 4), Math.round(boundingBox.height / 4) * 2, Math.round(boundingBox.height / 4) * 3]
+ }
+ }
+ KeyboardRow {
+ id: bottomRow
+ Layout.preferredHeight: 1
+ keyWeight: 160
+ ShiftKey {
+ weight: 240
+ }
+ InputModeKey {
+ }
+ Key {
+ key: Qt.Key_Comma
+ text: "、"
+ smallText: "\u2699"
+ smallTextVisible: true
+ highlighted: true
+ }
+ SpaceKey {
+ weight: 10 * 160 - 4 * 160 - 2 * 240
+ }
+ Key {
+ key: Qt.Key_Period
+ text: "。"
+ alternativeKeys: "¥‘’“”~…—《》〈〉「」\",.:;。?!"
+ smallText: "!?"
+ smallTextVisible: true
+ highlighted: true
+ }
+ BackspaceKey {
+ }
+ EnterKey {
+ weight: 240
+ }
+ }
+}
diff --git a/src/plugins/t9write/plugin/t9writeplugin.cpp b/src/plugins/cerence/cerence-hwr/plugin/qtvirtualkeyboardcerencehwrplugin.cpp
index 25c1366f..6189b6ac 100644
--- a/src/plugins/t9write/plugin/t9writeplugin.cpp
+++ b/src/plugins/cerence/cerence-hwr/plugin/qtvirtualkeyboardcerencehwrplugin.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
@@ -27,7 +27,7 @@
**
****************************************************************************/
-#include "t9writeplugin.h"
+#include "qtvirtualkeyboardcerencehwrplugin.h"
#include "t9writeinputmethod_p.h"
#include <QtQml>
@@ -35,9 +35,12 @@ QT_BEGIN_NAMESPACE
using namespace QtVirtualKeyboard;
-void QtVirtualKeyboardT9WritePlugin::registerTypes(const char *uri) const
+void QtVirtualKeyboardCerenceHwrPlugin::registerTypes(const char *uri) const
{
- Q_INIT_RESOURCE(qmake_t9write_db);
+#ifdef HAVE_CERENCE_HWR_RESOURCE
+ Q_INIT_RESOURCE(qmake_cerencecommondata_db);
+ Q_INIT_RESOURCE(qmake_cerencehwrdata_db);
+#endif
qmlRegisterType<T9WriteInputMethod>(uri, 2, 0, "HandwritingInputMethod");
}
diff --git a/src/plugins/cerence/cerence-hwr/plugin/qtvirtualkeyboardcerencehwrplugin.h b/src/plugins/cerence/cerence-hwr/plugin/qtvirtualkeyboardcerencehwrplugin.h
new file mode 100644
index 00000000..61fc9870
--- /dev/null
+++ b/src/plugins/cerence/cerence-hwr/plugin/qtvirtualkeyboardcerencehwrplugin.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTVIRTUALKEYBOARDCERENCEHWRPLUGIN_H
+#define QTVIRTUALKEYBOARDCERENCEHWRPLUGIN_H
+
+#include <QVirtualKeyboardExtensionPlugin>
+
+QT_BEGIN_NAMESPACE
+
+class QtVirtualKeyboardCerenceHwrPlugin : public QVirtualKeyboardExtensionPlugin
+{
+ Q_OBJECT
+ Q_INTERFACES(QVirtualKeyboardExtensionPlugin)
+ Q_PLUGIN_METADATA(IID QVirtualKeyboardExtensionPluginFactoryInterface_iid
+ FILE "cerence_hwr.json")
+public:
+ void registerTypes(const char *uri) const;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/t9write/plugin/t9writedictionary_p.h b/src/plugins/cerence/cerence-hwr/plugin/t9writeabstractdictionary_p.h
index d728a583..f25c8352 100644
--- a/src/plugins/t9write/plugin/t9writedictionary_p.h
+++ b/src/plugins/cerence/cerence-hwr/plugin/t9writeabstractdictionary_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
@@ -27,8 +27,8 @@
**
****************************************************************************/
-#ifndef T9WRITEDICTIONARY_P_H
-#define T9WRITEDICTIONARY_P_H
+#ifndef T9WRITEABSTRACTDICTIONARY_P_H
+#define T9WRITEABSTRACTDICTIONARY_P_H
//
// W A R N I N G
@@ -42,39 +42,35 @@
//
#include <QtGlobal>
-#include <QFile>
-#include "t9write_p.h"
QT_BEGIN_NAMESPACE
namespace QtVirtualKeyboard {
-class T9WriteDictionary
+class T9WriteAbstractDictionary
{
- Q_DISABLE_COPY(T9WriteDictionary)
-public:
- explicit T9WriteDictionary(DECUMA_SESSION *decumaSession, const DECUMA_MEM_FUNCTIONS &memFuncs, bool cjk);
- ~T9WriteDictionary();
+ Q_DISABLE_COPY(T9WriteAbstractDictionary)
+
+protected:
+ T9WriteAbstractDictionary() {}
- bool load(const QString &fileName);
- bool convert(const DECUMA_SRC_DICTIONARY_INFO &dictionaryInfo);
+public:
+ virtual ~T9WriteAbstractDictionary() {}
- QString fileName() const;
- const void *data() const;
- qint64 size() const;
- bool isConverted() const;
+ virtual bool load() = 0;
+ virtual bool create(qint64 createSize) { Q_UNUSED(createSize) return false; }
+ virtual void close() {}
+ virtual bool convert() { return false; }
+ virtual QString name() const = 0;
+ virtual const void *data() const = 0;
+ virtual qint64 size() const = 0;
+ bool isCompleted() const { return state > 0; }
private:
- QFile file;
- DECUMA_SESSION *decumaSession;
- const DECUMA_MEM_FUNCTIONS &memFuncs;
- bool cjk;
- void *sourceData;
- qint64 sourceSize;
- void *convertedData;
- DECUMA_UINT32 convertedSize;
+ friend class T9WriteDictionaryTask;
+ QAtomicInt state;
};
} // namespace QtVirtualKeyboard
QT_END_NAMESPACE
-#endif // T9WRITEDICTIONARY_P_H
+#endif // T9WRITEABSTRACTDICTIONARY_P_H
diff --git a/src/plugins/cerence/cerence-hwr/plugin/t9writedictionary.cpp b/src/plugins/cerence/cerence-hwr/plugin/t9writedictionary.cpp
new file mode 100644
index 00000000..59c89b45
--- /dev/null
+++ b/src/plugins/cerence/cerence-hwr/plugin/t9writedictionary.cpp
@@ -0,0 +1,307 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "t9writedictionary_p.h"
+#include <QLoggingCategory>
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+Q_DECLARE_LOGGING_CATEGORY(lcT9Write)
+
+// T9WriteAbstractSource
+
+T9WriteAbstractSource::T9WriteAbstractSource(const DECUMA_SRC_DICTIONARY_INFO &info) :
+ _info(info)
+{
+}
+
+T9WriteAbstractSource::~T9WriteAbstractSource()
+{
+}
+
+const DECUMA_SRC_DICTIONARY_INFO *T9WriteAbstractSource::info() const
+{
+ return &_info;
+}
+
+// T9WriteFileSource
+
+T9WriteFileSource::T9WriteFileSource(const DECUMA_SRC_DICTIONARY_INFO &info, const QString &fileName) :
+ T9WriteAbstractSource(info),
+ file(fileName),
+ _data(nullptr),
+ _size(0)
+{
+}
+
+bool T9WriteFileSource::load()
+{
+ if (!_data) {
+ if (file.open(QIODevice::ReadOnly)) {
+ _size = file.size();
+ _data = file.map(0, _size, QFile::NoOptions);
+ if (!_data) {
+ _size = 0;
+ qCWarning(lcT9Write) << "Could not read dictionary file" << file.fileName();
+ }
+ file.close();
+ }
+ }
+
+ return _data != nullptr;
+}
+
+bool T9WriteFileSource::create(qint64 createSize)
+{
+ close();
+
+ if (file.open(QIODevice::ReadWrite)) {
+ if (file.resize(createSize)) {
+ _size = file.size();
+ _data = file.map(0, _size, QFile::NoOptions);
+ if (!_data) {
+ _size = 0;
+ qCWarning(lcT9Write) << "Could not read dictionary file" << file.fileName();
+ }
+ } else {
+ qCWarning(lcT9Write) << "Could not resize dictionary file" << file.fileName();
+ }
+ file.close();
+ }
+
+ return _data != nullptr;
+}
+
+void T9WriteFileSource::close()
+{
+ if (_data) {
+ file.unmap(static_cast<uchar *>(_data));
+ _data = nullptr;
+ _size = 0;
+ }
+}
+
+QString T9WriteFileSource::name() const
+{
+ return file.fileName();
+}
+
+const void *T9WriteFileSource::data() const
+{
+ return _data;
+}
+
+qint64 T9WriteFileSource::size() const
+{
+ return _size;
+}
+
+// T9WriteStringSource
+
+T9WriteStringSource::T9WriteStringSource(const DECUMA_SRC_DICTIONARY_INFO &info, const QStringList &source, const QString &name) :
+ T9WriteAbstractSource(info),
+ source(source),
+ _name(name)
+{
+}
+
+bool T9WriteStringSource::load()
+{
+ _data = source.join(QLatin1Char('\r'));
+ return true;
+}
+
+QString T9WriteStringSource::name() const
+{
+ return _name;
+}
+
+const void *T9WriteStringSource::data() const
+{
+ return _data.utf16();
+}
+
+qint64 T9WriteStringSource::size() const
+{
+ return _data.size();
+}
+
+// T9WriteDictionary
+
+T9WriteDictionary::T9WriteDictionary(QSharedPointer<T9WriteAbstractSource> source,
+ DECUMA_SESSION *decumaSession,
+ const DECUMA_MEM_FUNCTIONS &memFuncs,
+ bool cjk) :
+ source(source),
+ decumaSession(decumaSession),
+ memFuncs(memFuncs),
+ cjk(cjk),
+ convertedData(nullptr),
+ convertedSize(0)
+{
+}
+
+T9WriteDictionary::~T9WriteDictionary()
+{
+ if (convertedData) {
+ DECUMA_STATUS status = DECUMA_API(DestroyConvertedDictionary)(&convertedData, &memFuncs);
+ Q_ASSERT(status == decumaNoError);
+ Q_ASSERT(convertedData == nullptr);
+ }
+}
+
+bool T9WriteDictionary::load()
+{
+ return source->load();
+}
+
+bool T9WriteDictionary::convert()
+{
+ if (!source->data() || convertedData)
+ return false;
+
+ DECUMA_STATUS status;
+ status = DECUMA_API(ConvertDictionary)(&convertedData, source->data(), static_cast<DECUMA_UINT32>(source->size()),
+ source->info(), &convertedSize, &memFuncs);
+
+ if (status != decumaNoError) {
+ qCWarning(lcT9Write) << "Could not convert dictionary";
+ }
+
+ return status == decumaNoError;
+}
+
+QString T9WriteDictionary::name() const
+{
+ return source->name();
+}
+
+const void *T9WriteDictionary::data() const
+{
+ return convertedData ? convertedData : source->data();
+}
+
+qint64 T9WriteDictionary::size() const
+{
+ return convertedData ? convertedSize : source->size();
+}
+
+T9WriteDynamicDictionary::T9WriteDynamicDictionary(QSharedPointer<T9WriteAbstractSource> source, int maxWords, const DECUMA_MEM_FUNCTIONS &memFuncs, bool cjk) :
+ source(source),
+ memFuncs(memFuncs),
+ cjk(cjk),
+ _data(nullptr)
+{
+ DECUMA_API(DynamicDictionaryCreate)(&_data, static_cast<DECUMA_UINT32>(maxWords), &memFuncs);
+}
+
+T9WriteDynamicDictionary::~T9WriteDynamicDictionary()
+{
+ if (_data) {
+ DECUMA_API(DynamicDictionaryDestroy)(&_data);
+ }
+}
+
+bool T9WriteDynamicDictionary::load()
+{
+ if (!_data)
+ return false;
+
+ DECUMA_STATUS status;
+ DECUMA_UINT32 nUnprocessedSize = 0;
+ if (source->load()) {
+ status = DECUMA_API(DynamicDictionaryAddWords)(_data, source->data(), static_cast<DECUMA_UINT32>(source->size()), &nUnprocessedSize);
+ if (status) {
+ qCWarning(lcT9Write) << "Could not load words to dynamic dictionary, error" << status;
+ }
+ source->close();
+ }
+
+ return true;
+}
+
+QString T9WriteDynamicDictionary::name() const
+{
+ return source->name();
+}
+
+const void *T9WriteDynamicDictionary::data() const
+{
+ return _data;
+}
+
+qint64 T9WriteDynamicDictionary::size() const
+{
+ return 0;
+}
+
+qint64 T9WriteDynamicDictionary::bufferSize() const
+{
+ DECUMA_UINT32 result = 0;
+ if (_data)
+ DECUMA_API(DynamicDictionaryGetWordsBufferSize)(_data, &result);
+ return result;
+}
+
+void T9WriteDynamicDictionary::save()
+{
+ if (_data) {
+ DECUMA_UINT32 nWordsWritten = 0;
+ DECUMA_UINT32 nBytesWritten = 0;
+ qint64 fileSize = bufferSize();
+ if (source->create(fileSize)) {
+ DECUMA_STATUS status = DECUMA_API(DynamicDictionaryGetWords)(_data, const_cast<void *>(source->data()), static_cast<DECUMA_UINT32>(fileSize), &nWordsWritten, &nBytesWritten);
+ source->close();
+ }
+ }
+}
+
+bool T9WriteDynamicDictionary::hasWord(const QString &word)
+{
+ if (!_data)
+ return false;
+
+ int found = 0;
+ DECUMA_API(DynamicDictionaryHasWord)(_data, word.utf16(), &found);
+
+ return found != 0;
+}
+
+bool T9WriteDynamicDictionary::removeWord(const QString &word)
+{
+ DECUMA_STATUS status;
+
+ status = DECUMA_API(DynamicDictionaryDeleteWord)(_data, word.utf16());
+
+ return !status;
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
diff --git a/src/plugins/cerence/cerence-hwr/plugin/t9writedictionary_p.h b/src/plugins/cerence/cerence-hwr/plugin/t9writedictionary_p.h
new file mode 100644
index 00000000..e4be1c33
--- /dev/null
+++ b/src/plugins/cerence/cerence-hwr/plugin/t9writedictionary_p.h
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef T9WRITEDICTIONARY_P_H
+#define T9WRITEDICTIONARY_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "t9writeabstractdictionary_p.h"
+#include <QFile>
+#include <QSharedPointer>
+#include "cerence_hwr_p.h"
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+class T9WriteAbstractSource : public T9WriteAbstractDictionary
+{
+public:
+ T9WriteAbstractSource(const DECUMA_SRC_DICTIONARY_INFO &info);
+ virtual ~T9WriteAbstractSource();
+
+ const DECUMA_SRC_DICTIONARY_INFO *info() const;
+
+private:
+ const DECUMA_SRC_DICTIONARY_INFO _info;
+};
+
+class T9WriteFileSource : public T9WriteAbstractSource
+{
+public:
+ T9WriteFileSource(const DECUMA_SRC_DICTIONARY_INFO &info, const QString &fileName);
+
+ bool load() override;
+ bool create(qint64 createSize) override;
+ void close() override;
+
+ QString name() const override;
+ const void *data() const override;
+ qint64 size() const override;
+
+private:
+ QFile file;
+ void *_data;
+ qint64 _size;
+};
+
+class T9WriteStringSource : public T9WriteAbstractSource
+{
+public:
+ T9WriteStringSource(const DECUMA_SRC_DICTIONARY_INFO &info, const QStringList &source, const QString &name);
+
+ bool load() override;
+ QString name() const override;
+ const void *data() const override;
+ qint64 size() const override;
+
+private:
+ QStringList source;
+ QString _data;
+ QString _name;
+};
+
+class T9WriteDictionary : public T9WriteAbstractDictionary
+{
+ Q_DISABLE_COPY(T9WriteDictionary)
+public:
+ explicit T9WriteDictionary(QSharedPointer<T9WriteAbstractSource> source, DECUMA_SESSION *decumaSession, const DECUMA_MEM_FUNCTIONS &memFuncs, bool cjk);
+ ~T9WriteDictionary() override;
+
+ bool load() override;
+ bool convert() override;
+ QString name() const override;
+ const void *data() const override;
+ qint64 size() const override;
+
+private:
+ QSharedPointer<T9WriteAbstractSource> source;
+ DECUMA_SESSION *decumaSession;
+ const DECUMA_MEM_FUNCTIONS &memFuncs;
+ bool cjk;
+ void *convertedData;
+ DECUMA_UINT32 convertedSize;
+};
+
+class T9WriteDynamicDictionary : public T9WriteAbstractDictionary
+{
+ Q_DISABLE_COPY(T9WriteDynamicDictionary)
+public:
+ explicit T9WriteDynamicDictionary(QSharedPointer<T9WriteAbstractSource> source, int maxWords, const DECUMA_MEM_FUNCTIONS &memFuncs, bool cjk);
+ ~T9WriteDynamicDictionary() override;
+
+ bool load() override;
+ QString name() const override;
+ const void *data() const override;
+ qint64 size() const override;
+ qint64 bufferSize() const;
+
+ void save();
+ bool hasWord(const QString &word);
+ bool removeWord(const QString &word);
+
+private:
+ QSharedPointer<T9WriteAbstractSource> source;
+ const DECUMA_MEM_FUNCTIONS &memFuncs;
+ const bool cjk;
+ DECUMA_DYNAMIC_DICTIONARY *_data;
+};
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
+
+#endif // T9WRITEDICTIONARY_P_H
diff --git a/src/plugins/t9write/plugin/t9writeinputmethod.cpp b/src/plugins/cerence/cerence-hwr/plugin/t9writeinputmethod.cpp
index 2989de8d..30712410 100644
--- a/src/plugins/t9write/plugin/t9writeinputmethod.cpp
+++ b/src/plugins/cerence/cerence-hwr/plugin/t9writeinputmethod.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
@@ -37,16 +37,31 @@
#include <QCryptographicHash>
#include <QTime>
#include <QMetaEnum>
+#include <QtCore/QLibraryInfo>
+#include <QtVirtualKeyboard/private/settings_p.h>
#include <QtVirtualKeyboard/private/handwritinggesturerecognizer_p.h>
+#include <QtVirtualKeyboard/private/qvirtualkeyboardabstractinputmethod_p.h>
#ifdef QT_VIRTUALKEYBOARD_RECORD_TRACE_INPUT
#include <QtVirtualKeyboard/private/unipentrace_p.h>
#include <QStandardPaths>
#endif
+#include <QtVirtualKeyboard/qvirtualkeyboarddictionary.h>
+#include <QtVirtualKeyboard/qvirtualkeyboarddictionarymanager.h>
#include "decumaStatus.h"
#include "decumaSymbolCategories.h"
#include "decumaLanguages.h"
-#include "xxt9wOem.h"
+#include "xxchOem.h"
+#include "xt9ldbmanager.h"
+#include "t9writewordcandidate_p.h"
+#ifdef HAVE_XT9
+#include <xt9awime.h>
+#include <xt9cpime.h>
+#include <xt9jime.h>
+#include <xt9kime.h>
+#include <xt9callbacks.h>
+#include <xt9languagemap.h>
+#endif
/* Set to 1 to enable T9 Write log.
@@ -54,12 +69,14 @@
and when reporting issues. The log must not to be enabled in production
build.
*/
-#define QT_VIRTUALKEYBOARD_T9WRITE_LOG 0
+#define QT_VIRTUALKEYBOARD_CERENCE_HWR_LOG 0
+
+#define CERENCE_HWR_DLM_MAX_WORDS 10000
QT_BEGIN_NAMESPACE
namespace QtVirtualKeyboard {
-Q_LOGGING_CATEGORY(lcT9Write, "qt.virtualkeyboard.t9write")
+Q_LOGGING_CATEGORY(lcT9Write, "qt.virtualkeyboard.cerence-hwr")
class T9WriteCaseFormatter
{
@@ -104,18 +121,21 @@ private:
QList<QVirtualKeyboardInputEngine::TextCase> textCaseList;
};
-class T9WriteInputMethodPrivate
+class T9WriteInputMethodPrivate : public QVirtualKeyboardAbstractInputMethodPrivate
+#ifdef HAVE_XT9
+ , public Xt9RequestCallback
+#endif
{
Q_DECLARE_PUBLIC(T9WriteInputMethod)
public:
T9WriteInputMethodPrivate(T9WriteInputMethod *q_ptr) :
+ QVirtualKeyboardAbstractInputMethodPrivate(),
q_ptr(q_ptr),
cjk(false),
engineMode(T9WriteInputMethod::EngineMode::Uninitialized),
- defaultHwrDbPath(QLatin1String(":/QtQuick/VirtualKeyboard/T9Write/data/")),
- defaultDictionaryDbPath(defaultHwrDbPath),
traceListHardLimit(32),
attachedDictionary(nullptr),
+ ldbManager(new Xt9LdbManager()),
resultId(0),
lastResultId(0),
resultTimer(0),
@@ -128,6 +148,21 @@ public:
, unipenTrace()
#endif
{
+ const QString pathListSep(
+#if defined(Q_OS_WIN32)
+ QStringLiteral(";")
+#else
+ QStringLiteral(":")
+#endif
+ );
+ const QString userHwrDbPath(qEnvironmentVariable("QT_VIRTUALKEYBOARD_CERENCE_HWR_DB_PATH"));
+ defaultHwrDbPaths = userHwrDbPath.split(pathListSep, Qt::SkipEmptyParts)
+ << QDir(QStringLiteral("%1/qtvirtualkeyboard/cerence/handwriting/").arg(QLibraryInfo::path(QLibraryInfo::DataPath))).absolutePath()
+ << QStringLiteral(":/QtQuick/VirtualKeyboard/Cerence/Handwriting/");
+ ldbManager->setPhdEnabled(true);
+ for (const QString &searchPath : defaultHwrDbPaths) {
+ ldbManager->addSearchPath(searchPath);
+ }
}
static void *decumaMalloc(size_t size, void *pPrivate)
@@ -148,7 +183,7 @@ public:
free(ptr);
}
-#if QT_VIRTUALKEYBOARD_T9WRITE_LOG
+#if QT_VIRTUALKEYBOARD_CERENCE_HWR_LOG
static void decumaLogString(void *pUserData, const char *pLogString, DECUMA_UINT32 nLogStringLength)
{
static QMutex s_logMutex;
@@ -205,7 +240,7 @@ public:
memset(&sessionSettings, 0, sizeof(sessionSettings));
- QString hwrDb = findHwrDb(engineMode, defaultHwrDbPath);
+ QString hwrDb = findHwrDb(engineMode);
hwrDbFile.setFileName(hwrDb);
if (!hwrDbFile.open(QIODevice::ReadOnly)) {
qCCritical(lcT9Write) << "Could not open HWR database" << hwrDb;
@@ -213,7 +248,7 @@ public:
return false;
}
- sessionSettings.pStaticDB = (DECUMA_STATIC_DB_PTR)hwrDbFile.map(0, hwrDbFile.size(), QFile::NoOptions);
+ sessionSettings.pStaticDB = reinterpret_cast<DECUMA_STATIC_DB_PTR>(hwrDbFile.map(0, hwrDbFile.size(), QFile::NoOptions));
if (!sessionSettings.pStaticDB) {
qCCritical(lcT9Write) << "Could not read HWR database" << hwrDb;
exitEngine();
@@ -226,12 +261,12 @@ public:
sessionSettings.recognitionMode = mcrMode;
sessionSettings.writingDirection = unknownWriting;
sessionSettings.charSet.pSymbolCategories = symbolCategories.data();
- sessionSettings.charSet.nSymbolCategories = symbolCategories.size();
+ sessionSettings.charSet.nSymbolCategories = static_cast<DECUMA_UINT8>(symbolCategories.size());
sessionSettings.charSet.pLanguages = languageCategories.data();
- sessionSettings.charSet.nLanguages = languageCategories.size();
+ sessionSettings.charSet.nLanguages = static_cast<DECUMA_UINT8>(languageCategories.size());
- session = QByteArray(DECUMA_API(GetSessionSize)(), 0);
- decumaSession = (DECUMA_SESSION *)(!session.isEmpty() ? session.data() : nullptr);
+ session = QByteArray(static_cast<int>(DECUMA_API(GetSessionSize)()), 0);
+ decumaSession = reinterpret_cast<DECUMA_SESSION *>(!session.isEmpty() ? session.data() : nullptr);
DECUMA_STATUS status = DECUMA_API(BeginSession)(decumaSession, &sessionSettings, &memFuncs);
Q_ASSERT(status == decumaNoError);
@@ -241,7 +276,7 @@ public:
return false;
}
-#if QT_VIRTUALKEYBOARD_T9WRITE_LOG
+#if QT_VIRTUALKEYBOARD_CERENCE_HWR_LOG
DECUMA_API(StartLogging)(decumaSession, 0, decumaLogString);
#endif
@@ -249,7 +284,25 @@ public:
worker->start();
Q_Q(T9WriteInputMethod);
- processResultConnection = QObject::connect(q, &T9WriteInputMethod::resultListChanged, q, &T9WriteInputMethod::processResult, Qt::QueuedConnection);
+ availableDictionariesChangedConnection = QObjectPrivate::connect(QVirtualKeyboardDictionaryManager::instance(),
+ &QVirtualKeyboardDictionaryManager::availableDictionariesChanged,
+ this, &T9WriteInputMethodPrivate::onAvailableDynamicDictionariesChanged);
+ activeDictionariesChangedConnection = QObjectPrivate::connect(QVirtualKeyboardDictionaryManager::instance(),
+ &QVirtualKeyboardDictionaryManager::activeDictionariesChanged,
+ this, &T9WriteInputMethodPrivate::onActiveDynamicDictionariesChanged);
+
+ onAvailableDynamicDictionariesChanged();
+ onActiveDynamicDictionariesChanged();
+
+ const Qt::InputMethodHints inputMethodHints = q->inputContext()->inputMethodHints();
+ if (!inputMethodHints.testFlag(Qt::ImhHiddenText) && !inputMethodHints.testFlag(Qt::ImhNoPredictiveText) &&
+ !inputMethodHints.testFlag(Qt::ImhSensitiveData)) {
+ dlmActivate();
+ }
+
+#ifdef HAVE_XT9
+ bindSettings();
+#endif
return true;
}
@@ -258,24 +311,40 @@ public:
{
qCDebug(lcT9Write) << "T9WriteInputMethodPrivate::exitEngine()";
- if (processResultConnection)
- QObject::disconnect(processResultConnection);
+#ifdef HAVE_XT9
+ unbindSettings();
+#endif
+
+ QObject::disconnect(availableDictionariesChangedConnection);
+ QObject::disconnect(activeDictionariesChangedConnection);
worker.reset();
+#ifdef HAVE_XT9
+ xt9Exit();
+#endif
+
if (sessionSettings.pStaticDB) {
- hwrDbFile.unmap((uchar *)sessionSettings.pStaticDB);
+ hwrDbFile.unmap(const_cast<uchar *>(reinterpret_cast<const uchar *>(sessionSettings.pStaticDB)));
hwrDbFile.close();
}
+ dlmDeactivate();
+
if (attachedDictionary) {
detachDictionary(attachedDictionary);
attachedDictionary.reset();
}
loadedDictionary.reset();
+ for (auto &dynamicDictionary : attachedDynamicDictionaries) {
+ detachDictionary(dynamicDictionary);
+ }
+ attachedDynamicDictionaries.clear();
+ dynamicDictionaries.clear();
+
if (decumaSession) {
-#if QT_VIRTUALKEYBOARD_T9WRITE_LOG
+#if QT_VIRTUALKEYBOARD_CERENCE_HWR_LOG
DECUMA_API(StopLogging)(decumaSession);
#endif
DECUMA_API(EndSession)(decumaSession);
@@ -288,48 +357,311 @@ public:
symbolCategories.clear();
languageCategories.clear();
+ ldbManager->closeAll();
+
engineMode = T9WriteInputMethod::EngineMode::Uninitialized;
cjk = false;
}
+#ifdef HAVE_XT9
+ void xt9Init(const QLocale &locale, QVirtualKeyboardInputEngine::InputMode inputMode, T9WriteInputMethod::EngineMode newEngineMode)
+ {
+ ET9U32 dwFirstLdbNum = Xt9LanguageMap::languageId(locale);
+ ET9U32 eInputMode = ET9AWInputMode_Default;
+
+ xt9DetachAllDynamicDictionaries();
+
+ switch (newEngineMode) {
+ case T9WriteInputMethod::EngineMode::SimplifiedChinese:
+ case T9WriteInputMethod::EngineMode::TraditionalChinese:
+ case T9WriteInputMethod::EngineMode::HongKongChinese:
+ if (inputMode == QVirtualKeyboardInputEngine::InputMode::ChineseHandwriting) {
+ xt9Ime.reset(new Xt9CpIme(this));
+ switch (locale.script()) {
+ case QLocale::SimplifiedHanScript:
+ if (static_cast<Xt9CpIme *>(xt9Ime.data())) {
+ eInputMode = ET9CPMODE_PINYIN;
+ }
+ break;
+ default:
+ break;
+ }
+ } else {
+ if (xt9IsAlphabeticCoreDisabled()) {
+ xt9Exit();
+ return;
+ }
+ xt9Ime.reset(new Xt9AwIme(this));
+ dwFirstLdbNum = ET9LIDEnglish_UK;
+ }
+ break;
+
+ case T9WriteInputMethod::EngineMode::Japanese:
+ xt9Ime.reset(new Xt9JIme(this));
+ eInputMode = ET9AWInputMode_RomajiConversion;
+ break;
+
+ case T9WriteInputMethod::EngineMode::Korean:
+ xt9Ime.reset(new Xt9KIme(this));
+ break;
+
+ default:
+ if (xt9IsAlphabeticCoreDisabled()) {
+ xt9Exit();
+ return;
+ }
+ xt9Ime.reset(new Xt9AwIme(this));
+ break;
+ }
+
+ xt9Ime->ldbManager = ldbManager;
+ xt9Ime->sysInit();
+ xt9Ime->setWorkingDirectory(Settings::instance()->userDataPath());
+ if (xt9DynamicDictionaries.isEmpty())
+ xt9Ime->removeAllIndexes();
+
+ // PHD must be disabled during XT9 init to prevent finding
+ // T9 Write specific dictionary files.
+ ldbManager->setPhdEnabled(false);
+
+ xt9Ime->ldbInit(dwFirstLdbNum, ET9PLIDNone, eInputMode);
+
+ ldbManager->setPhdEnabled(true);
+
+ onDefaultDictionaryDisabledChanged();
+ onAvailableDynamicDictionariesChanged();
+ onActiveDynamicDictionariesChanged();
+ }
+
+ void xt9Exit()
+ {
+ if (xt9Ime)
+ xt9Ime->removeAllIndexes();
+
+ Q_Q(T9WriteInputMethod);
+ QVirtualKeyboardDictionaryManager *dictionaryManager = QVirtualKeyboardDictionaryManager::instance();
+ const QStringList availableDictionaries = dictionaryManager->availableDictionaries();
+ for (const QString &dictionaryName : availableDictionaries) {
+ QVirtualKeyboardDictionary *dictionary = dictionaryManager->dictionary(dictionaryName);
+ dictionary->disconnect(q); // lambdas
+ }
+
+ xt9AttachedDynamicDictionaries.clear();
+ xt9DynamicDictionaries.clear();
+ xt9DynamicDictionaryNextId = 0;
+
+ xt9Ime.reset();
+ }
+
+ void bindSettings()
+ {
+ if (!defaultInputMethodDisabledChangedConnection)
+ defaultInputMethodDisabledChangedConnection = QObjectPrivate::connect(
+ Settings::instance(), &Settings::defaultInputMethodDisabledChanged,
+ this, &T9WriteInputMethodPrivate::onXt9AlphabeticCoreDisabledChanged);
+ if (!defaultDictionaryDisabledChangedConnection)
+ defaultDictionaryDisabledChangedConnection = QObjectPrivate::connect(
+ Settings::instance(), &Settings::defaultDictionaryDisabledChanged,
+ this, &T9WriteInputMethodPrivate::onDefaultDictionaryDisabledChanged);
+
+ }
+
+ void unbindSettings()
+ {
+ QObject::disconnect(defaultInputMethodDisabledChangedConnection);
+ QObject::disconnect(defaultDictionaryDisabledChangedConnection);
+ }
+
+ void onXt9AlphabeticCoreDisabledChanged()
+ {
+ if (xt9IsAlphabeticCoreDisabled()) {
+ xt9Exit();
+ } else if (!xt9Ime) {
+ Q_Q(T9WriteInputMethod);
+ const QVirtualKeyboardInputEngine::InputMode inputMode = q->inputEngine()->inputMode();
+ const QLocale locale = QLocale(q->inputContext()->locale());
+ const DECUMA_UINT32 language = mapToDecumaLanguage(locale, inputMode);
+ const T9WriteInputMethod::EngineMode newEngineMode = mapLocaleToEngineMode(locale, language);
+ xt9Init(locale, inputMode, newEngineMode);
+ }
+ }
+
+ static bool xt9IsAlphabeticCoreDisabled()
+ {
+ Settings *settings = Settings::instance();
+ return settings->isDefaultInputMethodDisabled();
+ }
+
+ void onDefaultDictionaryDisabledChanged()
+ {
+ if (Xt9AwIme *xt9AwIme = dynamic_cast<Xt9AwIme *>(xt9Ime.data()))
+ xt9AwIme->setLdbEnabled(!Settings::instance()->isDefaultDictionaryDisabled());
+ }
+
+ ET9STATUS request(ET9_Request *const pRequest) override
+ {
+ Q_Q(T9WriteInputMethod);
+
+ switch (pRequest->eType) {
+ case ET9_REQ_BufferContext:
+ {
+ QVirtualKeyboardInputContext *ic = q->inputContext();
+ if (!ic)
+ break;
+
+ const ET9U32 dwContextLen = static_cast<ET9U32>(ic->cursorPosition());
+ const ET9U32 dwStartIndex =
+ dwContextLen <= pRequest->data.sBufferContextInfo.dwMaxBufLen ?
+ 0 : dwContextLen - pRequest->data.sBufferContextInfo.dwMaxBufLen;
+
+ pRequest->data.sBufferContextInfo.dwBufLen = dwContextLen - dwStartIndex;
+ const QString surroundingText = ic->surroundingText();
+
+ memcpy(pRequest->data.sBufferContextInfo.psBuf, surroundingText.utf16() + dwStartIndex,
+ pRequest->data.sBufferContextInfo.dwBufLen * sizeof(ET9SYMB));
+
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ return ET9STATUS_NONE;
+ }
+
+ bool xt9AllSymbsArePinyin(const QString &symbs) const
+ {
+ bool allSymbsArePinyin = false;
+ for (const QChar &symb : symbs) {
+ const ushort ucs = symb.unicode();
+ allSymbsArePinyin = ET9CPIsPinyinSymbol(ucs);
+ if (!allSymbsArePinyin)
+ break;
+ }
+ return allSymbsArePinyin;
+ }
+
+ bool xt9AttachDictionary(const QString &dictionaryName)
+ {
+ if (!xt9DynamicDictionaries.contains(dictionaryName))
+ return false;
+
+ const quint16 id = xt9DynamicDictionaries.value(dictionaryName);
+ qCDebug(lcT9Write) << "T9WriteInputMethodPrivate::xt9AttachDictionary():" << dictionaryName << id;
+ xt9Ime->mountIndex(id);
+ xt9AttachedDynamicDictionaries[dictionaryName] = id;
+
+ return true;
+ }
+
+ void xt9DetachDictionary(const QString &dictionaryName)
+ {
+ if (!xt9AttachedDynamicDictionaries.contains(dictionaryName))
+ return;
+
+ const quint16 id = xt9AttachedDynamicDictionaries[dictionaryName];
+ qCDebug(lcT9Write) << "T9WriteInputMethodPrivate::xt9DetachDictionary():" << dictionaryName << id;
+ xt9Ime->unmountIndex(id);
+ xt9AttachedDynamicDictionaries.remove(dictionaryName);
+ }
+#endif
+
+#ifdef HAVE_XT9
+ void xt9DetachAllDynamicDictionaries()
+ {
+ if (xt9Ime) {
+ const QStringList dictionaryNames = xt9AttachedDynamicDictionaries.keys();
+ for (const QString &dictionaryName : dictionaryNames) {
+ xt9DetachDictionary(dictionaryName);
+ }
+ }
+ xt9AttachedDynamicDictionaries.clear();
+ }
+#endif
+
+ QStringList xt9BuildSelectionList(const QString &exactWord, int *defaultListIndex)
+ {
+#ifdef HAVE_XT9
+ if (!xt9Ime)
+ return QStringList();
+
+ xt9Ime->cursorMoved();
+
+ Q_Q(T9WriteInputMethod);
+ bool forceLowerCase =
+ engineMode == T9WriteInputMethod::EngineMode::SimplifiedChinese &&
+ q->inputEngine()->inputMode() == QVirtualKeyboardInputEngine::InputMode::ChineseHandwriting &&
+ xt9AllSymbsArePinyin(exactWord);
+
+ ET9ClearAllSymbs(&xt9Ime->sWordSymbInfo);
+ for (const QChar &c : exactWord) {
+ ET9AddExplicitSymb(&xt9Ime->sWordSymbInfo, c.unicode(), 0, !forceLowerCase && c.isUpper() ? ET9SHIFT : ET9NOSHIFT, ET9_NO_ACTIVE_INDEX);
+ }
+
+ ET9SYMB gestureValue = 0;
+ return xt9Ime->buildSelectionList(defaultListIndex, &gestureValue);
+#else
+ return QStringList();
+#endif
+ }
+
+ void appendWordCandidates(QList<T9WriteWordCandidate> &aWordCandidates, int &activeWordIndex, const QString &exactWord, const QStringList &wordCandidatesToAppend, int defaultListIndex, T9WriteWordCandidate::Origin origin) const
+ {
+ for (int index = 0; index < wordCandidatesToAppend.size(); ++index) {
+ const T9WriteWordCandidate wordCandidate(wordCandidatesToAppend[index], index, origin);
+ if (!aWordCandidates.contains(wordCandidate)) {
+ bool isDefaultIndex = defaultListIndex > 0 &&
+ index == defaultListIndex && !cjk &&
+ origin == T9WriteWordCandidate::Origin::XT9;
+ if (isDefaultIndex) {
+ activeWordIndex = qMin(aWordCandidates.size(), 1);
+ aWordCandidates.insert(activeWordIndex, wordCandidate);
+ } else {
+ aWordCandidates.append(wordCandidate);
+ }
+ }
+ }
+
+ if (aWordCandidates.isEmpty()) {
+ aWordCandidates.append(T9WriteWordCandidate(exactWord));
+ }
+ }
+
+ QString findHwrDb(T9WriteInputMethod::EngineMode mode) const
+ {
+ for (const QString &defaultHwrDbPath : defaultHwrDbPaths) {
+ const QString result = findHwrDb(mode, defaultHwrDbPath);
+ if (!result.isEmpty())
+ return result;
+ }
+
+ qCCritical(lcT9Write) << "Could not find HWR database for" << engineModeToString(mode);
+ return QString();
+ }
+
QString findHwrDb(T9WriteInputMethod::EngineMode mode, const QString &dir) const
{
- QString hwrDbPath(dir);
+ QString hwrDbPath(QDir::fromNativeSeparators(dir));
+ if (!hwrDbPath.endsWith(QLatin1Char('/')))
+ hwrDbPath.append(QLatin1Char('/'));
switch (mode) {
case T9WriteInputMethod::EngineMode::Alphabetic:
-#if T9WRITEAPIMAJORVERNUM >= 21
hwrDbPath.append(QLatin1String("hwrDB_le.bin"));
-#else
- hwrDbPath.append(QLatin1String("_databas_le.bin"));
-#endif
break;
case T9WriteInputMethod::EngineMode::Arabic:
-#if T9WRITEAPIMAJORVERNUM >= 21
hwrDbPath.append(QLatin1String("arabic/hwrDB_le.bin"));
-#else
- hwrDbPath.append(QLatin1String("arabic/_databas_le.bin"));
-#endif
break;
case T9WriteInputMethod::EngineMode::Hebrew:
-#if T9WRITEAPIMAJORVERNUM >= 21
hwrDbPath.append(QLatin1String("hebrew/hwrDB_le.bin"));
-#else
- hwrDbPath.append(QLatin1String("hebrew/_databas_le.bin"));
-#endif
break;
case T9WriteInputMethod::EngineMode::Thai:
-#if T9WRITEAPIMAJORVERNUM >= 21
hwrDbPath.append(QLatin1String("thai/hwrDB_le.bin"));
-#else
- hwrDbPath.append(QLatin1String("thai/_databas_le.bin"));
-#endif
break;
case T9WriteInputMethod::EngineMode::SimplifiedChinese:
hwrDbPath.append(QLatin1String("cjk_S_gb18030_le.hdb"));
break;
case T9WriteInputMethod::EngineMode::TraditionalChinese:
- hwrDbPath.append(QLatin1String("cjk_T_std_le.hdb"));
- break;
case T9WriteInputMethod::EngineMode::HongKongChinese:
hwrDbPath.append(QLatin1String("cjk_HK_std_le.hdb"));
break;
@@ -343,82 +675,47 @@ public:
return QString();
}
if (!QFileInfo::exists(hwrDbPath)) {
- qCCritical(lcT9Write) << "Could not find HWR database for" << engineModeToString(mode);
return QString();
}
return hwrDbPath;
}
- QString findDictionary(const QString &dir, const QLocale &locale, DECUMA_SRC_DICTIONARY_TYPE &srcType)
+ QString findDictionary(const QLocale &locale, DECUMA_SRC_DICTIONARY_TYPE &srcType)
{
srcType = numberOfSrcDictionaryTypes;
- QStringList languageCountry = locale.name().split(QLatin1String("_"));
- if (languageCountry.length() != 2)
- return QString();
- const QString language = languageCountry[0].toUpper();
-
- QString dictionary;
- QDirIterator it(dir, QDirIterator::NoIteratorFlags);
- while (it.hasNext()) {
- QString fileEntry = it.next();
- const QFileInfo fileInfo(fileEntry);
-
- if (fileInfo.isDir())
- continue;
-
- const QString fileName(fileInfo.fileName());
- if (!fileName.startsWith(language) &&
- !fileName.startsWith(QLatin1String("zzEval_") + language))
- continue;
-
- if (fileEntry.endsWith(QLatin1String(".ldb"))) {
-#if T9WRITEAPIMAJORVERNUM >= 20
- qCCritical(lcT9Write) << "Incompatible dictionary" << fileEntry;
- continue;
-#else
- srcType = decumaXT9LDB;
-#endif
- } else if (fileEntry.endsWith(QLatin1String(".phd"))) {
-#if T9WRITEAPIMAJORVERNUM >= 20
+ QString dictionary = ldbManager->findDictionary(locale);
+ if (!dictionary.isEmpty()) {
+ if (dictionary.endsWith(QLatin1String(".ldb"))) {
+ srcType = decumaPortableHWRDictionary;
+ } else if (dictionary.endsWith(QLatin1String(".phd"))) {
srcType = decumaPortableHWRDictionary;
-#else
- qCCritical(lcT9Write) << "Incompatible dictionary" << fileEntry;
- continue;
-#endif
} else {
- qCCritical(lcT9Write) << "Incompatible dictionary" << fileEntry;
- continue;
+ qCCritical(lcT9Write) << "Incompatible dictionary" << dictionary;
+ dictionary.clear();
}
-
- dictionary = fileEntry;
- break;
}
return dictionary;
}
- bool attachDictionary(const QSharedPointer<T9WriteDictionary> &dictionary)
+ bool attachDictionary(const QSharedPointer<T9WriteAbstractDictionary> &dictionary)
{
const std::lock_guard<QRecursiveMutex> dictionaryGuard(dictionaryLock);
Q_ASSERT(decumaSession != nullptr);
Q_ASSERT(dictionary != nullptr);
- qCDebug(lcT9Write) << "T9WriteInputMethodPrivate::attachDictionary():" << dictionary->fileName();
-#if T9WRITEAPIMAJORVERNUM >= 20
- DECUMA_STATUS status = DECUMA_API(AttachDictionary)(decumaSession, dictionary->data(), dictionary->size());
-#else
- DECUMA_STATUS status = DECUMA_API(AttachConvertedDictionary)(decumaSession, dictionary->data());
-#endif
+ qCDebug(lcT9Write) << "T9WriteInputMethodPrivate::attachDictionary():" << dictionary->name();
+ DECUMA_STATUS status = DECUMA_API(AttachDictionary)(decumaSession, dictionary->data(), static_cast<DECUMA_UINT32>(dictionary->size()));
return status == decumaNoError;
}
- void detachDictionary(const QSharedPointer<T9WriteDictionary> &dictionary)
+ void detachDictionary(const QSharedPointer<T9WriteAbstractDictionary> &dictionary)
{
const std::lock_guard<QRecursiveMutex> dictionaryGuard(dictionaryLock);
if (!dictionary)
return;
- qCDebug(lcT9Write) << "T9WriteInputMethodPrivate::detachDictionary():" << dictionary->fileName();
+ qCDebug(lcT9Write) << "T9WriteInputMethodPrivate::detachDictionary():" << dictionary->name();
Q_ASSERT(decumaSession != nullptr);
DECUMA_STATUS status = DECUMA_API(DetachDictionary)(decumaSession, dictionary->data());
@@ -433,14 +730,30 @@ public:
finishRecognition();
+ // All tasks must be completed before changing the session settings
+ if (worker) {
+ worker->waitForAllTasks();
+ dictionaryTask.reset();
+ }
+
DECUMA_UINT32 language = mapToDecumaLanguage(locale, inputMode);
if (language == DECUMA_LANG_GSMDEFAULT) {
qCCritical(lcT9Write) << "Language is not supported" << locale.name();
return false;
}
- if (!initEngine(mapLocaleToEngineMode(locale, language)))
+ T9WriteInputMethod::EngineMode newEngineMode = mapLocaleToEngineMode(locale, language);
+
+#ifdef HAVE_XT9
+ xt9Init(locale, inputMode, newEngineMode);
+#endif
+
+ if (!initEngine(newEngineMode)) {
+#ifdef HAVE_XT9
+ xt9Exit();
+#endif
return false;
+ }
int isLanguageSupported = 0;
DECUMA_API(DatabaseIsLanguageSupported)(sessionSettings.pStaticDB, language, &isLanguageSupported);
@@ -462,7 +775,6 @@ public:
if (!updateSymbolCategories(language, locale, inputMode))
return false;
updateRecognitionMode(language, locale, inputMode);
- updateDictionary(language, locale, languageChanged);
static const QList<DECUMA_UINT32> rtlLanguages = QList<DECUMA_UINT32>()
<< DECUMA_LANG_AR << DECUMA_LANG_IW << DECUMA_LANG_FA << DECUMA_LANG_UR;
sessionSettings.writingDirection = rtlLanguages.contains(language) ? rightToLeft : leftToRight;
@@ -480,30 +792,37 @@ public:
// Change session settings
sessionSettings.charSet.pSymbolCategories = symbolCategories.data();
- sessionSettings.charSet.nSymbolCategories = symbolCategories.size();
+ sessionSettings.charSet.nSymbolCategories = static_cast<DECUMA_UINT8>(symbolCategories.size());
sessionSettings.charSet.pLanguages = languageCategories.data();
- sessionSettings.charSet.nLanguages = languageCategories.size();
+ sessionSettings.charSet.nLanguages = static_cast<DECUMA_UINT8>(languageCategories.size());
DECUMA_STATUS status = DECUMA_API(ChangeSessionSettings)(decumaSession, &sessionSettings);
- Q_ASSERT(status == decumaNoError);
+
+ if (status == decumaUnsupportedLanguageInUcrMode || status == decumaUnsupportedSymbolCategoryInUcrMode) {
+ sessionSettings.recognitionMode = mcrMode;
+ status = DECUMA_API(ChangeSessionSettings)(decumaSession, &sessionSettings);
+ }
+
+ if (status != decumaNoError)
+ qCWarning(lcT9Write) << "Failed to configure HWR engine" << status;
caseFormatter.preferLowercase = q->inputContext()->inputMethodHints().testFlag(Qt::ImhPreferLowercase);
+ updateDictionary(language, locale, languageChanged);
+
return status == decumaNoError;
}
T9WriteInputMethod::EngineMode mapLocaleToEngineMode(const QLocale &locale, DECUMA_UINT32 language = 0)
{
-#ifdef HAVE_T9WRITE_CJK
+#ifdef HAVE_CERENCE_HWR_CJK
switch (locale.language()) {
case QLocale::Chinese: {
if (locale.script() == QLocale::TraditionalChineseScript)
return locale.country() == QLocale::HongKong ? T9WriteInputMethod::EngineMode::HongKongChinese : T9WriteInputMethod::EngineMode::TraditionalChinese;
return T9WriteInputMethod::EngineMode::SimplifiedChinese;
- break;
}
case QLocale::Japanese:
return T9WriteInputMethod::EngineMode::Japanese;
- break;
case QLocale::Korean:
return T9WriteInputMethod::EngineMode::Korean;
default:
@@ -514,7 +833,7 @@ public:
Q_UNUSED(language);
#endif
-#ifdef HAVE_T9WRITE_ALPHABETIC
+#ifdef HAVE_CERENCE_HWR_ALPHABETIC
switch (locale.script()) {
case QLocale::ArabicScript:
return T9WriteInputMethod::EngineMode::Arabic;
@@ -533,153 +852,92 @@ public:
DECUMA_UINT32 mapToDecumaLanguage(const QLocale &locale, QVirtualKeyboardInputEngine::InputMode inputMode)
{
- static const QLocale::Language maxLanguage = QLocale::Vietnamese;
- static const DECUMA_UINT32 languageMap[maxLanguage + 1] = {
- DECUMA_LANG_GSMDEFAULT, // AnyLanguage = 0
- DECUMA_LANG_GSMDEFAULT, // C = 1
- DECUMA_LANG_GSMDEFAULT, // Abkhazian = 2
- DECUMA_LANG_GSMDEFAULT, // Oromo = 3
- DECUMA_LANG_GSMDEFAULT, // Afar = 4
- DECUMA_LANG_AF, // Afrikaans = 5
- DECUMA_LANG_SQ, // Albanian = 6
- DECUMA_LANG_GSMDEFAULT, // Amharic = 7
- DECUMA_LANG_AR, // Arabic = 8
- DECUMA_LANG_GSMDEFAULT, // Armenian = 9
- DECUMA_LANG_GSMDEFAULT, // Assamese = 10
- DECUMA_LANG_GSMDEFAULT, // Aymara = 11
- DECUMA_LANG_AZ, // Azerbaijani = 12
- DECUMA_LANG_GSMDEFAULT, // Bashkir = 13
- DECUMA_LANG_EU, // Basque = 14
- DECUMA_LANG_BN, // Bengali = 15
- DECUMA_LANG_GSMDEFAULT, // Dzongkha = 16
- DECUMA_LANG_GSMDEFAULT, // Bihari = 17
- DECUMA_LANG_GSMDEFAULT, // Bislama = 18
- DECUMA_LANG_GSMDEFAULT, // Breton = 19
- DECUMA_LANG_BG, // Bulgarian = 20
- DECUMA_LANG_GSMDEFAULT, // Burmese = 21
- DECUMA_LANG_BE, // Belarusian = 22
- DECUMA_LANG_KM, // Khmer = 23
- DECUMA_LANG_CA, // Catalan = 24
- DECUMA_LANG_PRC, // Chinese = 25
- DECUMA_LANG_GSMDEFAULT, // Corsican = 26
- DECUMA_LANG_HR, // Croatian = 27
- DECUMA_LANG_CS, // Czech = 28
- DECUMA_LANG_DA, // Danish = 29
- DECUMA_LANG_NL, // Dutch = 30
- DECUMA_LANG_EN, // English = 31
- DECUMA_LANG_GSMDEFAULT, // Esperanto = 32
- DECUMA_LANG_ET, // Estonian = 33
- DECUMA_LANG_GSMDEFAULT, // Faroese = 34
- DECUMA_LANG_GSMDEFAULT, // Fijian = 35
- DECUMA_LANG_FI, // Finnish = 36
- DECUMA_LANG_FR, // French = 37
- DECUMA_LANG_GSMDEFAULT, // WesternFrisian = 38
- DECUMA_LANG_GSMDEFAULT, // Gaelic = 39
- DECUMA_LANG_GL, // Galician = 40
- DECUMA_LANG_GSMDEFAULT, // Georgian = 41
- DECUMA_LANG_DE, // German = 42
- DECUMA_LANG_EL, // Greek = 43
- DECUMA_LANG_GSMDEFAULT, // Greenlandic = 44
- DECUMA_LANG_GSMDEFAULT, // Guarani = 45
- DECUMA_LANG_GU, // Gujarati = 46
- DECUMA_LANG_HA, // Hausa = 47
- DECUMA_LANG_IW, // Hebrew = 48
- DECUMA_LANG_HI, // Hindi = 49
- DECUMA_LANG_HU, // Hungarian = 50
- DECUMA_LANG_IS, // Icelandic = 51
- DECUMA_LANG_IN, // Indonesian = 52
- DECUMA_LANG_GSMDEFAULT, // Interlingua = 53
- DECUMA_LANG_GSMDEFAULT, // Interlingue = 54
- DECUMA_LANG_GSMDEFAULT, // Inuktitut = 55
- DECUMA_LANG_GSMDEFAULT, // Inupiak = 56
- DECUMA_LANG_GSMDEFAULT, // Irish = 57
- DECUMA_LANG_IT, // Italian = 58
- DECUMA_LANG_JP, // Japanese = 59
- DECUMA_LANG_GSMDEFAULT, // Javanese = 60
- DECUMA_LANG_KN, // Kannada = 61
- DECUMA_LANG_GSMDEFAULT, // Kashmiri = 62
- DECUMA_LANG_KK, // Kazakh = 63
- DECUMA_LANG_GSMDEFAULT, // Kinyarwanda = 64
- DECUMA_LANG_KY, // Kirghiz = 65
- DECUMA_LANG_KO, // Korean = 66
- DECUMA_LANG_GSMDEFAULT, // Kurdish = 67
- DECUMA_LANG_GSMDEFAULT, // Rundi = 68
- DECUMA_LANG_GSMDEFAULT, // Lao = 69
- DECUMA_LANG_GSMDEFAULT, // Latin = 70
- DECUMA_LANG_LV, // Latvian = 71
- DECUMA_LANG_GSMDEFAULT, // Lingala = 72
- DECUMA_LANG_LT, // Lithuanian = 73
- DECUMA_LANG_MK, // Macedonian = 74
- DECUMA_LANG_GSMDEFAULT, // Malagasy = 75
- DECUMA_LANG_MS, // Malay = 76
- DECUMA_LANG_ML, // Malayalam = 77
- DECUMA_LANG_GSMDEFAULT, // Maltese = 78
- DECUMA_LANG_GSMDEFAULT, // Maori = 79
- DECUMA_LANG_MR, // Marathi = 80
- DECUMA_LANG_GSMDEFAULT, // Marshallese = 81
- DECUMA_LANG_MN, // Mongolian = 82
- DECUMA_LANG_GSMDEFAULT, // NauruLanguage = 83
- DECUMA_LANG_GSMDEFAULT, // Nepali = 84
- DECUMA_LANG_NO, // NorwegianBokmal = 85
- DECUMA_LANG_GSMDEFAULT, // Occitan = 86
- DECUMA_LANG_GSMDEFAULT, // Oriya = 87
- DECUMA_LANG_GSMDEFAULT, // Pashto = 88
- DECUMA_LANG_FA, // Persian = 89
- DECUMA_LANG_PL, // Polish = 90
- DECUMA_LANG_PT, // Portuguese = 91
- DECUMA_LANG_PA, // Punjabi = 92
- DECUMA_LANG_GSMDEFAULT, // Quechua = 93
- DECUMA_LANG_GSMDEFAULT, // Romansh = 94
- DECUMA_LANG_RO, // Romanian = 95
- DECUMA_LANG_RU, // Russian = 96
- DECUMA_LANG_GSMDEFAULT, // Samoan = 97
- DECUMA_LANG_GSMDEFAULT, // Sango = 98
- DECUMA_LANG_GSMDEFAULT, // Sanskrit = 99
- DECUMA_LANG_SRCY, // Serbian = 100
- DECUMA_LANG_GSMDEFAULT, // Ossetic = 101
- DECUMA_LANG_ST, // SouthernSotho = 102
- DECUMA_LANG_GSMDEFAULT, // Tswana = 103
- DECUMA_LANG_GSMDEFAULT, // Shona = 104
- DECUMA_LANG_GSMDEFAULT, // Sindhi = 105
- DECUMA_LANG_SI, // Sinhala = 106
- DECUMA_LANG_GSMDEFAULT, // Swati = 107
- DECUMA_LANG_SK, // Slovak = 108
- DECUMA_LANG_SL, // Slovenian = 109
- DECUMA_LANG_GSMDEFAULT, // Somali = 110
- DECUMA_LANG_ES, // Spanish = 111
- DECUMA_LANG_GSMDEFAULT, // Sundanese = 112
- DECUMA_LANG_SW, // Swahili = 113
- DECUMA_LANG_SV, // Swedish = 114
- DECUMA_LANG_GSMDEFAULT, // Sardinian = 115
- DECUMA_LANG_TG, // Tajik = 116
- DECUMA_LANG_TA, // Tamil = 117
- DECUMA_LANG_GSMDEFAULT, // Tatar = 118
- DECUMA_LANG_TE, // Telugu = 119
- DECUMA_LANG_TH, // Thai = 120
- DECUMA_LANG_GSMDEFAULT, // Tibetan = 121
- DECUMA_LANG_GSMDEFAULT, // Tigrinya = 122
- DECUMA_LANG_GSMDEFAULT, // Tongan = 123
- DECUMA_LANG_GSMDEFAULT, // Tsonga = 124
- DECUMA_LANG_TR, // Turkish = 125
- DECUMA_LANG_GSMDEFAULT, // Turkmen = 126
- DECUMA_LANG_GSMDEFAULT, // Tahitian = 127
- DECUMA_LANG_GSMDEFAULT, // Uighur = 128
- DECUMA_LANG_UK, // Ukrainian = 129
- DECUMA_LANG_UR, // Urdu = 130
- DECUMA_LANG_UZ, // Uzbek = 131
- DECUMA_LANG_VI // Vietnamese = 132
+ struct LanguageMap {
+ QLocale::Language localeLanguage;
+ DECUMA_UINT16 decumaLanguage;
+ };
+ static const LanguageMap languageMap[] = {
+ { QLocale::Language::Afrikaans, DECUMA_LANG_AF },
+ { QLocale::Language::Albanian, DECUMA_LANG_SQ },
+ { QLocale::Language::Arabic, DECUMA_LANG_AR },
+ { QLocale::Language::Azerbaijani, DECUMA_LANG_AZ },
+ { QLocale::Language::Basque, DECUMA_LANG_EU },
+ { QLocale::Language::Belarusian, DECUMA_LANG_BE },
+ { QLocale::Language::Bengali, DECUMA_LANG_BN },
+ { QLocale::Language::Bulgarian, DECUMA_LANG_BG },
+ { QLocale::Language::Catalan, DECUMA_LANG_CA },
+ { QLocale::Language::Chinese, DECUMA_LANG_PRC },
+ { QLocale::Language::Croatian, DECUMA_LANG_HR },
+ { QLocale::Language::Czech, DECUMA_LANG_CS },
+ { QLocale::Language::Danish, DECUMA_LANG_DA },
+ { QLocale::Language::Dutch, DECUMA_LANG_NL },
+ { QLocale::Language::English, DECUMA_LANG_EN },
+ { QLocale::Language::Estonian, DECUMA_LANG_ET },
+ { QLocale::Language::Finnish, DECUMA_LANG_FI },
+ { QLocale::Language::French, DECUMA_LANG_FR },
+ { QLocale::Language::Galician, DECUMA_LANG_GL },
+ { QLocale::Language::German, DECUMA_LANG_DE },
+ { QLocale::Language::Greek, DECUMA_LANG_EL },
+ { QLocale::Language::Gujarati, DECUMA_LANG_GU },
+ { QLocale::Language::Hausa, DECUMA_LANG_HA },
+ { QLocale::Language::Hebrew, DECUMA_LANG_IW },
+ { QLocale::Language::Hindi, DECUMA_LANG_HI },
+ { QLocale::Language::Hungarian, DECUMA_LANG_HU },
+ { QLocale::Language::Icelandic, DECUMA_LANG_IS },
+ { QLocale::Language::Indonesian, DECUMA_LANG_IN },
+ { QLocale::Language::Italian, DECUMA_LANG_IT },
+ { QLocale::Language::Japanese, DECUMA_LANG_JP },
+ { QLocale::Language::Kannada, DECUMA_LANG_KN },
+ { QLocale::Language::Kazakh, DECUMA_LANG_KK },
+ { QLocale::Language::Khmer, DECUMA_LANG_KM },
+ { QLocale::Language::Kirghiz, DECUMA_LANG_KY },
+ { QLocale::Language::Korean, DECUMA_LANG_KO },
+ { QLocale::Language::Latvian, DECUMA_LANG_LV },
+ { QLocale::Language::Lithuanian, DECUMA_LANG_LT },
+ { QLocale::Language::Macedonian, DECUMA_LANG_MK },
+ { QLocale::Language::Malay, DECUMA_LANG_MS },
+ { QLocale::Language::Malayalam, DECUMA_LANG_ML },
+ { QLocale::Language::Marathi, DECUMA_LANG_MR },
+ { QLocale::Language::Mongolian, DECUMA_LANG_MN },
+ { QLocale::Language::NorwegianBokmal, DECUMA_LANG_NO },
+ { QLocale::Language::Persian, DECUMA_LANG_FA },
+ { QLocale::Language::Polish, DECUMA_LANG_PL },
+ { QLocale::Language::Portuguese, DECUMA_LANG_PT },
+ { QLocale::Language::Punjabi, DECUMA_LANG_PA },
+ { QLocale::Language::Romanian, DECUMA_LANG_RO },
+ { QLocale::Language::Russian, DECUMA_LANG_RU },
+ { QLocale::Language::Serbian, DECUMA_LANG_SRCY },
+ { QLocale::Language::Sinhala, DECUMA_LANG_SI },
+ { QLocale::Language::Slovak, DECUMA_LANG_SK },
+ { QLocale::Language::Slovenian, DECUMA_LANG_SL },
+ { QLocale::Language::SouthernSotho, DECUMA_LANG_ST },
+ { QLocale::Language::Spanish, DECUMA_LANG_ES },
+ { QLocale::Language::Swahili, DECUMA_LANG_SW },
+ { QLocale::Language::Swedish, DECUMA_LANG_SV },
+ { QLocale::Language::Tajik, DECUMA_LANG_TG },
+ { QLocale::Language::Tamil, DECUMA_LANG_TA },
+ { QLocale::Language::Telugu, DECUMA_LANG_TE },
+ { QLocale::Language::Thai, DECUMA_LANG_TH },
+ { QLocale::Language::Turkish, DECUMA_LANG_TR },
+ { QLocale::Language::Ukrainian, DECUMA_LANG_UK },
+ { QLocale::Language::Urdu, DECUMA_LANG_UR },
+ { QLocale::Language::Uzbek, DECUMA_LANG_UZ },
+ { QLocale::Language::Vietnamese, DECUMA_LANG_VI },
+ // Last entry
+ { QLocale::Language::AnyLanguage, DECUMA_LANG_GSMDEFAULT }
};
- int localeLanguage = locale.language();
- if (locale.language() > maxLanguage)
- return DECUMA_LANG_GSMDEFAULT;
+ const int localeLanguage = locale.language();
+ const LanguageMap *languageMapIterator = languageMap;
+ for (; languageMapIterator->localeLanguage != QLocale::Language::AnyLanguage &&
+ languageMapIterator->localeLanguage != localeLanguage; languageMapIterator++) {}
- DECUMA_UINT32 language = languageMap[localeLanguage];
+ DECUMA_UINT32 language = languageMapIterator->decumaLanguage;
if (language == DECUMA_LANG_PRC) {
if (inputMode != QVirtualKeyboardInputEngine::InputMode::ChineseHandwriting)
language = DECUMA_LANG_EN;
else if (locale.script() == QLocale::TraditionalChineseScript)
- language = (locale.country() == QLocale::HongKong) ? DECUMA_LANG_HK : DECUMA_LANG_TW;
+ language = DECUMA_LANG_HK; // Common language for the traditional script
} else if (language == DECUMA_LANG_JP) {
if (inputMode != QVirtualKeyboardInputEngine::InputMode::JapaneseHandwriting)
language = DECUMA_LANG_EN;
@@ -716,30 +974,25 @@ public:
sessionSettings.recognitionMode = mcrMode;
// T9 Write Alphabetic v8.0.0 supports UCR mode for specific languages
-#if T9WRITEAPIMAJORVERNUM >= 21
if (!cjk) {
switch (inputMode) {
case QVirtualKeyboardInputEngine::InputMode::Latin:
- switch (language) {
- case DECUMA_LANG_EN:
- case DECUMA_LANG_FR:
- case DECUMA_LANG_IT:
- case DECUMA_LANG_DE:
- case DECUMA_LANG_ES:
- sessionSettings.recognitionMode = ucrMode;
- break;
- default:
- break;
- }
+ sessionSettings.recognitionMode = ucrMode;
break;
case QVirtualKeyboardInputEngine::InputMode::Arabic:
sessionSettings.recognitionMode = ucrMode;
break;
+ case QVirtualKeyboardInputEngine::InputMode::Cyrillic:
+ sessionSettings.recognitionMode = ucrMode;
+ break;
+ case QVirtualKeyboardInputEngine::InputMode::Hebrew:
+ case QVirtualKeyboardInputEngine::InputMode::Thai:
+ sessionSettings.recognitionMode = ucrMode;
+ break;
default:
break;
}
}
-#endif
// Use scrMode with hidden text or with no predictive mode
if (inputMode != QVirtualKeyboardInputEngine::InputMode::ChineseHandwriting &&
@@ -888,6 +1141,11 @@ public:
symbolCategories.append(DECUMA_CATEGORY_CJK_SYMBOL);
symbolCategories.append(DECUMA_CATEGORY_CJK_GENERAL_PUNCTUATIONS);
symbolCategories.append(DECUMA_CATEGORY_PUNCTUATIONS);
+#ifdef HAVE_XT9
+ if (xt9Ime) {
+ symbolCategories.append(DECUMA_CATEGORY_ANSI);
+ }
+#endif
break;
case QLocale::TraditionalChineseScript:
@@ -915,6 +1173,11 @@ public:
symbolCategories.append(DECUMA_CATEGORY_CJK_SYMBOL);
symbolCategories.append(DECUMA_CATEGORY_CJK_GENERAL_PUNCTUATIONS);
symbolCategories.append(DECUMA_CATEGORY_PUNCTUATIONS);
+#ifdef HAVE_XT9
+ if (xt9Ime) {
+ symbolCategories.append(DECUMA_CATEGORY_ANSI);
+ }
+#endif
break;
case QVirtualKeyboardInputEngine::InputMode::KoreanHandwriting:
@@ -970,8 +1233,8 @@ public:
dictionaryFileName.clear();
QLocale decumaLocale;
- for (QLocale tryLocale : decumaLocales) {
- dictionaryFileName = findDictionary(defaultDictionaryDbPath, tryLocale, dictionaryInfo.srcType);
+ for (const QLocale &tryLocale : decumaLocales) {
+ dictionaryFileName = findDictionary(tryLocale, dictionaryInfo.srcType);
if (!dictionaryFileName.isEmpty()) {
decumaLocale = tryLocale;
break;
@@ -982,17 +1245,19 @@ public:
qCDebug(lcT9Write) << " -> load dictionary:" << dictionaryFileName;
bool convertDictionary = true;
-#if defined(HAVE_T9WRITE_CJK) && T9WRITEAPIMAJORVERNUM >= 20
+#if defined(HAVE_CERENCE_HWR_CJK)
// Chinese dictionary cannot be converted (PHD)
if (dictionaryInfo.srcType == decumaPortableHWRDictionary && decumaLocale.language() == QLocale::Chinese)
convertDictionary = false;
#endif
- QSharedPointer<T9WriteDictionary> newDictionary(new T9WriteDictionary(decumaSession, memFuncs, cjk));
- dictionaryTask.reset(new T9WriteDictionaryTask(newDictionary, dictionaryFileName, convertDictionary, dictionaryInfo));
+ QSharedPointer<T9WriteAbstractSource> sourceDictionary(new T9WriteFileSource(dictionaryInfo, dictionaryFileName));
+
+ QSharedPointer<T9WriteDictionary> newDictionary(new T9WriteDictionary(sourceDictionary, decumaSession, memFuncs, cjk));
+ dictionaryTask.reset(new T9WriteDictionaryTask(newDictionary, convertDictionary));
- QObject::connect(dictionaryTask.data(), &T9WriteDictionaryTask::completed,
- q, &T9WriteInputMethod::dictionaryLoadCompleted, Qt::DirectConnection);
+ QObjectPrivate::connect(dictionaryTask.data(), &T9WriteDictionaryTask::completed,
+ this, &T9WriteInputMethodPrivate::dictionaryLoadCompleted, Qt::DirectConnection);
worker->addTask(dictionaryTask);
}
}
@@ -1012,7 +1277,7 @@ public:
{
QCryptographicHash hash(QCryptographicHash::Md5);
- hash.addData((const char *)&patternRecognitionMode, sizeof(patternRecognitionMode));
+ hash.addData(reinterpret_cast<const char *>(&patternRecognitionMode), sizeof(patternRecognitionMode));
QByteArray mapData;
QDataStream ds(&mapData, QIODevice::WriteOnly);
@@ -1029,6 +1294,7 @@ public:
const QByteArray &context)
{
Q_UNUSED(patternRecognitionMode);
+ Q_UNUSED(traceScreenInfo);
if (context == currentContext)
return;
currentContext = context;
@@ -1038,16 +1304,14 @@ public:
// Finish recognition, but preserve current input
Q_Q(T9WriteInputMethod);
QString preeditText = q->inputContext()->preeditText();
- // WA: T9Write CJK may crash in some cases with long stringStart.
- // Therefore we don't restore the current input in this mode.
- bool preserveCurrentInput = !preeditText.isEmpty() && !cjk;
+ bool preserveCurrentInput = !preeditText.isEmpty();
T9WriteCaseFormatter oldCaseFormatter(caseFormatter);
finishRecognition(!preserveCurrentInput);
if (preserveCurrentInput) {
caseFormatter = oldCaseFormatter;
stringStart = preeditText;
- wordCandidates.append(preeditText);
+ wordCandidates.append(T9WriteWordCandidate(preeditText));
activeWordIndex = 0;
emit q->selectionListChanged(QVirtualKeyboardSelectionListModel::Type::WordCandidateList);
emit q->selectionListActiveItemChanged(QVirtualKeyboardSelectionListModel::Type::WordCandidateList, activeWordIndex);
@@ -1056,31 +1320,16 @@ public:
const int dpi = traceCaptureDeviceInfo.value(QLatin1String("dpi"), 96).toInt();
static const int INSTANT_GESTURE_WIDTH_THRESHOLD_MM = 25;
static const int INSTANT_GESTURE_HEIGHT_THRESHOLD_MM = 25;
- instantGestureSettings.widthThreshold = INSTANT_GESTURE_WIDTH_THRESHOLD_MM / 25.4 * dpi;
- instantGestureSettings.heightThreshold = INSTANT_GESTURE_HEIGHT_THRESHOLD_MM / 25.4 * dpi;
+ instantGestureSettings.widthThreshold = static_cast<DECUMA_UINT32>(INSTANT_GESTURE_WIDTH_THRESHOLD_MM / 25.4 * dpi);
+ instantGestureSettings.heightThreshold = static_cast<DECUMA_UINT32>(INSTANT_GESTURE_HEIGHT_THRESHOLD_MM / 25.4 * dpi);
gestureRecognizer.setDpi(dpi);
- QVariantList horizontalRulers(traceScreenInfo.value(QLatin1String("horizontalRulers"), QVariantList()).toList());
- if (horizontalRulers.count() > 2) {
- sessionSettings.baseline = horizontalRulers.last().toInt();
- sessionSettings.helpline = 0;
- sessionSettings.topline = horizontalRulers.first().toInt();
- sessionSettings.supportLineSet = baselineAndTopline;
- sessionSettings.UIInputGuide = supportlines;
- } else if (horizontalRulers.count() == 2) {
- sessionSettings.baseline = horizontalRulers.last().toInt();
- sessionSettings.helpline = horizontalRulers.first().toInt();
- sessionSettings.topline = 0;
- sessionSettings.supportLineSet = baselineAndHelpline;
- sessionSettings.UIInputGuide = supportlines;
- } else {
- sessionSettings.baseline = 0;
- sessionSettings.helpline = 0;
- sessionSettings.topline = 0;
- sessionSettings.supportLineSet = baselineAndHelpline;
- sessionSettings.UIInputGuide = none;
- }
+ sessionSettings.baseline = 0;
+ sessionSettings.helpline = 0;
+ sessionSettings.topline = 0;
+ sessionSettings.supportLineSet = baselineAndHelpline;
+ sessionSettings.UIInputGuide = none;
DECUMA_STATUS status = DECUMA_API(ChangeSessionSettings)(decumaSession, &sessionSettings);
Q_ASSERT(status == decumaNoError);
@@ -1100,10 +1349,8 @@ public:
stopResultTimer();
// Dictionary must be completed before the arc addition can begin
- if (dictionaryTask) {
- dictionaryTask->wait();
- dictionaryTask.reset();
- }
+ worker->waitForAllTasksOfType<T9WriteDictionaryTask>();
+ dictionaryTask.reset();
// Cancel the current recognition task
worker->removeAllTasks<T9WriteRecognitionResultsTask>();
@@ -1113,6 +1360,13 @@ public:
recognitionTask.reset();
}
+ // Check for hard limit on the size the trace list
+ if (traceList.count() >= traceListHardLimit) {
+ worker->waitForAllTasksOfType<T9WriteAddArcTask>();
+ while (traceListHardLimit < traceList.count())
+ delete traceList.takeFirst();
+ }
+
#ifdef QT_VIRTUALKEYBOARD_RECORD_TRACE_INPUT
if (!unipenTrace)
unipenTrace.reset(new UnipenTrace(traceCaptureDeviceInfo, traceScreenInfo));
@@ -1128,7 +1382,25 @@ public:
if (!arcAdditionStarted) {
worker->waitForAllTasks();
- status = DECUMA_API(BeginArcAddition)(decumaSession);
+
+ DECUMA_RECOGNITION_SETTINGS recSettings;
+ memset(&recSettings, 0, sizeof(recSettings));
+
+ // Boost dictionary words by default
+ recSettings.boostLevel = attachedDictionary || attachedDynamicDictionaries.size() > 0 ? boostDictWords : noBoost;
+
+ // Disable dictionary boost in UCR mode for URL and E-mail input
+ // Otherwise it will completely mess input
+ Q_Q(T9WriteInputMethod);
+ const Qt::InputMethodHints inputMethodHints = q->inputContext()->inputMethodHints();
+ if (sessionSettings.recognitionMode == ucrMode && (inputMethodHints & (Qt::ImhUrlCharactersOnly | Qt::ImhEmailCharactersOnly)))
+ recSettings.boostLevel = noBoost;
+
+ recSettings.stringCompleteness = canBeContinued;
+ if (!stringStart.isEmpty())
+ recSettings.pStringStart = const_cast<DECUMA_UNICODE *>(stringStart.utf16());
+
+ status = DECUMA_API(BeginArcAddition)(decumaSession, &recSettings);
Q_ASSERT(status == decumaNoError);
arcAdditionStarted = true;
}
@@ -1183,46 +1455,50 @@ public:
void noteSelected(int index)
{
- if (wordCandidatesHwrResultIndex.isEmpty())
+ if (index < 0 || index >= wordCandidates.size())
return;
qCDebug(lcT9Write) << "T9WriteInputMethodPrivate::noteSelected():" << index;
- Q_ASSERT(index >= 0 && index < wordCandidatesHwrResultIndex.length());
- int resultIndex = wordCandidatesHwrResultIndex[index];
- DECUMA_API(NoteSelectedCandidate)(decumaSession, resultIndex);
+ const T9WriteWordCandidate &wordCandidate = wordCandidates[index];
+ switch (wordCandidate.origin) {
+ case T9WriteWordCandidate::Origin::T9Write:
+ DECUMA_API(NoteSelectedCandidate)(decumaSession, wordCandidate.resultIndex);
+ break;
+#ifdef HAVE_XT9
+ case T9WriteWordCandidate::Origin::XT9:
+ {
+ Xt9AwIme *xt9AwIme = static_cast<Xt9AwIme *>(xt9Ime.data());
+ if (xt9AwIme) {
+ xt9AwIme->noteWordDone(wordCandidate.symbs);
+ xt9AwIme->selectWord(wordCandidate.resultIndex, true);
+ }
+ break;
+ }
+#endif
+ default:
+ break;
+ }
}
void restartRecognition()
{
qCDebug(lcT9Write) << "T9WriteInputMethodPrivate::restartRecognition()";
- Q_Q(T9WriteInputMethod);
-
worker->removeAllTasks<T9WriteRecognitionResultsTask>();
if (recognitionTask) {
recognitionTask->cancelRecognition();
recognitionTask.reset();
}
- // Boost dictionary words by default
- BOOST_LEVEL boostLevel = attachedDictionary ? boostDictWords : noBoost;
-
- // Disable dictionary boost in UCR mode for URL and E-mail input
- // Otherwise it will completely mess input
- const Qt::InputMethodHints inputMethodHints = q->inputContext()->inputMethodHints();
- if (sessionSettings.recognitionMode == ucrMode && (inputMethodHints & (Qt::ImhUrlCharactersOnly | Qt::ImhEmailCharactersOnly)))
- boostLevel = noBoost;
-
QSharedPointer<T9WriteRecognitionResult> recognitionResult(new T9WriteRecognitionResult(resultId, 9, 64));
- recognitionTask.reset(new T9WriteRecognitionTask(recognitionResult, instantGestureSettings,
- boostLevel, stringStart));
+ recognitionTask.reset(new T9WriteRecognitionTask(recognitionResult));
worker->addTask(recognitionTask);
QSharedPointer<T9WriteRecognitionResultsTask> resultsTask(new T9WriteRecognitionResultsTask(recognitionResult));
- q->connect(resultsTask.data(), SIGNAL(resultsAvailable(const QVariantList &)), SLOT(resultsAvailable(const QVariantList &)));
+ QObjectPrivate::connect(resultsTask.data(), &T9WriteRecognitionResultsTask::resultsAvailable, this, &T9WriteInputMethodPrivate::processResultCheckTimer, Qt::QueuedConnection);
worker->addTask(resultsTask);
- resetResultTimer();
+ resetResultTimer(cjk ? Settings::instance()->hwrTimeoutForCjk() : Settings::instance()->hwrTimeoutForAlphabetic());
}
void waitForRecognitionResults()
@@ -1232,7 +1508,6 @@ public:
qCDebug(lcT9Write) << "T9WriteInputMethodPrivate::waitForRecognitionResults()";
worker->waitForAllTasks();
- processResult();
}
bool finishRecognition(bool emitSelectionListChanged = true)
@@ -1254,6 +1529,7 @@ public:
recognitionTask.reset();
result = true;
}
+ worker->waitForAllTasks();
clearTraces();
@@ -1264,7 +1540,6 @@ public:
if (!wordCandidates.isEmpty()) {
wordCandidates.clear();
- wordCandidatesHwrResultIndex.clear();
activeWordIndex = -1;
if (emitSelectionListChanged) {
Q_Q(T9WriteInputMethod);
@@ -1305,7 +1580,8 @@ public:
if (sessionSettings.recognitionMode != scrMode) {
index = index >= 0 ? index : activeWordIndex;
noteSelected(index);
- QString finalWord = wordCandidates.at(index);
+ QString finalWord = wordCandidates.at(index).symbs;
+ dlmAddWord(finalWord);
#ifdef QT_VIRTUALKEYBOARD_RECORD_TRACE_INPUT
// Record trace
@@ -1334,7 +1610,7 @@ public:
} else if (sessionSettings.recognitionMode == scrMode) {
QString finalWord = scrResult;
finishRecognition();
- q->inputContext()->inputEngine()->virtualKeyClick((Qt::Key)finalWord.at(0).unicode(), finalWord, Qt::NoModifier);
+ q->inputContext()->inputEngine()->virtualKeyClick(static_cast<Qt::Key>(finalWord.at(0).unicode()), finalWord, Qt::NoModifier);
}
return true;
@@ -1358,27 +1634,96 @@ public:
}
}
- void processResult()
+ void dictionaryLoadCompleted(QSharedPointer<T9WriteAbstractDictionary> dictionary)
+ {
+ // Note: This method is called in worker thread context
+ const std::lock_guard<QRecursiveMutex> dictionaryGuard(dictionaryLock);
+
+ if (!dictionary)
+ return;
+
+ qCDebug(lcT9Write) << "T9WriteInputMethodPrivate::dictionaryLoadCompleted():"
+ << dictionary->name() << dictionary->data() << dictionary->size();
+
+ Q_Q(T9WriteInputMethod);
+ QVirtualKeyboardInputContext *ic = q->inputContext();
+ if (ic && dictionary->name() == dictionaryFileName) {
+ loadedDictionary = dictionary;
+ if (sessionSettings.recognitionMode != scrMode &&
+ !ic->inputMethodHints().testFlag(Qt::ImhNoPredictiveText) &&
+ !attachedDictionary) {
+ if (attachDictionary(loadedDictionary))
+ attachedDictionary = loadedDictionary;
+ }
+ }
+ }
+
+ void recognitionError(int status)
+ {
+ qCDebug(lcT9Write) << "T9WriteInputMethodPrivate::recognitionError():" << status;
+ Q_Q(T9WriteInputMethod);
+ q->reset();
+ }
+
+ void processResultCheckTimer(const QVariantList &resultList)
+ {
+ bool resultTimerWasRunning = resultTimer != 0;
+
+ processResult(resultList);
+
+ // Restart the result timer now if it stopped before the results were completed
+ if (!resultTimerWasRunning && (!scrResult.isEmpty() || !wordCandidates.isEmpty()))
+ resetResultTimer(0);
+
+ }
+
+ void processResult(const QVariantList &resultList)
{
qCDebug(lcT9Write) << "T9WriteInputMethodPrivate::processResult()";
+
+#ifdef SENSITIVE_DEBUG
+ if (lcT9Write().isDebugEnabled()) {
+ for (int i = 0; i < resultList.size(); i++) {
+ QVariantMap result = resultList.at(i).toMap();
+ QString resultPrint = QStringLiteral("%1: ").arg(i + 1);
+ QString resultChars = result.value(QLatin1String("chars")).toString();
+ if (!resultChars.isEmpty())
+ resultPrint.append(resultChars);
+ if (result.contains(QLatin1String("gesture"))) {
+ if (!resultChars.isEmpty())
+ resultPrint.append(QLatin1String(", "));
+ QString gesture = result[QLatin1String("gesture")].toString();
+ resultPrint.append(QLatin1String("gesture ="));
+ for (const QChar &chr : gesture) {
+ resultPrint.append(QString::fromLatin1(" 0x%1").arg(chr.unicode(), 0, 16));
+ }
+ }
+ qCDebug(lcT9Write) << resultPrint.toUtf8().constData();
+ }
+ }
+#endif
+
Q_Q(T9WriteInputMethod);
QVirtualKeyboardInputContext *ic = q->inputContext();
if (!ic)
return;
- QStringList newWordCandidates;
- QList<int> newWordCandidatesHwrResultIndex;
+#ifdef HAVE_XT9
+ int xt9DefaultListIndex = 0;
+ QStringList xt9Candidates;
+#endif
+
+ QList<T9WriteWordCandidate> newWordCandidates;
+ int newActiveWordIndex = -1;
QString resultString;
QString gesture;
QVariantList symbolStrokes;
{
- QMutexLocker resultListGuard(&resultListLock);
if (resultList.isEmpty())
return;
if (resultList.first().toMap()[QLatin1String("resultId")] != resultId) {
qCDebug(lcT9Write) << "T9WriteInputMethodPrivate::processResult(): resultId mismatch" << resultList.first().toMap()[QLatin1String("resultId")] << "(" << resultId << ")";
- resultList.clear();
return;
}
lastResultId = resultId;
@@ -1396,9 +1741,8 @@ public:
}
if (!resultChars.isEmpty()) {
resultChars = caseFormatter.formatString(resultChars);
- if (sessionSettings.recognitionMode != scrMode) {
- newWordCandidates.append(resultChars);
- newWordCandidatesHwrResultIndex.append(i);
+ if (sessionSettings.recognitionMode != scrMode && !newWordCandidates.contains(T9WriteWordCandidate(resultChars))) {
+ newWordCandidates.append(T9WriteWordCandidate(resultChars, i, T9WriteWordCandidate::Origin::T9Write));
}
}
if (i == 0) {
@@ -1409,6 +1753,9 @@ public:
symbolStrokes = result[QLatin1String("symbolStrokes")].toList();
if (sessionSettings.recognitionMode == scrMode)
break;
+#ifdef HAVE_XT9
+ xt9Candidates = xt9BuildSelectionList(resultString, &xt9DefaultListIndex);
+#endif
} else {
// Add a gesture symbol to the secondary candidate
if (sessionSettings.recognitionMode != scrMode && result.contains(QLatin1String("gesture"))) {
@@ -1418,29 +1765,37 @@ public:
if (!symbol.isNull()) {
// Check for duplicates
bool duplicateFound = false;
- for (const QString &wordCandidate : newWordCandidates) {
- duplicateFound = wordCandidate.size() == 1 && wordCandidate.at(0) == symbol;
+ for (const T9WriteWordCandidate &wordCandidate : newWordCandidates) {
+ duplicateFound = wordCandidate.symbs.size() == 1 && wordCandidate.symbs.at(0) == symbol;
if (duplicateFound)
break;
}
if (!duplicateFound) {
if (!resultChars.isEmpty()) {
- newWordCandidates.last().append(symbol);
+ newWordCandidates.last().symbs.append(symbol);
} else {
- newWordCandidates.append(symbol);
- newWordCandidatesHwrResultIndex.append(i);
+ newWordCandidates.append(T9WriteWordCandidate(symbol, i, T9WriteWordCandidate::Origin::T9Write));
}
}
}
}
}
+#ifdef HAVE_XT9
+ if (i >= 2 && !xt9Candidates.isEmpty())
+ break;
+#endif
}
}
- resultList.clear();
+ if (!newWordCandidates.isEmpty())
+ newActiveWordIndex = 0;
+#ifdef HAVE_XT9
+ if (!xt9Candidates.isEmpty())
+ appendWordCandidates(newWordCandidates, newActiveWordIndex, resultString, xt9Candidates, xt9DefaultListIndex, T9WriteWordCandidate::Origin::XT9);
+#endif
}
- bool wordCandidatesChanged = wordCandidates != newWordCandidates;
+ bool wordCandidatesChanged = true;
#ifndef QT_VIRTUALKEYBOARD_RECORD_TRACE_INPUT
// Delete trace history
@@ -1449,15 +1804,23 @@ public:
if (worker->numberOfPendingTasks() == 0) {
const QVirtualKeyboardInputEngine::InputMode inputMode = q->inputEngine()->inputMode();
- if (sessionSettings.recognitionMode == mcrMode && !symbolStrokes.isEmpty() &&
+ if (sessionSettings.recognitionMode != scrMode &&
inputMode != QVirtualKeyboardInputEngine::InputMode::ChineseHandwriting &&
inputMode != QVirtualKeyboardInputEngine::InputMode::JapaneseHandwriting &&
inputMode != QVirtualKeyboardInputEngine::InputMode::KoreanHandwriting) {
- int activeTraces = symbolStrokes.at(symbolStrokes.count() - 1).toInt();
- if (symbolStrokes.count() > 1)
- activeTraces += symbolStrokes.at(symbolStrokes.count() - 2).toInt();
- while (activeTraces < traceList.count())
- delete traceList.takeFirst();
+ const int hwrTimeout = cjk ?
+ Settings::instance()->hwrTimeoutForCjk() :
+ Settings::instance()->hwrTimeoutForAlphabetic();
+ for (int traceIndex = 0; traceIndex < traceList.size();) {
+ QVirtualKeyboardTrace *trace = traceList.at(traceIndex);
+ if (trace->opacity() > 0) {
+ trace->startHideTimer(hwrTimeout);
+ ++traceIndex;
+ } else {
+ traceList.removeAt(traceIndex);
+ delete trace;
+ }
+ }
}
// Enforce hard limit for number of traces
@@ -1490,8 +1853,7 @@ public:
if (wordCandidatesChanged) {
wordCandidates = newWordCandidates;
- wordCandidatesHwrResultIndex = newWordCandidatesHwrResultIndex;
- activeWordIndex = wordCandidates.isEmpty() ? -1 : 0;
+ activeWordIndex = wordCandidates.isEmpty() ? -1 : newActiveWordIndex;
emit q->selectionListChanged(QVirtualKeyboardSelectionListModel::Type::WordCandidateList);
emit q->selectionListActiveItemChanged(QVirtualKeyboardSelectionListModel::Type::WordCandidateList, activeWordIndex);
}
@@ -1649,6 +2011,269 @@ public:
return false;
}
+ void onAvailableDynamicDictionariesChanged()
+ {
+ if (!worker)
+ return;
+
+ const std::lock_guard<QRecursiveMutex> dictionaryGuard(dictionaryLock);
+ QVirtualKeyboardDictionaryManager *dictionaryManager = QVirtualKeyboardDictionaryManager::instance();
+
+ const QStringList availableDictionaries = dictionaryManager->availableDictionaries();
+ for (const QString &dictionaryName : availableDictionaries) {
+
+ if (!dynamicDictionaries.contains(dictionaryName)) {
+
+ DECUMA_SRC_DICTIONARY_INFO sourceInfo;
+ sourceInfo.srcType = decumaTextList;
+ sourceInfo.bNoFrequencyRanking = 1;
+ sourceInfo.multiStepWordSeparator = 0;
+
+ QSharedPointer<T9WriteAbstractSource> sourceDictionary(
+ new T9WriteStringSource(
+ sourceInfo,
+ dictionaryManager->dictionary(dictionaryName)->contents(),
+ dictionaryName));
+
+ QSharedPointer<T9WriteDictionary> dynamicDictionary(
+ new T9WriteDictionary(
+ sourceDictionary,
+ decumaSession,
+ memFuncs,
+ cjk));
+
+ dynamicDictionaries[dictionaryName] = dynamicDictionary;
+
+ QSharedPointer<T9WriteDictionaryTask> dynamicDictionaryTask(
+ new T9WriteDictionaryTask(
+ dynamicDictionary,
+ true));
+
+ Q_Q(T9WriteInputMethod);
+ q->connect(dynamicDictionaryTask.data(),
+ &T9WriteDictionaryTask::completed,
+ [=](QSharedPointer<T9WriteAbstractDictionary> dynamicDictionary) {
+
+ const std::lock_guard<QRecursiveMutex> dictionaryGuard(dictionaryLock);
+
+ if (dynamicDictionary->data()) {
+ if (dictionaryManager->activeDictionaries().contains(dictionaryName) &&
+ !attachedDynamicDictionaries.contains(dictionaryName) &&
+ attachDictionary(dynamicDictionary))
+ attachedDynamicDictionaries[dictionaryName] = dynamicDictionary;
+ } else {
+ dynamicDictionaries.remove(dictionaryName);
+ }
+ });
+
+ worker->addTask(dynamicDictionaryTask);
+ }
+
+#ifdef HAVE_XT9
+ if (!xt9DynamicDictionaries.contains(dictionaryName)) {
+ if (xt9Ime) {
+ QVirtualKeyboardDictionary *dictionary = dictionaryManager->dictionary(dictionaryName);
+ const quint16 id = static_cast<quint16>(xt9DynamicDictionaryNextId.fetchAndAddRelaxed(1));
+ xt9DynamicDictionaries[dictionaryName] = id;
+
+ xt9Ime->updateIndex(id, dictionary->contents());
+
+ Q_Q(T9WriteInputMethod);
+ q->connect(dictionary, &QVirtualKeyboardDictionary::contentsChanged, q, [=]() {
+ xt9Ime->updateIndex(id, dictionary->contents());
+ if (xt9AttachedDynamicDictionaries.contains(dictionaryName))
+ xt9Ime->mountIndex(id);
+ });
+ }
+ }
+#endif
+ }
+ }
+
+ void onActiveDynamicDictionariesChanged()
+ {
+ if (!worker)
+ return;
+
+ const std::lock_guard<QRecursiveMutex> dictionaryGuard(dictionaryLock);
+ QVirtualKeyboardDictionaryManager *dictionaryManager = QVirtualKeyboardDictionaryManager::instance();
+
+ // Attach
+ const QStringList activeDictionaries = dictionaryManager->activeDictionaries();
+ for (const QString &dictionaryName : activeDictionaries) {
+
+ QSharedPointer<T9WriteAbstractDictionary> dynamicDictionary = dynamicDictionaries.value(dictionaryName);
+ if (dynamicDictionary && dynamicDictionary->data() &&
+ !attachedDynamicDictionaries.contains(dictionaryName) &&
+ dynamicDictionary->isCompleted() &&
+ attachDictionary(dynamicDictionary)) {
+ attachedDynamicDictionaries[dictionaryName] = dynamicDictionary;
+ }
+#ifdef HAVE_XT9
+ if (xt9Ime) {
+ if (!xt9AttachedDynamicDictionaries.contains(dictionaryName)) {
+ xt9AttachDictionary(dictionaryName);
+ }
+ }
+#endif
+ }
+
+ // Detach
+ const QStringList attachedDynamicDictionariesKeys = attachedDynamicDictionaries.keys();
+ for (const QString &dictionaryName : attachedDynamicDictionariesKeys) {
+ if (!activeDictionaries.contains(dictionaryName)) {
+ if (attachedDynamicDictionaries.contains(dictionaryName)) {
+ detachDictionary(attachedDynamicDictionaries[dictionaryName]);
+ attachedDynamicDictionaries.remove(dictionaryName);
+ }
+ }
+ }
+#ifdef HAVE_XT9
+ // Detach (XT9)
+ if (xt9Ime) {
+ const QStringList xt9AttachedDynamicDictionariesKeys = xt9AttachedDynamicDictionaries.keys();
+ for (const QString &dictionaryName : xt9AttachedDynamicDictionariesKeys) {
+ if (!activeDictionaries.contains(dictionaryName)) {
+ xt9DetachDictionary(dictionaryName);
+ }
+ }
+ }
+#endif
+ }
+
+ bool isDlmActive()
+ {
+ const std::lock_guard<QRecursiveMutex> dictionaryGuard(dictionaryLock);
+ return !loadedDlmDictionary.isNull();
+ }
+
+ QString dlmFileName() const
+ {
+ QString suffix;
+ switch (engineMode) {
+ case T9WriteInputMethod::EngineMode::Alphabetic:
+ case T9WriteInputMethod::EngineMode::Arabic:
+ case T9WriteInputMethod::EngineMode::Hebrew:
+ case T9WriteInputMethod::EngineMode::Thai:
+ suffix = QStringLiteral("aw");
+ break;
+ case T9WriteInputMethod::EngineMode::SimplifiedChinese:
+ case T9WriteInputMethod::EngineMode::TraditionalChinese:
+ case T9WriteInputMethod::EngineMode::HongKongChinese:
+ suffix = QStringLiteral("cp");
+ break;
+ case T9WriteInputMethod::EngineMode::Japanese:
+ suffix = QStringLiteral("j");
+ break;
+ case T9WriteInputMethod::EngineMode::Korean:
+ suffix = QStringLiteral("k");
+ break;
+ default:
+ break;
+ }
+ return QStringLiteral("cerence-hwr%1.dlm").arg(suffix);
+ }
+
+ void dlmActivate()
+ {
+ qCDebug(lcT9Write) << "T9WriteInputMethodPrivate::dlmActivate()";
+
+ const std::lock_guard<QRecursiveMutex> dictionaryGuard(dictionaryLock);
+ if (loadedDlmDictionary)
+ return;
+
+ DECUMA_SRC_DICTIONARY_INFO sourceInfo;
+ sourceInfo.srcType = decumaPortableHWRDictionary;
+ sourceInfo.bNoFrequencyRanking = 1;
+ sourceInfo.multiStepWordSeparator = 0;
+
+ QString dictionaryName(QStringLiteral("%1/%2").arg(Settings::instance()->userDataPath(), dlmFileName()));
+ QSharedPointer<T9WriteAbstractSource> sourceDictionary(
+ new T9WriteFileSource(
+ sourceInfo,
+ dictionaryName));
+
+ loadedDlmDictionary.reset(new T9WriteDynamicDictionary(
+ sourceDictionary,
+ CERENCE_HWR_DLM_MAX_WORDS,
+ memFuncs,
+ cjk));
+
+ QSharedPointer<T9WriteDictionaryTask> dynamicDictionaryTask(
+ new T9WriteDictionaryTask(
+ loadedDlmDictionary,
+ false));
+
+ Q_Q(T9WriteInputMethod);
+ q->connect(dynamicDictionaryTask.data(),
+ &T9WriteDictionaryTask::completed,
+ [=](QSharedPointer<T9WriteAbstractDictionary> dynamicDictionary) {
+
+ const std::lock_guard<QRecursiveMutex> dictionaryGuard(dictionaryLock);
+
+ if (!loadedDlmDictionary || dynamicDictionary != loadedDlmDictionary)
+ return;
+
+ if (dynamicDictionary->data()) {
+ if (attachedDlmDictionary != dynamicDictionary &&
+ attachDictionary(dynamicDictionary)) {
+ attachedDlmDictionary = dynamicDictionary;
+ }
+ } else {
+ dlmDeactivate();
+ }
+ });
+
+ worker->addTask(dynamicDictionaryTask);
+ }
+
+ void dlmDeactivate()
+ {
+ const std::lock_guard<QRecursiveMutex> dictionaryGuard(dictionaryLock);
+
+ if (loadedDlmDictionary) {
+ qCDebug(lcT9Write) << "T9WriteInputMethodPrivate::dlmDeactivate()";
+ loadedDlmDictionary.reset();
+ }
+
+ if (attachedDlmDictionary) {
+ detachDictionary(attachedDlmDictionary);
+ attachedDlmDictionary.reset();
+ }
+ }
+
+ void dlmAddWord(const QString &word)
+ {
+ if (!isDlmActive() || !worker)
+ return;
+
+ qCDebug(lcT9Write) << "T9WriteInputMethodPrivate::dlmAddWord()";
+
+ QSharedPointer<T9WriteDlmWordTask> learnWordTask(new T9WriteDlmWordTask(loadedDlmDictionary, word, stringStart));
+ worker->addTask(learnWordTask);
+ }
+
+ bool dlmHasWord(const QString &word)
+ {
+ if (!isDlmActive() || !worker)
+ return false;
+
+ worker->waitForAllTasks();
+
+ const std::lock_guard<QRecursiveMutex> dictionaryGuard(dictionaryLock);
+ T9WriteDynamicDictionary *dictionary = static_cast<T9WriteDynamicDictionary *>(loadedDlmDictionary.data());
+
+ return dictionary->hasWord(word);
+ }
+
+ void dlmRemoveWord(const QString &word)
+ {
+ qCDebug(lcT9Write) << "T9WriteInputMethodPrivate::dlmRemoveWord()";
+
+ QSharedPointer<T9WriteDlmRemoveWordTask> removeWordTask(new T9WriteDlmRemoveWordTask(loadedDlmDictionary, word));
+ worker->addTask(removeWordTask);
+ }
+
T9WriteInputMethod *q_ptr;
static const DECUMA_MEM_FUNCTIONS memFuncs;
bool cjk;
@@ -1656,8 +2281,7 @@ public:
QByteArray currentContext;
DECUMA_SESSION_SETTINGS sessionSettings;
DECUMA_INSTANT_GESTURE_SETTINGS instantGestureSettings;
- QString defaultHwrDbPath;
- QString defaultDictionaryDbPath;
+ QStringList defaultHwrDbPaths;
QFile hwrDbFile;
QList<DECUMA_UINT32> languageCategories;
QList<DECUMA_UINT32> symbolCategories;
@@ -1666,20 +2290,23 @@ public:
int traceListHardLimit;
QRecursiveMutex dictionaryLock;
QString dictionaryFileName;
- QSharedPointer<T9WriteDictionary> loadedDictionary;
- QSharedPointer<T9WriteDictionary> attachedDictionary;
+ QSharedPointer<T9WriteAbstractDictionary> loadedDictionary;
+ QSharedPointer<T9WriteAbstractDictionary> attachedDictionary;
+ QSharedPointer<Xt9LdbManager> ldbManager;
QSharedPointer<T9WriteDictionaryTask> dictionaryTask;
+ QMap<QString, QSharedPointer<T9WriteAbstractDictionary>> dynamicDictionaries;
+ QMap<QString, QSharedPointer<T9WriteAbstractDictionary>> attachedDynamicDictionaries;
+ QSharedPointer<T9WriteAbstractDictionary> loadedDlmDictionary;
+ QSharedPointer<T9WriteAbstractDictionary> attachedDlmDictionary;
+ QMetaObject::Connection availableDictionariesChangedConnection;
+ QMetaObject::Connection activeDictionariesChangedConnection;
QSharedPointer<T9WriteRecognitionTask> recognitionTask;
- QMutex resultListLock;
- QVariantList resultList;
int resultId;
int lastResultId;
int resultTimer;
- QMetaObject::Connection processResultConnection;
QByteArray session;
DECUMA_SESSION *decumaSession;
- QStringList wordCandidates;
- QList<int> wordCandidatesHwrResultIndex;
+ QList<T9WriteWordCandidate> wordCandidates;
QString stringStart;
QString scrResult;
int activeWordIndex;
@@ -1691,6 +2318,14 @@ public:
#ifdef QT_VIRTUALKEYBOARD_RECORD_TRACE_INPUT
QScopedPointer<UnipenTrace> unipenTrace;
#endif
+#ifdef HAVE_XT9
+ QScopedPointer<Xt9Ime> xt9Ime;
+ QMap<QString, quint16> xt9DynamicDictionaries;
+ QMap<QString, quint16> xt9AttachedDynamicDictionaries;
+ QAtomicInt xt9DynamicDictionaryNextId;
+ QMetaObject::Connection defaultInputMethodDisabledChangedConnection;
+ QMetaObject::Connection defaultDictionaryDisabledChangedConnection;
+#endif
};
const DECUMA_MEM_FUNCTIONS T9WriteInputMethodPrivate::memFuncs = {
@@ -1706,13 +2341,16 @@ const DECUMA_MEM_FUNCTIONS T9WriteInputMethodPrivate::memFuncs = {
*/
T9WriteInputMethod::T9WriteInputMethod(QObject *parent) :
- QVirtualKeyboardAbstractInputMethod(parent),
- d_ptr(new T9WriteInputMethodPrivate(this))
+ QVirtualKeyboardAbstractInputMethod(*new T9WriteInputMethodPrivate(this), parent)
{
}
T9WriteInputMethod::~T9WriteInputMethod()
{
+}
+
+void T9WriteInputMethod::clearInputMode()
+{
Q_D(T9WriteInputMethod);
d->exitEngine();
}
@@ -1727,9 +2365,9 @@ QList<QVirtualKeyboardInputEngine::InputMode> T9WriteInputMethod::inputModes(con
// Add primary input mode
switch (mode) {
-#ifdef HAVE_T9WRITE_ALPHABETIC
+#ifdef HAVE_CERENCE_HWR_ALPHABETIC
case T9WriteInputMethod::EngineMode::Alphabetic:
- if (d->findHwrDb(T9WriteInputMethod::EngineMode::Alphabetic, d->defaultHwrDbPath).isEmpty())
+ if (d->findHwrDb(T9WriteInputMethod::EngineMode::Alphabetic).isEmpty())
return availableInputModes;
if (!(inputMethodHints & (Qt::ImhDialableCharactersOnly | Qt::ImhFormattedNumbersOnly | Qt::ImhDigitsOnly | Qt::ImhLatinOnly))) {
switch (loc.script()) {
@@ -1749,41 +2387,41 @@ QList<QVirtualKeyboardInputEngine::InputMode> T9WriteInputMethod::inputModes(con
}
break;
case T9WriteInputMethod::EngineMode::Arabic:
- if (d->findHwrDb(T9WriteInputMethod::EngineMode::Arabic, d->defaultHwrDbPath).isEmpty())
+ if (d->findHwrDb(T9WriteInputMethod::EngineMode::Arabic).isEmpty())
return availableInputModes;
if (!(inputMethodHints & (Qt::ImhDialableCharactersOnly | Qt::ImhFormattedNumbersOnly | Qt::ImhDigitsOnly | Qt::ImhLatinOnly)))
availableInputModes.append(QVirtualKeyboardInputEngine::InputMode::Arabic);
break;
case T9WriteInputMethod::EngineMode::Hebrew:
- if (d->findHwrDb(T9WriteInputMethod::EngineMode::Hebrew, d->defaultHwrDbPath).isEmpty())
+ if (d->findHwrDb(T9WriteInputMethod::EngineMode::Hebrew).isEmpty())
return availableInputModes;
if (!(inputMethodHints & (Qt::ImhDialableCharactersOnly | Qt::ImhFormattedNumbersOnly | Qt::ImhDigitsOnly | Qt::ImhLatinOnly)))
availableInputModes.append(QVirtualKeyboardInputEngine::InputMode::Hebrew);
break;
case T9WriteInputMethod::EngineMode::Thai:
- if (d->findHwrDb(T9WriteInputMethod::EngineMode::Thai, d->defaultHwrDbPath).isEmpty())
+ if (d->findHwrDb(T9WriteInputMethod::EngineMode::Thai).isEmpty())
return availableInputModes;
if (!(inputMethodHints & (Qt::ImhDialableCharactersOnly | Qt::ImhFormattedNumbersOnly | Qt::ImhDigitsOnly | Qt::ImhLatinOnly)))
availableInputModes.append(QVirtualKeyboardInputEngine::InputMode::Thai);
break;
#endif
-#ifdef HAVE_T9WRITE_CJK
+#ifdef HAVE_CERENCE_HWR_CJK
case T9WriteInputMethod::EngineMode::SimplifiedChinese:
case T9WriteInputMethod::EngineMode::TraditionalChinese:
case T9WriteInputMethod::EngineMode::HongKongChinese:
- if (d->findHwrDb(mode, d->defaultHwrDbPath).isEmpty())
+ if (d->findHwrDb(mode).isEmpty())
return availableInputModes;
if (!(inputMethodHints & (Qt::ImhDialableCharactersOnly | Qt::ImhFormattedNumbersOnly | Qt::ImhDigitsOnly | Qt::ImhLatinOnly)))
availableInputModes.append(QVirtualKeyboardInputEngine::InputMode::ChineseHandwriting);
break;
case T9WriteInputMethod::EngineMode::Japanese:
- if (d->findHwrDb(T9WriteInputMethod::EngineMode::Japanese, d->defaultHwrDbPath).isEmpty())
+ if (d->findHwrDb(T9WriteInputMethod::EngineMode::Japanese).isEmpty())
return availableInputModes;
if (!(inputMethodHints & (Qt::ImhDialableCharactersOnly | Qt::ImhFormattedNumbersOnly | Qt::ImhDigitsOnly | Qt::ImhLatinOnly)))
availableInputModes.append(QVirtualKeyboardInputEngine::InputMode::JapaneseHandwriting);
break;
case T9WriteInputMethod::EngineMode::Korean:
- if (d->findHwrDb(T9WriteInputMethod::EngineMode::Korean, d->defaultHwrDbPath).isEmpty())
+ if (d->findHwrDb(T9WriteInputMethod::EngineMode::Korean).isEmpty())
return availableInputModes;
if (!(inputMethodHints & (Qt::ImhDialableCharactersOnly | Qt::ImhFormattedNumbersOnly | Qt::ImhDigitsOnly | Qt::ImhLatinOnly)))
availableInputModes.append(QVirtualKeyboardInputEngine::InputMode::KoreanHandwriting);
@@ -1845,21 +2483,14 @@ bool T9WriteInputMethod::keyEvent(Qt::Key key, const QString &text, Qt::Keyboard
if (preeditText.length() > 1) {
preeditText.chop(1);
ic->setPreeditText(preeditText);
- // WA: T9Write CJK may crash in some cases with long stringStart.
- // Therefore we commit the current input and finish the recognition.
- if (d->cjk) {
- d->waitForRecognitionResults();
- ic->commit();
- d->finishRecognition();
- return true;
- }
d->caseFormatter.ensureLength(preeditText.length(), d->textCase);
T9WriteCaseFormatter caseFormatter(d->caseFormatter);
d->finishRecognition(false);
d->caseFormatter = caseFormatter;
d->stringStart = preeditText;
- d->wordCandidates.append(preeditText);
+ int xt9DefaultListIndex = 0;
d->activeWordIndex = 0;
+ d->appendWordCandidates(d->wordCandidates, d->activeWordIndex, d->stringStart, d->xt9BuildSelectionList(d->stringStart, &xt9DefaultListIndex), xt9DefaultListIndex, T9WriteWordCandidate::Origin::XT9);
emit selectionListChanged(QVirtualKeyboardSelectionListModel::Type::WordCandidateList);
emit selectionListActiveItemChanged(QVirtualKeyboardSelectionListModel::Type::WordCandidateList, d->activeWordIndex);
return true;
@@ -1872,7 +2503,6 @@ bool T9WriteInputMethod::keyEvent(Qt::Key key, const QString &text, Qt::Keyboard
d->finishRecognition();
return result;
}
- break;
}
default:
@@ -1940,11 +2570,23 @@ QVariant T9WriteInputMethod::selectionListData(QVirtualKeyboardSelectionListMode
Q_D(T9WriteInputMethod);
switch (role) {
case QVirtualKeyboardSelectionListModel::Role::Display:
- result = QVariant(d->wordCandidates.at(index));
+ result = QVariant(d->wordCandidates.at(index).symbs);
break;
case QVirtualKeyboardSelectionListModel::Role::WordCompletionLength:
result.setValue(0);
break;
+ case QVirtualKeyboardSelectionListModel::Role::Dictionary:
+ {
+ QVirtualKeyboardSelectionListModel::DictionaryType dictionaryType =
+ d->dlmHasWord(d->wordCandidates.at(index).symbs) ?
+ QVirtualKeyboardSelectionListModel::DictionaryType::User :
+ QVirtualKeyboardSelectionListModel::DictionaryType::Default;
+ result = QVariant(static_cast<int>(dictionaryType));
+ break;
+ }
+ case QVirtualKeyboardSelectionListModel::Role::CanRemoveSuggestion:
+ result = QVariant(d->dlmHasWord(d->wordCandidates.at(index).symbs));
+ break;
default:
result = QVirtualKeyboardAbstractInputMethod::selectionListData(type, index, role);
break;
@@ -1956,9 +2598,63 @@ void T9WriteInputMethod::selectionListItemSelected(QVirtualKeyboardSelectionList
{
Q_UNUSED(type);
Q_D(T9WriteInputMethod);
+
+#ifdef HAVE_XT9
+ switch (d->engineMode) {
+ case T9WriteInputMethod::EngineMode::SimplifiedChinese:
+ if (inputEngine()->inputMode() != QVirtualKeyboardInputEngine::InputMode::ChineseHandwriting)
+ break;
+
+ [[fallthrough]]; case T9WriteInputMethod::EngineMode::Japanese:
+ if (d->wordCandidates[index].origin == T9WriteWordCandidate::Origin::T9Write) {
+ if (d->xt9AllSymbsArePinyin(d->wordCandidates[index].symbs)) {
+ int indexOfFirstXt9Candidate;
+ for (indexOfFirstXt9Candidate = 0; indexOfFirstXt9Candidate < d->wordCandidates.size(); ++indexOfFirstXt9Candidate) {
+ if (d->wordCandidates[indexOfFirstXt9Candidate].origin == T9WriteWordCandidate::Origin::XT9)
+ break;
+ }
+
+ while (indexOfFirstXt9Candidate < d->wordCandidates.size()) {
+ d->wordCandidates.removeAt(indexOfFirstXt9Candidate);
+ }
+
+ int xt9DefaultListIndex = 0;
+ d->appendWordCandidates(d->wordCandidates, d->activeWordIndex, d->wordCandidates[index].symbs, d->xt9BuildSelectionList(d->wordCandidates[index].symbs, &xt9DefaultListIndex), xt9DefaultListIndex, T9WriteWordCandidate::Origin::XT9);
+ d->activeWordIndex = index;
+
+ emit selectionListChanged(QVirtualKeyboardSelectionListModel::Type::WordCandidateList);
+ emit selectionListActiveItemChanged(QVirtualKeyboardSelectionListModel::Type::WordCandidateList, d->activeWordIndex);
+ return;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+#endif
+
d->select(index);
}
+bool T9WriteInputMethod::selectionListRemoveItem(QVirtualKeyboardSelectionListModel::Type type, int index)
+{
+ Q_UNUSED(type)
+ Q_D(T9WriteInputMethod);
+ if (index < 0 || index >= d->wordCandidates.size())
+ return false;
+ d->dlmRemoveWord(d->wordCandidates.at(index).symbs);
+ if (d->wordCandidates.size() > 1) {
+ d->wordCandidates.removeAt(index);
+ emit selectionListChanged(QVirtualKeyboardSelectionListModel::Type::WordCandidateList);
+ emit selectionListActiveItemChanged(QVirtualKeyboardSelectionListModel::Type::WordCandidateList, d->activeWordIndex);
+ } else {
+ inputContext()->clear();
+ reset();
+ }
+ return true;
+}
+
QList<QVirtualKeyboardInputEngine::PatternRecognitionMode> T9WriteInputMethod::patternRecognitionModes() const
{
return QList<QVirtualKeyboardInputEngine::PatternRecognitionMode>()
@@ -1994,10 +2690,13 @@ bool T9WriteInputMethod::reselect(int cursorPosition, const QVirtualKeyboardInpu
const QVirtualKeyboardInputEngine::InputMode inputMode = inputEngine()->inputMode();
const int maxLength = (inputMode == QVirtualKeyboardInputEngine::InputMode::ChineseHandwriting ||
inputMode == QVirtualKeyboardInputEngine::InputMode::JapaneseHandwriting ||
- inputMode == QVirtualKeyboardInputEngine::InputMode::KoreanHandwriting) ? 0 : 32;
+ inputMode == QVirtualKeyboardInputEngine::InputMode::KoreanHandwriting) ? 16 : 32;
const QString surroundingText = ic->surroundingText();
int replaceFrom = 0;
+ if (cursorPosition > surroundingText.length())
+ return false;
+
if (reselectFlags.testFlag(QVirtualKeyboardInputEngine::ReselectFlag::WordBeforeCursor)) {
for (int i = cursorPosition - 1; i >= 0 && d->stringStart.length() < maxLength; --i) {
QChar c = surroundingText.at(i);
@@ -2055,8 +2754,9 @@ bool T9WriteInputMethod::reselect(int cursorPosition, const QVirtualKeyboardInpu
ic->setPreeditText(d->stringStart, QList<QInputMethodEvent::Attribute>(), replaceFrom, d->stringStart.length());
for (int i = 0; i < d->stringStart.length(); ++i)
d->caseFormatter.ensureLength(i + 1, d->stringStart.at(i).isUpper() ? QVirtualKeyboardInputEngine::TextCase::Upper : QVirtualKeyboardInputEngine::TextCase::Lower);
- d->wordCandidates.append(d->stringStart);
+ int xt9DefaultListIndex = 0;
d->activeWordIndex = 0;
+ d->appendWordCandidates(d->wordCandidates, d->activeWordIndex, d->stringStart, d->xt9BuildSelectionList(d->stringStart, &xt9DefaultListIndex), xt9DefaultListIndex, T9WriteWordCandidate::Origin::XT9);
emit selectionListChanged(QVirtualKeyboardSelectionListModel::Type::WordCandidateList);
emit selectionListActiveItemChanged(QVirtualKeyboardSelectionListModel::Type::WordCandidateList, d->activeWordIndex);
@@ -2101,78 +2801,5 @@ void T9WriteInputMethod::timerEvent(QTimerEvent *timerEvent)
}
}
-void T9WriteInputMethod::dictionaryLoadCompleted(QSharedPointer<T9WriteDictionary> dictionary)
-{
- Q_D(T9WriteInputMethod);
- // Note: This method is called in worker thread context
- const std::lock_guard<QRecursiveMutex> dictionaryGuard(d->dictionaryLock);
-
- if (!dictionary)
- return;
-
- qCDebug(lcT9Write) << "T9WriteInputMethod::dictionaryLoadCompleted():"
- << dictionary->fileName() << dictionary->data() << dictionary->size();
-
- QVirtualKeyboardInputContext *ic = inputContext();
- if (ic && dictionary->fileName() == d->dictionaryFileName) {
- d->loadedDictionary = dictionary;
- if (d->sessionSettings.recognitionMode != scrMode &&
- !ic->inputMethodHints().testFlag(Qt::ImhNoPredictiveText) &&
- !d->attachedDictionary) {
- if (d->attachDictionary(d->loadedDictionary))
- d->attachedDictionary = d->loadedDictionary;
- }
- }
-}
-
-void T9WriteInputMethod::resultsAvailable(const QVariantList &resultList)
-{
-#ifdef SENSITIVE_DEBUG
- if (lcT9Write().isDebugEnabled()) {
- qCDebug(lcT9Write) << "T9WriteInputMethod::resultsAvailable():";
- for (int i = 0; i < resultList.size(); i++) {
- QVariantMap result = resultList.at(i).toMap();
- QString resultPrint = QStringLiteral("%1: ").arg(i + 1);
- QString resultChars = result.value(QLatin1String("chars")).toString();
- if (!resultChars.isEmpty())
- resultPrint.append(resultChars);
- if (result.contains(QLatin1String("gesture"))) {
- if (!resultChars.isEmpty())
- resultPrint.append(QLatin1String(", "));
- QString gesture = result[QLatin1String("gesture")].toString();
- resultPrint.append(QLatin1String("gesture ="));
- for (const QChar &chr : gesture) {
- resultPrint.append(QString::fromLatin1(" 0x%1").arg(chr.unicode(), 0, 16));
- }
- }
- qCDebug(lcT9Write) << resultPrint.toUtf8().constData();
- }
- }
-#endif
- Q_D(T9WriteInputMethod);
- QMutexLocker resultListGuard(&d->resultListLock);
- d->resultList = resultList;
- emit resultListChanged();
-}
-
-void T9WriteInputMethod::processResult()
-{
- Q_D(T9WriteInputMethod);
- bool resultTimerWasRunning = d->resultTimer != 0;
-
- d->processResult();
-
- // Restart the result timer now if it stopped before the results were completed
- if (!resultTimerWasRunning && (!d->scrResult.isEmpty() || !d->wordCandidates.isEmpty()))
- d->resetResultTimer(0);
-
-}
-
-void T9WriteInputMethod::recognitionError(int status)
-{
- qCDebug(lcT9Write) << "T9WriteInputMethod::recognitionError():" << status;
- reset();
-}
-
} // namespace QtVirtualKeyboard
QT_END_NAMESPACE
diff --git a/src/plugins/t9write/plugin/t9writeinputmethod_p.h b/src/plugins/cerence/cerence-hwr/plugin/t9writeinputmethod_p.h
index 39a0b2ac..7d6f39a0 100644
--- a/src/plugins/t9write/plugin/t9writeinputmethod_p.h
+++ b/src/plugins/cerence/cerence-hwr/plugin/t9writeinputmethod_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
@@ -42,13 +42,12 @@
//
#include <QtVirtualKeyboard/qvirtualkeyboardabstractinputmethod.h>
-#include <QSharedPointer>
QT_BEGIN_NAMESPACE
namespace QtVirtualKeyboard {
class T9WriteInputMethodPrivate;
-class T9WriteDictionary;
+class T9WriteAbstractDictionary;
class T9WriteInputMethod : public QVirtualKeyboardAbstractInputMethod
{
@@ -73,6 +72,8 @@ public:
explicit T9WriteInputMethod(QObject *parent = nullptr);
~T9WriteInputMethod();
+ void clearInputMode() override;
+
QList<QVirtualKeyboardInputEngine::InputMode> inputModes(const QString &locale);
bool setInputMode(const QString &locale, QVirtualKeyboardInputEngine::InputMode inputMode);
bool setTextCase(QVirtualKeyboardInputEngine::TextCase textCase);
@@ -86,6 +87,7 @@ public:
int selectionListItemCount(QVirtualKeyboardSelectionListModel::Type type);
QVariant selectionListData(QVirtualKeyboardSelectionListModel::Type type, int index, QVirtualKeyboardSelectionListModel::Role role);
void selectionListItemSelected(QVirtualKeyboardSelectionListModel::Type type, int index);
+ bool selectionListRemoveItem(QVirtualKeyboardSelectionListModel::Type type, int index) override;
QList<QVirtualKeyboardInputEngine::PatternRecognitionMode> patternRecognitionModes() const;
QVirtualKeyboardTrace *traceBegin(
@@ -95,20 +97,8 @@ public:
bool reselect(int cursorPosition, const QVirtualKeyboardInputEngine::ReselectFlags &reselectFlags);
-signals:
- void resultListChanged();
-
protected:
void timerEvent(QTimerEvent *timerEvent);
-
-protected slots:
- void dictionaryLoadCompleted(QSharedPointer<T9WriteDictionary> dictionary);
- void resultsAvailable(const QVariantList &resultList);
- void processResult();
- void recognitionError(int status);
-
-private:
- QScopedPointer<T9WriteInputMethodPrivate> d_ptr;
};
} // namespace QtVirtualKeyboard
diff --git a/src/plugins/cerence/cerence-hwr/plugin/t9writewordcandidate.cpp b/src/plugins/cerence/cerence-hwr/plugin/t9writewordcandidate.cpp
new file mode 100644
index 00000000..a1f7df32
--- /dev/null
+++ b/src/plugins/cerence/cerence-hwr/plugin/t9writewordcandidate.cpp
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "t9writewordcandidate_p.h"
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+T9WriteWordCandidate::T9WriteWordCandidate(QString symbs, int resultIndex, T9WriteWordCandidate::Origin origin) :
+ symbs(symbs),
+ resultIndex(resultIndex),
+ origin(origin)
+{
+
+}
+
+bool operator==(const T9WriteWordCandidate &a, const T9WriteWordCandidate &b)
+{
+ return a.symbs == b.symbs;
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
diff --git a/src/plugins/cerence/cerence-hwr/plugin/t9writewordcandidate_p.h b/src/plugins/cerence/cerence-hwr/plugin/t9writewordcandidate_p.h
new file mode 100644
index 00000000..9f35d772
--- /dev/null
+++ b/src/plugins/cerence/cerence-hwr/plugin/t9writewordcandidate_p.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef T9WRITEWORDCANDIDATE_H
+#define T9WRITEWORDCANDIDATE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QString>
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+class T9WriteWordCandidate
+{
+public:
+ enum class Origin {
+ None,
+ T9Write,
+ XT9
+ };
+
+ T9WriteWordCandidate(QString symbs, int resultIndex = -1, Origin origin = Origin::None);
+
+public:
+ QString symbs;
+ int resultIndex;
+ Origin origin;
+};
+
+bool operator==(const T9WriteWordCandidate &a, const T9WriteWordCandidate &b);
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
+
+#endif // T9WRITEWORDCANDIDATE_H
diff --git a/src/plugins/t9write/plugin/t9writeworker.cpp b/src/plugins/cerence/cerence-hwr/plugin/t9writeworker.cpp
index 7ed1a4b7..76b9696c 100644
--- a/src/plugins/t9write/plugin/t9writeworker.cpp
+++ b/src/plugins/cerence/cerence-hwr/plugin/t9writeworker.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
@@ -31,7 +31,7 @@
#include <QLoggingCategory>
#include <QFile>
-#include <QTime>
+#include <QElapsedTimer>
QT_BEGIN_NAMESPACE
namespace QtVirtualKeyboard {
@@ -61,14 +61,10 @@ void T9WriteTask::wait()
\internal
*/
-T9WriteDictionaryTask::T9WriteDictionaryTask(QSharedPointer<T9WriteDictionary> dictionary,
- const QString &dictionaryFileName,
- bool convertDictionary,
- const DECUMA_SRC_DICTIONARY_INFO &dictionaryInfo) :
+T9WriteDictionaryTask::T9WriteDictionaryTask(QSharedPointer<T9WriteAbstractDictionary> dictionary,
+ bool convertDictionary) :
dictionary(dictionary),
- dictionaryFileName(dictionaryFileName),
- convertDictionary(convertDictionary),
- dictionaryInfo(dictionaryInfo)
+ convertDictionary(convertDictionary)
{
}
@@ -76,20 +72,22 @@ void T9WriteDictionaryTask::run()
{
qCDebug(lcT9Write) << "T9WriteDictionaryTask::run()";
- QTime perf;
+ QElapsedTimer perf;
perf.start();
bool result = false;
if (dictionary) {
- result = dictionary->load(dictionaryFileName);
+ result = dictionary->load();
if (result && convertDictionary)
- result = dictionary->convert(dictionaryInfo);
+ result = dictionary->convert();
}
qCDebug(lcT9Write) << "T9WriteDictionaryTask::run(): time:" << perf.elapsed() << "ms";
- if (result)
+ if (result) {
+ dictionary->state++;
emit completed(dictionary);
+ }
}
T9WriteAddArcTask::T9WriteAddArcTask(QVirtualKeyboardTrace *trace) :
@@ -99,7 +97,7 @@ T9WriteAddArcTask::T9WriteAddArcTask(QVirtualKeyboardTrace *trace) :
void T9WriteAddArcTask::run()
{
- QTime perf;
+ QElapsedTimer perf;
perf.start();
DECUMA_UINT32 arcID = (DECUMA_UINT32)trace->traceId();
DECUMA_STATUS status = DECUMA_API(StartNewArc)(decumaSession, arcID);
@@ -162,20 +160,11 @@ T9WriteRecognitionResult::T9WriteRecognitionResult(int id, int maxResults, int m
\internal
*/
-T9WriteRecognitionTask::T9WriteRecognitionTask(QSharedPointer<T9WriteRecognitionResult> result,
- const DECUMA_INSTANT_GESTURE_SETTINGS &instantGestureSettings,
- BOOST_LEVEL boostLevel,
- const QString &stringStart) :
+T9WriteRecognitionTask::T9WriteRecognitionTask(QSharedPointer<T9WriteRecognitionResult> result) :
T9WriteTask(),
result(result),
- instantGestureSettings(instantGestureSettings),
- boostLevel(boostLevel),
- stringStart(stringStart),
stateCancelled(false)
{
-#ifdef SENSITIVE_DEBUG
- qCDebug(lcT9Write) << "T9WriteRecognitionTask():" << "boostLevel:" << boostLevel << "stringStart:" << stringStart;
-#endif
}
void T9WriteRecognitionTask::run()
@@ -183,63 +172,61 @@ void T9WriteRecognitionTask::run()
if (!decumaSession)
return;
- {
- QMutexLocker stateGuard(&stateLock);
- Q_UNUSED(stateGuard);
- if (stateCancelled)
+ perf.start();
+
+ while (true) {
+ DECUMA_BG_REC_STATE bgRecState = bgRecIdle;
+ DECUMA_STATUS status = DECUMA_API(GetBackgroundRecognitionState(decumaSession, &bgRecState));
+ if (status) {
+ qCDebug(lcT9Write) << "T9WriteRecognitionTask::run(): GetBackgroundRecognitionState failed, status:" << status;
+ break;
+ }
+
+ if (bgRecState != bgRecStarted) {
+ qCDebug(lcT9Write) << "T9WriteRecognitionTask::run(): state:" << bgRecState << "time:" << perf.elapsed() << "ms";
+ break;
+ }
+
+ if (checkCancelled())
return;
- }
- //In a normal text composition case boostDictWords and canBeContinued are the preffered settings
- DECUMA_RECOGNITION_SETTINGS recSettings;
- memset(&recSettings, 0, sizeof(recSettings));
- recSettings.boostLevel = boostLevel;
- recSettings.stringCompleteness = canBeContinued;
- if (!stringStart.isEmpty())
- recSettings.pStringStart = (DECUMA_UNICODE *)stringStart.utf16();
+ QThread::msleep(25);
- QTime perf;
- perf.start();
+ if (checkCancelled())
+ return;
+ }
-#if SUPPORTS_ABORTRECOGNITION
- DECUMA_INTERRUPT_FUNCTIONS interruptFunctions;
- interruptFunctions.pShouldAbortRecognize = shouldAbortRecognize;
- interruptFunctions.pUserData = (void *)this;
- DECUMA_INTERRUPT_FUNCTIONS *pInterruptFunctions = &interruptFunctions;
-#else
- DECUMA_INTERRUPT_FUNCTIONS *pInterruptFunctions = nullptr;
-#endif
- result->status = DECUMA_API(Recognize)(decumaSession, result->results.data(), result->results.size(), &result->numResults, result->maxCharsPerWord, &recSettings, pInterruptFunctions);
+ result->status = DECUMA_API(Recognize)(decumaSession, result->results.data(), result->results.size(), &result->numResults, result->maxCharsPerWord, nullptr, nullptr);
if (result->status != decumaNoError)
qCWarning(lcT9Write) << "T9WriteRecognitionTask::run(): Recognition failed, status:" << result->status;
- int perfElapsed = perf.elapsed();
-
- {
- QMutexLocker stateGuard(&stateLock);
- Q_UNUSED(stateGuard);
- if (stateCancelled)
- result.reset();
- qCDebug(lcT9Write) << "T9WriteRecognitionTask::run(): time:" << perfElapsed << "ms" << (stateCancelled ? "(cancelled)" : "");
- }
-}
+ if (checkCancelled())
+ return;
-int T9WriteRecognitionTask::shouldAbortRecognize(void *pUserData)
-{
- T9WriteRecognitionTask *pThis = (T9WriteRecognitionTask *)pUserData;
- QMutexLocker stateGuard(&pThis->stateLock);
- Q_UNUSED(stateGuard);
- return pThis->stateCancelled;
+ qCDebug(lcT9Write) << "T9WriteRecognitionTask::run(): time:" << perf.elapsed() << "ms";
}
bool T9WriteRecognitionTask::cancelRecognition()
{
QMutexLocker stateGuard(&stateLock);
- Q_UNUSED(stateGuard);
+ Q_UNUSED(stateGuard)
stateCancelled = true;
return true;
}
+bool T9WriteRecognitionTask::checkCancelled()
+{
+ QMutexLocker stateGuard(&stateLock);
+ Q_UNUSED(stateGuard)
+ if (stateCancelled) {
+ result.reset();
+ qCDebug(lcT9Write) << "T9WriteRecognitionTask cancelled, time:" << perf.elapsed() << "ms";
+ return true;
+ }
+
+ return false;
+}
+
int T9WriteRecognitionTask::resultId() const
{
return result != nullptr ? result->id : -1;
@@ -278,7 +265,7 @@ void T9WriteRecognitionResultsTask::run()
int charPos = 0;
for (int symbolIndex = 0; symbolIndex < hwrResult.nSymbols; symbolIndex++) {
int symbolLength = hwrResult.pSymbolChars[symbolIndex];
- QString symbol(QString::fromUtf16(&hwrResult.pChars[charPos], symbolLength));
+ QString symbol(QString::fromUtf16(reinterpret_cast<const char16_t *>(&hwrResult.pChars[charPos]), symbolLength));
// Do not append gesture symbol to result string
if (hwrResult.bGesture) {
gesture = symbol.right(1);
@@ -299,13 +286,109 @@ void T9WriteRecognitionResultsTask::run()
resultList.append(resultMap);
}
- if (resultList.isEmpty())
+ if (resultList.isEmpty()) {
+ qCDebug(lcT9Write) << "T9WriteRecognitionResultsTask::run(): no results available";
return;
+ }
+ qCDebug(lcT9Write) << "T9WriteRecognitionResultsTask::run():" << resultList.size() << "results available";
emit resultsAvailable(resultList);
}
/*!
+ \class QtVirtualKeyboard::T9WriteLearnWordTask
+ \internal
+*/
+
+T9WriteDlmWordTask::T9WriteDlmWordTask(QSharedPointer<T9WriteAbstractDictionary> dlmDictionary, const QString &word, const QString &stringStart) :
+ T9WriteTask(),
+ dlmDictionary(dlmDictionary),
+ word(word),
+ stringStart(stringStart)
+{
+
+}
+
+void T9WriteDlmWordTask::run()
+{
+ DECUMA_RECOGNITION_SETTINGS recSettings;
+ memset(&recSettings, 0, sizeof(recSettings));
+ recSettings.boostLevel = boostDictWords;
+ recSettings.stringCompleteness = canBeContinued;
+ if (!stringStart.isEmpty())
+ recSettings.pStringStart = const_cast<DECUMA_UNICODE *>(stringStart.utf16());
+
+ DECUMA_UINT16 nDictionaries = 0;
+ DECUMA_STATUS status = DECUMA_API(GetNAttachedDictionaries)(decumaSession, &nDictionaries);
+ if (status)
+ return;
+
+ bool wordFound = false;
+ if (nDictionaries != 0) {
+ QVector<DECUMA_MATCH_RESULT> matchResults;
+ matchResults.resize(nDictionaries);
+ status = DECUMA_API(MatchWord)(decumaSession, word.utf16(),
+ static_cast<DECUMA_UINT16>(word.length()),
+ &recSettings, matchResults.data());
+ if (!status) {
+ for (const auto &matchResult : qAsConst(matchResults)) {
+ qCDebug(lcT9Write) << "T9WriteDlmWordTask::run(): MatchWord string type" << matchResult.stringType;
+ if (matchResult.stringType != notFromDictionary) {
+ wordFound = true;
+ break;
+ }
+ }
+ } else {
+ qCDebug(lcT9Write) << "T9WriteDlmWordTask::run(): MatchWord failed" << status;
+ return;
+ }
+ }
+
+ if (!wordFound) {
+ qCDebug(lcT9Write) << "T9WriteDlmWordTask::run(): DynamicDictionaryAddWord";
+ status = DECUMA_API(DynamicDictionaryAddWord)(
+ const_cast<DECUMA_DYNAMIC_DICTIONARY *>(
+ reinterpret_cast<const DECUMA_DYNAMIC_DICTIONARY *>(dlmDictionary->data())),
+ word.utf16());
+
+ if (!status) {
+ persist();
+ }
+ }
+}
+
+void T9WriteDlmWordTask::persist()
+{
+ T9WriteDynamicDictionary *dictionary = static_cast<T9WriteDynamicDictionary *>(dlmDictionary.data());
+
+ QElapsedTimer perf;
+ perf.start();
+
+ dictionary->save();
+
+ qCDebug(lcT9Write) << "T9WriteDlmWordTask::persist(): time:" << perf.elapsed() << "ms";
+}
+
+/*!
+ \class QtVirtualKeyboard::T9WriteDlmRemoveWordTask
+ \internal
+*/
+
+T9WriteDlmRemoveWordTask::T9WriteDlmRemoveWordTask(QSharedPointer<T9WriteAbstractDictionary> dlmDictionary, const QString &word) :
+ T9WriteDlmWordTask(dlmDictionary, word, QString())
+{
+
+}
+
+void T9WriteDlmRemoveWordTask::run()
+{
+ T9WriteDynamicDictionary *dictionary = static_cast<T9WriteDynamicDictionary *>(dlmDictionary.data());
+ if (dictionary->removeWord(word)) {
+ persist();
+ }
+}
+
+/*!
\class QtVirtualKeyboard::T9WriteWorker
\internal
*/
@@ -342,19 +425,27 @@ int T9WriteWorker::removeTask(QSharedPointer<T9WriteTask> task)
int count = 0;
if (task) {
QMutexLocker guard(&taskLock);
- count = taskList.removeAll(task);
- taskSema.acquire(qMin(count, taskSema.available()));
+ const bool isRunning = taskList.indexOf(task) == 0;
+ if (isRunning) {
+ task->wait();
+ } else if (taskList.removeOne(task)) {
+ ++count;
+ task->runSema.release();
+ }
}
return count;
}
int T9WriteWorker::removeAllTasks()
{
+ idleSema.acquire();
QMutexLocker guard(&taskLock);
int count = taskList.count();
+ for (QSharedPointer<T9WriteTask> task : taskList) {
+ task->runSema.release();
+ }
taskList.clear();
- if (taskSema.available())
- taskSema.acquire(taskSema.available());
+ idleSema.release();
return count;
}
@@ -374,7 +465,7 @@ void T9WriteWorker::waitForAllTasks()
int T9WriteWorker::numberOfPendingTasks()
{
QMutexLocker guard(&taskLock);
- return taskList.count() + (!idleSema.available() ? 1 : 0);
+ return taskList.count();
}
void T9WriteWorker::run()
@@ -390,7 +481,6 @@ void T9WriteWorker::run()
QMutexLocker guard(&taskLock);
if (!taskList.isEmpty()) {
currentTask = taskList.front();
- taskList.pop_front();
}
}
if (currentTask) {
@@ -398,6 +488,8 @@ void T9WriteWorker::run()
currentTask->cjk = cjk;
currentTask->run();
currentTask->runSema.release();
+ QMutexLocker guard(&taskLock);
+ taskList.removeOne(currentTask);
}
}
}
diff --git a/src/plugins/t9write/plugin/t9writeworker_p.h b/src/plugins/cerence/cerence-hwr/plugin/t9writeworker_p.h
index 0cdb19a4..d21735fe 100644
--- a/src/plugins/t9write/plugin/t9writeworker_p.h
+++ b/src/plugins/cerence/cerence-hwr/plugin/t9writeworker_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
@@ -51,8 +51,9 @@
#include <QPointer>
#include <QMap>
#include <QList>
+#include <QElapsedTimer>
-#include "t9write_p.h"
+#include "cerence_hwr_p.h"
#include "t9writedictionary_p.h"
QT_BEGIN_NAMESPACE
@@ -82,20 +83,18 @@ class T9WriteDictionaryTask : public T9WriteTask
{
Q_OBJECT
public:
- explicit T9WriteDictionaryTask(QSharedPointer<T9WriteDictionary> dictionary,
- const QString &dictionaryFileName,
- bool convertDictionary,
- const DECUMA_SRC_DICTIONARY_INFO &dictionaryInfo);
+ explicit T9WriteDictionaryTask(QSharedPointer<T9WriteAbstractDictionary> dictionary,
+ bool convertDictionary);
void run();
- QSharedPointer<T9WriteDictionary> dictionary;
+ QSharedPointer<T9WriteAbstractDictionary> dictionary;
+ QSharedPointer<T9WriteAbstractSource> source;
const QString dictionaryFileName;
bool convertDictionary;
- const DECUMA_SRC_DICTIONARY_INFO dictionaryInfo;
signals:
- void completed(QSharedPointer<T9WriteDictionary> dictionary);
+ void completed(QSharedPointer<T9WriteAbstractDictionary> dictionary);
};
class T9WriteAddArcTask : public T9WriteTask
@@ -135,26 +134,21 @@ class T9WriteRecognitionTask : public T9WriteTask
{
Q_OBJECT
public:
- explicit T9WriteRecognitionTask(QSharedPointer<T9WriteRecognitionResult> result,
- const DECUMA_INSTANT_GESTURE_SETTINGS &instantGestureSettings,
- BOOST_LEVEL boostLevel,
- const QString &stringStart);
+ explicit T9WriteRecognitionTask(QSharedPointer<T9WriteRecognitionResult> result);
void run();
bool cancelRecognition();
+ bool checkCancelled();
int resultId() const;
private:
- static int shouldAbortRecognize(void *pUserData);
- friend int shouldAbortRecognize(void *pUserData);
+ void waitForBackgroundRecognition();
private:
QSharedPointer<T9WriteRecognitionResult> result;
- DECUMA_INSTANT_GESTURE_SETTINGS instantGestureSettings;
- BOOST_LEVEL boostLevel;
- QString stringStart;
QMutex stateLock;
bool stateCancelled;
+ QElapsedTimer perf;
};
class T9WriteRecognitionResultsTask : public T9WriteTask
@@ -173,6 +167,32 @@ private:
QSharedPointer<T9WriteRecognitionResult> result;
};
+class T9WriteDlmWordTask : public T9WriteTask
+{
+ Q_OBJECT
+public:
+ explicit T9WriteDlmWordTask(QSharedPointer<T9WriteAbstractDictionary> dlmDictionary, const QString &word, const QString &stringStart);
+
+ void run();
+
+protected:
+ void persist();
+
+protected:
+ QSharedPointer<T9WriteAbstractDictionary> dlmDictionary;
+ const QString word;
+ const QString stringStart;
+};
+
+class T9WriteDlmRemoveWordTask : public T9WriteDlmWordTask
+{
+ Q_OBJECT
+public:
+ explicit T9WriteDlmRemoveWordTask(QSharedPointer<T9WriteAbstractDictionary> dlmDictionary, const QString &word);
+
+ void run();
+};
+
class T9WriteWorker : public QThread
{
Q_OBJECT
@@ -202,6 +222,21 @@ public:
return count;
}
+ template <class X>
+ void waitForAllTasksOfType() {
+ QSharedPointer<X> task;
+ {
+ QMutexLocker guard(&taskLock);
+ for (int i = taskList.size() - 1; i >= 0; --i) {
+ task = taskList[i].objectCast<X>();
+ if (task)
+ break;
+ }
+ }
+ if (task)
+ task->wait();
+ }
+
protected:
void run();
diff --git a/src/plugins/cerence/cerencecommon/CMakeLists.txt b/src/plugins/cerence/cerencecommon/CMakeLists.txt
new file mode 100644
index 00000000..4a2f1675
--- /dev/null
+++ b/src/plugins/cerence/cerencecommon/CMakeLists.txt
@@ -0,0 +1,200 @@
+# Generated from cerencecommon.pro.
+
+#####################################################################
+## BundledCerencecommon Generic Library:
+#####################################################################
+
+qt_internal_add_3rdparty_library(BundledCerencecommon
+ QMAKE_LIB_NAME cerencecommon
+ STATIC
+ SOURCES
+ xt9dbfile.cpp xt9dbfile.h
+ xt9ldbmanager.cpp xt9ldbmanager.h
+ PUBLIC_INCLUDE_DIRECTORIES
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::VirtualKeyboardPrivate
+)
+
+## Scopes:
+#####################################################################
+
+qt_extend_target(BundledCerencecommon CONDITION FEATURE_vkb_bundle_cerence OR FEATURE_vkb_bundle_cerence_xt9
+ PUBLIC_DEFINES
+ HAVE_XT9_RESOURCE
+)
+
+qt_extend_target(BundledCerencecommon CONDITION FEATURE_vkb_cerence_xt9_debug
+ PUBLIC_DEFINES
+ XT9_DEBUG
+)
+
+if(FEATURE_vkb_bundle_cerence OR FEATURE_vkb_bundle_cerence_xt9)
+
+ set(qmake_cerencecommondata_db_resource_files)
+
+ foreach(lang IN LISTS valid_languages)
+ if(FEATURE_vkb_lang_${lang})
+ if(${lang} STREQUAL "en_GB")
+ set(ldb_glob "EN*UK*.ldb")
+ elseif(${lang} STREQUAL "en_US")
+ set(ldb_glob "EN*US*.ldb")
+ elseif(${lang} STREQUAL "es_ES")
+ set(ldb_glob "ESusUN_*.ldb")
+ elseif(${lang} STREQUAL "es_MX")
+ set(ldb_glob "ESusUNlatam_*.ldb")
+ elseif(${lang} STREQUAL "fr_FR")
+ set(ldb_glob "FRusUN_*.ldb")
+ elseif(${lang} STREQUAL "fr_CA")
+ set(ldb_glob "FRusUNCA_*.ldb")
+ elseif(${lang} STREQUAL "ko_KR")
+ set(ldb_glob "KOusUN_xt9_ALM3.ldb")
+ elseif(${lang} STREQUAL "pt_PT")
+ set(ldb_glob "PTusUN_*.ldb")
+ elseif(${lang} STREQUAL "pt_BR")
+ set(ldb_glob "PTusUNBR_*.ldb")
+ elseif(${lang} STREQUAL "zh_CN")
+ set(ldb_glob "ZHsbUNps_GB18030_*.ldb")
+ elseif(${lang} STREQUAL "zh_TW")
+ set(ldb_glob "ZHtbUNps_Big5_*.ldb")
+ elseif(${lang} STREQUAL "zh_HK")
+ set(ldb_glob "ZHtbUNps_Big5HKSCS_*.ldb")
+ else()
+ string(SUBSTRING ${lang} 0 2 lang_code)
+ string(TOUPPER lang_code ${lang_code})
+ set(ldb_glob "${lang_code}*.ldb")
+ endif()
+ file(GLOB resource_glob_0 RELATIVE "${CERENCE_XT9_DATAPATH}" "${CERENCE_XT9_DATAPATH}/${ldb_glob}")
+ foreach(file IN LISTS resource_glob_0)
+ set_source_files_properties("${CERENCE_XT9_DATAPATH}/${file}" PROPERTIES QT_RESOURCE_ALIAS "${file}")
+ endforeach()
+ list(APPEND qmake_cerencecommondata_db_resource_files ${resource_glob_0})
+ endif()
+ endforeach()
+
+ list(REMOVE_DUPLICATES qmake_cerencecommondata_db_resource_files)
+
+ qt_internal_add_resource(BundledCerencecommon "qmake_cerencecommondata_db"
+ PREFIX
+ "/QtQuick/VirtualKeyboard/Cerence/Xt9"
+ BASE
+ "${CERENCE_XT9_DATAPATH}"
+ FILES
+ ${qmake_cerencecommondata_db_resource_files}
+ OPTIONS
+ -no-compress
+ )
+else()
+ qt_copy_or_install(
+ DIRECTORY "${CERENCE_XT9_DATAPATH}/"
+ DESTINATION "${VKB_INSTALL_DATA}/cerence/xt9"
+ FILES_MATCHING
+ PATTERN "*.ldb"
+ )
+endif()
+
+#### Keys ignored in scope 2:.:.:cerencecommon.pro:FEATURE_vkb_bundle_cerence OR FEATURE_vkb_bundle_cerence_xt9:
+# QMAKE_RESOURCE_FLAGS = "-no-compress"
+
+#### Keys ignored in scope 3:.:.:cerencecommon.pro:COMMON_RESOURCE_FILES_ISEMPTY:
+# COMMON_RESOURCE_FILES = "dummy.txt"
+
+#### Keys ignored in scope 5:.:..:../cerence.pri:CERENCE_SDK_ROOT_ISEMPTY:
+# EXT_CERENCE_SDK_ROOT = "$$(CERENCE_SDK_ROOT)"
+
+#### Keys ignored in scope 6:.:..:../cerence.pri:NOT EXT_CERENCE_SDK_ROOT_ISEMPTY:
+# CERENCE_SDK_ROOT = "$$EXT_CERENCE_SDK_ROOT"
+
+#### Keys ignored in scope 8:.:..:../cerence.pri:CERENCE_SDK_ROOT_ISEMPTY:
+# CERENCE_SDK_ROOT = "$$PWD/sdk"
+
+#### Keys ignored in scope 11:.:..:../cerence.pri:QT_ARCH___equals___arm:
+# CERENCE_SHARED_LIB_PATH = "lib/linux/arm/shared"
+# CERENCE_STATIC_LIB_PATH = "lib/linux/arm/static"
+
+#### Keys ignored in scope 13:.:..:../cerence.pri:QT_ARCH___equals___arm64:
+# CERENCE_SHARED_LIB_PATH = "lib/linux/arm64/shared"
+# CERENCE_STATIC_LIB_PATH = "lib/linux/arm64/static"
+
+#### Keys ignored in scope 15:.:..:../cerence.pri:QT_ARCH___equals___x86_64:
+# CERENCE_SHARED_LIB_PATH = "lib/linux/x86_64/shared"
+# CERENCE_STATIC_LIB_PATH = "lib/linux/x86_64/static"
+
+#### Keys ignored in scope 17:.:..:../cerence.pri:QT_ARCH___equals___x86 OR QT_ARCH___equals___i386:
+# CERENCE_SHARED_LIB_PATH = "lib/linux/x86/shared"
+# CERENCE_STATIC_LIB_PATH = "lib/linux/x86/static"
+
+#### Keys ignored in scope 20:.:..:../cerence.pri:QT_ARCH___equals___x86_64:
+# CERENCE_SHARED_LIB_PATH = "lib/win32/x86_64/shared"
+# CERENCE_STATIC_LIB_PATH = "lib/win32/x86_64/static"
+
+#### Keys ignored in scope 21:.:..:../cerence.pri:else:
+# CERENCE_SHARED_LIB_PATH = "lib/win32/x86/shared"
+# CERENCE_STATIC_LIB_PATH = "lib/win32/x86/static"
+
+#### Keys ignored in scope 23:.:..:../cerence.pri:WIN32:
+# result = "$$1/*.obj"
+
+#### Keys ignored in scope 24:.:..:../cerence.pri:result_ISEMPTY:
+# result = "$$1/*.lib"
+
+#### Keys ignored in scope 25:.:..:../cerence.pri:else:
+# result = "$$1/*.o"
+
+#### Keys ignored in scope 26:.:..:../cerence.pri:result_ISEMPTY:
+# result = "$$1/*.a"
+
+#### Keys ignored in scope 28:.:..:../cerence.pri:WIN32:
+# result = "$$1/*.lib"
+
+#### Keys ignored in scope 29:.:..:../cerence.pri:else:
+# result = "$$1/*.so"
+
+#### Keys ignored in scope 31:.:..:../cerence.pri:WIN32:
+# result = "$$1/*.dll"
+
+#### Keys ignored in scope 32:.:..:../cerence.pri:else:
+# result = "$$1/*.so"
+
+#### Keys ignored in scope 33:.:..:../cerence.pri:EXISTS _ss_CERENCE_HWR_INCLUDEPATH/decuma_hwr.h:
+# CERENCE_HWR_ALPHABETIC_FOUND = "1"
+
+#### Keys ignored in scope 34:.:..:../cerence.pri:EXISTS _ss_CERENCE_HWR_INCLUDEPATH/decuma_hwr_cjk.h:
+# CERENCE_HWR_CJK_FOUND = "1"
+
+#### Keys ignored in scope 37:.:..:../cerence.pri:NOT cerence-hwr-static:
+# CERENCE_HWR_ALPHABETIC_LIBS = "$$findSharedLibrary($$CERENCE_SDK_ROOT/t9write/$$CERENCE_SHARED_LIB_PATH/alphabetic)"
+
+#### Keys ignored in scope 38:.:..:../cerence.pri:NOT CERENCE_HWR_ALPHABETIC_LIBS_ISEMPTY:
+# CERENCE_HWR_ALPHABETIC_BINS = "$$findSharedBinary($$CERENCE_SDK_ROOT/t9write/$$CERENCE_SHARED_LIB_PATH/alphabetic)"
+
+#### Keys ignored in scope 39:.:..:../cerence.pri:else:
+# CERENCE_HWR_ALPHABETIC_LIBS = "$$findStaticLibrary($$CERENCE_SDK_ROOT/t9write/$$CERENCE_STATIC_LIB_PATH/alphabetic)"
+
+#### Keys ignored in scope 41:.:..:../cerence.pri:NOT cerence-hwr-static:
+# CERENCE_HWR_CJK_LIBS = "$$findSharedLibrary($$CERENCE_SDK_ROOT/t9write/$$CERENCE_SHARED_LIB_PATH/cjk)"
+
+#### Keys ignored in scope 42:.:..:../cerence.pri:NOT CERENCE_HWR_CJK_LIBS_ISEMPTY:
+# CERENCE_HWR_CJK_BINS = "$$findSharedBinary($$CERENCE_SDK_ROOT/t9write/$$CERENCE_SHARED_LIB_PATH/cjk)"
+
+#### Keys ignored in scope 43:.:..:../cerence.pri:else:
+# CERENCE_HWR_CJK_LIBS = "$$findStaticLibrary($$CERENCE_SDK_ROOT/t9write/$$CERENCE_STATIC_LIB_PATH/cjk)"
+
+#### Keys ignored in scope 44:.:..:../cerence.pri:(CERENCE_HWR_ALPHABETIC_FOUND EQUAL 1) AND NOT CERENCE_HWR_ALPHABETIC_LIBS_ISEMPTY:
+# CERENCE_HWR_FOUND = "1"
+
+#### Keys ignored in scope 45:.:..:../cerence.pri:(CERENCE_HWR_CJK_FOUND EQUAL 1) AND NOT CERENCE_HWR_CJK_LIBS_ISEMPTY:
+# CERENCE_HWR_FOUND = "1"
+
+#### Keys ignored in scope 46:.:..:../cerence.pri:EXISTS _ss_XT9_INCLUDEPATH/et9api.h:
+# XT9_FOUND = "1"
+
+#### Keys ignored in scope 48:.:..:../cerence.pri:NOT QT_FEATURE_xt9_static:
+# XT9_LIBS = "$$findSharedLibrary($$CERENCE_SDK_ROOT/xt9/$$CERENCE_SHARED_LIB_PATH)"
+
+#### Keys ignored in scope 49:.:..:../cerence.pri:NOT XT9_LIBS_ISEMPTY:
+# XT9_BINS = "$$findSharedBinary($$CERENCE_SDK_ROOT/xt9/$$CERENCE_SHARED_LIB_PATH)"
+
+#### Keys ignored in scope 50:.:..:../cerence.pri:else:
+# XT9_LIBS = "$$findStaticLibrary($$CERENCE_SDK_ROOT/xt9/$$CERENCE_STATIC_LIB_PATH)"
diff --git a/src/plugins/cerence/cerencecommon/dummy.txt b/src/plugins/cerence/cerencecommon/dummy.txt
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/plugins/cerence/cerencecommon/dummy.txt
diff --git a/src/plugins/cerence/cerencecommon/xt9dbfile.cpp b/src/plugins/cerence/cerencecommon/xt9dbfile.cpp
new file mode 100644
index 00000000..4dde96b4
--- /dev/null
+++ b/src/plugins/cerence/cerencecommon/xt9dbfile.cpp
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xt9dbfile.h"
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+Xt9DbFile::Xt9DbFile(const QString &fileName) :
+ file(fileName),
+ _data(nullptr),
+ _size(0),
+ _rw(false)
+{
+
+}
+
+QString Xt9DbFile::fileName() const
+{
+ return file.fileName();
+}
+
+const void *Xt9DbFile::roData()
+{
+ if (_data == nullptr) {
+ if (file.open(QIODevice::ReadOnly)) {
+ _rw = false;
+ _size = file.size();
+ _data = file.map(0, _size, QFile::NoOptions);
+ if (!_data) {
+ _size = 0;
+ }
+ file.close();
+ }
+ }
+
+ return _data;
+}
+
+void *Xt9DbFile::rwData(qint64 size)
+{
+ if (_data == nullptr || !_rw) {
+ if (!_rw) {
+ file.unmap(static_cast<uchar *>(_data));
+ _data = nullptr;
+ _rw = false;
+ }
+ if (file.open(QIODevice::ReadWrite)) {
+ _rw = true;
+ _size = file.size();
+ if (_size == 0) {
+ _size = size;
+ file.resize(_size);
+ }
+ _data = file.map(0, _size, QFile::NoOptions);
+ if (!_data) {
+ _size = 0;
+ }
+ file.close();
+ }
+ }
+
+ return _data;
+}
+
+qint64 Xt9DbFile::size() const
+{
+ return _size;
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
diff --git a/src/plugins/cerence/cerencecommon/xt9dbfile.h b/src/plugins/cerence/cerencecommon/xt9dbfile.h
new file mode 100644
index 00000000..e65b1e1e
--- /dev/null
+++ b/src/plugins/cerence/cerencecommon/xt9dbfile.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XT9DBFILE_H
+#define XT9DBFILE_H
+
+#include <QFile>
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+class Xt9DbFile
+{
+public:
+ Xt9DbFile(const QString &fileName);
+
+ QString fileName() const;
+ const void *roData();
+ void *rwData(qint64 size);
+ qint64 size() const;
+
+private:
+ QFile file;
+ void *_data;
+ qint64 _size;
+ bool _rw;
+};
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
+
+#endif // XT9DBFILE_H
diff --git a/src/plugins/cerence/cerencecommon/xt9ldbmanager.cpp b/src/plugins/cerence/cerencecommon/xt9ldbmanager.cpp
new file mode 100644
index 00000000..409dd6b5
--- /dev/null
+++ b/src/plugins/cerence/cerencecommon/xt9ldbmanager.cpp
@@ -0,0 +1,193 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xt9ldbmanager.h"
+#include "xt9dbfile.h"
+#include <QDirIterator>
+#include <QLibraryInfo>
+#include <QMap>
+#include <QtVirtualKeyboard/private/settings_p.h>
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+const QRegularExpression Xt9LdbManager::ldbRegex = QRegularExpression(QStringLiteral("([A-Z]{2})([a-z]{2})(?:UN)(.*?)(?:_xt9_?)?((?:CJI_|HC_|big_)?ALM3?)?(\\.ldb|\\.phd)"));
+
+Xt9LdbManager::Xt9LdbManager() :
+ _phdEnabled(false)
+{
+ QString xt9LdbPath(qEnvironmentVariable("QT_VIRTUALKEYBOARD_XT9_LDB_PATH"));
+ const QString pathListSep(
+#if defined(Q_OS_WIN32)
+ QStringLiteral(";")
+#else
+ QStringLiteral(":")
+#endif
+ );
+ QStringList userPaths(xt9LdbPath.split(pathListSep, Qt::SkipEmptyParts));
+ const QStringList defaultPaths = userPaths
+ << QDir(QStringLiteral("%1/qtvirtualkeyboard/cerence/xt9/").arg(QLibraryInfo::path(QLibraryInfo::DataPath))).absolutePath()
+ << QLatin1String(":/QtQuick/VirtualKeyboard/Cerence/Xt9")
+ ;
+ for (const QString &defaultPath : defaultPaths) {
+ addSearchPath(defaultPath);
+ }
+}
+
+void Xt9LdbManager::addSearchPath(const QString &searchPath)
+{
+ if (!searchPaths.contains(searchPath))
+ searchPaths.append(searchPath);
+}
+
+void Xt9LdbManager::setPhdEnabled(bool enabled)
+{
+ _phdEnabled = enabled;
+}
+
+bool Xt9LdbManager::phdEnabled() const
+{
+ return _phdEnabled;
+}
+
+bool Xt9LdbManager::loadDictionary(const QLocale &locale, const void *&data, qint64 &size)
+{
+ const QString language = locale.name();
+ if (ldbMap.contains(language)) {
+ QSharedPointer<Xt9DbFile> ldb = ldbMap[language];
+ if (_phdEnabled || !ldb->fileName().endsWith(QLatin1String(".phd"), Qt::CaseInsensitive)) {
+ data = ldb->roData();
+ size = ldb->size();
+ return true;
+ }
+ }
+
+ QString dictionaryFile = findDictionary(locale);
+ if (!dictionaryFile.isEmpty()) {
+ QSharedPointer<Xt9DbFile> ldb(new Xt9DbFile(dictionaryFile));
+ data = ldb->roData();
+ size = ldb->size();
+ if (data) {
+ ldbMap[language] = ldb;
+ return true;
+ }
+ }
+
+ data = nullptr;
+ size = 0;
+
+ return false;
+}
+
+void Xt9LdbManager::closeAll()
+{
+ ldbMap.clear();
+}
+
+QString Xt9LdbManager::findDictionary(const QLocale &locale) const
+{
+ QStringList languageCountry = locale.name().split(QLatin1String("_"));
+ if (languageCountry.length() != 2)
+ return QString();
+ const QString language_ISO_639_1 = languageCountry[0].toUpper();
+ const QString country = languageCountry[1].toUpper();
+ const QLocale::Script script = locale.script();
+
+ QMap<QString, int> matchedDictionaries;
+ for (const QString &ldbDirectory : searchPaths) {
+ QDirIterator it(ldbDirectory, QDirIterator::NoIteratorFlags);
+ while (it.hasNext()) {
+ QString fileEntry = it.next();
+ const QFileInfo fileInfo(fileEntry);
+
+ if (fileInfo.isDir())
+ continue;
+
+ QString fileName(fileInfo.fileName());
+ fileName.remove(QRegularExpression(QLatin1String("^zzEval_")));
+
+ QRegularExpressionMatch match = ldbRegex.match(fileName);
+ if (!match.hasMatch())
+ continue;
+
+ QString xt9Language = match.captured(1);
+
+ // Special case for language codes not following ISO 639-1
+ if (xt9Language == QLatin1String("NO"))
+ xt9Language = QStringLiteral("NB");
+
+ const QString ext(match.captured(5));
+ if (xt9Language == language_ISO_639_1 &&
+ (ext == QLatin1String(".ldb") || (_phdEnabled && ext == QLatin1String(".phd")))) {
+
+ int score = 1;
+
+ QString xt9CountryOrDetail = match.captured(3);
+ const QString charsetClassifier = match.captured(2);
+ const QString almClassifier = match.captured(4);
+
+ // Special case for country codes not following ISO 639-1
+ if (xt9CountryOrDetail == QLatin1String("UK"))
+ xt9CountryOrDetail = QStringLiteral("GB");
+ else if (xt9CountryOrDetail == QLatin1String("latam"))
+ xt9CountryOrDetail = QStringLiteral("MX");
+ else if (xt9CountryOrDetail.isEmpty() && country == language_ISO_639_1)
+ xt9CountryOrDetail = country;
+
+ if (xt9CountryOrDetail == country ||
+ ((script == QLocale::SimplifiedHanScript && charsetClassifier == QLatin1String("sb")) ||
+ (script == QLocale::TraditionalHanScript && charsetClassifier == QLatin1String("tb"))))
+ ++score;
+
+ if (locale.country() == QLocale::Taiwan && xt9CountryOrDetail == QLatin1String("ps_Big5_bpmf_pinyin_CJ"))
+ ++score;
+ else if (locale.country() == QLocale::HongKong && xt9CountryOrDetail == QLatin1String("ps_Big5HKSCS_bpmf_pinyin_CJ"))
+ ++score;
+
+ if (!almClassifier.isEmpty())
+ ++score;
+
+ matchedDictionaries.insert(fileEntry, score);
+ }
+ }
+ }
+
+ if (matchedDictionaries.isEmpty())
+ return QString();
+
+ QList<int> scoreList = matchedDictionaries.values();
+ std::sort(scoreList.begin(), scoreList.end());
+ const int highScore = scoreList.last();
+ const QString bestMatch = matchedDictionaries.key(highScore);
+
+ return bestMatch;
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
diff --git a/src/plugins/cerence/cerencecommon/xt9ldbmanager.h b/src/plugins/cerence/cerencecommon/xt9ldbmanager.h
new file mode 100644
index 00000000..0cec38e3
--- /dev/null
+++ b/src/plugins/cerence/cerencecommon/xt9ldbmanager.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XT9LDBMANAGER_H
+#define XT9LDBMANAGER_H
+
+#include <QLocale>
+#include <QSharedPointer>
+#include <QRegularExpression>
+#include <QSet>
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+class Xt9DbFile;
+
+class Xt9LdbManager
+{
+public:
+ Xt9LdbManager();
+
+ void addSearchPath(const QString &ldbDirectory);
+ void setPhdEnabled(bool enabled);
+ bool phdEnabled() const;
+
+ bool loadDictionary(const QLocale &locale, const void *&data, qint64 &size);
+ void closeAll();
+
+ QString findDictionary(const QLocale &locale) const;
+
+private:
+ QStringList searchPaths;
+ QMap<QString, QSharedPointer<Xt9DbFile>> ldbMap;
+ bool _phdEnabled;
+ static const QRegularExpression ldbRegex;
+};
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
+
+#endif // XT9LDBMANAGER_H
diff --git a/src/plugins/t9write/3rdparty/t9write/unpack.py b/src/plugins/cerence/unpack.py
index 4fc1f4dc..0d219e4b 100644
--- a/src/plugins/t9write/3rdparty/t9write/unpack.py
+++ b/src/plugins/cerence/unpack.py
@@ -3,7 +3,7 @@
#############################################################################
##
-## Copyright (C) 2017 The Qt Company Ltd.
+## Copyright (C) 2021 The Qt Company Ltd.
## Contact: https://www.qt.io/licensing/
##
## This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
@@ -38,13 +38,17 @@ import shutil
import fnmatch
#
-# This utility script unpacks the T9 Write SDK to appropriate directory
+# This utility script unpacks the Cerence SDK to appropriate directory
# structure for Qt Virtual Keyboard.
#
-# Usage: unpack.py <filename.zip> <target dir>
-# unpack.py <input dir> <target dir>
+# Usage: unpack.py <filename.zip> [<target dir>]
#
-# The script will happily overwrite existing files, so be careful.
+# - <filename.zip> The Cerence SDK zip.
+# - <target dir> Target directory to unpack files to. The
+# directory can be located out of tree.
+# The default directory is src/plugins/cerence/sdk.
+#
+# The script will overwrite existing files, so be careful.
#
#
@@ -72,9 +76,21 @@ import fnmatch
# files found in the same directory.
#
+T9WRITE_DIR = 't9write/'
+T9WRITE_DATA_DIR = 't9write/data/'
+XT9_DIR = 'xt9/'
+XT9_DATA_DIR = 'xt9/data/'
+
UNPACK_RULES = [
+
+##############################################################################
+#
+# T9 Write
+#
+##############################################################################
+
{ # Header files
-'api': [
+T9WRITE_DIR + 'api': [
'*/decuma_hwr.h',
'*/decuma_hwr_cjk.h',
'*/decuma_hwr_types.h',
@@ -93,74 +109,193 @@ UNPACK_RULES = [
'*/decumaStorageSpecifiers.h',
'*/decumaSymbolCategories.h',
'*/decumaUnicodeTypes.h',
- '*/t9write_alpha_version.h',
- '*/t9write_api_version.h',
- '*/t9write_cjk_version.h',
- '*/xxt9wApiOem.h',
- '*/xxt9wOem.h',
-],
-}, { # Data: Arabic and Hebrew database must be copied first (the file name collides with Alphabetic database)
-'data/arabic': [
+ '*/cerence_handwriting_alpha_version.h',
+ '*/cerence_handwriting_api_version.h',
+ '*/cerence_handwriting_cjk_version.h',
+ '*/xxchApiOem.h',
+ '*/xxchOem.h',
+],
+}, { # Data
+T9WRITE_DATA_DIR + 'arabic': [
'*/Arabic/*_le.bin',
],
-'data/hebrew': [
+T9WRITE_DATA_DIR + 'hebrew': [
'*/Hebrew/*_le.bin',
],
-'data/thai': [
+T9WRITE_DATA_DIR + 'thai': [
'*/*Thai*/*_le.bin',
],
-}, { # Data: Alphabetic and CJK databases
-'data': [
+T9WRITE_DATA_DIR + '': [
'*/*_le.bin',
'*/*.hdb',
'*/*.phd',
- '*/*.ldb',
],
}, { # Libraries
-'lib/arm/static/alphabetic': [
- '*T9Write_Alpha*/*Android_ARM*/*.a',
- '*T9Write_Alpha*/*Android_ARM*/*.o',
+# T9 Write ARM Linux 32-bit
+T9WRITE_DIR + 'lib/linux/arm/static/alphabetic': [
+ '*T9Write_Alphabetic*/arm_linux*_32bit/*.a',
+ '*T9Write_Alphabetic*/arm_linux*_32bit/*.o',
+],
+T9WRITE_DIR + 'lib/linux/arm/shared/alphabetic': [
+ '*T9Write_Alphabetic*/arm_linux*_32bit/*.so',
+],
+T9WRITE_DIR + 'lib/linux/arm/static/cjk': [
+ '*T9Write_CJK*/arm_linux*_32bit/*.a',
+ '*T9Write_CJK*/arm_linux*_32bit/*.o',
+],
+T9WRITE_DIR + 'lib/linux/arm/shared/cjk': [
+ '*T9Write_CJK*/arm_linux*_32bit/*.so',
+],
+# T9 Write ARM Linux 64-bit
+T9WRITE_DIR + 'lib/linux/arm64/static/alphabetic': [
+ '*T9Write_Alphabetic*/arm_linux*_64bit/*.a',
+ '*T9Write_Alphabetic*/arm_linux*_64bit/*.o',
+],
+T9WRITE_DIR + 'lib/linux/arm64/shared/alphabetic': [
+ '*T9Write_Alphabetic*/arm_linux*_64bit/*.so',
+],
+T9WRITE_DIR + 'lib/linux/arm64/static/cjk': [
+ '*T9Write_CJK*/arm_linux*_64bit/*.a',
+ '*T9Write_CJK*/arm_linux*_64bit/*.o',
+],
+T9WRITE_DIR + 'lib/linux/arm64/shared/cjk': [
+ '*T9Write_CJK*/arm_linux*_64bit/*.so',
+],
+# T9 Write x86 Linux 32-bit
+T9WRITE_DIR + 'lib/linux/x86/static/alphabetic': [
+ '*T9Write_Alphabetic*/i86_linux*_32bit/*.a',
+ '*T9Write_Alphabetic*/i86_linux*_32bit/*.o',
+],
+T9WRITE_DIR + 'lib/linux/x86/shared/alphabetic': [
+ '*T9Write_Alphabetic*/i86_linux*_32bit/*.so',
+],
+T9WRITE_DIR + 'lib/linux/x86/static/cjk': [
+ '*T9Write_CJK*/i86_linux*_32bit/*.a',
+ '*T9Write_CJK*/i86_linux*_32bit/*.o',
+],
+T9WRITE_DIR + 'lib/linux/x86/shared/cjk': [
+ '*T9Write_CJK*/i86_linux*_32bit/*.so',
+],
+# T9 Write x86 Linux 64-bit
+T9WRITE_DIR + 'lib/linux/x86_64/static/alphabetic': [
+ '*T9Write_Alphabetic*/i86_linux*_64bit/*.a',
+ '*T9Write_Alphabetic*/i86_linux*_64bit/*.o',
+],
+T9WRITE_DIR + 'lib/linux/x86_64/shared/alphabetic': [
+ '*T9Write_Alphabetic*/i86_linux*_64bit/*.so',
+],
+T9WRITE_DIR + 'lib/linux/x86_64/static/cjk': [
+ '*T9Write_CJK*/i86_linux*_64bit/*.a',
+ '*T9Write_CJK*/i86_linux*_64bit/*.o',
+],
+T9WRITE_DIR + 'lib/linux/x86_64/shared/cjk': [
+ '*T9Write_CJK*/i86_linux*_64bit/*.so',
+],
+# T9 Write x86 Win32 32-bit
+T9WRITE_DIR + 'lib/win32/x86/static/alphabetic': [
+ '*T9Write_Alphabetic*/i86_win32_32bit/libt9write*.lib',
+],
+T9WRITE_DIR + 'lib/win32/x86/shared/alphabetic': [
+ [ '*T9Write_Alphabetic*/i86_win32_32bit/t9write*.dll', 't9write*.lib' ],
+],
+T9WRITE_DIR + 'lib/win32/x86/static/cjk': [
+ '*T9Write_CJK*/i86_win32_32bit/libt9write*.lib',
+],
+T9WRITE_DIR + 'lib/win32/x86/shared/cjk': [
+ [ '*T9Write_CJK*/i86_win32_32bit/t9write*.dll', 't9write*.lib' ],
+],
+# T9 Write x86 Win32 64-bit
+T9WRITE_DIR + 'lib/win32/amd64/static/alphabetic': [
+ '*T9Write_Alphabetic*/i86_win32_64bit/libt9write*.lib',
+],
+T9WRITE_DIR + 'lib/win32/amd64/shared/alphabetic': [
+ [ '*T9Write_Alphabetic*/i86_win32_64bit/t9write*.dll', 't9write*.lib' ],
+],
+T9WRITE_DIR + 'lib/win32/amd64/static/cjk': [
+ '*T9Write_CJK*/i86_win32_64bit/libt9write*.lib',
+],
+T9WRITE_DIR + 'lib/win32/amd64/shared/cjk': [
+ [ '*T9Write_CJK*/i86_win32_64bit/t9write*.dll', 't9write*.lib' ],
+],
+},
+
+##############################################################################
+#
+# XT9
+#
+##############################################################################
+
+{ # Header files
+XT9_DIR + 'api': [
+ '*/et9api.h',
+ '*/et9awapi.h',
+ '*/et9cpapi.h',
+ '*/et9kapi.h',
+ '*/et9kbdef.h',
+ '*/et9navapi.h',
+ '*/xxet9oem.h',
+],
+}, { # Libraries
+# XT9 ARM Linux 32-bit
+XT9_DIR + 'lib/linux/arm/static': [
+ '*/Xt9/*/arm_linux*_32bit/*.a',
+ '*/Xt9/*/arm_linux*_32bit/*.o',
],
-'lib/arm/shared/alphabetic': [
- '*T9Write_Alpha*/*Android_ARM*/*.so',
+XT9_DIR + 'lib/linux/arm/shared': [
+ '*/Xt9/*/arm_linux*_32bit/*.so',
],
-'lib/arm/static/cjk': [
- '*T9Write_CJK*/*Android_ARM*/*.a',
- '*T9Write_CJK*/*Android_ARM*/*.o',
+# XT9 ARM Linux 64-bit
+XT9_DIR + 'lib/linux/arm64/static': [
+ '*/Xt9/*/arm_linux*_64bit/*.a',
+ '*/Xt9/*/arm_linux*_64bit/*.o',
],
-'lib/arm/shared/cjk': [
- '*T9Write_CJK*/*Android_ARM*/*.so',
+XT9_DIR + 'lib/linux/arm64/shared': [
+ '*/Xt9/*/arm_linux*_64bit/*.so',
],
-'lib/linux/static/alphabetic': [
- '*T9Write_Alpha*/*Android_x86*/*.a',
- '*T9Write_Alpha*/*Android_x86*/*.o',
+# XT9 x86 Linux 32-bit
+XT9_DIR + 'lib/linux/x86/static': [
+ '*/Xt9/*/i86_linux*_32bit/*.a',
+ '*/Xt9/*/i86_linux*_32bit/*.o',
],
-'lib/linux/shared/alphabetic': [
- '*T9Write_Alpha*/*Android_x86*/*.so',
+XT9_DIR + 'lib/linux/x86/shared': [
+ '*/Xt9/*/i86_linux*_32bit/*.so',
],
-'lib/linux/static/cjk': [
- '*T9Write_CJK*/*Android_x86*/*.a',
- '*T9Write_CJK*/*Android_x86*/*.o',
+# XT9 x86 Linux 64-bit
+XT9_DIR + 'lib/linux/x86_64/static': [
+ '*/Xt9/*/i86_linux*_64bit/*.a',
+ '*/Xt9/*/i86_linux*_64bit/*.o',
],
-'lib/linux/shared/cjk': [
- '*T9Write_CJK*/*Android_x86*/*.so',
+XT9_DIR + 'lib/linux/x86_64/shared': [
+ '*/Xt9/*/i86_linux*_64bit/*.so',
],
-'lib/win32/static/alphabetic': [
- '*T9Write_Alpha*/*.obj',
+# XT9 x86 Win32 32-bit
+XT9_DIR + 'lib/win32/x86/static': [
+ '*/Xt9/*/i86_win32_32bit/libxt9*.lib',
],
-'lib/win32/shared/alphabetic': [
- [ '*T9Write_Alpha*/*.dll', '*.lib' ],
+XT9_DIR + 'lib/win32/x86/shared': [
+ [ '*/Xt9/*/i86_win32_32bit/xt9*.dll', 'xt9*.lib' ],
],
-'lib/win32/static/cjk': [
- '*T9Write_CJK*/*.obj',
+# XT9 x86 Win32 64-bit
+XT9_DIR + 'lib/win32/amd64/static': [
+ '*/Xt9/*/i86_win32_64bit/libxt9*.lib',
],
-'lib/win32/shared/cjk': [
- [ '*T9Write_CJK*/*.dll', '*.lib' ],
+XT9_DIR + 'lib/win32/amd64/shared': [
+ [ '*/Xt9/*/i86_win32_64bit/xt9*.dll', 'xt9*.lib' ],
],
-'lib/win32/shared/alphabetic': [
- [ '*T9Write_Alpha*/*.dll', '*.lib' ],
+},
+
+##############################################################################
+#
+# XT9 Data
+#
+##############################################################################
+
+{
+XT9_DATA_DIR: [
+ '*/*.ldb',
],
-}
+},
+
]
#
@@ -215,14 +350,16 @@ def unzip(zip_file, target_dir):
return zip_list
def match_file_list(file_list, base_dir, fnpattern):
- return [file_name for file_name in file_list \
+ result_list = [file_name for file_name in file_list \
if fnmatch.fnmatch(file_name, fnpattern) and \
os.path.isfile(os.path.join(base_dir, file_name))]
+ for file_name in result_list:
+ file_list.remove(file_name)
+ return result_list
def unpack(zip_list, zip_dir, out_dir):
if not zip_list:
return
-
for unpack_rules in UNPACK_RULES:
process_unpack_rules(zip_list, zip_dir, out_dir, unpack_rules)
@@ -260,14 +397,13 @@ def process_unpack_rules(zip_list, zip_dir, out_dir, unpack_rules):
dst = os.path.join(dst_dir, os.path.basename(zip_name)).replace('\\', '/')
print(zip_name + ' -> ' + dst)
shutil.copy2(src, dst)
- zip_list.remove(zip_name)
if __name__ == '__main__':
- if len(sys.argv) != 3:
- print("Usage: %s <filename.zip> <target dir>" % os.path.basename(__file__))
+ if len(sys.argv) < 2:
+ print("Usage: %s <filename.zip> [<target dir>]" % os.path.basename(__file__))
exit()
- out_dir = sys.argv[2]
+ out_dir = os.path.join(sys.path[0], 'sdk') if len(sys.argv) == 2 else sys.argv[2]
zip_dir = tempfile.mkdtemp()
try:
diff --git a/src/plugins/cerence/xt9/CMakeLists.txt b/src/plugins/cerence/xt9/CMakeLists.txt
new file mode 100644
index 00000000..941e8ffc
--- /dev/null
+++ b/src/plugins/cerence/xt9/CMakeLists.txt
@@ -0,0 +1,4 @@
+# Generated from xt9.pro.
+
+add_subdirectory(plugin)
+add_subdirectory(xt9common)
diff --git a/src/plugins/cerence/xt9/plugin/9key_layouts/content/layouts/ja_JP/main.qml b/src/plugins/cerence/xt9/plugin/9key_layouts/content/layouts/ja_JP/main.qml
new file mode 100644
index 00000000..738bb096
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/9key_layouts/content/layouts/ja_JP/main.qml
@@ -0,0 +1,694 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick
+import QtQuick.Layouts
+import QtQuick.VirtualKeyboard
+
+KeyboardLayoutLoader {
+ function createInputMethod() {
+ return Qt.createQmlObject('import QtQuick; import QtQuick.VirtualKeyboard.Plugins; JapaneseInputMethod {}', parent, "japaneseInputMethod")
+ }
+ sourceComponent: {
+ switch (InputContext.inputEngine.inputMode) {
+ case InputEngine.Katakana:
+ return katakana9key
+ case InputEngine.Hiragana:
+ return hiragana9key
+ case InputEngine.FullwidthLatin:
+ return fullWidthQwerty
+ default:
+ return qwerty
+ }
+ }
+ Component {
+ id: hiragana9key
+ KeyboardLayout {
+ KeyboardRow {
+ Layout.fillWidth: false
+ Layout.fillHeight: true
+ Layout.alignment: Qt.AlignHCenter
+ KeyboardColumn {
+ Layout.fillWidth: false
+ Layout.fillHeight: true
+ Layout.preferredWidth: parent.height / 4 * 1
+ Key {
+ text: "~"
+ alternativeKeys: "~『』「」()〔〕〈〉《》【】"
+ highlighted: true
+ }
+ Key {
+ text: "@"
+ alternativeKeys: "@#$%^&*()=<>,.:;!?~"
+ highlighted: true
+ }
+ InputModeKey {}
+ SymbolModeKey {}
+ }
+ KeyboardColumn {
+ Layout.fillWidth: false
+ Layout.fillHeight: true
+ Layout.preferredWidth: parent.height / 30
+ KeyboardRow {
+ FillerKey {}
+ }
+ }
+ KeyboardColumn {
+ Layout.fillWidth: false
+ Layout.fillHeight: true
+ Layout.preferredWidth: parent.height / 4 * 3
+ KeyboardRow {
+ FlickKey {
+ text: "あ"
+ alternativeKeys: "あいうえお"
+ }
+ FlickKey {
+ text: "か"
+ alternativeKeys: "かきくけこ"
+ }
+ FlickKey {
+ text: "さ"
+ alternativeKeys: "さしすせそ"
+ }
+ }
+ KeyboardRow {
+ FlickKey {
+ text: "た"
+ alternativeKeys: "たちつてと"
+ }
+ FlickKey {
+ text: "な"
+ alternativeKeys: "なにぬねの"
+ }
+ FlickKey {
+ text: "は"
+ alternativeKeys: "はひふへほ"
+ }
+ }
+ KeyboardRow {
+ FlickKey {
+ text: "ま"
+ alternativeKeys: "まみむめも"
+ }
+ FlickKey {
+ text: "や"
+ alternativeKeys: "や(ゆ)よ"
+ }
+ FlickKey {
+ text: "ら"
+ alternativeKeys: "らりるれろ"
+ }
+ }
+ KeyboardRow {
+ readonly property bool modifyKeyEnabled: InputContext.inputEngine.inputMethod !== null &&
+ InputContext.inputEngine.inputMethod.hasOwnProperty("modifyKeyEnabled") &&
+ InputContext.inputEngine.inputMethod.modifyKeyEnabled
+ FlickKey {
+ visible: parent.modifyKeyEnabled
+ text: "小"
+ alternativeKeys: "小\u3099\u309A"
+ }
+ Key {
+ visible: !parent.modifyKeyEnabled
+ key: Qt.Key_Comma
+ text: "\u3001"
+ smallText: "\u2699"
+ smallTextVisible: true
+ }
+ FlickKey {
+ text: "わ"
+ alternativeKeys: "わをんー〜"
+ }
+ FlickKey {
+ text: "。"
+ alternativeKeys: "。,!:?"
+ }
+ }
+ }
+ KeyboardColumn {
+ Layout.fillWidth: false
+ Layout.fillHeight: true
+ Layout.preferredWidth: parent.height / 30
+ KeyboardRow {
+ FillerKey {}
+ }
+ }
+ KeyboardColumn {
+ Layout.fillWidth: false
+ Layout.fillHeight: true
+ Layout.preferredWidth: parent.height / 4 * 1
+ BackspaceKey {}
+ Key {
+ text: "\u3000"
+ displayText: "\u2423"
+ repeat: true
+ showPreview: false
+ key: Qt.Key_Space
+ highlighted: true
+ }
+ HideKeyboardKey {}
+ EnterKey {}
+ }
+ }
+ }
+ }
+ Component {
+ id: katakana9key
+ KeyboardLayout {
+ KeyboardRow {
+ Layout.fillWidth: false
+ Layout.fillHeight: true
+ Layout.alignment: Qt.AlignHCenter
+ KeyboardColumn {
+ Layout.fillWidth: false
+ Layout.fillHeight: true
+ Layout.preferredWidth: parent.height / 4 * 1
+ Key {
+ text: "~"
+ alternativeKeys: "~『』「」()〔〕〈〉《》【】"
+ highlighted: true
+ }
+ Key {
+ text: "@"
+ alternativeKeys: "@#$%^&*()=<>,.:;!?~"
+ highlighted: true
+ }
+ InputModeKey {}
+ SymbolModeKey {}
+ }
+ KeyboardColumn {
+ Layout.fillWidth: false
+ Layout.fillHeight: true
+ Layout.preferredWidth: parent.height / 30
+ KeyboardRow {
+ FillerKey {}
+ }
+ }
+ KeyboardColumn {
+ Layout.fillWidth: false
+ Layout.fillHeight: true
+ Layout.preferredWidth: parent.height / 4 * 3
+ KeyboardRow {
+ FlickKey {
+ text: "ア"
+ alternativeKeys: "アイウエオ"
+ }
+ FlickKey {
+ text: "カ"
+ alternativeKeys: "カキクケコ"
+ }
+ FlickKey {
+ text: "サ"
+ alternativeKeys: "サシスセソ"
+ }
+ }
+ KeyboardRow {
+ FlickKey {
+ text: "タ"
+ alternativeKeys: "タチツテト"
+ }
+ FlickKey {
+ text: "ナ"
+ alternativeKeys: "ナニヌネノ"
+ }
+ FlickKey {
+ text: "ハ"
+ alternativeKeys: "ハヒフヘホ"
+ }
+ }
+ KeyboardRow {
+ FlickKey {
+ text: "マ"
+ alternativeKeys: "マミムメモ"
+ }
+ FlickKey {
+ text: "ヤ"
+ alternativeKeys: "ヤ(ユ)ヨ"
+ }
+ FlickKey {
+ text: "ラ"
+ alternativeKeys: "ラリルレロ"
+ }
+ }
+ KeyboardRow {
+ readonly property bool modifyKeyEnabled: InputContext.inputEngine.inputMethod !== null &&
+ InputContext.inputEngine.inputMethod.hasOwnProperty("modifyKeyEnabled") &&
+ InputContext.inputEngine.inputMethod.modifyKeyEnabled
+ FlickKey {
+ visible: parent.modifyKeyEnabled
+ text: "小"
+ alternativeKeys: "小\u3099\u309A"
+ }
+ Key {
+ visible: !parent.modifyKeyEnabled
+ key: Qt.Key_Comma
+ text: "\u3001"
+ smallText: "\u2699"
+ smallTextVisible: true
+ }
+ FlickKey {
+ text: "ワ"
+ alternativeKeys: "ワヲンー〜"
+ }
+ FlickKey {
+ text: "。"
+ alternativeKeys: "。,!:?"
+ }
+ }
+ }
+ KeyboardColumn {
+ Layout.fillWidth: false
+ Layout.fillHeight: true
+ Layout.preferredWidth: parent.height / 30
+ KeyboardRow {
+ FillerKey {}
+ }
+ }
+ KeyboardColumn {
+ Layout.fillWidth: false
+ Layout.fillHeight: true
+ Layout.preferredWidth: parent.height / 4 * 1
+ BackspaceKey {}
+ Key {
+ text: "\u3000"
+ displayText: "\u2423"
+ repeat: true
+ showPreview: false
+ key: Qt.Key_Space
+ highlighted: true
+ }
+ HideKeyboardKey {}
+ EnterKey {}
+ }
+ }
+ }
+ }
+ Component {
+ id: qwerty
+ KeyboardLayout {
+ keyWeight: 160
+ readonly property real normalKeyWidth: normalKey.width
+ readonly property real functionKeyWidth: mapFromItem(normalKey, normalKey.width / 2, 0).x
+ KeyboardRow {
+ Key {
+ key: Qt.Key_Q
+ text: "q"
+ }
+ Key {
+ id: normalKey
+ key: Qt.Key_W
+ text: "w"
+ }
+ Key {
+ key: Qt.Key_E
+ text: "e"
+ }
+ Key {
+ key: Qt.Key_R
+ text: "r"
+ }
+ Key {
+ key: Qt.Key_T
+ text: "t"
+ }
+ Key {
+ key: Qt.Key_Y
+ text: "y"
+ }
+ Key {
+ key: Qt.Key_U
+ text: "u"
+ }
+ Key {
+ key: Qt.Key_I
+ text: "i"
+ }
+ Key {
+ key: Qt.Key_O
+ text: "o"
+ }
+ Key {
+ key: Qt.Key_P
+ text: "p"
+ }
+ }
+ KeyboardRow {
+ KeyboardRow {
+ Layout.preferredWidth: functionKeyWidth
+ Layout.fillWidth: false
+ FillerKey {
+ }
+ Key {
+ key: Qt.Key_A
+ text: "a"
+ Layout.preferredWidth: normalKeyWidth
+ Layout.fillWidth: false
+ }
+ }
+ Key {
+ key: Qt.Key_S
+ text: "s"
+ }
+ Key {
+ key: Qt.Key_D
+ text: "d"
+ }
+ Key {
+ key: Qt.Key_F
+ text: "f"
+ }
+ Key {
+ key: Qt.Key_G
+ text: "g"
+ }
+ Key {
+ key: Qt.Key_H
+ text: "h"
+ }
+ Key {
+ key: Qt.Key_J
+ text: "j"
+ }
+ Key {
+ key: Qt.Key_K
+ text: "k"
+ }
+ KeyboardRow {
+ Layout.preferredWidth: functionKeyWidth
+ Layout.fillWidth: false
+ Key {
+ key: Qt.Key_L
+ text: "l"
+ Layout.preferredWidth: normalKeyWidth
+ Layout.fillWidth: false
+ }
+ FillerKey {
+ }
+ }
+ }
+ KeyboardRow {
+ ShiftKey {
+ Layout.preferredWidth: functionKeyWidth
+ Layout.fillWidth: false
+ }
+ Key {
+ key: Qt.Key_Z
+ text: "z"
+ }
+ Key {
+ key: Qt.Key_X
+ text: "x"
+ }
+ Key {
+ key: Qt.Key_C
+ text: "c"
+ }
+ Key {
+ key: Qt.Key_V
+ text: "v"
+ }
+ Key {
+ key: Qt.Key_B
+ text: "b"
+ }
+ Key {
+ key: Qt.Key_N
+ text: "n"
+ }
+ Key {
+ key: Qt.Key_M
+ text: "m"
+ }
+ BackspaceKey {
+ Layout.preferredWidth: functionKeyWidth
+ Layout.fillWidth: false
+ }
+ }
+ KeyboardRow {
+ SymbolModeKey {
+ Layout.preferredWidth: functionKeyWidth
+ Layout.fillWidth: false
+ }
+ Key {
+ key: Qt.Key_Comma
+ Layout.preferredWidth: normalKeyWidth
+ Layout.fillWidth: false
+ text: "\u3001"
+ smallText: "\u2699"
+ smallTextVisible: true
+ highlighted: true
+ }
+ InputModeKey {
+ enabled: !(InputContext.inputMethodHints & Qt.ImhLatinOnly) && inputModeCount > 1
+ Layout.preferredWidth: normalKeyWidth
+ Layout.fillWidth: false
+ inputModeNameList: [
+ "半角", // InputEngine.InputMode.Latin
+ "", // InputEngine.InputMode.Numeric
+ "", // InputEngine.InputMode.Dialable
+ "", // InputEngine.InputMode.Pinyin
+ "", // InputEngine.InputMode.Cangjie
+ "", // InputEngine.InputMode.Zhuyin
+ "", // InputEngine.InputMode.Hangul
+ "あ", // InputEngine.InputMode.Hiragana
+ "カ", // InputEngine.InputMode.Katakana
+ "全角", // InputEngine.InputMode.FullwidthLatin
+ ]
+ }
+ SpaceKey {
+ }
+ Key {
+ key: Qt.Key_Period
+ Layout.preferredWidth: normalKeyWidth
+ Layout.fillWidth: false
+ text: "\u3002"
+ alternativeKeys: "\u3001\uFF01\u3002\uFF1F,.?!"
+ smallText: "!?"
+ smallTextVisible: true
+ highlighted: true
+ }
+ EnterKey {
+ Layout.preferredWidth: functionKeyWidth
+ Layout.fillWidth: false
+ }
+ }
+ }
+ }
+ Component {
+ id: fullWidthQwerty
+ KeyboardLayout {
+ keyWeight: 160
+ readonly property real normalKeyWidth: normalKey.width
+ readonly property real functionKeyWidth: mapFromItem(normalKey, normalKey.width / 2, 0).x
+ KeyboardRow {
+ Key {
+ key: Qt.Key_Q
+ text: "\uFF51"
+ }
+ Key {
+ id: normalKey
+ key: Qt.Key_W
+ text: "\uFF57"
+ }
+ Key {
+ key: Qt.Key_E
+ text: "\uFF45"
+ }
+ Key {
+ key: Qt.Key_R
+ text: "\uFF52"
+ }
+ Key {
+ key: Qt.Key_T
+ text: "\uFF54"
+ }
+ Key {
+ key: Qt.Key_Y
+ text: "\uFF59"
+ }
+ Key {
+ key: Qt.Key_U
+ text: "\uFF55"
+ }
+ Key {
+ key: Qt.Key_I
+ text: "\uFF49"
+ }
+ Key {
+ key: Qt.Key_O
+ text: "\uFF4F"
+ }
+ Key {
+ key: Qt.Key_P
+ text: "\uFF50"
+ }
+ }
+ KeyboardRow {
+ KeyboardRow {
+ Layout.preferredWidth: functionKeyWidth
+ Layout.fillWidth: false
+ FillerKey {
+ }
+ Key {
+ key: Qt.Key_A
+ text: "\uFF41"
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ }
+ }
+ Key {
+ key: Qt.Key_S
+ text: "\uFF53"
+ }
+ Key {
+ key: Qt.Key_D
+ text: "\uFF44"
+ }
+ Key {
+ key: Qt.Key_F
+ text: "\uFF46"
+ }
+ Key {
+ key: Qt.Key_G
+ text: "\uFF47"
+ }
+ Key {
+ key: Qt.Key_H
+ text: "\uFF48"
+ }
+ Key {
+ key: Qt.Key_J
+ text: "\uFF4A"
+ }
+ Key {
+ key: Qt.Key_K
+ text: "\uFF4B"
+ }
+ KeyboardRow {
+ Layout.preferredWidth: functionKeyWidth
+ Layout.fillWidth: false
+ Key {
+ key: Qt.Key_L
+ text: "\uFF4C"
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ }
+ FillerKey {
+ }
+ }
+ }
+ KeyboardRow {
+ ShiftKey {
+ weight: functionKeyWidth
+ Layout.fillWidth: false
+ }
+ Key {
+ key: Qt.Key_Z
+ text: "\uFF5A"
+ }
+ Key {
+ key: Qt.Key_X
+ text: "\uFF58"
+ }
+ Key {
+ key: Qt.Key_C
+ text: "\uFF43"
+ }
+ Key {
+ key: Qt.Key_V
+ text: "\uFF56"
+ }
+ Key {
+ key: Qt.Key_B
+ text: "\uFF42"
+ }
+ Key {
+ key: Qt.Key_N
+ text: "\uFF4E"
+ }
+ Key {
+ key: Qt.Key_M
+ text: "\uFF4D"
+ }
+ BackspaceKey {
+ weight: functionKeyWidth
+ Layout.fillWidth: false
+ }
+ }
+ KeyboardRow {
+ SymbolModeKey {
+ weight: functionKeyWidth
+ Layout.fillWidth: false
+ }
+ Key {
+ key: Qt.Key_Comma
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ text: "\u3001"
+ smallText: "\u2699"
+ smallTextVisible: true
+ highlighted: true
+ }
+ InputModeKey {
+ enabled: !(InputContext.inputMethodHints & Qt.ImhLatinOnly) && inputModeCount > 1
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ inputModeNameList: [
+ "半角", // InputEngine.InputMode.Latin
+ "", // InputEngine.InputMode.Numeric
+ "", // InputEngine.InputMode.Dialable
+ "", // InputEngine.InputMode.Pinyin
+ "", // InputEngine.InputMode.Cangjie
+ "", // InputEngine.InputMode.Zhuyin
+ "", // InputEngine.InputMode.Hangul
+ "あ", // InputEngine.InputMode.Hiragana
+ "カ", // InputEngine.InputMode.Katakana
+ "全角", // InputEngine.InputMode.FullwidthLatin
+ ]
+ }
+ SpaceKey {
+ }
+ Key {
+ key: Qt.Key_Period
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ text: "\u3002"
+ alternativeKeys: "\u3001\uFF01\u3002\uFF1F,.?!"
+ smallText: "!?"
+ smallTextVisible: true
+ highlighted: true
+ }
+ EnterKey {
+ weight: functionKeyWidth
+ Layout.fillWidth: false
+ }
+ }
+ }
+ }
+}
diff --git a/src/plugins/cerence/xt9/plugin/9key_layouts/content/layouts/zh_CN/main.qml b/src/plugins/cerence/xt9/plugin/9key_layouts/content/layouts/zh_CN/main.qml
new file mode 100644
index 00000000..14fca086
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/9key_layouts/content/layouts/zh_CN/main.qml
@@ -0,0 +1,188 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick
+import QtQuick.Layouts
+import QtQuick.VirtualKeyboard
+
+KeyboardLayout {
+ function createInputMethod() {
+ return Qt.createQmlObject('import QtQuick; import QtQuick.VirtualKeyboard.Plugins; PinyinInputMethod {}', parent, "main.qml")
+ }
+ sharedLayouts: ['symbols']
+ smallTextVisible: true
+ inputMode: InputEngine.InputMode.Pinyin
+ KeyboardRow {
+ Layout.fillWidth: false
+ Layout.fillHeight: true
+ Layout.alignment: Qt.AlignHCenter
+ KeyboardColumn {
+ Layout.fillWidth: false
+ Layout.fillHeight: true
+ Layout.preferredWidth: parent.height / 4 * 1
+ Key {
+ text: "~"
+ alternativeKeys: "~『』「」()〔〕〈〉《》【】"
+ highlighted: true
+ }
+ Key {
+ text: "@"
+ alternativeKeys: "@#$%^&*()=<>,.:;!?~"
+ highlighted: true
+ }
+ FillerKey {}
+ SymbolModeKey {}
+ }
+ KeyboardColumn {
+ Layout.fillWidth: false
+ Layout.fillHeight: true
+ Layout.preferredWidth: parent.height / 30
+ KeyboardRow {
+ FillerKey {}
+ }
+ }
+ KeyboardColumn {
+ Layout.fillWidth: false
+ Layout.fillHeight: true
+ Layout.preferredWidth: parent.height / 4 * 3
+ KeyboardRow {
+ Key {
+ enabled: InputContext.preeditText.length > 0
+ key: Qt.Key_Apostrophe
+ text: "'"
+ displayText: "词"
+ smallText: "1"
+ alternativeKeys: "'1"
+ }
+ Key {
+ key: Qt.Key_2
+ text: "a"
+ displayText: "ABC"
+ smallText: "2"
+ alternativeKeys: "abc2"
+ }
+ Key {
+ key: Qt.Key_3
+ text: "d"
+ displayText: "DEF"
+ smallText: "3"
+ alternativeKeys: "def3"
+ }
+ }
+ KeyboardRow {
+ Key {
+ key: Qt.Key_4
+ text: "g"
+ displayText: "GHI"
+ smallText: "4"
+ alternativeKeys: "ghi4"
+ }
+ Key {
+ key: Qt.Key_5
+ text: "j"
+ displayText: "JKL"
+ smallText: "5"
+ alternativeKeys: "jkl5"
+ }
+ Key {
+ key: Qt.Key_6
+ text: "m"
+ displayText: "MNO"
+ smallText: "6"
+ alternativeKeys: "mno6"
+ }
+ }
+ KeyboardRow {
+ Key {
+ key: Qt.Key_7
+ text: "p"
+ displayText: "PQRS"
+ smallText: "7"
+ alternativeKeys: "pqrs7"
+ }
+ Key {
+ key: Qt.Key_8
+ text: "t"
+ displayText: "TUV"
+ smallText: "8"
+ alternativeKeys: "tuv8"
+ }
+ Key {
+ key: Qt.Key_9
+ text: "w"
+ displayText: "WXYZ"
+ smallText: "9"
+ alternativeKeys: "wxyz9"
+ }
+ }
+ KeyboardRow {
+ Key {
+ key: Qt.Key_Comma
+ text: "\u3001"
+ smallText: "\u2699"
+ smallTextVisible: true
+ }
+ Key {
+ key: Qt.Key_0
+ text: ","
+ alternativeKeys: ",;0"
+ smallText: "0"
+ }
+ Key {
+ text: "。"
+ alternativeKeys: "。?!:"
+ }
+ }
+ }
+ KeyboardColumn {
+ Layout.fillWidth: false
+ Layout.fillHeight: true
+ Layout.preferredWidth: parent.height / 30
+ KeyboardRow {
+ FillerKey {}
+ }
+ }
+ KeyboardColumn {
+ Layout.fillWidth: false
+ Layout.fillHeight: true
+ Layout.preferredWidth: parent.height / 4 * 1
+ BackspaceKey {}
+ Key {
+ text: "\u3000"
+ displayText: "\u2423"
+ repeat: true
+ showPreview: false
+ key: Qt.Key_Space
+ highlighted: true
+ }
+ HideKeyboardKey {}
+ EnterKey {}
+ }
+ }
+}
diff --git a/src/plugins/cerence/xt9/plugin/9key_layouts/content/layouts/zh_TW/main.qml b/src/plugins/cerence/xt9/plugin/9key_layouts/content/layouts/zh_TW/main.qml
new file mode 100644
index 00000000..9b580c15
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/9key_layouts/content/layouts/zh_TW/main.qml
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick
+import QtQuick.Layouts
+import QtQuick.VirtualKeyboard
+
+KeyboardLayout {
+ function createInputMethod() {
+ return Qt.createQmlObject('import QtQuick; import QtQuick.VirtualKeyboard.Plugins; StrokeInputMethod {}', parent, "main.qml")
+ }
+ sharedLayouts: ['symbols']
+ smallTextVisible: true
+ inputMode: InputEngine.InputMode.Stroke
+ KeyboardRow {
+ Layout.fillWidth: false
+ Layout.fillHeight: true
+ Layout.alignment: Qt.AlignHCenter
+ KeyboardColumn {
+ Layout.fillWidth: false
+ Layout.fillHeight: true
+ Layout.preferredWidth: parent.height / 4 * 1
+ Key {
+ text: "~"
+ alternativeKeys: "~『』「」()〔〕〈〉《》【】"
+ highlighted: true
+ }
+ Key {
+ text: "@"
+ alternativeKeys: "@#$%^&*()=<>,.:;!?~"
+ highlighted: true
+ }
+ FillerKey {}
+ SymbolModeKey {}
+ }
+ KeyboardColumn {
+ Layout.fillWidth: false
+ Layout.fillHeight: true
+ Layout.preferredWidth: parent.height / 30
+ KeyboardRow {
+ FillerKey {}
+ }
+ }
+ KeyboardColumn {
+ Layout.fillWidth: false
+ Layout.fillHeight: true
+ Layout.preferredWidth: parent.height / 4 * 3
+ KeyboardRow {
+ Key {
+ key: Qt.Key_1
+ text: "\u0001"
+ displayText: "\u4E00"
+ smallText: "1"
+ alternativeKeys: "\u00011"
+ }
+ Key {
+ key: Qt.Key_2
+ text: "\u0002"
+ displayText: "\u4E28"
+ smallText: "2"
+ alternativeKeys: "\u00022"
+ }
+ Key {
+ key: Qt.Key_3
+ text: "\u0003"
+ displayText: "\u4E3F"
+ smallText: "3"
+ alternativeKeys: "\u00033"
+ }
+ }
+ KeyboardRow {
+ Key {
+ key: Qt.Key_4
+ text: "\u0004"
+ displayText: "\u4E36"
+ smallText: "4"
+ alternativeKeys: "\u00044"
+ }
+ Key {
+ key: Qt.Key_5
+ text: "\u0005"
+ displayText: "\u4E5B"
+ smallText: "5"
+ alternativeKeys: "\u00055"
+ }
+ Key {
+ key: Qt.Key_6
+ text: "\u0006"
+ displayText: "*"
+ smallText: "6"
+ alternativeKeys: "\u00066"
+ }
+ }
+ KeyboardRow {
+ Key {
+ key: Qt.Key_7
+ text: ","
+ smallText: "7"
+ alternativeKeys: ",7"
+ }
+ Key {
+ key: Qt.Key_8
+ text: "!"
+ smallText: "8"
+ alternativeKeys: "!8"
+ }
+ Key {
+ key: Qt.Key_9
+ text: "?"
+ smallText: "9"
+ alternativeKeys: "?9"
+ }
+ }
+ KeyboardRow {
+ Key {
+ key: Qt.Key_Comma
+ text: "\u3001"
+ smallText: "\u2699"
+ smallTextVisible: true
+ }
+ Key {
+ key: Qt.Key_0
+ text: ";"
+ alternativeKeys: ";0"
+ smallText: "0"
+ }
+ Key {
+ text: "。"
+ alternativeKeys: "。:"
+ }
+ }
+ }
+ KeyboardColumn {
+ Layout.fillWidth: false
+ Layout.fillHeight: true
+ Layout.preferredWidth: parent.height / 30
+ KeyboardRow {
+ FillerKey {}
+ }
+ }
+ KeyboardColumn {
+ Layout.fillWidth: false
+ Layout.fillHeight: true
+ Layout.preferredWidth: parent.height / 4 * 1
+ BackspaceKey {}
+ Key {
+ text: "\u3000"
+ displayText: "\u2423"
+ repeat: true
+ showPreview: false
+ key: Qt.Key_Space
+ highlighted: true
+ }
+ HideKeyboardKey {}
+ EnterKey {}
+ }
+ }
+}
diff --git a/src/plugins/cerence/xt9/plugin/CMakeLists.txt b/src/plugins/cerence/xt9/plugin/CMakeLists.txt
new file mode 100644
index 00000000..45b31b08
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/CMakeLists.txt
@@ -0,0 +1,413 @@
+# Generated from plugin.pro.
+
+#####################################################################
+## QtVirtualKeyboardXt9Plugin Plugin:
+#####################################################################
+
+qt_internal_add_plugin(QtVirtualKeyboardXt9Plugin
+ OUTPUT_NAME qtvirtualkeyboard_cerence_xt9
+ TYPE virtualkeyboard
+ SOURCES
+ xt9awinputmethod.cpp xt9awinputmethod_p.h
+ xt9awinputmethodprivate.cpp xt9awinputmethodprivate_p.h
+ xt9cpinputmethod.cpp xt9cpinputmethod_p.h
+ xt9cpinputmethodprivate.cpp xt9cpinputmethodprivate_p.h
+ xt9inputmethod.cpp xt9inputmethod_p.h
+ xt9inputmethodprivate.cpp xt9inputmethodprivate_p.h
+ xt9jinputmethod.cpp xt9jinputmethod_p.h
+ xt9jinputmethodprivate.cpp xt9jinputmethodprivate_p.h
+ xt9kinputmethod.cpp xt9kinputmethod_p.h
+ xt9kinputmethodprivate.cpp xt9kinputmethodprivate_p.h
+ xt9plugin.cpp xt9plugin.h
+ xt9thaiinputmethod.cpp xt9thaiinputmethod_p.h
+ xt9thaiinputmethodprivate.cpp xt9thaiinputmethodprivate_p.h
+ DEFINES
+ QT_ASCII_CAST_WARNINGS
+ QT_NO_CAST_FROM_ASCII
+ QT_NO_CAST_FROM_BYTEARRAY
+ QT_NO_CAST_TO_ASCII
+ LIBRARIES
+ BundledCerencecommon
+ BundledXt9Common
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::Gui
+ Qt::Qml
+ Qt::VirtualKeyboardPrivate
+)
+
+#### Keys ignored in scope 1:.:.:plugin.pro:<TRUE>:
+# DISTFILES = "cerence_xt9.json"
+# OTHER_FILES = "$$LAYOUT_FILES"
+# virtualkeyboard_xt9_custom_layouts.base = "$$PWD"
+# virtualkeyboard_xt9_custom_layouts.prefix = "$$LAYOUTS_PREFIX"
+# virtualkeyboard_xt9_layouts.base = "$$LAYOUTS_BASE"
+# virtualkeyboard_xt9_layouts.prefix = "$$LAYOUTS_PREFIX"
+
+## Scopes:
+#####################################################################
+
+#### Keys ignored in scope 3:.:.:plugin.pro:NOT XT9_BINS_ISEMPTY:
+# INSTALLS = "xt9_bins"
+# xt9_bins.files = "$$XT9_BINS"
+
+#### Keys ignored in scope 4:.:.:plugin.pro:WIN32 OR win64:
+# xt9_bins.path = "$$[QT_INSTALL_BINS]"
+
+#### Keys ignored in scope 5:.:.:plugin.pro:else:
+# xt9_bins.path = "$$[QT_INSTALL_LIBS]"
+
+#### Keys ignored in scope 6:.:.:plugin.pro:NOT prefix_build:
+# COPIES = "xt9_bins"
+
+#### Keys ignored in scope 7:.:.:plugin.pro:CONFIG___contains___lang-ja._x_:
+# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/ja_JP/digits.fallback" "$$LAYOUTS_BASE/content/layouts/ja_JP/numbers.fallback" "$$LAYOUTS_BASE/content/layouts/ja_JP/symbols.qml" "$$LAYOUTS_BASE/content/layouts/ja_JP/dialpad.fallback"
+
+#### Keys ignored in scope 11:.:.:plugin.pro:CONFIG___contains___lang-ko._x_:
+# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/ko_KR/digits.fallback" "$$LAYOUTS_BASE/content/layouts/ko_KR/main.qml" "$$LAYOUTS_BASE/content/layouts/ko_KR/numbers.fallback" "$$LAYOUTS_BASE/content/layouts/ko_KR/symbols.qml" "$$LAYOUTS_BASE/content/layouts/ko_KR/dialpad.fallback"
+
+#### Keys ignored in scope 16:.:.:plugin.pro:CONFIG___contains___lang-th._x_:
+# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/th_TH/digits.fallback" "$$LAYOUTS_BASE/content/layouts/th_TH/main.qml" "$$LAYOUTS_BASE/content/layouts/th_TH/numbers.fallback" "$$LAYOUTS_BASE/content/layouts/th_TH/symbols.qml" "$$LAYOUTS_BASE/content/layouts/th_TH/dialpad.fallback"
+
+#### Keys ignored in scope 21:.:.:plugin.pro:CONFIG___contains___lang-zh(_CN?):
+# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/zh_CN/digits.fallback" "$$LAYOUTS_BASE/content/layouts/zh_CN/numbers.fallback" "$$LAYOUTS_BASE/content/layouts/zh_CN/symbols.qml" "$$LAYOUTS_BASE/content/layouts/zh_CN/dialpad.fallback"
+
+#### Keys ignored in scope 25:.:.:plugin.pro:NOT xt9-9key-pinyin AND CONFIG___contains___lang-zh(_CN?):
+# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/zh_CN/main.qml"
+
+#### Keys ignored in scope 26:.:.:plugin.pro:CONFIG___contains___lang-zh(_TW?):
+# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/zh_TW/digits.fallback" "$$LAYOUTS_BASE/content/layouts/zh_TW/numbers.fallback" "$$LAYOUTS_BASE/content/layouts/zh_TW/symbols.qml" "$$LAYOUTS_BASE/content/layouts/zh_TW/dialpad.fallback"
+
+#### Keys ignored in scope 31:.:.:plugin.pro:xt9-9key-pinyin AND CONFIG___contains___lang-zh(_CN?):
+# CUSTOM_LAYOUT_FILES = "$$PWD/content/layouts/zh_CN/main.qml"
+
+#### Keys ignored in scope 32:.:.:plugin.pro:CONFIG___contains___lang-zh(_HK?):
+# CUSTOM_LAYOUT_FILES = "$$PWD/content/layouts/zh_HK/digits.fallback" "$$PWD/content/layouts/zh_HK/numbers.fallback" "$$PWD/content/layouts/zh_HK/symbols.qml" "$$PWD/content/layouts/zh_HK/main.qml" "$$PWD/content/layouts/zh_HK/dialpad.fallback"
+
+#### Keys ignored in scope 38:.:.:plugin.pro:xt9-9key-stroke:
+# CUSTOM_LAYOUT_FILES = "$$PWD/content/layouts/zh_TW/main.qml"
+
+set(qmake_virtualkeyboard_xt9_layouts_resource_files)
+if (QT_FEATURE_vkb_lang_ja_JP)
+ list(APPEND qmake_virtualkeyboard_xt9_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/ja_JP/digits.fallback"
+ "${VKB_LAYOUTS_BASE}/content/layouts/ja_JP/numbers.fallback"
+ "${VKB_LAYOUTS_BASE}/content/layouts/ja_JP/symbols.qml"
+ "${VKB_LAYOUTS_BASE}/content/layouts/ja_JP/dialpad.fallback"
+ )
+endif()
+if (QT_FEATURE_vkb_lang_ko_KR)
+ list(APPEND qmake_virtualkeyboard_xt9_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/ko_KR/digits.fallback"
+ "${VKB_LAYOUTS_BASE}/content/layouts/ko_KR/main.qml"
+ "${VKB_LAYOUTS_BASE}/content/layouts/ko_KR/numbers.fallback"
+ "${VKB_LAYOUTS_BASE}/content/layouts/ko_KR/symbols.qml"
+ "${VKB_LAYOUTS_BASE}/content/layouts/ko_KR/dialpad.fallback"
+ )
+endif()
+if (QT_FEATURE_vkb_lang_th_TH)
+ list(APPEND qmake_virtualkeyboard_xt9_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/th_TH/digits.fallback"
+ "${VKB_LAYOUTS_BASE}/content/layouts/th_TH/main.qml"
+ "${VKB_LAYOUTS_BASE}/content/layouts/th_TH/numbers.fallback"
+ "${VKB_LAYOUTS_BASE}/content/layouts/th_TH/symbols.qml"
+ "${VKB_LAYOUTS_BASE}/content/layouts/th_TH/dialpad.fallback"
+ )
+endif()
+if (QT_FEATURE_vkb_lang_zh_CN)
+ list(APPEND qmake_virtualkeyboard_xt9_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/zh_CN/digits.fallback"
+ "${VKB_LAYOUTS_BASE}/content/layouts/zh_CN/numbers.fallback"
+ "${VKB_LAYOUTS_BASE}/content/layouts/zh_CN/symbols.qml"
+ "${VKB_LAYOUTS_BASE}/content/layouts/zh_CN/dialpad.fallback"
+ )
+endif()
+if (NOT FEATURE_vkb_cerence_xt9_9key_layouts AND QT_FEATURE_vkb_lang_zh_CN)
+ list(APPEND qmake_virtualkeyboard_xt9_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/zh_CN/main.qml"
+ )
+endif()
+if (QT_FEATURE_vkb_lang_zh_TW)
+ list(APPEND qmake_virtualkeyboard_xt9_layouts_resource_files
+ "${VKB_LAYOUTS_BASE}/content/layouts/zh_TW/digits.fallback"
+ "${VKB_LAYOUTS_BASE}/content/layouts/zh_TW/numbers.fallback"
+ "${VKB_LAYOUTS_BASE}/content/layouts/zh_TW/symbols.qml"
+ "${VKB_LAYOUTS_BASE}/content/layouts/zh_TW/dialpad.fallback"
+ )
+endif()
+
+qt_internal_add_resource(QtVirtualKeyboardXt9Plugin "qmake_virtualkeyboard_xt9_layouts"
+ PREFIX
+ "${VKB_LAYOUTS_PREFIX}"
+ BASE
+ "${VKB_LAYOUTS_BASE}"
+ FILES
+ ${qmake_virtualkeyboard_xt9_layouts_resource_files}
+)
+
+
+set(qmake_virtualkeyboard_xt9_custom_layouts_resource_files)
+if (QT_FEATURE_vkb_lang_ja_JP AND NOT FEATURE_vkb_cerence_xt9_9key_layouts)
+ list(APPEND qmake_virtualkeyboard_xt9_custom_layouts_resource_files
+ "${CMAKE_CURRENT_SOURCE_DIR}/content/layouts/ja_JP/main.qml"
+ )
+endif()
+if (QT_FEATURE_vkb_lang_zh_HK)
+ list(APPEND qmake_virtualkeyboard_xt9_custom_layouts_resource_files
+ "${CMAKE_CURRENT_SOURCE_DIR}/content/layouts/zh_HK/digits.fallback"
+ "${CMAKE_CURRENT_SOURCE_DIR}/content/layouts/zh_HK/numbers.fallback"
+ "${CMAKE_CURRENT_SOURCE_DIR}/content/layouts/zh_HK/symbols.qml"
+ "${CMAKE_CURRENT_SOURCE_DIR}/content/layouts/zh_HK/main.qml"
+ "${CMAKE_CURRENT_SOURCE_DIR}/content/layouts/zh_HK/dialpad.fallback"
+ )
+endif()
+
+qt_internal_add_resource(QtVirtualKeyboardXt9Plugin "qmake_virtualkeyboard_xt9_custom_layouts"
+ PREFIX
+ "${VKB_LAYOUTS_PREFIX}"
+ BASE
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ ${qmake_virtualkeyboard_xt9_custom_layouts_resource_files}
+)
+
+if (QT_FEATURE_vkb_lang_zh_TW AND NOT FEATURE_vkb_cerence_xt9_9key_layouts)
+ # Resources:
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/content/layouts/zh_HK/main.qml ${CMAKE_CURRENT_BINARY_DIR}/content/layouts/zh_TW/main.qml COPYONLY)
+ set(qmake_virtualkeyboard_xt9_cangjie_layouts_resource_files
+ "${CMAKE_CURRENT_BINARY_DIR}/content/layouts/zh_TW/main.qml"
+ )
+
+ qt_internal_add_resource(QtVirtualKeyboardXt9Plugin "qmake_virtualkeyboard_xt9_cangjie_layouts"
+ PREFIX
+ "${VKB_LAYOUTS_PREFIX}"
+ BASE
+ "${CMAKE_CURRENT_BINARY_DIR}"
+ FILES
+ ${qmake_virtualkeyboard_xt9_cangjie_layouts_resource_files}
+ )
+endif()
+
+if (FEATURE_vkb_cerence_xt9_9key_layouts)
+ if (QT_FEATURE_vkb_lang_zh_CN)
+ list(APPEND qmake_virtualkeyboard_xt9_9key_layouts_resource_files
+ "${CMAKE_CURRENT_SOURCE_DIR}/9key_layouts/content/layouts/zh_CN/main.qml"
+ )
+ endif()
+
+ if (QT_FEATURE_vkb_lang_zh_TW)
+ list(APPEND qmake_virtualkeyboard_xt9_9key_layouts_resource_files
+ "${CMAKE_CURRENT_SOURCE_DIR}/9key_layouts/content/layouts/zh_TW/main.qml"
+ )
+ endif()
+
+ if (QT_FEATURE_vkb_lang_ja_JP)
+ list(APPEND qmake_virtualkeyboard_xt9_9key_layouts_resource_files
+ "${CMAKE_CURRENT_SOURCE_DIR}/9key_layouts/content/layouts/ja_JP/main.qml"
+ )
+ endif()
+
+ qt_internal_add_resource(QtVirtualKeyboardXt9Plugin "qmake_virtualkeyboard_xt9_9key_layouts"
+ PREFIX
+ "${VKB_LAYOUTS_PREFIX}"
+ BASE
+ "${CMAKE_CURRENT_SOURCE_DIR}/9key_layouts"
+ FILES
+ ${qmake_virtualkeyboard_xt9_9key_layouts_resource_files}
+ )
+endif()
+
+#### Keys ignored in scope 40:.:.:plugin.pro:WIN32:
+# QMAKE_TARGET_DESCRIPTION = "Virtual Keyboard Extension for Qt."
+# QMAKE_TARGET_PRODUCT = "Qt Virtual Keyboard Cerence XT9 (Qt $$QT_VERSION)"
+
+#### Keys ignored in scope 42:.:../..:../../cerence.pri:CERENCE_SDK_ROOT_ISEMPTY:
+# EXT_CERENCE_SDK_ROOT = "$$(CERENCE_SDK_ROOT)"
+
+#### Keys ignored in scope 43:.:../..:../../cerence.pri:NOT EXT_CERENCE_SDK_ROOT_ISEMPTY:
+# CERENCE_SDK_ROOT = "$$EXT_CERENCE_SDK_ROOT"
+
+#### Keys ignored in scope 45:.:../..:../../cerence.pri:CERENCE_SDK_ROOT_ISEMPTY:
+# CERENCE_SDK_ROOT = "$$PWD/sdk"
+
+#### Keys ignored in scope 48:.:../..:../../cerence.pri:QT_ARCH___equals___arm:
+# CERENCE_SHARED_LIB_PATH = "lib/linux/arm/shared"
+# CERENCE_STATIC_LIB_PATH = "lib/linux/arm/static"
+
+#### Keys ignored in scope 50:.:../..:../../cerence.pri:QT_ARCH___equals___arm64:
+# CERENCE_SHARED_LIB_PATH = "lib/linux/arm64/shared"
+# CERENCE_STATIC_LIB_PATH = "lib/linux/arm64/static"
+
+#### Keys ignored in scope 52:.:../..:../../cerence.pri:QT_ARCH___equals___x86_64:
+# CERENCE_SHARED_LIB_PATH = "lib/linux/x86_64/shared"
+# CERENCE_STATIC_LIB_PATH = "lib/linux/x86_64/static"
+
+#### Keys ignored in scope 54:.:../..:../../cerence.pri:QT_ARCH___equals___x86 OR QT_ARCH___equals___i386:
+# CERENCE_SHARED_LIB_PATH = "lib/linux/x86/shared"
+# CERENCE_STATIC_LIB_PATH = "lib/linux/x86/static"
+
+#### Keys ignored in scope 57:.:../..:../../cerence.pri:QT_ARCH___equals___x86_64:
+# CERENCE_SHARED_LIB_PATH = "lib/win32/x86_64/shared"
+# CERENCE_STATIC_LIB_PATH = "lib/win32/x86_64/static"
+
+#### Keys ignored in scope 58:.:../..:../../cerence.pri:else:
+# CERENCE_SHARED_LIB_PATH = "lib/win32/x86/shared"
+# CERENCE_STATIC_LIB_PATH = "lib/win32/x86/static"
+
+#### Keys ignored in scope 60:.:../..:../../cerence.pri:WIN32:
+# result = "$$1/*.obj"
+
+#### Keys ignored in scope 61:.:../..:../../cerence.pri:result_ISEMPTY:
+# result = "$$1/*.lib"
+
+#### Keys ignored in scope 62:.:../..:../../cerence.pri:else:
+# result = "$$1/*.o"
+
+#### Keys ignored in scope 63:.:../..:../../cerence.pri:result_ISEMPTY:
+# result = "$$1/*.a"
+
+#### Keys ignored in scope 65:.:../..:../../cerence.pri:WIN32:
+# result = "$$1/*.lib"
+
+#### Keys ignored in scope 66:.:../..:../../cerence.pri:else:
+# result = "$$1/*.so"
+
+#### Keys ignored in scope 68:.:../..:../../cerence.pri:WIN32:
+# result = "$$1/*.dll"
+
+#### Keys ignored in scope 69:.:../..:../../cerence.pri:else:
+# result = "$$1/*.so"
+
+#### Keys ignored in scope 70:.:../..:../../cerence.pri:EXISTS _ss_CERENCE_HWR_INCLUDEPATH/decuma_hwr.h:
+# CERENCE_HWR_ALPHABETIC_FOUND = "1"
+
+#### Keys ignored in scope 71:.:../..:../../cerence.pri:EXISTS _ss_CERENCE_HWR_INCLUDEPATH/decuma_hwr_cjk.h:
+# CERENCE_HWR_CJK_FOUND = "1"
+
+#### Keys ignored in scope 74:.:../..:../../cerence.pri:NOT cerence-hwr-static:
+# CERENCE_HWR_ALPHABETIC_LIBS = "$$findSharedLibrary($$CERENCE_SDK_ROOT/t9write/$$CERENCE_SHARED_LIB_PATH/alphabetic)"
+
+#### Keys ignored in scope 75:.:../..:../../cerence.pri:NOT CERENCE_HWR_ALPHABETIC_LIBS_ISEMPTY:
+# CERENCE_HWR_ALPHABETIC_BINS = "$$findSharedBinary($$CERENCE_SDK_ROOT/t9write/$$CERENCE_SHARED_LIB_PATH/alphabetic)"
+
+#### Keys ignored in scope 76:.:../..:../../cerence.pri:else:
+# CERENCE_HWR_ALPHABETIC_LIBS = "$$findStaticLibrary($$CERENCE_SDK_ROOT/t9write/$$CERENCE_STATIC_LIB_PATH/alphabetic)"
+
+#### Keys ignored in scope 78:.:../..:../../cerence.pri:NOT cerence-hwr-static:
+# CERENCE_HWR_CJK_LIBS = "$$findSharedLibrary($$CERENCE_SDK_ROOT/t9write/$$CERENCE_SHARED_LIB_PATH/cjk)"
+
+#### Keys ignored in scope 79:.:../..:../../cerence.pri:NOT CERENCE_HWR_CJK_LIBS_ISEMPTY:
+# CERENCE_HWR_CJK_BINS = "$$findSharedBinary($$CERENCE_SDK_ROOT/t9write/$$CERENCE_SHARED_LIB_PATH/cjk)"
+
+#### Keys ignored in scope 80:.:../..:../../cerence.pri:else:
+# CERENCE_HWR_CJK_LIBS = "$$findStaticLibrary($$CERENCE_SDK_ROOT/t9write/$$CERENCE_STATIC_LIB_PATH/cjk)"
+
+#### Keys ignored in scope 81:.:../..:../../cerence.pri:(CERENCE_HWR_ALPHABETIC_FOUND EQUAL 1) AND NOT CERENCE_HWR_ALPHABETIC_LIBS_ISEMPTY:
+# CERENCE_HWR_FOUND = "1"
+
+#### Keys ignored in scope 82:.:../..:../../cerence.pri:(CERENCE_HWR_CJK_FOUND EQUAL 1) AND NOT CERENCE_HWR_CJK_LIBS_ISEMPTY:
+# CERENCE_HWR_FOUND = "1"
+
+#### Keys ignored in scope 83:.:../..:../../cerence.pri:EXISTS _ss_XT9_INCLUDEPATH/et9api.h:
+# XT9_FOUND = "1"
+
+#### Keys ignored in scope 85:.:../..:../../cerence.pri:NOT QT_FEATURE_xt9_static:
+# XT9_LIBS = "$$findSharedLibrary($$CERENCE_SDK_ROOT/xt9/$$CERENCE_SHARED_LIB_PATH)"
+
+#### Keys ignored in scope 86:.:../..:../../cerence.pri:NOT XT9_LIBS_ISEMPTY:
+# XT9_BINS = "$$findSharedBinary($$CERENCE_SDK_ROOT/xt9/$$CERENCE_SHARED_LIB_PATH)"
+
+#### Keys ignored in scope 87:.:../..:../../cerence.pri:else:
+# XT9_LIBS = "$$findStaticLibrary($$CERENCE_SDK_ROOT/xt9/$$CERENCE_STATIC_LIB_PATH)"
+
+#### Keys ignored in scope 133:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:MYSCRIPT_PATH_ISEMPTY:
+# MYSCRIPT_PATH = "$$PWD"
+
+#### Keys ignored in scope 134:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:UNIX AND LINUX AND NOT ANDROID:
+# MYSCRIPT_LIB_PREFIX = "lib"
+# MYSCRIPT_LIB_SUFFIX = ".so"
+# MYSCRIPT_VOIM_LIB_NAME = "libvoim.so"
+# MYSCRIPT_VOIM_LIB_PATH = "$$MYSCRIPT_PATH/$$MYSCRIPT_VOIM_PATH/$$MYSCRIPT_VOIM_LIB_NAME"
+
+#### Keys ignored in scope 135:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:QT_ARCH___equals___arm64:
+# MYSCRIPT_ENGINE_PATH = "engine/bin/lin-arm64"
+# MYSCRIPT_VOIM_PATH = "voim/bin/lin-arm64"
+
+#### Keys ignored in scope 137:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:QT_ARCH___equals___arm:
+# MYSCRIPT_ENGINE_PATH = "engine/bin/lin-armv7"
+# MYSCRIPT_VOIM_PATH = "voim/bin/lin-armv7"
+
+#### Keys ignored in scope 139:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:QT_ARCH___equals___x86_64:
+# MYSCRIPT_ENGINE_PATH = "engine/bin/lin-x64"
+# MYSCRIPT_VOIM_PATH = "voim/bin/lin-x64"
+
+#### Keys ignored in scope 141:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:QT_ARCH___equals___x86 OR QT_ARCH___equals___i386:
+# MYSCRIPT_ENGINE_PATH = "engine/bin/lin-x86"
+# MYSCRIPT_VOIM_PATH = "voim/bin/lin-x86"
+
+#### Keys ignored in scope 142:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:else:
+# MYSCRIPT_ENGINE_PATH = "engine/bin/lin-$$QT_ARCH"
+# MYSCRIPT_VOIM_PATH = "voim/bin/lin-$$QT_ARCH"
+
+#### Keys ignored in scope 144:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:WIN32 OR win64:
+# MYSCRIPT_LIB_PREFIX = ""
+# MYSCRIPT_LIB_SUFFIX = ".dll"
+# MYSCRIPT_VOIM_LIB_NAME = "voim.lib"
+# MYSCRIPT_VOIM_LIB_PATH = "$$MYSCRIPT_PATH/voim/api/c/lib/$$MYSCRIPT_VOIM_LIB_NAME"
+
+#### Keys ignored in scope 145:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:QT_ARCH___equals___x86_64:
+# MYSCRIPT_ENGINE_PATH = "engine/bin/win-x64"
+# MYSCRIPT_VOIM_PATH = "voim/bin/win-x64"
+
+#### Keys ignored in scope 146:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:else:
+# MYSCRIPT_ENGINE_PATH = "engine/bin/win-x86"
+# MYSCRIPT_VOIM_PATH = "voim/bin/win-x86"
+
+#### Keys ignored in scope 148:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:EXISTS _ss_MYSCRIPT_VOIM_LIB_PATH:
+# MYSCRIPT_FOUND = "1"
+
+#### Keys ignored in scope 150:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:MYSCRIPT_PATH_ISEMPTY:
+# MYSCRIPT_PATH = "$$PWD"
+
+#### Keys ignored in scope 151:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:UNIX AND LINUX AND NOT ANDROID:
+# MYSCRIPT_LIB_PREFIX = "lib"
+# MYSCRIPT_LIB_SUFFIX = ".so"
+# MYSCRIPT_VOIM_LIB_NAME = "libvoim.so"
+# MYSCRIPT_VOIM_LIB_PATH = "$$MYSCRIPT_PATH/$$MYSCRIPT_VOIM_PATH/$$MYSCRIPT_VOIM_LIB_NAME"
+
+#### Keys ignored in scope 152:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:QT_ARCH___equals___arm64:
+# MYSCRIPT_ENGINE_PATH = "engine/bin/lin-arm64"
+# MYSCRIPT_VOIM_PATH = "voim/bin/lin-arm64"
+
+#### Keys ignored in scope 154:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:QT_ARCH___equals___arm:
+# MYSCRIPT_ENGINE_PATH = "engine/bin/lin-armv7"
+# MYSCRIPT_VOIM_PATH = "voim/bin/lin-armv7"
+
+#### Keys ignored in scope 156:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:QT_ARCH___equals___x86_64:
+# MYSCRIPT_ENGINE_PATH = "engine/bin/lin-x64"
+# MYSCRIPT_VOIM_PATH = "voim/bin/lin-x64"
+
+#### Keys ignored in scope 158:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:QT_ARCH___equals___x86 OR QT_ARCH___equals___i386:
+# MYSCRIPT_ENGINE_PATH = "engine/bin/lin-x86"
+# MYSCRIPT_VOIM_PATH = "voim/bin/lin-x86"
+
+#### Keys ignored in scope 159:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:else:
+# MYSCRIPT_ENGINE_PATH = "engine/bin/lin-$$QT_ARCH"
+# MYSCRIPT_VOIM_PATH = "voim/bin/lin-$$QT_ARCH"
+
+#### Keys ignored in scope 161:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:WIN32 OR win64:
+# MYSCRIPT_LIB_PREFIX = ""
+# MYSCRIPT_LIB_SUFFIX = ".dll"
+# MYSCRIPT_VOIM_LIB_NAME = "voim.lib"
+# MYSCRIPT_VOIM_LIB_PATH = "$$MYSCRIPT_PATH/voim/api/c/lib/$$MYSCRIPT_VOIM_LIB_NAME"
+
+#### Keys ignored in scope 162:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:QT_ARCH___equals___x86_64:
+# MYSCRIPT_ENGINE_PATH = "engine/bin/win-x64"
+# MYSCRIPT_VOIM_PATH = "voim/bin/win-x64"
+
+#### Keys ignored in scope 163:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:else:
+# MYSCRIPT_ENGINE_PATH = "engine/bin/win-x86"
+# MYSCRIPT_VOIM_PATH = "voim/bin/win-x86"
+
+#### Keys ignored in scope 165:.:../../../../plugins/myscript/3rdparty/myscript:../../../../plugins/myscript/3rdparty/myscript/myscript.pri:EXISTS _ss_MYSCRIPT_VOIM_LIB_PATH:
+# MYSCRIPT_FOUND = "1"
diff --git a/src/plugins/cerence/xt9/plugin/cerence_xt9.json b/src/plugins/cerence/xt9/plugin/cerence_xt9.json
new file mode 100644
index 00000000..6eb368ed
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/cerence_xt9.json
@@ -0,0 +1,12 @@
+{
+ "Name": "xt9",
+ "Provider": "Qt Cerence XT9 Extension",
+ "InputMethod": [
+ "DefaultInputMethod",
+ "PinyinInputMethod",
+ "StrokeInputMethod",
+ "HangulInputMethod",
+ "JapaneseInputMethod"
+ ],
+ "Version": 200
+}
diff --git a/src/plugins/cerence/xt9/plugin/content/layouts/ja_JP/main.qml b/src/plugins/cerence/xt9/plugin/content/layouts/ja_JP/main.qml
new file mode 100644
index 00000000..810ff82a
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/content/layouts/ja_JP/main.qml
@@ -0,0 +1,920 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick
+import QtQuick.Layouts
+import QtQuick.VirtualKeyboard
+
+KeyboardLayoutLoader {
+ function createInputMethod() {
+ return Qt.createQmlObject('import QtQuick; import QtQuick.VirtualKeyboard.Plugins; JapaneseInputMethod {}', parent, "main.qml")
+ }
+ sourceComponent: {
+ switch (InputContext.inputEngine.inputMode) {
+ case InputEngine.Katakana:
+ return katakana
+ case InputEngine.Hiragana:
+ return hiragana
+ case InputEngine.FullwidthLatin:
+ return fullWidthQwerty
+ default:
+ return qwerty
+ }
+ }
+ Component {
+ id: hiragana
+ KeyboardLayout {
+ keyWeight: 160
+ readonly property real normalKeyWidth: normalKey.width
+ readonly property real functionKeyWidth: mapFromItem(normalKey, normalKey.width / 2, 0).x
+ KeyboardRow {
+ Layout.preferredHeight: 3
+ KeyboardColumn {
+ KeyboardRow {
+ smallTextVisible: true
+ Key {
+ text: "\u306C"
+ }
+ Key {
+ id: normalKey
+ text: "\u3075"
+ }
+ Key {
+ text: "\u3042"
+ alternativeKeys: "\u3042\u3041"
+ }
+ Key {
+ text: "\u3046"
+ alternativeKeys: "\u3046\u3045"
+ }
+ Key {
+ text: "\u3048"
+ alternativeKeys: "\u3048\u3047"
+ }
+ Key {
+ text: "\u304A"
+ alternativeKeys: "\u304A\u3049"
+ }
+ Key {
+ text: "\u3084"
+ alternativeKeys: "\u3084\u3083"
+ }
+ Key {
+ text: "\u3086"
+ alternativeKeys: "\u3086\u3085"
+ }
+ Key {
+ text: "\u3088"
+ alternativeKeys: "\u3088\u3087"
+ }
+ Key {
+ text: "\u308F"
+ alternativeKeys: "\u308F\u3092"
+ }
+ Key {
+ text: "\u307B"
+ }
+ Key {
+ text: "\u3078"
+ }
+ }
+ KeyboardRow {
+ smallTextVisible: true
+ Key {
+ text: "\u305F"
+ }
+ Key {
+ text: "\u3066"
+ }
+ Key {
+ text: "\u3044"
+ alternativeKeys: "\u3044\u3043"
+ }
+ Key {
+ text: "\u3059"
+ }
+ Key {
+ text: "\u304B"
+ }
+ Key {
+ text: "\u3093"
+ }
+ Key {
+ text: "\u306A"
+ }
+ Key {
+ text: "\u306B"
+ }
+ Key {
+ text: "\u3089"
+ }
+ Key {
+ text: "\u305B"
+ }
+ Key {
+ text: "\u3099"
+ }
+ Key {
+ text: "\u309A"
+ }
+ }
+ KeyboardRow {
+ Key {
+ text: "\u3061"
+ }
+ Key {
+ text: "\u3068"
+ }
+ Key {
+ text: "\u3057"
+ }
+ Key {
+ text: "\u306F"
+ }
+ Key {
+ text: "\u304D"
+ }
+ Key {
+ text: "\u304F"
+ }
+ Key {
+ text: "\u307E"
+ }
+ Key {
+ text: "\u306E"
+ }
+ Key {
+ text: "\u308A"
+ }
+ Key {
+ text: "\u308C"
+ }
+ Key {
+ text: "\u3051"
+ }
+ Key {
+ text: "\u3080"
+ }
+ }
+ KeyboardRow {
+ smallTextVisible: true
+ KeyboardRow {
+ Layout.preferredWidth: functionKeyWidth
+ Layout.fillWidth: false
+ FillerKey {
+ }
+ Key {
+ text: "\u3064"
+ alternativeKeys: "\u3064\u3063"
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ }
+ }
+ Key {
+ text: "\u3055"
+ }
+ Key {
+ text: "\u305D"
+ }
+ Key {
+ text: "\u3072"
+ }
+ Key {
+ text: "\u3053"
+ }
+ Key {
+ text: "\u307F"
+ }
+ Key {
+ text: "\u3082"
+ }
+ Key {
+ text: "\u306D"
+ }
+ Key {
+ text: "\u308B"
+ }
+ Key {
+ text: "\u3081"
+ }
+ KeyboardRow {
+ Layout.preferredWidth: functionKeyWidth
+ Layout.fillWidth: false
+ Key {
+ text: "\u308D"
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ }
+ FillerKey {
+ }
+ }
+ }
+ }
+ }
+ KeyboardRow {
+ SymbolModeKey {
+ weight: functionKeyWidth
+ Layout.fillWidth: false
+ }
+ Key {
+ key: Qt.Key_Comma
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ text: "\u3001"
+ smallText: "\u2699"
+ smallTextVisible: true
+ highlighted: true
+ }
+ InputModeKey {
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ enabled: !(InputContext.inputMethodHints & Qt.ImhLatinOnly) && inputModeCount > 1
+ inputModeNameList: [
+ "半角", // InputEngine.InputMode.Latin
+ "", // InputEngine.InputMode.Numeric
+ "", // InputEngine.InputMode.Dialable
+ "", // InputEngine.InputMode.Pinyin
+ "", // InputEngine.InputMode.Cangjie
+ "", // InputEngine.InputMode.Zhuyin
+ "", // InputEngine.InputMode.Hangul
+ "あ", // InputEngine.InputMode.Hiragana
+ "カ", // InputEngine.InputMode.Katakana
+ "全角", // InputEngine.InputMode.FullwidthLatin
+ ]
+ }
+ SpaceKey {
+ }
+ Key {
+ key: Qt.Key_Period
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ text: "\u3002"
+ alternativeKeys: "\u3001\uFF01\u3002\uFF1F,.?!"
+ smallText: "!?"
+ smallTextVisible: true
+ highlighted: true
+ }
+ BackspaceKey {
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ }
+ EnterKey {
+ weight: functionKeyWidth
+ Layout.fillWidth: false
+ }
+ }
+ }
+ }
+ Component {
+ id: katakana
+ KeyboardLayout {
+ keyWeight: 160
+ readonly property real normalKeyWidth: normalKey.width
+ readonly property real functionKeyWidth: mapFromItem(normalKey, normalKey.width / 2, 0).x
+ KeyboardRow {
+ Layout.preferredHeight: 3
+ KeyboardColumn {
+ KeyboardRow {
+ smallTextVisible: true
+ Key {
+ text: "\u30CC"
+ }
+ Key {
+ id: normalKey
+ text: "\u30D5"
+ }
+ Key {
+ text: "\u30A2"
+ alternativeKeys: "\u30A2\u30A1"
+ }
+ Key {
+ text: "\u30A6"
+ alternativeKeys: "\u30A6\u30A5"
+ }
+ Key {
+ text: "\u30A8"
+ alternativeKeys: "\u30A8\u30A7"
+ }
+ Key {
+ text: "\u30AA"
+ alternativeKeys: "\u30AA\u30A9"
+ }
+ Key {
+ text: "\u30E4"
+ alternativeKeys: "\u30E4\u30E3"
+ }
+ Key {
+ text: "\u30E6"
+ alternativeKeys: "\u30E6\u30E5"
+ }
+ Key {
+ text: "\u30E8"
+ alternativeKeys: "\u30E8\u30E7"
+ }
+ Key {
+ text: "\u30EF"
+ alternativeKeys: "\u30EF\u30F2"
+ }
+ Key {
+ text: "\u30DB"
+ }
+ Key {
+ text: "\u30D8"
+ }
+ }
+ KeyboardRow {
+ smallTextVisible: true
+ Key {
+ text: "\u30BF"
+ }
+ Key {
+ text: "\u30C6"
+ }
+ Key {
+ text: "\u30A4"
+ alternativeKeys: "\u30A4\u30A3"
+ }
+ Key {
+ text: "\u30B9"
+ }
+ Key {
+ text: "\u30AB"
+ }
+ Key {
+ text: "\u30F3"
+ }
+ Key {
+ text: "\u30CA"
+ }
+ Key {
+ text: "\u30CB"
+ }
+ Key {
+ text: "\u30E9"
+ }
+ Key {
+ text: "\u30BB"
+ }
+ Key {
+ text: "\u3099"
+ }
+ Key {
+ text: "\u309A"
+ }
+ }
+ KeyboardRow {
+ Key {
+ text: "\u30C1"
+ }
+ Key {
+ text: "\u30C8"
+ }
+ Key {
+ text: "\u30B7"
+ }
+ Key {
+ text: "\u30CF"
+ }
+ Key {
+ text: "\u30AD"
+ }
+ Key {
+ text: "\u30AF"
+ }
+ Key {
+ text: "\u30DE"
+ }
+ Key {
+ text: "\u30CE"
+ }
+ Key {
+ text: "\u30EA"
+ }
+ Key {
+ text: "\u30EC"
+ }
+ Key {
+ text: "\u30B1"
+ }
+ Key {
+ text: "\u30E0"
+ }
+ }
+ KeyboardRow {
+ smallTextVisible: true
+ KeyboardRow {
+ Layout.preferredWidth: functionKeyWidth
+ Layout.fillWidth: false
+ FillerKey {
+ }
+ Key {
+ text: "\u30C4"
+ alternativeKeys: "\u30C4\u30C3"
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ }
+ }
+ Key {
+ text: "\u30B5"
+ }
+ Key {
+ text: "\u30BD"
+ }
+ Key {
+ text: "\u30D2"
+ }
+ Key {
+ text: "\u30B3"
+ }
+ Key {
+ text: "\u30DF"
+ }
+ Key {
+ text: "\u30E2"
+ }
+ Key {
+ text: "\u30CD"
+ }
+ Key {
+ text: "\u30EB"
+ }
+ Key {
+ text: "\u30E1"
+ }
+ KeyboardRow {
+ Layout.preferredWidth: functionKeyWidth
+ Layout.fillWidth: false
+ Key {
+ text: "\u30ED"
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ }
+ FillerKey {
+ }
+ }
+ }
+ }
+ }
+ KeyboardRow {
+ SymbolModeKey {
+ weight: functionKeyWidth
+ Layout.fillWidth: false
+ }
+ Key {
+ key: Qt.Key_Comma
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ text: "\u3001"
+ smallText: "\u2699"
+ smallTextVisible: true
+ highlighted: true
+ }
+ InputModeKey {
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ enabled: !(InputContext.inputMethodHints & Qt.ImhLatinOnly) && inputModeCount > 1
+ inputModeNameList: [
+ "半角", // InputEngine.InputMode.Latin
+ "", // InputEngine.InputMode.Numeric
+ "", // InputEngine.InputMode.Dialable
+ "", // InputEngine.InputMode.Pinyin
+ "", // InputEngine.InputMode.Cangjie
+ "", // InputEngine.InputMode.Zhuyin
+ "", // InputEngine.InputMode.Hangul
+ "あ", // InputEngine.InputMode.Hiragana
+ "カ", // InputEngine.InputMode.Katakana
+ "全角", // InputEngine.InputMode.FullwidthLatin
+ ]
+ }
+ SpaceKey {
+ }
+ Key {
+ key: Qt.Key_Period
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ text: "\u3002"
+ alternativeKeys: "\u3001\uFF01\u3002\uFF1F,.?!"
+ smallText: "!?"
+ smallTextVisible: true
+ highlighted: true
+ }
+ BackspaceKey {
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ }
+ EnterKey {
+ weight: functionKeyWidth
+ Layout.fillWidth: false
+ }
+ }
+ }
+ }
+ Component {
+ id: qwerty
+ KeyboardLayout {
+ keyWeight: 160
+ readonly property real normalKeyWidth: normalKey.width
+ readonly property real functionKeyWidth: mapFromItem(normalKey, normalKey.width / 2, 0).x
+ KeyboardRow {
+ Key {
+ key: Qt.Key_Q
+ text: "q"
+ }
+ Key {
+ id: normalKey
+ key: Qt.Key_W
+ text: "w"
+ }
+ Key {
+ key: Qt.Key_E
+ text: "e"
+ }
+ Key {
+ key: Qt.Key_R
+ text: "r"
+ }
+ Key {
+ key: Qt.Key_T
+ text: "t"
+ }
+ Key {
+ key: Qt.Key_Y
+ text: "y"
+ }
+ Key {
+ key: Qt.Key_U
+ text: "u"
+ }
+ Key {
+ key: Qt.Key_I
+ text: "i"
+ }
+ Key {
+ key: Qt.Key_O
+ text: "o"
+ }
+ Key {
+ key: Qt.Key_P
+ text: "p"
+ }
+ }
+ KeyboardRow {
+ KeyboardRow {
+ Layout.preferredWidth: functionKeyWidth
+ Layout.fillWidth: false
+ FillerKey {
+ }
+ Key {
+ key: Qt.Key_A
+ text: "a"
+ Layout.preferredWidth: normalKeyWidth
+ Layout.fillWidth: false
+ }
+ }
+ Key {
+ key: Qt.Key_S
+ text: "s"
+ }
+ Key {
+ key: Qt.Key_D
+ text: "d"
+ }
+ Key {
+ key: Qt.Key_F
+ text: "f"
+ }
+ Key {
+ key: Qt.Key_G
+ text: "g"
+ }
+ Key {
+ key: Qt.Key_H
+ text: "h"
+ }
+ Key {
+ key: Qt.Key_J
+ text: "j"
+ }
+ Key {
+ key: Qt.Key_K
+ text: "k"
+ }
+ KeyboardRow {
+ Layout.preferredWidth: functionKeyWidth
+ Layout.fillWidth: false
+ Key {
+ key: Qt.Key_L
+ text: "l"
+ Layout.preferredWidth: normalKeyWidth
+ Layout.fillWidth: false
+ }
+ FillerKey {
+ }
+ }
+ }
+ KeyboardRow {
+ ShiftKey {
+ Layout.preferredWidth: functionKeyWidth
+ Layout.fillWidth: false
+ }
+ Key {
+ key: Qt.Key_Z
+ text: "z"
+ }
+ Key {
+ key: Qt.Key_X
+ text: "x"
+ }
+ Key {
+ key: Qt.Key_C
+ text: "c"
+ }
+ Key {
+ key: Qt.Key_V
+ text: "v"
+ }
+ Key {
+ key: Qt.Key_B
+ text: "b"
+ }
+ Key {
+ key: Qt.Key_N
+ text: "n"
+ }
+ Key {
+ key: Qt.Key_M
+ text: "m"
+ }
+ BackspaceKey {
+ Layout.preferredWidth: functionKeyWidth
+ Layout.fillWidth: false
+ }
+ }
+ KeyboardRow {
+ SymbolModeKey {
+ Layout.preferredWidth: functionKeyWidth
+ Layout.fillWidth: false
+ }
+ Key {
+ key: Qt.Key_Comma
+ Layout.preferredWidth: normalKeyWidth
+ Layout.fillWidth: false
+ text: "\u3001"
+ smallText: "\u2699"
+ smallTextVisible: true
+ highlighted: true
+ }
+ InputModeKey {
+ enabled: !(InputContext.inputMethodHints & Qt.ImhLatinOnly) && inputModeCount > 1
+ Layout.preferredWidth: normalKeyWidth
+ Layout.fillWidth: false
+ inputModeNameList: [
+ "半角", // InputEngine.InputMode.Latin
+ "", // InputEngine.InputMode.Numeric
+ "", // InputEngine.InputMode.Dialable
+ "", // InputEngine.InputMode.Pinyin
+ "", // InputEngine.InputMode.Cangjie
+ "", // InputEngine.InputMode.Zhuyin
+ "", // InputEngine.InputMode.Hangul
+ "あ", // InputEngine.InputMode.Hiragana
+ "カ", // InputEngine.InputMode.Katakana
+ "全角", // InputEngine.InputMode.FullwidthLatin
+ ]
+ }
+ SpaceKey {
+ }
+ Key {
+ key: Qt.Key_Period
+ Layout.preferredWidth: normalKeyWidth
+ Layout.fillWidth: false
+ text: "\u3002"
+ alternativeKeys: "\u3001\uFF01\u3002\uFF1F,.?!"
+ smallText: "!?"
+ smallTextVisible: true
+ highlighted: true
+ }
+ EnterKey {
+ Layout.preferredWidth: functionKeyWidth
+ Layout.fillWidth: false
+ }
+ }
+ }
+ }
+ Component {
+ id: fullWidthQwerty
+ KeyboardLayout {
+ keyWeight: 160
+ readonly property real normalKeyWidth: normalKey.width
+ readonly property real functionKeyWidth: mapFromItem(normalKey, normalKey.width / 2, 0).x
+ KeyboardRow {
+ Key {
+ key: Qt.Key_Q
+ text: "\uFF51"
+ }
+ Key {
+ id: normalKey
+ key: Qt.Key_W
+ text: "\uFF57"
+ }
+ Key {
+ key: Qt.Key_E
+ text: "\uFF45"
+ }
+ Key {
+ key: Qt.Key_R
+ text: "\uFF52"
+ }
+ Key {
+ key: Qt.Key_T
+ text: "\uFF54"
+ }
+ Key {
+ key: Qt.Key_Y
+ text: "\uFF59"
+ }
+ Key {
+ key: Qt.Key_U
+ text: "\uFF55"
+ }
+ Key {
+ key: Qt.Key_I
+ text: "\uFF49"
+ }
+ Key {
+ key: Qt.Key_O
+ text: "\uFF4F"
+ }
+ Key {
+ key: Qt.Key_P
+ text: "\uFF50"
+ }
+ }
+ KeyboardRow {
+ KeyboardRow {
+ Layout.preferredWidth: functionKeyWidth
+ Layout.fillWidth: false
+ FillerKey {
+ }
+ Key {
+ key: Qt.Key_A
+ text: "\uFF41"
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ }
+ }
+ Key {
+ key: Qt.Key_S
+ text: "\uFF53"
+ }
+ Key {
+ key: Qt.Key_D
+ text: "\uFF44"
+ }
+ Key {
+ key: Qt.Key_F
+ text: "\uFF46"
+ }
+ Key {
+ key: Qt.Key_G
+ text: "\uFF47"
+ }
+ Key {
+ key: Qt.Key_H
+ text: "\uFF48"
+ }
+ Key {
+ key: Qt.Key_J
+ text: "\uFF4A"
+ }
+ Key {
+ key: Qt.Key_K
+ text: "\uFF4B"
+ }
+ KeyboardRow {
+ Layout.preferredWidth: functionKeyWidth
+ Layout.fillWidth: false
+ Key {
+ key: Qt.Key_L
+ text: "\uFF4C"
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ }
+ FillerKey {
+ }
+ }
+ }
+ KeyboardRow {
+ ShiftKey {
+ weight: functionKeyWidth
+ Layout.fillWidth: false
+ }
+ Key {
+ key: Qt.Key_Z
+ text: "\uFF5A"
+ }
+ Key {
+ key: Qt.Key_X
+ text: "\uFF58"
+ }
+ Key {
+ key: Qt.Key_C
+ text: "\uFF43"
+ }
+ Key {
+ key: Qt.Key_V
+ text: "\uFF56"
+ }
+ Key {
+ key: Qt.Key_B
+ text: "\uFF42"
+ }
+ Key {
+ key: Qt.Key_N
+ text: "\uFF4E"
+ }
+ Key {
+ key: Qt.Key_M
+ text: "\uFF4D"
+ }
+ BackspaceKey {
+ weight: functionKeyWidth
+ Layout.fillWidth: false
+ }
+ }
+ KeyboardRow {
+ SymbolModeKey {
+ weight: functionKeyWidth
+ Layout.fillWidth: false
+ }
+ Key {
+ key: Qt.Key_Comma
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ text: "\u3001"
+ smallText: "\u2699"
+ smallTextVisible: true
+ highlighted: true
+ }
+ InputModeKey {
+ enabled: !(InputContext.inputMethodHints & Qt.ImhLatinOnly) && inputModeCount > 1
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ inputModeNameList: [
+ "半角", // InputEngine.InputMode.Latin
+ "", // InputEngine.InputMode.Numeric
+ "", // InputEngine.InputMode.Dialable
+ "", // InputEngine.InputMode.Pinyin
+ "", // InputEngine.InputMode.Cangjie
+ "", // InputEngine.InputMode.Zhuyin
+ "", // InputEngine.InputMode.Hangul
+ "あ", // InputEngine.InputMode.Hiragana
+ "カ", // InputEngine.InputMode.Katakana
+ "全角", // InputEngine.InputMode.FullwidthLatin
+ ]
+ }
+ SpaceKey {
+ }
+ Key {
+ key: Qt.Key_Period
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ text: "\u3002"
+ alternativeKeys: "\u3001\uFF01\u3002\uFF1F,.?!"
+ smallText: "!?"
+ smallTextVisible: true
+ highlighted: true
+ }
+ EnterKey {
+ weight: functionKeyWidth
+ Layout.fillWidth: false
+ }
+ }
+ }
+ }
+}
diff --git a/src/plugins/cerence/xt9/plugin/content/layouts/zh_HK/dialpad.fallback b/src/plugins/cerence/xt9/plugin/content/layouts/zh_HK/dialpad.fallback
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/content/layouts/zh_HK/dialpad.fallback
diff --git a/src/plugins/cerence/xt9/plugin/content/layouts/zh_HK/digits.fallback b/src/plugins/cerence/xt9/plugin/content/layouts/zh_HK/digits.fallback
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/content/layouts/zh_HK/digits.fallback
diff --git a/src/plugins/cerence/xt9/plugin/content/layouts/zh_HK/main.qml b/src/plugins/cerence/xt9/plugin/content/layouts/zh_HK/main.qml
new file mode 100644
index 00000000..46a320d0
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/content/layouts/zh_HK/main.qml
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick
+import QtQuick.Layouts
+import QtQuick.VirtualKeyboard
+
+KeyboardLayout {
+ keyWeight: 160
+ readonly property real normalKeyWidth: normalKey.width
+ readonly property real functionKeyWidth: mapFromItem(normalKey, normalKey.width / 2, 0).x
+ function createInputMethod() {
+ return Qt.createQmlObject('import QtQuick; import QtQuick.VirtualKeyboard.Plugins; CangjieInputMethod {}', parent, "main.qml")
+ }
+ sharedLayouts: ['symbols']
+ smallTextVisible: true
+ inputMode: InputEngine.InputMode.Cangjie
+ KeyboardRow {
+ Key {
+ text: "\u624B"
+ }
+ Key {
+ id: normalKey
+ text: "\u7530"
+ }
+ Key {
+ text: "\u6C34"
+ }
+ Key {
+ text: "\u53E3"
+ }
+ Key {
+ text: "\u5EFF"
+ }
+ Key {
+ text: "\u535C"
+ }
+ Key {
+ text: "\u5C71"
+ }
+ Key {
+ text: "\u6208"
+ }
+ Key {
+ text: "\u4EBA"
+ }
+ Key {
+ text: "\u5FC3"
+ }
+ }
+ KeyboardRow {
+ KeyboardRow {
+ Layout.preferredWidth: functionKeyWidth
+ Layout.fillWidth: false
+ FillerKey {
+ }
+ Key {
+ text: "\u65E5"
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ }
+ }
+ Key {
+ text: "\u5C38"
+ }
+ Key {
+ text: "\u6728"
+ }
+ Key {
+ text: "\u706B"
+ }
+ Key {
+ text: "\u571F"
+ }
+ Key {
+ text: "\u7AF9"
+ }
+ Key {
+ text: "\u5341"
+ }
+ Key {
+ text: "\u5927"
+ }
+ KeyboardRow {
+ Layout.preferredWidth: functionKeyWidth
+ Layout.fillWidth: false
+ Key {
+ text: "\u4E2D"
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ }
+ FillerKey {
+ }
+ }
+ }
+ KeyboardRow {
+ ShiftKey {
+ weight: functionKeyWidth
+ Layout.fillWidth: false
+ }
+ Key {
+ text: "\u91CD"
+ }
+ Key {
+ text: "\u96E3"
+ }
+ Key {
+ text: "\u91D1"
+ }
+ Key {
+ text: "\u5973"
+ }
+ Key {
+ text: "\u6708"
+ }
+ Key {
+ text: "\u5F13"
+ }
+ Key {
+ text: "\u4E00"
+ }
+ BackspaceKey {
+ weight: functionKeyWidth
+ Layout.fillWidth: false
+ }
+ }
+ KeyboardRow {
+ SymbolModeKey {
+ weight: functionKeyWidth
+ Layout.fillWidth: false
+ }
+ Key {
+ key: Qt.Key_Comma
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ text: "\uFF0C"
+ smallText: "\u2699"
+ smallTextVisible: true
+ highlighted: true
+ }
+ InputModeKey {
+ visible: InputContext.inputEngine.inputModes.indexOf(InputEngine.InputMode.Zhuyin) !== -1
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ }
+ SpaceKey {
+ }
+ Key {
+ key: Qt.Key_Period
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ text: "\uFF0E"
+ alternativeKeys: "\uFF1B\u3001\uFF0E\uFF1A\u3002?!"
+ smallText: "!?"
+ smallTextVisible: true
+ highlighted: true
+ }
+ EnterKey {
+ weight: functionKeyWidth
+ Layout.fillWidth: false
+ }
+ }
+}
diff --git a/src/plugins/cerence/xt9/plugin/content/layouts/zh_HK/numbers.fallback b/src/plugins/cerence/xt9/plugin/content/layouts/zh_HK/numbers.fallback
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/content/layouts/zh_HK/numbers.fallback
diff --git a/src/plugins/cerence/xt9/plugin/content/layouts/zh_HK/symbols.qml b/src/plugins/cerence/xt9/plugin/content/layouts/zh_HK/symbols.qml
new file mode 100644
index 00000000..4243e783
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/content/layouts/zh_HK/symbols.qml
@@ -0,0 +1,477 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick
+import QtQuick.Layouts
+import QtQuick.VirtualKeyboard
+
+KeyboardLayoutLoader {
+ function createInputMethod() {
+ return Qt.createQmlObject('import QtQuick; import QtQuick.VirtualKeyboard.Plugins; CangjieInputMethod {}', parent, "symbols.qml")
+ }
+ sharedLayouts: ['main']
+ property int page
+ readonly property int numPages: 3
+ sourceComponent: {
+ switch (page) {
+ case 2: return page3
+ case 1: return page2
+ default: return page1
+ }
+ }
+ Component {
+ id: page1
+ KeyboardLayout {
+ keyWeight: 160
+ readonly property real normalKeyWidth: normalKey.width
+ readonly property real functionKeyWidth: mapFromItem(normalKey, normalKey.width / 2, 0).x
+ KeyboardRow {
+ Key {
+ key: Qt.Key_1
+ text: "1"
+ }
+ Key {
+ id: normalKey
+ key: Qt.Key_2
+ text: "2"
+ }
+ Key {
+ key: Qt.Key_3
+ text: "3"
+ }
+ Key {
+ key: Qt.Key_4
+ text: "4"
+ }
+ Key {
+ key: Qt.Key_5
+ text: "5"
+ }
+ Key {
+ key: Qt.Key_6
+ text: "6"
+ }
+ Key {
+ key: Qt.Key_7
+ text: "7"
+ }
+ Key {
+ key: Qt.Key_8
+ text: "8"
+ }
+ Key {
+ key: Qt.Key_9
+ text: "9"
+ }
+ Key {
+ key: Qt.Key_0
+ text: "0"
+ }
+ }
+ KeyboardRow {
+ Key {
+ key: Qt.Key_1
+ text: "@"
+ }
+ Key {
+ key: Qt.Key_1
+ text: "#"
+ }
+ Key {
+ key: Qt.Key_1
+ text: "%"
+ }
+ Key {
+ key: Qt.Key_1
+ text: "&"
+ }
+ Key {
+ key: Qt.Key_1
+ text: "*"
+ }
+ Key {
+ key: Qt.Key_1
+ text: "_"
+ }
+ Key {
+ key: Qt.Key_1
+ text: "-"
+ }
+ Key {
+ key: Qt.Key_1
+ text: "+"
+ }
+ Key {
+ key: Qt.Key_1
+ text: "("
+ }
+ Key {
+ key: Qt.Key_1
+ text: ")"
+ }
+ }
+ KeyboardRow {
+ Key {
+ displayText: (page + 1) + "/" + numPages
+ functionKey: true
+ onClicked: page = (page + 1) % numPages
+ highlighted: true
+ }
+ Key {
+ text: "“"
+ }
+ Key {
+ text: "”"
+ }
+ Key {
+ text: "、"
+ }
+ Key {
+ text: ":"
+ }
+ Key {
+ text: ";"
+ }
+ Key {
+ text: "!"
+ }
+ Key {
+ text: "?"
+ }
+ Key {
+ text: "~"
+ }
+ BackspaceKey {
+ }
+ }
+ KeyboardRow {
+ SymbolModeKey {
+ weight: functionKeyWidth
+ Layout.fillWidth: false
+ displayText: "ABC"
+ }
+ Key {
+ key: Qt.Key_Comma
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ text: ","
+ smallText: "\u2699"
+ smallTextVisible: true
+ highlighted: true
+ }
+ SpaceKey {
+ }
+ Key {
+ key: Qt.Key_Period
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ text: "—"
+ highlighted: true
+ }
+ EnterKey {
+ weight: functionKeyWidth
+ Layout.fillWidth: false
+ }
+ }
+ }
+ }
+ Component {
+ id: page2
+ KeyboardLayout {
+ keyWeight: 160
+ readonly property real normalKeyWidth: normalKey.width
+ readonly property real functionKeyWidth: mapFromItem(normalKey, normalKey.width / 2, 0).x
+ KeyboardRow {
+ Key {
+ text: "½"
+ alternativeKeys: "½¼¾"
+ }
+ Key {
+ id: normalKey
+ text: "'"
+ }
+ Key {
+ text: "/"
+ }
+ Key {
+ text: "\\"
+ }
+ Key {
+ text: "|"
+ }
+ Key {
+ text: "["
+ }
+ Key {
+ text: "]"
+ }
+ Key {
+ text: "{"
+ }
+ Key {
+ text: "}"
+ }
+ Key {
+ text: "·"
+ }
+ }
+ KeyboardRow {
+ Key {
+ text: "<"
+ }
+ Key {
+ text: ">"
+ }
+ Key {
+ text: ","
+ }
+ Key {
+ text: "."
+ }
+ Key {
+ text: ":"
+ }
+ Key {
+ text: ";"
+ }
+ Key {
+ text: "!"
+ }
+ Key {
+ text: "?"
+ }
+ Key {
+ text: "="
+ }
+ Key {
+ text: "~"
+ }
+ }
+ KeyboardRow {
+ Key {
+ displayText: (page + 1) + "/" + numPages
+ functionKey: true
+ onClicked: page = (page + 1) % numPages
+ highlighted: true
+ }
+ Key {
+ text: "\""
+ }
+ Key {
+ text: "§"
+ }
+ Key {
+ text: "^"
+ }
+ Key {
+ text: "$"
+ }
+ Key {
+ text: "¥"
+ }
+ Key {
+ text: "€"
+ }
+ Key {
+ text: "£"
+ }
+ Key {
+ text: "¢"
+ }
+ BackspaceKey {
+ }
+ }
+ KeyboardRow {
+ SymbolModeKey {
+ weight: functionKeyWidth
+ Layout.fillWidth: false
+ displayText: "ABC"
+ }
+ Key {
+ key: Qt.Key_Comma
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ text: ","
+ smallText: "\u2699"
+ smallTextVisible: true
+ highlighted: true
+ }
+ SpaceKey {
+ }
+ Key {
+ key: Qt.Key_Period
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ text: "。"
+ highlighted: true
+ }
+ EnterKey {
+ weight: functionKeyWidth
+ Layout.fillWidth: false
+ }
+ }
+ }
+ }
+ Component {
+ id: page3
+ KeyboardLayout {
+ keyWeight: 160
+ readonly property real normalKeyWidth: normalKey.width
+ readonly property real functionKeyWidth: mapFromItem(normalKey, normalKey.width / 2, 0).x
+ KeyboardRow {
+ Key {
+ text: "\"
+ }
+ Key {
+ id: normalKey
+ text: "/"
+ }
+ Key {
+ text: "("
+ }
+ Key {
+ text: ")"
+ }
+ Key {
+ text: "〔"
+ }
+ Key {
+ text: "〕"
+ }
+ Key {
+ text: "〈"
+ }
+ Key {
+ text: "〉"
+ }
+ Key {
+ text: "《"
+ }
+ Key {
+ text: "》"
+ }
+ }
+ KeyboardRow {
+ Key {
+ text: "→"
+ }
+ Key {
+ text: "←"
+ }
+ Key {
+ text: "↑"
+ }
+ Key {
+ text: "↓"
+ }
+ Key {
+ text: "■"
+ }
+ Key {
+ text: "□"
+ }
+ Key {
+ text: "●"
+ }
+ Key {
+ text: "○"
+ }
+ Key {
+ text: "【"
+ }
+ Key {
+ text: "】"
+ }
+ }
+ KeyboardRow {
+ Key {
+ displayText: (page + 1) + "/" + numPages
+ functionKey: true
+ onClicked: page = (page + 1) % numPages
+ highlighted: true
+ }
+ Key {
+ text: "『"
+ }
+ Key {
+ text: "』"
+ }
+ Key {
+ text: "「"
+ }
+ Key {
+ text: "」"
+ }
+ Key {
+ text: "★"
+ }
+ Key {
+ text: "☆"
+ }
+ Key {
+ text: "◆"
+ }
+ Key {
+ text: "◇"
+ }
+ BackspaceKey {
+ }
+ }
+ KeyboardRow {
+ SymbolModeKey {
+ weight: functionKeyWidth
+ Layout.fillWidth: false
+ displayText: "ABC"
+ }
+ Key {
+ key: Qt.Key_Comma
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ text: ","
+ smallText: "\u2699"
+ smallTextVisible: true
+ highlighted: true
+ }
+ SpaceKey {
+ }
+ Key {
+ key: Qt.Key_Period
+ weight: normalKeyWidth
+ Layout.fillWidth: false
+ text: "…"
+ highlighted: true
+ }
+ EnterKey {
+ weight: functionKeyWidth
+ Layout.fillWidth: false
+ }
+ }
+ }
+ }
+}
diff --git a/src/plugins/cerence/xt9/plugin/xt9awinputmethod.cpp b/src/plugins/cerence/xt9/plugin/xt9awinputmethod.cpp
new file mode 100644
index 00000000..2a2becad
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/xt9awinputmethod.cpp
@@ -0,0 +1,329 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xt9awinputmethod_p.h"
+#include "xt9awinputmethodprivate_p.h"
+#include <QtVirtualKeyboard/qvirtualkeyboardinputcontext.h>
+#include <QtVirtualKeyboard/qvirtualkeyboardobserver.h>
+#include <QLoggingCategory>
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+/*!
+ \class QtVirtualKeyboard::Xt9AwInputMethod
+ \internal
+*/
+
+Xt9AwInputMethod::Xt9AwInputMethod(Xt9AwInputMethodPrivate &dd, QObject *parent) :
+ Xt9InputMethod(dd, parent)
+{
+}
+
+Xt9AwInputMethod::Xt9AwInputMethod(QObject *parent) :
+ Xt9InputMethod(*new Xt9AwInputMethodPrivate(this), parent)
+{
+}
+
+QList<QVirtualKeyboardInputEngine::InputMode> Xt9AwInputMethod::inputModes(const QString &locale)
+{
+ QList<QVirtualKeyboardInputEngine::InputMode> result;
+ bool supportsLatinInputMode = true;
+ switch (QLocale(locale).script()) {
+ case QLocale::GreekScript:
+ result.append(QVirtualKeyboardInputEngine::InputMode::Greek);
+ break;
+ case QLocale::CyrillicScript:
+ if (locale == QLatin1String("uk_UA") || locale == QLatin1String("ru_RU") || locale == QLatin1String("bg_BG")) {
+ result.append(QVirtualKeyboardInputEngine::InputMode::Cyrillic);
+ supportsLatinInputMode = false;
+ }
+ break;
+ case QLocale::ArabicScript:
+ result.append(QVirtualKeyboardInputEngine::InputMode::Arabic);
+ break;
+ case QLocale::HebrewScript:
+ result.append(QVirtualKeyboardInputEngine::InputMode::Hebrew);
+ break;
+ default:
+ break;
+ }
+ if (supportsLatinInputMode)
+ result.append(QVirtualKeyboardInputEngine::InputMode::Latin);
+ result.append(QVirtualKeyboardInputEngine::InputMode::Numeric);
+ return result;
+}
+
+bool Xt9AwInputMethod::setInputMode(const QString &locale, QVirtualKeyboardInputEngine::InputMode inputMode)
+{
+ Q_D(Xt9AwInputMethod);
+
+ return d->init(QLocale(locale), inputMode);
+}
+
+bool Xt9AwInputMethod::setTextCase(QVirtualKeyboardInputEngine::TextCase textCase)
+{
+ Q_UNUSED(textCase)
+ return true;
+}
+
+bool Xt9AwInputMethod::keyEvent(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers)
+{
+ Q_UNUSED(modifiers)
+ Q_D(Xt9AwInputMethod);
+
+ QVirtualKeyboardInputContext *ic = inputContext();
+ const Qt::InputMethodHints inputMethodHints = ic->inputMethodHints();
+ if (inputMethodHints.testFlag(Qt::ImhHiddenText) || inputMethodHints.testFlag(Qt::ImhNoPredictiveText)) {
+ const Qt::KeyboardModifiers mods = (key == Qt::Key_Return) ? Qt::NoModifier : modifiers;
+ inputContext()->sendKeyClick(key, text, mods);
+ return true;
+ }
+
+ switch (key) {
+ case Qt::Key_Backspace: {
+ const int cursorPosition = ic->cursorPosition();
+ if (cursorPosition > 0 && !d->xt9Ime()->hasActiveInput() &&
+ reselect(cursorPosition, QVirtualKeyboardInputEngine::ReselectFlag::WordBeforeCursor))
+ return true;
+ return d->processBackspace();
+ }
+
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ case Qt::Key_Tab:
+ case Qt::Key_Space: {
+ Xt9DeferredSelectionListUpdate deferredSelectionListUpdate(d);
+ if (d->xt9Ime()->hasActiveInput() && !d->selectionList.isEmpty() && d->defaultListIndex >= 0) {
+ if (key == Qt::Key_Space)
+ d->selectionList.replace(d->defaultListIndex, d->selectionList.at(d->defaultListIndex) + QLatin1String(" "));
+ d->selectionListSelectItem(d->defaultListIndex);
+ if (key == Qt::Key_Space) {
+ d->setAutoSpaceAllowed(false);
+ return true;
+ }
+ return false;
+ }
+
+ update();
+ if (key == Qt::Key_Space) {
+ ic->commit(QLatin1String(" "));
+ d->buildSelectionList();
+ return true;
+ }
+ break;
+ }
+
+ case Qt::Key_Shift:
+ break;
+
+ default:
+ if (text.length() > 0) {
+ const bool autoSpaceAllowed = d->xt9Ime()->hasActiveInput() || d->autoSpaceAllowed;
+ if (text.length() == 1) {
+ if (!d->processKeyBySymbol(text.at(0))) {
+ ic->sendKeyClick(key, text, modifiers);
+ d->setAutoSpaceAllowed(autoSpaceAllowed);
+ }
+ return true;
+ } else {
+ update();
+ d->setAutoSpaceAllowed(true);
+ if (autoSpaceAllowed && d->isAutoSpaceAllowed())
+ ic->commit(QLatin1String(" "));
+ ic->commit(text);
+ d->setAutoSpaceAllowed(autoSpaceAllowed);
+ d->buildSelectionList();
+ return true;
+ }
+ }
+ break;
+ }
+
+ return false;
+}
+
+QList<QVirtualKeyboardSelectionListModel::Type> Xt9AwInputMethod::selectionLists()
+{
+ return QList<QVirtualKeyboardSelectionListModel::Type>() << QVirtualKeyboardSelectionListModel::Type::WordCandidateList;
+}
+
+int Xt9AwInputMethod::selectionListItemCount(QVirtualKeyboardSelectionListModel::Type type)
+{
+ Q_UNUSED(type)
+ Q_D(Xt9AwInputMethod);
+ return d->selectionList.count();
+}
+
+QVariant Xt9AwInputMethod::selectionListData(QVirtualKeyboardSelectionListModel::Type type, int index, QVirtualKeyboardSelectionListModel::Role role)
+{
+ Q_UNUSED(type)
+ QVariant result;
+ Q_D(Xt9AwInputMethod);
+ switch (role) {
+ case QVirtualKeyboardSelectionListModel::Role::Display:
+ result = QVariant(d->selectionList.at(index));
+ break;
+ case QVirtualKeyboardSelectionListModel::Role::WordCompletionLength:
+ result.setValue(0);
+ break;
+ case QVirtualKeyboardSelectionListModel::Role::Dictionary:
+ {
+ ET9AWWordInfo *wordInfo = nullptr;
+ XT9_API(ET9AWSelLstGetWord, &d->xt9Ime()->sLingInfo, &wordInfo, static_cast<ET9U8>(index));
+ if (wordInfo) {
+ QVirtualKeyboardSelectionListModel::DictionaryType dictionaryType = wordInfo->bWordSource == ET9AWORDSOURCE_CUSTOM ?
+ QVirtualKeyboardSelectionListModel::DictionaryType::User :
+ QVirtualKeyboardSelectionListModel::DictionaryType::Default;
+ result = QVariant(static_cast<int>(dictionaryType));
+ }
+ break;
+ }
+ case QVirtualKeyboardSelectionListModel::Role::CanRemoveSuggestion:
+ {
+ ET9AWWordInfo *wordInfo = nullptr;
+ XT9_API(ET9AWSelLstGetWord, &d->xt9Ime()->sLingInfo, &wordInfo, static_cast<ET9U8>(index));
+ result = QVariant(wordInfo && wordInfo->bIsDeletable != 0);
+ break;
+ }
+ }
+ return result;
+}
+
+void Xt9AwInputMethod::selectionListItemSelected(QVirtualKeyboardSelectionListModel::Type type, int index)
+{
+ Q_UNUSED(type)
+ Q_D(Xt9AwInputMethod);
+
+ d->selectionListSelectItem(index);
+}
+
+bool Xt9AwInputMethod::selectionListRemoveItem(QVirtualKeyboardSelectionListModel::Type type, int index)
+{
+ Q_D(Xt9AwInputMethod);
+ Q_UNUSED(type)
+
+ if (index <= 0 || index >= d->selectionList.size())
+ return false;
+
+ QString word = d->selectionList.at(index);
+ d->removeFromDictionary(word);
+ d->buildSelectionList();
+
+ return true;
+}
+
+bool Xt9AwInputMethod::reselect(int cursorPosition, const QVirtualKeyboardInputEngine::ReselectFlags &reselectFlags)
+{
+ Q_D(Xt9AwInputMethod);
+
+ QVirtualKeyboardInputContext *ic = inputContext();
+ if (!ic)
+ return false;
+
+ QString word;
+ const QString surroundingText = ic->surroundingText();
+ int replaceFrom = 0;
+
+ if (reselectFlags.testFlag(QVirtualKeyboardInputEngine::ReselectFlag::WordBeforeCursor)) {
+ for (int i = cursorPosition - 1; i >= 0; --i) {
+ QChar c = surroundingText.at(i);
+ if (!d->isValidInputChar(c))
+ break;
+ word.insert(0, c);
+ --replaceFrom;
+ }
+
+ while (replaceFrom < 0 && d->isJoiner(word.at(0))) {
+ word.remove(0, 1);
+ ++replaceFrom;
+ }
+ }
+
+ if (reselectFlags.testFlag(QVirtualKeyboardInputEngine::ReselectFlag::WordAtCursor) && replaceFrom == 0)
+ return false;
+
+ if (reselectFlags.testFlag(QVirtualKeyboardInputEngine::ReselectFlag::WordAfterCursor)) {
+ for (int i = cursorPosition; i < surroundingText.length(); ++i) {
+ QChar c = surroundingText.at(i);
+ if (!d->isValidInputChar(c))
+ break;
+ word.append(c);
+ }
+
+ while (replaceFrom > -word.length()) {
+ int lastPos = word.length() - 1;
+ if (!d->isJoiner(word.at(lastPos)))
+ break;
+ word.remove(lastPos, 1);
+ }
+ }
+
+ if (word.isEmpty())
+ return false;
+
+ if (reselectFlags.testFlag(QVirtualKeyboardInputEngine::ReselectFlag::WordAtCursor) && replaceFrom == -word.length())
+ return false;
+
+ if (d->isJoiner(word.at(0)))
+ return false;
+
+ if (d->isJoiner(word.at(word.length() - 1)))
+ return false;
+
+ if (!d->reselectWord(word))
+ return false;
+
+ ic->setPreeditText(word, QList<QInputMethodEvent::Attribute>(), replaceFrom, word.length());
+ d->setAutoSpaceAllowed(false);
+
+ return true;
+}
+
+void Xt9AwInputMethod::reset()
+{
+ Q_D(Xt9AwInputMethod);
+
+ d->reset();
+}
+
+void Xt9AwInputMethod::update()
+{
+ Q_D(Xt9AwInputMethod);
+
+ if (d->xt9Ime()->hasActiveInput()) {
+ d->learnWord(d->xt9Ime()->exactWord());
+ inputContext()->commit();
+ }
+
+ reset();
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
diff --git a/src/plugins/cerence/xt9/plugin/xt9awinputmethod_p.h b/src/plugins/cerence/xt9/plugin/xt9awinputmethod_p.h
new file mode 100644
index 00000000..37bf9e1d
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/xt9awinputmethod_p.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XT9AWINPUTMETHOD_P_H
+#define XT9AWINPUTMETHOD_P_H
+
+#include "xt9inputmethod_p.h"
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+class Xt9AwInputMethodPrivate;
+
+class Xt9AwInputMethod : public Xt9InputMethod
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(Xt9AwInputMethod)
+protected:
+ Xt9AwInputMethod(Xt9AwInputMethodPrivate &dd, QObject *parent = nullptr);
+
+public:
+ explicit Xt9AwInputMethod(QObject *parent = nullptr);
+
+ QList<QVirtualKeyboardInputEngine::InputMode> inputModes(const QString &locale);
+ bool setInputMode(const QString &locale, QVirtualKeyboardInputEngine::InputMode inputMode);
+ bool setTextCase(QVirtualKeyboardInputEngine::TextCase textCase);
+
+ bool keyEvent(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers);
+
+ QList<QVirtualKeyboardSelectionListModel::Type> selectionLists();
+ int selectionListItemCount(QVirtualKeyboardSelectionListModel::Type type);
+ QVariant selectionListData(QVirtualKeyboardSelectionListModel::Type type, int index, QVirtualKeyboardSelectionListModel::Role role);
+ void selectionListItemSelected(QVirtualKeyboardSelectionListModel::Type type, int index);
+ bool selectionListRemoveItem(QVirtualKeyboardSelectionListModel::Type type, int index);
+
+ bool reselect(int cursorPosition, const QVirtualKeyboardInputEngine::ReselectFlags &reselectFlags);
+
+ void reset();
+ void update();
+};
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/cerence/xt9/plugin/xt9awinputmethodprivate.cpp b/src/plugins/cerence/xt9/plugin/xt9awinputmethodprivate.cpp
new file mode 100644
index 00000000..9e6819b3
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/xt9awinputmethodprivate.cpp
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xt9awinputmethodprivate_p.h"
+#include "xt9awinputmethod_p.h"
+#include "xt9languagemap.h"
+#include <QtVirtualKeyboard/qvirtualkeyboardinputengine.h>
+#include <QtVirtualKeyboard/qvirtualkeyboardinputcontext.h>
+#include <QtVirtualKeyboard/qvirtualkeyboarddictionarymanager.h>
+#include <QtVirtualKeyboard/private/settings_p.h>
+#include <et9api.h>
+#include <QLoggingCategory>
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+Xt9AwInputMethodPrivate::Xt9AwInputMethodPrivate(Xt9InputMethod *q, Xt9Ime *xt9Ime, const QString &aDlmFileName) :
+ Xt9InputMethodPrivate(q, xt9Ime, aDlmFileName)
+{
+}
+
+Xt9AwInputMethodPrivate::Xt9AwInputMethodPrivate(Xt9AwInputMethod *q) :
+ Xt9InputMethodPrivate(q, new Xt9AwIme(this), QStringLiteral("xt9aw.dlm"))
+{
+}
+
+void Xt9AwInputMethodPrivate::uninit()
+{
+ Xt9InputMethodPrivate::uninit();
+
+ defaultDictionaryDisabledConnection = QMetaObject::Connection();
+}
+
+void Xt9AwInputMethodPrivate::bindToSettings()
+{
+ Xt9InputMethodPrivate::bindToSettings();
+
+ if (!defaultDictionaryDisabledConnection)
+ defaultDictionaryDisabledConnection = QObjectPrivate::connect(
+ Settings::instance(), &Settings::defaultDictionaryDisabledChanged,
+ this, &Xt9AwInputMethodPrivate::onDefaultDictionaryDisabledChanged);
+}
+
+void Xt9AwInputMethodPrivate::updateLdb()
+{
+ Xt9InputMethodPrivate::updateLdb();
+
+ xt9Ime()->setLdbEnabled(!Settings::instance()->isDefaultDictionaryDisabled());
+}
+
+void Xt9AwInputMethodPrivate::selectionListSelectItem(int index)
+{
+ Q_Q(Xt9AwInputMethod);
+ Xt9DeferredSelectionListUpdate deferredSelectionListUpdate(this);
+
+ if (index >= 0 && index < selectionList.count()) {
+ QVirtualKeyboardInputContext *ic = q->inputContext();
+ const QString &selectedWord = selectionList.at(index);
+
+ // Auto space after next word prediction
+ bool wordIsPunct = selectedWord.length() == 1 && selectedWord.at(0).isPunct();
+ QString exactWord = xt9Ime()->exactWord();
+ if (!wordIsPunct && exactWord.isEmpty() && isAutoSpaceAllowed())
+ ic->commit(QLatin1String(" "));
+
+ // Commit selected word
+ xt9Ime()->selectWord(index, true);
+ ic->commit(selectedWord);
+ }
+
+ reset();
+ setAutoSpaceAllowed(true);
+
+ // Next word prediction
+ buildSelectionList();
+}
+
+bool Xt9AwInputMethodPrivate::reselectWord(const QString &word)
+{
+ ET9STATUS eStatus;
+ ET9U8 totalWords;
+ ET9U8 defaultListIndex;
+ ET9BOOL selectedWasAutomatic;
+ ET9BOOL wasFoundInHistory;
+
+ xt9Ime()->cursorMoved();
+
+ eStatus = XT9_API(ET9AWReselectWord,
+ &xt9Ime()->sLingInfo,
+ &xt9Ime()->sKdbInfo,
+ static_cast<const ET9SYMB *>(word.utf16()),
+ static_cast<ET9U16>(word.length()),
+ ET9AWReselectMode_Edit_Retain_Default,
+ &totalWords,
+ &defaultListIndex,
+ &selectedWasAutomatic,
+ &wasFoundInHistory);
+
+ if (eStatus)
+ return false;
+
+ buildSelectionList();
+
+ return true;
+}
+
+void Xt9AwInputMethodPrivate::learnWord(const QString &word)
+{
+ xt9Ime()->noteWordDone(word);
+}
+
+bool Xt9AwInputMethodPrivate::removeFromDictionary(const QString &word)
+{
+ ET9STATUS eStatus = XT9_API(ET9AWDLMDeleteWord,
+ &xt9Ime()->sLingInfo,
+ static_cast<const ET9SYMB *>(word.utf16()),
+ static_cast<ET9U16>(word.length()));
+
+ return !eStatus;
+}
+
+bool Xt9AwInputMethodPrivate::isJoiner(const QChar &c) const
+{
+ if (Xt9InputMethodPrivate::isJoiner(c))
+ return true;
+
+ if (c.isPunct() || c.isSymbol()) {
+ ushort unicode = c.unicode();
+ if (unicode == Qt::Key_Apostrophe || unicode == Qt::Key_Minus)
+ return true;
+ }
+ return false;
+}
+
+ET9U32 Xt9AwInputMethodPrivate::inputModeToET9InputMode(QVirtualKeyboardInputEngine::InputMode aInputMode) const
+{
+ Q_UNUSED(aInputMode)
+ return ET9AWInputMode_Default;
+}
+
+void Xt9AwInputMethodPrivate::onDefaultDictionaryDisabledChanged()
+{
+ xt9Ime()->setLdbEnabled(!Settings::instance()->isDefaultDictionaryDisabled());
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
diff --git a/src/plugins/cerence/xt9/plugin/xt9awinputmethodprivate_p.h b/src/plugins/cerence/xt9/plugin/xt9awinputmethodprivate_p.h
new file mode 100644
index 00000000..20faca8a
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/xt9awinputmethodprivate_p.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XT9AWINPUTMETHODPRIVATE_P_H
+#define XT9AWINPUTMETHODPRIVATE_P_H
+
+#include "xt9inputmethodprivate_p.h"
+#include "xt9awinputmethod_p.h"
+#include "xt9awime.h"
+#include <QMetaObject>
+#include <QByteArray>
+#include <QLocale>
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+class Xt9AwInputMethodPrivate : public Xt9InputMethodPrivate
+{
+ Q_DECLARE_PUBLIC(Xt9AwInputMethod)
+
+protected:
+ Xt9AwInputMethodPrivate(Xt9InputMethod *q_ptr, Xt9Ime *xt9Ime, const QString &aDlmFileName);
+
+public:
+ Xt9AwInputMethodPrivate(Xt9AwInputMethod *q_ptr);
+
+ inline Xt9AwIme *xt9Ime() const;
+
+ void uninit() override;
+ void bindToSettings() override;
+ void updateLdb() override;
+ void selectionListSelectItem(int index) override;
+
+ bool reselectWord(const QString &word);
+ void learnWord(const QString &word);
+ bool removeFromDictionary(const QString &word);
+
+ bool isJoiner(const QChar &c) const override;
+ ET9U32 inputModeToET9InputMode(QVirtualKeyboardInputEngine::InputMode aInputMode) const override;
+
+ void onDefaultDictionaryDisabledChanged();
+
+private:
+ QMetaObject::Connection defaultDictionaryDisabledConnection;
+};
+
+Xt9AwIme *Xt9AwInputMethodPrivate::xt9Ime() const
+{
+ return static_cast<Xt9AwIme *>(_xt9Ime.data());
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
+
+#endif // XT9AWINPUTMETHODPRIVATE_P_H
diff --git a/src/plugins/cerence/xt9/plugin/xt9cpinputmethod.cpp b/src/plugins/cerence/xt9/plugin/xt9cpinputmethod.cpp
new file mode 100644
index 00000000..ae3d8e0d
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/xt9cpinputmethod.cpp
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xt9cpinputmethod_p.h"
+#include "xt9cpinputmethodprivate_p.h"
+#include <QtVirtualKeyboard/qvirtualkeyboardinputcontext.h>
+#include <QtVirtualKeyboard/qvirtualkeyboardobserver.h>
+#include <QLoggingCategory>
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+/*!
+ \class QtVirtualKeyboard::Xt9CpInputMethod
+ \internal
+*/
+
+Xt9CpInputMethod::Xt9CpInputMethod(QObject *parent) :
+ Xt9InputMethod(*new Xt9CpInputMethodPrivate(this), parent)
+{
+}
+
+QList<QVirtualKeyboardInputEngine::InputMode> Xt9CpInputMethod::inputModes(const QString &locale)
+{
+ Q_UNUSED(locale)
+ QList<QVirtualKeyboardInputEngine::InputMode> result;
+ result.append(QVirtualKeyboardInputEngine::InputMode::Pinyin);
+ result.append(QVirtualKeyboardInputEngine::InputMode::Cangjie);
+ result.append(QVirtualKeyboardInputEngine::InputMode::Stroke);
+ return result;
+}
+
+bool Xt9CpInputMethod::setInputMode(const QString &locale, QVirtualKeyboardInputEngine::InputMode inputMode)
+{
+ Q_D(Xt9CpInputMethod);
+
+ return d->init(QLocale(locale), inputMode);
+}
+
+bool Xt9CpInputMethod::setTextCase(QVirtualKeyboardInputEngine::TextCase textCase)
+{
+ Q_UNUSED(textCase)
+ return true;
+}
+
+bool Xt9CpInputMethod::keyEvent(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers)
+{
+ Q_UNUSED(modifiers)
+ Q_D(Xt9CpInputMethod);
+
+ switch (key) {
+ case Qt::Key_Backspace:
+ return d->processBackspace();
+
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ case Qt::Key_Tab:
+ case Qt::Key_Space:
+ if (d->xt9Ime()->hasActiveInput() && !d->selectionList.isEmpty() && d->defaultListIndex >= 0) {
+ selectionListItemSelected(QVirtualKeyboardSelectionListModel::Type::WordCandidateList, d->defaultListIndex);
+ return key == Qt::Key_Space;
+ }
+
+ update();
+ break;
+
+ case Qt::Key_Shift:
+ break;
+
+ case Qt::Key_Apostrophe:
+ d->cycleTones();
+ return true;
+
+ default:
+ if (text.length() > 0) {
+ if (text.length() == 1) {
+ QString symbs = (d->inputMode == QVirtualKeyboardInputEngine::InputMode::Cangjie) ?
+ d->xt9Ime()->getCangjieConverter()->convertFrom(text) : text;
+ if (!d->processKeyBySymbol(symbs.at(0))) {
+ inputContext()->sendKeyClick(key, text, modifiers);
+ }
+ } else {
+ update();
+ inputContext()->commit(text);
+ }
+ return true;
+ }
+ break;
+ }
+
+ return false;
+}
+
+QList<QVirtualKeyboardSelectionListModel::Type> Xt9CpInputMethod::selectionLists()
+{
+ return QList<QVirtualKeyboardSelectionListModel::Type>() << QVirtualKeyboardSelectionListModel::Type::WordCandidateList;
+}
+
+int Xt9CpInputMethod::selectionListItemCount(QVirtualKeyboardSelectionListModel::Type type)
+{
+ Q_UNUSED(type)
+ Q_D(Xt9CpInputMethod);
+ return d->selectionList.count();
+}
+
+QVariant Xt9CpInputMethod::selectionListData(QVirtualKeyboardSelectionListModel::Type type, int index, QVirtualKeyboardSelectionListModel::Role role)
+{
+ QVariant result;
+ Q_D(Xt9CpInputMethod);
+ switch (role) {
+ case QVirtualKeyboardSelectionListModel::Role::Display:
+ result = QVariant(d->selectionList.at(index));
+ break;
+ case QVirtualKeyboardSelectionListModel::Role::WordCompletionLength:
+ result.setValue(0);
+ break;
+ default:
+ result = QVirtualKeyboardAbstractInputMethod::selectionListData(type, index, role);
+ break;
+ }
+ return result;
+}
+
+void Xt9CpInputMethod::selectionListItemSelected(QVirtualKeyboardSelectionListModel::Type type, int index)
+{
+ Q_UNUSED(type)
+ Q_D(Xt9CpInputMethod);
+
+ d->selectionListSelectItem(index);
+}
+
+void Xt9CpInputMethod::reset()
+{
+ Q_D(Xt9CpInputMethod);
+
+ d->reset();
+}
+
+void Xt9CpInputMethod::update()
+{
+ Q_D(Xt9CpInputMethod);
+
+ if (d->xt9Ime()->hasActiveInput() && !d->selectionList.isEmpty() && d->defaultListIndex >= 0) {
+ d->selectionListSelectItem(d->defaultListIndex);
+ }
+
+ inputContext()->clear();
+
+ d->reset();
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
diff --git a/src/plugins/cerence/xt9/plugin/xt9cpinputmethod_p.h b/src/plugins/cerence/xt9/plugin/xt9cpinputmethod_p.h
new file mode 100644
index 00000000..f727dbe4
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/xt9cpinputmethod_p.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XT9CPINPUTMETHOD_P_H
+#define XT9CPINPUTMETHOD_P_H
+
+#include "xt9inputmethod_p.h"
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+class Xt9CpInputMethodPrivate;
+
+class Xt9CpInputMethod : public Xt9InputMethod
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(Xt9CpInputMethod)
+public:
+ explicit Xt9CpInputMethod(QObject *parent = nullptr);
+
+ QList<QVirtualKeyboardInputEngine::InputMode> inputModes(const QString &locale);
+ bool setInputMode(const QString &locale, QVirtualKeyboardInputEngine::InputMode inputMode);
+ bool setTextCase(QVirtualKeyboardInputEngine::TextCase textCase);
+
+ bool keyEvent(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers);
+
+ QList<QVirtualKeyboardSelectionListModel::Type> selectionLists();
+ int selectionListItemCount(QVirtualKeyboardSelectionListModel::Type type);
+ QVariant selectionListData(QVirtualKeyboardSelectionListModel::Type type, int index, QVirtualKeyboardSelectionListModel::Role role);
+ void selectionListItemSelected(QVirtualKeyboardSelectionListModel::Type type, int index);
+
+ void reset();
+ void update();
+};
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/cerence/xt9/plugin/xt9cpinputmethodprivate.cpp b/src/plugins/cerence/xt9/plugin/xt9cpinputmethodprivate.cpp
new file mode 100644
index 00000000..96b7a24a
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/xt9cpinputmethodprivate.cpp
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xt9cpinputmethodprivate_p.h"
+#include "xt9cpinputmethod_p.h"
+#include <QtVirtualKeyboard/qvirtualkeyboardinputengine.h>
+#include <QtVirtualKeyboard/qvirtualkeyboardinputcontext.h>
+#include <QtVirtualKeyboard/qvirtualkeyboardobserver.h>
+#include <et9api.h>
+#include "xt9languagemap.h"
+#include <QDateTime>
+#include <QLoggingCategory>
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+Xt9CpInputMethodPrivate::Xt9CpInputMethodPrivate(Xt9CpInputMethod *q) :
+ Xt9InputMethodPrivate(q, new Xt9CpIme(this), QStringLiteral("xt9cp.dlm"))
+{
+}
+
+void Xt9CpInputMethodPrivate::cycleTones()
+{
+ if (!xt9Ime()->sWordSymbInfo.wNumSymbs)
+ return;
+
+ const ET9SYMB lastSymb = xt9Ime()->lastSymb();
+ ET9U8 tone = ET9CPSymToCPTone(lastSymb);
+
+ if (lastSymb == ET9CPSYLLABLEDELIMITER || tone) {
+ XT9_API(ET9ClearOneSymb, &xt9Ime()->sWordSymbInfo);
+
+ for (tone++; tone < 6; tone++) {
+ if (xt9Ime()->addTone(static_cast<ET9CPSYMB>(tone + ET9CPTONE1 - 1)))
+ break;
+ }
+
+ if (tone == 6) {
+ for (tone = 1; tone < 6; tone++) {
+ if (xt9Ime()->addTone(static_cast<ET9CPSYMB>(tone + ET9CPTONE1 - 1)))
+ break;
+ }
+ }
+
+ if (tone == 6) {
+ /* cycle back to delimiter */
+ XT9_API(ET9AddExplicitSymb, &xt9Ime()->sWordSymbInfo, ET9CPSYLLABLEDELIMITER, 0, ET9NOSHIFT, ET9_NO_ACTIVE_INDEX);
+ }
+ } else { /* first call, add delim */
+ XT9_API(ET9AddExplicitSymb, &xt9Ime()->sWordSymbInfo, ET9CPSYLLABLEDELIMITER, 0, ET9NOSHIFT, ET9_NO_ACTIVE_INDEX);
+ }
+
+ buildSelectionList();
+ updatePreeditText();
+}
+
+void Xt9CpInputMethodPrivate::updatePreeditText()
+{
+ QString spell = xt9Ime()->spell();
+ if (!spell.isEmpty()) {
+ Q_Q(Xt9InputMethod);
+ if (inputMode == QVirtualKeyboardInputEngine::InputMode::Cangjie)
+ spell = xt9Ime()->getCangjieConverter()->convertTo(spell);
+ q->inputContext()->setPreeditText(spell);
+ } else {
+ Xt9InputMethodPrivate::updatePreeditText();
+ }
+}
+
+void Xt9CpInputMethodPrivate::selectionListSelectItem(int index)
+{
+ Q_Q(Xt9CpInputMethod);
+ Xt9DeferredSelectionListUpdate deferredSelectionListUpdate(this);
+ QVirtualKeyboardInputContext *ic = q->inputContext();
+
+ ET9STATUS eStatus = xt9Ime()->selectWord(index);
+ if (eStatus == ET9STATUS_SELECTED_CHINESE_COMPONENT) {
+ processKeyBySymbol(selectionList.at(index).at(0));
+ } else {
+ ic->commit(selectionList.at(index));
+ if (eStatus == ET9STATUS_ALL_SYMB_SELECTED) {
+ reset();
+ } else {
+ updatePreeditText();
+ }
+ buildSelectionList();
+ }
+}
+
+bool Xt9CpInputMethodPrivate::isValidInputChar(const QChar &c) const
+{
+ const ushort ucs = c.unicode();
+ if (inputMode == QVirtualKeyboardInputEngine::InputMode::Stroke) {
+ return ET9CPIsStrokeSymbol(ucs) || ET9CPIsComponent(&xt9Ime()->sLingInfo, ucs);
+ }
+
+ return Xt9InputMethodPrivate::isValidInputChar(c);
+}
+
+void Xt9CpInputMethodPrivate::reset()
+{
+ xt9Ime()->commitSelection();
+
+ Xt9InputMethodPrivate::reset();
+}
+
+bool Xt9CpInputMethodPrivate::maybeInsertSpaceBeforeNextInputSymbol(QChar symbol) const
+{
+ Q_UNUSED(symbol)
+ return false;
+}
+
+ET9U32 Xt9CpInputMethodPrivate::inputModeToET9InputMode(QVirtualKeyboardInputEngine::InputMode aInputMode) const
+{
+ switch (aInputMode) {
+ case QVirtualKeyboardInputEngine::InputMode::Pinyin:
+ return ET9CPMODE_PINYIN;
+
+ case QVirtualKeyboardInputEngine::InputMode::Cangjie:
+ return ET9CPMODE_CANGJIE;
+
+ case QVirtualKeyboardInputEngine::InputMode::Zhuyin:
+ return ET9CPMODE_BPMF;
+
+ case QVirtualKeyboardInputEngine::InputMode::Stroke:
+ return ET9CPMODE_STROKE;
+
+ default:
+ return ET9CPMODE_PINYIN;
+ }
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
diff --git a/src/plugins/cerence/xt9/plugin/xt9cpinputmethodprivate_p.h b/src/plugins/cerence/xt9/plugin/xt9cpinputmethodprivate_p.h
new file mode 100644
index 00000000..0947301a
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/xt9cpinputmethodprivate_p.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XT9CPINPUTMETHODPRIVATE_P_H
+#define XT9CPINPUTMETHODPRIVATE_P_H
+
+#include "xt9inputmethodprivate_p.h"
+#include "xt9cpinputmethod_p.h"
+#include "xt9cpime.h"
+#include <QMetaObject>
+#include <QByteArray>
+#include <QLocale>
+#include <QtVirtualKeyboard/qvirtualkeyboardinputengine.h>
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+class Xt9CpInputMethodPrivate : public Xt9InputMethodPrivate
+{
+ Q_DECLARE_PUBLIC(Xt9CpInputMethod)
+public:
+ Xt9CpInputMethodPrivate(Xt9CpInputMethod *q_ptr);
+
+ inline Xt9CpIme *xt9Ime() const;
+
+ void cycleTones();
+ void updatePreeditText() override;
+ void selectionListSelectItem(int index) override;
+ bool isValidInputChar(const QChar &c) const override;
+ void reset() override;
+
+ bool maybeInsertSpaceBeforeNextInputSymbol(QChar symbol) const override;
+ ET9U32 inputModeToET9InputMode(QVirtualKeyboardInputEngine::InputMode aInputMode) const override;
+};
+
+Xt9CpIme *Xt9CpInputMethodPrivate::xt9Ime() const
+{
+ return static_cast<Xt9CpIme *>(_xt9Ime.data());
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
+
+#endif // XT9CPINPUTMETHODPRIVATE_P_H
diff --git a/src/plugins/cerence/xt9/plugin/xt9inputmethod.cpp b/src/plugins/cerence/xt9/plugin/xt9inputmethod.cpp
new file mode 100644
index 00000000..26611943
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/xt9inputmethod.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xt9inputmethod_p.h"
+#include "xt9inputmethodprivate_p.h"
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+/*!
+ \class QtVirtualKeyboard::Xt9InputMethod
+ \internal
+*/
+
+Xt9InputMethod::Xt9InputMethod(Xt9InputMethodPrivate &dd, QObject *parent) :
+ QVirtualKeyboardAbstractInputMethod(dd, parent)
+{
+ Q_D(Xt9InputMethod);
+ d->sysInit();
+}
+
+void Xt9InputMethod::clearInputMode()
+{
+ qCDebug(lcXT9) << "clearInputMode";
+ Q_D(Xt9InputMethod);
+ d->uninit();
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
diff --git a/src/plugins/cerence/xt9/plugin/xt9inputmethod_p.h b/src/plugins/cerence/xt9/plugin/xt9inputmethod_p.h
new file mode 100644
index 00000000..305ce546
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/xt9inputmethod_p.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XT9INPUTMETHOD_P_H
+#define XT9INPUTMETHOD_P_H
+
+#include <QtVirtualKeyboard/qvirtualkeyboardabstractinputmethod.h>
+#include "xt9inputmethodprivate_p.h"
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+class Xt9InputMethod : public QVirtualKeyboardAbstractInputMethod
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(Xt9InputMethod)
+
+protected:
+ Xt9InputMethod(Xt9InputMethodPrivate &dd, QObject *parent = nullptr);
+
+public:
+ void clearInputMode() override;
+};
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/cerence/xt9/plugin/xt9inputmethodprivate.cpp b/src/plugins/cerence/xt9/plugin/xt9inputmethodprivate.cpp
new file mode 100644
index 00000000..aee3197b
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/xt9inputmethodprivate.cpp
@@ -0,0 +1,576 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xt9inputmethodprivate_p.h"
+#include "xt9inputmethod_p.h"
+#include "xt9languagemap.h"
+#include "xt9dbfile.h"
+#include <QtVirtualKeyboard/qvirtualkeyboardinputcontext.h>
+#include <QtVirtualKeyboard/qvirtualkeyboardobserver.h>
+#include <QtVirtualKeyboard/qvirtualkeyboarddictionarymanager.h>
+#include <QtVirtualKeyboard/qvirtualkeyboarddictionary.h>
+#include <QtVirtualKeyboard/private/settings_p.h>
+#include <QDateTime>
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+Xt9InputMethodPrivate::Xt9InputMethodPrivate(Xt9InputMethod *q_ptr, Xt9Ime *xt9Ime, const QString &aDlmFileName) :
+ QVirtualKeyboardAbstractInputMethodPrivate(),
+ q_ptr(q_ptr),
+ _xt9Ime(xt9Ime),
+ inputMode(QVirtualKeyboardInputEngine::InputMode::Latin),
+ selectionListUpdateCount(0),
+ defaultListIndex(ET9_NO_ACTIVE_INDEX),
+ autoSpaceAllowed(false),
+ initDone(false),
+ dlmFileName(aDlmFileName)
+{
+}
+
+void Xt9InputMethodPrivate::sysInit()
+{
+ xt9Ime()->sysInit();
+ bindToSettings();
+ xt9Ime()->setWorkingDirectory(Settings::instance()->userDataPath());
+ xt9Ime()->removeAllIndexes();
+}
+
+bool Xt9InputMethodPrivate::init(QLocale aLocale, QVirtualKeyboardInputEngine::InputMode aInputMode)
+{
+ initDone = true;
+
+ xt9Ime()->setWorkingDirectory(Settings::instance()->userDataPath());
+
+ bindToDictionaryManager();
+ bindToSettings();
+ bindToKeyboard();
+
+ this->locale = aLocale;
+ this->inputMode = aInputMode;
+
+ updateLdb();
+ updateShiftState();
+ updateLayout();
+ updateDlm();
+ updateDynamicDictionaries();
+
+ return true;
+}
+
+void Xt9InputMethodPrivate::uninit()
+{
+ Q_Q(Xt9InputMethod);
+
+ initDone = false;
+
+ QObject::disconnect(availableDictionariesChangedConnection);
+ QObject::disconnect(activeDictionariesChangedConnection);
+ QObject::disconnect(userDataPathChangedConnection);
+ QObject::disconnect(userDataResetConnection);
+ QObject::disconnect(layoutChangedConnection);
+ QObject::disconnect(shiftActiveChangedConnection);
+ QObject::disconnect(capsLockActiveChangedConnection);
+ QObject::disconnect(inputMethodHintsChangedConnection);
+
+ dlmDeactivate();
+
+ removeAllDynamicDictionaries();
+
+ xt9Ime()->uninit();
+}
+
+void Xt9InputMethodPrivate::bindToDictionaryManager()
+{
+ if (!availableDictionariesChangedConnection)
+ availableDictionariesChangedConnection = QObjectPrivate::connect(QVirtualKeyboardDictionaryManager::instance(),
+ &QVirtualKeyboardDictionaryManager::availableDictionariesChanged,
+ this, &Xt9InputMethodPrivate::onAvailableDynamicDictionariesChanged);
+
+ if (!activeDictionariesChangedConnection)
+ activeDictionariesChangedConnection = QObjectPrivate::connect(QVirtualKeyboardDictionaryManager::instance(),
+ &QVirtualKeyboardDictionaryManager::activeDictionariesChanged,
+ this, &Xt9InputMethodPrivate::onActiveDynamicDictionariesChanged);
+}
+
+void Xt9InputMethodPrivate::bindToSettings()
+{
+ if (!userDataPathChangedConnection)
+ userDataPathChangedConnection = QObjectPrivate::connect(
+ Settings::instance(), &Settings::userDataPathChanged,
+ this, &Xt9InputMethodPrivate::onUserDataPathChanged);
+
+ if (!userDataResetConnection)
+ userDataResetConnection = QObjectPrivate::connect(
+ Settings::instance(), &Settings::userDataReset,
+ this, &Xt9InputMethodPrivate::onUserDataReset);
+}
+
+void Xt9InputMethodPrivate::bindToKeyboard()
+{
+ Q_Q(Xt9InputMethod);
+ QVirtualKeyboardInputContext *ic = q->inputContext();
+ if (!ic)
+ return;
+
+ if (!layoutChangedConnection)
+ layoutChangedConnection = QObjectPrivate::connect(
+ ic->keyboardObserver(), &QVirtualKeyboardObserver::layoutChanged,
+ this, &Xt9InputMethodPrivate::updateLayout);
+
+ if (!shiftActiveChangedConnection)
+ shiftActiveChangedConnection = QObjectPrivate::connect(
+ ic, &QVirtualKeyboardInputContext::shiftActiveChanged,
+ this, &Xt9InputMethodPrivate::updateShiftState);
+
+ if (!capsLockActiveChangedConnection)
+ capsLockActiveChangedConnection = QObjectPrivate::connect(
+ ic, &QVirtualKeyboardInputContext::capsLockActiveChanged,
+ this, &Xt9InputMethodPrivate::updateShiftState);
+
+ if (!inputMethodHintsChangedConnection)
+ inputMethodHintsChangedConnection = QObjectPrivate::connect(
+ ic, &QVirtualKeyboardInputContext::inputMethodHintsChanged,
+ this, &Xt9InputMethodPrivate::updateDlm);
+}
+
+void Xt9InputMethodPrivate::dlmActivate()
+{
+ const QString userDataPath = Settings::instance()->userDataPath();
+ const QString dlmFile = QStringLiteral("%1/%2").arg(userDataPath).arg(dlmFileName);
+ if (dlm && dlm->fileName() != dlmFile)
+ dlmDeactivate();
+
+ if (!dlm) {
+ if (!userDataPath.isEmpty()) {
+ qCDebug(lcXT9) << "dlmActivate" << dlmFile;
+ dlm.reset(new Xt9DbFile(dlmFile));
+ void *data = dlm->rwData(xt9Ime()->dlmPreferredSize());
+ qint64 size = dlm->size();
+ if (data != nullptr && size > 0) {
+ if (!xt9Ime()->dlmInit(data, size)) {
+ qCWarning(lcXT9) << "Failed to init DLM file - " << dlmFile;
+ dlm.reset();
+ }
+ } else {
+ qCWarning(lcXT9) << "Failed to open DLM file - " << dlmFile;
+ dlm.reset();
+ }
+ }
+ }
+}
+
+void Xt9InputMethodPrivate::dlmDeactivate()
+{
+ if (dlm) {
+ qCDebug(lcXT9) << "dlmDeactivate";
+ xt9Ime()->dlmInit(nullptr, 0);
+ dlm.reset();
+ }
+}
+
+void Xt9InputMethodPrivate::updateLdb()
+{
+ ET9U32 dwFirstLdbNum = Xt9LanguageMap::languageId(locale);
+ ET9U32 eInputMode = inputModeToET9InputMode(inputMode);
+
+ xt9Ime()->ldbInit(dwFirstLdbNum, ET9PLIDNone, eInputMode);
+}
+
+void Xt9InputMethodPrivate::updateDlm()
+{
+ Q_Q(Xt9InputMethod);
+ QVirtualKeyboardInputContext *ic = q->inputContext();
+ if (ic == nullptr)
+ return;
+
+ const Qt::InputMethodHints inputMethodHints = ic->inputMethodHints();
+ if (!inputMethodHints.testFlag(Qt::ImhHiddenText) && !inputMethodHints.testFlag(Qt::ImhSensitiveData))
+ dlmActivate();
+ else
+ dlmDeactivate();
+}
+
+void Xt9InputMethodPrivate::removeAllDynamicDictionaries()
+{
+ Q_Q(Xt9InputMethod);
+ xt9Ime()->removeAllIndexes();
+
+ QVirtualKeyboardDictionaryManager *dictionaryManager = QVirtualKeyboardDictionaryManager::instance();
+ const QStringList availableDictionaries = dictionaryManager->availableDictionaries();
+ for (const QString &dictionaryName : availableDictionaries) {
+ QVirtualKeyboardDictionary *dictionary = dictionaryManager->dictionary(dictionaryName);
+ dictionary->disconnect(q); // lambdas
+ }
+
+ attachedDynamicDictionaries.clear();
+ dynamicDictionaries.clear();
+ dynamicDictionaryNextId = 0;
+}
+
+void Xt9InputMethodPrivate::updateDynamicDictionaries()
+{
+ onAvailableDynamicDictionariesChanged();
+ onActiveDynamicDictionariesChanged();
+}
+
+void Xt9InputMethodPrivate::updateShiftState()
+{
+ Q_Q(Xt9InputMethod);
+ QVirtualKeyboardInputContext *ic = q->inputContext();
+ if (ic) {
+ if (ic->isCapsLockActive())
+ xt9Ime()->setCapsLock();
+ else if (ic->isShiftActive())
+ xt9Ime()->setShift();
+ else
+ xt9Ime()->setUnShift();
+ }
+}
+
+bool Xt9InputMethodPrivate::updateLayout()
+{
+ Q_Q(Xt9InputMethod);
+ QVirtualKeyboardInputContext *ic = q->inputContext();
+ if (ic == nullptr)
+ return false;
+
+ QVariantMap vkbLayout = ic->keyboardObserver()->layout().toMap();
+ ET9U32 dwFirstLdbNum = Xt9LanguageMap::languageId(locale);
+ vkbLayout[Xt9KeyboardGenerator::PRIMARY_ID] = static_cast<int>(dwFirstLdbNum & ET9PLIDMASK);
+ vkbLayout[Xt9KeyboardGenerator::SECONDARY_ID] = static_cast<int>(ET9SKIDNone);
+
+ return xt9Ime()->kdbInit(vkbLayout);
+}
+
+void Xt9InputMethodPrivate::updatePreeditText()
+{
+ Q_Q(Xt9InputMethod);
+
+ QString exactWord = xt9Ime()->exactWord();
+ q->inputContext()->setPreeditText(exactWord);
+}
+
+void Xt9InputMethodPrivate::buildSelectionList()
+{
+ ET9U16 gestureValue;
+ Xt9DeferredSelectionListUpdate deferredSelectionListUpdate(this);
+
+ if (xt9Ime()->exactWord().isEmpty()) {
+ // Check if next word prediction is not allowed
+ Q_Q(Xt9InputMethod);
+ const Qt::InputMethodHints inputMethodHints = q->inputContext()->inputMethodHints();
+ if (inputMethodHints.testFlag(Qt::ImhHiddenText) || inputMethodHints.testFlag(Qt::ImhNoPredictiveText)) {
+ selectionList.clear();
+ defaultListIndex = -1;
+ return;
+ }
+
+ // Ensure the buffer context is up-to-date for next word prediction
+ xt9Ime()->cursorMoved();
+ }
+
+ selectionList = xt9Ime()->buildSelectionList(&defaultListIndex, &gestureValue);
+}
+
+void Xt9InputMethodPrivate::selectionListUpdate()
+{
+ Q_Q(Xt9InputMethod);
+ emit q->selectionListChanged(QVirtualKeyboardSelectionListModel::Type::WordCandidateList);
+ emit q->selectionListActiveItemChanged(QVirtualKeyboardSelectionListModel::Type::WordCandidateList, defaultListIndex);
+}
+
+void Xt9InputMethodPrivate::updatePunctuationBreaking()
+{
+ Q_Q(Xt9InputMethod);
+ Qt::InputMethodHints inputMethodHints = q->inputContext()->inputMethodHints();
+ bool enabled = !inputMethodHints.testFlag(Qt::ImhUrlCharactersOnly) &&
+ !inputMethodHints.testFlag(Qt::ImhEmailCharactersOnly);
+
+ if (enabled)
+ XT9_API(ET9SetPunctuationBreaking, &xt9Ime()->sWordSymbInfo);
+ else
+ XT9_API(ET9ClearPunctuationBreaking, &xt9Ime()->sWordSymbInfo);
+}
+
+bool Xt9InputMethodPrivate::processBackspace()
+{
+ if (XT9_API(ET9ClearOneSymb, &xt9Ime()->sWordSymbInfo))
+ return false;
+
+ buildSelectionList();
+ updatePreeditText();
+
+ return true;
+}
+
+bool Xt9InputMethodPrivate::processKeyBySymbol(const QChar &symbol)
+{
+ QString exactWord = xt9Ime()->exactWord();
+ bool addToWord = isValidInputChar(symbol) && (!exactWord.isEmpty() || !isJoiner(symbol));
+ if (!addToWord) {
+ Q_Q(Xt9InputMethod);
+ q->update();
+ return false;
+ }
+
+ if (maybeInsertSpaceBeforeNextInputSymbol(symbol)) {
+ Q_Q(Xt9InputMethod);
+ q->update();
+ q->inputContext()->commit(QLatin1String(" "));
+ }
+
+ if (exactWord.isEmpty()) {
+ updatePunctuationBreaking();
+ updateShiftState();
+ xt9Ime()->cursorMoved();
+ }
+
+ ET9STATUS eStatus;
+ ET9SYMB functionKey = 0;
+ const ET9U8 currIndexInList = defaultListIndex < 0 ?
+ ET9_NO_ACTIVE_INDEX : static_cast<ET9U8>(defaultListIndex);
+ const ET9BOOL bInitialSymCheck = 1;
+ const ET9U32 dwTimeMS = static_cast<ET9U32>(QDateTime::currentMSecsSinceEpoch());
+
+ eStatus = XT9_API(ET9KDB_ProcessKeyBySymbol,
+ &xt9Ime()->sKdbInfo,
+ symbol.unicode(),
+ dwTimeMS,
+ currIndexInList,
+ &functionKey,
+ bInitialSymCheck);
+
+ if (eStatus == ET9STATUS_NO_KEY) {
+ const ET9INPUTSHIFTSTATE eShiftState = ET9SHIFT_STATE(&xt9Ime()->sWordSymbInfo);
+ eStatus = XT9_API(ET9AddExplicitSymb, &xt9Ime()->sWordSymbInfo, symbol.unicode(), dwTimeMS, eShiftState, 0);
+ } else if (eStatus) {
+ return false;
+ }
+
+ buildSelectionList();
+ updatePreeditText();
+
+ return true;
+}
+
+bool Xt9InputMethodPrivate::maybeInsertSpaceBeforeNextInputSymbol(QChar symbol) const
+{
+ Q_UNUSED(symbol)
+
+ QString exactWord = xt9Ime()->exactWord();
+ if (exactWord.isEmpty()) {
+ Q_Q(const Xt9InputMethod);
+
+ if (QVirtualKeyboardInputContext *ic = q->inputContext()) {
+ const QString surroundingText = ic->surroundingText();
+ const int cursorPosition = ic->cursorPosition();
+
+ if (!surroundingText.isEmpty() && cursorPosition == surroundingText.length()) {
+ QChar lastChar = surroundingText.at(cursorPosition - 1);
+
+ if (!lastChar.isSpace() && lastChar != QChar(Qt::Key_Minus) && isAutoSpaceAllowed())
+ return symbol.isLetterOrNumber();
+ }
+ }
+ }
+
+ return false;
+}
+
+void Xt9InputMethodPrivate::setAutoSpaceAllowed(bool value)
+{
+ if (autoSpaceAllowed == value)
+ return;
+
+ autoSpaceAllowed = value;
+ qCDebug(lcXT9) << "setAutoSpaceAllowed():" << value;
+}
+
+bool Xt9InputMethodPrivate::isAutoSpaceAllowed() const
+{
+ Q_Q(const Xt9InputMethod);
+ if (!autoSpaceAllowed)
+ return false;
+ if (q->inputEngine()->inputMode() == QVirtualKeyboardInputEngine::InputMode::Numeric)
+ return false;
+ Qt::InputMethodHints inputMethodHints = q->inputContext()->inputMethodHints();
+ return !inputMethodHints.testFlag(Qt::ImhUrlCharactersOnly) &&
+ !inputMethodHints.testFlag(Qt::ImhEmailCharactersOnly);
+}
+
+bool Xt9InputMethodPrivate::isValidInputChar(const QChar &c) const
+{
+ if (c.isLetterOrNumber())
+ return true;
+ if (isJoiner(c))
+ return true;
+ if (c.isMark())
+ return true;
+ return false;
+}
+
+bool Xt9InputMethodPrivate::isJoiner(const QChar &c) const
+{
+ if (c.isPunct() || c.isSymbol()) {
+ Q_Q(const Xt9InputMethod);
+ if (QVirtualKeyboardInputContext *ic = q->inputContext()) {
+ Qt::InputMethodHints inputMethodHints = ic->inputMethodHints();
+ if (inputMethodHints.testFlag(Qt::ImhUrlCharactersOnly) || inputMethodHints.testFlag(Qt::ImhEmailCharactersOnly))
+ return QStringView(u":/?#[]@!$&'()*+,;=-_.%").contains(c);
+ }
+ }
+ return false;
+}
+
+void Xt9InputMethodPrivate::setShiftState(bool shift, bool caps)
+{
+ if (caps)
+ xt9Ime()->setCapsLock();
+ else if (shift)
+ xt9Ime()->setShift();
+ else
+ xt9Ime()->setUnShift();
+}
+
+void Xt9InputMethodPrivate::reset()
+{
+ xt9Ime()->clearInput();
+
+ if (!selectionList.isEmpty() || defaultListIndex != -1) {
+ Xt9DeferredSelectionListUpdate deferredSelectionListUpdate(this);
+
+ selectionList.clear();
+ defaultListIndex = -1;
+ }
+
+ setAutoSpaceAllowed(false);
+}
+
+void Xt9InputMethodPrivate::onAvailableDynamicDictionariesChanged()
+{
+ Q_Q(Xt9InputMethod);
+ QVirtualKeyboardDictionaryManager *dictionaryManager = QVirtualKeyboardDictionaryManager::instance();
+
+ const QStringList availableDictionaries = dictionaryManager->availableDictionaries();
+ for (const QString &dictionaryName : availableDictionaries) {
+ if (!dynamicDictionaries.contains(dictionaryName)) {
+
+ QVirtualKeyboardDictionary *dictionary = dictionaryManager->dictionary(dictionaryName);
+ const quint16 id = static_cast<quint16>(dynamicDictionaryNextId.fetchAndAddRelaxed(1));
+ dynamicDictionaries[dictionaryName] = id;
+
+ xt9Ime()->updateIndex(id, dictionary->contents());
+
+ q->connect(dictionary, &QVirtualKeyboardDictionary::contentsChanged, q, [=]() {
+ xt9Ime()->updateIndex(id, dictionary->contents());
+ if (attachedDynamicDictionaries.contains(dictionaryName))
+ xt9Ime()->mountIndex(id);
+ });
+ }
+ }
+}
+
+void Xt9InputMethodPrivate::onActiveDynamicDictionariesChanged()
+{
+ QVirtualKeyboardDictionaryManager *dictionaryManager = QVirtualKeyboardDictionaryManager::instance();
+
+ // Attach
+ const QStringList activeDictionaries = dictionaryManager->activeDictionaries();
+ for (const QString &dictionaryName : activeDictionaries) {
+ if (!attachedDynamicDictionaries.contains(dictionaryName)) {
+ const quint16 id = dynamicDictionaries.value(dictionaryName);
+ xt9Ime()->mountIndex(id);
+ attachedDynamicDictionaries[dictionaryName] = id;
+ }
+ }
+
+ // Detach
+ for (const QString &dictionaryName : attachedDynamicDictionaries.keys()) {
+ if (!activeDictionaries.contains(dictionaryName)) {
+ const quint16 id = attachedDynamicDictionaries[dictionaryName];
+ xt9Ime()->unmountIndex(id);
+ attachedDynamicDictionaries.remove(dictionaryName);
+ }
+ }
+}
+
+void Xt9InputMethodPrivate::onUserDataPathChanged()
+{
+ updateDlm();
+ xt9Ime()->setWorkingDirectory(Settings::instance()->userDataPath());
+}
+
+void Xt9InputMethodPrivate::onUserDataReset()
+{
+ dlmDeactivate();
+ removeAllDynamicDictionaries();
+}
+
+ET9STATUS Xt9InputMethodPrivate::request(ET9_Request *const pRequest)
+{
+ Q_Q(Xt9InputMethod);
+
+ switch (pRequest->eType) {
+ case ET9_REQ_AutoCap:
+ break;
+
+ case ET9_REQ_AutoAccept:
+ selectionListSelectItem(defaultListIndex);
+ break;
+
+ case ET9_REQ_BufferContext:
+ {
+ QVirtualKeyboardInputContext *ic = q->inputContext();
+ if (!ic)
+ break;
+
+ const ET9U32 dwContextLen = static_cast<ET9U32>(ic->cursorPosition());
+ const ET9U32 dwStartIndex =
+ dwContextLen <= pRequest->data.sBufferContextInfo.dwMaxBufLen ?
+ 0 : dwContextLen - pRequest->data.sBufferContextInfo.dwMaxBufLen;
+
+ pRequest->data.sBufferContextInfo.dwBufLen = dwContextLen - dwStartIndex;
+ const QString surroundingText = ic->surroundingText();
+
+ memcpy(pRequest->data.sBufferContextInfo.psBuf, surroundingText.utf16() + dwStartIndex,
+ pRequest->data.sBufferContextInfo.dwBufLen * sizeof(ET9SYMB));
+
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ return ET9STATUS_NONE;
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
diff --git a/src/plugins/cerence/xt9/plugin/xt9inputmethodprivate_p.h b/src/plugins/cerence/xt9/plugin/xt9inputmethodprivate_p.h
new file mode 100644
index 00000000..70f5dda4
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/xt9inputmethodprivate_p.h
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XT9INPUTMETHODPRIVATE_P_H
+#define XT9INPUTMETHODPRIVATE_P_H
+
+#include <QtGlobal>
+#include <et9api.h>
+#include <QStringList>
+#include "xt9callbacks.h"
+#include "xt9ime.h"
+#include <QtVirtualKeyboard/qvirtualkeyboardinputengine.h>
+#include <QtVirtualKeyboard/private/qvirtualkeyboardabstractinputmethod_p.h>
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+class Xt9InputMethod;
+
+class Xt9InputMethodPrivate : public QVirtualKeyboardAbstractInputMethodPrivate, public Xt9RequestCallback
+{
+ Q_DECLARE_PUBLIC(Xt9InputMethod)
+public:
+ Xt9InputMethodPrivate(Xt9InputMethod *q_ptr, Xt9Ime *xt9Ime, const QString &aDlmFileName);
+
+ inline Xt9Ime *xt9Ime() const;
+ void sysInit();
+ bool init(QLocale aLocale, QVirtualKeyboardInputEngine::InputMode aInputMode);
+ virtual void uninit();
+ void bindToDictionaryManager();
+ virtual void bindToSettings();
+ void bindToKeyboard();
+ void dlmActivate();
+ void dlmDeactivate();
+ virtual void updateLdb();
+ void updateDlm();
+ void removeAllDynamicDictionaries();
+ void updateDynamicDictionaries();
+ void updateShiftState();
+ bool updateLayout();
+ virtual void updatePreeditText();
+ void buildSelectionList();
+ void selectionListUpdate();
+ virtual void selectionListSelectItem(int index) = 0;
+ void updatePunctuationBreaking();
+ bool processBackspace();
+ bool processKeyBySymbol(const QChar &symbol);
+ virtual bool maybeInsertSpaceBeforeNextInputSymbol(QChar symbol) const;
+ void setAutoSpaceAllowed(bool value);
+ virtual bool isAutoSpaceAllowed() const;
+ virtual bool isValidInputChar(const QChar &c) const;
+ virtual bool isJoiner(const QChar &c) const;
+ void setShiftState(bool shift, bool caps);
+ virtual void reset();
+ void onAvailableDynamicDictionariesChanged();
+ void onActiveDynamicDictionariesChanged();
+ void onUserDataPathChanged();
+ void onUserDataReset();
+
+ virtual ET9U32 inputModeToET9InputMode(QVirtualKeyboardInputEngine::InputMode aInputMode) const = 0;
+ ET9STATUS request(ET9_Request *const pRequest) override;
+
+public:
+ Xt9InputMethod *q_ptr;
+ QScopedPointer<Xt9Ime> _xt9Ime;
+ QMetaObject::Connection availableDictionariesChangedConnection;
+ QMetaObject::Connection activeDictionariesChangedConnection;
+ QMetaObject::Connection userDataPathChangedConnection;
+ QMetaObject::Connection userDataResetConnection;
+ QMetaObject::Connection layoutChangedConnection;
+ QMetaObject::Connection shiftActiveChangedConnection;
+ QMetaObject::Connection capsLockActiveChangedConnection;
+ QMetaObject::Connection inputMethodHintsChangedConnection;
+ QLocale locale;
+ QVirtualKeyboardInputEngine::InputMode inputMode;
+ QStringList selectionList;
+ QAtomicInt selectionListUpdateCount;
+ int defaultListIndex;
+ bool autoSpaceAllowed;
+ bool initDone;
+ const QString dlmFileName;
+ QSharedPointer<Xt9DbFile> dlm;
+ QMap<QString, quint16> dynamicDictionaries;
+ QMap<QString, quint16> attachedDynamicDictionaries;
+ QAtomicInt dynamicDictionaryNextId;
+};
+
+Xt9Ime *Xt9InputMethodPrivate::xt9Ime() const
+{
+ return _xt9Ime.data();
+}
+
+class Xt9DeferredSelectionListUpdate
+{
+ Q_DISABLE_COPY(Xt9DeferredSelectionListUpdate)
+public:
+ inline explicit Xt9DeferredSelectionListUpdate(Xt9InputMethodPrivate *d) :
+ d(d)
+ {
+ d->selectionListUpdateCount.ref();
+ }
+
+ inline ~Xt9DeferredSelectionListUpdate()
+ {
+ if (!d->selectionListUpdateCount.deref()) {
+ d->selectionListUpdate();
+ }
+ }
+
+private:
+ Xt9InputMethodPrivate *d;
+};
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
+
+#endif // XT9INPUTMETHODPRIVATE_P_H
diff --git a/src/plugins/cerence/xt9/plugin/xt9jinputmethod.cpp b/src/plugins/cerence/xt9/plugin/xt9jinputmethod.cpp
new file mode 100644
index 00000000..0455b5b2
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/xt9jinputmethod.cpp
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xt9jinputmethod_p.h"
+#include "xt9jinputmethodprivate_p.h"
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+/*!
+ \class QtVirtualKeyboard::Xt9JInputMethod
+ \internal
+*/
+
+Xt9JInputMethod::Xt9JInputMethod(QObject *parent) :
+ Xt9AwInputMethod(*new Xt9JInputMethodPrivate(this), parent)
+{
+}
+
+QList<QVirtualKeyboardInputEngine::InputMode> Xt9JInputMethod::inputModes(const QString &locale)
+{
+ QList<QVirtualKeyboardInputEngine::InputMode> result;
+ result.append(QVirtualKeyboardInputEngine::InputMode::Hiragana);
+ result.append(QVirtualKeyboardInputEngine::InputMode::Katakana);
+ result.append(QVirtualKeyboardInputEngine::InputMode::Romaji);
+ return result;
+}
+
+bool Xt9JInputMethod::setInputMode(const QString &locale, QVirtualKeyboardInputEngine::InputMode inputMode)
+{
+ return Xt9AwInputMethod::setInputMode(locale, inputMode);
+}
+
+bool Xt9JInputMethod::keyEvent(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers)
+{
+ Q_D(Xt9JInputMethod);
+
+ switch (key) {
+ case Qt::Key_Right:
+ case Qt::Key_Left:
+ {
+ ET9U16 wCurrLen;
+ ET9STATUS eStatus = XT9_API(ET9GetSegmentationLength, &d->xt9Ime()->sWordSymbInfo, &wCurrLen);
+ if (eStatus == ET9STATUS_INVALID_MODE) {
+ if (key == Qt::Key_Right) {
+
+ } else if (!XT9_API(ET9SetSegmentationLength, &d->xt9Ime()->sWordSymbInfo, wCurrLen)) {
+ d->selectionListUpdate();
+ return true;
+ }
+ } else if (!eStatus) {
+ if (key == Qt::Key_Left) {
+ --wCurrLen;
+ } else {
+ ++wCurrLen;
+ }
+
+ if (!XT9_API(ET9SetSegmentationLength, &d->xt9Ime()->sWordSymbInfo, wCurrLen)) {
+ d->selectionListUpdate();
+ return true;
+ }
+ }
+ break;
+ }
+
+ case 0x5C0F:
+ case 0x3099:
+ case 0x309A:
+ {
+ ET9MODIFIER eModifier;
+ switch (key) {
+ case 0x3099:
+ eModifier = ET9MODIFIER_JPNDAKUTEN_HANDAKUTEN;
+ break;
+ case 0x309A:
+ eModifier = ET9MODIFIER_JPNHANDAKUTEN;
+ break;
+ default:
+ eModifier = ET9MODIFIER_JPNALL;
+ break;
+ }
+ if (!XT9_API(ET9KDB_ModifyCurrentKey, &d->xt9Ime()->sKdbInfo, eModifier)) {
+ d->buildSelectionList();
+ d->updatePreeditText();
+ return true;
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ return Xt9AwInputMethod::keyEvent(key, d->xt9Ime()->codeConverter->convertTo(text), modifiers);
+}
+
+bool Xt9JInputMethod::isModifyKeyEnabled() const
+{
+ Q_D(const Xt9JInputMethod);
+ return d->isModifyKeyEnabled;
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
diff --git a/src/plugins/cerence/xt9/plugin/xt9jinputmethod_p.h b/src/plugins/cerence/xt9/plugin/xt9jinputmethod_p.h
new file mode 100644
index 00000000..95ac2848
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/xt9jinputmethod_p.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XT9JINPUTMETHOD_P_H
+#define XT9JINPUTMETHOD_P_H
+
+#include "xt9awinputmethod_p.h"
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+class Xt9JInputMethodPrivate;
+
+class Xt9JInputMethod : public Xt9AwInputMethod
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(Xt9JInputMethod)
+ Q_PROPERTY(bool modifyKeyEnabled READ isModifyKeyEnabled NOTIFY modifyKeyEnabledChanged)
+public:
+ explicit Xt9JInputMethod(QObject *parent = nullptr);
+
+ QList<QVirtualKeyboardInputEngine::InputMode> inputModes(const QString &locale) override;
+ bool setInputMode(const QString &locale, QVirtualKeyboardInputEngine::InputMode inputMode) override;
+
+ bool keyEvent(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers) override;
+
+ bool isModifyKeyEnabled() const;
+
+signals:
+ void modifyKeyEnabledChanged();
+};
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/cerence/xt9/plugin/xt9jinputmethodprivate.cpp b/src/plugins/cerence/xt9/plugin/xt9jinputmethodprivate.cpp
new file mode 100644
index 00000000..a2acbde7
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/xt9jinputmethodprivate.cpp
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xt9jinputmethodprivate_p.h"
+#include <QtVirtualKeyboard/qvirtualkeyboardinputcontext.h>
+#include <QTextFormat>
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+Xt9JInputMethodPrivate::Xt9JInputMethodPrivate(Xt9JInputMethod *q) :
+ Xt9AwInputMethodPrivate(q, new Xt9JIme(this), QStringLiteral("xt9j.dlm")),
+ isModifyKeyEnabled(false)
+{
+}
+
+void Xt9JInputMethodPrivate::updateLdb()
+{
+ Xt9AwInputMethodPrivate::updateLdb();
+ XT9_API(ET9AWSetMultiWordInputProperties, &xt9Ime()->sLingInfo, ET9AW_MWI_SegmentMode_Manual, 1);
+ if (inputMode == QVirtualKeyboardInputEngine::InputMode::Katakana) {
+ static const ET9AW_UtilityWord eList[] = {
+ ET9AW_UtilityWord_Katakana_FW,
+ ET9AW_UtilityWord_Hiragana_FW,
+ ET9AW_UtilityWord_Romaji_IC_HW,
+ ET9AW_UtilityWord_Romaji_LC_HW,
+ ET9AW_UtilityWord_Romaji_UC_HW
+ };
+ XT9_API(ET9AWSetUtilityWords, &xt9Ime()->sLingInfo, eList, sizeof(eList) / sizeof(ET9AW_UtilityWord), 2);
+ } else if (inputMode == QVirtualKeyboardInputEngine::InputMode::Hiragana) {
+ static const ET9AW_UtilityWord eList[] = {
+ ET9AW_UtilityWord_Hiragana_FW,
+ ET9AW_UtilityWord_Katakana_FW,
+ ET9AW_UtilityWord_Romaji_IC_HW,
+ ET9AW_UtilityWord_Romaji_LC_HW,
+ ET9AW_UtilityWord_Romaji_UC_HW
+ };
+ XT9_API(ET9AWSetUtilityWords, &xt9Ime()->sLingInfo, eList, sizeof(eList) / sizeof(ET9AW_UtilityWord), 2);
+ } else if (inputMode == QVirtualKeyboardInputEngine::InputMode::Latin) {
+ static const ET9AW_UtilityWord eList[] = {
+ ET9AW_UtilityWord_Romaji_IC_HW,
+ ET9AW_UtilityWord_Hiragana_FW,
+ ET9AW_UtilityWord_Katakana_FW,
+ ET9AW_UtilityWord_Romaji_LC_HW,
+ ET9AW_UtilityWord_Romaji_UC_HW
+ };
+ XT9_API(ET9AWSetUtilityWords, &xt9Ime()->sLingInfo, eList, sizeof(eList) / sizeof(ET9AW_UtilityWord), 2);
+ } else if (inputMode == QVirtualKeyboardInputEngine::InputMode::FullwidthLatin) {
+ static const ET9AW_UtilityWord eList[] = {
+ ET9AW_UtilityWord_Romaji_IC_FW,
+ ET9AW_UtilityWord_Hiragana_FW,
+ ET9AW_UtilityWord_Katakana_FW,
+ ET9AW_UtilityWord_Romaji_LC_HW,
+ ET9AW_UtilityWord_Romaji_UC_HW
+ };
+ XT9_API(ET9AWSetUtilityWords, &xt9Ime()->sLingInfo, eList, sizeof(eList) / sizeof(ET9AW_UtilityWord), 2);
+ }
+}
+
+void Xt9JInputMethodPrivate::updatePreeditText()
+{
+ Q_Q(Xt9JInputMethod);
+
+ QString exactWord = xt9Ime()->exactWord();
+ if (inputMode == QVirtualKeyboardInputEngine::InputMode::Katakana) {
+ exactWord = xt9Ime()->codeConverter->convertFrom(exactWord);
+ }
+
+ QList<QInputMethodEvent::Attribute> attributes;
+ QTextCharFormat textFormat;
+ textFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline);
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, exactWord.length(), textFormat));
+
+ ET9U16 wCurrLen;
+ if (!XT9_API(ET9GetSegmentationLength, &xt9Ime()->sWordSymbInfo, &wCurrLen)) {
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, wCurrLen, 1, QVariant()));
+ }
+
+ setModifyKeyEnabled(!exactWord.isEmpty());
+
+ q->inputContext()->setPreeditText(exactWord, attributes);
+}
+
+ET9U32 Xt9JInputMethodPrivate::inputModeToET9InputMode(QVirtualKeyboardInputEngine::InputMode aInputMode) const
+{
+ switch (aInputMode) {
+ case QVirtualKeyboardInputEngine::InputMode::Latin:
+ return ET9AWInputMode_Transliteration;
+
+ case QVirtualKeyboardInputEngine::InputMode::Romaji:
+ return ET9AWInputMode_RomajiConversion;
+
+ default:
+ break;
+ }
+
+ return ET9AWInputMode_Conversion;
+}
+
+void Xt9JInputMethodPrivate::reset()
+{
+ Xt9AwInputMethodPrivate::reset();
+ setModifyKeyEnabled(false);
+}
+
+void Xt9JInputMethodPrivate::setModifyKeyEnabled(bool value)
+{
+ if (isModifyKeyEnabled != value) {
+ isModifyKeyEnabled = value;
+ Q_Q(Xt9JInputMethod);
+ emit q->modifyKeyEnabledChanged();
+ }
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
diff --git a/src/plugins/cerence/xt9/plugin/xt9jinputmethodprivate_p.h b/src/plugins/cerence/xt9/plugin/xt9jinputmethodprivate_p.h
new file mode 100644
index 00000000..6fc40bcc
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/xt9jinputmethodprivate_p.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XT9JINPUTMETHODPRIVATE_P_H
+#define XT9JINPUTMETHODPRIVATE_P_H
+
+#include "xt9awinputmethodprivate_p.h"
+#include "xt9jinputmethod_p.h"
+#include "xt9jime.h"
+#include <QMetaObject>
+#include <QByteArray>
+#include <QLocale>
+#include <QtVirtualKeyboard/qvirtualkeyboardinputengine.h>
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+class Xt9JInputMethodPrivate : public Xt9AwInputMethodPrivate
+{
+ Q_DECLARE_PUBLIC(Xt9JInputMethod)
+public:
+ Xt9JInputMethodPrivate(Xt9JInputMethod *q_ptr);
+
+ inline Xt9JIme *xt9Ime() const;
+
+ void updateLdb() override;
+ void updatePreeditText() override;
+ ET9U32 inputModeToET9InputMode(QVirtualKeyboardInputEngine::InputMode aInputMode) const override;
+ void reset() override;
+
+ void setModifyKeyEnabled(bool value);
+
+ bool isModifyKeyEnabled;
+};
+
+Xt9JIme *Xt9JInputMethodPrivate::xt9Ime() const
+{
+ return static_cast<Xt9JIme *>(_xt9Ime.data());
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
+
+#endif // XT9JINPUTMETHODPRIVATE_P_H
diff --git a/src/plugins/cerence/xt9/plugin/xt9kinputmethod.cpp b/src/plugins/cerence/xt9/plugin/xt9kinputmethod.cpp
new file mode 100644
index 00000000..b9754c74
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/xt9kinputmethod.cpp
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xt9kinputmethod_p.h"
+#include "xt9kinputmethodprivate_p.h"
+#include <QVirtualKeyboardInputContext>
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+/*!
+ \class QtVirtualKeyboard::Xt9KInputMethod
+ \internal
+*/
+
+Xt9KInputMethod::Xt9KInputMethod(QObject *parent) :
+ Xt9AwInputMethod(*new Xt9KInputMethodPrivate(this), parent)
+{
+}
+
+bool Xt9KInputMethod::keyEvent(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers)
+{
+ Q_D(Xt9KInputMethod);
+ return Xt9AwInputMethod::keyEvent(key, d->xt9Ime()->codeConverter->convertTo(text), modifiers);
+}
+
+void Xt9KInputMethod::update()
+{
+ Q_D(Xt9KInputMethod);
+
+ if (d->xt9Ime()->hasActiveInput()) {
+ if (d->selectionList.length() > 0) {
+ d->learnWord(d->selectionList.at(0));
+ d->setAutoSpaceAllowed(false);
+ d->selectionListSelectItem(0);
+ } else {
+ inputContext()->commit();
+ reset();
+ }
+ }
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
diff --git a/src/plugins/cerence/xt9/plugin/xt9kinputmethod_p.h b/src/plugins/cerence/xt9/plugin/xt9kinputmethod_p.h
new file mode 100644
index 00000000..9b5623ac
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/xt9kinputmethod_p.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XT9KINPUTMETHOD_P_H
+#define XT9KINPUTMETHOD_P_H
+
+#include "xt9awinputmethod_p.h"
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+class Xt9KInputMethodPrivate;
+
+class Xt9KInputMethod : public Xt9AwInputMethod
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(Xt9KInputMethod)
+public:
+ explicit Xt9KInputMethod(QObject *parent = nullptr);
+
+ bool keyEvent(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers) override;
+
+ void update() override;
+};
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/cerence/xt9/plugin/xt9kinputmethodprivate.cpp b/src/plugins/cerence/xt9/plugin/xt9kinputmethodprivate.cpp
new file mode 100644
index 00000000..f56949a2
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/xt9kinputmethodprivate.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xt9kinputmethodprivate_p.h"
+#include <QVirtualKeyboardInputContext>
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+Xt9KInputMethodPrivate::Xt9KInputMethodPrivate(Xt9KInputMethod *q) :
+ Xt9AwInputMethodPrivate(q, new Xt9KIme(this), QStringLiteral("xt9k.dlm"))
+{
+}
+
+void Xt9KInputMethodPrivate::updatePreeditText()
+{
+ ET9KHangulWord hangul;
+ ET9STATUS eStatus = XT9_API(ET9KBuildHangul, &xt9Ime()->sLingInfo, &hangul);
+ if (!eStatus && hangul.wLen) {
+ Q_Q(Xt9KInputMethod);
+ q->inputContext()->setPreeditText(QString::fromUtf16(reinterpret_cast<const char16_t*>(hangul.sString), hangul.wLen));
+ } else {
+ Xt9AwInputMethodPrivate::updatePreeditText();
+ }
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
diff --git a/src/plugins/cerence/xt9/plugin/xt9kinputmethodprivate_p.h b/src/plugins/cerence/xt9/plugin/xt9kinputmethodprivate_p.h
new file mode 100644
index 00000000..642beb92
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/xt9kinputmethodprivate_p.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XT9KINPUTMETHODPRIVATE_P_H
+#define XT9KINPUTMETHODPRIVATE_P_H
+
+#include "xt9awinputmethodprivate_p.h"
+#include "xt9kinputmethod_p.h"
+#include "xt9kime.h"
+#include <QMetaObject>
+#include <QByteArray>
+#include <QLocale>
+#include <QtVirtualKeyboard/qvirtualkeyboardinputengine.h>
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+class Xt9KInputMethodPrivate : public Xt9AwInputMethodPrivate
+{
+ Q_DECLARE_PUBLIC(Xt9KInputMethod)
+public:
+ Xt9KInputMethodPrivate(Xt9KInputMethod *q_ptr);
+
+ inline Xt9KIme *xt9Ime() const;
+
+ void updatePreeditText();
+};
+
+Xt9KIme *Xt9KInputMethodPrivate::xt9Ime() const
+{
+ return static_cast<Xt9KIme *>(_xt9Ime.data());
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
+
+#endif // XT9KINPUTMETHODPRIVATE_P_H
diff --git a/src/plugins/cerence/xt9/plugin/xt9plugin.cpp b/src/plugins/cerence/xt9/plugin/xt9plugin.cpp
new file mode 100644
index 00000000..9de8805e
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/xt9plugin.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xt9plugin.h"
+#include "xt9awinputmethod_p.h"
+#include "xt9cpinputmethod_p.h"
+#include "xt9kinputmethod_p.h"
+#include "xt9jinputmethod_p.h"
+#include "xt9thaiinputmethod_p.h"
+#include <QtQml>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QtVirtualKeyboard;
+
+void QtVirtualKeyboardXt9Plugin::registerTypes(const char *uri) const
+{
+#ifdef HAVE_XT9_RESOURCE
+ Q_INIT_RESOURCE(qmake_cerencecommondata_db);
+#endif
+ qmlRegisterType<Xt9AwInputMethod>(uri, 2, 0, "DefaultInputMethod");
+ qmlRegisterType<Xt9CpInputMethod>(uri, 2, 0, "PinyinInputMethod");
+ qmlRegisterType<Xt9CpInputMethod>(uri, 2, 0, "CangjieInputMethod");
+ qmlRegisterType<Xt9CpInputMethod>(uri, 2, 0, "StrokeInputMethod");
+ qmlRegisterType<Xt9KInputMethod>(uri, 2, 0, "HangulInputMethod");
+ qmlRegisterType<Xt9JInputMethod>(uri, 2, 0, "JapaneseInputMethod");
+ qmlRegisterType<Xt9ThaiInputMethod>(uri, 2, 0, "ThaiInputMethod");
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/t9write/plugin/t9writeplugin.h b/src/plugins/cerence/xt9/plugin/xt9plugin.h
index 570aea46..9afe3b34 100644
--- a/src/plugins/t9write/plugin/t9writeplugin.h
+++ b/src/plugins/cerence/xt9/plugin/xt9plugin.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
@@ -27,19 +27,19 @@
**
****************************************************************************/
-#ifndef T9WRITEPLUGIN_H
-#define T9WRITEPLUGIN_H
+#ifndef XT9PLUGIN_H
+#define XT9PLUGIN_H
#include <QVirtualKeyboardExtensionPlugin>
QT_BEGIN_NAMESPACE
-class QtVirtualKeyboardT9WritePlugin : public QVirtualKeyboardExtensionPlugin
+class QtVirtualKeyboardXt9Plugin : public QVirtualKeyboardExtensionPlugin
{
Q_OBJECT
Q_INTERFACES(QVirtualKeyboardExtensionPlugin)
Q_PLUGIN_METADATA(IID QVirtualKeyboardExtensionPluginFactoryInterface_iid
- FILE "t9write.json")
+ FILE "cerence_xt9.json")
public:
void registerTypes(const char *uri) const;
};
diff --git a/src/plugins/cerence/xt9/plugin/xt9thaiinputmethod.cpp b/src/plugins/cerence/xt9/plugin/xt9thaiinputmethod.cpp
new file mode 100644
index 00000000..ed8e7068
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/xt9thaiinputmethod.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xt9thaiinputmethod_p.h"
+#include "xt9thaiinputmethodprivate_p.h"
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+/*!
+ \class QtVirtualKeyboard::Xt9ThaiInputMethod
+ \internal
+*/
+
+Xt9ThaiInputMethod::Xt9ThaiInputMethod(QObject *parent) :
+ Xt9AwInputMethod(*new Xt9ThaiInputMethodPrivate(this), parent)
+{
+}
+
+bool Xt9ThaiInputMethod::keyEvent(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers)
+{
+ const bool isMark = text.length() == 2 && text.at(0) == QLatin1Char(' ');
+ if (isMark) {
+ const QString mark(text.right(1));
+ return Xt9AwInputMethod::keyEvent(static_cast<Qt::Key>(mark.at(0).unicode()),
+ mark, modifiers);
+ }
+ return Xt9AwInputMethod::keyEvent(key, text, modifiers);
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
diff --git a/src/plugins/cerence/xt9/plugin/xt9thaiinputmethod_p.h b/src/plugins/cerence/xt9/plugin/xt9thaiinputmethod_p.h
new file mode 100644
index 00000000..0611db34
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/xt9thaiinputmethod_p.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XT9THAIINPUTMETHOD_P_H
+#define XT9THAIINPUTMETHOD_P_H
+
+#include "xt9awinputmethod_p.h"
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+class Xt9ThaiInputMethodPrivate;
+
+class Xt9ThaiInputMethod : public Xt9AwInputMethod
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(Xt9ThaiInputMethod)
+public:
+ explicit Xt9ThaiInputMethod(QObject *parent = nullptr);
+
+ bool keyEvent(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers) override;
+};
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/cerence/xt9/plugin/xt9thaiinputmethodprivate.cpp b/src/plugins/cerence/xt9/plugin/xt9thaiinputmethodprivate.cpp
new file mode 100644
index 00000000..672a5e24
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/xt9thaiinputmethodprivate.cpp
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xt9thaiinputmethodprivate_p.h"
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+Xt9ThaiInputMethodPrivate::Xt9ThaiInputMethodPrivate(Xt9ThaiInputMethod *q) :
+ Xt9AwInputMethodPrivate(q, new Xt9AwIme(this), QStringLiteral("xt9aw.dlm"))
+{
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
diff --git a/src/plugins/cerence/xt9/plugin/xt9thaiinputmethodprivate_p.h b/src/plugins/cerence/xt9/plugin/xt9thaiinputmethodprivate_p.h
new file mode 100644
index 00000000..787976ec
--- /dev/null
+++ b/src/plugins/cerence/xt9/plugin/xt9thaiinputmethodprivate_p.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XT9THAIINPUTMETHODPRIVATE_P_H
+#define XT9THAIINPUTMETHODPRIVATE_P_H
+
+#include "xt9awinputmethodprivate_p.h"
+#include "xt9thaiinputmethod_p.h"
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+class Xt9ThaiInputMethodPrivate : public Xt9AwInputMethodPrivate
+{
+ Q_DECLARE_PUBLIC(Xt9ThaiInputMethod)
+public:
+ Xt9ThaiInputMethodPrivate(Xt9ThaiInputMethod *q_ptr);
+};
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
+
+#endif // XT9KINPUTMETHODPRIVATE_P_H
diff --git a/src/plugins/cerence/xt9/xt9common/CMakeLists.txt b/src/plugins/cerence/xt9/xt9common/CMakeLists.txt
new file mode 100644
index 00000000..d2676bd2
--- /dev/null
+++ b/src/plugins/cerence/xt9/xt9common/CMakeLists.txt
@@ -0,0 +1,141 @@
+# Generated from xt9common.pro.
+
+#####################################################################
+## BundledXt9Common Generic Library:
+#####################################################################
+
+qt_internal_add_3rdparty_library(BundledXt9Common
+ QMAKE_LIB_NAME xt9common
+ STATIC
+ SOURCES
+ xt9awime.cpp xt9awime.h
+ xt9callbacks.h
+ xt9cpime.cpp xt9cpime.h
+ xt9ime.cpp xt9ime.h
+ xt9jime.cpp xt9jime.h
+ xt9kdb.cpp xt9kdb.h
+ xt9kdbarea.cpp xt9kdbarea.h
+ xt9kdbelement.cpp xt9kdbelement.h
+ xt9kdbkey.cpp xt9kdbkey.h
+ xt9kdblayout.cpp xt9kdblayout.h
+ xt9keyboardgenerator.cpp xt9keyboardgenerator.h
+ xt9kime.cpp xt9kime.h
+ xt9languagemap.cpp xt9languagemap.h
+ PUBLIC_INCLUDE_DIRECTORIES
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
+ LIBRARIES
+ BundledCerencecommon
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::VirtualKeyboard
+ Cerence::XT9
+)
+
+## Scopes:
+#####################################################################
+
+if(NOT FEATURE_vkb_cerence_static)
+ qt_copy_or_install(
+ FILES "${CERENCE_XT9_BINARIES}"
+ DESTINATION "${QT_BUILD_DIR}/${INSTALL_BINDIR}"
+ )
+endif()
+
+#### Keys ignored in scope 3:.:../..:../../cerence.pri:CERENCE_SDK_ROOT_ISEMPTY:
+# EXT_CERENCE_SDK_ROOT = "$$(CERENCE_SDK_ROOT)"
+
+#### Keys ignored in scope 4:.:../..:../../cerence.pri:NOT EXT_CERENCE_SDK_ROOT_ISEMPTY:
+# CERENCE_SDK_ROOT = "$$EXT_CERENCE_SDK_ROOT"
+
+#### Keys ignored in scope 6:.:../..:../../cerence.pri:CERENCE_SDK_ROOT_ISEMPTY:
+# CERENCE_SDK_ROOT = "$$PWD/sdk"
+
+#### Keys ignored in scope 9:.:../..:../../cerence.pri:QT_ARCH___equals___arm:
+# CERENCE_SHARED_LIB_PATH = "lib/linux/arm/shared"
+# CERENCE_STATIC_LIB_PATH = "lib/linux/arm/static"
+
+#### Keys ignored in scope 11:.:../..:../../cerence.pri:QT_ARCH___equals___arm64:
+# CERENCE_SHARED_LIB_PATH = "lib/linux/arm64/shared"
+# CERENCE_STATIC_LIB_PATH = "lib/linux/arm64/static"
+
+#### Keys ignored in scope 13:.:../..:../../cerence.pri:QT_ARCH___equals___x86_64:
+# CERENCE_SHARED_LIB_PATH = "lib/linux/x86_64/shared"
+# CERENCE_STATIC_LIB_PATH = "lib/linux/x86_64/static"
+
+#### Keys ignored in scope 15:.:../..:../../cerence.pri:QT_ARCH___equals___x86 OR QT_ARCH___equals___i386:
+# CERENCE_SHARED_LIB_PATH = "lib/linux/x86/shared"
+# CERENCE_STATIC_LIB_PATH = "lib/linux/x86/static"
+
+#### Keys ignored in scope 18:.:../..:../../cerence.pri:QT_ARCH___equals___x86_64:
+# CERENCE_SHARED_LIB_PATH = "lib/win32/x86_64/shared"
+# CERENCE_STATIC_LIB_PATH = "lib/win32/x86_64/static"
+
+#### Keys ignored in scope 19:.:../..:../../cerence.pri:else:
+# CERENCE_SHARED_LIB_PATH = "lib/win32/x86/shared"
+# CERENCE_STATIC_LIB_PATH = "lib/win32/x86/static"
+
+#### Keys ignored in scope 21:.:../..:../../cerence.pri:WIN32:
+# result = "$$1/*.obj"
+
+#### Keys ignored in scope 22:.:../..:../../cerence.pri:result_ISEMPTY:
+# result = "$$1/*.lib"
+
+#### Keys ignored in scope 23:.:../..:../../cerence.pri:else:
+# result = "$$1/*.o"
+
+#### Keys ignored in scope 24:.:../..:../../cerence.pri:result_ISEMPTY:
+# result = "$$1/*.a"
+
+#### Keys ignored in scope 26:.:../..:../../cerence.pri:WIN32:
+# result = "$$1/*.lib"
+
+#### Keys ignored in scope 27:.:../..:../../cerence.pri:else:
+# result = "$$1/*.so"
+
+#### Keys ignored in scope 29:.:../..:../../cerence.pri:WIN32:
+# result = "$$1/*.dll"
+
+#### Keys ignored in scope 30:.:../..:../../cerence.pri:else:
+# result = "$$1/*.so"
+
+#### Keys ignored in scope 31:.:../..:../../cerence.pri:EXISTS _ss_CERENCE_HWR_INCLUDEPATH/decuma_hwr.h:
+# CERENCE_HWR_ALPHABETIC_FOUND = "1"
+
+#### Keys ignored in scope 32:.:../..:../../cerence.pri:EXISTS _ss_CERENCE_HWR_INCLUDEPATH/decuma_hwr_cjk.h:
+# CERENCE_HWR_CJK_FOUND = "1"
+
+#### Keys ignored in scope 35:.:../..:../../cerence.pri:NOT cerence-hwr-static:
+# CERENCE_HWR_ALPHABETIC_LIBS = "$$findSharedLibrary($$CERENCE_SDK_ROOT/t9write/$$CERENCE_SHARED_LIB_PATH/alphabetic)"
+
+#### Keys ignored in scope 36:.:../..:../../cerence.pri:NOT CERENCE_HWR_ALPHABETIC_LIBS_ISEMPTY:
+# CERENCE_HWR_ALPHABETIC_BINS = "$$findSharedBinary($$CERENCE_SDK_ROOT/t9write/$$CERENCE_SHARED_LIB_PATH/alphabetic)"
+
+#### Keys ignored in scope 37:.:../..:../../cerence.pri:else:
+# CERENCE_HWR_ALPHABETIC_LIBS = "$$findStaticLibrary($$CERENCE_SDK_ROOT/t9write/$$CERENCE_STATIC_LIB_PATH/alphabetic)"
+
+#### Keys ignored in scope 39:.:../..:../../cerence.pri:NOT cerence-hwr-static:
+# CERENCE_HWR_CJK_LIBS = "$$findSharedLibrary($$CERENCE_SDK_ROOT/t9write/$$CERENCE_SHARED_LIB_PATH/cjk)"
+
+#### Keys ignored in scope 40:.:../..:../../cerence.pri:NOT CERENCE_HWR_CJK_LIBS_ISEMPTY:
+# CERENCE_HWR_CJK_BINS = "$$findSharedBinary($$CERENCE_SDK_ROOT/t9write/$$CERENCE_SHARED_LIB_PATH/cjk)"
+
+#### Keys ignored in scope 41:.:../..:../../cerence.pri:else:
+# CERENCE_HWR_CJK_LIBS = "$$findStaticLibrary($$CERENCE_SDK_ROOT/t9write/$$CERENCE_STATIC_LIB_PATH/cjk)"
+
+#### Keys ignored in scope 42:.:../..:../../cerence.pri:(CERENCE_HWR_ALPHABETIC_FOUND EQUAL 1) AND NOT CERENCE_HWR_ALPHABETIC_LIBS_ISEMPTY:
+# CERENCE_HWR_FOUND = "1"
+
+#### Keys ignored in scope 43:.:../..:../../cerence.pri:(CERENCE_HWR_CJK_FOUND EQUAL 1) AND NOT CERENCE_HWR_CJK_LIBS_ISEMPTY:
+# CERENCE_HWR_FOUND = "1"
+
+#### Keys ignored in scope 44:.:../..:../../cerence.pri:EXISTS _ss_XT9_INCLUDEPATH/et9api.h:
+# XT9_FOUND = "1"
+
+#### Keys ignored in scope 46:.:../..:../../cerence.pri:NOT QT_FEATURE_xt9_static:
+# XT9_LIBS = "$$findSharedLibrary($$CERENCE_SDK_ROOT/xt9/$$CERENCE_SHARED_LIB_PATH)"
+
+#### Keys ignored in scope 47:.:../..:../../cerence.pri:NOT XT9_LIBS_ISEMPTY:
+# XT9_BINS = "$$findSharedBinary($$CERENCE_SDK_ROOT/xt9/$$CERENCE_SHARED_LIB_PATH)"
+
+#### Keys ignored in scope 48:.:../..:../../cerence.pri:else:
+# XT9_LIBS = "$$findStaticLibrary($$CERENCE_SDK_ROOT/xt9/$$CERENCE_STATIC_LIB_PATH)"
diff --git a/src/plugins/cerence/xt9/xt9common/xt9awime.cpp b/src/plugins/cerence/xt9/xt9common/xt9awime.cpp
new file mode 100644
index 00000000..912b65e3
--- /dev/null
+++ b/src/plugins/cerence/xt9/xt9common/xt9awime.cpp
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xt9awime.h"
+#include "xt9languagemap.h"
+#include "xt9dbfile.h"
+#include <QStandardPaths>
+#include <QLoggingCategory>
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+Xt9AwIme::Xt9AwIme(Xt9RequestCallback *requestCallback, Xt9KeyboardGenerator::CodeConverter *codeConverter) :
+ Xt9Ime(requestCallback, codeConverter)
+{
+}
+
+void Xt9AwIme::sysInit()
+{
+ Xt9Ime::sysInit();
+ memset(&sLingInfo, 0, sizeof(sLingInfo));
+ memset(&sLingCmnInfo, 0, sizeof(sLingCmnInfo));
+ XT9_API(ET9AWSysInit, &sLingInfo, &sLingCmnInfo, &sWordSymbInfo, 1, this);
+}
+
+bool Xt9AwIme::ldbInit(ET9U32 dwFirstLdbNum, ET9U32 dwSecondLdbNum, ET9U32 eInputMode)
+{
+ ET9STATUS eStatus;
+
+ eStatus = XT9_API(ET9AWEnableDBs, &sLingInfo, ET9ALLDBMASK);
+
+ XT9_API(ET9AWLdbInit, &sLingInfo, &ET9AWLdbReadData);
+ eStatus = XT9_API(ET9AWLdbSetLanguage, &sLingInfo, dwFirstLdbNum, dwSecondLdbNum, 1, static_cast<ET9AWInputMode>(eInputMode));
+
+ //XT9_API(ET9AWClearNextWordPrediction, &sLingInfo);
+ XT9_API(ET9AWClearAutoAppendInList, &sLingInfo);
+
+ return !eStatus;
+}
+
+void Xt9AwIme::setLdbEnabled(bool enabled)
+{
+ XT9_API(ET9AWEnableDBs, &sLingInfo, ET9ALLDBMASK);
+
+ if (!enabled)
+ XT9_API(ET9AWDisableDBs, &sLingInfo, ET9STATELDBENABLEDMASK);
+}
+
+qint64 Xt9AwIme::dlmPreferredSize() const
+{
+ return ET9AWDLM_SIZE_NORMAL;
+}
+
+bool Xt9AwIme::dlmInit(void *data, qint64 size)
+{
+ ET9STATUS eStatus;
+
+ eStatus = XT9_API(ET9AWDLMInit, &sLingInfo, static_cast<_ET9DLM_info *>(data), static_cast<ET9U32>(size), nullptr);
+
+ return !eStatus;
+}
+
+QStringList Xt9AwIme::buildSelectionList(int *defaultListIndex, ET9U16 *gestureValue)
+{
+ ET9STATUS eStatus;
+ ET9U8 totalWords;
+ ET9U8 listIndex;
+
+ eStatus = XT9_API(ET9AWSelLstBuild, &sLingInfo, &totalWords, &listIndex, gestureValue);
+
+ if (defaultListIndex)
+ *defaultListIndex = listIndex == ET9_NO_ACTIVE_INDEX || exactWord().isEmpty() ? -1 : static_cast<int>(listIndex);
+
+ if (eStatus)
+ return QStringList();
+
+ QStringList list;
+ for (ET9U8 i = 0; i < totalWords; ++i) {
+ ET9AWWordInfo *wordInfo = nullptr;
+ eStatus = ET9AWSelLstGetWord(&sLingInfo, &wordInfo, i);
+ if (eStatus || !wordInfo)
+ return QStringList();
+
+ const QString word = QString::fromUtf16(reinterpret_cast<const char16_t *>(wordInfo->sWord), wordInfo->wWordLen);
+
+ list.append(word);
+ }
+
+ return list;
+}
+
+void Xt9AwIme::selectWord(int index, bool isUserExplicitChoice)
+{
+ if (index < 0)
+ return;
+
+ qCDebug(lcXT9) << "selectWord" << index;
+
+ XT9_API(ET9AWSelLstSelWord, &sLingInfo, static_cast<ET9U8>(index), isUserExplicitChoice);
+}
+
+void Xt9AwIme::noteWordDone(const QString &word)
+{
+ XT9_API(ET9AWNoteWordDone, &sLingInfo, word.utf16(), static_cast<ET9U32>(word.length()), 0);
+}
+
+ET9STATUS Xt9AwIme::ET9AWLdbReadData(ET9AWLingInfo *pLingInfo, ET9U8 *ET9FARDATA *ppbSrc, ET9U32 *pdwSizeInBytes)
+{
+ return reinterpret_cast<Xt9AwIme *>(pLingInfo->pPublicExtension)->ldbReadData(pLingInfo->pLingCmnInfo->dwLdbNum, ppbSrc, pdwSizeInBytes);
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
diff --git a/src/plugins/cerence/xt9/xt9common/xt9awime.h b/src/plugins/cerence/xt9/xt9common/xt9awime.h
new file mode 100644
index 00000000..5a1c688f
--- /dev/null
+++ b/src/plugins/cerence/xt9/xt9common/xt9awime.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XT9AWIME_H
+#define XT9AWIME_H
+
+#include "xt9ime.h"
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+class Xt9AwIme : public Xt9Ime
+{
+public:
+ Xt9AwIme(Xt9RequestCallback *requestCallback, Xt9KeyboardGenerator::CodeConverter *codeConverter = nullptr);
+
+ void sysInit() override;
+ bool ldbInit(ET9U32 dwFirstLdbNum, ET9U32 dwSecondLdbNum = ET9PLIDNone, ET9U32 eInputMode = 0) override;
+ void setLdbEnabled(bool enabled);
+ qint64 dlmPreferredSize() const override;
+ bool dlmInit(void *data, qint64 size) override;
+
+ QStringList buildSelectionList(int *defaultListIndex, ET9U16 *gestureValue) override;
+ void selectWord(int index, bool isUserExplicitChoice);
+
+ void noteWordDone(const QString &word);
+
+private:
+ static ET9STATUS ET9AWLdbReadData(ET9AWLingInfo *pLingInfo, ET9U8 *ET9FARDATA *ppbSrc, ET9U32 *pdwSizeInBytes);
+
+public:
+ ET9AWLingInfo sLingInfo;
+ ET9AWLingCmnInfo sLingCmnInfo;
+};
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
+
+#endif // XT9AWIME_H
diff --git a/src/plugins/cerence/xt9/xt9common/xt9callbacks.h b/src/plugins/cerence/xt9/xt9common/xt9callbacks.h
new file mode 100644
index 00000000..d3c5c3fb
--- /dev/null
+++ b/src/plugins/cerence/xt9/xt9common/xt9callbacks.h
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XT9CPALLBACKS_H
+#define XT9CPALLBACKS_H
+
+#include <et9api.h>
+#include <QtGlobal>
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+class Xt9RequestCallback {
+public:
+ virtual ET9STATUS request(ET9_Request *const pRequest) = 0;
+};
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
+
+#endif // XT9CPALLBACKS_H
diff --git a/src/plugins/cerence/xt9/xt9common/xt9cpime.cpp b/src/plugins/cerence/xt9/xt9common/xt9cpime.cpp
new file mode 100644
index 00000000..17ae0526
--- /dev/null
+++ b/src/plugins/cerence/xt9/xt9common/xt9cpime.cpp
@@ -0,0 +1,311 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xt9cpime.h"
+#include "xt9languagemap.h"
+#include "xt9dbfile.h"
+#include "xt9callbacks.h"
+#include <QStandardPaths>
+#include <QLoggingCategory>
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+static const ET9SYMB CANGJIE_MAP[] = {
+ 0x65E5, 0x6708, 0x91D1, 0x6728, 0x6C34, 0x706B, 0x571F, 0x7AF9, 0x6208,
+ 0x5341, 0x5927, 0x4E2D, 0x4E00, 0x5F13, 0x4EBA, 0x5FC3, 0x624B, 0x53E3,
+ 0x5C38, 0x5EFF, 0x5C71, 0x5973, 0x7530, 0x96E3, 0x535C };
+static const size_t CANGJIE_MAP_SIZE = sizeof(CANGJIE_MAP) / sizeof(ET9SYMB);
+static const ET9SYMB CANGJIE_WILDCARD_SYMB = 0x91CD;
+
+static ET9SYMB GetCangjieMappingSymb(ET9SYMB symb)
+{
+ if (symb == CANGJIE_WILDCARD_SYMB)
+ return ET9CPCANGJIEWILDCARD;
+
+ for (size_t i = 0; i < CANGJIE_MAP_SIZE; i++) {
+ if (CANGJIE_MAP[i] == symb)
+ return static_cast<ET9SYMB>(i + 'a');
+ }
+
+ return symb;
+}
+
+static ET9SYMB GetCangjieSymb(ET9SYMB symb)
+{
+ if (symb == ET9CPCANGJIEWILDCARD)
+ return CANGJIE_WILDCARD_SYMB;
+
+ if (ET9CPIsCangJieLowerSymbol(symb))
+ return CANGJIE_MAP[symb - 'a'];
+
+ if (ET9CPIsCangJieUpperSymbol(symb))
+ return CANGJIE_MAP[symb - 'A'];
+
+ return symb;
+}
+
+class CangjieConverter : public Xt9KeyboardGenerator::CodeConverter {
+public:
+ QString convertTo(const QString &codes) const override
+ {
+ QVector<ushort> cangjieBuf(codes.size());
+ for (int i = 0; i < codes.size(); ++i) {
+ cangjieBuf[i] = GetCangjieSymb(codes.at(i).unicode());
+ }
+ return QString::fromUtf16(reinterpret_cast<const char16_t *>(cangjieBuf.constData()), cangjieBuf.length());
+ }
+
+ QString convertFrom(const QString &codes) const override
+ {
+ QVector<ushort> cangjieBuf(codes.size());
+ for (int i = 0; i < codes.size(); ++i) {
+ cangjieBuf[i] = GetCangjieMappingSymb(codes.at(i).unicode());
+ }
+ return QString::fromUtf16(reinterpret_cast<const char16_t *>(cangjieBuf.constData()), cangjieBuf.length());
+ }
+};
+
+Q_GLOBAL_STATIC(CangjieConverter, cangjieConverter)
+
+Xt9CpIme::Xt9CpIme(Xt9RequestCallback *requestCallback) :
+ Xt9Ime(requestCallback)
+{
+}
+
+Xt9KeyboardGenerator::CodeConverter *Xt9CpIme::getCangjieConverter()
+{
+ return cangjieConverter;
+}
+
+void Xt9CpIme::sysInit()
+{
+ Xt9Ime::sysInit();
+ memset(&sLingInfo, 0, sizeof(sLingInfo));
+ XT9_API(ET9CPSysInit, &sLingInfo, &sWordSymbInfo, this);
+}
+
+bool Xt9CpIme::ldbInit(ET9U32 dwFirstLdbNum, ET9U32 dwSecondLdbNum, ET9U32 eInputMode)
+{
+ ET9STATUS eStatus;
+ Q_UNUSED(dwSecondLdbNum)
+
+ eStatus = XT9_API(ET9CPLdbInit, &sLingInfo, dwFirstLdbNum, &ET9CPLdbReadData);
+ if (!eStatus) {
+ XT9_API(ET9CPSetInputMode, &sLingInfo, static_cast<ET9CPMode>(eInputMode));
+ XT9_API(ET9CPClearComponent, &sLingInfo);
+ XT9_API(ET9CPSetBilingual, &sLingInfo);
+ }
+
+ return !eStatus;
+}
+
+qint64 Xt9CpIme::dlmPreferredSize() const
+{
+ return ET9CPDLM_SIZE_NORMAL;
+}
+
+bool Xt9CpIme::dlmInit(void *data, qint64 size)
+{
+ ET9STATUS eStatus;
+
+ eStatus = XT9_API(ET9CPDLMInit, &sLingInfo, static_cast<ET9CPDLM_info *>(data), static_cast<ET9U32>(size), nullptr);
+
+ return !eStatus;
+}
+
+QString Xt9CpIme::exactWord(int *wordCompLen)
+{
+ QString exactWord = Xt9Ime::exactWord(wordCompLen);
+
+ ET9CPPhrase phrase;
+ ET9CPSpell spell;
+ ET9U8 selSymbCount = 0;
+ if (!ET9CPGetSelection(&sLingInfo, &phrase, &spell, &selSymbCount) && selSymbCount)
+ exactWord.remove(0, static_cast<int>(selSymbCount));
+
+ replaceSpecialSymbol(exactWord);
+
+ return exactWord;
+}
+
+void Xt9CpIme::replaceSpecialSymbol(QString &exactWord) const
+{
+ for (int i = 0; i < exactWord.length(); ++i) {
+ ET9SYMB symb = exactWord.at(i).unicode();
+ if (ET9CPSymToCPTone(symb)) {
+ exactWord.replace(i, 1, QChar(symb - ET9CPTONE1 + '1'));
+ } else if (ET9CPIsStrokeSymbol(symb)) {
+ int strokeIndex = symb - ET9CPSTROKE1;
+ static const ushort STROKE_TABLE[ET9CPSTROKEWILDCARD - ET9CPSTROKE1 + 1] = {
+ 0x4E00,
+ 0x4E28,
+ 0x4E3F,
+ 0x4E36,
+ 0x4E5B,
+ '*'
+ };
+ exactWord.replace(i, 1, QChar(STROKE_TABLE[strokeIndex]));
+ }
+ }
+}
+
+QString Xt9CpIme::spell()
+{
+ ET9STATUS eStatus;
+ ET9CPSpell spell;
+
+ eStatus = XT9_API(ET9CPGetSpell, &sLingInfo, &spell);
+ if (eStatus == ET9STATUS_NEED_SELLIST_BUILD) {
+ ET9U16 gestureValue;
+ eStatus = XT9_API(ET9CPBuildSelectionList, &sLingInfo, &gestureValue);
+ if (eStatus)
+ return QString();
+
+ eStatus = XT9_API(ET9CPGetSpell, &sLingInfo, &spell);
+ if (eStatus)
+ return QString();
+ } else if (eStatus) {
+ return QString();
+ }
+
+ QString result = QString::fromUtf16(reinterpret_cast<const char16_t *>(spell.pSymbs), spell.bLen);
+
+ replaceSpecialSymbol(result);
+
+ return result;
+}
+
+QStringList Xt9CpIme::buildSelectionList(int *defaultListIndex, ET9U16 *gestureValue)
+{
+ ET9STATUS eStatus;
+ ET9U16 totalWords;
+
+ eStatus = XT9_API(ET9CPBuildSelectionList, &sLingInfo, gestureValue);
+
+ if (defaultListIndex)
+ *defaultListIndex = -1;
+
+ if (eStatus)
+ return QStringList();
+
+ eStatus = XT9_API(ET9CPGetPhraseCount, &sLingInfo, &totalWords);
+
+ if (defaultListIndex && totalWords > 0 && !exactWord().isEmpty())
+ *defaultListIndex = 0;
+
+ QStringList list;
+ for (ET9U16 i = 0; i < totalWords; ++i) {
+ ET9CPPhrase phrase;
+ ET9CPSpell spell;
+ ET9CPPhraseSource phraseSource;
+ eStatus = ET9CPGetPhrase(&sLingInfo, i, &phrase, &spell, &phraseSource);
+ if (eStatus)
+ return QStringList();
+
+ const QString word = QString::fromUtf16(reinterpret_cast<const char16_t *>(phrase.pSymbs), phrase.bLen);
+
+ list.append(word);
+ }
+
+ return list;
+}
+
+ET9STATUS Xt9CpIme::selectWord(int index)
+{
+ ET9CPPhrase phrase;
+ ET9CPSpell spell;
+ ET9CPPhraseSource phraseSource;
+ ET9STATUS eStatus;
+
+ qCDebug(lcXT9) << "selectWord" << index;
+
+ eStatus = XT9_API(ET9CPGetPhrase, &sLingInfo, static_cast<ET9U16>(index), &phrase, &spell, &phraseSource);
+ if (!eStatus) {
+ eStatus = XT9_API(ET9CPSelectPhrase, &sLingInfo, static_cast<ET9U16>(index), &spell);
+ }
+
+ return eStatus;
+}
+
+void Xt9CpIme::cursorMoved()
+{
+ const ET9U32 maxBufLen = 456;
+ ET9SYMB buffer[maxBufLen];
+ ET9_Request request;
+
+ request.eType = ET9_REQ_BufferContext;
+ request.data.sBufferContextInfo.psBuf = buffer;
+ request.data.sBufferContextInfo.dwMaxBufLen = maxBufLen;
+ request.data.sBufferContextInfo.dwBufLen = static_cast<ET9U32>(-1);
+
+ _requestCallback->request(&request);
+
+ if (request.data.sBufferContextInfo.dwBufLen != static_cast<ET9U32>(-1))
+ ET9CPSetContext(&sLingInfo, request.data.sBufferContextInfo.psBuf, request.data.sBufferContextInfo.dwBufLen);
+ else
+ ET9CPSetContext(&sLingInfo, request.data.sBufferContextInfo.psBuf, 0);
+}
+
+void Xt9CpIme::commitSelection()
+{
+ XT9_API(ET9CPCommitSelection, &sLingInfo);
+}
+
+ET9SYMB Xt9CpIme::lastSymb()
+{
+ const QString word = Xt9Ime::exactWord();
+ const int wordLength = word.length();
+ return wordLength > 0 ? word.at(wordLength - 1).unicode() : 0;
+}
+
+bool Xt9CpIme::addTone(ET9CPSYMB symb)
+{
+ ET9STATUS eStatus;
+
+ eStatus = XT9_API(ET9AddExplicitSymb, sLingInfo.Base.pWordSymbInfo, symb, 0, ET9NOSHIFT, ET9_NO_ACTIVE_INDEX);
+ if (eStatus)
+ return false;
+
+ eStatus = XT9_API(ET9CPBuildSelectionList, &sLingInfo, nullptr);
+ if (eStatus) {
+ XT9_API(ET9ClearOneSymb, sLingInfo.Base.pWordSymbInfo);
+ return false;
+ }
+
+ return true;
+}
+
+ET9STATUS Xt9CpIme::ET9CPLdbReadData(ET9CPLingInfo *pLingInfo, ET9U8 *ET9FARDATA *ppbSrc, ET9U32 *pdwSizeInBytes)
+{
+ return reinterpret_cast<Xt9CpIme *>(pLingInfo->pPublicExtension)->ldbReadData(pLingInfo->dwLdbNum, ppbSrc, pdwSizeInBytes);
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
diff --git a/src/plugins/cerence/xt9/xt9common/xt9cpime.h b/src/plugins/cerence/xt9/xt9common/xt9cpime.h
new file mode 100644
index 00000000..8aa6e7ca
--- /dev/null
+++ b/src/plugins/cerence/xt9/xt9common/xt9cpime.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XT9CPIME_H
+#define XT9CPIME_H
+
+#include "xt9ime.h"
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+class Xt9CpIme : public Xt9Ime
+{
+public:
+ Xt9CpIme(Xt9RequestCallback *requestCallback);
+
+ static Xt9KeyboardGenerator::CodeConverter *getCangjieConverter();
+
+ void sysInit() override;
+ bool ldbInit(ET9U32 dwFirstLdbNum, ET9U32 dwSecondLdbNum = ET9PLIDNone, ET9U32 eInputMode = 0) override;
+ qint64 dlmPreferredSize() const override;
+ bool dlmInit(void *data, qint64 size) override;
+
+ QString exactWord(int *wordCompLen = nullptr) override;
+ void replaceSpecialSymbol(QString &exactWord) const;
+ QString spell();
+ QStringList buildSelectionList(int *defaultListIndex, ET9U16 *gestureValue) override;
+ ET9STATUS selectWord(int index);
+
+ void cursorMoved() override;
+
+ void commitSelection();
+
+ ET9SYMB lastSymb();
+ bool addTone(ET9CPSYMB symb);
+
+private:
+ static ET9STATUS ET9CPLdbReadData(ET9CPLingInfo *pLingInfo, ET9U8 *ET9FARDATA *ppbSrc, ET9U32 *pdwSizeInBytes);
+
+public:
+ ET9CPLingInfo sLingInfo;
+};
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
+
+#endif // XT9CPIME_H
diff --git a/src/plugins/cerence/xt9/xt9common/xt9ime.cpp b/src/plugins/cerence/xt9/xt9common/xt9ime.cpp
new file mode 100644
index 00000000..93c50bd3
--- /dev/null
+++ b/src/plugins/cerence/xt9/xt9common/xt9ime.cpp
@@ -0,0 +1,324 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xt9ime.h"
+#include "xt9callbacks.h"
+#include "xt9languagemap.h"
+#include "xt9dbfile.h"
+#include <QStandardPaths>
+#include <QDir>
+#include <QLoggingCategory>
+#include <QtVirtualKeyboard/qvirtualkeyboarddictionarymanager.h>
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+Q_LOGGING_CATEGORY(lcXT9, "qt.virtualkeyboard.xt9")
+
+Xt9Ime::Xt9Ime(Xt9RequestCallback *requestCallback, Xt9KeyboardGenerator::CodeConverter *codeConverter) :
+ _requestCallback(requestCallback),
+ codeConverter(codeConverter)
+{
+}
+
+void Xt9Ime::sysInit()
+{
+ if (!ldbManager)
+ ldbManager.reset(new Xt9LdbManager());
+ memset(&sWordSymbInfo, 0, sizeof(sWordSymbInfo));
+ memset(&sKdbInfo, 0, sizeof(sKdbInfo));
+ memset(&sSearchEngine, 0, sizeof(sSearchEngine));
+ XT9_API(ET9WordSymbInit, &sWordSymbInfo, 1, ET9Request, this);
+ XT9_API(ET9NAV_Init, &sSearchEngine, &sWordSymbInfo);
+}
+
+bool Xt9Ime::kdbInit(const QVariantMap &vkbLayout)
+{
+ ET9STATUS eStatus;
+
+ keyboardGenerator.reset(new Xt9KeyboardGenerator(vkbLayout, codeConverter));
+
+ const ET9U32 dwFirstKdbNum = static_cast<ET9U32>(vkbLayout[Xt9KeyboardGenerator::PRIMARY_ID].toInt());
+
+ eStatus = XT9_API(ET9KDB_Init,
+ &sKdbInfo,
+ &sWordSymbInfo,
+ dwFirstKdbNum,
+ 0,
+ &ET9KDBLoad,
+ &ET9KDBRequest,
+ this);
+
+ return !eStatus;
+}
+
+void Xt9Ime::uninit()
+{
+ clearInput();
+ keyboardGenerator.reset();
+ ldbManager->closeAll();
+ sysInit();
+}
+
+QString Xt9Ime::exactWord(int *wordCompLen)
+{
+ ET9SimpleWord simpleWord;
+ ET9STATUS eStatus;
+
+ eStatus = XT9_API(ET9GetExactWord, &sWordSymbInfo, &simpleWord);
+ if (eStatus) {
+ if (wordCompLen)
+ *wordCompLen = 0;
+ return QString();
+ }
+
+ if (wordCompLen)
+ *wordCompLen = simpleWord.wCompLen;
+
+ return QString::fromUtf16(reinterpret_cast<const char16_t *>(simpleWord.sString), simpleWord.wLen);
+}
+
+bool Xt9Ime::hasActiveInput() const
+{
+ return ET9HasActiveInput(&sWordSymbInfo);
+}
+
+void Xt9Ime::cursorMoved()
+{
+ XT9_API(ET9CursorMoved, &sWordSymbInfo, 1);
+}
+
+void Xt9Ime::clearInput()
+{
+ XT9_API(ET9ClearAllSymbs, &sWordSymbInfo);
+}
+
+void Xt9Ime::setCapsLock()
+{
+ XT9_API(ET9SetCapsLock, &sWordSymbInfo);
+}
+
+void Xt9Ime::setShift()
+{
+ XT9_API(ET9SetShift, &sWordSymbInfo);
+}
+
+void Xt9Ime::setUnShift()
+{
+ XT9_API(ET9SetUnShift, &sWordSymbInfo);
+}
+
+void Xt9Ime::setWorkingDirectory(const QString &workingDirectory)
+{
+ QString dir = workingDirectory;
+ if (!workingDirectory.isEmpty() && !dir.endsWith(QLatin1Char('/')))
+ dir.append(QLatin1Char('/'));
+ dir = QDir::toNativeSeparators(dir);
+ XT9_API(ET9NAVCore_SetWorkingDirectory, &sSearchEngine, dir.toUtf8().constData());
+}
+
+bool Xt9Ime::indexExists(quint16 id)
+{
+ ET9BOOL exists = 0;
+
+ XT9_API(ET9NAVCore_IndexExists, &sSearchEngine, id, &exists);
+
+ return exists != 0;
+}
+
+bool Xt9Ime::createIndex(quint16 id, quint32 contentInfo)
+{
+ ET9STATUS eStatus;
+ ET9NAVTypeInfo sTypeInfo;
+
+ if (indexExists(id)) {
+ removeIndex(id);
+ }
+
+ eStatus = XT9_API(ET9NAVTypeInfo_Init, &sTypeInfo, id, ET9NAVNO_RECORD_KEY_LENGTH, 0, ET9NAVSTORE_DISPLAY_STR_IN_INDEX);
+ if (!eStatus) {
+ eStatus = XT9_API(ET9NAVCore_CreateIndex, &sSearchEngine, id, &sTypeInfo, 1, contentInfo, 0);
+ }
+
+ return !eStatus;
+}
+
+bool Xt9Ime::insertRecord(quint16 id, const QString &phrase, const QString &tokens)
+{
+ ET9STATUS eStatus;
+ ET9NAVRecord sRecord;
+
+ eStatus = XT9_API(ET9NAVRecord_Init_NoKey, &sSearchEngine, &sRecord, id);
+ if (!eStatus) {
+ if (tokens.length() > 0) {
+ eStatus = XT9_API(ET9NAVRecord_AddField_Conversion, &sRecord,
+ static_cast<const ET9SYMB *>(tokens.utf16()),
+ static_cast<quint16>(tokens.length()),
+ static_cast<const ET9SYMB *>(phrase.utf16()),
+ static_cast<quint16>(phrase.length()),
+ ET9NAVMATCHLOGIC_ANY);
+ } else {
+ eStatus = XT9_API(ET9NAVRecord_AddField_16BIT, &sRecord,
+ static_cast<const ET9SYMB *>(phrase.utf16()),
+ static_cast<quint16>(phrase.length()),
+ ET9NAVMATCHLOGIC_ANY);
+ }
+
+ if (!eStatus) {
+ eStatus = XT9_API(ET9NAVCore_InsertRecord, &sSearchEngine, &sRecord);
+ }
+ }
+
+ return !eStatus;
+}
+
+void Xt9Ime::finalizeIndex(quint16 id)
+{
+ XT9_API(ET9NAVCore_FinalizeIndex, &sSearchEngine, id);
+}
+
+void Xt9Ime::updateIndex(quint16 id, const QStringList &wordList)
+{
+ createIndex(id);
+ for (const QString &word : wordList) {
+ insertRecord(id, word);
+ }
+ finalizeIndex(id);
+}
+
+void Xt9Ime::removeIndex(quint16 id)
+{
+ XT9_API(ET9NAVCore_RemoveIndex, &sSearchEngine, id);
+}
+
+void Xt9Ime::removeAllIndexes()
+{
+ XT9_API(ET9NAVCore_RemoveAllIndexes, &sSearchEngine);
+}
+
+void Xt9Ime::mountIndex(quint16 id)
+{
+ XT9_API(ET9NAVCore_MountIndex, &sSearchEngine, id, ET9NAVMountProperty_ReadOnlyNoValidation);
+}
+
+void Xt9Ime::unmountIndex(quint16 id)
+{
+ XT9_API(ET9NAVCore_UnmountIndex, &sSearchEngine, id);
+}
+
+ET9STATUS Xt9Ime::ldbReadData(ET9U32 dwLdbNum, ET9U8 *ET9FARDATA *ppbSrc, ET9U32 *pdwSizeInBytes)
+{
+ const QLocale locale = Xt9LanguageMap::locale(dwLdbNum);
+ if (locale.language() == QLocale::AnyLanguage) {
+ return ET9STATUS_READ_DB_FAIL;
+ }
+
+ const void *data;
+ qint64 size;
+ if (!ldbManager->loadDictionary(locale, data, size)) {
+ return ET9STATUS_READ_DB_FAIL;
+ }
+
+ *ppbSrc = static_cast<ET9U8 *>(const_cast<void *>(data));
+ *pdwSizeInBytes = static_cast<ET9U32>(size);
+
+ return ET9STATUS_NONE;
+}
+
+ET9STATUS Xt9Ime::ET9Request(ET9WordSymbInfo *const pWordSymbInfo, ET9_Request *const pRequest)
+{
+ return reinterpret_cast<Xt9Ime *>(pWordSymbInfo->pPublicExtension)->request(pRequest);
+}
+
+ET9STATUS Xt9Ime::request(ET9_Request *const pRequest)
+{
+#ifdef XT9_DEBUG
+ qCDebug(lcXT9) << "ET9Request, type =" << pRequest->eType;
+#endif
+ return _requestCallback->request(pRequest);
+}
+
+ET9STATUS Xt9Ime::ET9KDBLoad(ET9KDBInfo *const pKdbInfo, const ET9U32 dwKdbNum, const ET9U16 wPageNum)
+{
+ return reinterpret_cast<Xt9Ime *>(pKdbInfo->pPublicExtension)->kdbLoad(dwKdbNum, wPageNum);
+}
+
+ET9STATUS Xt9Ime::kdbLoad(const ET9U32 dwKdbNum, const ET9U16 wPageNum)
+{
+ Q_UNUSED(dwKdbNum)
+
+ ET9STATUS eStatus;
+ ET9UINT nErrorLine = 0;
+
+ if (keyboardGenerator->vkbLayout.isEmpty()) {
+ qCWarning(lcXT9) << "Keyboard layout is not set.";
+ return ET9STATUS_READ_DB_FAIL;
+ }
+
+ QByteArray xmlData = keyboardGenerator->createXmlLayout();
+ if (xmlData.isEmpty()) {
+ qCWarning(lcXT9) << "Failed to create xml layout.";
+ return ET9STATUS_READ_DB_FAIL;
+ }
+
+ eStatus = XT9_API(ET9KDB_Load_XmlKDB,
+ &sKdbInfo,
+ static_cast<ET9U16>(qRound(keyboardGenerator->layoutWidth)),
+ static_cast<ET9U16>(qRound(keyboardGenerator->layoutHeight)),
+ wPageNum,
+ reinterpret_cast<const ET9U8 *>(xmlData.constData()),
+ static_cast<ET9U32>(xmlData.size()),
+ nullptr,
+ nullptr,
+ &nErrorLine);
+
+ if (eStatus) {
+ qCWarning(lcXT9).nospace() << "Failed to load xml layout, status: " << eStatus << ", line: " << nErrorLine;
+ qCWarning(lcXT9).nospace().noquote() << xmlData.constData();
+ }
+
+ return eStatus;
+}
+
+ET9STATUS Xt9Ime::ET9KDBRequest(ET9KDBInfo *const pKDBInfo, ET9WordSymbInfo *const pWordSymbInfo, ET9KDB_Request *const pET9KDB_Request)
+{
+ Q_UNUSED(pWordSymbInfo)
+ return reinterpret_cast<Xt9Ime *>(pKDBInfo->pPublicExtension)->kdbRequest(pET9KDB_Request);
+}
+
+ET9STATUS Xt9Ime::kdbRequest(ET9KDB_Request *const pET9KDB_Request)
+{
+#ifdef XT9_DEBUG
+ qCDebug(lcXT9) << "ET9KDB_Request, type =" << pET9KDB_Request->eType;
+#endif
+ return ET9STATUS_NONE;
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
diff --git a/src/plugins/cerence/xt9/xt9common/xt9ime.h b/src/plugins/cerence/xt9/xt9common/xt9ime.h
new file mode 100644
index 00000000..759898ad
--- /dev/null
+++ b/src/plugins/cerence/xt9/xt9common/xt9ime.h
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XT9IME_H
+#define XT9IME_H
+
+#include <QtGlobal>
+#include <QVariantMap>
+#include <QLoggingCategory>
+#include <et9api.h>
+#include "xt9keyboardgenerator.h"
+#include "xt9ldbmanager.h"
+#include "xt9dbfile.h"
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+Q_DECLARE_LOGGING_CATEGORY(lcXT9)
+
+#ifdef XT9_DEBUG
+inline ET9STATUS xt9_log(ET9STATUS eStatus, const char *funcName) {
+ if (eStatus)
+ qCWarning(lcXT9) << funcName << "->" << eStatus;
+ else
+ qCDebug(lcXT9) << funcName;
+ return eStatus;
+}
+inline ET9STATUS xt9_nolog(ET9STATUS eStatus, const char *funcName) {
+ if (eStatus)
+ qCWarning(lcXT9) << funcName << "->" << eStatus;
+ return eStatus;
+}
+#else
+#define xt9_log(func, funcName) func
+#define xt9_nolog(func, funcName) func
+#endif
+
+#define XT9_API(FUNC_NAME, ...) \
+ xt9_log(FUNC_NAME(__VA_ARGS__), "" # FUNC_NAME)
+#define XT9_VAPI(FUNC_NAME, ...) \
+ xt9_nolog(FUNC_NAME(__VA_ARGS__), "" # FUNC_NAME)
+
+class Xt9RequestCallback;
+
+class Xt9Ime
+{
+public:
+ Xt9Ime(Xt9RequestCallback *requestCallback, Xt9KeyboardGenerator::CodeConverter *codeConverter = nullptr);
+ virtual ~Xt9Ime() {}
+
+ virtual void sysInit();
+ virtual bool ldbInit(ET9U32 dwFirstLdbNum, ET9U32 dwSecondLdbNum = ET9PLIDNone, ET9U32 eInputMode = 0) = 0;
+ virtual qint64 dlmPreferredSize() const = 0;
+ virtual bool dlmInit(void *data, qint64 size) = 0;
+ bool kdbInit(const QVariantMap &vkbLayout);
+
+ virtual void uninit();
+
+ virtual QString exactWord(int *wordCompLen = nullptr);
+ bool hasActiveInput() const;
+ virtual QStringList buildSelectionList(int *defaultListIndex, ET9U16 *gestureValue) = 0;
+ virtual void cursorMoved();
+ void clearInput();
+ void setCapsLock();
+ void setShift();
+ void setUnShift();
+
+ void setWorkingDirectory(const QString &workingDirectory);
+ bool indexExists(quint16 id);
+ bool createIndex(quint16 id, quint32 contentInfo = ET9_ContentInfo_None);
+ bool insertRecord(quint16 id, const QString &phrase, const QString &tokens = QString());
+ void finalizeIndex(quint16 id);
+ void updateIndex(quint16 id, const QStringList &wordList);
+ void removeIndex(quint16 id);
+ void removeAllIndexes();
+ void mountIndex(quint16 id);
+ void unmountIndex(quint16 id);
+
+protected:
+ ET9STATUS ldbReadData(ET9U32 dwLdbNum, ET9U8 *ET9FARDATA *ppbSrc, ET9U32 *pdwSizeInBytes);
+
+private:
+ static ET9STATUS ET9Request(ET9WordSymbInfo *const pWordSymbInfo, ET9_Request *const pRequest);
+ ET9STATUS request(ET9_Request *const pRequest);
+
+ static ET9STATUS ET9KDBLoad(ET9KDBInfo *const pKdbInfo, const ET9U32 dwKdbNum, const ET9U16 wPageNum);
+ ET9STATUS kdbLoad(const ET9U32 dwKdbNum, const ET9U16 wPageNum);
+
+ static ET9STATUS ET9KDBRequest(ET9KDBInfo *const pKDBInfo, ET9WordSymbInfo *const pWordSymbInfo, ET9KDB_Request *const pET9KDB_Request);
+ ET9STATUS kdbRequest(ET9KDB_Request *const pET9KDB_Request);
+
+public:
+ ET9WordSymbInfo sWordSymbInfo;
+ ET9KDBInfo sKdbInfo;
+ ET9NAVInfo sSearchEngine;
+ Xt9RequestCallback *const _requestCallback;
+ const Xt9KeyboardGenerator::CodeConverter *codeConverter;
+ QSharedPointer<Xt9LdbManager> ldbManager;
+
+protected:
+ QScopedPointer<Xt9KeyboardGenerator> keyboardGenerator;
+};
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
+
+#endif // XT9IME_H
diff --git a/src/plugins/cerence/xt9/xt9common/xt9jime.cpp b/src/plugins/cerence/xt9/xt9common/xt9jime.cpp
new file mode 100644
index 00000000..6cb3aed6
--- /dev/null
+++ b/src/plugins/cerence/xt9/xt9common/xt9jime.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xt9jime.h"
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+class KanaConverter : public Xt9KeyboardGenerator::CodeConverter {
+public:
+ QString convertTo(const QString &codes) const override
+ {
+ QString buf(codes);
+ for (int i = 0; i < buf.length(); ++i) {
+ const ushort uc = buf.at(i).unicode();
+ if ((uc >= 0x30a1 && uc <= 0x30f6) || uc == 0x30fd || uc == 0x30fe)
+ buf.replace(i, 1, QChar(uc - 0x0060));
+ }
+ return buf;
+ }
+
+ QString convertFrom(const QString &codes) const override
+ {
+ QString buf(codes);
+ for (int i = 0; i < buf.length(); ++i) {
+ const ushort uc = buf.at(i).unicode();
+ if ((uc >= 0x30a1 && uc <= 0x30f6) || uc == 0x30fd || uc == 0x30fe)
+ buf.replace(i, 1, QChar(uc + 0x0060));
+ }
+ return buf;
+ }
+};
+
+Q_GLOBAL_STATIC(KanaConverter, kanaConverter)
+
+Xt9JIme::Xt9JIme(Xt9RequestCallback *requestCallback) :
+ Xt9AwIme(requestCallback, kanaConverter)
+{
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
diff --git a/src/plugins/cerence/xt9/xt9common/xt9jime.h b/src/plugins/cerence/xt9/xt9common/xt9jime.h
new file mode 100644
index 00000000..f0eb4056
--- /dev/null
+++ b/src/plugins/cerence/xt9/xt9common/xt9jime.h
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XT9JIME_H
+#define XT9JIME_H
+
+#include "xt9awime.h"
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+class Xt9JIme : public Xt9AwIme
+{
+public:
+ Xt9JIme(Xt9RequestCallback *requestCallback);
+};
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
+
+#endif // XT9JIME_H
diff --git a/src/plugins/cerence/xt9/xt9common/xt9kdb.cpp b/src/plugins/cerence/xt9/xt9common/xt9kdb.cpp
new file mode 100644
index 00000000..57878cea
--- /dev/null
+++ b/src/plugins/cerence/xt9/xt9common/xt9kdb.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xt9kdb.h"
+#include <QXmlStreamWriter>
+#include <QBuffer>
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+QByteArray Xt9Kdb::generate(const Xt9KdbLayout &layout, bool prettyPrint)
+{
+ QByteArray result;
+ QXmlStreamWriter writer(&result);
+
+ writer.setAutoFormatting(prettyPrint);
+ writer.writeStartDocument();
+ layout.serialize(writer);
+ writer.writeEndDocument();
+
+ return result;
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
diff --git a/src/plugins/cerence/xt9/xt9common/xt9kdb.h b/src/plugins/cerence/xt9/xt9common/xt9kdb.h
new file mode 100644
index 00000000..4e3aeeb9
--- /dev/null
+++ b/src/plugins/cerence/xt9/xt9common/xt9kdb.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XT9KDB_H
+#define XT9KDB_H
+
+#include "xt9kdblayout.h"
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+class Xt9Kdb
+{
+ Q_DISABLE_COPY(Xt9Kdb)
+
+public:
+ static QByteArray generate(const Xt9KdbLayout &layout, bool prettyPrint = false);
+};
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
+
+#endif // XT9KDBGENERATOR_H
diff --git a/src/plugins/cerence/xt9/xt9common/xt9kdbarea.cpp b/src/plugins/cerence/xt9/xt9common/xt9kdbarea.cpp
new file mode 100644
index 00000000..0d99ee2f
--- /dev/null
+++ b/src/plugins/cerence/xt9/xt9common/xt9kdbarea.cpp
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xt9kdbarea.h"
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+void Xt9KdbArea::serialize(QXmlStreamWriter &writer) const
+{
+ writer.writeStartElement(QStringLiteral("area"));
+ if (!conditionValue.isEmpty())
+ writer.writeAttribute(QStringLiteral("conditionValue"), conditionValue);
+ for (const Xt9KdbKey &key : keys) {
+ key.serialize(writer);
+ }
+ writer.writeEndElement();
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
diff --git a/src/plugins/cerence/xt9/xt9common/xt9kdbarea.h b/src/plugins/cerence/xt9/xt9common/xt9kdbarea.h
new file mode 100644
index 00000000..b32829aa
--- /dev/null
+++ b/src/plugins/cerence/xt9/xt9common/xt9kdbarea.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XT9KDBAREA_H
+#define XT9KDBAREA_H
+
+#include "xt9kdbelement.h"
+#include "xt9kdbkey.h"
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+class Xt9KdbArea : public Xt9KdbElement
+{
+public:
+ void serialize(QXmlStreamWriter &writer) const;
+
+ QString conditionValue;
+ QList<Xt9KdbKey> keys;
+};
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
+
+#endif // XT9KDBAREA_H
diff --git a/src/plugins/cerence/xt9/xt9common/xt9kdbelement.cpp b/src/plugins/cerence/xt9/xt9common/xt9kdbelement.cpp
new file mode 100644
index 00000000..6dfb913c
--- /dev/null
+++ b/src/plugins/cerence/xt9/xt9common/xt9kdbelement.cpp
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xt9kdbelement.h"
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+Xt9KdbElement::~Xt9KdbElement()
+{
+
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
diff --git a/src/plugins/cerence/xt9/xt9common/xt9kdbelement.h b/src/plugins/cerence/xt9/xt9common/xt9kdbelement.h
new file mode 100644
index 00000000..654b2def
--- /dev/null
+++ b/src/plugins/cerence/xt9/xt9common/xt9kdbelement.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XT9KDBELEMENT_H
+#define XT9KDBELEMENT_H
+
+#include <QXmlStreamWriter>
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+class Xt9KdbElement
+{
+public:
+ virtual ~Xt9KdbElement();
+
+ virtual void serialize(QXmlStreamWriter &writer) const = 0;
+};
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
+
+#endif // XT9KDBELEMENT_H
diff --git a/src/plugins/cerence/xt9/xt9common/xt9kdbkey.cpp b/src/plugins/cerence/xt9/xt9common/xt9kdbkey.cpp
new file mode 100644
index 00000000..af5e42df
--- /dev/null
+++ b/src/plugins/cerence/xt9/xt9common/xt9kdbkey.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xt9kdbkey.h"
+#include <QMetaEnum>
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+static const QString DP_VALUE = QStringLiteral("%1dp");
+static const QString PC_VALUE = QStringLiteral("%1%");
+const QString HEX_VALUE = QStringLiteral("0x%1");
+
+static bool isPrintable(const QString &str)
+{
+ for (const QChar &chr : str) {
+ if (!QChar::isPrint(chr.unicode()))
+ return false;
+ }
+ return true;
+}
+
+Xt9KdbKey::Xt9KdbKey() :
+ type(Type::nonRegional),
+ name(Name::NONE)
+{
+
+}
+
+void Xt9KdbKey::serialize(QXmlStreamWriter &writer) const
+{
+ /* WORKAROUND:
+ *
+ * This workaround generates a key for each alternate key. This ensures that
+ * ET9KDB_ProcessKeyBySymbol finds the key and that ET9KDB_ModifyCurrentKey
+ * works.
+ */
+ if (hackWriteDistinctKeysForAllCodes && !codes.isEmpty()) {
+ Xt9KdbKey tmpKey;
+ tmpKey = *this;
+ tmpKey.hackWriteDistinctKeysForAllCodes = false;
+ tmpKey.codes.clear();
+ tmpKey.codesShifted.clear();
+ if (!absolute.isEmpty()) {
+ tmpKey.absolute.adjust(0, 0, (tmpKey.absolute.width() / (codes.size() + 1)) - tmpKey.absolute.width(), 0);
+ } else if (!relative.isEmpty()) {
+ tmpKey.relative.adjust(0, 0, (tmpKey.relative.width() / (codes.size() + 1)) - tmpKey.relative.width(), 0);
+ }
+ tmpKey.serialize(writer);
+ if (!absolute.isEmpty()) {
+ tmpKey.absolute.adjust(tmpKey.absolute.width(), 0, tmpKey.absolute.width(), 0);
+ } else if (!relative.isEmpty()) {
+ tmpKey.relative.adjust(tmpKey.relative.width(), 0, tmpKey.relative.width(), 0);
+ }
+ for (const QChar &code : codes) {
+ tmpKey.label = code;
+ if (!labelShifted.isEmpty())
+ tmpKey.labelShifted = code.toUpper();
+ tmpKey.serialize(writer);
+ if (!absolute.isEmpty()) {
+ tmpKey.absolute.adjust(tmpKey.absolute.width(), 0, tmpKey.absolute.width(), 0);
+ } else if (!relative.isEmpty()) {
+ tmpKey.relative.adjust(tmpKey.relative.width(), 0, tmpKey.relative.width(), 0);
+ }
+ }
+ return;
+ }
+ /* WORKAROUND END */
+ if (!absolute.isEmpty()) {
+ writer.writeStartElement(QStringLiteral("key"));
+ writer.writeAttribute(QStringLiteral("keyLeft"), DP_VALUE.arg(absolute.left()));
+ writer.writeAttribute(QStringLiteral("keyTop"), DP_VALUE.arg(absolute.top()));
+ writer.writeAttribute(QStringLiteral("keyWidth"), DP_VALUE.arg(absolute.width()));
+ writer.writeAttribute(QStringLiteral("keyHeight"), DP_VALUE.arg(absolute.height()));
+ } else if (!relative.isEmpty()) {
+ writer.writeStartElement(QStringLiteral("key"));
+ writer.writeAttribute(QStringLiteral("keyLeft"), PC_VALUE.arg(relative.left() * 100.));
+ writer.writeAttribute(QStringLiteral("keyTop"), PC_VALUE.arg(relative.top() * 100.));
+ writer.writeAttribute(QStringLiteral("keyWidth"), PC_VALUE.arg(relative.width() * 100.));
+ writer.writeAttribute(QStringLiteral("keyHeight"), PC_VALUE.arg(relative.height() * 100.));
+ } else {
+ // No geometry, skip
+ return;
+ }
+ writer.writeAttribute(QStringLiteral("keyType"), QMetaEnum::fromType<Xt9KdbKey::Type>().key(static_cast<int>(type)));
+ if (name != Name::NONE)
+ writer.writeAttribute(QStringLiteral("keyName"), QMetaEnum::fromType<Xt9KdbKey::Name>().key(static_cast<int>(name)));
+ if (!label.isEmpty())
+ writer.writeAttribute(QStringLiteral("keyLabel"), isPrintable(label) ? label : joinCodeList(label));
+ if (!labelShifted.isEmpty())
+ writer.writeAttribute(QStringLiteral("keyLabelShifted"), isPrintable(labelShifted) ? labelShifted : joinCodeList(labelShifted));
+ if (!codes.isEmpty())
+ writer.writeAttribute(QStringLiteral("keyCodes"), joinCodeList(codes));
+ if (!codesShifted.isEmpty())
+ writer.writeAttribute(QStringLiteral("keyCodesShifted"), joinCodeList(codesShifted));
+ writer.writeEndElement();
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
diff --git a/src/plugins/cerence/xt9/xt9common/xt9kdbkey.h b/src/plugins/cerence/xt9/xt9common/xt9kdbkey.h
new file mode 100644
index 00000000..ef1264a8
--- /dev/null
+++ b/src/plugins/cerence/xt9/xt9common/xt9kdbkey.h
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XT9KDBKEY_H
+#define XT9KDBKEY_H
+
+#include "xt9kdbelement.h"
+#include <QRect>
+#include <QRectF>
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+class Xt9KdbKey : public Xt9KdbElement
+{
+ Q_GADGET
+
+public:
+ enum class Type {
+ regional,
+ nonRegional,
+ smartPunct,
+ string,
+ function
+ };
+ Q_ENUM(Type)
+
+ // The names must match with et9kbdef.h.
+ // The enum value must not be assigned.
+ enum class Name {
+ NONE,
+ ET9KEY_BACK,
+ ET9KEY_TAB,
+ ET9KEY_NEW_LINE,
+ ET9KEY_SPACE,
+ ET9KEY_LEFT,
+ ET9KEY_UP,
+ ET9KEY_RIGHT,
+ ET9KEY_DOWN,
+ ET9KEY_SHIFT,
+ ET9KEY_LANGUAGE,
+ };
+ Q_ENUM(Name)
+
+ Xt9KdbKey();
+
+ void serialize(QXmlStreamWriter &writer) const;
+
+ QRect absolute;
+ QRectF relative;
+ Type type;
+ Name name;
+ QString label;
+ QString labelShifted;
+ QString codes;
+ QString codesShifted;
+ bool hackWriteDistinctKeysForAllCodes;
+
+private:
+ template<typename T>
+ static QString joinCodeList(const T &codes);
+};
+
+template<typename T>
+QString Xt9KdbKey::joinCodeList(const T &codes)
+{
+ static const QString HEX_VALUE = QStringLiteral("0x%1");
+
+ QString result;
+ bool first = true;
+
+ for (const QChar &code : codes) {
+ if (first)
+ first = false;
+ else
+ result.append(QLatin1Char(','));
+
+ result.append(HEX_VALUE.arg(code.unicode(), 0, 16));
+ }
+
+ return result;
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
+
+#endif // XT9KDBKEY_H
diff --git a/src/plugins/cerence/xt9/xt9common/xt9kdblayout.cpp b/src/plugins/cerence/xt9/xt9common/xt9kdblayout.cpp
new file mode 100644
index 00000000..f2cdb75e
--- /dev/null
+++ b/src/plugins/cerence/xt9/xt9common/xt9kdblayout.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xt9kdblayout.h"
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+Xt9KdbLayout::Xt9KdbLayout() :
+ primaryId(0),
+ secondaryId(0),
+ defaultLayoutWidth(0),
+ defaultLayoutHeight(0),
+ supportsExact(false),
+ smartTouchActive(false)
+{
+
+}
+
+void Xt9KdbLayout::serialize(QXmlStreamWriter &writer) const
+{
+ writer.writeStartElement(QStringLiteral("keyboard"));
+ writer.writeAttribute(QStringLiteral("primaryId"), QString::number(primaryId));
+ writer.writeAttribute(QStringLiteral("secondaryId"), QString::number(secondaryId));
+ if (defaultLayoutWidth > 0 && defaultLayoutHeight > 0) {
+ writer.writeAttribute(QStringLiteral("defaultLayoutWidth"), QString::number(defaultLayoutWidth));
+ writer.writeAttribute(QStringLiteral("defaultLayoutHeight"), QString::number(defaultLayoutHeight + 1));
+ }
+ if (supportsExact)
+ writer.writeAttribute(QStringLiteral("supportsExact"), QString(QStringLiteral("%1")).arg(supportsExact));
+ if (smartTouchActive)
+ writer.writeAttribute(QStringLiteral("smartTouchActive"), QString(QStringLiteral("%1")).arg(smartTouchActive));
+ for (const Xt9KdbArea &area : areas) {
+ area.serialize(writer);
+ }
+ writer.writeEndElement();
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
diff --git a/src/plugins/cerence/xt9/xt9common/xt9kdblayout.h b/src/plugins/cerence/xt9/xt9common/xt9kdblayout.h
new file mode 100644
index 00000000..feeed854
--- /dev/null
+++ b/src/plugins/cerence/xt9/xt9common/xt9kdblayout.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XT9KDBLAYOUT_H
+#define XT9KDBLAYOUT_H
+
+#include "xt9kdbarea.h"
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+class Xt9KdbLayout : public Xt9KdbElement
+{
+public:
+ Xt9KdbLayout();
+
+ void serialize(QXmlStreamWriter &writer) const;
+
+ int primaryId;
+ int secondaryId;
+ int defaultLayoutWidth;
+ int defaultLayoutHeight;
+ bool supportsExact;
+ bool smartTouchActive;
+ QList<Xt9KdbArea> areas;
+};
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
+
+#endif // XT9KDBLAYOUT_H
diff --git a/src/plugins/cerence/xt9/xt9common/xt9keyboardgenerator.cpp b/src/plugins/cerence/xt9/xt9common/xt9keyboardgenerator.cpp
new file mode 100644
index 00000000..ae7b8376
--- /dev/null
+++ b/src/plugins/cerence/xt9/xt9common/xt9keyboardgenerator.cpp
@@ -0,0 +1,167 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xt9keyboardgenerator.h"
+#include "xt9kdblayout.h"
+#include "xt9kdb.h"
+#include <QtVirtualKeyboard/qvirtualkeyboard_namespace.h>
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+const QString Xt9KeyboardGenerator::PRIMARY_ID = QStringLiteral("primaryId");
+const QString Xt9KeyboardGenerator::SECONDARY_ID = QStringLiteral("secondaryId");
+const QString Xt9KeyboardGenerator::WIDTH = QStringLiteral("width");
+const QString Xt9KeyboardGenerator::HEIGHT = QStringLiteral("height");
+const QString Xt9KeyboardGenerator::KEY = QStringLiteral("key");
+const QString Xt9KeyboardGenerator::KEYS = QStringLiteral("keys");
+const QString Xt9KeyboardGenerator::KEY_TYPE = QStringLiteral("keyType");
+const QString Xt9KeyboardGenerator::TOP = QStringLiteral("top");
+const QString Xt9KeyboardGenerator::LEFT = QStringLiteral("left");
+const QString Xt9KeyboardGenerator::TEXT = QStringLiteral("text");
+const QString Xt9KeyboardGenerator::ALT_KEYS = QStringLiteral("altKeys");
+const int Xt9KeyboardGenerator::EMOTICON_KEY = 0xE000;
+
+Xt9KeyboardGenerator::Xt9KeyboardGenerator(const QVariantMap &vkbLayout, const CodeConverter *keyConverter) :
+ vkbLayout(vkbLayout),
+ layoutWidth(vkbLayout[WIDTH].toDouble()),
+ layoutHeight(vkbLayout[HEIGHT].toDouble()),
+ codeConverter(keyConverter)
+{
+
+}
+
+QByteArray Xt9KeyboardGenerator::createXmlLayout() const
+{
+ if (layoutWidth <= 0 || layoutHeight <= 0)
+ return QByteArray();
+
+ Xt9KdbLayout kdbLayout;
+ kdbLayout.primaryId = vkbLayout[PRIMARY_ID].toInt();
+ kdbLayout.secondaryId = vkbLayout[SECONDARY_ID].toInt();
+ kdbLayout.defaultLayoutWidth = qRound(layoutWidth);
+ kdbLayout.defaultLayoutHeight = qRound(layoutHeight);
+
+ Xt9KdbArea xt9Area;
+ if (convertFromVkb(xt9Area))
+ kdbLayout.areas.append(xt9Area);
+
+ return Xt9Kdb::generate(kdbLayout, true);
+}
+
+bool Xt9KeyboardGenerator::convertFromVkb(Xt9KdbArea &xt9Area) const
+{
+ QVariantList vkbKeys = vkbLayout[KEYS].toList();
+
+ for (const QVariant &i : vkbKeys) {
+ Xt9KdbKey xt9Key;
+ if (convertFromVkb(xt9Key, i.toMap()))
+ xt9Area.keys.append(xt9Key);
+ }
+
+ return true;
+}
+
+bool Xt9KeyboardGenerator::convertFromVkb(Xt9KdbKey &xt9Key, const QVariantMap &vkbKey) const
+{
+ const KeyType vkbKeyType = static_cast<KeyType>(vkbKey[KEY_TYPE].toInt());
+
+ switch (vkbKeyType) {
+ case KeyType::BackspaceKey:
+ xt9Key.type = Xt9KdbKey::Type::function;
+ xt9Key.name = Xt9KdbKey::Name::ET9KEY_BACK;
+ break;
+
+ case KeyType::EnterKey:
+ xt9Key.type = Xt9KdbKey::Type::function;
+ xt9Key.name = Xt9KdbKey::Name::ET9KEY_NEW_LINE;
+ break;
+
+ case KeyType::Key:
+ case KeyType::FlickKey:
+ xt9Key.hackWriteDistinctKeysForAllCodes = (vkbKeyType == KeyType::FlickKey);
+ switch (vkbKey[KEY].toInt()) {
+ case Qt::Key_Space:
+ xt9Key.type = Xt9KdbKey::Type::function;
+ xt9Key.name = Xt9KdbKey::Name::ET9KEY_SPACE;
+ break;
+
+ case EMOTICON_KEY:
+ xt9Key.type = Xt9KdbKey::Type::string;
+ break;
+
+ default:
+ xt9Key.type = Xt9KdbKey::Type::nonRegional;
+ break;
+ }
+ break;
+
+ case KeyType::SpaceKey:
+ xt9Key.type = Xt9KdbKey::Type::function;
+ xt9Key.name = Xt9KdbKey::Name::ET9KEY_SPACE;
+ break;
+
+ default:
+ return false;
+ }
+
+ xt9Key.relative.setLeft(vkbKey[LEFT].toDouble() / layoutWidth);
+ xt9Key.relative.setTop(vkbKey[TOP].toDouble() / layoutHeight);
+ xt9Key.relative.setWidth(vkbKey[WIDTH].toDouble() / layoutWidth);
+ xt9Key.relative.setHeight(vkbKey[HEIGHT].toDouble() / layoutHeight);
+
+ switch (xt9Key.type) {
+ case Xt9KdbKey::Type::regional:
+ case Xt9KdbKey::Type::nonRegional:
+ case Xt9KdbKey::Type::string:
+ xt9Key.label = vkbKey[TEXT].toString().toUpper();
+ if (xt9Key.label.isEmpty())
+ return false;
+ xt9Key.codes = vkbKey[ALT_KEYS].toString();
+ if (codeConverter) {
+ xt9Key.label = codeConverter->convertTo(xt9Key.label);
+ xt9Key.codes = codeConverter->convertTo(xt9Key.codes);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return true;
+}
+
+Xt9KeyboardGenerator::CodeConverter::~CodeConverter()
+{
+
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
diff --git a/src/plugins/cerence/xt9/xt9common/xt9keyboardgenerator.h b/src/plugins/cerence/xt9/xt9common/xt9keyboardgenerator.h
new file mode 100644
index 00000000..b255b244
--- /dev/null
+++ b/src/plugins/cerence/xt9/xt9common/xt9keyboardgenerator.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XT9KEYBOARDGENERATOR_H
+#define XT9KEYBOARDGENERATOR_H
+
+#include <QVariantMap>
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+class Xt9KdbArea;
+class Xt9KdbKey;
+
+class Xt9KeyboardGenerator
+{
+public:
+ class CodeConverter;
+
+ Xt9KeyboardGenerator(const QVariantMap &vkbLayout, const CodeConverter *codeConverter = nullptr);
+
+ QByteArray createXmlLayout() const;
+
+ static const QString PRIMARY_ID;
+ static const QString SECONDARY_ID;
+ static const QString WIDTH;
+ static const QString HEIGHT;
+ static const QString KEY;
+ static const QString KEYS;
+ static const QString KEY_TYPE;
+ static const QString TOP;
+ static const QString LEFT;
+ static const QString TEXT;
+ static const QString ALT_KEYS;
+ static const int EMOTICON_KEY;
+
+ class CodeConverter {
+ public:
+ virtual ~CodeConverter();
+ virtual QString convertTo(const QString &codes) const = 0;
+ virtual QString convertFrom(const QString &codes) const = 0;
+ };
+
+private:
+ bool convertFromVkb(Xt9KdbArea &xt9Area) const;
+ bool convertFromVkb(Xt9KdbKey &xt9Key, const QVariantMap &vkbKey) const;
+
+public:
+ const QVariantMap vkbLayout;
+ const double layoutWidth;
+ const double layoutHeight;
+ const CodeConverter *codeConverter;
+};
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
+
+#endif // XT9KEYBOARDGENERATOR_H
diff --git a/src/plugins/cerence/xt9/xt9common/xt9kime.cpp b/src/plugins/cerence/xt9/xt9common/xt9kime.cpp
new file mode 100644
index 00000000..9faacce9
--- /dev/null
+++ b/src/plugins/cerence/xt9/xt9common/xt9kime.cpp
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xt9kime.h"
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+class JamoConverter : public Xt9KeyboardGenerator::CodeConverter {
+public:
+ QString convertTo(const QString &codes) const override
+ {
+ QVector<ushort> jamoBuf(codes.size());
+ memcpy(jamoBuf.data(), codes.utf16(), static_cast<size_t>(jamoBuf.size()) * sizeof(ushort));
+ XT9_VAPI(ET9KCompatibilityJamoToJamo, jamoBuf.data(), static_cast<ET9U32>(jamoBuf.length()));
+ return QString::fromUtf16(reinterpret_cast<const char16_t *>(jamoBuf.constData()), jamoBuf.length());
+ }
+
+ QString convertFrom(const QString &codes) const override
+ {
+ QVector<ushort> jamoBuf(codes.size());
+ memcpy(jamoBuf.data(), codes.utf16(), static_cast<size_t>(jamoBuf.size()) * sizeof(ushort));
+ XT9_VAPI(ET9KJamoToCompatibilityJamo, jamoBuf.data(), static_cast<ET9U32>(jamoBuf.length()));
+ return QString::fromUtf16(reinterpret_cast<const char16_t *>(jamoBuf.constData()), jamoBuf.length());
+ }
+};
+
+Q_GLOBAL_STATIC(JamoConverter, jamoConverter)
+
+Xt9KIme::Xt9KIme(Xt9RequestCallback *requestCallback) :
+ Xt9AwIme(requestCallback, jamoConverter)
+{
+}
+
+void Xt9KIme::sysInit()
+{
+ Xt9AwIme::sysInit();
+ memset(&sKLingCmn, 0, sizeof(sKLingCmn));
+ XT9_API(ET9KSysActivate, &sLingInfo, &sKLingCmn, 1);
+}
+
+QString Xt9KIme::exactWord(int *wordCompLen)
+{
+ return jamoConverter->convertFrom(Xt9AwIme::exactWord(wordCompLen));
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
diff --git a/src/plugins/cerence/xt9/xt9common/xt9kime.h b/src/plugins/cerence/xt9/xt9common/xt9kime.h
new file mode 100644
index 00000000..a27e68ad
--- /dev/null
+++ b/src/plugins/cerence/xt9/xt9common/xt9kime.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XT9KIME_H
+#define XT9KIME_H
+
+#include "xt9awime.h"
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+class Xt9KIme : public Xt9AwIme
+{
+public:
+ Xt9KIme(Xt9RequestCallback *requestCallback);
+
+ void sysInit() override;
+ QString exactWord(int *wordCompLen = nullptr) override;
+
+public:
+ ET9KLingCmnInfo sKLingCmn;
+};
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
+
+#endif // XT9KIME_H
diff --git a/src/plugins/cerence/xt9/xt9common/xt9languagemap.cpp b/src/plugins/cerence/xt9/xt9common/xt9languagemap.cpp
new file mode 100644
index 00000000..1e30123b
--- /dev/null
+++ b/src/plugins/cerence/xt9/xt9common/xt9languagemap.cpp
@@ -0,0 +1,250 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xt9languagemap.h"
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+const Xt9LanguageMap::SimpleLanguageMapEntry Xt9LanguageMap::SIMPLE_LANGUAGE_MAP[] = {
+ { ET9PLIDAbkhazian, QLocale::Language::Abkhazian },
+ { ET9PLIDAfar, QLocale::Language::Afar },
+ { ET9PLIDAfrikaans, QLocale::Language::Afrikaans },
+ { ET9PLIDAlbanian, QLocale::Language::Albanian },
+ { ET9PLIDAmharic, QLocale::Language::Amharic },
+ { ET9PLIDArabic, QLocale::Language::Arabic },
+ { ET9PLIDArmenian, QLocale::Language::Armenian },
+ { ET9PLIDAssamese, QLocale::Language::Assamese },
+ { ET9PLIDAymara, QLocale::Language::Aymara },
+ { ET9PLIDAzerbaijani, QLocale::Language::Azerbaijani },
+ { ET9PLIDBashkir, QLocale::Language::Bashkir },
+ { ET9PLIDBasque, QLocale::Language::Basque },
+ { ET9PLIDBelarusian, QLocale::Language::Belarusian },
+ { ET9PLIDBengali, QLocale::Language::Bengali },
+ { ET9PLIDBislama, QLocale::Language::Bislama },
+ { ET9PLIDBosnian, QLocale::Language::Bosnian },
+ { ET9PLIDBreton, QLocale::Language::Breton },
+ { ET9PLIDBulgarian, QLocale::Language::Bulgarian },
+ { ET9PLIDBurmese, QLocale::Language::Burmese },
+ { ET9PLIDCatalan, QLocale::Language::Catalan },
+ { ET9PLIDChineseSimplified, QLocale::Language::Chinese },
+ { ET9PLIDCorsican, QLocale::Language::Corsican },
+ { ET9PLIDCroatian, QLocale::Language::Croatian },
+ { ET9PLIDCzech, QLocale::Language::Czech },
+ { ET9PLIDDanish, QLocale::Language::Danish },
+ { ET9PLIDDutch, QLocale::Language::Dutch },
+ { ET9PLIDEnglish, QLocale::Language::English },
+ { ET9PLIDEsperanto, QLocale::Language::Esperanto },
+ { ET9PLIDEstonian, QLocale::Language::Estonian },
+ { ET9PLIDFilipino, QLocale::Language::Filipino },
+ { ET9PLIDFinnish, QLocale::Language::Finnish },
+ { ET9PLIDFrench, QLocale::Language::French },
+ { ET9PLIDGalician, QLocale::Language::Galician },
+ { ET9PLIDGeorgian, QLocale::Language::Georgian },
+ { ET9PLIDGerman, QLocale::Language::German },
+ { ET9PLIDGerman, QLocale::Language::LowGerman },
+ { ET9PLIDGerman, QLocale::Language::SwissGerman },
+ { ET9PLIDGreek, QLocale::Language::Greek },
+ { ET9PLIDGreenlandic, QLocale::Language::Greenlandic },
+ { ET9PLIDGuarani, QLocale::Language::Guarani },
+ { ET9PLIDGujarati, QLocale::Language::Gujarati },
+ { ET9PLIDHausa, QLocale::Language::Hausa },
+ { ET9PLIDHawaiian, QLocale::Language::Hawaiian },
+ { ET9PLIDHebrew, QLocale::Language::Hebrew },
+ { ET9PLIDHindi, QLocale::Language::Hindi },
+ { ET9PLIDHungarian, QLocale::Language::Hungarian },
+ { ET9PLIDIcelandic, QLocale::Language::Icelandic },
+ { ET9PLIDIgbo, QLocale::Language::Igbo },
+ { ET9PLIDIndonesian, QLocale::Language::Indonesian },
+ { ET9PLIDInterlingua, QLocale::Language::Interlingua },
+ { ET9PLIDInterlingue, QLocale::Language::Interlingue },
+ { ET9PLIDInuktitut, QLocale::Language::Inuktitut },
+ { ET9PLIDInupiak, QLocale::Language::Inupiak },
+ { ET9PLIDIrish, QLocale::Language::Irish },
+ { ET9PLIDItalian, QLocale::Language::Italian },
+ { ET9PLIDJapanese, QLocale::Language::Japanese },
+ { ET9PLIDJavanese, QLocale::Language::Javanese },
+ { ET9PLIDKannada, QLocale::Language::Kannada },
+ { ET9PLIDKashmiri, QLocale::Language::Kashmiri },
+ { ET9PLIDKazakh, QLocale::Language::Kazakh },
+ { ET9PLIDKhmer, QLocale::Language::Khmer },
+ { ET9PLIDKirghiz, QLocale::Language::Kirghiz },
+ { ET9PLIDKonkani, QLocale::Language::Konkani },
+ { ET9PLIDKorean, QLocale::Language::Korean },
+ { ET9PLIDKurdish, QLocale::Language::Kurdish },
+ { ET9PLIDLao, QLocale::Language::Lao },
+ { ET9PLIDLatin, QLocale::Language::Latin },
+ { ET9PLIDLatvian, QLocale::Language::Latvian },
+ { ET9PLIDLingala, QLocale::Language::Lingala },
+ { ET9PLIDLithuanian, QLocale::Language::Lithuanian },
+ { ET9PLIDMacedonian, QLocale::Language::Macedonian },
+ { ET9PLIDMalagasy, QLocale::Language::Malagasy },
+ { ET9PLIDMalay, QLocale::Language::Malay },
+ { ET9PLIDMalayalam, QLocale::Language::Malayalam },
+ { ET9PLIDMaltese, QLocale::Language::Maltese },
+ { ET9PLIDMaori, QLocale::Language::Maori },
+ { ET9PLIDMarathi, QLocale::Language::Marathi },
+ { ET9PLIDMongolian, QLocale::Language::Mongolian },
+ { ET9PLIDNepali, QLocale::Language::Nepali },
+ { ET9PLIDNorwegian, QLocale::Language::NorwegianBokmal },
+ { ET9PLIDNorwegian, QLocale::Language::NorwegianNynorsk },
+ { ET9PLIDOccitan, QLocale::Language::Occitan },
+ { ET9PLIDOriya, QLocale::Language::Oriya },
+ { ET9PLIDOromo, QLocale::Language::Oromo },
+ { ET9PLIDPashto, QLocale::Language::Pashto },
+ { ET9PLIDPersian, QLocale::Language::Persian },
+ { ET9PLIDPolish, QLocale::Language::Polish },
+ { ET9PLIDPortuguese, QLocale::Language::Portuguese },
+ { ET9PLIDPunjabi, QLocale::Language::Punjabi },
+ { ET9PLIDQuechua, QLocale::Language::Quechua },
+ { ET9PLIDRomanian, QLocale::Language::Romanian },
+ { ET9PLIDRussian, QLocale::Language::Russian },
+ { ET9PLIDSami, QLocale::Language::NorthernSami },
+ { ET9PLIDSamoan, QLocale::Language::Samoan },
+ { ET9PLIDSangho, QLocale::Language::Sango },
+ { ET9PLIDSanskrit, QLocale::Language::Sanskrit },
+ { ET9PLIDSerbian, QLocale::Language::Serbian },
+ { ET9PLIDSesotho, QLocale::Language::NorthernSotho },
+ { ET9PLIDSesotho, QLocale::Language::SouthernSotho },
+ { ET9PLIDShona, QLocale::Language::Shona },
+ { ET9PLIDSindhi, QLocale::Language::Sindhi },
+ { ET9PLIDSinhala, QLocale::Language::Sinhala },
+ { ET9PLIDSiswati, QLocale::Language::Swati },
+ { ET9PLIDSlovak, QLocale::Language::Slovak },
+ { ET9PLIDSlovenian, QLocale::Language::Slovenian },
+ { ET9PLIDSomali, QLocale::Language::Somali },
+ { ET9PLIDSpanish, QLocale::Language::Spanish },
+ { ET9PLIDSundanese, QLocale::Language::Sundanese },
+ { ET9PLIDSwahili, QLocale::Language::Swahili },
+ { ET9PLIDSwedish, QLocale::Language::Swedish },
+ { ET9PLIDTajik, QLocale::Language::Tajik },
+ { ET9PLIDTamil, QLocale::Language::Tamil },
+ { ET9PLIDTatar, QLocale::Language::Tatar },
+ { ET9PLIDTelugu, QLocale::Language::Telugu },
+ { ET9PLIDThai, QLocale::Language::Thai },
+ { ET9PLIDTibetan, QLocale::Language::Tibetan },
+ { ET9PLIDTigrinya, QLocale::Language::Tigrinya },
+ { ET9PLIDTonga, QLocale::Language::Tongan },
+ { ET9PLIDTsonga, QLocale::Language::Tsonga },
+ { ET9PLIDTswana, QLocale::Language::Tswana },
+ { ET9PLIDTurkish, QLocale::Language::Turkish },
+ { ET9PLIDTurkmen, QLocale::Language::Turkmen },
+ { ET9PLIDUkrainian, QLocale::Language::Ukrainian },
+ { ET9PLIDUrdu, QLocale::Language::Urdu },
+ { ET9PLIDUzbek, QLocale::Language::Uzbek },
+ { ET9PLIDVenda, QLocale::Language::Venda },
+ { ET9PLIDVietnamese, QLocale::Language::Vietnamese },
+ { ET9PLIDVolapuk, QLocale::Language::Volapuk },
+ { ET9PLIDWelsh, QLocale::Language::Welsh },
+ { ET9PLIDWolof, QLocale::Language::Wolof },
+ { ET9PLIDXhosa, QLocale::Language::Xhosa },
+ { ET9PLIDYiddish, QLocale::Language::Yiddish },
+ { ET9PLIDYoruba, QLocale::Language::Yoruba },
+ { ET9PLIDZhuang, QLocale::Language::Zhuang },
+ { ET9PLIDZulu, QLocale::Language::Zulu },
+ // End-of-map
+ { ET9PLIDNone, QLocale::Language::AnyLanguage }
+};
+
+const struct Xt9LanguageMap::LanguageMapEntry Xt9LanguageMap::LANGUAGE_MAP[] = {
+ { ET9LIDEnglish_UK, QLocale(QLocale::English, QLocale::UnitedKingdom) },
+ { ET9LIDEnglish_Australia, QLocale(QLocale::English, QLocale::Australia) },
+ { ET9LIDEnglish_India, QLocale(QLocale::English, QLocale::India) },
+ { ET9LIDEnglish_US, QLocale(QLocale::English, QLocale::UnitedStates) },
+ { ET9PLIDEnglish|ET9SLIDDEFAULT, QLocale(QLocale::English, QLocale::UnitedKingdom) },
+ { ET9LIDSpanish_LatinAmerican, QLocale(QLocale::Spanish, QLocale::LatinAmerica) },
+ { ET9PLIDSpanish|ET9SLIDDEFAULT, QLocale(QLocale::Spanish, QLocale::Spain) },
+ { ET9LIDFrench_Canada, QLocale(QLocale::French, QLocale::Canada) },
+ { ET9LIDFrench_Switzerland, QLocale(QLocale::French, QLocale::Switzerland) },
+ { ET9PLIDFrench|ET9SLIDDEFAULT, QLocale(QLocale::French, QLocale::France) },
+ { ET9LIDItalian_Switzerland, QLocale(QLocale::Italian, QLocale::Switzerland) },
+ { ET9LIDDutch_Belgium, QLocale(QLocale::Dutch, QLocale::Belgium) },
+ { ET9PLIDPortuguese|ET9SLIDDEFAULT, QLocale(QLocale::Portuguese, QLocale::Portugal) },
+ { ET9LIDPortuguese_Brazil, QLocale(QLocale::Portuguese, QLocale::Brazil) },
+ { ET9PLIDChineseSimplified, QLocale(QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China) },
+ { ET9PLIDChineseTraditional, QLocale(QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan) },
+ { ET9PLIDChineseHongkong, QLocale(QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::HongKong) },
+ { ET9PLIDChineseSingapore, QLocale(QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Singapore) },
+ { ET9LIDJapanese_Hiragana, QLocale(QLocale::Japanese) },
+ // End-of-map
+ { 0, QLocale(QLocale::AnyLanguage) },
+};
+
+ET9U32 Xt9LanguageMap::languageId(const QLocale &locale)
+{
+ const QLocale::Language localeLanguage = locale.language();
+ const QLocale::Country localeCountry = locale.country();
+
+ for (int i = 0; LANGUAGE_MAP[i].languageId != 0; ++i) {
+ const QLocale &item = LANGUAGE_MAP[i].locale;
+ if (item.language() == localeLanguage && item.country() == localeCountry)
+ return LANGUAGE_MAP[i].languageId;
+ }
+
+ const SimpleLanguageMapEntry *simpleLanguageMapIterator = SIMPLE_LANGUAGE_MAP;
+ for (; simpleLanguageMapIterator->localeLanguage != QLocale::Language::AnyLanguage;
+ simpleLanguageMapIterator++) {
+ if (simpleLanguageMapIterator->localeLanguage == localeLanguage)
+ return simpleLanguageMapIterator->languageId;
+ }
+
+ return ET9PLIDNone;
+}
+
+QLocale Xt9LanguageMap::locale(ET9U32 languageId)
+{
+ for (int i = 0; LANGUAGE_MAP[i].languageId != 0; ++i) {
+ if (LANGUAGE_MAP[i].languageId == languageId)
+ return LANGUAGE_MAP[i].locale;
+ }
+
+ if (!(languageId & ET9SLIDMASK) &&
+ (languageId < ET9PLIDChineseTraditional || languageId > ET9PLIDChineseSingapore)) {
+
+ languageId |= ET9SLIDDEFAULT;
+
+ for (int i = 0; LANGUAGE_MAP[i].languageId != 0; ++i) {
+ if (LANGUAGE_MAP[i].languageId == languageId)
+ return LANGUAGE_MAP[i].locale;
+ }
+ }
+
+ const ET9U32 plid = languageId & ET9PLIDMASK;
+ const SimpleLanguageMapEntry *simpleLanguageMapIterator = SIMPLE_LANGUAGE_MAP;
+ for (; simpleLanguageMapIterator->localeLanguage != QLocale::Language::AnyLanguage;
+ simpleLanguageMapIterator++) {
+ if (simpleLanguageMapIterator->languageId == plid)
+ return QLocale(simpleLanguageMapIterator->localeLanguage);
+ }
+
+ return QLocale(QLocale::AnyLanguage);
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
diff --git a/src/plugins/cerence/xt9/xt9common/xt9languagemap.h b/src/plugins/cerence/xt9/xt9common/xt9languagemap.h
new file mode 100644
index 00000000..35bbaf10
--- /dev/null
+++ b/src/plugins/cerence/xt9/xt9common/xt9languagemap.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XT9LANGUAGEMAP_H
+#define XT9LANGUAGEMAP_H
+
+#include <QLocale>
+#include <et9api.h>
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+class Xt9LanguageMap
+{
+private:
+ Xt9LanguageMap();
+
+public:
+ static ET9U32 languageId(const QLocale &locale);
+ static QLocale locale(ET9U32 languageId);
+
+private:
+ struct SimpleLanguageMapEntry {
+ ET9U32 languageId;
+ QLocale::Language localeLanguage;
+ };
+
+ struct LanguageMapEntry {
+ ET9U32 languageId;
+ QLocale locale;
+ };
+
+ static const SimpleLanguageMapEntry SIMPLE_LANGUAGE_MAP[];
+ static const struct LanguageMapEntry LANGUAGE_MAP[];
+};
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE
+
+#endif // XT9LANGUAGEMAP_H
diff --git a/src/plugins/t9write/3rdparty/t9write/CMakeLists.txt b/src/plugins/t9write/3rdparty/t9write/CMakeLists.txt
deleted file mode 100644
index e8589084..00000000
--- a/src/plugins/t9write/3rdparty/t9write/CMakeLists.txt
+++ /dev/null
@@ -1,71 +0,0 @@
-# Generated from t9write.pro.
-
-#####################################################################
-## BundledT9Write_Db Generic Library:
-#####################################################################
-
-qt_internal_add_3rdparty_library(BundledT9Write_Db
- QMAKE_LIB_NAME t9write_db
- STATIC
- SOURCES
- api/*
- PUBLIC_LIBRARIES
- Qt::Core
-)
-
-file(GLOB resource_glob_0 RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "data/arabic/*.bin")
-foreach(file IN LISTS resource_glob_0)
- set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/${file}" PROPERTIES QT_RESOURCE_ALIAS "${file}")
-endforeach()
-
-file(GLOB resource_glob_1 RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "data/hebrew/*.bin")
-foreach(file IN LISTS resource_glob_1)
- set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/${file}" PROPERTIES QT_RESOURCE_ALIAS "${file}")
-endforeach()
-
-file(GLOB resource_glob_2 RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "data/thai/*.bin")
-foreach(file IN LISTS resource_glob_2)
- set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/${file}" PROPERTIES QT_RESOURCE_ALIAS "${file}")
-endforeach()
-
-file(GLOB resource_glob_3 RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "data/*.bin")
-foreach(file IN LISTS resource_glob_3)
- set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/${file}" PROPERTIES QT_RESOURCE_ALIAS "${file}")
-endforeach()
-
-file(GLOB resource_glob_4 RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "data/*.ldb")
-foreach(file IN LISTS resource_glob_4)
- set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/${file}" PROPERTIES QT_RESOURCE_ALIAS "${file}")
-endforeach()
-
-file(GLOB resource_glob_5 RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "data/*.hdb")
-foreach(file IN LISTS resource_glob_5)
- set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/${file}" PROPERTIES QT_RESOURCE_ALIAS "${file}")
-endforeach()
-
-file(GLOB resource_glob_6 RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "data/*.phd")
-foreach(file IN LISTS resource_glob_6)
- set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/${file}" PROPERTIES QT_RESOURCE_ALIAS "${file}")
-endforeach()
-
-# Resources:
-set(qmake_t9write_db_resource_files
- ${resource_glob_0}
- ${resource_glob_1}
- ${resource_glob_2}
- ${resource_glob_3}
- ${resource_glob_4}
- ${resource_glob_5}
- ${resource_glob_6}
-)
-
-qt_internal_add_resource(BundledT9Write_Db "qmake_t9write_db"
- PREFIX
- "/QtQuick/VirtualKeyboard/T9Write"
- FILES
- ${qmake_t9write_db_resource_files}
-)
-
-
-#### Keys ignored in scope 1:.:.:t9write.pro:<TRUE>:
-# QMAKE_RESOURCE_FLAGS = "-no-compress"
diff --git a/src/plugins/t9write/CMakeLists.txt b/src/plugins/t9write/CMakeLists.txt
deleted file mode 100644
index f136b3f3..00000000
--- a/src/plugins/t9write/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-# Generated from t9write.pro.
-
-add_subdirectory(3rdparty/t9write)
-add_subdirectory(plugin)
diff --git a/src/plugins/t9write/plugin/CMakeLists.txt b/src/plugins/t9write/plugin/CMakeLists.txt
deleted file mode 100644
index 98d5a163..00000000
--- a/src/plugins/t9write/plugin/CMakeLists.txt
+++ /dev/null
@@ -1,264 +0,0 @@
-# Generated from plugin.pro.
-
-#####################################################################
-## QtVirtualKeyboardT9WritePlugin Plugin:
-#####################################################################
-
-qt_internal_add_plugin(QtVirtualKeyboardT9WritePlugin
- OUTPUT_NAME qtvirtualkeyboard_t9write
- TYPE virtualkeyboard
- SOURCES
- t9write_p.h
- t9writedictionary.cpp t9writedictionary_p.h
- t9writeinputmethod.cpp t9writeinputmethod_p.h
- t9writeplugin.cpp t9writeplugin.h
- t9writeworker.cpp t9writeworker_p.h
- DEFINES
- HAVE_T9WRITE
- QT_ASCII_CAST_WARNINGS
- QT_NO_CAST_FROM_ASCII
- QT_NO_CAST_FROM_BYTEARRAY
- QT_NO_CAST_TO_ASCII
- INCLUDE_DIRECTORIES
- api
- PUBLIC_LIBRARIES
- Qt::Core
- Qt::Gui
- Qt::Qml
- Qt::VirtualKeyboardPrivate
- t9write_db
-)
-
-# Resources:
-set(qmake_virtualkeyboard_t9write_layouts_resource_files
- "${VKB_LAYOUTS_BASE}/content/layouts/fallback/handwriting.qml"
-)
-
-qt_internal_add_resource(QtVirtualKeyboardT9WritePlugin "qmake_virtualkeyboard_t9write_layouts"
- PREFIX
- "${VKB_LAYOUTS_PREFIX}"
- BASE
- "${VKB_LAYOUTS_BASE}"
- FILES
- ${qmake_virtualkeyboard_t9write_layouts_resource_files}
-)
-
-
-#### Keys ignored in scope 1:.:.:plugin.pro:<TRUE>:
-# OTHER_FILES = "t9write.json" "$$LAYOUT_FILES"
-
-## Scopes:
-#####################################################################
-
-qt_internal_extend_target(QtVirtualKeyboardT9WritePlugin CONDITION QT_FEATURE_t9write_alphabetic
- DEFINES
- HAVE_T9WRITE_ALPHABETIC
-)
-
-#### Keys ignored in scope 4:.:.:plugin.pro:QT_FEATURE_vkb_lang_en_GB:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/en_GB/handwriting.fallback"
-
-#### Keys ignored in scope 5:.:.:plugin.pro:QT_FEATURE_vkb_lang_en_US:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/en_US/handwriting.fallback"
-
-#### Keys ignored in scope 6:.:.:plugin.pro:QT_FEATURE_vkb_lang_ar_AR:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/ar_AR/handwriting.qml"
-
-#### Keys ignored in scope 7:.:.:plugin.pro:QT_FEATURE_vkb_lang_bg_BG:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/bg_BG/handwriting.qml"
-
-#### Keys ignored in scope 8:.:.:plugin.pro:QT_FEATURE_vkb_lang_cs_CZ:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/cs_CZ/handwriting.qml"
-
-#### Keys ignored in scope 9:.:.:plugin.pro:QT_FEATURE_vkb_lang_da_DK:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/da_DK/handwriting.fallback"
-
-#### Keys ignored in scope 10:.:.:plugin.pro:QT_FEATURE_vkb_lang_de_DE:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/de_DE/handwriting.fallback"
-
-#### Keys ignored in scope 11:.:.:plugin.pro:QT_FEATURE_vkb_lang_el_GR:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/el_GR/handwriting.qml"
-
-#### Keys ignored in scope 12:.:.:plugin.pro:QT_FEATURE_vkb_lang_es_ES:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/es_ES/handwriting.qml"
-
-#### Keys ignored in scope 13:.:.:plugin.pro:QT_FEATURE_vkb_lang_es_MX:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/es_MX/handwriting.qml"
-
-#### Keys ignored in scope 14:.:.:plugin.pro:QT_FEATURE_vkb_lang_et_EE:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/et_EE/handwriting.fallback"
-
-#### Keys ignored in scope 15:.:.:plugin.pro:QT_FEATURE_vkb_lang_fa_FA:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/fa_FA/handwriting.qml"
-
-#### Keys ignored in scope 16:.:.:plugin.pro:QT_FEATURE_vkb_lang_fi_FI:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/fi_FI/handwriting.fallback"
-
-#### Keys ignored in scope 17:.:.:plugin.pro:QT_FEATURE_vkb_lang_fr_FR:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/fr_FR/handwriting.fallback"
-
-#### Keys ignored in scope 18:.:.:plugin.pro:QT_FEATURE_vkb_lang_fr_CA:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/fr_CA/handwriting.fallback"
-
-#### Keys ignored in scope 19:.:.:plugin.pro:QT_FEATURE_vkb_lang_he_IL:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/he_IL/handwriting.qml"
-
-#### Keys ignored in scope 20:.:.:plugin.pro:QT_FEATURE_vkb_lang_hr_HR:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/hr_HR/handwriting.qml"
-
-#### Keys ignored in scope 21:.:.:plugin.pro:QT_FEATURE_vkb_lang_hu_HU:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/hu_HU/handwriting.qml"
-
-#### Keys ignored in scope 22:.:.:plugin.pro:QT_FEATURE_vkb_lang_id_ID:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/id_ID/handwriting.fallback"
-
-#### Keys ignored in scope 23:.:.:plugin.pro:QT_FEATURE_vkb_lang_it_IT:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/it_IT/handwriting.fallback"
-
-#### Keys ignored in scope 24:.:.:plugin.pro:QT_FEATURE_vkb_lang_ms_MY:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/ms_MY/handwriting.fallback"
-
-#### Keys ignored in scope 25:.:.:plugin.pro:QT_FEATURE_vkb_lang_nb_NO:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/nb_NO/handwriting.fallback"
-
-#### Keys ignored in scope 26:.:.:plugin.pro:QT_FEATURE_vkb_lang_nl_NL:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/nl_NL/handwriting.fallback"
-
-#### Keys ignored in scope 27:.:.:plugin.pro:QT_FEATURE_vkb_lang_pl_PL:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/pl_PL/handwriting.fallback"
-
-#### Keys ignored in scope 28:.:.:plugin.pro:QT_FEATURE_vkb_lang_pt_BR:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/pt_BR/handwriting.fallback"
-
-#### Keys ignored in scope 29:.:.:plugin.pro:QT_FEATURE_vkb_lang_pt_PT:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/pt_PT/handwriting.fallback"
-
-#### Keys ignored in scope 30:.:.:plugin.pro:QT_FEATURE_vkb_lang_ro_RO:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/ro_RO/handwriting.qml"
-
-#### Keys ignored in scope 31:.:.:plugin.pro:QT_FEATURE_vkb_lang_ru_RU:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/ru_RU/handwriting.fallback"
-
-#### Keys ignored in scope 32:.:.:plugin.pro:QT_FEATURE_vkb_lang_sk_SK:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/sk_SK/handwriting.fallback"
-
-#### Keys ignored in scope 33:.:.:plugin.pro:QT_FEATURE_vkb_lang_sl_SI:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/sl_SI/handwriting.fallback"
-
-#### Keys ignored in scope 34:.:.:plugin.pro:QT_FEATURE_vkb_lang_sq_AL:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/sq_AL/handwriting.fallback"
-
-#### Keys ignored in scope 35:.:.:plugin.pro:QT_FEATURE_vkb_lang_sr_SP:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/sr_SP/handwriting.qml"
-
-#### Keys ignored in scope 36:.:.:plugin.pro:QT_FEATURE_vkb_lang_sv_SE:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/sv_SE/handwriting.fallback"
-
-#### Keys ignored in scope 37:.:.:plugin.pro:QT_FEATURE_vkb_lang_th_TH:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/th_TH/handwriting.qml"
-
-#### Keys ignored in scope 38:.:.:plugin.pro:QT_FEATURE_vkb_lang_tr_TR:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/tr_TR/handwriting.fallback"
-
-#### Keys ignored in scope 39:.:.:plugin.pro:QT_FEATURE_vkb_lang_uk_UA:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/uk_UA/handwriting.fallback"
-
-#### Keys ignored in scope 40:.:.:plugin.pro:QT_FEATURE_vkb_lang_vi_VN:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/vi_VN/handwriting.fallback"
-
-qt_internal_extend_target(QtVirtualKeyboardT9WritePlugin CONDITION QT_FEATURE_t9write_cjk
- DEFINES
- HAVE_T9WRITE_CJK
-)
-
-#### Keys ignored in scope 42:.:.:plugin.pro:QT_FEATURE_vkb_lang_ja_JP:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/ja_JP/handwriting.qml"
-
-#### Keys ignored in scope 43:.:.:plugin.pro:QT_FEATURE_vkb_lang_ko_KR:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/ko_KR/handwriting.qml"
-
-#### Keys ignored in scope 44:.:.:plugin.pro:QT_FEATURE_vkb_lang_zh_CN:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/zh_CN/handwriting.qml"
-
-#### Keys ignored in scope 45:.:.:plugin.pro:QT_FEATURE_vkb_lang_zh_TW:
-# LAYOUT_FILES = "$$LAYOUTS_BASE/content/layouts/zh_TW/handwriting.qml"
-
-#### Keys ignored in scope 47:.:.:plugin.pro:NOT T9WRITE_ALPHABETIC_BINS_ISEMPTY:
-# INSTALLS = "t9write_alphabetic_bins"
-# t9write_alphabetic_bins.files = "$$T9WRITE_ALPHABETIC_BINS"
-# t9write_alphabetic_bins.path = "$$[QT_INSTALL_BINS]"
-
-#### Keys ignored in scope 48:.:.:plugin.pro:NOT prefix_build:
-# COPIES = "t9write_alphabetic_bins"
-
-#### Keys ignored in scope 50:.:.:plugin.pro:NOT T9WRITE_CJK_BINS_ISEMPTY:
-# INSTALLS = "t9write_cjk_bins"
-# t9write_cjk_bins.files = "$$T9WRITE_CJK_BINS"
-# t9write_cjk_bins.path = "$$[QT_INSTALL_BINS]"
-
-#### Keys ignored in scope 51:.:.:plugin.pro:NOT prefix_build:
-# COPIES = "t9write_cjk_bins"
-
-#### Keys ignored in scope 52:.:.:plugin.pro:WIN32:
-# QMAKE_TARGET_DESCRIPTION = "Virtual Keyboard Extension for Qt."
-# QMAKE_TARGET_PRODUCT = "Qt Virtual Keyboard T9 Write (Qt $$QT_VERSION)"
-
-#### Keys ignored in scope 55:.:../3rdparty/t9write:../3rdparty/t9write/t9write-build.pri:QT_ARCH___contains___arm:
-# T9WRITE_BUILD_SHARED_DIR = "lib/arm/shared"
-# T9WRITE_BUILD_STATIC_DIR = "lib/arm/static"
-
-#### Keys ignored in scope 57:.:../3rdparty/t9write:../3rdparty/t9write/t9write-build.pri:LINUX:
-# T9WRITE_BUILD_SHARED_DIR = "lib/linux/shared"
-# T9WRITE_BUILD_STATIC_DIR = "lib/linux/static"
-
-#### Keys ignored in scope 59:.:../3rdparty/t9write:../3rdparty/t9write/t9write-build.pri:WIN32:
-# T9WRITE_BUILD_SHARED_DIR = "lib/win32/shared"
-# T9WRITE_BUILD_STATIC_DIR = "lib/win32/static"
-
-#### Keys ignored in scope 61:.:../3rdparty/t9write:../3rdparty/t9write/t9write-build.pri:WIN32:
-# result = "$$1/*.obj"
-
-#### Keys ignored in scope 62:.:../3rdparty/t9write:../3rdparty/t9write/t9write-build.pri:result_ISEMPTY:
-# result = "$$1/*.lib"
-
-#### Keys ignored in scope 63:.:../3rdparty/t9write:../3rdparty/t9write/t9write-build.pri:else:
-# result = "$$1/*.o"
-
-#### Keys ignored in scope 64:.:../3rdparty/t9write:../3rdparty/t9write/t9write-build.pri:result_ISEMPTY:
-# result = "$$1/*.a"
-
-#### Keys ignored in scope 66:.:../3rdparty/t9write:../3rdparty/t9write/t9write-build.pri:WIN32:
-# result = "$$1/*.lib"
-
-#### Keys ignored in scope 67:.:../3rdparty/t9write:../3rdparty/t9write/t9write-build.pri:else:
-# result = "$$1/*.so"
-
-#### Keys ignored in scope 69:.:../3rdparty/t9write:../3rdparty/t9write/t9write-build.pri:WIN32:
-# result = "$$1/*.dll"
-
-#### Keys ignored in scope 70:.:../3rdparty/t9write:../3rdparty/t9write/t9write-build.pri:else:
-# result = "$$1/*.so"
-
-#### Keys ignored in scope 72:.:../3rdparty/t9write:../3rdparty/t9write/t9write-build.pri:(T9WRITE_ALPHABETIC_FOUND EQUAL 1):
-# T9WRITE_ALPHABETIC_LIBS = "$$findSharedLibrary($$PWD/$$T9WRITE_BUILD_SHARED_DIR/alphabetic)"
-
-#### Keys ignored in scope 73:.:../3rdparty/t9write:../3rdparty/t9write/t9write-build.pri:NOT T9WRITE_ALPHABETIC_LIBS_ISEMPTY:
-# T9WRITE_ALPHABETIC_BINS = "$$findSharedBinary($$PWD/$$T9WRITE_BUILD_SHARED_DIR/alphabetic)"
-
-#### Keys ignored in scope 74:.:../3rdparty/t9write:../3rdparty/t9write/t9write-build.pri:else:
-# T9WRITE_ALPHABETIC_LIBS = "$$findStaticLibrary($$PWD/$$T9WRITE_BUILD_STATIC_DIR/alphabetic)"
-
-#### Keys ignored in scope 75:.:../3rdparty/t9write:../3rdparty/t9write/t9write-build.pri:(T9WRITE_CJK_FOUND EQUAL 1):
-# T9WRITE_CJK_LIBS = "$$findSharedLibrary($$PWD/$$T9WRITE_BUILD_SHARED_DIR/cjk)"
-
-#### Keys ignored in scope 76:.:../3rdparty/t9write:../3rdparty/t9write/t9write-build.pri:NOT T9WRITE_CJK_LIBS_ISEMPTY:
-# T9WRITE_CJK_BINS = "$$findSharedBinary($$PWD/$$T9WRITE_BUILD_SHARED_DIR/cjk)"
-
-#### Keys ignored in scope 77:.:../3rdparty/t9write:../3rdparty/t9write/t9write-build.pri:else:
-# T9WRITE_CJK_LIBS = "$$findStaticLibrary($$PWD/$$T9WRITE_BUILD_STATIC_DIR/cjk)"
-
-#### Keys ignored in scope 78:.:../3rdparty/t9write:../3rdparty/t9write/t9write-build.pri:(T9WRITE_ALPHABETIC_FOUND EQUAL 1) AND NOT T9WRITE_ALPHABETIC_LIBS_ISEMPTY:
-# T9WRITE_FOUND = "1"
-
-#### Keys ignored in scope 79:.:../3rdparty/t9write:../3rdparty/t9write/t9write-build.pri:(T9WRITE_CJK_FOUND EQUAL 1) AND NOT T9WRITE_CJK_LIBS_ISEMPTY:
-# T9WRITE_FOUND = "1"
diff --git a/src/plugins/t9write/plugin/t9writedictionary.cpp b/src/plugins/t9write/plugin/t9writedictionary.cpp
deleted file mode 100644
index 5a17ae6d..00000000
--- a/src/plugins/t9write/plugin/t9writedictionary.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 or (at your option) any later version
-** approved by the KDE Free Qt Foundation. The licenses are as published by
-** the Free Software Foundation and appearing in the file LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "t9writedictionary_p.h"
-#include <QLoggingCategory>
-
-QT_BEGIN_NAMESPACE
-namespace QtVirtualKeyboard {
-
-Q_DECLARE_LOGGING_CATEGORY(lcT9Write)
-
-T9WriteDictionary::T9WriteDictionary(DECUMA_SESSION *decumaSession,
- const DECUMA_MEM_FUNCTIONS &memFuncs,
- bool cjk) :
- decumaSession(decumaSession),
- memFuncs(memFuncs),
- cjk(cjk),
- sourceData(nullptr),
- sourceSize(0),
- convertedData(nullptr),
- convertedSize(0)
-{
-}
-
-T9WriteDictionary::~T9WriteDictionary()
-{
- if (convertedData) {
- DECUMA_STATUS status = DECUMA_API(DestroyConvertedDictionary)(&convertedData, &memFuncs);
- Q_ASSERT(status == decumaNoError);
- Q_ASSERT(convertedData == nullptr);
- }
-}
-
-bool T9WriteDictionary::load(const QString &fileName)
-{
- if (sourceData || convertedData)
- return false;
-
- file.setFileName(fileName);
- if (file.open(QIODevice::ReadOnly)) {
- sourceSize = file.size();
- sourceData = file.map(0, sourceSize, QFile::NoOptions);
- if (!sourceData) {
- sourceSize = 0;
- qCWarning(lcT9Write) << "Could not read dictionary file" << fileName;
- }
- file.close();
- } else {
- qCWarning(lcT9Write) << "Could not open dictionary file" << fileName;
- }
-
- return sourceData != nullptr;
-}
-
-bool T9WriteDictionary::convert(const DECUMA_SRC_DICTIONARY_INFO &dictionaryInfo)
-{
- if (!sourceData || convertedData)
- return false;
-
- DECUMA_STATUS status;
- status = DECUMA_API(ConvertDictionary)(&convertedData, sourceData, (DECUMA_UINT32)sourceSize,
- &dictionaryInfo, &convertedSize, &memFuncs);
-
- if (status != decumaNoError) {
- qCWarning(lcT9Write) << "Could not convert dictionary" << file.fileName();
- file.unmap((uchar *)sourceData);
- sourceSize = 0;
- sourceData = nullptr;
- }
-
- return status == decumaNoError;
-}
-
-QString T9WriteDictionary::fileName() const
-{
- return file.fileName();
-}
-
-const void *T9WriteDictionary::data() const
-{
- return convertedData ? convertedData : sourceData;
-}
-
-qint64 T9WriteDictionary::size() const
-{
- return convertedData ? convertedSize : sourceSize;
-}
-
-bool T9WriteDictionary::isConverted() const
-{
- return convertedData != nullptr;
-}
-
-} // namespace QtVirtualKeyboard
-QT_END_NAMESPACE
diff --git a/src/virtualkeyboard/.prev_configure.cmake b/src/virtualkeyboard/.prev_configure.cmake
index 0cd91f0c..d11fe3d0 100644
--- a/src/virtualkeyboard/.prev_configure.cmake
+++ b/src/virtualkeyboard/.prev_configure.cmake
@@ -11,10 +11,10 @@ set_property(CACHE INPUT_vkb_hunspell PROPERTY STRINGS undefined no 3rdparty sys
#### Libraries
qt_find_package(Hunspell PROVIDED_TARGETS Hunspell::Hunspell MODULE_NAME virtualkeyboard QMAKE_LIB hunspell)
-if((LINUX) OR QT_FIND_ALL_PACKAGES_ALWAYS)
+if((X11_SUPPORTED) OR QT_FIND_ALL_PACKAGES_ALWAYS)
qt_find_package(XCB 1.11 PROVIDED_TARGETS XCB::XCB MODULE_NAME virtualkeyboard QMAKE_LIB xcb)
endif()
-if((LINUX) OR QT_FIND_ALL_PACKAGES_ALWAYS)
+if((X11_SUPPORTED) OR QT_FIND_ALL_PACKAGES_ALWAYS)
qt_find_package(XCB COMPONENTS XFIXES PROVIDED_TARGETS XCB::XFIXES MODULE_NAME virtualkeyboard QMAKE_LIB xcb-xfixes)
endif()
qt_add_qmake_lib_dependency(xcb-xfixes xcb)
@@ -65,20 +65,54 @@ qt_feature("vkb-sensitive-debug" PRIVATE
LABEL "Sensitive Debug"
AUTODETECT OFF
)
-qt_feature("t9write-alphabetic" PRIVATE
- LABEL " Alphabetic"
- CONDITION VKB_HAVE_T9WRITE_ALPHA
+qt_feature("cerence-sdk" PRIVATE
+ LABEL "Cerence"
+ CONDITION tests.cerence-sdk OR FIXME
)
-qt_feature("t9write-cjk" PRIVATE
- LABEL " CJK"
- CONDITION VKB_HAVE_T9WRITE_CJK
-)
-qt_feature("t9write" PRIVATE
- LABEL "T9Write handwriting"
- CONDITION QT_FEATURE_t9write_alphabetic OR QT_FEATURE_t9write_cjk
- ENABLE INPUT_vkb_handwriting STREQUAL 't9write'
+qt_feature("cerence-hwr" PRIVATE
+ LABEL " Handwriting"
+ CONDITION QT_FEATURE_cerence_hwr_alphabetic OR QT_FEATURE_cerence_hwr_cjk
+ ENABLE INPUT_vkb_handwriting STREQUAL 'cerence-hwr'
DISABLE INPUT_vkb_handwriting STREQUAL 'no'
)
+qt_feature("cerence-hwr-alphabetic" PRIVATE
+ LABEL " Alphabetic"
+ CONDITION tests.cerence-hwr-alphabetic OR FIXME
+)
+qt_feature("cerence-hwr-cjk" PRIVATE
+ LABEL " CJK"
+ CONDITION tests.cerence-hwr-cjk OR FIXME
+)
+qt_feature("vkb-bundle-cerence" PUBLIC
+ LABEL " Bundle resources"
+ AUTODETECT OFF
+)
+qt_feature("vkb-bundle-cerence-hwr" PUBLIC
+ LABEL " Handwriting"
+ AUTODETECT OFF
+ ENABLE QT_FEATURE_vkb_bundle_cerence
+)
+qt_feature("vkb-bundle-cerence-xt9" PUBLIC
+ LABEL " XT9"
+ AUTODETECT OFF
+ ENABLE QT_FEATURE_vkb_bundle_cerence
+)
+qt_feature("cerence-xt9" PRIVATE
+ LABEL " XT9"
+ CONDITION feature.cerence-sdk AND tests.cerence-xt9 OR FIXME
+)
+qt_feature("vkb-cerence-xt9-debug" PUBLIC
+ LABEL " XT9 Debug"
+ AUTODETECT OFF
+)
+qt_feature("vkb-cerence-xt9-9key-layouts" PUBLIC
+ LABEL " XT9 9-key layouts"
+ AUTODETECT OFF
+)
+qt_feature("vkb-cerence-static" PUBLIC
+ LABEL " Static Linking"
+ AUTODETECT OFF
+)
qt_feature("system-hunspell" PRIVATE
LABEL "System Hunspell"
CONDITION Hunspell_FOUND
@@ -91,10 +125,12 @@ qt_feature("3rdparty-hunspell" PRIVATE
qt_feature("hunspell" PRIVATE
LABEL "Hunspell"
CONDITION QT_FEATURE_3rdparty_hunspell OR QT_FEATURE_system_hunspell
+ DISABLE feature.cerence-xt9 OR FIXME
)
qt_feature("openwnn" PRIVATE
LABEL "OpenWnn"
AUTODETECT ( NOT INPUT_lang_ja_JP STREQUAL 'no' )
+ DISABLE feature.cerence-xt9 OR FIXME
)
qt_feature("vkb-myscript" PRIVATE
LABEL "MyScript"
@@ -103,6 +139,7 @@ qt_feature("vkb-myscript" PRIVATE
qt_feature("pinyin" PRIVATE
LABEL "libpinyin"
AUTODETECT ( NOT INPUT_lang_ch_CN STREQUAL 'no' )
+ DISABLE feature.cerence-xt9 OR FIXME
)
qt_feature("vkb-no-bundle-pinyin" PRIVATE
LABEL "Disable resource bundle for the pinyin"
@@ -112,6 +149,7 @@ qt_feature("tcime" PRIVATE
LABEL "Traditional Chinese IME (tcime)"
AUTODETECT ( NOT INPUT_lang_ch_TW STREQUAL 'no' )
CONDITION QT_FEATURE_zhuyin OR QT_FEATURE_cangjie
+ DISABLE feature.cerence-xt9 OR FIXME
)
qt_feature("vkb-no-bundle-tcime" PRIVATE
LABEL "Disable resource bundle for the tcime"
@@ -120,16 +158,22 @@ qt_feature("vkb-no-bundle-tcime" PRIVATE
qt_feature("zhuyin" PRIVATE
LABEL "Zhuyin"
AUTODETECT ( NOT INPUT_lang_zh_TW STREQUAL 'no' )
+ DISABLE feature.cerence-xt9 OR FIXME
)
qt_feature("cangjie" PRIVATE
LABEL "Cangjie"
AUTODETECT ( NOT INPUT_lang_zh_TW STREQUAL 'no' )
+ DISABLE feature.cerence-xt9 OR FIXME
)
qt_feature("hangul" PRIVATE
LABEL "Hangul"
+ AUTODETECT ( NOT INPUT_lang_ko_KR STREQUAL 'no' )
+ DISABLE feature.cerence-xt9 OR FIXME
)
qt_feature("thai" PRIVATE
LABEL "Thai"
+ AUTODETECT ( NOT INPUT_lang_th_TH STREQUAL 'no' )
+ DISABLE feature.cerence-xt9 OR FIXME
)
qt_feature("vkb-lang-ar_AR" PRIVATE
LABEL "Arabic"
@@ -217,7 +261,7 @@ qt_feature("vkb-lang-it_IT" PRIVATE
)
qt_feature("vkb-lang-ja_JP" PRIVATE
LABEL "Japanese"
- CONDITION QT_FEATURE_openwnn
+ CONDITION QT_FEATURE_openwnn OR QT_FEATURE_cerence_xt9
)
qt_feature("vkb-lang-ko_KR" PRIVATE
LABEL "Korean"
@@ -277,7 +321,7 @@ qt_feature("vkb-lang-sv_SE" PRIVATE
)
qt_feature("vkb-lang-th_TH" PRIVATE
LABEL "Thai"
- CONDITION QT_FEATURE_thai
+ CONDITION QT_FEATURE_thai OR QT_FEATURE_cerence_xt9
)
qt_feature("vkb-lang-tr_TR" PRIVATE
LABEL "Turkish"
@@ -294,12 +338,17 @@ qt_feature("vkb-lang-vi_VN" PRIVATE
qt_feature("vkb-lang-zh_CN" PRIVATE
LABEL "Simplified Chinese"
AUTODETECT ( NOT INPUT_lang_zh_CN STREQUAL 'no' )
- CONDITION QT_FEATURE_pinyin
+ CONDITION QT_FEATURE_pinyin OR QT_FEATURE_cerence_xt9
)
qt_feature("vkb-lang-zh_TW" PRIVATE
LABEL "Traditional Chinese"
AUTODETECT ( NOT INPUT_lang_zh_TW STREQUAL 'no' )
- CONDITION QT_FEATURE_tcime OR QT_FEATURE_zhuyin OR QT_FEATURE_cangjie
+ CONDITION QT_FEATURE_tcime OR QT_FEATURE_zhuyin OR QT_FEATURE_cangjie OR QT_FEATURE_cerence_xt9
+)
+qt_feature("vkb-lang-zh_HK" PRIVATE
+ LABEL "HongKong Chinese"
+ AUTODETECT ( NOT INPUT_lang_zh_HK STREQUAL 'no' )
+ CONDITION QT_FEATURE_cerence_xt9
)
qt_configure_add_summary_section(NAME "Qt Virtualkeyboard")
qt_configure_add_summary_entry(ARGS "vkb-desktop")
@@ -307,9 +356,17 @@ qt_configure_add_summary_entry(ARGS "vkb-layouts")
qt_configure_add_summary_entry(ARGS "vkb-arrow-keynavigation")
qt_configure_add_summary_entry(ARGS "vkb-retro-style")
qt_configure_add_summary_entry(ARGS "vkb-sensitive-debug")
-qt_configure_add_summary_entry(ARGS "t9write")
-qt_configure_add_summary_entry(ARGS "t9write-alphabetic")
-qt_configure_add_summary_entry(ARGS "t9write-cjk")
+qt_configure_add_summary_entry(ARGS "cerence-sdk")
+qt_configure_add_summary_entry(ARGS "vkb-cerence-static")
+qt_configure_add_summary_entry(ARGS "cerence-hwr")
+qt_configure_add_summary_entry(ARGS "cerence-hwr-alphabetic")
+qt_configure_add_summary_entry(ARGS "cerence-hwr-cjk")
+qt_configure_add_summary_entry(ARGS "cerence-xt9")
+qt_configure_add_summary_entry(ARGS "vkb-cerence-xt9-debug")
+qt_configure_add_summary_entry(ARGS "vkb-cerence-xt9-9key-layouts")
+qt_configure_add_summary_entry(ARGS "vkb-bundle-cerence")
+qt_configure_add_summary_entry(ARGS "vkb-bundle-cerence-hwr")
+qt_configure_add_summary_entry(ARGS "vkb-bundle-cerence-xt9")
qt_configure_add_summary_entry(ARGS "hunspell")
qt_configure_add_summary_entry(ARGS "3rdparty-hunspell")
qt_configure_add_summary_entry(ARGS "openwnn")
@@ -365,8 +422,8 @@ qt_configure_end_summary_section() # end of "Traditional chinese input methods"
qt_configure_end_summary_section() # end of "Qt Virtualkeyboard" section
qt_configure_add_report_entry(
TYPE ERROR
- MESSAGE "T9Write SDK could not be found. For more information, see the documentation in 'Building Qt Virtual Keyboard'."
- CONDITION INPUT_vkb_handwriting STREQUAL 't9write' AND NOT QT_FEATURE_t9write
+ MESSAGE "Cerence HWR SDK could not be found. For more information, see the documentation in 'Building Qt Virtual Keyboard'."
+ CONDITION INPUT_vkb_handwriting STREQUAL 'cerence-hwr' AND NOT QT_FEATURE_cerence_hwr
)
qt_configure_add_report_entry(
TYPE NOTE
diff --git a/src/virtualkeyboard/CMakeLists.txt b/src/virtualkeyboard/CMakeLists.txt
index 6080b603..17c74a93 100644
--- a/src/virtualkeyboard/CMakeLists.txt
+++ b/src/virtualkeyboard/CMakeLists.txt
@@ -122,16 +122,11 @@ qt_internal_add_resource(VirtualKeyboard "virtualkeyboard_content"
#### Keys ignored in scope 1:.:.:virtualkeyboard.pro:<TRUE>:
# LAYOUT_FILES = "content/layouts/fallback/dialpad.qml" "content/layouts/fallback/digits.qml" "content/layouts/fallback/numbers.qml" "content/layouts/fallback/main.qml" "content/layouts/fallback/symbols.qml"
# MODULE = "virtualkeyboard"
-# OTHER_FILES = "$$PWD/qtvirtualkeyboard.qdocconf" "$$PWD/src/qtvirtualkeyboard-index.qdoc" "$$PWD/src/deployment-guide.qdoc" "$$PWD/src/technical-guide.qdoc" "$$PWD/src/user-guide.qdoc" "$$PWD/src/build.qdoc" "$$PWD/src/snippets/CustomInputMethod.qml" "content/styles/default/*.qml" "content/styles/retro/*.qml" "content/*.qml" "content/components/*.qml" "qtvirtualkeyboard.json" "$$LAYOUT_FILES"
+# OTHER_FILES = "$$PWD/images/*.*" "$$PWD/images/layouts/*.*" "$$PWD/qtvirtualkeyboard.qdocconf" "$$PWD/src/*.qdoc" "$$PWD/src/includes/*.qdocinc" "content/styles/default/*.qml" "content/styles/retro/*.qml" "content/*.qml" "content/components/*.qml" "qtvirtualkeyboard.json" "$$LAYOUT_FILES"
## Scopes:
#####################################################################
-qt_internal_extend_target(VirtualKeyboard CONDITION QT_FEATURE_vkb_sensitive_debug
- PUBLIC_DEFINES
- SENSITIVE_DEBUG
-)
-
if(NOT no-builtin-style)
# Resources:
set(virtualkeyboard_default_style_resource_files
diff --git a/src/virtualkeyboard/configure.cmake b/src/virtualkeyboard/configure.cmake
index 7fdf29ca..52ef7d05 100644
--- a/src/virtualkeyboard/configure.cmake
+++ b/src/virtualkeyboard/configure.cmake
@@ -6,6 +6,8 @@
set(INPUT_vkb_hunspell "undefined" CACHE STRING "")
set_property(CACHE INPUT_vkb_hunspell PROPERTY STRINGS undefined no 3rdparty system)
+# input vkb-cerence-sdk
+set(INPUT_vkb_cerence_sdk "" CACHE PATH "")
#### Libraries
@@ -18,12 +20,13 @@ if((LINUX) OR QT_FIND_ALL_PACKAGES_ALWAYS AND NOT TARGET XCB::XFIXES) # special
qt_find_package(XCB COMPONENTS XFIXES PROVIDED_TARGETS XCB::XFIXES MODULE_NAME virtualkeyboard QMAKE_LIB xcb-xfixes)
endif()
qt_add_qmake_lib_dependency(xcb-xfixes xcb)
-
+qt_find_package(CerenceHwrAlphabetic PROVIDED_TARGETS Cerence::HWR::Alphabetic MODULE_NAME virtualkeyboard QMAKE_LIB t9write-ucr)
+qt_find_package(CerenceHwrCjk PROVIDED_TARGETS Cerence::HWR::CJK MODULE_NAME virtualkeyboard QMAKE_LIB t9write-cjk)
+qt_find_package(CerenceXt9 PROVIDED_TARGETS Cerence::XT9 MODULE_NAME virtualkeyboard QMAKE_LIB xt9-acktn)
#### Tests
-
#### Features
qt_feature("vkb-record-trace-input" PUBLIC
@@ -65,19 +68,59 @@ qt_feature("vkb-sensitive-debug" PRIVATE
LABEL "Sensitive Debug"
AUTODETECT OFF
)
-qt_feature("t9write-alphabetic" PRIVATE
- LABEL " Alphabetic"
- CONDITION VKB_HAVE_T9WRITE_ALPHA
+qt_feature("cerence-sdk" PRIVATE
+ LABEL "Cerence"
+ AUTODETECT CERENCE_HWR_ALPHABETIC_FOUND OR CERENCE_XT9_FOUND
)
-qt_feature("t9write-cjk" PRIVATE
- LABEL " CJK"
- CONDITION VKB_HAVE_T9WRITE_CJK
+qt_feature("cerence-hwr" PRIVATE
+ LABEL " Handwriting"
+ CONDITION QT_FEATURE_cerence_hwr_alphabetic OR QT_FEATURE_cerence_hwr_cjk
+ ENABLE INPUT_vkb_handwriting STREQUAL 'cerence-hwr'
+ DISABLE INPUT_vkb_handwriting STREQUAL 'no'
+)
+qt_feature("cerence-hwr-alphabetic" PRIVATE
+ LABEL " Alphabetic"
+ CONDITION QT_FEATURE_cerence_sdk
+ ENABLE INPUT_vkb_handwriting STREQUAL 'cerence-hwr'
+ DISABLE INPUT_vkb_handwriting STREQUAL 'no'
+ AUTODETECT CERENCE_HWR_ALPHABETIC_FOUND
)
-qt_feature("t9write" PRIVATE
- LABEL "T9Write handwriting"
- CONDITION QT_FEATURE_t9write_alphabetic OR QT_FEATURE_t9write_cjk
- ENABLE INPUT_vkb_handwriting STREQUAL 't9write'
+qt_feature("cerence-hwr-cjk" PRIVATE
+ LABEL " CJK"
+ CONDITION QT_FEATURE_cerence_sdk
+ ENABLE INPUT_vkb_handwriting STREQUAL 'cerence-hwr'
DISABLE INPUT_vkb_handwriting STREQUAL 'no'
+ AUTODETECT CERENCE_HWR_CJK_FOUND
+)
+qt_feature("vkb-bundle-cerence" PUBLIC
+ LABEL " Bundle resources"
+ AUTODETECT OFF
+)
+qt_feature("vkb-bundle-cerence-hwr" PUBLIC
+ LABEL " Handwriting"
+ AUTODETECT OFF
+ ENABLE FEATURE_vkb_bundle_cerence
+)
+qt_feature("vkb-bundle-cerence-xt9" PUBLIC
+ LABEL " XT9"
+ AUTODETECT OFF
+ ENABLE FEATURE_vkb_bundle_cerence
+)
+qt_feature("cerence-xt9" PRIVATE
+ LABEL " XT9"
+ CONDITION CERENCE_XT9_FOUND
+)
+qt_feature("vkb-cerence-xt9-debug" PUBLIC
+ LABEL " XT9 Debug"
+ AUTODETECT OFF
+)
+qt_feature("vkb-cerence-xt9-9key-layouts" PUBLIC
+ LABEL " XT9 9-key layouts"
+ AUTODETECT OFF
+)
+qt_feature("vkb-cerence-static" PUBLIC
+ LABEL " Static Linking"
+ AUTODETECT OFF
)
qt_feature("system-hunspell" PRIVATE
LABEL "System Hunspell"
@@ -91,10 +134,12 @@ qt_feature("3rdparty-hunspell" PRIVATE
qt_feature("hunspell" PRIVATE
LABEL "Hunspell"
CONDITION QT_FEATURE_3rdparty_hunspell OR QT_FEATURE_system_hunspell
+ DISABLE QT_FEATURE_cerence_xt9
)
qt_feature("openwnn" PRIVATE
LABEL "OpenWnn"
AUTODETECT ( NOT INPUT_lang_ja_JP STREQUAL 'no' )
+ DISABLE QT_FEATURE_cerence_xt9
)
qt_feature("vkb-myscript" PRIVATE
LABEL "MyScript"
@@ -103,6 +148,7 @@ qt_feature("vkb-myscript" PRIVATE
qt_feature("pinyin" PRIVATE
LABEL "libpinyin"
AUTODETECT ( NOT INPUT_lang_ch_CN STREQUAL 'no' )
+ DISABLE QT_FEATURE_cerence_xt9
)
qt_feature("vkb-no-bundle-pinyin" PRIVATE
LABEL "Disable resource bundle for the pinyin"
@@ -112,6 +158,7 @@ qt_feature("tcime" PRIVATE
LABEL "Traditional Chinese IME (tcime)"
AUTODETECT ( NOT INPUT_lang_ch_TW STREQUAL 'no' )
CONDITION QT_FEATURE_zhuyin OR QT_FEATURE_cangjie
+ DISABLE QT_FEATURE_cerence_xt9
)
qt_feature("vkb-no-bundle-tcime" PRIVATE
LABEL "Disable resource bundle for the tcime"
@@ -120,16 +167,22 @@ qt_feature("vkb-no-bundle-tcime" PRIVATE
qt_feature("zhuyin" PRIVATE
LABEL "Zhuyin"
AUTODETECT ( NOT INPUT_lang_zh_TW STREQUAL 'no' )
+ DISABLE QT_FEATURE_cerence_xt9
)
qt_feature("cangjie" PRIVATE
LABEL "Cangjie"
AUTODETECT ( NOT INPUT_lang_zh_TW STREQUAL 'no' )
+ DISABLE QT_FEATURE_cerence_xt9
)
qt_feature("hangul" PRIVATE
LABEL "Hangul"
+ AUTODETECT ( NOT INPUT_lang_ko_KR STREQUAL 'no' )
+ DISABLE QT_FEATURE_cerence_xt9
)
qt_feature("thai" PRIVATE
LABEL "Thai"
+ AUTODETECT ( NOT INPUT_lang_th_TH STREQUAL 'no' )
+ DISABLE QT_FEATURE_cerence_xt9
)
qt_feature("vkb-lang-ar_AR" PRIVATE
LABEL "Arabic"
@@ -217,7 +270,7 @@ qt_feature("vkb-lang-it_IT" PRIVATE
)
qt_feature("vkb-lang-ja_JP" PRIVATE
LABEL "Japanese"
- CONDITION QT_FEATURE_openwnn
+ CONDITION QT_FEATURE_openwnn OR QT_FEATURE_cerence_xt9
)
qt_feature("vkb-lang-ko_KR" PRIVATE
LABEL "Korean"
@@ -277,7 +330,7 @@ qt_feature("vkb-lang-sv_SE" PRIVATE
)
qt_feature("vkb-lang-th_TH" PRIVATE
LABEL "Thai"
- CONDITION QT_FEATURE_thai
+ CONDITION QT_FEATURE_thai OR QT_FEATURE_cerence_xt9
)
qt_feature("vkb-lang-tr_TR" PRIVATE
LABEL "Turkish"
@@ -294,12 +347,17 @@ qt_feature("vkb-lang-vi_VN" PRIVATE
qt_feature("vkb-lang-zh_CN" PRIVATE
LABEL "Simplified Chinese"
AUTODETECT ( NOT INPUT_lang_zh_CN STREQUAL 'no' )
- CONDITION QT_FEATURE_pinyin
+ CONDITION QT_FEATURE_pinyin OR QT_FEATURE_cerence_xt9
)
qt_feature("vkb-lang-zh_TW" PRIVATE
LABEL "Traditional Chinese"
AUTODETECT ( NOT INPUT_lang_zh_TW STREQUAL 'no' )
- CONDITION QT_FEATURE_tcime OR QT_FEATURE_zhuyin OR QT_FEATURE_cangjie
+ CONDITION QT_FEATURE_tcime OR QT_FEATURE_zhuyin OR QT_FEATURE_cangjie OR QT_FEATURE_cerence_xt9
+)
+qt_feature("vkb-lang-zh_HK" PRIVATE
+ LABEL "HongKong Chinese"
+ AUTODETECT ( NOT INPUT_lang_zh_HK STREQUAL 'no' )
+ CONDITION QT_FEATURE_cerence_xt9
)
qt_configure_add_summary_section(NAME "Qt Virtualkeyboard")
qt_configure_add_summary_entry(ARGS "vkb-desktop")
@@ -307,9 +365,17 @@ qt_configure_add_summary_entry(ARGS "vkb-layouts")
qt_configure_add_summary_entry(ARGS "vkb-arrow-keynavigation")
qt_configure_add_summary_entry(ARGS "vkb-retro-style")
qt_configure_add_summary_entry(ARGS "vkb-sensitive-debug")
-qt_configure_add_summary_entry(ARGS "t9write")
-qt_configure_add_summary_entry(ARGS "t9write-alphabetic")
-qt_configure_add_summary_entry(ARGS "t9write-cjk")
+qt_configure_add_summary_entry(ARGS "cerence-sdk")
+qt_configure_add_summary_entry(ARGS "vkb-cerence-static")
+qt_configure_add_summary_entry(ARGS "cerence-hwr")
+qt_configure_add_summary_entry(ARGS "cerence-hwr-alphabetic")
+qt_configure_add_summary_entry(ARGS "cerence-hwr-cjk")
+qt_configure_add_summary_entry(ARGS "cerence-xt9")
+qt_configure_add_summary_entry(ARGS "vkb-cerence-xt9-debug")
+qt_configure_add_summary_entry(ARGS "vkb-cerence-xt9-9key-layouts")
+qt_configure_add_summary_entry(ARGS "vkb-bundle-cerence")
+qt_configure_add_summary_entry(ARGS "vkb-bundle-cerence-hwr")
+qt_configure_add_summary_entry(ARGS "vkb-bundle-cerence-xt9")
qt_configure_add_summary_entry(ARGS "hunspell")
qt_configure_add_summary_entry(ARGS "3rdparty-hunspell")
qt_configure_add_summary_entry(ARGS "openwnn")
@@ -357,6 +423,7 @@ qt_configure_add_summary_entry(ARGS "vkb-lang-uk_UA")
qt_configure_add_summary_entry(ARGS "vkb-lang-vi_VN")
qt_configure_add_summary_entry(ARGS "vkb-lang-zh_CN")
qt_configure_add_summary_entry(ARGS "vkb-lang-zh_TW")
+qt_configure_add_summary_entry(ARGS "vkb-lang-zh_HK")
qt_configure_end_summary_section() # end of "Language support enabled for" section
qt_configure_add_summary_section(NAME "Traditional chinese input methods")
qt_configure_add_summary_entry(ARGS "zhuyin")
@@ -365,8 +432,8 @@ qt_configure_end_summary_section() # end of "Traditional chinese input methods"
qt_configure_end_summary_section() # end of "Qt Virtualkeyboard" section
qt_configure_add_report_entry(
TYPE ERROR
- MESSAGE "T9Write SDK could not be found. For more information, see the documentation in 'Building Qt Virtual Keyboard'."
- CONDITION INPUT_vkb_handwriting STREQUAL 't9write' AND NOT QT_FEATURE_t9write
+ MESSAGE "Cerence HWR SDK could not be found. For more information, see the documentation in 'Building Qt Virtual Keyboard'."
+ CONDITION INPUT_vkb_handwriting STREQUAL 'cerence-hwr' AND NOT QT_FEATURE_cerence_hwr
)
qt_configure_add_report_entry(
TYPE NOTE
diff --git a/src/virtualkeyboard/configure.json b/src/virtualkeyboard/configure.json
index a26ff6ef..73b23d86 100644
--- a/src/virtualkeyboard/configure.json
+++ b/src/virtualkeyboard/configure.json
@@ -12,10 +12,17 @@
"vkb-cangjie": { "type": "boolean", "value": "cangjie" },
"vkb-zhuyin": { "type": "boolean", "value": "zhuyin" },
"vkb-hunspell": { "type": "enum", "values": [ "no", "3rdparty", "system" ] },
- "vkb-handwriting": { "type": "optionalString", "values": [ "yes", "no", "t9write" ] },
+ "vkb-handwriting": { "type": "optionalString", "values": [ "yes", "no", "cerence-hwr" ] },
+ "vkb-cerence-sdk": { "type": "string" },
"vkb-style": { "type": "string", "values": [ "standard", "retro" , "none"] },
"vkb-no-bundle-pinyin": "boolean",
- "vkb-no-bundle-tcime": "boolean"
+ "vkb-no-bundle-tcime": "boolean",
+ "vkb-cerence-static": "boolean",
+ "vkb-bundle-cerence": "boolean",
+ "vkb-bundle-cerence-hwr": "boolean",
+ "vkb-bundle-cerence-xt9": "boolean",
+ "vkb-cerence-xt9-debug": "boolean",
+ "vkb-cerence-xt9-9key-layouts": "boolean"
}
},
@@ -52,13 +59,21 @@
"label": "Hunspell copy under 3rdparty/",
"type": "3rdparty-hunspell"
},
- "t9write-alphabetic": {
- "label" : "T9Write Alphabetic Support",
- "type" : "t9write-alphabetic"
+ "cerence-sdk": {
+ "label": "Cerence SDK",
+ "type": "cerence-sdk"
},
- "t9write-cjk": {
- "label" : "T9Write CJK Support",
- "type" : "t9write-cjk"
+ "cerence-hwr-alphabetic": {
+ "label": "Cerence HWR Alphabetic Support",
+ "type": "cerence-hwr-alphabetic"
+ },
+ "cerence-hwr-cjk": {
+ "label": "Cerence HWR CJK Support",
+ "type": "cerence-hwr-cjk"
+ },
+ "cerence-xt9": {
+ "label": "Cerence XT9",
+ "type": "cerence-xt9"
}
},
@@ -111,24 +126,65 @@
"autoDetect": false,
"output": [ "privateFeature" ]
},
-
- "t9write-alphabetic": {
- "label": " Alphabetic",
- "condition": "tests.t9write-alphabetic",
+ "cerence-sdk": {
+ "label": "Cerence",
+ "condition": "tests.cerence-sdk",
+ "output": [ "privateFeature" ]
+ },
+ "cerence-hwr": {
+ "label": " Handwriting",
+ "enable": "input.vkb-handwriting == 'cerence-hwr'",
+ "disable": "input.vkb-handwriting == 'no'",
+ "condition": "features.cerence-hwr-alphabetic || features.cerence-hwr-cjk",
"output": [ "privateFeature" ]
},
- "t9write-cjk": {
- "label": " CJK",
- "condition": "tests.t9write-cjk",
+ "cerence-hwr-alphabetic": {
+ "label": " Alphabetic",
+ "condition": "tests.cerence-hwr-alphabetic",
"output": [ "privateFeature" ]
},
- "t9write": {
- "label": "T9Write handwriting",
- "enable": "input.vkb-handwriting == 't9write'",
- "disable": "input.vkb-handwriting == 'no'",
- "condition": "features.t9write-alphabetic || features.t9write-cjk",
+ "cerence-hwr-cjk": {
+ "label": " CJK",
+ "condition": "tests.cerence-hwr-cjk",
+ "output": [ "privateFeature" ]
+ },
+ "vkb-bundle-cerence": {
+ "label": " Bundle resources",
+ "autoDetect": false,
+ "output": [ "publicFeature" ]
+ },
+ "vkb-bundle-cerence-hwr": {
+ "label": " Handwriting",
+ "enable": "features.vkb-bundle-cerence",
+ "autoDetect": false,
+ "output": [ "publicFeature" ]
+ },
+ "vkb-bundle-cerence-xt9": {
+ "label": " XT9",
+ "enable": "features.vkb-bundle-cerence",
+ "autoDetect": false,
+ "output": [ "publicFeature" ]
+ },
+ "cerence-xt9": {
+ "label": " XT9",
+ "condition": "feature.cerence-sdk && tests.cerence-xt9",
"output": [ "privateFeature" ]
},
+ "vkb-cerence-xt9-debug": {
+ "label": " XT9 Debug",
+ "autoDetect": false,
+ "output": [ "publicFeature" ]
+ },
+ "vkb-cerence-xt9-9key-layouts": {
+ "label": " XT9 9-key layouts",
+ "autoDetect": false,
+ "output": [ "publicFeature" ]
+ },
+ "vkb-cerence-static": {
+ "label": " Static Linking",
+ "autoDetect": false,
+ "output": [ "publicFeature" ]
+ },
"system-hunspell": {
"label": "System Hunspell",
"condition": "libs.hunspell",
@@ -143,11 +199,13 @@
"hunspell": {
"label": "Hunspell",
"condition": "features.3rdparty-hunspell || features.system-hunspell",
+ "disable": "feature.cerence-xt9",
"output": [ "privateFeature" ]
},
"openwnn": {
"label": "OpenWnn",
"autoDetect": "input.lang-ja_JP != 'no'",
+ "disable": "feature.cerence-xt9",
"output": [ "privateFeature" ]
},
"vkb-myscript": {
@@ -158,6 +216,7 @@
"pinyin": {
"label": "libpinyin",
"autoDetect": "input.lang-ch_CN != 'no'",
+ "disable": "feature.cerence-xt9",
"output": [ "privateFeature" ]
},
"vkb-no-bundle-pinyin": {
@@ -169,6 +228,7 @@
"label": "Traditional Chinese IME (tcime)",
"autoDetect": "input.lang-ch_TW != 'no'",
"condition": "features.zhuyin || features.cangjie",
+ "disable": "feature.cerence-xt9",
"output": [ "privateFeature" ]
},
"vkb-no-bundle-tcime": {
@@ -179,21 +239,25 @@
"zhuyin": {
"label": "Zhuyin",
"autoDetect": "input.lang-zh_TW != 'no'",
+ "disable": "feature.cerence-xt9",
"output": [ "privateFeature" ]
},
"cangjie": {
"label": "Cangjie",
"autoDetect": "input.lang-zh_TW != 'no'",
+ "disable": "feature.cerence-xt9",
"output": [ "privateFeature" ]
},
"hangul": {
"label": "Hangul",
- "autoDectect": "input.lang-ko_KR != 'no'",
+ "autoDetect": "input.lang-ko_KR != 'no'",
+ "disable": "feature.cerence-xt9",
"output": [ "privateFeature" ]
},
"thai": {
"label": "Thai",
- "autoDectect": "input.lang-th_TH != 'no'",
+ "autoDetect": "input.lang-th_TH != 'no'",
+ "disable": "feature.cerence-xt9",
"output": [ "privateFeature" ]
},
"vkb-lang-ar_AR": {
@@ -303,7 +367,7 @@
},
"vkb-lang-ja_JP": {
"label": "Japanese",
- "condition": "features.openwnn",
+ "condition": "features.openwnn || features.cerence-xt9",
"output": [ "privateFeature" ]
},
"vkb-lang-ko_KR": {
@@ -378,7 +442,7 @@
},
"vkb-lang-th_TH": {
"label": "Thai",
- "condition": "features.thai",
+ "condition": "features.thai || features.cerence-xt9",
"output": [ "privateFeature" ]
},
"vkb-lang-tr_TR": {
@@ -399,13 +463,19 @@
"vkb-lang-zh_CN": {
"label": "Simplified Chinese",
"autoDetect": "input.lang-zh_CN != 'no'",
- "condition": "features.pinyin",
+ "condition": "features.pinyin || features.cerence-xt9",
"output": [ "privateFeature" ]
},
"vkb-lang-zh_TW": {
"label": "Traditional Chinese",
"autoDetect": "input.lang-zh_TW != 'no'",
- "condition": "features.tcime || features.zhuyin || features.cangjie",
+ "condition": "features.tcime || features.zhuyin || features.cangjie || features.cerence-xt9",
+ "output": [ "privateFeature" ]
+ },
+ "vkb-lang-zh_HK": {
+ "label": "HongKong Chinese",
+ "autoDetect": "input.lang-zh_HK != 'no'",
+ "condition": "features.cerence-xt9",
"output": [ "privateFeature" ]
}
},
@@ -413,9 +483,8 @@
"report": [
{
"type": "error",
- "condition": "input.vkb-handwriting == 't9write' && !features.t9write",
- "message": "T9Write SDK could not be found. For more information,
-see the documentation in 'Building Qt Virtual Keyboard'."
+ "condition": "input.vkb-handwriting == 'cerence-hwr' && !features.cerence-hwr",
+ "message": "Cerence HWR SDK could not be found. For more information, see the documentation in 'Building Qt Virtual Keyboard'."
},
{
"type": "note",
@@ -433,9 +502,17 @@ see the documentation in 'Building Qt Virtual Keyboard'."
"vkb-arrow-keynavigation",
"vkb-retro-style",
"vkb-sensitive-debug",
- "t9write",
- "t9write-alphabetic",
- "t9write-cjk",
+ "cerence-sdk",
+ "vkb-cerence-static",
+ "cerence-hwr",
+ "cerence-hwr-alphabetic",
+ "cerence-hwr-cjk",
+ "cerence-xt9",
+ "vkb-cerence-xt9-debug",
+ "vkb-cerence-xt9-9key-layouts",
+ "vkb-bundle-cerence",
+ "vkb-bundle-cerence-hwr",
+ "vkb-bundle-cerence-xt9",
"hunspell",
"3rdparty-hunspell",
"openwnn",
diff --git a/src/virtualkeyboard/content/layouts/ja_JP/symbols.qml b/src/virtualkeyboard/content/layouts/ja_JP/symbols.qml
index 3a28fe2f..cd80dde2 100644
--- a/src/virtualkeyboard/content/layouts/ja_JP/symbols.qml
+++ b/src/virtualkeyboard/content/layouts/ja_JP/symbols.qml
@@ -33,7 +33,7 @@ import QtQuick.VirtualKeyboard
KeyboardLayoutLoader {
function createInputMethod() {
- return Qt.createQmlObject('import QtQuick; import QtQuick.VirtualKeyboard.Plugins; JapaneseInputMethod {}', parent, "japaneseInputMethod")
+ return Qt.createQmlObject('import QtQuick; import QtQuick.VirtualKeyboard.Plugins; JapaneseInputMethod {}', parent, "symbols.qml")
}
sharedLayouts: ['main']
property int page
diff --git a/src/virtualkeyboard/content/layouts/ko_KR/main.qml b/src/virtualkeyboard/content/layouts/ko_KR/main.qml
index ffa5cfd1..2b2e960b 100644
--- a/src/virtualkeyboard/content/layouts/ko_KR/main.qml
+++ b/src/virtualkeyboard/content/layouts/ko_KR/main.qml
@@ -33,7 +33,7 @@ import QtQuick.Layouts
KeyboardLayoutLoader {
function createInputMethod() {
- return Qt.createQmlObject('import QtQuick; import QtQuick.VirtualKeyboard.Plugins; HangulInputMethod {}', parent, "hangulInputMethod")
+ return Qt.createQmlObject('import QtQuick; import QtQuick.VirtualKeyboard.Plugins; HangulInputMethod {}', parent, "main.qml")
}
sourceComponent: InputContext.shiftActive ? page2 : page1
sharedLayouts: ['symbols']
diff --git a/src/virtualkeyboard/content/layouts/ko_KR/symbols.qml b/src/virtualkeyboard/content/layouts/ko_KR/symbols.qml
index b6dc9cb2..5001d072 100644
--- a/src/virtualkeyboard/content/layouts/ko_KR/symbols.qml
+++ b/src/virtualkeyboard/content/layouts/ko_KR/symbols.qml
@@ -33,7 +33,7 @@ import QtQuick.VirtualKeyboard
KeyboardLayoutLoader {
function createInputMethod() {
- return Qt.createQmlObject('import QtQuick; import QtQuick.VirtualKeyboard.Plugins; HangulInputMethod {}', parent, "hangulInputMethod")
+ return Qt.createQmlObject('import QtQuick; import QtQuick.VirtualKeyboard.Plugins; HangulInputMethod {}', parent, "symbols.qml")
}
sharedLayouts: ['main']
property bool secondPage
diff --git a/src/virtualkeyboard/content/layouts/th_TH/main.qml b/src/virtualkeyboard/content/layouts/th_TH/main.qml
index c7d5ccfa..1be89912 100644
--- a/src/virtualkeyboard/content/layouts/th_TH/main.qml
+++ b/src/virtualkeyboard/content/layouts/th_TH/main.qml
@@ -34,7 +34,7 @@ import QtQuick.VirtualKeyboard
KeyboardLayoutLoader {
inputMode: InputEngine.InputMode.Latin
function createInputMethod() {
- return Qt.createQmlObject('import QtQuick; import QtQuick.VirtualKeyboard.Plugins; ThaiInputMethod {}', parent, "thaiInputMethod")
+ return Qt.createQmlObject('import QtQuick; import QtQuick.VirtualKeyboard.Plugins; ThaiInputMethod {}', parent, "main.qml")
}
sharedLayouts: [ "symbols" ]
sourceComponent: InputContext.shiftActive ? page2 : page1
diff --git a/src/virtualkeyboard/content/layouts/zh_CN/main.qml b/src/virtualkeyboard/content/layouts/zh_CN/main.qml
index 89444c03..37509fa9 100644
--- a/src/virtualkeyboard/content/layouts/zh_CN/main.qml
+++ b/src/virtualkeyboard/content/layouts/zh_CN/main.qml
@@ -33,7 +33,7 @@ import QtQuick.VirtualKeyboard
KeyboardLayout {
function createInputMethod() {
- return Qt.createQmlObject('import QtQuick; import QtQuick.VirtualKeyboard.Plugins; PinyinInputMethod {}', parent, "pinyinInputMethod")
+ return Qt.createQmlObject('import QtQuick; import QtQuick.VirtualKeyboard.Plugins; PinyinInputMethod {}', parent, "main.qml")
}
sharedLayouts: ['symbols']
keyWeight: 160
diff --git a/src/virtualkeyboard/content/layouts/zh_CN/symbols.qml b/src/virtualkeyboard/content/layouts/zh_CN/symbols.qml
index eb16446d..5bf51b39 100644
--- a/src/virtualkeyboard/content/layouts/zh_CN/symbols.qml
+++ b/src/virtualkeyboard/content/layouts/zh_CN/symbols.qml
@@ -33,7 +33,7 @@ import QtQuick.VirtualKeyboard
KeyboardLayoutLoader {
function createInputMethod() {
- return Qt.createQmlObject('import QtQuick; import QtQuick.VirtualKeyboard.Plugins; PinyinInputMethod {}', parent, "pinyinInputMethod")
+ return Qt.createQmlObject('import QtQuick; import QtQuick.VirtualKeyboard.Plugins; PinyinInputMethod {}', parent, "symbols.qml")
}
sharedLayouts: ['main']
property int page
diff --git a/src/virtualkeyboard/content/layouts/zh_TW/symbols.qml b/src/virtualkeyboard/content/layouts/zh_TW/symbols.qml
index 6b0e310e..0352c55e 100644
--- a/src/virtualkeyboard/content/layouts/zh_TW/symbols.qml
+++ b/src/virtualkeyboard/content/layouts/zh_TW/symbols.qml
@@ -33,7 +33,7 @@ import QtQuick.VirtualKeyboard
KeyboardLayoutLoader {
function createInputMethod() {
- return Qt.createQmlObject('import QtQuick; import QtQuick.VirtualKeyboard.Plugins; TCInputMethod {}', parent, "tcInputMethod")
+ return Qt.createQmlObject('import QtQuick; import QtQuick.VirtualKeyboard.Plugins; TCInputMethod {}', parent, "symbols.qml")
}
sharedLayouts: ['main']
property int page
diff --git a/src/virtualkeyboard/doc/src/build.qdoc b/src/virtualkeyboard/doc/src/build.qdoc
index 32ac92d1..2b636cfd 100644
--- a/src/virtualkeyboard/doc/src/build.qdoc
+++ b/src/virtualkeyboard/doc/src/build.qdoc
@@ -112,13 +112,13 @@ keyboard features.
if no other languages are specified.
\row
\li \e -vkb-handwriting
- \li [yes|no|t9write]
+ \li [yes|no|cerence-hwr]
\li Enables or disabled handwriting input
\li This flag enables handwriting input. By default, the first engine
available at build time is used. The engines are chosen in the
- following order: \c t9write. To force handwriting
+ following order: \c cerence-hwr. To force handwriting
input using to use a specific engine, specify the engine to be used;
- for example, \c {-vkb-handwriting t9write}.
+ for example, \c {-vkb-handwriting cerence-hwr}.
\row
\li \e [-no]-vkb-arrow-keynavigation
\li
@@ -187,13 +187,13 @@ qmake $SRCDIR -- [options]
system, or if it is built using the local project file. Integration can be
disabled using this option.
\row
- \li \e vkb-no-bundle-pinyin
+ \li \e -vkb-no-bundle-pinyin
\li \e n/a
\li Disables bundling of pinyin resources
\li This option excludes pinyin resources from the plugin binary. This option may be
used to reduce the plugin binary size.
\row
- \li \e vkb-no-bundle-tcime
+ \li \e -vkb-no-bundle-tcime
\li \e n/a
\li Disables bundling of tcime resources
\li This option excludes tcime resources from the plugin binary. This option may be
@@ -221,6 +221,31 @@ qmake $SRCDIR -- [options]
\li This option activates the OpenWnn input method for the Japanese language.
\include build.qdocinc input-method-language-option-note
+\row
+ \li \e -vkb-cerence-sdk
+ \li \e path/to/cerence/sdk
+ \li Configures the Cerence SDK location and enables the Cerence Handwriting and XT9 integrations.
+ \li The Cerence SDK (zip) must be unpacked using the \e src/virtualkeyboard/plugins/cerence/unpack.py
+ script. By default, the SDK is unpacked to \e src/virtualkeyboard/plugins/cerence/sdk, where
+ the build scripts can pick it up automatically. However, by using the second parameter to the unpack.py
+ script, it is possible to use different location for the SDK. In that case, the location must be
+ passed to the build script using the -vkb-cerence-sdk command line parameter.
+\row
+ \li \e -vkb-cerence-static
+ \li \e handwriting
+ \li Enables static linking of the Cerence Handwriting engine.
+ \li The Cerence Handwriting engine is linked dynamically by default. Use \e -vkb-cerence-static to
+ force static linking.
+\row
+ \li \e -vkb-bundle-cerence-hwr or \e -vkb-bundle-cerence
+ \li \e n/a
+ \li Enables bundling of Cerence Handwriting resources
+ \li This option bundles the Cerence Handwriting resources in the plugin binary.
+\row
+ \li \e -vkb-bundle-xt9 or \e -vkb-bundle-cerence
+ \li \e n/a
+ \li Enables bundling of XT9 resources
+ \li This option bundles the XT9 resources in the plugin binary.
\endtable
\section2 Building Documentation
@@ -259,88 +284,100 @@ Hunspell sources and dictionary files is listed below:
(etc.)
\endcode
-\section2 T9 Write Integration
+\section2 Cerence Handwriting Integration
-T9 Write integration supports the T9 Write Alphabetic and T9 Write CJK engines. Both
-engines are integrated via T9WriteInputMethod. The input method can be initialized
-with either of the engines at runtime. The engine selection happens automatically
-based on input locale and input mode from the keyboard.
+Cerence Handwriting integration supports the Alphabetic and CJK (Chinese Japanese Korean)
+engines. Both engines are integrated via T9WriteInputMethod. The input method is initialized
+with one engine at the time. The engine selection happens automatically based on the current
+input locale.
-\section3 T9 Write Compatibility
+\section3 Cerence Handwriting Compatibility
-Qt Virtual Keyboard is compatible with T9 Write v7.5.0 onward.
+Qt Virtual Keyboard is compatible with Cerence Handwriting v8.7 or later.
-The latest tested version is v7.8.1.
+\section3 Cerence Handwriting Build Preparations
-\section3 T9 Write Build Preparations
+The contents of the SDK must unpacked using the \e unpack.py script located in the \e cerence
+directory. This ensures the correct directory structure for CMake to find the content.
-The contents of the SDK must be either manually copied to the directory structure
-described below, or by using the \e unpack.py script found in the t9write directory.
+\badcode
+$ cd src/plugins/cerence/
+$ python unpack.py filename.zip
+\endcode
-To unpack the SDK using the script:
+This will unpack the contents to the \e src/plugins/cerence/sdk directory, where the CMake can
+pick it up automatically.
+
+Alternatively, you can unpack to any other directory by adding extra parameter to the command
+line. In this case, the location of the SDK must be passed to the \e configure script.
\badcode
-$ cd src/plugins/t9write/3rdparty/t9write/
-$ python unpack.py T9Write_Alpha_v7-8-0_SDK.zip .
+configure ... -vkb-cerence-sdk /path/to/cerence/sdk
\endcode
+\section3 Layout of the Cerence SDK
+
+The extracted content of the SDK looks like this:
+
\badcode
-3rdparty
-└── t9write
- ├─── api
- │ ├─── decuma*.h
- │ ├─── t9write*.h
- │ └─── xxt9w*.h
- ├─── data
- │ ├─── arabic
- │ │ └─── *.bin [T9 Write Arabic]
- │ ├─── hebrew
- │ │ └─── *.bin [T9 Write Hebrew]
- │ ├─── *.bin [T9 Write Alphabetic]
- │ ├─── *.hdb
- │ ├─── *.phd
- │ └─── *.ldb [T9 Write v7.5]
- └─── lib
- ├─── arm
- │ ├─── shared
- │ │ ├─── alphabetic
- │ │ │ └─── *.so
- │ │ └─── cjk
- │ │ └─── *.so
- │ └─── static
- │ ├─── alphabetic
- │ │ └─── *.a / *.o
- │ └─── cjk
- │ └─── *.a / *.o
- ├─── linux-x86
- │ ├─── shared
- │ │ ├─── alphabetic
- │ │ │ └─── *.so
- │ │ └─── cjk
- │ │ └─── *.so
- │ └─── static
- │ ├─── alphabetic
- │ │ └─── *.a / *.o
- │ └─── cjk
- │ └─── *.a / *.o
- └─── win32
- ├─── shared
- │ ├─── alphabetic
- │ │ ├─── *.dll
- │ │ └─── *.lib
- │ └─── cjk
- │ ├─── *.dll
- │ └─── *.lib
- └─── static
- ├─── alphabetic
- │ └─── *.lib / *.obj
- └─── cjk
- └─── *.lib / *.obj
+sdk
+├───t9write
+│ ├───api
+│ ├───data
+│ │ ├───arabic
+│ │ ├───hebrew
+│ │ └───thai
+│ └───lib
+│ ├───linux
+│ │ ├───arm64
+│ │ │ ├───shared
+│ │ │ │ ├───alphabetic
+│ │ │ │ └───cjk
+│ │ │ └───static
+│ │ │ ├───alphabetic
+│ │ │ └───cjk
+│ │ └───x86_64
+│ │ ├───shared
+│ │ │ ├───alphabetic
+│ │ │ └───cjk
+│ │ └───static
+│ │ ├───alphabetic
+│ │ └───cjk
+│ └───win32
+│ ├───x86
+│ │ ├───shared
+│ │ │ ├───alphabetic
+│ │ │ └───cjk
+│ │ └───static
+│ │ ├───alphabetic
+│ │ └───cjk
+│ └───x86_64
+│ ├───shared
+│ │ ├───alphabetic
+│ │ └───cjk
+│ └───static
+│ ├───alphabetic
+│ └───cjk
+└───xt9
+ ├───api
+ ├───data
+ └───lib
+ ├───linux
+ │ ├───arm64
+ │ │ ├───shared
+ │ │ └───static
+ │ └───x86_64
+ │ ├───shared
+ │ └───static
+ └───win32
+ ├───x86
+ │ ├───shared
+ │ └───static
+ └───x86_64
+ ├───shared
+ └───static
\endcode
-\note The above files are from the T9 Write demo SDK for Windows; the contents may vary for other
- platforms.
-
Where the contents of each directory are:
\table
@@ -360,12 +397,12 @@ Where the contents of each directory are:
\li \e data
\li This directory should contain all HWR databases and optionally
XT9 databases.
- \li HWR database for the T9 Write Alphabetic:
+ \li HWR database for the Cerence Handwriting Alphabetic:
\list
\li \e _databas_le.bin
\endlist
- HWR database for the T9 Write CJK:
+ HWR database for the Cerence Handwriting CJK:
\list
\li \e cjk_HK_std_le.hdb HongKong Chinese
\li \e cjk_J_std_le.hdb Japanese
@@ -384,14 +421,23 @@ Where the contents of each directory are:
\li These directories should hold the desired target libraries.
If both shared and static libraries are found, shared libraries
are preferred.
-
- For example, to enable a static win32 build, copy
- \e t9write_alphabetic_rel.obj to \e lib/win32/static/alphabetic
- directory.
\endtable
-Finally, the SDK is included in the build by adding CONFIG+=t9write to the
-qmake command line.
+The Cerence Handwriting and XT9 integration code is automatically activated when the
+Cerence SDK is detected.
+
+All other extensions should be cleaned from the \e [qtbase]/plugins/virtualkeyboard directory
+before building the Cerence extensions to avoid conflicting behavior at runtime. The
+Cerence extensions do not require any other virtual keyboard plugin to function.
+
+Handwriting databases and language databases for XT9 are installed in the
+\e [qtbase]/qtvirtualkeyboard/cerence directory. In addition, there are two other
+alternatives for locating these files:
+
+\list
+ \li A custom runtime location defined by \l {Environment Variables}
+ \li The \e -vkb-bundle-cerence command line option to embed resources in the plugin binaries
+\endlist
\section2 MyScript Text SDK Integration
diff --git a/src/virtualkeyboard/doc/src/deployment-guide.qdoc b/src/virtualkeyboard/doc/src/deployment-guide.qdoc
index ffce377c..edd6300c 100644
--- a/src/virtualkeyboard/doc/src/deployment-guide.qdoc
+++ b/src/virtualkeyboard/doc/src/deployment-guide.qdoc
@@ -245,6 +245,35 @@ There are several environment variables defined by the module that are listed be
For example, for Qt libraries built from source,
it could be \c {qtbase/qtvirtualkeyboard/tcime/dict_phrases.dat}.
\row
+ \li QT_VIRTUALKEYBOARD_CERENCE_HWR_DB_PATH
+ \li Specifies the location of Cerence Handwriting handwriting database.
+
+ The default search location for Cerence Handwriting handwriting database are:
+ \list
+ \li \c QT_VIRTUALKEYBOARD_CERENCE_HWR_DB_PATH
+ \li \c {QLibraryInfo::location(QLibraryInfo::DataPath) + "/qtvirtualkeyboard/cerence/handwriting"}
+ \li \c {":/QtQuick/VirtualKeyboard/Cerence/Handwriting"}
+ \endlist
+
+ The environment variable may contain multiple paths. Multiple paths are separated with
+ semicolon in Windows and with colon in other operating systems.
+ \row
+ \li QT_VIRTUALKEYBOARD_XT9_LDB_PATH
+ \li Specifies the location of XT9 databases.
+
+ The default search location for LDB files are:
+ \list
+ \li \c QT_VIRTUALKEYBOARD_XT9_LDB_PATH
+ \li \c {QLibraryInfo::location(QLibraryInfo::DataPath) + "/qtvirtualkeyboard/cerence/xt9"}
+ \li \c {":/QtQuick/VirtualKeyboard/Cerence/Xt9"}
+ \endlist
+
+ Additional search paths can be specified by setting this environment variable. Multiple paths are
+ separated with semicolon in Windows and with colon in other operating systems.
+
+ The LDB files are shared between XT9 and Cerence Handwriting plugins, so this environment variable
+ affects both plugins.
+ \row
\li QT_VIRTUALKEYBOARD_STYLE
\li Specifies the location of the style to use with the virtual keyboard.
diff --git a/src/virtualkeyboard/doc/src/handwriting.qdoc b/src/virtualkeyboard/doc/src/handwriting.qdoc
index 5163dfd7..328971df 100644
--- a/src/virtualkeyboard/doc/src/handwriting.qdoc
+++ b/src/virtualkeyboard/doc/src/handwriting.qdoc
@@ -45,52 +45,20 @@ For instructions on how to activate and use the handwriting input mode, see the
For information about building Qt Virtual Keyboard with a particular
handwriting engine, see \l {Configuration Options}.
-\section1 T9 Write
+\section1 Cerence Handwriting
-\l {https://www.nuance.com/mobile/mobile-solutions/text-input-solutions/t9-write.html}{T9 Write}
+\l {https://cerence.com}{Cerence Handwriting}
is a commercial handwriting recognition engine.
-T9 Write supports handwriting written in the following languages:
+Cerence Handwriting works with all languages supported by the virtual keyboard.
-\table
-\row
-\li \list
- \li Arabic
- \li Bulgarian
- \li Croatian
- \li Czech
- \li Danish
- \li Dutch
- \li English
-\endlist
-\li \list
- \li Estonian
- \li Finnish
- \li French
- \li German
- \li Greek
- \li Hebrew
- \li Hungarian
-\endlist
-\li \list
- \li Italian
- \li Japanese
- \li Korean
- \li Norwegian
- \li Persian/Farsi
- \li Polish
- \li Portugese
-\endlist
-\li \list
- \li Romanian
- \li Russian
- \li Serbian
- \li Simplified Chinese
- \li Spanish
- \li Swedish
- \li Traditional Chinese
-\endlist
-\endtable
+ \list
+ \li \l {Qt Virtual Keyboard#Supported Languages}{Supported Languages}
+ \endlist
+
+\b {See also}: \l {Cerence Handwriting Integration}
+
+\b {See also}: \l {Cerence XT9 Advanced Input}
\section1 MyScript
diff --git a/src/virtualkeyboard/doc/src/qtvirtualkeyboard-index.qdoc b/src/virtualkeyboard/doc/src/qtvirtualkeyboard-index.qdoc
index a3156cd0..09bddb95 100644
--- a/src/virtualkeyboard/doc/src/qtvirtualkeyboard-index.qdoc
+++ b/src/virtualkeyboard/doc/src/qtvirtualkeyboard-index.qdoc
@@ -30,7 +30,7 @@
\page qtvirtualkeyboard-index.html
The Qt Virtual Keyboard project provides an input framework and reference
- keyboard frontend for Qt 5 on Linux Desktop/X11, Windows Desktop, and
+ keyboard frontend for Qt 6 on Linux Desktop/X11, Windows Desktop, and
Boot2Qt targets.
The input framework makes it easy to write custom input methods or to
@@ -67,7 +67,8 @@
The Qt Virtual Keyboard supports third-party plugins from the following vendors:
\list
- \li \l {Handwriting Recognition#T9 Write}{T9 Write} handwriting text input.
+ \li \l {Cerence XT9 Advanced Input}{Cerence XT9} advanced input.
+ \li \l {Handwriting Recognition#Cerence Handwriting}{Cerence Handwriting} text input.
\li \l {Handwriting Recognition#MyScript}{MyScript} Text handwriting recognition
\endlist
diff --git a/src/virtualkeyboard/doc/src/xt9.qdoc b/src/virtualkeyboard/doc/src/xt9.qdoc
new file mode 100644
index 00000000..cc2b6919
--- /dev/null
+++ b/src/virtualkeyboard/doc/src/xt9.qdoc
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+
+\page xt9.html
+
+\title Cerence XT9 Advanced Input
+
+The Cerence XT9 advanced input offers high-quality spell correction and predictive
+text input that works with standard keyboard layouts bundled with
+the Qt Virtual Keyboard.
+
+The Cerence XT9 works as an add-on loaded into the Qt Virtual Keyboard at start-up.
+
+Main features:
+
+\list
+ \li \l {Multilingual}
+ \li \l {Advanced correction and learning capabilities}
+ \li \l {Next word prediction}
+ \li \l {Application specific dictionaries} (e.g. phone book)
+ \li \l {Handwriting Recognition with XT9 Capabilities}
+\endlist
+
+\section2 Multilingual
+
+The XT9 engine supports all the alphabetical languages as well as other languages, such
+as Chinese, Japanese and Korean.
+
+\section2 Advanced correction and learning capabilities
+
+Correction and learning capabilities are based the advanced language model that XT9 uses
+to correct and learn from the user input. For instance, frequently used words are prioritized
+in the word candidate list.
+
+\section2 Next word prediction
+
+Next word prediction is activated after selecting a candidate from the word candidate list.
+It automatically fills the word candidate list with followup words based on the context and
+previous input.
+
+\section2 Application specific dictionaries
+
+With the new \l {QVirtualKeyboardDictionaryManager} {dictionary manager} the application can
+create custom dictionaries and attach them to any context within the application. Together
+with \l {VirtualKeyboardSettings.defaultDictionaryDisabled} API it is also possible to use
+custom dictionaries exclusively without standard built-in dictionaries.
+
+\section2 Handwriting Recognition with XT9 Capabilities
+
+Cerence handwriting recognition and XT9 engines are uniquely integrated together in the Qt
+Virtual Keyboard. This means that the improved word candidate suggestions and next word
+prediction are also available in the handwriting mode.
+
+*/
diff --git a/src/virtualkeyboard/qt_cmdline.cmake b/src/virtualkeyboard/qt_cmdline.cmake
index 694b1698..2dc6be19 100644
--- a/src/virtualkeyboard/qt_cmdline.cmake
+++ b/src/virtualkeyboard/qt_cmdline.cmake
@@ -6,6 +6,14 @@ qt_commandline_option(vkb-desktop TYPE boolean)
qt_commandline_option(vkb-cangjie TYPE boolean VALUE cangjie)
qt_commandline_option(vkb-zhuyin TYPE boolean VALUE zhuyin)
qt_commandline_option(vkb-hunspell TYPE enum VALUES no 3rdparty system)
+qt_commandline_option(vkb-handwriting TYPE optionalString VALUES yes no cerence-hwr)
+qt_commandline_option(vkb-cerence-sdk TYPE string)
qt_commandline_option(vkb-style TYPE string VALUES standard retro none)
qt_commandline_option(vkb-no-bundle-pinyin TYPE boolean)
qt_commandline_option(vkb-no-bundle-tcime TYPE boolean)
+qt_commandline_option(vkb-cerence-static TYPE boolean)
+qt_commandline_option(vkb-bundle-cerence TYPE boolean)
+qt_commandline_option(vkb-bundle-cerence-hwr TYPE boolean)
+qt_commandline_option(vkb-bundle-cerence-xt9 TYPE boolean)
+qt_commandline_option(vkb-cerence-xt9-debug TYPE boolean)
+qt_commandline_option(vkb-cerence-xt9-9key-layouts TYPE boolean)