InputHandler // Remove errorCallback().
This commit is contained in:
parent
581122720d
commit
0a0f02861b
|
@ -171,11 +171,7 @@ func handleInputText(_ inputText: String?, key keyCode: Int, modifiers flags: In
|
|||
或者 InputHandler 內:
|
||||
```swift
|
||||
extension InputHandler {
|
||||
func handle(
|
||||
input: InputHandler,
|
||||
state: InputState,
|
||||
errorCallback: @escaping (String) -> Void
|
||||
) -> Bool {
|
||||
func handle(input: InputSignalProtocol) -> Bool {
|
||||
let charCode: UniChar = input.charCode
|
||||
...
|
||||
}
|
||||
|
@ -242,7 +238,7 @@ if composeReading { // 符合按鍵組合條件
|
|||
// 向語言模型詢問是否有對應的記錄
|
||||
if !ifLangModelHasUnigrams(forKey: reading) { // 如果沒有的話
|
||||
vCLog("B49C0979:語彙庫內無「\(reading)」的匹配記錄。")
|
||||
errorCallback("114514") // 向狀態管理引擎回呼一個錯誤狀態
|
||||
delegate.callError("114514") // 向狀態管理引擎回呼一個錯誤狀態
|
||||
_composer.clear() // 清空注拼槽的內容
|
||||
// 根據「天權星引擎 (威注音) 或 Gramambular (小麥) 的組字器是否為空」來判定回呼哪一種狀態
|
||||
delegate.switchState(
|
||||
|
|
|
@ -37,6 +37,7 @@ public protocol InputHandlerDelegate {
|
|||
var selectionKeys: String { get }
|
||||
var state: IMEStateProtocol { get set }
|
||||
var clientBundleIdentifier: String { get }
|
||||
func callError(_ logMessage: String)
|
||||
func switchState(_ newState: IMEStateProtocol)
|
||||
func candidateController() -> CtlCandidateProtocol
|
||||
func candidateSelectionCalledByInputHandler(at index: Int)
|
||||
|
|
|
@ -17,17 +17,9 @@ extension InputHandler {
|
|||
/// 當且僅當選字窗出現時,對於經過初次篩選處理的輸入訊號的處理均藉由此函式來進行。
|
||||
/// - Parameters:
|
||||
/// - input: 輸入訊號。
|
||||
/// - errorCallback: 錯誤回呼。
|
||||
/// - Returns: 告知 IMK「該按鍵是否已經被輸入法攔截處理」。
|
||||
func handleCandidate(
|
||||
input: InputSignalProtocol,
|
||||
errorCallback: @escaping (String) -> Void
|
||||
) -> Bool {
|
||||
guard let delegate = delegate else {
|
||||
errorCallback("06661F6E")
|
||||
return true
|
||||
}
|
||||
|
||||
func handleCandidate(input: InputSignalProtocol) -> Bool {
|
||||
guard let delegate = delegate else { return false }
|
||||
var ctlCandidate = delegate.candidateController()
|
||||
let state = delegate.state
|
||||
|
||||
|
@ -79,7 +71,7 @@ extension InputHandler {
|
|||
? ctlCandidate.highlightPreviousCandidate()
|
||||
: ctlCandidate.highlightNextCandidate())
|
||||
if !updated {
|
||||
errorCallback("9B691919")
|
||||
delegate.callError("9B691919")
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -96,7 +88,7 @@ extension InputHandler {
|
|||
? ctlCandidate.showNextLine()
|
||||
: ctlCandidate.highlightNextCandidate())
|
||||
if !updated {
|
||||
errorCallback("A11C781F")
|
||||
delegate.callError("A11C781F")
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -106,7 +98,7 @@ extension InputHandler {
|
|||
if input.isPageDown {
|
||||
let updated: Bool = ctlCandidate.showNextPage()
|
||||
if !updated {
|
||||
errorCallback("9B691919")
|
||||
delegate.callError("9B691919")
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -116,7 +108,7 @@ extension InputHandler {
|
|||
if input.isPageUp {
|
||||
let updated: Bool = ctlCandidate.showPreviousPage()
|
||||
if !updated {
|
||||
errorCallback("9569955D")
|
||||
delegate.callError("9569955D")
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -127,11 +119,11 @@ extension InputHandler {
|
|||
switch ctlCandidate.currentLayout {
|
||||
case .horizontal:
|
||||
if !ctlCandidate.highlightPreviousCandidate() {
|
||||
errorCallback("1145148D")
|
||||
delegate.callError("1145148D")
|
||||
}
|
||||
case .vertical:
|
||||
if !ctlCandidate.showPreviousLine() {
|
||||
errorCallback("1919810D")
|
||||
delegate.callError("1919810D")
|
||||
}
|
||||
@unknown default:
|
||||
break
|
||||
|
@ -145,11 +137,11 @@ extension InputHandler {
|
|||
switch ctlCandidate.currentLayout {
|
||||
case .horizontal:
|
||||
if !ctlCandidate.highlightNextCandidate() {
|
||||
errorCallback("9B65138D")
|
||||
delegate.callError("9B65138D")
|
||||
}
|
||||
case .vertical:
|
||||
if !ctlCandidate.showNextLine() {
|
||||
errorCallback("9244908D")
|
||||
delegate.callError("9244908D")
|
||||
}
|
||||
@unknown default:
|
||||
break
|
||||
|
@ -163,11 +155,11 @@ extension InputHandler {
|
|||
switch ctlCandidate.currentLayout {
|
||||
case .horizontal:
|
||||
if !ctlCandidate.showPreviousLine() {
|
||||
errorCallback("9B614524")
|
||||
delegate.callError("9B614524")
|
||||
}
|
||||
case .vertical:
|
||||
if !ctlCandidate.highlightPreviousCandidate() {
|
||||
errorCallback("ASD9908D")
|
||||
delegate.callError("ASD9908D")
|
||||
}
|
||||
@unknown default:
|
||||
break
|
||||
|
@ -181,12 +173,12 @@ extension InputHandler {
|
|||
switch ctlCandidate.currentLayout {
|
||||
case .horizontal:
|
||||
if !ctlCandidate.showNextLine() {
|
||||
errorCallback("92B990DD")
|
||||
delegate.callError("92B990DD")
|
||||
break
|
||||
}
|
||||
case .vertical:
|
||||
if !ctlCandidate.highlightNextCandidate() {
|
||||
errorCallback("6B99908D")
|
||||
delegate.callError("6B99908D")
|
||||
}
|
||||
@unknown default:
|
||||
break
|
||||
|
@ -198,7 +190,7 @@ extension InputHandler {
|
|||
|
||||
if input.isHome {
|
||||
if ctlCandidate.selectedCandidateIndex == 0 {
|
||||
errorCallback("9B6EDE8D")
|
||||
delegate.callError("9B6EDE8D")
|
||||
} else {
|
||||
ctlCandidate.selectedCandidateIndex = 0
|
||||
}
|
||||
|
@ -213,7 +205,7 @@ extension InputHandler {
|
|||
} else { // 這裡不用「count > 0」,因為該整數變數只要「!isEmpty」那就必定滿足這個條件。
|
||||
if input.isEnd {
|
||||
if ctlCandidate.selectedCandidateIndex == state.candidates.count - 1 {
|
||||
errorCallback("9B69AAAD")
|
||||
delegate.callError("9B69AAAD")
|
||||
} else {
|
||||
ctlCandidate.selectedCandidateIndex = state.candidates.count - 1
|
||||
}
|
||||
|
@ -286,7 +278,7 @@ extension InputHandler {
|
|||
if candidateIndex != -114_514 {
|
||||
delegate.candidateSelectionCalledByInputHandler(at: candidateIndex)
|
||||
delegate.switchState(IMEState.ofAbortion())
|
||||
return handleInput(event: input, errorCallback: errorCallback)
|
||||
return handleInput(event: input)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -298,12 +290,12 @@ extension InputHandler {
|
|||
var updated = true
|
||||
updated = input.isShiftHold ? ctlCandidate.showPreviousLine() : ctlCandidate.showNextLine()
|
||||
if !updated {
|
||||
errorCallback("66F3477B")
|
||||
delegate.callError("66F3477B")
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
errorCallback("172A0F81")
|
||||
delegate.callError("172A0F81")
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,12 +15,8 @@ extension InputHandler {
|
|||
/// 用來處理 InputHandler.HandleInput() 當中的與組字有關的行為。
|
||||
/// - Parameters:
|
||||
/// - input: 輸入訊號。
|
||||
/// - errorCallback: 錯誤回呼。
|
||||
/// - Returns: 告知 IMK「該按鍵是否已經被輸入法攔截處理」。
|
||||
func handleComposition(
|
||||
input: InputSignalProtocol,
|
||||
errorCallback: @escaping (String) -> Void
|
||||
) -> Bool? {
|
||||
func handleComposition(input: InputSignalProtocol) -> Bool? {
|
||||
guard let delegate = delegate else { return nil }
|
||||
|
||||
// MARK: 注音按鍵輸入處理 (Handle BPMF Keys)
|
||||
|
@ -54,7 +50,7 @@ extension InputHandler {
|
|||
composer = theComposer
|
||||
// 這裡不需要回呼 generateStateOfInputting(),因為當前輸入的聲調鍵一定是合規的、會在之後回呼 generateStateOfInputting()。
|
||||
} else {
|
||||
errorCallback("4B0DD2D4:語彙庫內無「\(temporaryReadingKey)」的匹配記錄,放棄覆寫游標身後的內容。")
|
||||
delegate.callError("4B0DD2D4:語彙庫內無「\(temporaryReadingKey)」的匹配記錄,放棄覆寫游標身後的內容。")
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -86,7 +82,7 @@ extension InputHandler {
|
|||
|
||||
// 向語言模型詢問是否有對應的記錄。
|
||||
if !currentLM.hasUnigramsFor(key: readingKey) {
|
||||
errorCallback("B49C0979:語彙庫內無「\(readingKey)」的匹配記錄。")
|
||||
delegate.callError("B49C0979:語彙庫內無「\(readingKey)」的匹配記錄。")
|
||||
|
||||
if prefs.keepReadingUponCompositionError {
|
||||
composer.intonation.clear() // 砍掉聲調。
|
||||
|
|
|
@ -18,17 +18,7 @@ extension InputHandler {
|
|||
/// - Parameter event: 由 IMK 選字窗接收的裝置操作輸入事件。
|
||||
/// - Returns: 回「`true`」以將該案件已攔截處理的訊息傳遞給 IMK;回「`false`」則放行、不作處理。
|
||||
public func handleEvent(_ event: NSEvent) -> Bool {
|
||||
imkCandidatesEventPreHandler(event: event) ?? doHandleInput(event)
|
||||
}
|
||||
|
||||
/// 將按鍵行為與當前輸入法狀態結合起來、交給按鍵調度模組來處理。
|
||||
/// 再根據返回的 result bool 數值來告知 IMK「這個按鍵事件是被處理了還是被放行了」。
|
||||
/// 這裡不用 handleCandidate() 是因為需要針對聯想詞輸入狀態做額外處理。
|
||||
private func doHandleInput(_ event: NSEvent) -> Bool {
|
||||
handleInput(event: event) { errorString in
|
||||
vCLog(errorString)
|
||||
IMEApp.buzz()
|
||||
}
|
||||
imkCandidatesEventPreHandler(event: event) ?? handleInput(event: event)
|
||||
}
|
||||
|
||||
/// 專門處理與 IMK 選字窗有關的判斷語句。
|
||||
|
@ -79,7 +69,7 @@ extension InputHandler {
|
|||
let eventArray = [event]
|
||||
guard let imkC = delegate.candidateController() as? CtlCandidateIMK else { return false }
|
||||
if event.isEsc || event.isBackSpace || event.isDelete || (event.isShiftHold && !event.isSpace) {
|
||||
return doHandleInput(event)
|
||||
return handleInput(event: event)
|
||||
} else if event.isSymbolMenuPhysicalKey {
|
||||
// 符號鍵的行為是固定的,不受偏好設定影響。
|
||||
switch imkC.currentLayout {
|
||||
|
@ -108,7 +98,7 @@ extension InputHandler {
|
|||
if let newEvent = newEvent {
|
||||
if prefs.useSCPCTypingMode, delegate.state.type == .ofAssociates {
|
||||
// 註:input.isShiftHold 已經在 Self.handle() 內處理,因為在那邊處理才有效。
|
||||
return event.isShiftHold ? true : doHandleInput(event)
|
||||
return event.isShiftHold ? true : handleInput(event: event)
|
||||
} else {
|
||||
if #available(macOS 10.14, *) {
|
||||
imkC.handleKeyboardEvent(newEvent)
|
||||
|
@ -121,7 +111,7 @@ extension InputHandler {
|
|||
}
|
||||
|
||||
if prefs.useSCPCTypingMode, !event.isReservedKey {
|
||||
return doHandleInput(event)
|
||||
return handleInput(event: event)
|
||||
}
|
||||
|
||||
if delegate.state.type == .ofAssociates,
|
||||
|
@ -129,7 +119,7 @@ extension InputHandler {
|
|||
!event.isCursorClockLeft, !event.isCursorClockRight, !event.isSpace,
|
||||
!event.isEnter || !prefs.alsoConfirmAssociatedCandidatesByEnter
|
||||
{
|
||||
return doHandleInput(event)
|
||||
return handleInput(event: event)
|
||||
}
|
||||
imkC.interpretKeyEvents(eventArray)
|
||||
return true
|
||||
|
|
|
@ -20,12 +20,8 @@ extension InputHandler {
|
|||
/// - Remark: 送入該函式處理之前,先用 inputHandler.handleEvent() 分診、來判斷是否需要交給 IMKCandidates 處理。
|
||||
/// - Parameters:
|
||||
/// - input: 輸入訊號。
|
||||
/// - errorCallback: 錯誤回呼。
|
||||
/// - Returns: 告知 IMK「該按鍵是否已經被輸入法攔截處理」。
|
||||
func handleInput(
|
||||
event input: InputSignalProtocol,
|
||||
errorCallback: @escaping (String) -> Void
|
||||
) -> Bool {
|
||||
func handleInput(event input: InputSignalProtocol) -> Bool {
|
||||
// 如果按鍵訊號內的 inputTest 是空的話,則忽略該按鍵輸入,因為很可能是功能修飾鍵。
|
||||
// 不處理任何包含不可列印字元的訊號。
|
||||
// delegate 必須存在,否則不處理。
|
||||
|
@ -41,7 +37,7 @@ extension InputHandler {
|
|||
if state.type == .ofEmpty || state.type == .ofDeactivated {
|
||||
return false
|
||||
}
|
||||
errorCallback("550BCF7B: InputHandler just refused an invalid input.")
|
||||
delegate.callError("550BCF7B: InputHandler just refused an invalid input.")
|
||||
delegate.switchState(state)
|
||||
return true
|
||||
}
|
||||
|
@ -105,13 +101,13 @@ extension InputHandler {
|
|||
// MARK: 處理候選字詞 (Handle Candidates)
|
||||
|
||||
if [.ofCandidates, .ofSymbolTable].contains(state.type) {
|
||||
return handleCandidate(input: input, errorCallback: errorCallback)
|
||||
return handleCandidate(input: input)
|
||||
}
|
||||
|
||||
// MARK: 處理聯想詞 (Handle Associated Phrases)
|
||||
|
||||
if state.type == .ofAssociates {
|
||||
if handleCandidate(input: input, errorCallback: errorCallback) {
|
||||
if handleCandidate(input: input) {
|
||||
return true
|
||||
} else {
|
||||
delegate.switchState(IMEState.ofEmpty())
|
||||
|
@ -121,18 +117,14 @@ extension InputHandler {
|
|||
// MARK: 處理標記範圍、以便決定要把哪個範圍拿來新增使用者(濾除)語彙 (Handle Marking)
|
||||
|
||||
if state.type == .ofMarking {
|
||||
if handleMarkingState(input: input, errorCallback: errorCallback) { return true }
|
||||
if handleMarkingState(input: input) { return true }
|
||||
state = state.convertedToInputting
|
||||
delegate.switchState(state)
|
||||
}
|
||||
|
||||
// MARK: 注音按鍵輸入處理 (Handle BPMF Keys)
|
||||
|
||||
if let compositionHandled = handleComposition(
|
||||
input: input, errorCallback: errorCallback
|
||||
) {
|
||||
return compositionHandled
|
||||
}
|
||||
if let compositionHandled = handleComposition(input: input) { return compositionHandled }
|
||||
|
||||
// MARK: 用上下左右鍵呼叫選字窗 (Calling candidate window using Up / Down or PageUp / PageDn.)
|
||||
|
||||
|
@ -161,12 +153,12 @@ extension InputHandler {
|
|||
}
|
||||
return true
|
||||
} else if input.isShiftHold { // 臉書等網站會攔截 Tab 鍵,所以用 Shift+Command+Space 對候選字詞做正向/反向輪替。
|
||||
return handleInlineCandidateRotation(reverseOrder: input.isCommandHold, errorCallback: errorCallback)
|
||||
return handleInlineCandidateRotation(reverseOrder: input.isCommandHold)
|
||||
}
|
||||
}
|
||||
let candidateState: IMEStateProtocol = generateStateOfCandidates()
|
||||
if candidateState.candidates.isEmpty {
|
||||
errorCallback("3572F238")
|
||||
delegate.callError("3572F238")
|
||||
} else {
|
||||
delegate.switchState(candidateState)
|
||||
}
|
||||
|
@ -179,38 +171,38 @@ extension InputHandler {
|
|||
switch keyCodeType {
|
||||
case .kEscape: return handleEsc()
|
||||
case .kTab:
|
||||
return handleInlineCandidateRotation(reverseOrder: input.isShiftHold, errorCallback: errorCallback)
|
||||
return handleInlineCandidateRotation(reverseOrder: input.isShiftHold)
|
||||
case .kUpArrow, .kDownArrow, .kLeftArrow, .kRightArrow:
|
||||
if (input.isControlHold || input.isShiftHold) && (input.isOptionHold) {
|
||||
if input.isLeft { // Ctrl+PgLf / Shift+PgLf
|
||||
return handleHome(errorCallback: errorCallback)
|
||||
return handleHome()
|
||||
} else if input.isRight { // Ctrl+PgRt or Shift+PgRt
|
||||
return handleEnd(errorCallback: errorCallback)
|
||||
return handleEnd()
|
||||
}
|
||||
}
|
||||
if input.isCursorBackward { // Forward
|
||||
return handleBackward(input: input, errorCallback: errorCallback)
|
||||
return handleBackward(input: input)
|
||||
}
|
||||
if input.isCursorForward { // Backward
|
||||
return handleForward(input: input, errorCallback: errorCallback)
|
||||
return handleForward(input: input)
|
||||
}
|
||||
if input.isCursorClockLeft || input.isCursorClockRight { // Clock keys
|
||||
if input.isOptionHold, state.type == .ofInputting {
|
||||
if input.isCursorClockRight {
|
||||
return handleInlineCandidateRotation(reverseOrder: false, errorCallback: errorCallback)
|
||||
return handleInlineCandidateRotation(reverseOrder: false)
|
||||
}
|
||||
if input.isCursorClockLeft {
|
||||
return handleInlineCandidateRotation(reverseOrder: true, errorCallback: errorCallback)
|
||||
return handleInlineCandidateRotation(reverseOrder: true)
|
||||
}
|
||||
}
|
||||
return handleClockKey(errorCallback: errorCallback)
|
||||
return handleClockKey()
|
||||
}
|
||||
case .kHome: return handleHome(errorCallback: errorCallback)
|
||||
case .kEnd: return handleEnd(errorCallback: errorCallback)
|
||||
case .kHome: return handleHome()
|
||||
case .kEnd: return handleEnd()
|
||||
case .kBackSpace:
|
||||
return handleBackSpace(input: input, errorCallback: errorCallback)
|
||||
return handleBackSpace(input: input)
|
||||
case .kWindowsDelete:
|
||||
return handleDelete(input: input, errorCallback: errorCallback)
|
||||
return handleDelete(input: input)
|
||||
case .kCarriageReturn, .kLineFeed:
|
||||
return (input.isCommandHold && input.isControlHold)
|
||||
? (input.isOptionHold
|
||||
|
@ -236,12 +228,12 @@ extension InputHandler {
|
|||
delegate.switchState(inputting)
|
||||
let candidateState = generateStateOfCandidates()
|
||||
if candidateState.candidates.isEmpty {
|
||||
errorCallback("B5127D8A")
|
||||
delegate.callError("B5127D8A")
|
||||
} else {
|
||||
delegate.switchState(candidateState)
|
||||
}
|
||||
} else { // 不要在注音沒敲完整的情況下叫出統合符號選單。
|
||||
errorCallback("17446655")
|
||||
delegate.callError("17446655")
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -280,7 +272,7 @@ extension InputHandler {
|
|||
let parser = currentKeyboardParser
|
||||
let arrCustomPunctuations: [String] = [punctuationNamePrefix, parser, input.text]
|
||||
let customPunctuation: String = arrCustomPunctuations.joined()
|
||||
if handlePunctuation(customPunctuation, errorCallback: errorCallback) {
|
||||
if handlePunctuation(customPunctuation) {
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -289,7 +281,7 @@ extension InputHandler {
|
|||
let arrPunctuations: [String] = [punctuationNamePrefix, input.text]
|
||||
let punctuation: String = arrPunctuations.joined()
|
||||
|
||||
if handlePunctuation(punctuation, errorCallback: errorCallback) {
|
||||
if handlePunctuation(punctuation) {
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -322,7 +314,7 @@ extension InputHandler {
|
|||
return true
|
||||
default: // 包括 case 0,直接塞給組字區。
|
||||
let letter = "_letter_\(inputText)"
|
||||
if handlePunctuation(letter, errorCallback: errorCallback) {
|
||||
if handlePunctuation(letter) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -336,9 +328,9 @@ extension InputHandler {
|
|||
/// 砍掉這一段會導致「F1-F12 按鍵干擾組字區」的問題。
|
||||
/// 暫時只能先恢復這段,且補上偵錯彙報機制,方便今後排查故障。
|
||||
if state.hasComposition || !composer.isEmpty {
|
||||
errorCallback(
|
||||
delegate.callError(
|
||||
"Blocked data: charCode: \(input.charCode), keyCode: \(input.keyCode)")
|
||||
errorCallback("A9BFF20E")
|
||||
delegate.callError("A9BFF20E")
|
||||
delegate.switchState(state)
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -83,7 +83,6 @@ extension InputHandler {
|
|||
// MARK: - 用以生成候選詞陣列及狀態
|
||||
|
||||
/// 拿著給定的候選字詞陣列資料內容,切換至選字狀態。
|
||||
/// - Parameters:
|
||||
/// - Returns: 回呼一個新的選詞狀態,來就給定的候選字詞陣列資料內容顯示選字窗。
|
||||
func generateStateOfCandidates() -> IMEStateProtocol {
|
||||
IMEState.ofCandidates(
|
||||
|
@ -117,12 +116,8 @@ extension InputHandler {
|
|||
/// 用以處理就地新增自訂語彙時的行為。
|
||||
/// - Parameters:
|
||||
/// - input: 輸入按鍵訊號。
|
||||
/// - errorCallback: 錯誤回呼。
|
||||
/// - Returns: 將按鍵行為「是否有處理掉」藉由 SessionCtl 回報給 IMK。
|
||||
func handleMarkingState(
|
||||
input: InputSignalProtocol,
|
||||
errorCallback: @escaping (String) -> Void
|
||||
) -> Bool {
|
||||
func handleMarkingState(input: InputSignalProtocol) -> Bool {
|
||||
guard let delegate = delegate else { return false }
|
||||
let state = delegate.state
|
||||
|
||||
|
@ -133,7 +128,7 @@ extension InputHandler {
|
|||
|
||||
// 阻止用於行內注音輸出的熱鍵。
|
||||
if input.isControlHold, input.isCommandHold, input.isEnter {
|
||||
errorCallback("1198E3E5")
|
||||
delegate.callError("1198E3E5")
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -141,15 +136,15 @@ extension InputHandler {
|
|||
if input.isEnter {
|
||||
// 先判斷是否是在摁了降權組合鍵的時候目標不在庫。
|
||||
if input.isShiftHold, input.isCommandHold, !state.isFilterable {
|
||||
errorCallback("2EAC1F7A")
|
||||
delegate.callError("2EAC1F7A")
|
||||
return true
|
||||
}
|
||||
if !state.isMarkedLengthValid {
|
||||
errorCallback("9AAFAC00")
|
||||
delegate.callError("9AAFAC00")
|
||||
return true
|
||||
}
|
||||
if !delegate.performUserPhraseOperation(addToFilter: false) {
|
||||
errorCallback("5B69CC8D")
|
||||
delegate.callError("5B69CC8D")
|
||||
return true
|
||||
}
|
||||
delegate.switchState(generateStateOfInputting())
|
||||
|
@ -159,11 +154,11 @@ extension InputHandler {
|
|||
// BackSpace & Delete
|
||||
if input.isBackSpace || input.isDelete {
|
||||
if !state.isFilterable {
|
||||
errorCallback("1F88B191")
|
||||
delegate.callError("1F88B191")
|
||||
return true
|
||||
}
|
||||
if !delegate.performUserPhraseOperation(addToFilter: true) {
|
||||
errorCallback("68D3C6C8")
|
||||
delegate.callError("68D3C6C8")
|
||||
return true
|
||||
}
|
||||
delegate.switchState(generateStateOfInputting())
|
||||
|
@ -186,7 +181,7 @@ extension InputHandler {
|
|||
marking.tooltipBackupForInputting = state.tooltipBackupForInputting
|
||||
delegate.switchState(marking.markedRange.isEmpty ? marking.convertedToInputting : marking)
|
||||
} else {
|
||||
errorCallback("1149908D")
|
||||
delegate.callError("1149908D")
|
||||
delegate.switchState(state)
|
||||
}
|
||||
return true
|
||||
|
@ -208,7 +203,7 @@ extension InputHandler {
|
|||
marking.tooltipBackupForInputting = state.tooltipBackupForInputting
|
||||
delegate.switchState(marking.markedRange.isEmpty ? marking.convertedToInputting : marking)
|
||||
} else {
|
||||
errorCallback("9B51408D")
|
||||
delegate.callError("9B51408D")
|
||||
delegate.switchState(state)
|
||||
}
|
||||
return true
|
||||
|
@ -221,12 +216,8 @@ extension InputHandler {
|
|||
/// 標點輸入的處理。
|
||||
/// - Parameters:
|
||||
/// - customPunctuation: 自訂標點索引鍵頭。
|
||||
/// - errorCallback: 錯誤回呼。
|
||||
/// - Returns: 將按鍵行為「是否有處理掉」藉由 SessionCtl 回報給 IMK。
|
||||
func handlePunctuation(
|
||||
_ customPunctuation: String,
|
||||
errorCallback: @escaping (String) -> Void
|
||||
) -> Bool {
|
||||
func handlePunctuation(_ customPunctuation: String) -> Bool {
|
||||
guard let delegate = delegate else { return false }
|
||||
let state = delegate.state
|
||||
|
||||
|
@ -236,7 +227,7 @@ extension InputHandler {
|
|||
|
||||
guard composer.isEmpty else {
|
||||
// 注音沒敲完的情況下,無視標點輸入。
|
||||
errorCallback("A9B69908D")
|
||||
delegate.callError("A9B69908D")
|
||||
delegate.switchState(state)
|
||||
return true
|
||||
}
|
||||
|
@ -263,7 +254,7 @@ extension InputHandler {
|
|||
} else {
|
||||
delegate.switchState(candidateState)
|
||||
}
|
||||
default: errorCallback("8DA4096E")
|
||||
default: delegate.callError("8DA4096E")
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -271,7 +262,6 @@ extension InputHandler {
|
|||
// MARK: - Enter 鍵的處理
|
||||
|
||||
/// Enter 鍵的處理。
|
||||
/// - Parameters:
|
||||
/// - Returns: 將按鍵行為「是否有處理掉」藉由 SessionCtl 回報給 IMK。
|
||||
func handleEnter() -> Bool {
|
||||
guard let delegate = delegate else { return false }
|
||||
|
@ -286,7 +276,6 @@ extension InputHandler {
|
|||
// MARK: - Command+Enter 鍵的處理(注音文)
|
||||
|
||||
/// Command+Enter 鍵的處理(注音文)。
|
||||
/// - Parameters:
|
||||
/// - Returns: 將按鍵行為「是否有處理掉」藉由 SessionCtl 回報給 IMK。
|
||||
func handleCtrlCommandEnter() -> Bool {
|
||||
guard let delegate = delegate else { return false }
|
||||
|
@ -311,7 +300,6 @@ extension InputHandler {
|
|||
// MARK: - Command+Option+Enter 鍵的處理(網頁 Ruby 注音文標記)
|
||||
|
||||
/// Command+Option+Enter 鍵的處理(網頁 Ruby 注音文標記)。
|
||||
/// - Parameters:
|
||||
/// - Returns: 將按鍵行為「是否有處理掉」藉由 SessionCtl 回報給 IMK。
|
||||
func handleCtrlOptionCommandEnter() -> Bool {
|
||||
guard let delegate = delegate else { return false }
|
||||
|
@ -346,12 +334,8 @@ extension InputHandler {
|
|||
/// 處理 BackSpace (macOS Delete) 按鍵行為。
|
||||
/// - Parameters:
|
||||
/// - input: 輸入按鍵訊號。
|
||||
/// - errorCallback: 錯誤回呼。
|
||||
/// - Returns: 將按鍵行為「是否有處理掉」藉由 SessionCtl 回報給 IMK。
|
||||
func handleBackSpace(
|
||||
input: InputSignalProtocol,
|
||||
errorCallback: @escaping (String) -> Void
|
||||
) -> Bool {
|
||||
func handleBackSpace(input: InputSignalProtocol) -> Bool {
|
||||
guard let delegate = delegate else { return false }
|
||||
let state = delegate.state
|
||||
guard state.type == .ofInputting else { return false }
|
||||
|
@ -385,7 +369,7 @@ extension InputHandler {
|
|||
compositor.dropKey(direction: .rear)
|
||||
walk()
|
||||
} else {
|
||||
errorCallback("9D69908D")
|
||||
delegate.callError("9D69908D")
|
||||
delegate.switchState(state)
|
||||
return true
|
||||
}
|
||||
|
@ -406,12 +390,8 @@ extension InputHandler {
|
|||
/// 處理 PC Delete (macOS Fn+BackSpace) 按鍵行為。
|
||||
/// - Parameters:
|
||||
/// - input: 輸入按鍵訊號。
|
||||
/// - errorCallback: 錯誤回呼。
|
||||
/// - Returns: 將按鍵行為「是否有處理掉」藉由 SessionCtl 回報給 IMK。
|
||||
func handleDelete(
|
||||
input: InputSignalProtocol,
|
||||
errorCallback: @escaping (String) -> Void
|
||||
) -> Bool {
|
||||
func handleDelete(input: InputSignalProtocol) -> Bool {
|
||||
guard let delegate = delegate else { return false }
|
||||
let state = delegate.state
|
||||
guard state.type == .ofInputting else { return false }
|
||||
|
@ -422,7 +402,7 @@ extension InputHandler {
|
|||
}
|
||||
|
||||
if compositor.cursor == compositor.length, composer.isEmpty {
|
||||
errorCallback("9B69938D")
|
||||
delegate.callError("9B69938D")
|
||||
delegate.switchState(state)
|
||||
return true
|
||||
}
|
||||
|
@ -447,17 +427,13 @@ extension InputHandler {
|
|||
// MARK: - 處理與當前文字輸入排版前後方向呈 90 度的那兩個方向鍵的按鍵行為
|
||||
|
||||
/// 處理與當前文字輸入排版前後方向呈 90 度的那兩個方向鍵的按鍵行為。
|
||||
/// - Parameters:
|
||||
/// - errorCallback: 錯誤回呼。
|
||||
/// - Returns: 將按鍵行為「是否有處理掉」藉由 SessionCtl 回報給 IMK。
|
||||
func handleClockKey(
|
||||
errorCallback: @escaping (String) -> Void
|
||||
) -> Bool {
|
||||
func handleClockKey() -> Bool {
|
||||
guard let delegate = delegate else { return false }
|
||||
let state = delegate.state
|
||||
guard state.type == .ofInputting else { return false }
|
||||
if !composer.isEmpty {
|
||||
errorCallback("9B6F908D")
|
||||
delegate.callError("9B6F908D")
|
||||
}
|
||||
delegate.switchState(state)
|
||||
return true
|
||||
|
@ -466,18 +442,14 @@ extension InputHandler {
|
|||
// MARK: - 處理 Home 鍵的行為
|
||||
|
||||
/// 處理 Home 鍵的行為。
|
||||
/// - Parameters:
|
||||
/// - errorCallback: 錯誤回呼。
|
||||
/// - Returns: 將按鍵行為「是否有處理掉」藉由 SessionCtl 回報給 IMK。
|
||||
func handleHome(
|
||||
errorCallback: @escaping (String) -> Void
|
||||
) -> Bool {
|
||||
func handleHome() -> Bool {
|
||||
guard let delegate = delegate else { return false }
|
||||
let state = delegate.state
|
||||
guard state.type == .ofInputting else { return false }
|
||||
|
||||
if !composer.isEmpty {
|
||||
errorCallback("ABC44080")
|
||||
delegate.callError("ABC44080")
|
||||
delegate.switchState(state)
|
||||
return true
|
||||
}
|
||||
|
@ -486,7 +458,7 @@ extension InputHandler {
|
|||
compositor.cursor = 0
|
||||
delegate.switchState(generateStateOfInputting())
|
||||
} else {
|
||||
errorCallback("66D97F90")
|
||||
delegate.callError("66D97F90")
|
||||
delegate.switchState(state)
|
||||
}
|
||||
|
||||
|
@ -496,18 +468,14 @@ extension InputHandler {
|
|||
// MARK: - 處理 End 鍵的行為
|
||||
|
||||
/// 處理 End 鍵的行為。
|
||||
/// - Parameters:
|
||||
/// - errorCallback: 錯誤回呼。
|
||||
/// - Returns: 將按鍵行為「是否有處理掉」藉由 SessionCtl 回報給 IMK。
|
||||
func handleEnd(
|
||||
errorCallback: @escaping (String) -> Void
|
||||
) -> Bool {
|
||||
func handleEnd() -> Bool {
|
||||
guard let delegate = delegate else { return false }
|
||||
let state = delegate.state
|
||||
guard state.type == .ofInputting else { return false }
|
||||
|
||||
if !composer.isEmpty {
|
||||
errorCallback("9B69908D")
|
||||
delegate.callError("9B69908D")
|
||||
delegate.switchState(state)
|
||||
return true
|
||||
}
|
||||
|
@ -516,7 +484,7 @@ extension InputHandler {
|
|||
compositor.cursor = compositor.length
|
||||
delegate.switchState(generateStateOfInputting())
|
||||
} else {
|
||||
errorCallback("9B69908E")
|
||||
delegate.callError("9B69908E")
|
||||
delegate.switchState(state)
|
||||
}
|
||||
|
||||
|
@ -526,7 +494,6 @@ extension InputHandler {
|
|||
// MARK: - 處理 Esc 鍵的行為
|
||||
|
||||
/// 處理 Esc 鍵的行為。
|
||||
/// - Parameters:
|
||||
/// - Returns: 將按鍵行為「是否有處理掉」藉由 SessionCtl 回報給 IMK。
|
||||
func handleEsc() -> Bool {
|
||||
guard let delegate = delegate else { return false }
|
||||
|
@ -555,18 +522,14 @@ extension InputHandler {
|
|||
/// 處理向前方向鍵的行為。
|
||||
/// - Parameters:
|
||||
/// - input: 輸入按鍵訊號。
|
||||
/// - errorCallback: 錯誤回呼。
|
||||
/// - Returns: 將按鍵行為「是否有處理掉」藉由 SessionCtl 回報給 IMK。
|
||||
func handleForward(
|
||||
input: InputSignalProtocol,
|
||||
errorCallback: @escaping (String) -> Void
|
||||
) -> Bool {
|
||||
func handleForward(input: InputSignalProtocol) -> Bool {
|
||||
guard let delegate = delegate else { return false }
|
||||
let state = delegate.state
|
||||
guard state.type == .ofInputting else { return false }
|
||||
|
||||
if !composer.isEmpty {
|
||||
errorCallback("B3BA5257")
|
||||
delegate.callError("B3BA5257")
|
||||
delegate.switchState(state)
|
||||
return true
|
||||
}
|
||||
|
@ -587,16 +550,16 @@ extension InputHandler {
|
|||
marking.tooltipBackupForInputting = state.tooltip
|
||||
delegate.switchState(marking)
|
||||
} else {
|
||||
errorCallback("BB7F6DB9")
|
||||
delegate.callError("BB7F6DB9")
|
||||
delegate.switchState(state)
|
||||
}
|
||||
} else if input.isOptionHold {
|
||||
if input.isControlHold {
|
||||
return handleEnd(errorCallback: errorCallback)
|
||||
return handleEnd()
|
||||
}
|
||||
// 游標跳轉動作無論怎樣都會執行,但如果出了執行失敗的結果的話則觸發報錯流程。
|
||||
if !compositor.jumpCursorBySpan(to: .front) {
|
||||
errorCallback("33C3B580")
|
||||
delegate.callError("33C3B580")
|
||||
delegate.switchState(state)
|
||||
return true
|
||||
}
|
||||
|
@ -609,7 +572,7 @@ extension InputHandler {
|
|||
}
|
||||
delegate.switchState(generateStateOfInputting())
|
||||
} else {
|
||||
errorCallback("A96AAD58")
|
||||
delegate.callError("A96AAD58")
|
||||
delegate.switchState(state)
|
||||
}
|
||||
}
|
||||
|
@ -622,18 +585,14 @@ extension InputHandler {
|
|||
/// 處理向後方向鍵的行為。
|
||||
/// - Parameters:
|
||||
/// - input: 輸入按鍵訊號。
|
||||
/// - errorCallback: 錯誤回呼。
|
||||
/// - Returns: 將按鍵行為「是否有處理掉」藉由 SessionCtl 回報給 IMK。
|
||||
func handleBackward(
|
||||
input: InputSignalProtocol,
|
||||
errorCallback: @escaping (String) -> Void
|
||||
) -> Bool {
|
||||
func handleBackward(input: InputSignalProtocol) -> Bool {
|
||||
guard let delegate = delegate else { return false }
|
||||
let state = delegate.state
|
||||
guard state.type == .ofInputting else { return false }
|
||||
|
||||
if !composer.isEmpty {
|
||||
errorCallback("6ED95318")
|
||||
delegate.callError("6ED95318")
|
||||
delegate.switchState(state)
|
||||
return true
|
||||
}
|
||||
|
@ -654,16 +613,16 @@ extension InputHandler {
|
|||
marking.tooltipBackupForInputting = state.tooltip
|
||||
delegate.switchState(marking)
|
||||
} else {
|
||||
errorCallback("D326DEA3")
|
||||
delegate.callError("D326DEA3")
|
||||
delegate.switchState(state)
|
||||
}
|
||||
} else if input.isOptionHold {
|
||||
if input.isControlHold {
|
||||
return handleHome(errorCallback: errorCallback)
|
||||
return handleHome()
|
||||
}
|
||||
// 游標跳轉動作無論怎樣都會執行,但如果出了執行失敗的結果的話則觸發報錯流程。
|
||||
if !compositor.jumpCursorBySpan(to: .rear) {
|
||||
errorCallback("8D50DD9E")
|
||||
delegate.callError("8D50DD9E")
|
||||
delegate.switchState(state)
|
||||
return true
|
||||
}
|
||||
|
@ -676,7 +635,7 @@ extension InputHandler {
|
|||
}
|
||||
delegate.switchState(generateStateOfInputting())
|
||||
} else {
|
||||
errorCallback("7045E6F3")
|
||||
delegate.callError("7045E6F3")
|
||||
delegate.switchState(state)
|
||||
}
|
||||
}
|
||||
|
@ -689,18 +648,14 @@ extension InputHandler {
|
|||
/// 以給定之參數來處理上下文候選字詞之輪替。
|
||||
/// - Parameters:
|
||||
/// - reverseOrder: 是否有控制輪替方向的修飾鍵輸入。
|
||||
/// - errorCallback: 錯誤回呼。
|
||||
/// - Returns: 將按鍵行為「是否有處理掉」藉由 SessionCtl 回報給 IMK。
|
||||
func handleInlineCandidateRotation(
|
||||
reverseOrder: Bool,
|
||||
errorCallback: @escaping (String) -> Void
|
||||
) -> Bool {
|
||||
func handleInlineCandidateRotation(reverseOrder: Bool) -> Bool {
|
||||
guard let delegate = delegate else { return false }
|
||||
let state = delegate.state
|
||||
if composer.isEmpty, compositor.isEmpty || compositor.walkedNodes.isEmpty { return false }
|
||||
guard state.type == .ofInputting else {
|
||||
guard state.type == .ofEmpty else {
|
||||
errorCallback("6044F081")
|
||||
delegate.callError("6044F081")
|
||||
return true
|
||||
}
|
||||
// 不妨礙使用者平時輸入 Tab 的需求。
|
||||
|
@ -708,13 +663,13 @@ extension InputHandler {
|
|||
}
|
||||
|
||||
guard composer.isEmpty else {
|
||||
errorCallback("A2DAF7BC")
|
||||
delegate.callError("A2DAF7BC")
|
||||
return true
|
||||
}
|
||||
|
||||
let candidates = generateArrayOfCandidates(fixOrder: true)
|
||||
guard !candidates.isEmpty else {
|
||||
errorCallback("3378A6DF")
|
||||
delegate.callError("3378A6DF")
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -730,7 +685,7 @@ extension InputHandler {
|
|||
}
|
||||
|
||||
guard let currentNode = currentNode else {
|
||||
errorCallback("F58DEA95")
|
||||
delegate.callError("F58DEA95")
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,11 @@ extension SessionCtl: InputHandlerDelegate {
|
|||
candidatePairSelected(at: index)
|
||||
}
|
||||
|
||||
public func callError(_ logMessage: String) {
|
||||
vCLog(logMessage)
|
||||
IMEApp.buzz()
|
||||
}
|
||||
|
||||
public func performUserPhraseOperation(addToFilter: Bool) -> Bool {
|
||||
guard state.type == .ofMarking else { return false }
|
||||
if !LMMgr.writeUserPhrase(
|
||||
|
|
Loading…
Reference in New Issue