Files
msime-windows/engine/providers/pinyin_candidate_provider.cpp
Lu Fan(SonnyCalcr) 58a27f3edb fix(engine,server): 候选末页满页且无法再展开时置灰下一页箭头 (#1070)
下一页箭头原先在当前页满时一律可点,为首字母候选分批展开留口子;
但只有单个首字母且首字母候选恰好截在 24 条时才能展开,其余情况
末页满页的右箭头点了没反应也不会变灰。

引擎新增只判断不查库的 can_expand_initial_candidates,与实际展开
共用前置条件;Server 发布候选页快照时,满页只有在还能展开时才算
有下一页。

Refs #1069
2026-10-18 23:11:22 +08:00

185 lines
6.7 KiB
C++

#include "pinyin_candidate_provider.h"
#include "../core/scheme_type.h"
#include "../shuangpin/shuangpin_query.h"
#include "../shuangpin/shuangpin_utils.h"
PinyinCandidateProvider::PinyinCandidateProvider(const ShuangpinProfile &shuangpin_profile,
metasequoia::RuntimePaths paths)
: shuangpin_profile_(shuangpin_profile), quanpin_engine_(paths), shuangpin_engine_(shuangpin_profile, paths)
{
}
std::vector<WordItem> PinyinCandidateProvider::query(const QueryRequest &request)
{
if (!request.valid)
{
return {};
}
std::vector<WordItem> candidates;
if (request.scheme == SchemeType::Shuangpin)
{
candidates = shuangpin_engine_.query(request);
}
else if (request.scheme == SchemeType::Quanpin)
{
candidates = quanpin_engine_.query(request);
}
else
{
return {};
}
// 候选带上产出它的方案:混输组合里五笔与拼音候选共存,删除与调频按候选自己的方案路由。
for (WordItem &item : candidates)
{
item.scheme = request.scheme;
}
return candidates;
}
bool PinyinCandidateProvider::resolve_direct_helpcode(QueryRequest &request)
{
return request.scheme == SchemeType::Shuangpin && shuangpin_engine_.resolve_direct_helpcode(request);
}
bool PinyinCandidateProvider::can_expand_initial_candidates(const QueryRequest &request,
const std::vector<WordItem> &candidates) const
{
if (request.scheme == SchemeType::Shuangpin)
{
return shuangpin_engine_.can_expand_initial_candidates(request, candidates);
}
if (request.scheme == SchemeType::Quanpin)
{
return quanpin_engine_.can_expand_initial_candidates(request, candidates);
}
return false;
}
bool PinyinCandidateProvider::expand_initial_candidates(const QueryRequest &request, std::vector<WordItem> &candidates)
{
bool expanded = false;
if (request.scheme == SchemeType::Shuangpin)
{
expanded = shuangpin_engine_.expand_initial_candidates(request, candidates);
}
else if (request.scheme == SchemeType::Quanpin)
{
expanded = quanpin_engine_.expand_initial_candidates(request, candidates);
}
// 展开出来的候选同样要带上方案,否则双拼会话选中/删除它们时会按默认 Quanpin 路由到全拼引擎,
// 跳过双拼到全拼的键归一化。
if (expanded)
{
for (WordItem &item : candidates)
{
item.scheme = request.scheme;
}
}
return expanded;
}
void PinyinCandidateProvider::reset_cache()
{
quanpin_engine_.reset_cache();
shuangpin_engine_.reset_cache();
}
void PinyinCandidateProvider::reset_sentence_cache()
{
quanpin_engine_.reset_sentence_cache();
shuangpin_engine_.reset_sentence_cache();
}
int PinyinCandidateProvider::create_word(SchemeType scheme, std::string pinyin, std::string word)
{
if (scheme == SchemeType::Shuangpin)
{
return shuangpin_engine_.create_word(std::move(pinyin), std::move(word));
}
return quanpin_engine_.create_word(std::move(pinyin), std::move(word));
}
int PinyinCandidateProvider::update_weight_by_pinyin_and_word(SchemeType scheme, std::string pinyin, std::string word)
{
if (scheme == SchemeType::Shuangpin)
{
return shuangpin_engine_.update_weight_by_pinyin_and_word(std::move(pinyin), std::move(word));
}
return quanpin_engine_.update_weight_by_pinyin_and_word(std::move(pinyin), std::move(word));
}
int PinyinCandidateProvider::delete_by_pinyin_and_word(SchemeType scheme, std::string pinyin, std::string word)
{
if (scheme == SchemeType::Shuangpin)
{
return shuangpin_engine_.delete_by_pinyin_and_word(std::move(pinyin), std::move(word));
}
return quanpin_engine_.delete_by_pinyin_and_word(std::move(pinyin), std::move(word));
}
int PinyinCandidateProvider::cache_dynamic_candidate(SchemeType scheme, const std::string &pinyin,
const std::string &word, CandidateSource source)
{
if (scheme == SchemeType::Shuangpin)
{
return shuangpin_engine_.insert_word_to_series_cache(pinyin, word, source);
}
return quanpin_engine_.insert_word_to_series_cache(pinyin, word, source);
}
std::optional<WordItem> PinyinCandidateProvider::find_candidate(SchemeType scheme, const std::string &key,
const std::string &value)
{
std::optional<WordItem> found = scheme == SchemeType::Shuangpin ? shuangpin_engine_.find_candidate(key, value)
: quanpin_engine_.find_candidate(key, value);
// 固定位置补入的候选不经过 query(),同样按查它的方案打标,调频与删除才会回到同一个引擎。
if (found)
{
found->scheme = scheme == SchemeType::Shuangpin ? SchemeType::Shuangpin : SchemeType::Quanpin;
}
return found;
}
int PinyinCandidateProvider::cache_dynamic_candidate_for_request(const QueryRequest &request, const std::string &word,
CandidateSource source)
{
if (request.scheme == SchemeType::Quanpin)
{
return quanpin_engine_.insert_word_to_series_cache(request, word, source);
}
if (request.scheme != SchemeType::Shuangpin)
{
return -1;
}
if (!request.enable_shuangpin_helpcode)
{
return shuangpin_engine_.insert_word_to_series_cache(request.raw_input, word, source);
}
const std::string &raw_input_with_cases =
request.raw_input_with_cases.empty() ? request.raw_input : request.raw_input_with_cases;
const std::string pure_input = shuangpin::remove_manual_delimiters(request.raw_input);
const std::string pure_input_with_cases = shuangpin::remove_manual_delimiters(raw_input_with_cases);
if (ShuangpinUtil::IsFullHelpMode(pure_input_with_cases, shuangpin_profile_))
{
return shuangpin_engine_.insert_word_to_active_helpcode_cache(
request.raw_input, word, source, ShuangpinUtil::GetFullHelpCodes(pure_input_with_cases));
}
if (pure_input.size() % 2 == 1 && pure_input.size() > 1)
{
const std::string base_raw_input = pure_input.substr(0, pure_input.size() - 1);
const std::string base_raw_segmentation = shuangpin::segment_input(base_raw_input, shuangpin_profile_);
if (ShuangpinUtil::is_all_complete_pinyin(base_raw_input, base_raw_segmentation))
{
return shuangpin_engine_.insert_word_to_active_helpcode_cache(request.raw_input, word, source);
}
}
return shuangpin_engine_.insert_word_to_series_cache(request.raw_input, word, source);
}