Pre Merge pull request !68 from ShikiSuen/upd/1.8.5

This commit is contained in:
ShikiSuen 2022-07-27 06:23:00 +00:00 committed by Gitee
commit 76b32e6d50
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
28 changed files with 488 additions and 375 deletions

View File

@ -27,6 +27,34 @@ import Foundation
public class ChineseConverter {
public static let shared = HotenkaChineseConverter.init(plistDir: mgrLangModel.getBundleDataPath("convdict"))
///
private static let currencyNumeralDictTable: [String: (String, String, String, String)] = [
"": ("", "", "", ""), "": ("", "", "", ""), "": ("", "", "", ""),
"": ("", "", "", ""), "": ("", "", "", ""), "": ("", "", "", ""),
"": ("", "", "", ""), "": ("", "", "", ""), "": ("", "", "", ""),
"": ("", "", "", ""), "": ("", "", "", ""), "": ("", "", "", ""),
"": ("", "", "", ""), "": ("", "", "", ""),
]
///
/// - Parameter target:
public static func ensureCurrencyNumerals(target: inout String) {
if !mgrPrefs.currencyNumeralsEnabled { return }
for key in currencyNumeralDictTable.keys {
guard let result = currencyNumeralDictTable[key] else { continue }
if IME.currentInputMode == InputMode.imeModeCHS {
target = target.replacingOccurrences(of: key, with: result.3) // Simplified Chinese
continue
}
switch (mgrPrefs.chineseConversionEnabled, mgrPrefs.shiftJISShinjitaiOutputEnabled) {
case (false, true), (true, true): target = target.replacingOccurrences(of: key, with: result.2) // JIS
case (true, false): target = target.replacingOccurrences(of: key, with: result.0) // KangXi
default: target = target.replacingOccurrences(of: key, with: result.1) // Contemporary
}
}
return
}
/// CrossConvert.
///
/// - Parameter string: Text in Original Script.

@ -1 +1 @@
Subproject commit 94b215d444e1c43e81ad173e9c28e6769f74c330
Subproject commit 2cbca5af7f281b7932878cda5e63f2dfed6b48b0

View File

@ -115,6 +115,9 @@ enum KeyCodeBlackListed: UInt16 {
/// 95 Key Code JIS
let arrNumpadKeyCodes: [UInt16] = [65, 67, 69, 71, 75, 78, 81, 82, 83, 84, 85, 86, 87, 88, 89, 91, 92, 95]
/// KeyCode
let arrMainAreaNumKey: [UInt16] = [18, 19, 20, 21, 22, 23, 25, 26, 28, 29]
// CharCodes: https://theasciicode.com.ar/ascii-control-characters/horizontal-tab-ascii-code-9.html
enum CharCode: UInt16 {
case yajuusenpaiA = 114
@ -128,27 +131,25 @@ enum CharCode: UInt16 {
struct InputSignal: CustomStringConvertible {
private(set) var isTypingVertical: Bool
private(set) var inputText: String?
private(set) var inputText: String
private(set) var inputTextIgnoringModifiers: String?
private(set) var charCode: UInt16
private(set) var keyCode: UInt16
private var isFlagChanged: Bool
private var flags: NSEvent.ModifierFlags
private var cursorForwardKey: KeyCode = .kNone
private var cursorBackwardKey: KeyCode = .kNone
private var extraChooseCandidateKey: KeyCode = .kNone
private var extraChooseCandidateKeyReverse: KeyCode = .kNone
private var absorbedArrowKey: KeyCode = .kNone
private var verticalTypingOnlyChooseCandidateKey: KeyCode = .kNone
private var cursorForwardKey: KeyCode = .kNone // 12 o'clock
private var cursorBackwardKey: KeyCode = .kNone // 6 o'clock
private var cursorKeyClockRight: KeyCode = .kNone // 3 o'clock
private var cursorKeyClockLeft: KeyCode = .kNone // 9 o'clock
private(set) var emacsKey: EmacsKey
public init(
inputText: String?, keyCode: UInt16, charCode: UInt16, flags: NSEvent.ModifierFlags,
inputText: String = "", keyCode: UInt16, charCode: UInt16, flags: NSEvent.ModifierFlags,
isVerticalTyping: Bool = false, inputTextIgnoringModifiers: String? = nil
) {
self.inputText = AppleKeyboardConverter.cnvStringApple2ABC(inputText ?? "")
self.inputText = AppleKeyboardConverter.cnvStringApple2ABC(inputText)
self.inputTextIgnoringModifiers = AppleKeyboardConverter.cnvStringApple2ABC(
inputTextIgnoringModifiers ?? inputText ?? "")
inputTextIgnoringModifiers ?? inputText)
self.flags = flags
isFlagChanged = false
isTypingVertical = isVerticalTyping
@ -164,7 +165,7 @@ struct InputSignal: CustomStringConvertible {
public init(event: NSEvent, isVerticalTyping: Bool = false) {
inputText = AppleKeyboardConverter.cnvStringApple2ABC(event.characters ?? "")
inputTextIgnoringModifiers = AppleKeyboardConverter.cnvStringApple2ABC(
event.charactersIgnoringModifiers ?? "")
event.charactersIgnoringModifiers ?? inputText)
keyCode = event.keyCode
flags = event.modifierFlags
isFlagChanged = (event.type == .flagsChanged)
@ -188,173 +189,83 @@ struct InputSignal: CustomStringConvertible {
mutating func defineArrowKeys() {
cursorForwardKey = isTypingVertical ? .kDownArrow : .kRightArrow
cursorBackwardKey = isTypingVertical ? .kUpArrow : .kLeftArrow
extraChooseCandidateKey = isTypingVertical ? .kLeftArrow : .kDownArrow
extraChooseCandidateKeyReverse = isTypingVertical ? .kRightArrow : .kUpArrow
absorbedArrowKey = isTypingVertical ? .kRightArrow : .kUpArrow
verticalTypingOnlyChooseCandidateKey = isTypingVertical ? absorbedArrowKey : .kNone
cursorKeyClockLeft = isTypingVertical ? .kRightArrow : .kUpArrow
cursorKeyClockRight = isTypingVertical ? .kLeftArrow : .kDownArrow
}
var description: String {
"<inputText:\(String(describing: inputText)), inputTextIgnoringModifiers:\(String(describing: inputTextIgnoringModifiers)) charCode:\(charCode), keyCode:\(keyCode), flags:\(flags), cursorForwardKey:\(cursorForwardKey), cursorBackwardKey:\(cursorBackwardKey), extraChooseCandidateKey:\(extraChooseCandidateKey), extraChooseCandidateKeyReverse:\(extraChooseCandidateKeyReverse), absorbedArrowKey:\(absorbedArrowKey), verticalTypingOnlyChooseCandidateKey:\(verticalTypingOnlyChooseCandidateKey), emacsKey:\(emacsKey), isTypingVertical:\(isTypingVertical)>"
var result = "<[InputSignal] "
result += "inputText:\(String(describing: inputText)), "
result += "inputTextIgnoringModifiers:\(String(describing: inputTextIgnoringModifiers)), "
result += "charCode:\(charCode), "
result += "keyCode:\(keyCode), "
result += "flags:\(flags), "
result += "cursorForwardKey:\(cursorForwardKey), "
result += "cursorBackwardKey:\(cursorBackwardKey), "
result += "cursorKeyClockRight:\(cursorKeyClockRight), "
result += "cursorKeyClockLeft:\(cursorKeyClockLeft), "
result += "emacsKey:\(emacsKey), "
result += "isTypingVertical:\(isTypingVertical)"
result += ">"
return result
}
// ANSI charCode Swift KeyHandler
var isInvalidInput: Bool {
switch charCode {
case 0x20...0xFF: // ANSI charCode
return false
default:
if isReservedKey, !isKeyCodeBlacklisted {
return false
}
return true
}
}
var isInvalid: Bool { (0x20...0xFF).contains(charCode) ? false : !(isReservedKey && !isKeyCodeBlacklisted) }
var isKeyCodeBlacklisted: Bool {
guard let code = KeyCodeBlackListed(rawValue: keyCode) else {
return false
}
guard let code = KeyCodeBlackListed(rawValue: keyCode) else { return false }
return code.rawValue != KeyCode.kNone.rawValue
}
var isShiftHold: Bool {
flags.contains([.shift])
}
var isCommandHold: Bool {
flags.contains([.command])
}
var isControlHold: Bool {
flags.contains([.control])
}
var isControlHotKey: Bool {
flags.contains([.control]) && inputText?.first?.isLetter ?? false
}
var isOptionHold: Bool {
flags.contains([.option])
}
var isOptionHotKey: Bool {
flags.contains([.option]) && inputText?.first?.isLetter ?? false
}
var isCapsLockOn: Bool {
flags.contains([.capsLock])
}
var isNumericPad: Bool {
flags.contains([.numericPad])
}
var isFunctionKeyHold: Bool {
flags.contains([.function])
}
var isReservedKey: Bool {
guard let code = KeyCode(rawValue: keyCode) else {
return false
}
guard let code = KeyCode(rawValue: keyCode) else { return false }
return code.rawValue != KeyCode.kNone.rawValue
}
// Alt+Shift+ macOS
// KeyCode
let mapMainAreaNumKey: [UInt16: String] = [
18: "1", 19: "2", 20: "3", 21: "4", 23: "5", 22: "6", 26: "7", 28: "8", 25: "9", 29: "0",
]
/// flags KeyCode
var isNumericPadAreaKey: Bool {
arrNumpadKeyCodes.contains(keyCode)
}
var isNumericPadKey: Bool { arrNumpadKeyCodes.contains(keyCode) }
var isMainAreaNumKey: Bool { arrMainAreaNumKey.contains(keyCode) }
var isShiftHold: Bool { flags.contains([.shift]) }
var isCommandHold: Bool { flags.contains([.command]) }
var isControlHold: Bool { flags.contains([.control]) }
var isControlHotKey: Bool { flags.contains([.control]) && inputText.first?.isLetter ?? false }
var isOptionHold: Bool { flags.contains([.option]) }
var isOptionHotKey: Bool { flags.contains([.option]) && inputText.first?.isLetter ?? false }
var isCapsLockOn: Bool { flags.contains([.capsLock]) }
var isFunctionKeyHold: Bool { flags.contains([.function]) }
var isNonLaptopFunctionKey: Bool { flags.contains([.numericPad]) && !isNumericPadKey }
var isEnter: Bool { [KeyCode.kCarriageReturn, KeyCode.kLineFeed].contains(KeyCode(rawValue: keyCode)) }
var isTab: Bool { KeyCode(rawValue: keyCode) == KeyCode.kTab }
var isUp: Bool { KeyCode(rawValue: keyCode) == KeyCode.kUpArrow }
var isDown: Bool { KeyCode(rawValue: keyCode) == KeyCode.kDownArrow }
var isLeft: Bool { KeyCode(rawValue: keyCode) == KeyCode.kLeftArrow }
var isRight: Bool { KeyCode(rawValue: keyCode) == KeyCode.kRightArrow }
var isPageUp: Bool { KeyCode(rawValue: keyCode) == KeyCode.kPageUp }
var isPageDown: Bool { KeyCode(rawValue: keyCode) == KeyCode.kPageDown }
var isSpace: Bool { KeyCode(rawValue: keyCode) == KeyCode.kSpace }
var isBackSpace: Bool { KeyCode(rawValue: keyCode) == KeyCode.kBackSpace }
var isEsc: Bool { KeyCode(rawValue: keyCode) == KeyCode.kEscape }
var isHome: Bool { KeyCode(rawValue: keyCode) == KeyCode.kHome }
var isEnd: Bool { KeyCode(rawValue: keyCode) == KeyCode.kEnd }
var isDelete: Bool { KeyCode(rawValue: keyCode) == KeyCode.kWindowsDelete }
var isCursorBackward: Bool { KeyCode(rawValue: keyCode) == cursorBackwardKey }
var isCursorForward: Bool { KeyCode(rawValue: keyCode) == cursorForwardKey }
var isCursorClockRight: Bool { KeyCode(rawValue: keyCode) == cursorKeyClockRight }
var isCursorClockLeft: Bool { KeyCode(rawValue: keyCode) == cursorKeyClockLeft }
var isTab: Bool {
KeyCode(rawValue: keyCode) == KeyCode.kTab
}
var isEnter: Bool {
(KeyCode(rawValue: keyCode) == KeyCode.kCarriageReturn)
|| (KeyCode(rawValue: keyCode) == KeyCode.kLineFeed)
}
var isUp: Bool {
KeyCode(rawValue: keyCode) == KeyCode.kUpArrow
}
var isDown: Bool {
KeyCode(rawValue: keyCode) == KeyCode.kDownArrow
}
var isLeft: Bool {
KeyCode(rawValue: keyCode) == KeyCode.kLeftArrow
}
var isRight: Bool {
KeyCode(rawValue: keyCode) == KeyCode.kRightArrow
}
var isPageUp: Bool {
KeyCode(rawValue: keyCode) == KeyCode.kPageUp
}
var isPageDown: Bool {
KeyCode(rawValue: keyCode) == KeyCode.kPageDown
}
var isSpace: Bool {
KeyCode(rawValue: keyCode) == KeyCode.kSpace
}
var isBackSpace: Bool {
KeyCode(rawValue: keyCode) == KeyCode.kBackSpace
}
var isEsc: Bool {
KeyCode(rawValue: keyCode) == KeyCode.kEscape
}
var isHome: Bool {
KeyCode(rawValue: keyCode) == KeyCode.kHome
}
var isEnd: Bool {
KeyCode(rawValue: keyCode) == KeyCode.kEnd
}
var isDelete: Bool {
KeyCode(rawValue: keyCode) == KeyCode.kWindowsDelete
}
var isCursorBackward: Bool {
KeyCode(rawValue: keyCode) == cursorBackwardKey
}
var isCursorForward: Bool {
KeyCode(rawValue: keyCode) == cursorForwardKey
}
var isAbsorbedArrowKey: Bool {
KeyCode(rawValue: keyCode) == absorbedArrowKey
}
var isExtraChooseCandidateKey: Bool {
KeyCode(rawValue: keyCode) == extraChooseCandidateKey
}
var isExtraChooseCandidateKeyReverse: Bool {
KeyCode(rawValue: keyCode) == extraChooseCandidateKeyReverse
}
var isVerticalTypingOnlyChooseCandidateKey: Bool {
KeyCode(rawValue: keyCode) == verticalTypingOnlyChooseCandidateKey
}
var isUpperCaseASCIILetterKey: Bool {
// flags == .shift Shift
(65...90).contains(charCode) && flags == .shift
}
// flags == .shift Shift
var isUpperCaseASCIILetterKey: Bool { (65...90).contains(charCode) && flags == .shift }
// KeyCode macOS Apple
// ![input isShift] 使 Shift
var isSymbolMenuPhysicalKey: Bool {
// KeyCode macOS Apple
// ![input isShift] 使 Shift
[KeyCode.kSymbolMenuPhysicalKeyIntl, KeyCode.kSymbolMenuPhysicalKeyJIS].contains(KeyCode(rawValue: keyCode))
}
}

View File

@ -33,7 +33,7 @@ enum StateType {
case ofDeactivated
case ofAssociatedPhrases
case ofEmpty
case ofEmptyIgnorePreviousState
case ofEmptyIgnoringPreviousState
case ofCommitting
case ofNotEmpty
case ofInputting
@ -70,7 +70,7 @@ protocol InputStateProtocol {
/// 西 .NotEmpty
/// - .Empty: 使
///
/// - .EmptyIgnorePreviousState: Empty
/// - .EmptyIgnoringPreviousState: Empty
/// .Empty()
/// - .Committing:
/// - .NotEmpty:
@ -106,11 +106,11 @@ enum InputState {
// MARK: -
/// .EmptyIgnorePreviousState: Empty
/// .EmptyIgnoringPreviousState: Empty
///
/// .Empty()
class EmptyIgnoringPreviousState: Empty {
override public var type: StateType { .ofEmptyIgnorePreviousState }
override public var type: StateType { .ofEmptyIgnoringPreviousState }
override var description: String {
"<InputState.EmptyIgnoringPreviousState>"
}
@ -126,6 +126,7 @@ enum InputState {
convenience init(textToCommit: String) {
self.init()
self.textToCommit = textToCommit
ChineseConverter.ensureCurrencyNumerals(target: &self.textToCommit)
}
var description: String {
@ -146,6 +147,17 @@ enum InputState {
self.isTypingVertical = isTypingVertical
}
var attributedString: NSMutableAttributedString {
let attributedString = NSMutableAttributedString(
string: " ",
attributes: [
.underlineStyle: NSUnderlineStyle.single.rawValue,
.markedClauseSegment: 0,
]
)
return attributedString
}
var description: String {
"<InputState.AssociatedPhrases, candidates:\(candidates), isTypingVertical:\(isTypingVertical)>"
}

View File

@ -288,7 +288,7 @@ extension KeyHandler {
var index: Int = NSNotFound
let match: String =
(state is InputState.AssociatedPhrases) ? input.inputTextIgnoringModifiers ?? "" : inputText ?? ""
(state is InputState.AssociatedPhrases) ? input.inputTextIgnoringModifiers ?? "" : inputText
var j = 0
while j < ctlCandidateCurrent.keyLabels.count {

View File

@ -0,0 +1,154 @@
// Copyright (c) 2021 and onwards The vChewing Project (MIT-NTL License).
// Refactored from the ObjCpp-version of this class by:
// (c) 2011 and onwards The OpenVanilla Project (MIT License).
/*
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
1. The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
2. No trademark license is granted to use the trade names, trademarks, service
marks, or product names of Contributor, except as required to fulfill notice
requirements above.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/// KeyHandler.HandleInput()
extension KeyHandler {
/// KeyHandler.HandleInput()
/// - Parameters:
/// - input:
/// - state:
/// - stateCallback:
/// - errorCallback:
/// - Returns: IMK
func handleComposition(
input: InputSignal,
state: InputStateProtocol,
stateCallback: @escaping (InputStateProtocol) -> Void,
errorCallback: @escaping () -> Void
) -> Bool? {
// MARK: (Handle BPMF Keys)
var keyConsumedByReading = false
let skipPhoneticHandling =
input.isReservedKey || input.isNumericPadKey || input.isNonLaptopFunctionKey
|| input.isControlHold || input.isOptionHold || input.isShiftHold || input.isCommandHold
// inputValidityCheck() charCode UniChar
// keyConsumedByReading
// composer.receiveKey() String UniChar
if !skipPhoneticHandling && composer.inputValidityCheck(key: input.charCode) {
composer.receiveKey(fromCharCode: input.charCode)
keyConsumedByReading = true
// 調 updateClientComposingBuffer() return true
// 調
if !composer.hasToneMarker() {
stateCallback(buildInputtingState)
return true
}
}
var composeReading = composer.hasToneMarker() //
// Enter Space _composer
// |=
composeReading = composeReading || (!composer.isEmpty && (input.isSpace || input.isEnter))
if composeReading {
if input.isSpace, !composer.hasToneMarker() {
// 調
// 使 OVMandarin調
composer.receiveKey(fromString: " ")
}
let readingKey = composer.getComposition() //
//
//
if !currentLM.hasUnigramsFor(key: readingKey) {
IME.prtDebugIntel("B49C0979語彙庫內無「\(readingKey)」的匹配記錄。")
errorCallback()
composer.clear()
//
stateCallback((compositor.isEmpty) ? InputState.EmptyIgnoringPreviousState() : buildInputtingState)
return true // IMK
}
//
compositor.insertReading(readingKey)
//
let textToCommit = commitOverflownCompositionAndWalk
//
fetchAndApplySuggestionsFromUserOverrideModel()
//
markNodesFixedIfNecessary()
//
composer.clear()
// updateClientComposingBuffer()
let inputting = buildInputtingState
inputting.textToCommit = textToCommit
stateCallback(inputting)
///
if mgrPrefs.useSCPCTypingMode {
let choosingCandidates: InputState.ChoosingCandidate = buildCandidate(
state: inputting,
isTypingVertical: input.isTypingVertical
)
if choosingCandidates.candidates.count == 1 {
clear()
let reading: String = choosingCandidates.candidates.first?.0 ?? ""
let text: String = choosingCandidates.candidates.first?.1 ?? ""
stateCallback(InputState.Committing(textToCommit: text))
if !mgrPrefs.associatedPhrasesEnabled {
stateCallback(InputState.Empty())
} else {
if let associatedPhrases =
buildAssociatePhraseState(
withPair: .init(key: reading, value: text),
isTypingVertical: input.isTypingVertical
), !associatedPhrases.candidates.isEmpty
{
stateCallback(associatedPhrases)
} else {
stateCallback(InputState.Empty())
}
}
} else {
stateCallback(choosingCandidates)
}
}
// ctlInputMethod IMK
return true
}
/// true 調調
/// 6jˊˊ調
/// 調ˊˊˊˊˇˊ
if keyConsumedByReading {
// updateClientComposingBuffer()
stateCallback(buildInputtingState)
return true
}
return nil
}
}

View File

@ -45,18 +45,17 @@ extension KeyHandler {
stateCallback: @escaping (InputStateProtocol) -> Void,
errorCallback: @escaping () -> Void
) -> Bool {
// inputTest
guard !input.inputText.isEmpty else { return false }
let charCode: UniChar = input.charCode
let inputText: String = input.inputText
var state = state //
// inputTest
guard let inputText: String = input.inputText, !inputText.isEmpty else {
return false
}
// Megrez
if input.isInvalidInput {
if input.isInvalid {
// .Empty(IgnoringPreviousState) .Deactivated
// .EmptyIgnorePreviousState.Empty
// .EmptyIgnoringPreviousState.Empty
if state is InputState.Empty || state is InputState.Deactivated {
return false
}
@ -68,7 +67,7 @@ extension KeyHandler {
//
let isFunctionKey: Bool =
input.isControlHotKey || (input.isCommandHold || input.isOptionHotKey || input.isNumericPad)
input.isControlHotKey || (input.isCommandHold || input.isOptionHotKey || input.isNonLaptopFunctionKey)
if !(state is InputState.NotEmpty) && !(state is InputState.AssociatedPhrases) && isFunctionKey {
return false
}
@ -79,8 +78,9 @@ extension KeyHandler {
/// Shift Chromium
/// IMK Shift 使
/// Caps Lock
if input.isBackSpace || input.isEnter || input.isAbsorbedArrowKey || input.isExtraChooseCandidateKey
|| input.isExtraChooseCandidateKeyReverse || input.isCursorForward || input.isCursorBackward
if input.isBackSpace || input.isEnter
|| input.isCursorClockLeft || input.isCursorClockRight
|| input.isCursorForward || input.isCursorBackward
{
// BackSpace
} else if input.isCapsLockOn {
@ -108,10 +108,10 @@ extension KeyHandler {
// MARK: (Numeric Pad Processing)
// isNumericPadAreaKey KeyCode
//
// isNumericPadKey KeyCode
// 使 Cocoa flags
//
if input.isNumericPadAreaKey {
if input.isNumericPadKey {
if !(state is InputState.ChoosingCandidate || state is InputState.AssociatedPhrases
|| state is InputState.SymbolTable)
{
@ -158,117 +158,17 @@ extension KeyHandler {
// MARK: (Handle BPMF Keys)
var keyConsumedByReading = false
let skipPhoneticHandling = input.isReservedKey || input.isControlHold || input.isOptionHold
// inputValidityCheck() charCode UniChar
// keyConsumedByReading
// composer.receiveKey() String UniChar
if !skipPhoneticHandling && composer.inputValidityCheck(key: charCode) {
composer.receiveKey(fromCharCode: charCode)
keyConsumedByReading = true
// 調 updateClientComposingBuffer() return true
// 調
if !composer.hasToneMarker() {
stateCallback(buildInputtingState)
return true
}
}
var composeReading = composer.hasToneMarker() //
// Enter Space _composer
// |=
composeReading = composeReading || (!composer.isEmpty && (input.isSpace || input.isEnter))
if composeReading {
if input.isSpace, !composer.hasToneMarker() {
// 調
// 使 OVMandarin調
composer.receiveKey(fromString: " ")
}
let readingKey = composer.getComposition() //
//
//
if !currentLM.hasUnigramsFor(key: readingKey) {
IME.prtDebugIntel("B49C0979語彙庫內無「\(readingKey)」的匹配記錄。")
errorCallback()
composer.clear()
//
stateCallback((compositor.isEmpty) ? InputState.EmptyIgnoringPreviousState() : buildInputtingState)
return true // IMK
}
//
compositor.insertReading(readingKey)
//
let textToCommit = commitOverflownCompositionAndWalk
//
fetchAndApplySuggestionsFromUserOverrideModel()
//
markNodesFixedIfNecessary()
//
composer.clear()
// updateClientComposingBuffer()
let inputting = buildInputtingState
inputting.textToCommit = textToCommit
stateCallback(inputting)
///
if mgrPrefs.useSCPCTypingMode {
let choosingCandidates: InputState.ChoosingCandidate = buildCandidate(
state: inputting,
isTypingVertical: input.isTypingVertical
)
if choosingCandidates.candidates.count == 1 {
clear()
let reading: String = choosingCandidates.candidates.first?.0 ?? ""
let text: String = choosingCandidates.candidates.first?.1 ?? ""
stateCallback(InputState.Committing(textToCommit: text))
if !mgrPrefs.associatedPhrasesEnabled {
stateCallback(InputState.Empty())
} else {
if let associatedPhrases =
buildAssociatePhraseState(
withPair: .init(key: reading, value: text),
isTypingVertical: input.isTypingVertical
), !associatedPhrases.candidates.isEmpty
{
stateCallback(associatedPhrases)
} else {
stateCallback(InputState.Empty())
}
}
} else {
stateCallback(choosingCandidates)
}
}
// ctlInputMethod IMK
return true
}
/// true 調調
/// 6jˊˊ調
/// 調ˊˊˊˊˇˊ
if keyConsumedByReading {
// updateClientComposingBuffer()
stateCallback(buildInputtingState)
return true
if let compositionHandled = handleComposition(
input: input, state: state, stateCallback: stateCallback, errorCallback: errorCallback)
{
return compositionHandled
}
// MARK: (Calling candidate window using Up / Down or PageUp / PageDn.)
if let currentState = state as? InputState.NotEmpty, composer.isEmpty, !input.isOptionHold,
input.isExtraChooseCandidateKey || input.isExtraChooseCandidateKeyReverse || input.isSpace
input.isCursorClockLeft || input.isCursorClockRight || input.isSpace
|| input.isPageDown || input.isPageUp || (input.isTab && mgrPrefs.specifyShiftTabKeyBehavior)
|| (input.isTypingVertical && (input.isVerticalTypingOnlyChooseCandidateKey))
{
if input.isSpace {
/// Space
@ -354,22 +254,22 @@ extension KeyHandler {
return handleEnd(state: state, stateCallback: stateCallback, errorCallback: errorCallback)
}
// MARK: AbsorbedArrowKey
// MARK: Clock-Left & Clock-Right
if input.isAbsorbedArrowKey || input.isExtraChooseCandidateKey || input.isExtraChooseCandidateKeyReverse {
if input.isCursorClockLeft || input.isCursorClockRight {
if input.isOptionHold, state is InputState.Inputting {
if input.isExtraChooseCandidateKey {
if input.isCursorClockRight {
return handleInlineCandidateRotation(
state: state, reverseModifier: false, stateCallback: stateCallback, errorCallback: errorCallback
)
}
if input.isExtraChooseCandidateKeyReverse {
if input.isCursorClockLeft {
return handleInlineCandidateRotation(
state: state, reverseModifier: true, stateCallback: stateCallback, errorCallback: errorCallback
)
}
}
return handleAbsorbedArrowKey(state: state, stateCallback: stateCallback, errorCallback: errorCallback)
return handleClockKey(state: state, stateCallback: stateCallback, errorCallback: errorCallback)
}
// MARK: Backspace
@ -424,6 +324,23 @@ extension KeyHandler {
}
}
// MARK: / (FW / HW Arabic Numbers Input)
if state is InputState.Empty {
if input.isMainAreaNumKey, input.isShiftHold, input.isOptionHold, !input.isControlHold, !input.isCommandHold {
// NOTE: macOS 10.11 El Capitan CFStringTransform StringTransform:
// https://developer.apple.com/documentation/foundation/stringtransform
guard let stringRAW = input.mapMainAreaNumKey[input.keyCode] else { return false }
let string = NSMutableString(string: stringRAW)
CFStringTransform(string, nil, kCFStringTransformFullwidthHalfwidth, true)
stateCallback(
InputState.Committing(textToCommit: mgrPrefs.halfWidthPunctuationEnabled ? stringRAW : string as String)
)
stateCallback(InputState.Empty())
return true
}
}
// MARK: Punctuation
///
@ -479,11 +396,11 @@ extension KeyHandler {
/// 使
if state is InputState.Empty {
if input.isSpace, !input.isOptionHold, !input.isFunctionKeyHold, !input.isControlHold, !input.isCommandHold {
if input.isSpace, !input.isOptionHold, !input.isControlHold, !input.isCommandHold {
stateCallback(InputState.Committing(textToCommit: input.isShiftHold ? " " : " "))
stateCallback(InputState.Empty())
return true
}
stateCallback(InputState.Empty())
return true
}
// MARK: - (Still Nothing)

View File

@ -509,7 +509,7 @@ extension KeyHandler {
/// - stateCallback:
/// - errorCallback:
/// - Returns: ctlInputMethod IMK
func handleAbsorbedArrowKey(
func handleClockKey(
state: InputStateProtocol,
stateCallback: @escaping (InputStateProtocol) -> Void,
errorCallback: @escaping () -> Void

View File

@ -120,6 +120,7 @@ extension ctlInputMethod: ctlCandidateDelegate {
keyHandler.clear()
let composingBuffer = inputting.composingBuffer
handle(state: InputState.Committing(textToCommit: composingBuffer))
// selectedValue.1
if mgrPrefs.associatedPhrasesEnabled,
let associatePhrases = keyHandler.buildAssociatePhraseState(
withPair: .init(key: selectedValue.0, value: selectedValue.1),
@ -139,16 +140,22 @@ extension ctlInputMethod: ctlCandidateDelegate {
if let state = state as? InputState.AssociatedPhrases {
let selectedValue = state.candidates[index]
handle(state: InputState.Committing(textToCommit: selectedValue.1))
// selectedValue.1
//
guard let valueKept = selectedValue.1.last else {
handle(state: InputState.Empty())
return
}
if mgrPrefs.associatedPhrasesEnabled,
let associatePhrases = keyHandler.buildAssociatePhraseState(
withPair: .init(key: selectedValue.0, value: selectedValue.1),
withPair: .init(key: selectedValue.0, value: String(valueKept)),
isTypingVertical: state.isTypingVertical
), !associatePhrases.candidates.isEmpty
{
handle(state: associatePhrases)
} else {
handle(state: InputState.Empty())
return
}
handle(state: InputState.Empty())
}
}
}

View File

@ -63,6 +63,14 @@ extension ctlInputMethod {
/// .NotEmpty()
private func setInlineDisplayWithCursor() {
if let state = state as? InputState.AssociatedPhrases {
client().setMarkedText(
state.attributedString, selectionRange: NSRange(location: 0, length: 0),
replacementRange: NSRange(location: NSNotFound, length: NSNotFound)
)
return
}
guard let state = state as? InputState.NotEmpty else {
clearInlineDisplay()
return
@ -225,7 +233,7 @@ extension ctlInputMethod {
private func handle(state: InputState.AssociatedPhrases, previous: InputStateProtocol) {
_ = previous //
ctlInputMethod.tooltipController.hide()
clearInlineDisplay()
setInlineDisplayWithCursor()
show(candidateWindowWith: state)
}
}

View File

@ -79,6 +79,13 @@ extension ctlInputMethod {
shiftJISConversionItem.state = mgrPrefs.shiftJISShinjitaiOutputEnabled.state
}
let currencyNumeralsItem = menu.addItem(
withTitle: NSLocalizedString("Currency Numeral Output", comment: ""),
action: #selector(toggleCurrencyNumerals(_:)), keyEquivalent: mgrPrefs.usingHotKeyCurrencyNumerals ? "M" : ""
)
currencyNumeralsItem.keyEquivalentModifierMask = [.command, .control]
currencyNumeralsItem.state = mgrPrefs.currencyNumeralsEnabled.state
let halfWidthPunctuationItem = menu.addItem(
withTitle: NSLocalizedString("Half-Width Punctuation Mode", comment: ""),
action: #selector(toggleHalfWidthPunctuation(_:)), keyEquivalent: mgrPrefs.usingHotKeyHalfWidthASCII ? "H" : ""
@ -245,6 +252,17 @@ extension ctlInputMethod {
))
}
@objc func toggleCurrencyNumerals(_: Any?) {
resetKeyHandler()
NotifierController.notify(
message: String(
format: "%@%@%@", NSLocalizedString("Currency Numeral Output", comment: ""), "\n",
mgrPrefs.toggleCurrencyNumeralsEnabled()
? NSLocalizedString("NotificationSwitchON", comment: "")
: NSLocalizedString("NotificationSwitchOFF", comment: "")
))
}
@objc func toggleHalfWidthPunctuation(_: Any?) {
resetKeyHandler()
NotifierController.notify(

View File

@ -450,6 +450,8 @@ extension Sequence {
}
}
// MARK: - Shell Extension
extension NSApplication {
public static func shell(_ command: String) throws -> String {
let task = Process()

View File

@ -45,6 +45,7 @@ struct UserDef {
static let kSymbolInputEnabled = "SymbolInputEnabled"
static let kChineseConversionEnabled = "ChineseConversionEnabled"
static let kShiftJISShinjitaiOutputEnabled = "ShiftJISShinjitaiOutputEnabled"
static let kCurrencyNumeralsEnabled = "CurrencyNumeralsEnabled"
static let kHalfWidthPunctuationEnabled = "HalfWidthPunctuationEnable"
static let kMoveCursorAfterSelectingCandidate = "MoveCursorAfterSelectingCandidate"
static let kEscToCleanInputBuffer = "EscToCleanInputBuffer"
@ -74,6 +75,7 @@ struct UserDef {
static let kUsingHotKeyKangXi = "UsingHotKeyKangXi"
static let kUsingHotKeyJIS = "UsingHotKeyJIS"
static let kUsingHotKeyHalfWidthASCII = "UsingHotKeyHalfWidthASCII"
static let kUsingHotKeyCurrencyNumerals = "UsingHotKeyCurrencyNumerals"
}
private let kDefaultCandidateListTextSize: CGFloat = 18
@ -286,6 +288,9 @@ public enum mgrPrefs {
UserDefaults.standard.setDefault(
mgrPrefs.alsoConfirmAssociatedCandidatesByEnter, forKey: UserDef.kAlsoConfirmAssociatedCandidatesByEnter
)
UserDefaults.standard.setDefault(
mgrPrefs.currencyNumeralsEnabled, forKey: UserDef.kCurrencyNumeralsEnabled
)
UserDefaults.standard.setDefault(mgrPrefs.usingHotKeySCPC, forKey: UserDef.kUsingHotKeySCPC)
UserDefaults.standard.setDefault(mgrPrefs.usingHotKeyAssociates, forKey: UserDef.kUsingHotKeyAssociates)
@ -293,6 +298,7 @@ public enum mgrPrefs {
UserDefaults.standard.setDefault(mgrPrefs.usingHotKeyKangXi, forKey: UserDef.kUsingHotKeyKangXi)
UserDefaults.standard.setDefault(mgrPrefs.usingHotKeyJIS, forKey: UserDef.kUsingHotKeyJIS)
UserDefaults.standard.setDefault(mgrPrefs.usingHotKeyHalfWidthASCII, forKey: UserDef.kUsingHotKeyHalfWidthASCII)
UserDefaults.standard.setDefault(mgrPrefs.usingHotKeyCurrencyNumerals, forKey: UserDef.kUsingHotKeyCurrencyNumerals)
UserDefaults.standard.synchronize()
}
@ -456,6 +462,14 @@ public enum mgrPrefs {
return shiftJISShinjitaiOutputEnabled
}
@UserDefault(key: UserDef.kCurrencyNumeralsEnabled, defaultValue: false)
static var currencyNumeralsEnabled: Bool
static func toggleCurrencyNumeralsEnabled() -> Bool {
currencyNumeralsEnabled = !currencyNumeralsEnabled
return currencyNumeralsEnabled
}
@UserDefault(key: UserDef.kHalfWidthPunctuationEnabled, defaultValue: false)
static var halfWidthPunctuationEnabled: Bool
@ -584,6 +598,9 @@ public enum mgrPrefs {
@UserDefault(key: UserDef.kUsingHotKeyHalfWidthASCII, defaultValue: true)
static var usingHotKeyHalfWidthASCII: Bool
@UserDefault(key: UserDef.kUsingHotKeyCurrencyNumerals, defaultValue: true)
static var usingHotKeyCurrencyNumerals: Bool
}
// MARK: Snapshot Extension
@ -609,6 +626,7 @@ extension mgrPrefs {
UserDef.kUsingHotKeyAssociates, UserDef.kUsingHotKeyCNS, UserDef.kUsingHotKeyKangXi, UserDef.kUsingHotKeyJIS,
UserDef.kUsingHotKeyHalfWidthASCII, UserDef.kUseFixecCandidateOrderOnSelection,
UserDef.kAutoCorrectReadingCombination, UserDef.kAlsoConfirmAssociatedCandidatesByEnter,
UserDef.kCurrencyNumeralsEnabled, UserDef.kUsingHotKeyCurrencyNumerals,
]
}

View File

@ -64,6 +64,7 @@
"Core Dict loading complete." = "Core Dict loading complete.";
"Optimize Memorized Phrases" = "Optimize Memorized Phrases";
"Clear Memorized Phrases" = "Clear Memorized Phrases";
"Currency Numeral Output" = "Currency Numeral Output";
// The followings are the category names used in the Symbol menu.
"catCommonSymbols" = "CommonSymbols";

View File

@ -64,6 +64,7 @@
"Core Dict loading complete." = "Core Dict loading complete.";
"Optimize Memorized Phrases" = "Optimize Memorized Phrases";
"Clear Memorized Phrases" = "Clear Memorized Phrases";
"Currency Numeral Output" = "Currency Numeral Output";
// The followings are the category names used in the Symbol menu.
"catCommonSymbols" = "CommonSymbols";

View File

@ -64,6 +64,7 @@
"Core Dict loading complete." = "核心辞書読込完了";
"Optimize Memorized Phrases" = "臨時記憶資料を整う";
"Clear Memorized Phrases" = "臨時記憶資料を削除";
"Currency Numeral Output" = "数字大字変換";
// The followings are the category names used in the Symbol menu.
"catCommonSymbols" = "常用";

View File

@ -64,6 +64,7 @@
"Core Dict loading complete." = "核心辞典载入完毕";
"Optimize Memorized Phrases" = "精简临时记忆语汇资料";
"Clear Memorized Phrases" = "清除临时记忆语汇资料";
"Currency Numeral Output" = "大写汉字数字输出";
// The followings are the category names used in the Symbol menu.
"catCommonSymbols" = "常用";

View File

@ -64,6 +64,7 @@
"Core Dict loading complete." = "核心辭典載入完畢";
"Optimize Memorized Phrases" = "精簡臨時記憶語彙資料";
"Clear Memorized Phrases" = "清除臨時記憶語彙資料";
"Currency Numeral Output" = "大寫漢字數字輸出";
// The followings are the category names used in the Symbol menu.
"catCommonSymbols" = "常用";

View File

@ -37,6 +37,8 @@ struct suiPrefPaneKeyboard: View {
@State private var selUsingHotKeyJIS = UserDefaults.standard.bool(forKey: UserDef.kUsingHotKeyJIS)
@State private var selUsingHotKeyHalfWidthASCII = UserDefaults.standard.bool(
forKey: UserDef.kUsingHotKeyHalfWidthASCII)
@State private var selUsingHotKeyCurrencyNumerals = UserDefaults.standard.bool(
forKey: UserDef.kUsingHotKeyCurrencyNumerals)
private let contentWidth: Double = {
switch mgrPrefs.appleLanguages[0] {
@ -174,6 +176,13 @@ struct suiPrefPaneKeyboard: View {
mgrPrefs.usingHotKeyHalfWidthASCII = value
selUsingHotKeyHalfWidthASCII = value
}
Toggle(
LocalizedStringKey("Currency Numeral Output"),
isOn: $selUsingHotKeyCurrencyNumerals
).onChange(of: selUsingHotKeyCurrencyNumerals) { value in
mgrPrefs.usingHotKeyCurrencyNumerals = value
selUsingHotKeyCurrencyNumerals = value
}
}
}
Divider()

View File

@ -184,7 +184,7 @@
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="vwf-Kq-s8M" userLabel="chkShowHanyuPinyinInCompositionBuffer">
<rect key="frame" x="19" y="122.5" width="401" height="16"/>
<rect key="frame" x="19" y="121.5" width="401" height="16"/>
<buttonCell key="cell" type="check" title="Show Hanyu-Pinyin in the inline composition buffer &amp; tooltip" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="wFR-zX-M8H">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="cellTitle"/>
@ -195,7 +195,7 @@
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="gZ0-OK-r7a" userLabel="InlineDumpPinyinInLieuOfZhuyin">
<rect key="frame" x="19" y="101.5" width="401" height="16"/>
<rect key="frame" x="19" y="100.5" width="401" height="16"/>
<buttonCell key="cell" type="check" title="Output Hanyu-Pinyin in lieu of Zhuyin when Ctrl(+Alt)+CMD+Enter" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="iWy-Nw-QKB">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="cellTitle"/>
@ -281,7 +281,7 @@
<constraint firstItem="Ldp-U1-36g" firstAttribute="leading" secondItem="5Rz-c8-hp9" secondAttribute="leading" id="AJV-6w-zzb"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="Ldp-U1-36g" secondAttribute="trailing" constant="20" symbolic="YES" id="CGs-3y-UKf"/>
<constraint firstItem="gZ0-OK-r7a" firstAttribute="leading" secondItem="E66-0o-wJZ" secondAttribute="leading" id="COA-Gy-V6W"/>
<constraint firstItem="E66-0o-wJZ" firstAttribute="top" secondItem="gZ0-OK-r7a" secondAttribute="bottom" constant="20" id="FEO-KC-ere"/>
<constraint firstItem="E66-0o-wJZ" firstAttribute="top" secondItem="gZ0-OK-r7a" secondAttribute="bottom" constant="19" id="FEO-KC-ere"/>
<constraint firstItem="da1-7e-els" firstAttribute="top" relation="lessThanOrEqual" secondItem="233" secondAttribute="bottom" constant="6" id="GPh-Pz-Koa"/>
<constraint firstItem="19" firstAttribute="top" secondItem="Yl4-Ar-L6r" secondAttribute="bottom" constant="6" id="HLS-hW-sXe"/>
<constraint firstItem="233" firstAttribute="top" secondItem="19" secondAttribute="bottom" constant="5" id="IRf-SV-AoA"/>
@ -303,7 +303,7 @@
<constraint firstItem="h4r-Sp-LBI" firstAttribute="trailing" secondItem="pYB-E5-4Nv" secondAttribute="trailing" id="eyF-ME-nzz"/>
<constraint firstItem="23" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="BUt-lg-GPp" secondAttribute="leading" constant="20" symbolic="YES" id="fVo-zM-hxe"/>
<constraint firstItem="90" firstAttribute="leading" secondItem="oS6-u5-7dP" secondAttribute="leading" id="h1Q-UC-WWd"/>
<constraint firstItem="vwf-Kq-s8M" firstAttribute="top" secondItem="pYB-E5-4Nv" secondAttribute="bottom" constant="5" id="iDF-SS-g0P"/>
<constraint firstItem="vwf-Kq-s8M" firstAttribute="top" secondItem="pYB-E5-4Nv" secondAttribute="bottom" constant="6" id="iDF-SS-g0P"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="da1-7e-els" secondAttribute="trailing" constant="20" symbolic="YES" id="iM3-gf-fp7"/>
<constraint firstItem="L5M-VG-W1X" firstAttribute="top" secondItem="5Rz-c8-hp9" secondAttribute="bottom" constant="9" id="iZF-3e-q0g"/>
<constraint firstItem="L5M-VG-W1X" firstAttribute="baseline" secondItem="oS6-u5-7dP" secondAttribute="baseline" constant="-1" id="inK-mb-fEf"/>
@ -813,11 +813,11 @@
<point key="canvasLocation" x="-896.5" y="-214"/>
</visualEffectView>
<visualEffectView blendingMode="behindWindow" material="sidebar" state="followsWindowActiveState" id="U4q-xw-mc0" userLabel="vwrKeyboard">
<rect key="frame" x="0.0" y="0.0" width="445" height="278"/>
<rect key="frame" x="0.0" y="0.0" width="445" height="289"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="onD-QP-KPf">
<rect key="frame" x="18" y="243" width="345" height="15"/>
<rect key="frame" x="18" y="254" width="345" height="15"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="242" id="7Fg-39-CRo"/>
</constraints>
@ -828,7 +828,7 @@
</textFieldCell>
</textField>
<textField wantsLayer="YES" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="hab-1o-1kS">
<rect key="frame" x="18" y="135" width="409" height="37"/>
<rect key="frame" x="18" y="146" width="409" height="37"/>
<constraints>
<constraint firstAttribute="height" constant="37" id="DuE-Bj-q43"/>
</constraints>
@ -840,7 +840,7 @@
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="249" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="11">
<rect key="frame" x="18" y="216" width="86" height="17"/>
<rect key="frame" x="18" y="227" width="86" height="17"/>
<constraints>
<constraint firstAttribute="height" constant="17" id="3Lz-Gj-jiD"/>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="82" id="Vfj-gd-B0r"/>
@ -852,7 +852,7 @@
</textFieldCell>
</textField>
<popUpButton wantsLayer="YES" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="3">
<rect key="frame" x="107" y="210" width="277" height="26"/>
<rect key="frame" x="107" y="221" width="277" height="26"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="270" id="s83-aB-x7j"/>
</constraints>
@ -883,7 +883,7 @@
</popUpButtonCell>
</popUpButton>
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="124">
<rect key="frame" x="107" y="182" width="277" height="26"/>
<rect key="frame" x="107" y="193" width="277" height="26"/>
<constraints>
<constraint firstAttribute="height" constant="21" id="MHr-9M-m65"/>
</constraints>
@ -897,7 +897,7 @@
</connections>
</popUpButton>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="125">
<rect key="frame" x="18" y="190" width="86" height="15"/>
<rect key="frame" x="18" y="201" width="86" height="15"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Basic Layout:" id="126">
<font key="font" metaFont="cellTitle"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -905,7 +905,7 @@
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Md1-t7-hU4">
<rect key="frame" x="18" y="112" width="246" height="15"/>
<rect key="frame" x="18" y="123" width="246" height="15"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="242" id="ap2-EM-Teq"/>
</constraints>
@ -915,111 +915,127 @@
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="qAe-7E-PPO" userLabel="UsingHotKeySCPC">
<rect key="frame" x="19" y="80.5" width="201" height="16"/>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="8fz-X4-HVS" userLabel="UsingHotKeySCPC">
<rect key="frame" x="19" y="92.5" width="201" height="16"/>
<buttonCell key="cell" type="check" title="Per-Char Select Mode" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="xibUsingHotKeySCPC">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="cellTitle"/>
</buttonCell>
<connections>
<binding destination="32" name="value" keyPath="values.UsingHotKeySCPC" id="Bda-2Q-cWF"/>
<binding destination="32" name="value" keyPath="values.UsingHotKeySCPC" id="fGT-OM-Lsm"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="LeH-0u-c97" userLabel="UsingHotKeyAssociates">
<rect key="frame" x="19" y="59.5" width="201" height="16"/>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ZWc-3p-TII" userLabel="UsingHotKeyAssociates">
<rect key="frame" x="19" y="71.5" width="201" height="16"/>
<buttonCell key="cell" type="check" title="Per-Char Associated Phrases" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="xibUsingHotKeyAssociates">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="cellTitle"/>
</buttonCell>
<connections>
<binding destination="32" name="value" keyPath="values.UsingHotKeyAssociates" id="knj-hU-irv"/>
<binding destination="32" name="value" keyPath="values.UsingHotKeyAssociates" id="rtd-1k-lXs"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="OwI-YY-9pZ" userLabel="UsingHotKeyCNS">
<rect key="frame" x="19" y="38.5" width="201" height="16"/>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="MVw-Gx-ueg" userLabel="UsingHotKeyCNS">
<rect key="frame" x="19" y="50.5" width="201" height="16"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="200" id="iq0-sB-5kH"/>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="200" id="gce-s6-ooU"/>
</constraints>
<buttonCell key="cell" type="check" title="CNS11643 Mode" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="xibUsingHotKeyCNS">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="cellTitle"/>
</buttonCell>
<connections>
<binding destination="32" name="value" keyPath="values.UsingHotKeyCNS" id="TDq-V9-Ojp"/>
<binding destination="32" name="value" keyPath="values.UsingHotKeyCNS" id="wR2-4R-4Fm"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="eNN-a4-bj8" userLabel="UsingHotKeyKangXi">
<rect key="frame" x="224" y="80.5" width="201" height="16"/>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ajS-Ja-Vxr" userLabel="UsingHotKeyKangXi">
<rect key="frame" x="224" y="92.5" width="201" height="16"/>
<buttonCell key="cell" type="check" title="Force KangXi Writing" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="xibUsingHotKeyKangXi">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="cellTitle"/>
</buttonCell>
<connections>
<binding destination="32" name="value" keyPath="values.UsingHotKeyKangXi" id="gy4-ge-8R1"/>
<binding destination="32" name="value" keyPath="values.UsingHotKeyKangXi" id="qXu-X7-Jbp"/>
</connections>
</button>
<button horizontalHuggingPriority="249" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="AMy-dJ-qCK" userLabel="UsingHotKeyJIS">
<rect key="frame" x="224" y="59.5" width="201" height="16"/>
<button horizontalHuggingPriority="249" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="vbm-7v-Dtb" userLabel="UsingHotKeyJIS">
<rect key="frame" x="224" y="71.5" width="201" height="16"/>
<buttonCell key="cell" type="check" title="JIS Shinjitai Output" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="xibUsingHotKeyJIS">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="cellTitle"/>
</buttonCell>
<connections>
<binding destination="32" name="value" keyPath="values.UsingHotKeyJIS" id="RBH-UU-T8y"/>
<binding destination="32" name="value" keyPath="values.UsingHotKeyJIS" id="ys3-4B-YOe"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Dsq-el-pj8" userLabel="UsingHotKeyHalfWidthASCII">
<rect key="frame" x="224" y="38.5" width="201" height="16"/>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="aBy-qb-ZL5" userLabel="UsingHotKeyHalfWidthASCII">
<rect key="frame" x="224" y="50.5" width="201" height="16"/>
<buttonCell key="cell" type="check" title="Half-Width Punctuation Mode" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="xibUsingHotKeyHalfWidthASCII">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="cellTitle"/>
</buttonCell>
<connections>
<binding destination="32" name="value" keyPath="values.UsingHotKeyHalfWidthASCII" id="Bwk-BZ-dX5"/>
<binding destination="32" name="value" keyPath="values.UsingHotKeyHalfWidthASCII" id="Sb7-46-oZ3"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="JvA-GK-VEW" userLabel="UsingHotKeyCNS">
<rect key="frame" x="19" y="29.5" width="201" height="16"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="200" id="zON-Mt-JWB"/>
</constraints>
<buttonCell key="cell" type="check" title="Currency Numeral Output" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="xibUsingCurrencyNumerals">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="cellTitle"/>
</buttonCell>
<connections>
<binding destination="32" name="value" keyPath="values.UsingHotKeyCurrencyNumerals" id="FuM-xj-9qa"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstItem="OwI-YY-9pZ" firstAttribute="trailing" secondItem="LeH-0u-c97" secondAttribute="trailing" id="4hI-Ii-l7H"/>
<constraint firstItem="aBy-qb-ZL5" firstAttribute="leading" secondItem="vbm-7v-Dtb" secondAttribute="leading" id="10e-oj-2e4"/>
<constraint firstItem="3" firstAttribute="trailing" secondItem="124" secondAttribute="trailing" id="76H-Ss-XPj"/>
<constraint firstItem="LeH-0u-c97" firstAttribute="top" secondItem="qAe-7E-PPO" secondAttribute="bottom" constant="6" symbolic="YES" id="7wy-ZX-Nzd"/>
<constraint firstItem="JvA-GK-VEW" firstAttribute="top" secondItem="MVw-Gx-ueg" secondAttribute="bottom" constant="6" symbolic="YES" id="7nv-rS-Ba0"/>
<constraint firstItem="hab-1o-1kS" firstAttribute="leading" secondItem="onD-QP-KPf" secondAttribute="leading" id="8LA-jZ-1CI"/>
<constraint firstItem="OwI-YY-9pZ" firstAttribute="top" secondItem="LeH-0u-c97" secondAttribute="bottom" constant="6" symbolic="YES" id="8hj-WH-Ii4"/>
<constraint firstItem="OwI-YY-9pZ" firstAttribute="leading" secondItem="LeH-0u-c97" secondAttribute="leading" id="Aop-aE-IvI"/>
<constraint firstItem="MVw-Gx-ueg" firstAttribute="trailing" secondItem="ZWc-3p-TII" secondAttribute="trailing" id="9Ya-y5-WoA"/>
<constraint firstItem="MVw-Gx-ueg" firstAttribute="leading" secondItem="8fz-X4-HVS" secondAttribute="leading" id="A1b-jn-JXI"/>
<constraint firstItem="MVw-Gx-ueg" firstAttribute="trailing" secondItem="8fz-X4-HVS" secondAttribute="trailing" id="Auf-V6-Qfk"/>
<constraint firstItem="aBy-qb-ZL5" firstAttribute="leading" secondItem="ajS-Ja-Vxr" secondAttribute="leading" id="BB9-6d-GXd"/>
<constraint firstItem="hab-1o-1kS" firstAttribute="top" secondItem="124" secondAttribute="bottom" constant="14" id="BLN-yz-HZ5"/>
<constraint firstItem="aBy-qb-ZL5" firstAttribute="trailing" secondItem="ajS-Ja-Vxr" secondAttribute="trailing" id="DAs-y8-Y5H"/>
<constraint firstItem="124" firstAttribute="leading" secondItem="125" secondAttribute="trailing" constant="8" symbolic="YES" id="HZF-Ed-Ic2"/>
<constraint firstItem="11" firstAttribute="leading" secondItem="125" secondAttribute="leading" id="JDY-99-OY4"/>
<constraint firstItem="OwI-YY-9pZ" firstAttribute="leading" secondItem="qAe-7E-PPO" secondAttribute="leading" id="JwA-yj-8xq"/>
<constraint firstItem="Dsq-el-pj8" firstAttribute="leading" secondItem="OwI-YY-9pZ" secondAttribute="trailing" constant="5" id="NUn-89-kRo"/>
<constraint firstItem="8fz-X4-HVS" firstAttribute="baseline" secondItem="ajS-Ja-Vxr" secondAttribute="baseline" id="M9z-zF-mvg"/>
<constraint firstItem="aBy-qb-ZL5" firstAttribute="top" secondItem="vbm-7v-Dtb" secondAttribute="bottom" constant="6" symbolic="YES" id="Mur-SU-yKs"/>
<constraint firstItem="8fz-X4-HVS" firstAttribute="leading" secondItem="hab-1o-1kS" secondAttribute="leading" id="OUA-UC-Zmg"/>
<constraint firstItem="aBy-qb-ZL5" firstAttribute="leading" secondItem="MVw-Gx-ueg" secondAttribute="trailing" constant="5" id="OVY-ez-7jX"/>
<constraint firstItem="8fz-X4-HVS" firstAttribute="top" secondItem="Md1-t7-hU4" secondAttribute="bottom" constant="15.5" id="R9J-Kf-2Tq"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="Md1-t7-hU4" secondAttribute="trailing" constant="20" symbolic="YES" id="RJh-7D-9dJ"/>
<constraint firstItem="onD-QP-KPf" firstAttribute="top" secondItem="U4q-xw-mc0" secondAttribute="top" constant="20" id="Sdp-nk-7ka"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="onD-QP-KPf" secondAttribute="trailing" constant="20" symbolic="YES" id="UY1-sM-Bqv"/>
<constraint firstItem="OwI-YY-9pZ" firstAttribute="leading" secondItem="hab-1o-1kS" secondAttribute="leading" id="Ubg-W8-aui"/>
<constraint firstItem="11" firstAttribute="leading" secondItem="U4q-xw-mc0" secondAttribute="leading" constant="20" id="VUP-BQ-kHu"/>
<constraint firstItem="qAe-7E-PPO" firstAttribute="baseline" secondItem="eNN-a4-bj8" secondAttribute="baseline" id="XUv-ud-KBW"/>
<constraint firstItem="MVw-Gx-ueg" firstAttribute="top" secondItem="ZWc-3p-TII" secondAttribute="bottom" constant="6" symbolic="YES" id="YQF-oT-uJD"/>
<constraint firstItem="124" firstAttribute="top" secondItem="3" secondAttribute="bottom" constant="7" id="dSu-bx-mNd"/>
<constraint firstItem="Dsq-el-pj8" firstAttribute="leading" secondItem="eNN-a4-bj8" secondAttribute="leading" id="ea8-gY-Vy8"/>
<constraint firstItem="OwI-YY-9pZ" firstAttribute="trailing" secondItem="qAe-7E-PPO" secondAttribute="trailing" id="ehC-vA-sYn"/>
<constraint firstItem="aBy-qb-ZL5" firstAttribute="trailing" secondItem="vbm-7v-Dtb" secondAttribute="trailing" id="dlm-mb-Hz9"/>
<constraint firstItem="onD-QP-KPf" firstAttribute="leading" secondItem="U4q-xw-mc0" secondAttribute="leading" constant="20" symbolic="YES" id="ezn-D5-52H"/>
<constraint firstAttribute="trailing" secondItem="3" secondAttribute="trailing" constant="65" id="f90-7x-Uam"/>
<constraint firstItem="Dsq-el-pj8" firstAttribute="trailing" secondItem="eNN-a4-bj8" secondAttribute="trailing" id="fQC-qn-PWP"/>
<constraint firstItem="Dsq-el-pj8" firstAttribute="trailing" secondItem="hab-1o-1kS" secondAttribute="trailing" id="gC2-eT-5wj"/>
<constraint firstItem="3" firstAttribute="leading" secondItem="11" secondAttribute="trailing" constant="8" symbolic="YES" id="gCv-rd-URb"/>
<constraint firstItem="Dsq-el-pj8" firstAttribute="leading" secondItem="AMy-dJ-qCK" secondAttribute="leading" id="gcV-P7-BB2"/>
<constraint firstAttribute="bottom" secondItem="OwI-YY-9pZ" secondAttribute="bottom" constant="38.5" id="hKf-Bf-LEv"/>
<constraint firstItem="MVw-Gx-ueg" firstAttribute="leading" secondItem="JvA-GK-VEW" secondAttribute="leading" id="h0C-T9-sc7"/>
<constraint firstItem="MVw-Gx-ueg" firstAttribute="baseline" secondItem="aBy-qb-ZL5" secondAttribute="baseline" id="iRt-Cq-jNG"/>
<constraint firstItem="ajS-Ja-Vxr" firstAttribute="trailing" secondItem="hab-1o-1kS" secondAttribute="trailing" id="jzH-4M-HMs"/>
<constraint firstAttribute="trailing" secondItem="hab-1o-1kS" secondAttribute="trailing" constant="20" id="k10-rQ-2Jc"/>
<constraint firstItem="3" firstAttribute="top" secondItem="onD-QP-KPf" secondAttribute="bottom" constant="8" id="kkD-wl-fMP"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="JvA-GK-VEW" secondAttribute="trailing" constant="20" symbolic="YES" id="mZf-K6-v3k"/>
<constraint firstItem="125" firstAttribute="baseline" secondItem="124" secondAttribute="firstBaseline" id="nTd-7q-D7u"/>
<constraint firstItem="11" firstAttribute="centerY" secondItem="3" secondAttribute="centerY" id="p8C-VN-s3f"/>
<constraint firstItem="11" firstAttribute="firstBaseline" secondItem="3" secondAttribute="firstBaseline" id="rB9-ff-s2J"/>
<constraint firstItem="OwI-YY-9pZ" firstAttribute="baseline" secondItem="Dsq-el-pj8" secondAttribute="baseline" id="rwB-0B-HbV"/>
<constraint firstItem="ZWc-3p-TII" firstAttribute="top" secondItem="8fz-X4-HVS" secondAttribute="bottom" constant="6" symbolic="YES" id="rmF-ds-Epf"/>
<constraint firstItem="8fz-X4-HVS" firstAttribute="leading" secondItem="Md1-t7-hU4" secondAttribute="leading" id="u3x-T2-w76"/>
<constraint firstItem="3" firstAttribute="leading" secondItem="124" secondAttribute="leading" id="vEJ-6b-kNs"/>
<constraint firstItem="OwI-YY-9pZ" firstAttribute="leading" secondItem="Md1-t7-hU4" secondAttribute="leading" id="xRy-Ap-bdu"/>
<constraint firstItem="Dsq-el-pj8" firstAttribute="top" secondItem="AMy-dJ-qCK" secondAttribute="bottom" constant="6" symbolic="YES" id="xo9-tg-HMe"/>
<constraint firstItem="Dsq-el-pj8" firstAttribute="trailing" secondItem="AMy-dJ-qCK" secondAttribute="trailing" id="ysU-b7-c1h"/>
<constraint firstItem="MVw-Gx-ueg" firstAttribute="leading" secondItem="ZWc-3p-TII" secondAttribute="leading" id="wWr-35-Mkg"/>
<constraint firstItem="Md1-t7-hU4" firstAttribute="top" secondItem="hab-1o-1kS" secondAttribute="bottom" constant="8" symbolic="YES" id="zZC-jv-TR3"/>
</constraints>
<point key="canvasLocation" x="-377" y="-200"/>
<point key="canvasLocation" x="-377.5" y="-194.5"/>
</visualEffectView>
</objects>
</document>

View File

@ -20,7 +20,6 @@
"29.title" = "Candidate UI font size:";
"2iG-Ic-gbl.label" = "Dictionary";
"2pS-nv-te4.title" = "Choose which keys you prefer for selecting candidates.";
"xibGeneralSettings.title" = "General Settings";
"5.title" = "OtherViews";
"6.title" = "Microsoft, Dachen, Wang, etc.";
"62u-jY-BRh.title" = "Stop farting (when typed phonetic combination is invalid, etc.)";
@ -74,15 +73,17 @@
"sZx-18-8dO.title" = "Debug Mode";
"TXr-FF-ehw.title" = "Traditional Chinese";
"ueU-Rz-a1C.title" = "Choose the behavior of (Shift+)Tab key in the candidate window.";
"xibOutputSettings.title" = "Output Settings";
"W24-T4-cg0.title" = "Enable CNS11643 Support (2022-07-20)";
"wFR-zX-M8H.title" = "Show Hanyu-Pinyin in the inline composition buffer & tooltip";
"wN3-k3-b2a.title" = "Choose your desired user data folder path. Will be omitted if invalid.";
"wQ9-px-b07.title" = "Apple Dynamic Bopomofo Basic Keyboard Layouts (Dachen & Eten Traditional) must match the Dachen parser in order to be functional.";
"Wvt-HE-LOv.title" = "Keyboard Layout";
"xC5-yV-1W1.title" = "Choose your preferred layout of the candidate window.";
"xibGeneralSettings.title" = "General Settings";
"xibKeyboardShortcuts.title" = "Keyboard Shortcuts";
"xibLabelBufferLimit.title" = "Buffer Limit:";
"xibOutputSettings.title" = "Output Settings";
"xibUsingCurrencyNumerals.title" = "Currency Numeral Output";
"xibUsingHotKeyAssociates.title" = "Per-Char Associated Phrases";
"xibUsingHotKeyCNS.title" = "CNS11643 Mode";
"xibUsingHotKeyHalfWidthASCII.title" = "Half-Width Punctuation Mode";

View File

@ -20,7 +20,6 @@
"29.title" = "候補文字の字号:";
"2iG-Ic-gbl.label" = "辞書";
"2pS-nv-te4.title" = "お好きなる言選り用キー陣列をお選びください。";
"xibGeneralSettings.title" = "全般設定";
"5.title" = "OtherViews";
"6.title" = "大千配列Microsoft 標準・王安など)";
"62u-jY-BRh.title" = "マナーモード // 外すと入力間違の時に変な音が出る";
@ -74,15 +73,17 @@
"sZx-18-8dO.title" = "欠陥辿着モード";
"TXr-FF-ehw.title" = "繁体中国語";
"ueU-Rz-a1C.title" = "入力候補陳列での (Shift+)Tab キーの輪番切替対象をご指定ください。";
"xibOutputSettings.title" = "出力設定";
"W24-T4-cg0.title" = "全字庫モード // 入力可能の漢字数倍増 (2022-07-20)";
"wFR-zX-M8H.title" = "弁音合併入力(入力緩衝列とヒントで音読みを漢語弁音に)";
"wN3-k3-b2a.title" = "欲しがるユーザー辞書保存先をご指定ください。無効の保存先設定は効かぬ。";
"wQ9-px-b07.title" = "Apple 動態注音キーボード (大千と倚天伝統) を使うには、共通語分析器の注音配列を大千と設定すべきである。";
"Wvt-HE-LOv.title" = "キーボード";
"xC5-yV-1W1.title" = "入力候補陳列の仕様をご指定ください。";
"xibGeneralSettings.title" = "全般設定";
"xibKeyboardShortcuts.title" = "ショートカット";
"xibLabelBufferLimit.title" = "緩衝列の容量:";
"xibOutputSettings.title" = "出力設定";
"xibUsingCurrencyNumerals.title" = "数字大字変換";
"xibUsingHotKeyAssociates.title" = "全候補入力で連想語彙";
"xibUsingHotKeyCNS.title" = "全字庫モード";
"xibUsingHotKeyHalfWidthASCII.title" = "半角句読モード";

View File

@ -20,7 +20,6 @@
"29.title" = "字型大小设定:";
"2iG-Ic-gbl.label" = "辞典";
"2pS-nv-te4.title" = "选择您所偏好的用来选字的按键组合。";
"xibGeneralSettings.title" = "一般设定";
"5.title" = "OtherViews";
"6.title" = "微软/大千/王安/国乔/零壹/仲鼎";
"62u-jY-BRh.title" = "廉耻模式 // 取消勾选的话,敲错字时会有异音";
@ -74,15 +73,17 @@
"sZx-18-8dO.title" = "侦错模式";
"TXr-FF-ehw.title" = "繁体中文";
"ueU-Rz-a1C.title" = "指定 (Shift+)Tab 热键在选字窗内的轮替操作对象。";
"xibOutputSettings.title" = "输出设定";
"W24-T4-cg0.title" = "启用 CNS11643 全字库支援 (2022-07-20)";
"wFR-zX-M8H.title" = "拼音并击(组字区与工具提示内显示汉语拼音)";
"wN3-k3-b2a.title" = "请在此指定您想指定的使用者语汇档案目录。无效值会被忽略。";
"wQ9-px-b07.title" = "Apple 动态注音键盘布局(大千与倚天)要求普通话/国音分析器的注音排列得配置为大千排列。";
"Wvt-HE-LOv.title" = "键盘布局";
"xC5-yV-1W1.title" = "选择您所偏好的候选字窗布局。";
"xibGeneralSettings.title" = "一般设定";
"xibKeyboardShortcuts.title" = "键盘快捷键";
"xibLabelBufferLimit.title" = "组字区容量:";
"xibOutputSettings.title" = "输出设定";
"xibUsingCurrencyNumerals.title" = "大写汉字数字输出";
"xibUsingHotKeyAssociates.title" = "逐字选字联想模式";
"xibUsingHotKeyCNS.title" = "全字库模式";
"xibUsingHotKeyHalfWidthASCII.title" = "半形标点模式";

View File

@ -20,7 +20,6 @@
"29.title" = "字型大小設定:";
"2iG-Ic-gbl.label" = "辭典";
"2pS-nv-te4.title" = "選擇您所偏好的用來選字的按鍵組合。";
"xibGeneralSettings.title" = "一般設定";
"5.title" = "OtherViews";
"6.title" = "微軟/大千/王安/國喬/零壹/仲鼎";
"62u-jY-BRh.title" = "廉恥模式 // 取消勾選的話,敲錯字時會有異音";
@ -74,15 +73,17 @@
"sZx-18-8dO.title" = "偵錯模式";
"TXr-FF-ehw.title" = "繁體中文";
"ueU-Rz-a1C.title" = "指定 (Shift+)Tab 熱鍵在選字窗內的輪替操作對象。";
"xibOutputSettings.title" = "輸出設定";
"W24-T4-cg0.title" = "啟用 CNS11643 全字庫支援 (2022-07-20)";
"wFR-zX-M8H.title" = "拼音並擊(組字區與工具提示內顯示漢語拼音)";
"wN3-k3-b2a.title" = "請在此指定您想指定的使用者語彙檔案目錄。無效值會被忽略。";
"wQ9-px-b07.title" = "Apple 動態注音鍵盤佈局(大千與倚天)要求普通話/國音分析器的注音排列得配置為大千排列。";
"Wvt-HE-LOv.title" = "鍵盤佈局";
"xC5-yV-1W1.title" = "選擇您所偏好的候選字窗佈局。";
"xibGeneralSettings.title" = "一般設定";
"xibKeyboardShortcuts.title" = "鍵盤快速鍵";
"xibLabelBufferLimit.title" = "組字區容量:";
"xibOutputSettings.title" = "輸出設定";
"xibUsingCurrencyNumerals.title" = "大寫漢字數字輸出";
"xibUsingHotKeyAssociates.title" = "逐字選字聯想模式";
"xibUsingHotKeyCNS.title" = "全字庫模式";
"xibUsingHotKeyHalfWidthASCII.title" = "半形標點模式";

View File

@ -3,9 +3,9 @@
<plist version="1.0">
<dict>
<key>CFBundleShortVersionString</key>
<string>1.8.4</string>
<string>1.8.5</string>
<key>CFBundleVersion</key>
<string>1984</string>
<string>1985</string>
<key>UpdateInfoEndpoint</key>
<string>https://gitee.com/vchewing/vChewing-macOS/raw/main/Update-Info.plist</string>
<key>UpdateInfoSite</key>

View File

@ -726,7 +726,7 @@
<key>USE_HFS+_COMPRESSION</key>
<false/>
<key>VERSION</key>
<string>1.8.4</string>
<string>1.8.5</string>
</dict>
<key>TYPE</key>
<integer>0</integer>

View File

@ -102,6 +102,7 @@
5BD05C6A27B2BBEF004C4F1D /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD05C6527B2BBEF004C4F1D /* ViewController.swift */; };
5BDC1CFA27FDF1310052C2B9 /* apiUpdate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BDC1CF927FDF1310052C2B9 /* apiUpdate.swift */; };
5BDCBB2E27B4E67A00D0CC59 /* vChewingPhraseEditor.app in Resources */ = {isa = PBXBuildFile; fileRef = 5BD05BB827B2A429004C4F1D /* vChewingPhraseEditor.app */; };
5BE377A0288FED8D0037365B /* KeyHandler_HandleComposition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BE3779F288FED8D0037365B /* KeyHandler_HandleComposition.swift */; };
5BE78BD927B3775B005EA1BE /* ctlAboutWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BE78BD827B37750005EA1BE /* ctlAboutWindow.swift */; };
5BE78BDD27B3776D005EA1BE /* frmAboutWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5BE78BDA27B37764005EA1BE /* frmAboutWindow.xib */; };
5BEDB721283B4C250078EB25 /* data-cns.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5BEDB71D283B4AEA0078EB25 /* data-cns.plist */; };
@ -303,6 +304,7 @@
5BDCBB4A27B4F6C700D0CC59 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/Localizable.strings"; sourceTree = "<group>"; };
5BDCBB4B27B4F6C700D0CC59 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/frmAboutWindow.strings"; sourceTree = "<group>"; };
5BDCBB4D27B4F6C700D0CC59 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
5BE3779F288FED8D0037365B /* KeyHandler_HandleComposition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyHandler_HandleComposition.swift; sourceTree = "<group>"; };
5BE78BD827B37750005EA1BE /* ctlAboutWindow.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = ctlAboutWindow.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
5BE78BDB27B37764005EA1BE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/frmAboutWindow.xib; sourceTree = "<group>"; };
5BE78BDF27B37968005EA1BE /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/frmAboutWindow.strings; sourceTree = "<group>"; };
@ -465,6 +467,7 @@
5BD0113C2818543900609769 /* KeyHandler_Core.swift */,
5B782EC3280C243C007276DE /* KeyHandler_HandleCandidate.swift */,
5B7F225C2808501000DDD3CB /* KeyHandler_HandleInput.swift */,
5BE3779F288FED8D0037365B /* KeyHandler_HandleComposition.swift */,
5B3133BE280B229700A4A505 /* KeyHandler_States.swift */,
5B62A33727AE79CD00A19448 /* StringUtils.swift */,
5BAA8FBD282CAF380066C406 /* SyllableComposer.swift */,
@ -1204,6 +1207,7 @@
5BA9FD3F27FEF3C8002DE248 /* Pane.swift in Sources */,
5BB802DA27FABA8300CF1C19 /* ctlInputMethod_Menu.swift in Sources */,
5B38F5A1281E2E49007D5F5D /* 1_Compositor.swift in Sources */,
5BE377A0288FED8D0037365B /* KeyHandler_HandleComposition.swift in Sources */,
5BDC1CFA27FDF1310052C2B9 /* apiUpdate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -1389,7 +1393,7 @@
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1984;
CURRENT_PROJECT_VERSION = 1985;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_PREPROCESSOR_DEFINITIONS = (
@ -1399,7 +1403,7 @@
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.8.4;
MARKETING_VERSION = 1.8.5;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewingTests;
@ -1428,13 +1432,13 @@
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1984;
CURRENT_PROJECT_VERSION = 1985;
ENABLE_NS_ASSERTIONS = NO;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.8.4;
MARKETING_VERSION = 1.8.5;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewingTests;
@ -1465,7 +1469,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1984;
CURRENT_PROJECT_VERSION = 1985;
DEAD_CODE_STRIPPING = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
@ -1486,7 +1490,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 1.8.4;
MARKETING_VERSION = 1.8.5;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewing.vChewingPhraseEditor;
@ -1515,7 +1519,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1984;
CURRENT_PROJECT_VERSION = 1985;
DEAD_CODE_STRIPPING = YES;
ENABLE_NS_ASSERTIONS = NO;
GCC_C_LANGUAGE_STANDARD = gnu11;
@ -1532,7 +1536,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 1.8.4;
MARKETING_VERSION = 1.8.5;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewing.vChewingPhraseEditor;
@ -1646,7 +1650,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1984;
CURRENT_PROJECT_VERSION = 1985;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = "";
@ -1674,7 +1678,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 1.8.4;
MARKETING_VERSION = 1.8.5;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.inputmethod.vChewing;
PRODUCT_NAME = "$(TARGET_NAME)";
@ -1701,7 +1705,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1984;
CURRENT_PROJECT_VERSION = 1985;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = "";
@ -1723,7 +1727,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 1.8.4;
MARKETING_VERSION = 1.8.5;
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.inputmethod.vChewing;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -1745,7 +1749,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1984;
CURRENT_PROJECT_VERSION = 1985;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = "";
GCC_C_LANGUAGE_STANDARD = gnu99;
@ -1765,7 +1769,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 1.8.4;
MARKETING_VERSION = 1.8.5;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "org.atelierInmu.vChewing.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
@ -1787,7 +1791,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1984;
CURRENT_PROJECT_VERSION = 1985;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = "";
GCC_C_LANGUAGE_STANDARD = gnu99;
@ -1801,7 +1805,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 1.8.4;
MARKETING_VERSION = 1.8.5;
PRODUCT_BUNDLE_IDENTIFIER = "org.atelierInmu.vChewing.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";

View File

@ -296,7 +296,7 @@ class KeyHandlerTestsNormalCHS: XCTestCase {
XCTAssertTrue(state is InputState.Empty, "\(state)")
}
func testisNumericPad() {
func testisNumericPadKey() {
var input = InputSignal(inputText: "b", keyCode: 0, charCode: charCode("b"), flags: [], isVerticalTyping: false)
var state: InputStateProtocol = InputState.Empty()
_ = handler.handle(input: input, state: state) { newState in
@ -304,7 +304,7 @@ class KeyHandlerTestsNormalCHS: XCTestCase {
} errorCallback: {
}
input = InputSignal(
inputText: "1", keyCode: 0, charCode: charCode("1"), flags: .numericPad, isVerticalTyping: false
inputText: "1", keyCode: 83, charCode: charCode("1"), flags: [], isVerticalTyping: false
)
var count = 0
var empty: InputStateProtocol = InputState.Empty()