diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 3b91db96..abd9a9be 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -84,6 +84,7 @@ set(SRC_FILES ) set(SRC_FILES_IME_ENGINE + "./MetasequoiaImeEngine/common/helpcode_utils.cpp" "./MetasequoiaImeEngine/common/string_utils.cpp" "./MetasequoiaImeEngine/core/ime_session.cpp" "./MetasequoiaImeEngine/providers/provider_registry.cpp" diff --git a/server/MetasequoiaImeEngine b/server/MetasequoiaImeEngine index 964b6940..0f2afad9 160000 --- a/server/MetasequoiaImeEngine +++ b/server/MetasequoiaImeEngine @@ -1 +1 @@ -Subproject commit 964b6940a6c1d64416884e3327f48d3d44b902e0 +Subproject commit 0f2afad94dfc77c602f61aba19ba45af07241ed1 diff --git a/server/src/ipc/event_listener.cpp b/server/src/ipc/event_listener.cpp index 04e8b664..b9710efd 100644 --- a/server/src/ipc/event_listener.cpp +++ b/server/src/ipc/event_listener.cpp @@ -19,7 +19,7 @@ #include "fmt/xchar.h" #include #include "global/globals.h" -#include "MetasequoiaImeEngine/shuangpin/shuangpin_utils.h" +#include "MetasequoiaImeEngine/common/helpcode_utils.h" #include "ipc/event_listener.h" #include "utils/ime_utils.h" #include "cloud/cloud_ime.h" @@ -61,7 +61,7 @@ std::string BuildCurrentCandidatePage() ui.selected_text = string_to_wstring(word); } - candidate_string += word + ShuangpinUtil::compute_helpcodes(word); + candidate_string += word + HelpcodeUtils::compute_helpcodes(word); maxCount = std::max(maxCount, static_cast(utf8::distance(word.begin(), word.end()))); ui.page_words.push_back(string_to_wstring(word)); if (i < loop - 1) diff --git a/server/src/session/engine_input_session.cpp b/server/src/session/engine_input_session.cpp index c4d15d6b..f446d49e 100644 --- a/server/src/session/engine_input_session.cpp +++ b/server/src/session/engine_input_session.cpp @@ -2,6 +2,7 @@ #include #include "config/ime_config.h" +#include "MetasequoiaImeEngine/common/helpcode_utils.h" #include "MetasequoiaImeEngine/shuangpin/shuangpin_query.h" #include "MetasequoiaImeEngine/shuangpin/shuangpin_utils.h" @@ -126,6 +127,10 @@ std::string EngineInputSession::get_pinyin_segmentation_with_cases() const { return request().raw_segmentation.empty() ? request().raw_input : request().raw_segmentation; } + if (current_scheme_type() == SchemeType::Quanpin) + { + return request().raw_segmentation.empty() ? request().raw_input_with_cases : request().raw_segmentation; + } return request().normalized_segmentation.empty() ? request().segmentation : request().normalized_segmentation; } @@ -198,7 +203,7 @@ IInputSession::SelectionTransition EngineInputSession::advance_composition_after if (is_shuangpin()) { const auto base = ResolveShuangpinCompositionBase(request()); - const size_t word_pinyin_length = ShuangpinUtil::cnt_han_chars(selected_word) * 2; + const size_t word_pinyin_length = HelpcodeUtils::count_han_chars(selected_word) * 2; const size_t total_input_length = base.raw_input.size(); transition.full_pure_pinyin = @@ -296,7 +301,7 @@ EngineInputSession::update_creating_word_progress(const std::string ¤t_pin progress.word = current_word + selected_word; progress.preedit = progress.word + selection_transition.current_segmentation; progress.completed = - is_shuangpin() ? ShuangpinUtil::cnt_han_chars(progress.word) * 2 == progress.pinyin.size() : false; + is_shuangpin() ? HelpcodeUtils::count_han_chars(progress.word) * 2 == progress.pinyin.size() : false; return progress; } diff --git a/server/src/session/shuangpin_input_session.cpp b/server/src/session/shuangpin_input_session.cpp index 9594654d..c0bbb02c 100644 --- a/server/src/session/shuangpin_input_session.cpp +++ b/server/src/session/shuangpin_input_session.cpp @@ -1,5 +1,5 @@ #include "shuangpin_input_session.h" -#include "MetasequoiaImeEngine/shuangpin/shuangpin_utils.h" +#include "MetasequoiaImeEngine/common/helpcode_utils.h" #include ShuangpinInputSession::ShuangpinInputSession() : dictionary_(std::make_unique()) @@ -169,6 +169,6 @@ ShuangpinInputSession::update_creating_word_progress(const std::string ¤t_ progress.pinyin = current_pinyin.empty() ? selection_transition.full_pure_pinyin : current_pinyin; progress.word = current_word + selected_word; progress.preedit = progress.word + selection_transition.current_segmentation; - progress.completed = ShuangpinUtil::cnt_han_chars(progress.word) * 2 == progress.pinyin.size(); + progress.completed = HelpcodeUtils::count_han_chars(progress.word) * 2 == progress.pinyin.size(); return progress; } diff --git a/server/tests/CMakeLists.txt b/server/tests/CMakeLists.txt index 18747a3a..bf21aa52 100644 --- a/server/tests/CMakeLists.txt +++ b/server/tests/CMakeLists.txt @@ -9,6 +9,7 @@ set(TEST_SOURCE_FILES "${CMAKE_SOURCE_DIR}/src/config/ime_config.cpp" "${CMAKE_SOURCE_DIR}/src/session/engine_input_session.cpp" "${CMAKE_SOURCE_DIR}/src/utils/common_utils.cpp" + "${CMAKE_SOURCE_DIR}/MetasequoiaImeEngine/common/helpcode_utils.cpp" "${CMAKE_SOURCE_DIR}/MetasequoiaImeEngine/core/ime_session.cpp" "${CMAKE_SOURCE_DIR}/MetasequoiaImeEngine/common/string_utils.cpp" "${CMAKE_SOURCE_DIR}/MetasequoiaImeEngine/providers/provider_registry.cpp" diff --git a/server/tests/src/test_quanpin_scheme.cpp b/server/tests/src/test_quanpin_scheme.cpp index cc1c0f52..34076e78 100644 --- a/server/tests/src/test_quanpin_scheme.cpp +++ b/server/tests/src/test_quanpin_scheme.cpp @@ -1,4 +1,5 @@ #include "tests/includes/test_framework.h" +#include "MetasequoiaImeEngine/common/helpcode_utils.h" #include "MetasequoiaImeEngine/schemes/quanpin_scheme.h" namespace @@ -34,3 +35,56 @@ TEST_CASE(QuanpinSchemeApostropheIsPreservedInRawInput) REQUIRE_EQ(request.raw_input, std::string("x'i")); REQUIRE_EQ(request.normalized_input, std::string("xi")); } + +TEST_CASE(QuanpinSchemePreservesUppercaseRawInputForHelpcodes) +{ + QuanpinScheme scheme; + InputKey(scheme, 'X', L'x'); + InputKey(scheme, 'I', L'i'); + InputKey(scheme, 'T', L't'); + InputKey(scheme, 'E', L'e'); + InputKey(scheme, 'L', L'l'); + InputKey(scheme, 'E', L'e'); + InputKey(scheme, 'A', L'A', 1); + InputKey(scheme, 'A', L'A', 1); + + const QueryRequest request = scheme.build_request(); + REQUIRE(request.valid); + REQUIRE_EQ(request.raw_input_with_cases, std::string("xiteleAA")); + REQUIRE_EQ(request.raw_input, std::string("xiteleaa")); + REQUIRE_EQ(request.normalized_input, std::string("xitele")); + REQUIRE_EQ(request.raw_segmentation, std::string("xi'te'le'AA")); +} + +TEST_CASE(QuanpinDoubleHelpModeRecognizesTrailingUppercaseLetters) +{ + REQUIRE(HelpcodeUtils::is_quanpin_double_help_mode("xiteleAA")); + REQUIRE(!HelpcodeUtils::is_quanpin_double_help_mode("xiteleaA")); + REQUIRE(!HelpcodeUtils::is_quanpin_double_help_mode("xiteleaa")); +} + +TEST_CASE(QuanpinSchemePreservesUppercaseRawInputForSingleHelpcode) +{ + QuanpinScheme scheme; + InputKey(scheme, 'X', L'x'); + InputKey(scheme, 'I', L'i'); + InputKey(scheme, 'T', L't'); + InputKey(scheme, 'E', L'e'); + InputKey(scheme, 'L', L'l'); + InputKey(scheme, 'E', L'e'); + InputKey(scheme, 'A', L'A', 1); + + const QueryRequest request = scheme.build_request(); + REQUIRE(request.valid); + REQUIRE_EQ(request.raw_input_with_cases, std::string("xiteleA")); + REQUIRE_EQ(request.raw_input, std::string("xitelea")); + REQUIRE_EQ(request.normalized_input, std::string("xitele")); + REQUIRE_EQ(request.raw_segmentation, std::string("xi'te'le'A")); +} + +TEST_CASE(QuanpinSingleHelpModeRecognizesTrailingUppercaseLetter) +{ + REQUIRE(HelpcodeUtils::is_quanpin_single_help_mode("xiteleA")); + REQUIRE(!HelpcodeUtils::is_quanpin_single_help_mode("xiteleAA")); + REQUIRE(!HelpcodeUtils::is_quanpin_single_help_mode("xitelea")); +}