* feat(engine,server): 五笔支持 T 模式与 V 模式 五笔方案此前被排除在 Shift+T 日期时间模式与 V 模式之外。根因是方案层就把 raw 归一成小写 a–y、丢弃数字与运算符,Server 的形状判定读不到大写 T/V 前缀。 - 引擎 WubiScheme 新增 raw_input_with_cases_:保留大小写与 T/V 模式的非字母键 (数字、运算符、: /),但按码字域丢掉越域字母(默认配置下 z)。查询码仍由 normalize_wubi_code 派生,普通码下两者长度相等——Server 用原样串长度数四码。 - Server:T 触发新增独立谓词 date_time_scheme(chinese_scheme || Wubi),不并入 chinese_scheme 本身;FormatVModeWorkerPayload 对五笔返回 UppercaseOnly。 - 自动上屏 / 顶字两个谓词新增 special_mode_active 前置:T 模式关键词归一后可能与 合法四码重合(Tdate → tdat),不挡会在第四个字母上结束模式。 - 引擎与 Server 测试、README 与两份配置模板文案同步。 * fix(engine,server,ui-html): 五笔 T/V 模式由宿主标注字面输入 原实现让五笔原样串不再裁到码长,普通码下原样串可以比码长(混输关、z 通配时 wqazb 对 wqaz), Server 读回后光标、退格和上屏都会错位;守卫也只认 T 模式的全小写主体,TdatE 仍会顶出 tdat。 - 引擎:InputSession::set_wubi_literal_input 随 pending 序列一起下发,只作用于同一次设置。 普通码的原样串就是带大小写的码,与查询码逐位对应、一起截断;字面输入原样保留, 不查码表与拼音,也不算完整四码。退格从原样串重新派生码,字母键两份视图取同一个字母。 - Server:ApplyCompositionEditKey 按 IsWubiLiteralComposition(T 模式触发标记或 V 模式形状) 标注字面输入;两个五笔上屏策略恢复原签名,不再需要 special_mode_active。 - 设置页 T/V 模式说明补上五笔。 --------- Co-authored-by: fanlusky <1730976608@qq.com>
70 lines
3.6 KiB
C++
70 lines
3.6 KiB
C++
#pragma once
|
|
|
|
#include "input_scheme.h"
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
class WubiScheme : public IInputScheme
|
|
{
|
|
public:
|
|
void reset() override;
|
|
void handle_key(ImeKeyCode vk, ImeModifierMask modifiers_down, ImeCharacter wch) override;
|
|
QueryRequest build_request() const override;
|
|
std::string get_preedit() const override;
|
|
SchemeType type() const override;
|
|
void set_raw_input(const std::string &raw_input, const std::string &raw_input_with_cases) override;
|
|
// A wubi code is four letters, and a fifth is normally refused. Mixed input lifts that only
|
|
// once the table has failed the code in hand, so a spelling long enough to need it -- nihao,
|
|
// women, zhongguo -- can be finished. A code the table answers keeps the four-letter limit and
|
|
// a fluent wubi typist sees no change.
|
|
void set_extended_length_allowed(bool allowed);
|
|
// No wubi code uses z, so the key is normally dropped. Mixed input has to accept it, because z
|
|
// is an ordinary pinyin letter: dropping it does not refuse the spelling, it silently turns it
|
|
// into a different one -- zhongguo would arrive as hongguo and zi as i. Unlike the length, this
|
|
// follows the setting rather than the last query, since the letter can open a composition.
|
|
void set_mixed_pinyin_allowed(bool allowed);
|
|
// The wildcard mode wants the same key for the opposite reason: no code contains z, so a z
|
|
// stands for a letter the typist does not know. Same acceptance, different query -- see
|
|
// QueryRequest::wubi_z_wildcard. Independent of mixed input: a host can enable either, both or
|
|
// neither.
|
|
void set_z_wildcard(bool enabled);
|
|
// The host says the next raw string is a special mode's literal input (T mode's Tdate,
|
|
// V mode's V1+2), not a code. The raw string with cases is then kept exactly as typed, and the
|
|
// code derived from it is never complete and never queried: a mode's keyword can normalize to a
|
|
// real code (Tdate -> tdat), and treating that as wubi would commit a word and end the mode.
|
|
// Cleared by reset(); a host that drives the session by raw string sets it with every string.
|
|
void set_literal_input(bool literal);
|
|
bool literal_input() const
|
|
{
|
|
return literal_input_;
|
|
}
|
|
// A complete wubi code is the four letters the table is indexed by. Mixed input only lifts the
|
|
// length limit after the table has already failed the code in hand, so "complete" stays the
|
|
// fixed four letters rather than max_code_length() (32 while extended input is on): a longer
|
|
// spelling is a pinyin answer and is never a complete wubi code.
|
|
bool has_complete_code() const
|
|
{
|
|
return !literal_input_ && raw_input_.size() == kMaxCodeLength;
|
|
}
|
|
|
|
private:
|
|
static constexpr size_t kMaxCodeLength = 4;
|
|
// Long enough for any spelling, short enough to stay a composition rather than a paragraph.
|
|
static constexpr size_t kMaxMixedCodeLength = 32;
|
|
|
|
size_t max_code_length() const;
|
|
|
|
// For a code: the code letters as typed, cases kept, so lowercasing it gives raw_input_ exactly
|
|
// -- same letters, same length, same clipping. A host that counts this string to find the fourth
|
|
// letter counts code letters. For literal input: the string as typed, so a host reading it back
|
|
// still sees the uppercase T or V prefix and the digits its mode decisions match on. Queries
|
|
// never see it: they use raw_input_, the normalized code below.
|
|
std::string raw_input_with_cases_;
|
|
std::string raw_input_;
|
|
std::vector<KeyStroke> key_strokes_;
|
|
bool extended_length_allowed_ = false;
|
|
bool mixed_pinyin_allowed_ = false;
|
|
bool z_wildcard_ = false;
|
|
bool literal_input_ = false;
|
|
};
|