KeyHandler // Use PrefMgrProtocol delegate to handle UserDefaults.
This commit is contained in:
parent
9d077a9d49
commit
03d4099894
|
@ -55,7 +55,7 @@ class ctlInputMethod: IMKInputController {
|
|||
// MARK: - Extracted methods and functions (Tekkon).
|
||||
|
||||
func ensureParser() {
|
||||
switch mgrPrefs.mandarinParser {
|
||||
switch PrefMgr.shared.mandarinParser {
|
||||
case MandarinParser.ofStandard.rawValue:
|
||||
_composer.ensureParser(arrange: .ofDachen) // 大千
|
||||
case MandarinParser.ofETen.rawValue:
|
||||
|
@ -82,7 +82,7 @@ class ctlInputMethod: IMKInputController {
|
|||
_composer.ensureParser(arrange: .ofUniversalPinyin) // 通用拼音
|
||||
default:
|
||||
_composer.ensureParser(arrange: .ofDachen) // 預設情況下按照 PrefMgr 內定義預設值來處理
|
||||
mgrPrefs.mandarinParser = MandarinParser.ofStandard.rawValue
|
||||
PrefMgr.shared.mandarinParser = MandarinParser.ofStandard.rawValue
|
||||
}
|
||||
_composer.clear()
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
|
|||
private func reloadOnFolderChangeHappens() {
|
||||
// 拖 100ms 再重載,畢竟有些有特殊需求的使用者可能會想使用巨型自訂語彙檔案。
|
||||
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1) {
|
||||
if mgrPrefs.shouldAutoReloadUserDataFiles {
|
||||
if PrefMgr.shared.shouldAutoReloadUserDataFiles {
|
||||
LMMgr.initUserLangModels()
|
||||
}
|
||||
}
|
||||
|
@ -39,10 +39,10 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
|
|||
func applicationDidFinishLaunching(_: Notification) {
|
||||
NSUserNotificationCenter.default.delegate = self
|
||||
// 一旦發現與使用者半衰模組的觀察行為有關的崩潰標記被開啟,就清空既有的半衰記憶資料檔案。
|
||||
if mgrPrefs.failureFlagForUOMObservation {
|
||||
if PrefMgr.shared.failureFlagForUOMObservation {
|
||||
LMMgr.clearUserOverrideModelData(.imeModeCHS)
|
||||
LMMgr.clearUserOverrideModelData(.imeModeCHT)
|
||||
mgrPrefs.failureFlagForUOMObservation = false
|
||||
PrefMgr.shared.failureFlagForUOMObservation = false
|
||||
let userNotification = NSUserNotification()
|
||||
userNotification.title = NSLocalizedString("vChewing", comment: "")
|
||||
userNotification.informativeText =
|
||||
|
@ -61,7 +61,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
|
|||
}
|
||||
}
|
||||
|
||||
mgrPrefs.fixOddPreferences()
|
||||
PrefMgr.shared.fixOddPreferences()
|
||||
|
||||
// 配置更新小助手
|
||||
updateSputnik.varkUpdateInfoPageURLKey = "UpdateInfoSite"
|
||||
|
@ -71,7 +71,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
|
|||
updateSputnik.varCheckUpdateAutomatically = "ChecvarkUpdateAutomatically"
|
||||
|
||||
// 只要使用者沒有勾選檢查更新、沒有主動做出要檢查更新的操作,就不要檢查更新。
|
||||
if mgrPrefs.checkUpdateAutomatically {
|
||||
if PrefMgr.shared.checkUpdateAutomatically {
|
||||
updateSputnik.checkForUpdate(forced: false, url: kUpdateInfoSourceURL)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,14 +54,14 @@ public enum ChineseConverter {
|
|||
/// 將指定字串內的小寫漢字數字轉換為大寫,會對轉換對象進行直接修改操作。
|
||||
/// - Parameter target: 轉換對象。
|
||||
public static func ensureCurrencyNumerals(target: inout String) {
|
||||
if !mgrPrefs.currencyNumeralsEnabled { return }
|
||||
if !PrefMgr.shared.currencyNumeralsEnabled { return }
|
||||
for key in currencyNumeralDictTable.keys {
|
||||
guard let result = currencyNumeralDictTable[key] else { continue }
|
||||
if IMEApp.currentInputMode == InputMode.imeModeCHS {
|
||||
target = target.replacingOccurrences(of: key, with: result.3) // Simplified Chinese
|
||||
continue
|
||||
}
|
||||
switch (mgrPrefs.chineseConversionEnabled, mgrPrefs.shiftJISShinjitaiOutputEnabled) {
|
||||
switch (PrefMgr.shared.chineseConversionEnabled, PrefMgr.shared.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
|
||||
|
@ -98,7 +98,7 @@ public enum ChineseConverter {
|
|||
|
||||
static func kanjiConversionIfRequired(_ text: String) -> String {
|
||||
guard IMEApp.currentInputMode == InputMode.imeModeCHT else { return text }
|
||||
switch (mgrPrefs.chineseConversionEnabled, mgrPrefs.shiftJISShinjitaiOutputEnabled) {
|
||||
switch (PrefMgr.shared.chineseConversionEnabled, PrefMgr.shared.shiftJISShinjitaiOutputEnabled) {
|
||||
case (false, true): return ChineseConverter.cnvTradToJIS(text)
|
||||
case (true, false): return ChineseConverter.cnvTradToKangXi(text)
|
||||
// 本來這兩個開關不該同時開啟的,但萬一被同時開啟了的話就這樣處理:
|
||||
|
|
|
@ -121,7 +121,7 @@ extension IMEState {
|
|||
// 注意資料的設定順序,一定得先設定 displayTextSegments。
|
||||
result.data.displayTextSegments = displayTextSegments.map {
|
||||
if !ctlInputMethod.isVerticalTyping { return $0 }
|
||||
guard mgrPrefs.hardenVerticalPunctuations else { return $0 }
|
||||
guard PrefMgr.shared.hardenVerticalPunctuations else { return $0 }
|
||||
var neta = $0
|
||||
ChineseConverter.hardenVerticalPunctuations(target: &neta, convert: ctlInputMethod.isVerticalTyping)
|
||||
return neta
|
||||
|
|
|
@ -10,11 +10,11 @@ import Tekkon
|
|||
|
||||
public struct StateData {
|
||||
private static var minCandidateLength: Int {
|
||||
mgrPrefs.allowBoostingSingleKanjiAsUserPhrase ? 1 : 2
|
||||
PrefMgr.shared.allowBoostingSingleKanjiAsUserPhrase ? 1 : 2
|
||||
}
|
||||
|
||||
static var allowedMarkLengthRange: ClosedRange<Int> {
|
||||
Self.minCandidateLength...mgrPrefs.maxCandidateLength
|
||||
Self.minCandidateLength...PrefMgr.shared.maxCandidateLength
|
||||
}
|
||||
|
||||
var displayedText: String = ""
|
||||
|
@ -177,8 +177,8 @@ extension StateData {
|
|||
arrOutput.append("??")
|
||||
continue
|
||||
}
|
||||
if mgrPrefs.showHanyuPinyinInCompositionBuffer,
|
||||
mgrPrefs.alwaysShowTooltipTextsHorizontally || !isVerticalTyping
|
||||
if PrefMgr.shared.showHanyuPinyinInCompositionBuffer,
|
||||
PrefMgr.shared.alwaysShowTooltipTextsHorizontally || !isVerticalTyping
|
||||
{
|
||||
// 恢復陰平標記->注音轉拼音->轉教科書式標調
|
||||
neta = Tekkon.restoreToneOneInZhuyinKey(target: neta)
|
||||
|
@ -215,7 +215,7 @@ extension StateData {
|
|||
mutating func updateTooltipForMarking() {
|
||||
var tooltipForMarking: String {
|
||||
let pair = userPhraseKVPair
|
||||
if mgrPrefs.phraseReplacementEnabled {
|
||||
if PrefMgr.shared.phraseReplacementEnabled {
|
||||
tooltipColorState = .warning
|
||||
return NSLocalizedString(
|
||||
"⚠︎ Phrase replacement mode enabled, interfering user phrase entry.", comment: ""
|
||||
|
|
|
@ -32,6 +32,7 @@ public protocol KeyHandlerDelegate {
|
|||
public class KeyHandler {
|
||||
/// 委任物件 (ctlInputMethod),以便呼叫其中的函式。
|
||||
public var delegate: KeyHandlerDelegate?
|
||||
public var prefs: PrefMgrProtocol
|
||||
|
||||
/// 半衰模組的衰減指數
|
||||
let kEpsilon: Double = 0.000_001
|
||||
|
@ -47,11 +48,12 @@ public class KeyHandler {
|
|||
}
|
||||
|
||||
/// 初期化。
|
||||
public init(lm: vChewingLM.LMInstantiator, uom: vChewingLM.LMUserOverride) {
|
||||
public init(lm: vChewingLM.LMInstantiator, uom: vChewingLM.LMUserOverride, pref: PrefMgrProtocol) {
|
||||
prefs = pref
|
||||
currentLM = lm
|
||||
currentUOM = uom
|
||||
/// 同步組字器單個詞的幅位長度上限。
|
||||
Megrez.Compositor.maxSpanLength = mgrPrefs.maxCandidateLength
|
||||
Megrez.Compositor.maxSpanLength = prefs.maxCandidateLength
|
||||
/// 組字器初期化。因為是首次初期化變數,所以這裡不能用 ensureCompositor() 代勞。
|
||||
compositor = Megrez.Compositor(with: currentLM, separator: "-")
|
||||
/// 注拼槽初期化。
|
||||
|
@ -85,7 +87,7 @@ public class KeyHandler {
|
|||
/// 威注音對游標前置與游標後置模式採取的候選字節點陣列抓取方法是分離的,且不使用 Node Crossing。
|
||||
var actualCandidateCursor: Int {
|
||||
compositor.cursor
|
||||
- ((compositor.cursor == compositor.width || !mgrPrefs.useRearCursorMode) && compositor.cursor > 0 ? 1 : 0)
|
||||
- ((compositor.cursor == compositor.width || !prefs.useRearCursorMode) && compositor.cursor > 0 ? 1 : 0)
|
||||
}
|
||||
|
||||
/// 利用給定的讀音鏈來試圖爬取最接近的組字結果(最大相似度估算)。
|
||||
|
@ -97,7 +99,7 @@ public class KeyHandler {
|
|||
compositor.walk()
|
||||
|
||||
// 在偵錯模式開啟時,將 GraphViz 資料寫入至指定位置。
|
||||
if mgrPrefs.isDebugModeEnabled {
|
||||
if prefs.isDebugModeEnabled {
|
||||
let result = compositor.dumpDOT
|
||||
let thePath = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)[0].path.appending(
|
||||
"/vChewing-visualization.dot")
|
||||
|
@ -222,12 +224,12 @@ public class KeyHandler {
|
|||
let currentNode = currentWalk.findNode(at: actualCandidateCursor, target: &accumulatedCursor)
|
||||
guard let currentNode = currentNode else { return }
|
||||
|
||||
if currentNode.currentUnigram.score > -12, mgrPrefs.fetchSuggestionsFromUserOverrideModel {
|
||||
if currentNode.currentUnigram.score > -12, prefs.fetchSuggestionsFromUserOverrideModel {
|
||||
vCLog("UOM: Start Observation.")
|
||||
// 這個過程可能會因為使用者半衰記憶模組內部資料錯亂、而導致輸入法在選字時崩潰。
|
||||
// 於是在這裡引入災後狀況察覺專用變數,且先開啟該開關。順利執行完觀察後會關閉。
|
||||
// 一旦輸入法崩潰,會在重啟時發現這個開關是開著的,屆時 AppDelegate 會做出應對。
|
||||
mgrPrefs.failureFlagForUOMObservation = true
|
||||
prefs.failureFlagForUOMObservation = true
|
||||
// 令半衰記憶模組觀測給定的三元圖。
|
||||
// 這個過程會讓半衰引擎根據當前上下文生成三元圖索引鍵。
|
||||
currentUOM.performObservation(
|
||||
|
@ -235,11 +237,11 @@ public class KeyHandler {
|
|||
timestamp: Date().timeIntervalSince1970, saveCallback: { self.currentUOM.saveData() }
|
||||
)
|
||||
// 如果沒有出現崩框的話,那就將這個開關復位。
|
||||
mgrPrefs.failureFlagForUOMObservation = false
|
||||
prefs.failureFlagForUOMObservation = false
|
||||
}
|
||||
|
||||
/// 若偏好設定內啟用了相關選項,則會在選字之後始終將游標推送至選字後的節錨的前方。
|
||||
if mgrPrefs.moveCursorAfterSelectingCandidate, respectCursorPushing {
|
||||
if prefs.moveCursorAfterSelectingCandidate, respectCursorPushing {
|
||||
// compositor.cursor = accumulatedCursor
|
||||
compositor.jumpCursorBySpan(to: .front)
|
||||
}
|
||||
|
@ -250,7 +252,7 @@ public class KeyHandler {
|
|||
/// 警告:不要對游標前置風格使用 nodesCrossing,否則會導致游標行為與 macOS 內建注音輸入法不一致。
|
||||
/// 微軟新注音輸入法的游標後置風格也是不允許 nodeCrossing 的。
|
||||
var arrCandidates: [Megrez.Compositor.KeyValuePaired] = {
|
||||
switch mgrPrefs.useRearCursorMode {
|
||||
switch prefs.useRearCursorMode {
|
||||
case false:
|
||||
return compositor.fetchCandidates(at: actualCandidateCursor, filter: .endAt)
|
||||
case true:
|
||||
|
@ -264,7 +266,7 @@ public class KeyHandler {
|
|||
if arrCandidates.isEmpty { return .init() }
|
||||
|
||||
// 決定是否根據半衰記憶模組的建議來調整候選字詞的順序。
|
||||
if !mgrPrefs.fetchSuggestionsFromUserOverrideModel || mgrPrefs.useSCPCTypingMode || fixOrder {
|
||||
if !prefs.fetchSuggestionsFromUserOverrideModel || prefs.useSCPCTypingMode || fixOrder {
|
||||
return arrCandidates.map { ($0.key, $0.value) }
|
||||
}
|
||||
|
||||
|
@ -282,9 +284,9 @@ public class KeyHandler {
|
|||
@discardableResult func fetchSuggestionsFromUOM(apply: Bool) -> [(String, Megrez.Unigram)] {
|
||||
var arrResult = [(String, Megrez.Unigram)]()
|
||||
/// 如果逐字選字模式有啟用的話,直接放棄執行這個函式。
|
||||
if mgrPrefs.useSCPCTypingMode { return arrResult }
|
||||
if prefs.useSCPCTypingMode { return arrResult }
|
||||
/// 如果這個開關沒打開的話,直接放棄執行這個函式。
|
||||
if !mgrPrefs.fetchSuggestionsFromUserOverrideModel { return arrResult }
|
||||
if !prefs.fetchSuggestionsFromUserOverrideModel { return arrResult }
|
||||
/// 獲取來自半衰記憶模組的建議結果
|
||||
let suggestion = currentUOM.fetchSuggestion(
|
||||
currentWalk: compositor.walkedNodes, cursor: actualCandidateCursor, timestamp: Date().timeIntervalSince1970
|
||||
|
@ -320,7 +322,7 @@ public class KeyHandler {
|
|||
}
|
||||
|
||||
var currentKeyboardParserType: KeyboardParser {
|
||||
.init(rawValue: mgrPrefs.keyboardParser) ?? .ofStandard
|
||||
.init(rawValue: prefs.keyboardParser) ?? .ofStandard
|
||||
}
|
||||
|
||||
/// 給注拼槽指定注音排列或拼音輸入種類之後,將注拼槽內容清空。
|
||||
|
@ -358,7 +360,7 @@ public class KeyHandler {
|
|||
composer.ensureParser(arrange: .ofUniversalPinyin)
|
||||
}
|
||||
composer.clear()
|
||||
composer.phonabetCombinationCorrectionEnabled = mgrPrefs.autoCorrectReadingCombination
|
||||
composer.phonabetCombinationCorrectionEnabled = prefs.autoCorrectReadingCombination
|
||||
}
|
||||
|
||||
/// 返回前一個游標位置的可解析的漢字讀音。
|
||||
|
@ -394,7 +396,7 @@ public class KeyHandler {
|
|||
/// - Parameter input: 輸入的按鍵訊號。
|
||||
/// - Returns: 生成的標點符號索引鍵。
|
||||
func generatePunctuationNamePrefix(withKeyCondition input: InputSignalProtocol) -> String {
|
||||
if mgrPrefs.halfWidthPunctuationEnabled {
|
||||
if prefs.halfWidthPunctuationEnabled {
|
||||
return "_half_punctuation_"
|
||||
}
|
||||
switch (input.isControlHold, input.isOptionHold) {
|
||||
|
@ -423,7 +425,7 @@ extension KeyHandler {
|
|||
guard !compositor.walkedNodes.isEmpty,
|
||||
compositor.width > compositorWidthLimit,
|
||||
let identifier = delegate?.clientBundleIdentifier,
|
||||
mgrPrefs.clientsIMKTextInputIncapable.contains(identifier)
|
||||
prefs.clientsIMKTextInputIncapable.contains(identifier)
|
||||
else {
|
||||
return ""
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ extension KeyHandler {
|
|||
|
||||
if cancelCandidateKey {
|
||||
if state.type == .ofAssociates
|
||||
|| mgrPrefs.useSCPCTypingMode
|
||||
|| prefs.useSCPCTypingMode
|
||||
|| compositor.isEmpty
|
||||
{
|
||||
// 如果此時發現當前組字緩衝區為真空的情況的話,
|
||||
|
@ -59,7 +59,7 @@ extension KeyHandler {
|
|||
// MARK: Enter
|
||||
|
||||
if input.isEnter {
|
||||
if state.type == .ofAssociates, !mgrPrefs.alsoConfirmAssociatedCandidatesByEnter {
|
||||
if state.type == .ofAssociates, !prefs.alsoConfirmAssociatedCandidatesByEnter {
|
||||
stateCallback(IMEState.ofAbortion())
|
||||
return true
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ extension KeyHandler {
|
|||
|
||||
if input.isTab {
|
||||
let updated: Bool =
|
||||
mgrPrefs.specifyShiftTabKeyBehavior
|
||||
prefs.specifyShiftTabKeyBehavior
|
||||
? (input.isShiftHold
|
||||
? ctlCandidate.showPreviousPage()
|
||||
: ctlCandidate.showNextPage())
|
||||
|
@ -88,7 +88,7 @@ extension KeyHandler {
|
|||
|
||||
if input.isSpace {
|
||||
let updated: Bool =
|
||||
mgrPrefs.specifyShiftSpaceKeyBehavior
|
||||
prefs.specifyShiftSpaceKeyBehavior
|
||||
? (input.isShiftHold
|
||||
? ctlCandidate.highlightNextCandidate()
|
||||
: ctlCandidate.showNextPage())
|
||||
|
@ -242,7 +242,7 @@ extension KeyHandler {
|
|||
|
||||
// MARK: 逐字選字模式的處理 (SCPC Mode Processing)
|
||||
|
||||
if mgrPrefs.useSCPCTypingMode {
|
||||
if prefs.useSCPCTypingMode {
|
||||
/// 檢查:
|
||||
/// - 是否是針對當前注音排列/拼音輸入種類專門提供的標點符號。
|
||||
/// - 是否是需要摁修飾鍵才可以輸入的那種標點符號。
|
||||
|
|
|
@ -36,7 +36,7 @@ extension KeyHandler {
|
|||
if !skipPhoneticHandling && composer.inputValidityCheck(key: input.charCode) {
|
||||
// 引入 macOS 內建注音輸入法的行為,允許用除了陰平以外的聲調鍵覆寫前一個漢字的讀音。
|
||||
// 但如果要覆寫的內容會導致游標身後的字音沒有對應的辭典記錄的話,那就只蜂鳴警告一下。
|
||||
proc: if [0, 1].contains(mgrPrefs.specifyIntonationKeyBehavior), composer.isEmpty, !input.isSpace {
|
||||
proc: if [0, 1].contains(prefs.specifyIntonationKeyBehavior), composer.isEmpty, !input.isSpace {
|
||||
// prevReading 的內容分別是:「完整讀音」「去掉聲調的讀音」「是否有聲調」。
|
||||
guard let prevReading = previousParsableReading, isIntonationKey(input) else { break proc }
|
||||
var theComposer = composer
|
||||
|
@ -44,7 +44,7 @@ extension KeyHandler {
|
|||
// 發現要覆寫的聲調與覆寫對象的聲調雷同的情況的話,直接跳過處理。
|
||||
let oldIntonation: Tekkon.Phonabet = theComposer.intonation
|
||||
theComposer.receiveKey(fromString: input.text)
|
||||
if theComposer.intonation == oldIntonation, mgrPrefs.specifyIntonationKeyBehavior == 1 { break proc }
|
||||
if theComposer.intonation == oldIntonation, prefs.specifyIntonationKeyBehavior == 1 { break proc }
|
||||
theComposer.intonation.clear()
|
||||
// 檢查新的漢字字音是否在庫。
|
||||
let temporaryReadingKey = theComposer.getComposition()
|
||||
|
@ -88,7 +88,7 @@ extension KeyHandler {
|
|||
if !currentLM.hasUnigramsFor(key: readingKey) {
|
||||
errorCallback("B49C0979:語彙庫內無「\(readingKey)」的匹配記錄。")
|
||||
|
||||
if mgrPrefs.keepReadingUponCompositionError {
|
||||
if prefs.keepReadingUponCompositionError {
|
||||
composer.intonation.clear() // 砍掉聲調。
|
||||
stateCallback(buildInputtingState)
|
||||
return true
|
||||
|
@ -125,14 +125,14 @@ extension KeyHandler {
|
|||
stateCallback(inputting)
|
||||
|
||||
/// 逐字選字模式的處理。
|
||||
if mgrPrefs.useSCPCTypingMode {
|
||||
if prefs.useSCPCTypingMode {
|
||||
let candidateState: IMEState = buildCandidate(state: inputting)
|
||||
if candidateState.candidates.count == 1, let firstCandidate = candidateState.candidates.first {
|
||||
let reading: String = firstCandidate.0
|
||||
let text: String = firstCandidate.1
|
||||
stateCallback(IMEState.ofCommitting(textToCommit: text))
|
||||
|
||||
if !mgrPrefs.associatedPhrasesEnabled {
|
||||
if !prefs.associatedPhrasesEnabled {
|
||||
stateCallback(IMEState.ofEmpty())
|
||||
} else {
|
||||
let associatedPhrases =
|
||||
|
|
|
@ -149,11 +149,11 @@ extension KeyHandler {
|
|||
|
||||
if state.hasComposition, composer.isEmpty, !input.isOptionHold,
|
||||
input.isCursorClockLeft || input.isCursorClockRight || input.isSpace
|
||||
|| input.isPageDown || input.isPageUp || (input.isTab && mgrPrefs.specifyShiftTabKeyBehavior)
|
||||
|| input.isPageDown || input.isPageUp || (input.isTab && prefs.specifyShiftTabKeyBehavior)
|
||||
{
|
||||
if input.isSpace {
|
||||
/// 倘若沒有在偏好設定內將 Space 空格鍵設為選字窗呼叫用鍵的話………
|
||||
if !mgrPrefs.chooseCandidateUsingSpace {
|
||||
if !prefs.chooseCandidateUsingSpace {
|
||||
if compositor.cursor >= compositor.length {
|
||||
let displayedText = state.displayedText
|
||||
if !displayedText.isEmpty {
|
||||
|
@ -317,7 +317,7 @@ extension KeyHandler {
|
|||
let string = NSMutableString(string: stringRAW)
|
||||
CFStringTransform(string, nil, kCFStringTransformFullwidthHalfwidth, true)
|
||||
stateCallback(
|
||||
IMEState.ofCommitting(textToCommit: mgrPrefs.halfWidthPunctuationEnabled ? stringRAW : string as String)
|
||||
IMEState.ofCommitting(textToCommit: prefs.halfWidthPunctuationEnabled ? stringRAW : string as String)
|
||||
)
|
||||
stateCallback(IMEState.ofEmpty())
|
||||
return true
|
||||
|
@ -372,7 +372,7 @@ extension KeyHandler {
|
|||
|
||||
if input.isUpperCaseASCIILetterKey, !input.isCommandHold, !input.isControlHold {
|
||||
if input.isShiftHold { // 這裡先不要判斷 isOptionHold。
|
||||
switch mgrPrefs.upperCaseLetterKeyBehavior {
|
||||
switch prefs.upperCaseLetterKeyBehavior {
|
||||
case 1:
|
||||
stateCallback(IMEState.ofEmpty())
|
||||
stateCallback(IMEState.ofCommitting(textToCommit: inputText.lowercased()))
|
||||
|
|
|
@ -23,7 +23,7 @@ extension KeyHandler {
|
|||
/// 換成由此處重新生成的組字字串(NSAttributeString,否則會不顯示)。
|
||||
var displayTextSegments: [String] = compositor.walkedNodes.values
|
||||
var cursor = convertCursorForDisplay(compositor.cursor)
|
||||
let reading = composer.getInlineCompositionForDisplay(isHanyuPinyin: mgrPrefs.showHanyuPinyinInCompositionBuffer)
|
||||
let reading = composer.getInlineCompositionForDisplay(isHanyuPinyin: prefs.showHanyuPinyinInCompositionBuffer)
|
||||
if !reading.isEmpty {
|
||||
var newDisplayTextSegments = [String]()
|
||||
var temporaryNode = ""
|
||||
|
@ -91,7 +91,7 @@ extension KeyHandler {
|
|||
state currentState: IMEStateProtocol
|
||||
) -> IMEState {
|
||||
IMEState.ofCandidates(
|
||||
candidates: getCandidatesArray(fixOrder: mgrPrefs.useFixecCandidateOrderOnSelection),
|
||||
candidates: getCandidatesArray(fixOrder: prefs.useFixecCandidateOrderOnSelection),
|
||||
displayTextSegments: compositor.walkedNodes.values,
|
||||
cursor: currentState.cursor
|
||||
)
|
||||
|
@ -263,7 +263,7 @@ extension KeyHandler {
|
|||
stateCallback(inputting)
|
||||
|
||||
// 從這一行之後開始,就是針對逐字選字模式的單獨處理。
|
||||
guard mgrPrefs.useSCPCTypingMode, composer.isEmpty else { return true }
|
||||
guard prefs.useSCPCTypingMode, composer.isEmpty else { return true }
|
||||
|
||||
let candidateState = buildCandidate(state: inputting)
|
||||
if candidateState.candidates.count == 1 {
|
||||
|
@ -312,7 +312,7 @@ extension KeyHandler {
|
|||
guard state.type == .ofInputting else { return false }
|
||||
|
||||
var displayedText = compositor.keys.joined(separator: "-")
|
||||
if mgrPrefs.inlineDumpPinyinInLieuOfZhuyin {
|
||||
if prefs.inlineDumpPinyinInLieuOfZhuyin {
|
||||
displayedText = Tekkon.restoreToneOneInZhuyinKey(target: displayedText) // 恢復陰平標記
|
||||
displayedText = Tekkon.cnvPhonaToHanyuPinyin(target: displayedText) // 注音轉拼音
|
||||
}
|
||||
|
@ -343,7 +343,7 @@ extension KeyHandler {
|
|||
|
||||
for node in compositor.walkedNodes {
|
||||
var key = node.key
|
||||
if mgrPrefs.inlineDumpPinyinInLieuOfZhuyin {
|
||||
if prefs.inlineDumpPinyinInLieuOfZhuyin {
|
||||
key = Tekkon.restoreToneOneInZhuyinKey(target: key) // 恢復陰平標記
|
||||
key = Tekkon.cnvPhonaToHanyuPinyin(target: key) // 注音轉拼音
|
||||
key = Tekkon.cnvHanyuPinyinToTextbookStyle(target: key) // 轉教科書式標調
|
||||
|
@ -380,7 +380,7 @@ extension KeyHandler {
|
|||
guard state.type == .ofInputting else { return false }
|
||||
|
||||
// 引入 macOS 內建注音輸入法的行為,允許用 Shift+BackSpace 解構前一個漢字的讀音。
|
||||
switch mgrPrefs.specifyShiftBackSpaceKeyBehavior {
|
||||
switch prefs.specifyShiftBackSpaceKeyBehavior {
|
||||
case 0:
|
||||
guard input.isShiftHold, composer.isEmpty else { break }
|
||||
guard let prevReading = previousParsableReading else { break }
|
||||
|
@ -567,7 +567,7 @@ extension KeyHandler {
|
|||
) -> Bool {
|
||||
guard state.type == .ofInputting else { return false }
|
||||
|
||||
if mgrPrefs.escToCleanInputBuffer {
|
||||
if prefs.escToCleanInputBuffer {
|
||||
/// 若啟用了該選項,則清空組字器的內容與注拼槽的內容。
|
||||
/// 此乃 macOS 內建注音輸入法預設之行為,但不太受 Windows 使用者群體之待見。
|
||||
stateCallback(IMEState.ofAbortion())
|
||||
|
|
|
@ -57,9 +57,9 @@ public enum LMMgr {
|
|||
// LMMgr 的 loadUserPhrases 等函式在自動讀取 dataFolderPath 時,
|
||||
// 如果發現自訂目錄不可用,則會自動抹去自訂目錄設定、改採預設目錄。
|
||||
// 所以這裡不需要特別處理。
|
||||
if mgrPrefs.associatedPhrasesEnabled { Self.loadUserAssociatesData() }
|
||||
if mgrPrefs.phraseReplacementEnabled { Self.loadUserPhraseReplacement() }
|
||||
if mgrPrefs.useSCPCTypingMode { Self.loadUserSCPCSequencesData() }
|
||||
if PrefMgr.shared.associatedPhrasesEnabled { Self.loadUserAssociatesData() }
|
||||
if PrefMgr.shared.phraseReplacementEnabled { Self.loadUserPhraseReplacement() }
|
||||
if PrefMgr.shared.useSCPCTypingMode { Self.loadUserSCPCSequencesData() }
|
||||
Self.loadUserPhrasesData()
|
||||
}
|
||||
|
||||
|
@ -445,7 +445,7 @@ public enum LMMgr {
|
|||
public static let appSupportURL = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)[0]
|
||||
|
||||
public static func dataFolderPath(isDefaultFolder: Bool) -> String {
|
||||
var userDictPathSpecified = mgrPrefs.userDataFolderSpecified.expandingTildeInPath
|
||||
var userDictPathSpecified = PrefMgr.shared.userDataFolderSpecified.expandingTildeInPath
|
||||
var userDictPathDefault =
|
||||
Self.appSupportURL.appendingPathComponent("vChewing").path.expandingTildeInPath
|
||||
|
||||
|
@ -516,7 +516,7 @@ public enum LMMgr {
|
|||
|
||||
// The new FolderMonitor module does NOT monitor cases that files are modified
|
||||
// by the current application itself, requiring additional manual loading process here.
|
||||
// if !mgrPrefs.shouldAutoReloadUserDataFiles {}
|
||||
// if !PrefMgr.shared.shouldAutoReloadUserDataFiles {}
|
||||
loadUserPhrasesData()
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -15,11 +15,11 @@ private let kDefaultKeys = "123456789"
|
|||
private let kDefaultBasicKeyboardLayout = "com.apple.keylayout.ZhuyinBopomofo"
|
||||
private let kDefaultAlphanumericalKeyboardLayout = "com.apple.keylayout.ABC"
|
||||
|
||||
public let mgrPrefs = PrefMgr()
|
||||
|
||||
// MARK: -
|
||||
|
||||
public class PrefMgr: PrefMgrProtocol {
|
||||
public static let shared = PrefMgr()
|
||||
|
||||
// MARK: - Settings (Tier 1)
|
||||
|
||||
@AppProperty(key: UserDef.kIsDebugModeEnabled.rawValue, defaultValue: false)
|
||||
|
|
|
@ -40,13 +40,13 @@ public class ctlCandidateIMK: IMKCandidates, ctlCandidateProtocol {
|
|||
ofSize: 14, weight: .medium
|
||||
)
|
||||
|
||||
public var candidateFont = NSFont.systemFont(ofSize: mgrPrefs.candidateListTextSize) {
|
||||
public var candidateFont = NSFont.systemFont(ofSize: PrefMgr.shared.candidateListTextSize) {
|
||||
didSet {
|
||||
if #available(macOS 10.14, *) { setFontSize(candidateFont.pointSize) }
|
||||
var attributes = attributes()
|
||||
// FB11300759: Set "NSAttributedString.Key.font" doesn't work.
|
||||
attributes?[NSAttributedString.Key.font] = candidateFont
|
||||
if mgrPrefs.handleDefaultCandidateFontsByLangIdentifier {
|
||||
if PrefMgr.shared.handleDefaultCandidateFontsByLangIdentifier {
|
||||
switch IMEApp.currentInputMode {
|
||||
case InputMode.imeModeCHS:
|
||||
if #available(macOS 12.0, *) {
|
||||
|
@ -55,7 +55,7 @@ public class ctlCandidateIMK: IMKCandidates, ctlCandidateProtocol {
|
|||
case InputMode.imeModeCHT:
|
||||
if #available(macOS 12.0, *) {
|
||||
attributes?[NSAttributedString.Key.languageIdentifier] =
|
||||
(mgrPrefs.shiftJISShinjitaiOutputEnabled || mgrPrefs.chineseConversionEnabled)
|
||||
(PrefMgr.shared.shiftJISShinjitaiOutputEnabled || PrefMgr.shared.chineseConversionEnabled)
|
||||
? "ja" as AnyObject : "zh-Hant" as AnyObject
|
||||
}
|
||||
default:
|
||||
|
@ -201,12 +201,12 @@ public class ctlCandidateIMK: IMKCandidates, ctlCandidateProtocol {
|
|||
case .vertical: event.isShiftHold ? moveLeft(self) : moveRight(self)
|
||||
}
|
||||
} else if event.isSpace {
|
||||
switch mgrPrefs.specifyShiftSpaceKeyBehavior {
|
||||
switch PrefMgr.shared.specifyShiftSpaceKeyBehavior {
|
||||
case true: _ = event.isShiftHold ? highlightNextCandidate() : showNextPage()
|
||||
case false: _ = event.isShiftHold ? showNextPage() : highlightNextCandidate()
|
||||
}
|
||||
} else if event.isTab {
|
||||
switch mgrPrefs.specifyShiftTabKeyBehavior {
|
||||
switch PrefMgr.shared.specifyShiftTabKeyBehavior {
|
||||
case true: _ = event.isShiftHold ? showPreviousPage() : showNextPage()
|
||||
case false: _ = event.isShiftHold ? highlightPreviousCandidate() : highlightNextCandidate()
|
||||
}
|
||||
|
@ -216,7 +216,7 @@ public class ctlCandidateIMK: IMKCandidates, ctlCandidateProtocol {
|
|||
/// 反正 IMK 選字窗目前也沒辦法修改選字鍵。
|
||||
let newEvent = event.reinitiate(characters: newChar)
|
||||
if let newEvent = newEvent {
|
||||
if mgrPrefs.useSCPCTypingMode, delegate.isAssociatedPhrasesState {
|
||||
if PrefMgr.shared.useSCPCTypingMode, delegate.isAssociatedPhrasesState {
|
||||
// 註:input.isShiftHold 已經在 ctlInputMethod.handle() 內處理,因為在那邊處理才有效。
|
||||
if !event.isShiftHold {
|
||||
_ = delegate.sharedEventHandler(event)
|
||||
|
@ -233,7 +233,7 @@ public class ctlCandidateIMK: IMKCandidates, ctlCandidateProtocol {
|
|||
}
|
||||
}
|
||||
|
||||
if mgrPrefs.useSCPCTypingMode, !event.isReservedKey {
|
||||
if PrefMgr.shared.useSCPCTypingMode, !event.isReservedKey {
|
||||
_ = delegate.sharedEventHandler(event)
|
||||
return
|
||||
}
|
||||
|
@ -241,7 +241,7 @@ public class ctlCandidateIMK: IMKCandidates, ctlCandidateProtocol {
|
|||
if delegate.isAssociatedPhrasesState,
|
||||
!event.isPageUp, !event.isPageDown, !event.isCursorForward, !event.isCursorBackward,
|
||||
!event.isCursorClockLeft, !event.isCursorClockRight, !event.isSpace,
|
||||
!event.isEnter || !mgrPrefs.alsoConfirmAssociatedCandidatesByEnter
|
||||
!event.isEnter || !PrefMgr.shared.alsoConfirmAssociatedCandidatesByEnter
|
||||
{
|
||||
_ = delegate.sharedEventHandler(event)
|
||||
return
|
||||
|
|
|
@ -134,7 +134,7 @@ private class vwrCandidateUniversal: NSView {
|
|||
}
|
||||
|
||||
func ensureLangIdentifier(for attr: inout [NSAttributedString.Key: AnyObject]) {
|
||||
if mgrPrefs.handleDefaultCandidateFontsByLangIdentifier {
|
||||
if PrefMgr.shared.handleDefaultCandidateFontsByLangIdentifier {
|
||||
switch IMEApp.currentInputMode {
|
||||
case InputMode.imeModeCHS:
|
||||
if #available(macOS 12.0, *) {
|
||||
|
@ -143,7 +143,7 @@ private class vwrCandidateUniversal: NSView {
|
|||
case InputMode.imeModeCHT:
|
||||
if #available(macOS 12.0, *) {
|
||||
attr[.languageIdentifier] =
|
||||
(mgrPrefs.shiftJISShinjitaiOutputEnabled || mgrPrefs.chineseConversionEnabled)
|
||||
(PrefMgr.shared.shiftJISShinjitaiOutputEnabled || PrefMgr.shared.chineseConversionEnabled)
|
||||
? "ja" as AnyObject : "zh-Hant" as AnyObject
|
||||
}
|
||||
default:
|
||||
|
@ -542,7 +542,7 @@ extension ctlCandidateUniversal {
|
|||
candidateView.frame = frameRect
|
||||
let counterHeight: CGFloat = newSize.height - 24
|
||||
|
||||
if pageCount > 1, mgrPrefs.showPageButtonsInCandidateWindow {
|
||||
if pageCount > 1, PrefMgr.shared.showPageButtonsInCandidateWindow {
|
||||
var buttonRect = nextPageButton.frame
|
||||
let spacing: CGFloat = 0.0
|
||||
|
||||
|
@ -587,7 +587,7 @@ extension ctlCandidateUniversal {
|
|||
? (newSize.height - rect.height) / 2
|
||||
: counterHeight
|
||||
let rectOriginX: CGFloat =
|
||||
mgrPrefs.showPageButtonsInCandidateWindow
|
||||
PrefMgr.shared.showPageButtonsInCandidateWindow
|
||||
? newSize.width
|
||||
: newSize.width + 4
|
||||
rect.origin = NSPoint(x: rectOriginX, y: rectOriginY)
|
||||
|
|
|
@ -21,11 +21,11 @@ struct suiPrefPaneDevZone: View {
|
|||
|
||||
private let contentMaxHeight: Double = 432
|
||||
private let contentWidth: Double = {
|
||||
switch mgrPrefs.appleLanguages[0] {
|
||||
switch PrefMgr.shared.appleLanguages[0] {
|
||||
case "ja":
|
||||
return 520
|
||||
default:
|
||||
if mgrPrefs.appleLanguages[0].contains("zh-Han") {
|
||||
if PrefMgr.shared.appleLanguages[0].contains("zh-Han") {
|
||||
return 480
|
||||
} else {
|
||||
return 580
|
||||
|
@ -53,7 +53,7 @@ struct suiPrefPaneDevZone: View {
|
|||
Toggle(
|
||||
LocalizedStringKey("Use IMK Candidate Window instead (will reboot the IME)"),
|
||||
isOn: $selUseIMKCandidateWindow.onChange {
|
||||
mgrPrefs.useIMKCandidateWindow = selUseIMKCandidateWindow
|
||||
PrefMgr.shared.useIMKCandidateWindow = selUseIMKCandidateWindow
|
||||
NSLog("vChewing App self-terminated due to enabling / disabling IMK candidate window.")
|
||||
NSApplication.shared.terminate(nil)
|
||||
}
|
||||
|
@ -67,7 +67,8 @@ struct suiPrefPaneDevZone: View {
|
|||
Toggle(
|
||||
LocalizedStringKey("Use .langIdentifier to handle UI fonts in candidate window"),
|
||||
isOn: $selHandleDefaultCandidateFontsByLangIdentifier.onChange {
|
||||
mgrPrefs.handleDefaultCandidateFontsByLangIdentifier = selHandleDefaultCandidateFontsByLangIdentifier
|
||||
PrefMgr.shared.handleDefaultCandidateFontsByLangIdentifier =
|
||||
selHandleDefaultCandidateFontsByLangIdentifier
|
||||
}
|
||||
)
|
||||
.disabled(!isMontereyOrAbove)
|
||||
|
@ -80,7 +81,7 @@ struct suiPrefPaneDevZone: View {
|
|||
Picker(
|
||||
"",
|
||||
selection: $selShiftKeyAccommodationBehavior.onChange {
|
||||
mgrPrefs.shiftKeyAccommodationBehavior = selShiftKeyAccommodationBehavior
|
||||
PrefMgr.shared.shiftKeyAccommodationBehavior = selShiftKeyAccommodationBehavior
|
||||
}
|
||||
) {
|
||||
Text(LocalizedStringKey("Disable Shift key accomodation in all cases")).tag(0)
|
||||
|
|
|
@ -37,11 +37,11 @@ struct suiPrefPaneDictionary: View {
|
|||
|
||||
private let contentMaxHeight: Double = 432
|
||||
private let contentWidth: Double = {
|
||||
switch mgrPrefs.appleLanguages[0] {
|
||||
switch PrefMgr.shared.appleLanguages[0] {
|
||||
case "ja":
|
||||
return 520
|
||||
default:
|
||||
if mgrPrefs.appleLanguages[0].contains("zh-Han") {
|
||||
if PrefMgr.shared.appleLanguages[0].contains("zh-Han") {
|
||||
return 480
|
||||
} else {
|
||||
return 580
|
||||
|
@ -72,7 +72,7 @@ struct suiPrefPaneDictionary: View {
|
|||
Self.dlgOpenPath.canChooseDirectories = true
|
||||
|
||||
let bolPreviousFolderValidity = LMMgr.checkIfSpecifiedUserDataFolderValid(
|
||||
mgrPrefs.userDataFolderSpecified.expandingTildeInPath)
|
||||
PrefMgr.shared.userDataFolderSpecified.expandingTildeInPath)
|
||||
|
||||
if let window = ctlPrefUI.shared.controller.window {
|
||||
Self.dlgOpenPath.beginSheetModal(for: window) { result in
|
||||
|
@ -83,8 +83,8 @@ struct suiPrefPaneDictionary: View {
|
|||
var newPath = url.path
|
||||
newPath.ensureTrailingSlash()
|
||||
if LMMgr.checkIfSpecifiedUserDataFolderValid(newPath) {
|
||||
mgrPrefs.userDataFolderSpecified = newPath
|
||||
tbxUserDataPathSpecified = mgrPrefs.userDataFolderSpecified
|
||||
PrefMgr.shared.userDataFolderSpecified = newPath
|
||||
tbxUserDataPathSpecified = PrefMgr.shared.userDataFolderSpecified
|
||||
BookmarkManager.shared.saveBookmark(for: url)
|
||||
(NSApplication.shared.delegate as! AppDelegate).updateDirectoryMonitorPath()
|
||||
} else {
|
||||
|
@ -115,7 +115,7 @@ struct suiPrefPaneDictionary: View {
|
|||
Toggle(
|
||||
LocalizedStringKey("Automatically reload user data files if changes detected"),
|
||||
isOn: $selAutoReloadUserData.onChange {
|
||||
mgrPrefs.shouldAutoReloadUserDataFiles = selAutoReloadUserData
|
||||
PrefMgr.shared.shouldAutoReloadUserDataFiles = selAutoReloadUserData
|
||||
}
|
||||
).controlSize(.small)
|
||||
}
|
||||
|
@ -123,39 +123,39 @@ struct suiPrefPaneDictionary: View {
|
|||
Toggle(
|
||||
LocalizedStringKey("Enable CNS11643 Support (2022-08-02)"),
|
||||
isOn: $selEnableCNS11643.onChange {
|
||||
mgrPrefs.cns11643Enabled = selEnableCNS11643
|
||||
LMMgr.setCNSEnabled(mgrPrefs.cns11643Enabled)
|
||||
PrefMgr.shared.cns11643Enabled = selEnableCNS11643
|
||||
LMMgr.setCNSEnabled(PrefMgr.shared.cns11643Enabled)
|
||||
}
|
||||
)
|
||||
Toggle(
|
||||
LocalizedStringKey("Enable symbol input support (incl. certain emoji symbols)"),
|
||||
isOn: $selEnableSymbolInputSupport.onChange {
|
||||
mgrPrefs.symbolInputEnabled = selEnableSymbolInputSupport
|
||||
LMMgr.setSymbolEnabled(mgrPrefs.symbolInputEnabled)
|
||||
PrefMgr.shared.symbolInputEnabled = selEnableSymbolInputSupport
|
||||
LMMgr.setSymbolEnabled(PrefMgr.shared.symbolInputEnabled)
|
||||
}
|
||||
)
|
||||
Toggle(
|
||||
LocalizedStringKey("Allow boosting / excluding a candidate of single kanji"),
|
||||
isOn: $selAllowBoostingSingleKanjiAsUserPhrase.onChange {
|
||||
mgrPrefs.allowBoostingSingleKanjiAsUserPhrase = selAllowBoostingSingleKanjiAsUserPhrase
|
||||
PrefMgr.shared.allowBoostingSingleKanjiAsUserPhrase = selAllowBoostingSingleKanjiAsUserPhrase
|
||||
}
|
||||
)
|
||||
Toggle(
|
||||
LocalizedStringKey("Applying typing suggestions from half-life user override model"),
|
||||
isOn: $selFetchSuggestionsFromUserOverrideModel.onChange {
|
||||
mgrPrefs.fetchSuggestionsFromUserOverrideModel = selFetchSuggestionsFromUserOverrideModel
|
||||
PrefMgr.shared.fetchSuggestionsFromUserOverrideModel = selFetchSuggestionsFromUserOverrideModel
|
||||
}
|
||||
)
|
||||
Toggle(
|
||||
LocalizedStringKey("Always use fixed listing order in candidate window"),
|
||||
isOn: $selUseFixecCandidateOrderOnSelection.onChange {
|
||||
mgrPrefs.useFixecCandidateOrderOnSelection = selUseFixecCandidateOrderOnSelection
|
||||
PrefMgr.shared.useFixecCandidateOrderOnSelection = selUseFixecCandidateOrderOnSelection
|
||||
}
|
||||
)
|
||||
Toggle(
|
||||
LocalizedStringKey("Consolidate the context on confirming candidate selection"),
|
||||
isOn: $selConsolidateContextOnCandidateSelection.onChange {
|
||||
mgrPrefs.consolidateContextOnCandidateSelection = selConsolidateContextOnCandidateSelection
|
||||
PrefMgr.shared.consolidateContextOnCandidateSelection = selConsolidateContextOnCandidateSelection
|
||||
}
|
||||
)
|
||||
Text(
|
||||
|
@ -167,7 +167,7 @@ struct suiPrefPaneDictionary: View {
|
|||
Toggle(
|
||||
LocalizedStringKey("Harden vertical punctuations during vertical typing (not recommended)"),
|
||||
isOn: $selHardenVerticalPunctuations.onChange {
|
||||
mgrPrefs.hardenVerticalPunctuations = selHardenVerticalPunctuations
|
||||
PrefMgr.shared.hardenVerticalPunctuations = selHardenVerticalPunctuations
|
||||
}
|
||||
)
|
||||
Text(
|
||||
|
|
|
@ -50,11 +50,11 @@ struct suiPrefPaneExperience: View {
|
|||
|
||||
private let contentMaxHeight: Double = 432
|
||||
private let contentWidth: Double = {
|
||||
switch mgrPrefs.appleLanguages[0] {
|
||||
switch PrefMgr.shared.appleLanguages[0] {
|
||||
case "ja":
|
||||
return 520
|
||||
default:
|
||||
if mgrPrefs.appleLanguages[0].contains("zh-Han") {
|
||||
if PrefMgr.shared.appleLanguages[0].contains("zh-Han") {
|
||||
return 480
|
||||
} else {
|
||||
return 580
|
||||
|
@ -85,7 +85,7 @@ struct suiPrefPaneExperience: View {
|
|||
Picker(
|
||||
"",
|
||||
selection: $selCursorPosition.onChange {
|
||||
mgrPrefs.useRearCursorMode = (selCursorPosition == 1) ? true : false
|
||||
PrefMgr.shared.useRearCursorMode = (selCursorPosition == 1) ? true : false
|
||||
}
|
||||
) {
|
||||
Text(LocalizedStringKey("in front of the phrase (like macOS built-in Zhuyin IME)")).tag(0)
|
||||
|
@ -98,7 +98,7 @@ struct suiPrefPaneExperience: View {
|
|||
Toggle(
|
||||
LocalizedStringKey("Push the cursor in front of the phrase after selection"),
|
||||
isOn: $selPushCursorAfterSelection.onChange {
|
||||
mgrPrefs.moveCursorAfterSelectingCandidate = selPushCursorAfterSelection
|
||||
PrefMgr.shared.moveCursorAfterSelectingCandidate = selPushCursorAfterSelection
|
||||
}
|
||||
).controlSize(.small)
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ struct suiPrefPaneExperience: View {
|
|||
Picker(
|
||||
"",
|
||||
selection: $selSpecifyShiftBackSpaceKeyBehavior.onChange {
|
||||
mgrPrefs.specifyShiftBackSpaceKeyBehavior = selSpecifyShiftBackSpaceKeyBehavior
|
||||
PrefMgr.shared.specifyShiftBackSpaceKeyBehavior = selSpecifyShiftBackSpaceKeyBehavior
|
||||
}
|
||||
) {
|
||||
Text(LocalizedStringKey("Disassemble the previous reading, dropping its intonation")).tag(0)
|
||||
|
@ -122,7 +122,7 @@ struct suiPrefPaneExperience: View {
|
|||
Picker(
|
||||
"",
|
||||
selection: $selKeyBehaviorShiftTab.onChange {
|
||||
mgrPrefs.specifyShiftTabKeyBehavior = (selKeyBehaviorShiftTab == 1) ? true : false
|
||||
PrefMgr.shared.specifyShiftTabKeyBehavior = (selKeyBehaviorShiftTab == 1) ? true : false
|
||||
}
|
||||
) {
|
||||
Text(LocalizedStringKey("for cycling candidates")).tag(0)
|
||||
|
@ -138,7 +138,7 @@ struct suiPrefPaneExperience: View {
|
|||
Picker(
|
||||
"",
|
||||
selection: $selKeyBehaviorShiftSpace.onChange {
|
||||
mgrPrefs.specifyShiftSpaceKeyBehavior = (selKeyBehaviorShiftSpace == 1) ? true : false
|
||||
PrefMgr.shared.specifyShiftSpaceKeyBehavior = (selKeyBehaviorShiftSpace == 1) ? true : false
|
||||
}
|
||||
) {
|
||||
Text(LocalizedStringKey("Space to +cycle candidates, Shift+Space to +cycle pages")).tag(0)
|
||||
|
@ -153,7 +153,7 @@ struct suiPrefPaneExperience: View {
|
|||
Picker(
|
||||
"",
|
||||
selection: $selUpperCaseLetterKeyBehavior.onChange {
|
||||
mgrPrefs.upperCaseLetterKeyBehavior = selUpperCaseLetterKeyBehavior
|
||||
PrefMgr.shared.upperCaseLetterKeyBehavior = selUpperCaseLetterKeyBehavior
|
||||
}
|
||||
) {
|
||||
Text(LocalizedStringKey("Type them into inline composition buffer")).tag(0)
|
||||
|
@ -169,7 +169,7 @@ struct suiPrefPaneExperience: View {
|
|||
Picker(
|
||||
"",
|
||||
selection: $selSpecifyIntonationKeyBehavior.onChange {
|
||||
mgrPrefs.specifyIntonationKeyBehavior = selSpecifyIntonationKeyBehavior
|
||||
PrefMgr.shared.specifyIntonationKeyBehavior = selSpecifyIntonationKeyBehavior
|
||||
}
|
||||
) {
|
||||
Text(LocalizedStringKey("Override the previous reading's intonation with candidate-reset")).tag(0)
|
||||
|
@ -185,57 +185,57 @@ struct suiPrefPaneExperience: View {
|
|||
Toggle(
|
||||
LocalizedStringKey("Completely disable using Shift key to toggle alphanumerical mode"),
|
||||
isOn: $selDisableShiftTogglingAlphanumericalMode.onChange {
|
||||
mgrPrefs.disableShiftTogglingAlphanumericalMode = selDisableShiftTogglingAlphanumericalMode
|
||||
PrefMgr.shared.disableShiftTogglingAlphanumericalMode = selDisableShiftTogglingAlphanumericalMode
|
||||
}
|
||||
)
|
||||
Toggle(
|
||||
LocalizedStringKey("Also toggle alphanumerical mode with Left-Shift"),
|
||||
isOn: $selTogglingAlphanumericalModeWithLShift.onChange {
|
||||
mgrPrefs.togglingAlphanumericalModeWithLShift = selTogglingAlphanumericalModeWithLShift
|
||||
PrefMgr.shared.togglingAlphanumericalModeWithLShift = selTogglingAlphanumericalModeWithLShift
|
||||
}
|
||||
).disabled(mgrPrefs.disableShiftTogglingAlphanumericalMode == true)
|
||||
).disabled(PrefMgr.shared.disableShiftTogglingAlphanumericalMode == true)
|
||||
}
|
||||
Preferences.Section(label: { Text(LocalizedStringKey("Misc Settings:")) }) {
|
||||
Toggle(
|
||||
LocalizedStringKey("Enable Space key for calling candidate window"),
|
||||
isOn: $selKeyBehaviorSpaceForCallingCandidate.onChange {
|
||||
mgrPrefs.chooseCandidateUsingSpace = selKeyBehaviorSpaceForCallingCandidate
|
||||
PrefMgr.shared.chooseCandidateUsingSpace = selKeyBehaviorSpaceForCallingCandidate
|
||||
}
|
||||
)
|
||||
Toggle(
|
||||
LocalizedStringKey("Use ESC key to clear the entire input buffer"),
|
||||
isOn: $selKeyBehaviorESCForClearingTheBuffer.onChange {
|
||||
mgrPrefs.escToCleanInputBuffer = selKeyBehaviorESCForClearingTheBuffer
|
||||
PrefMgr.shared.escToCleanInputBuffer = selKeyBehaviorESCForClearingTheBuffer
|
||||
}
|
||||
)
|
||||
Toggle(
|
||||
LocalizedStringKey("Automatically correct reading combinations when typing"),
|
||||
isOn: $selAutoCorrectReadingCombination.onChange {
|
||||
mgrPrefs.autoCorrectReadingCombination = selAutoCorrectReadingCombination
|
||||
PrefMgr.shared.autoCorrectReadingCombination = selAutoCorrectReadingCombination
|
||||
}
|
||||
)
|
||||
Toggle(
|
||||
LocalizedStringKey("Allow using Enter key to confirm associated candidate selection"),
|
||||
isOn: $selAlsoConfirmAssociatedCandidatesByEnter.onChange {
|
||||
mgrPrefs.alsoConfirmAssociatedCandidatesByEnter = selAlsoConfirmAssociatedCandidatesByEnter
|
||||
PrefMgr.shared.alsoConfirmAssociatedCandidatesByEnter = selAlsoConfirmAssociatedCandidatesByEnter
|
||||
}
|
||||
)
|
||||
Toggle(
|
||||
LocalizedStringKey("Allow backspace-editing miscomposed readings"),
|
||||
isOn: $selKeepReadingUponCompositionError.onChange {
|
||||
mgrPrefs.keepReadingUponCompositionError = selKeepReadingUponCompositionError
|
||||
PrefMgr.shared.keepReadingUponCompositionError = selKeepReadingUponCompositionError
|
||||
}
|
||||
)
|
||||
Toggle(
|
||||
LocalizedStringKey("Trim unfinished readings on commit"),
|
||||
isOn: $selTrimUnfinishedReadingsOnCommit.onChange {
|
||||
mgrPrefs.trimUnfinishedReadingsOnCommit = selTrimUnfinishedReadingsOnCommit
|
||||
PrefMgr.shared.trimUnfinishedReadingsOnCommit = selTrimUnfinishedReadingsOnCommit
|
||||
}
|
||||
)
|
||||
Toggle(
|
||||
LocalizedStringKey("Emulating select-candidate-per-character mode"),
|
||||
isOn: $selEnableSCPCTypingMode.onChange {
|
||||
mgrPrefs.useSCPCTypingMode = selEnableSCPCTypingMode
|
||||
PrefMgr.shared.useSCPCTypingMode = selEnableSCPCTypingMode
|
||||
}
|
||||
)
|
||||
Text(LocalizedStringKey("An accommodation for elder computer users."))
|
||||
|
@ -243,7 +243,7 @@ struct suiPrefPaneExperience: View {
|
|||
Toggle(
|
||||
LocalizedStringKey("Always show tooltip texts horizontally"),
|
||||
isOn: $selAlwaysShowTooltipTextsHorizontally.onChange {
|
||||
mgrPrefs.alwaysShowTooltipTextsHorizontally = selAlwaysShowTooltipTextsHorizontally
|
||||
PrefMgr.shared.alwaysShowTooltipTextsHorizontally = selAlwaysShowTooltipTextsHorizontally
|
||||
}
|
||||
).disabled(Bundle.main.preferredLocalizations[0] == "en")
|
||||
Text(
|
||||
|
|
|
@ -41,11 +41,11 @@ struct suiPrefPaneGeneral: View {
|
|||
|
||||
private let contentMaxHeight: Double = 432
|
||||
private let contentWidth: Double = {
|
||||
switch mgrPrefs.appleLanguages[0] {
|
||||
switch PrefMgr.shared.appleLanguages[0] {
|
||||
case "ja":
|
||||
return 520
|
||||
default:
|
||||
if mgrPrefs.appleLanguages[0].contains("zh-Han") {
|
||||
if PrefMgr.shared.appleLanguages[0].contains("zh-Han") {
|
||||
return 480
|
||||
} else {
|
||||
return 580
|
||||
|
@ -60,7 +60,7 @@ struct suiPrefPaneGeneral: View {
|
|||
Picker(
|
||||
"",
|
||||
selection: $selCandidateUIFontSize.onChange {
|
||||
mgrPrefs.candidateListTextSize = CGFloat(selCandidateUIFontSize)
|
||||
PrefMgr.shared.candidateListTextSize = CGFloat(selCandidateUIFontSize)
|
||||
}
|
||||
) {
|
||||
Group {
|
||||
|
@ -89,14 +89,14 @@ struct suiPrefPaneGeneral: View {
|
|||
LocalizedStringKey("Follow OS settings"),
|
||||
selection: $selUILanguage.onChange {
|
||||
vCLog(selUILanguage[0])
|
||||
if selUILanguage == mgrPrefs.appleLanguages
|
||||
if selUILanguage == PrefMgr.shared.appleLanguages
|
||||
|| (selUILanguage[0] == "auto"
|
||||
&& UserDefaults.standard.object(forKey: UserDef.kAppleLanguages.rawValue) == nil)
|
||||
{
|
||||
return
|
||||
}
|
||||
if selUILanguage[0] != "auto" {
|
||||
mgrPrefs.appleLanguages = selUILanguage
|
||||
PrefMgr.shared.appleLanguages = selUILanguage
|
||||
} else {
|
||||
UserDefaults.standard.removeObject(forKey: UserDef.kAppleLanguages.rawValue)
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ struct suiPrefPaneGeneral: View {
|
|||
Picker(
|
||||
"",
|
||||
selection: $selEnableHorizontalCandidateLayout.onChange {
|
||||
mgrPrefs.useHorizontalCandidateList = selEnableHorizontalCandidateLayout
|
||||
PrefMgr.shared.useHorizontalCandidateList = selEnableHorizontalCandidateLayout
|
||||
}
|
||||
) {
|
||||
Text(LocalizedStringKey("Vertical")).tag(false)
|
||||
|
@ -134,43 +134,43 @@ struct suiPrefPaneGeneral: View {
|
|||
Toggle(
|
||||
LocalizedStringKey("Show page buttons in candidate window"),
|
||||
isOn: $selShowPageButtonsInCandidateUI.onChange {
|
||||
mgrPrefs.showPageButtonsInCandidateWindow = selShowPageButtonsInCandidateUI
|
||||
PrefMgr.shared.showPageButtonsInCandidateWindow = selShowPageButtonsInCandidateUI
|
||||
}
|
||||
)
|
||||
.controlSize(.small)
|
||||
.disabled(mgrPrefs.useIMKCandidateWindow)
|
||||
.disabled(PrefMgr.shared.useIMKCandidateWindow)
|
||||
}
|
||||
Preferences.Section(label: { Text(LocalizedStringKey("Output Settings:")) }) {
|
||||
Toggle(
|
||||
LocalizedStringKey("Auto-convert traditional Chinese glyphs to KangXi characters"),
|
||||
isOn: $selEnableKanjiConvToKangXi.onChange {
|
||||
mgrPrefs.chineseConversionEnabled = selEnableKanjiConvToKangXi
|
||||
selEnableKanjiConvToJIS = mgrPrefs.shiftJISShinjitaiOutputEnabled
|
||||
PrefMgr.shared.chineseConversionEnabled = selEnableKanjiConvToKangXi
|
||||
selEnableKanjiConvToJIS = PrefMgr.shared.shiftJISShinjitaiOutputEnabled
|
||||
}
|
||||
)
|
||||
Toggle(
|
||||
LocalizedStringKey("Auto-convert traditional Chinese glyphs to JIS Shinjitai characters"),
|
||||
isOn: $selEnableKanjiConvToJIS.onChange {
|
||||
mgrPrefs.shiftJISShinjitaiOutputEnabled = selEnableKanjiConvToJIS
|
||||
selEnableKanjiConvToKangXi = mgrPrefs.chineseConversionEnabled
|
||||
PrefMgr.shared.shiftJISShinjitaiOutputEnabled = selEnableKanjiConvToJIS
|
||||
selEnableKanjiConvToKangXi = PrefMgr.shared.chineseConversionEnabled
|
||||
}
|
||||
)
|
||||
Toggle(
|
||||
LocalizedStringKey("Show Hanyu-Pinyin in the inline composition buffer"),
|
||||
isOn: $selShowHanyuPinyinInCompositionBuffer.onChange {
|
||||
mgrPrefs.showHanyuPinyinInCompositionBuffer = selShowHanyuPinyinInCompositionBuffer
|
||||
PrefMgr.shared.showHanyuPinyinInCompositionBuffer = selShowHanyuPinyinInCompositionBuffer
|
||||
}
|
||||
)
|
||||
Toggle(
|
||||
LocalizedStringKey("Commit Hanyu-Pinyin instead on Ctrl(+Option)+Command+Enter"),
|
||||
isOn: $selInlineDumpPinyinInLieuOfZhuyin.onChange {
|
||||
mgrPrefs.inlineDumpPinyinInLieuOfZhuyin = selInlineDumpPinyinInLieuOfZhuyin
|
||||
PrefMgr.shared.inlineDumpPinyinInLieuOfZhuyin = selInlineDumpPinyinInLieuOfZhuyin
|
||||
}
|
||||
)
|
||||
Toggle(
|
||||
LocalizedStringKey("Stop farting (when typed phonetic combination is invalid, etc.)"),
|
||||
isOn: $selEnableFartSuppressor.onChange {
|
||||
mgrPrefs.shouldNotFartInLieuOfBeep = selEnableFartSuppressor
|
||||
PrefMgr.shared.shouldNotFartInLieuOfBeep = selEnableFartSuppressor
|
||||
IMEApp.buzz()
|
||||
}
|
||||
)
|
||||
|
@ -179,14 +179,14 @@ struct suiPrefPaneGeneral: View {
|
|||
Toggle(
|
||||
LocalizedStringKey("Check for updates automatically"),
|
||||
isOn: $selEnableAutoUpdateCheck.onChange {
|
||||
mgrPrefs.checkUpdateAutomatically = selEnableAutoUpdateCheck
|
||||
PrefMgr.shared.checkUpdateAutomatically = selEnableAutoUpdateCheck
|
||||
}
|
||||
)
|
||||
.controlSize(.small)
|
||||
Toggle(
|
||||
LocalizedStringKey("Debug Mode"),
|
||||
isOn: $selEnableDebugMode.onChange {
|
||||
mgrPrefs.isDebugModeEnabled = selEnableDebugMode
|
||||
PrefMgr.shared.isDebugModeEnabled = selEnableDebugMode
|
||||
}
|
||||
)
|
||||
.controlSize(.small)
|
||||
|
|
|
@ -18,10 +18,10 @@ struct suiPrefPaneKeyboard: View {
|
|||
UserDefaults.standard.string(forKey: UserDef.kCandidateKeys.rawValue) ?? CandidateKey.defaultKeys
|
||||
@State private var selKeyboardParser = UserDefaults.standard.integer(forKey: UserDef.kKeyboardParser.rawValue)
|
||||
@State private var selBasicKeyboardLayout: String =
|
||||
UserDefaults.standard.string(forKey: UserDef.kBasicKeyboardLayout.rawValue) ?? mgrPrefs.basicKeyboardLayout
|
||||
UserDefaults.standard.string(forKey: UserDef.kBasicKeyboardLayout.rawValue) ?? PrefMgr.shared.basicKeyboardLayout
|
||||
@State private var selAlphanumericalKeyboardLayout: String =
|
||||
UserDefaults.standard.string(forKey: UserDef.kAlphanumericalKeyboardLayout.rawValue)
|
||||
?? mgrPrefs.alphanumericalKeyboardLayout
|
||||
?? PrefMgr.shared.alphanumericalKeyboardLayout
|
||||
|
||||
@State private var selUsingHotKeySCPC = UserDefaults.standard.bool(forKey: UserDef.kUsingHotKeySCPC.rawValue)
|
||||
@State private var selUsingHotKeyAssociates = UserDefaults.standard.bool(
|
||||
|
@ -36,11 +36,11 @@ struct suiPrefPaneKeyboard: View {
|
|||
|
||||
private let contentMaxHeight: Double = 432
|
||||
private let contentWidth: Double = {
|
||||
switch mgrPrefs.appleLanguages[0] {
|
||||
switch PrefMgr.shared.appleLanguages[0] {
|
||||
case "ja":
|
||||
return 520
|
||||
default:
|
||||
if mgrPrefs.appleLanguages[0].contains("zh-Han") {
|
||||
if PrefMgr.shared.appleLanguages[0].contains("zh-Han") {
|
||||
return 480
|
||||
} else {
|
||||
return 580
|
||||
|
@ -59,22 +59,22 @@ struct suiPrefPaneKeyboard: View {
|
|||
let keys: String = value.trimmingCharacters(in: .whitespacesAndNewlines).deduplicate
|
||||
do {
|
||||
try CandidateKey.validate(keys: keys)
|
||||
mgrPrefs.candidateKeys = keys
|
||||
selSelectionKeys = mgrPrefs.candidateKeys
|
||||
PrefMgr.shared.candidateKeys = keys
|
||||
selSelectionKeys = PrefMgr.shared.candidateKeys
|
||||
} catch CandidateKey.ErrorType.empty {
|
||||
selSelectionKeys = mgrPrefs.candidateKeys
|
||||
selSelectionKeys = PrefMgr.shared.candidateKeys
|
||||
} catch {
|
||||
if let window = ctlPrefUI.shared.controller.window {
|
||||
let alert = NSAlert(error: error)
|
||||
alert.beginSheetModal(for: window) { _ in
|
||||
selSelectionKeys = mgrPrefs.candidateKeys
|
||||
selSelectionKeys = PrefMgr.shared.candidateKeys
|
||||
}
|
||||
IMEApp.buzz()
|
||||
}
|
||||
}
|
||||
}
|
||||
).frame(width: 180).disabled(mgrPrefs.useIMKCandidateWindow)
|
||||
if mgrPrefs.useIMKCandidateWindow {
|
||||
).frame(width: 180).disabled(PrefMgr.shared.useIMKCandidateWindow)
|
||||
if PrefMgr.shared.useIMKCandidateWindow {
|
||||
Text(
|
||||
LocalizedStringKey(
|
||||
"⚠︎ This feature in IMK Candidate Window defects. Please consult Apple Developer Relations\nand tell them the related Radar ID: #FB11300759."
|
||||
|
@ -96,17 +96,17 @@ struct suiPrefPaneKeyboard: View {
|
|||
"",
|
||||
selection: $selKeyboardParser.onChange {
|
||||
let value = selKeyboardParser
|
||||
mgrPrefs.keyboardParser = value
|
||||
PrefMgr.shared.keyboardParser = value
|
||||
switch value {
|
||||
case 0:
|
||||
if !IMKHelper.arrDynamicBasicKeyLayouts.contains(mgrPrefs.basicKeyboardLayout) {
|
||||
mgrPrefs.basicKeyboardLayout = "com.apple.keylayout.ZhuyinBopomofo"
|
||||
selBasicKeyboardLayout = mgrPrefs.basicKeyboardLayout
|
||||
if !IMKHelper.arrDynamicBasicKeyLayouts.contains(PrefMgr.shared.basicKeyboardLayout) {
|
||||
PrefMgr.shared.basicKeyboardLayout = "com.apple.keylayout.ZhuyinBopomofo"
|
||||
selBasicKeyboardLayout = PrefMgr.shared.basicKeyboardLayout
|
||||
}
|
||||
default:
|
||||
if IMKHelper.arrDynamicBasicKeyLayouts.contains(mgrPrefs.basicKeyboardLayout) {
|
||||
mgrPrefs.basicKeyboardLayout = "com.apple.keylayout.ABC"
|
||||
selBasicKeyboardLayout = mgrPrefs.basicKeyboardLayout
|
||||
if IMKHelper.arrDynamicBasicKeyLayouts.contains(PrefMgr.shared.basicKeyboardLayout) {
|
||||
PrefMgr.shared.basicKeyboardLayout = "com.apple.keylayout.ABC"
|
||||
selBasicKeyboardLayout = PrefMgr.shared.basicKeyboardLayout
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -137,18 +137,18 @@ struct suiPrefPaneKeyboard: View {
|
|||
}
|
||||
.labelsHidden()
|
||||
Button {
|
||||
mgrPrefs.keyboardParser = 0
|
||||
selKeyboardParser = mgrPrefs.keyboardParser
|
||||
mgrPrefs.basicKeyboardLayout = "com.apple.keylayout.ZhuyinBopomofo"
|
||||
selBasicKeyboardLayout = mgrPrefs.basicKeyboardLayout
|
||||
PrefMgr.shared.keyboardParser = 0
|
||||
selKeyboardParser = PrefMgr.shared.keyboardParser
|
||||
PrefMgr.shared.basicKeyboardLayout = "com.apple.keylayout.ZhuyinBopomofo"
|
||||
selBasicKeyboardLayout = PrefMgr.shared.basicKeyboardLayout
|
||||
} label: {
|
||||
Text("↻ㄅ")
|
||||
}
|
||||
Button {
|
||||
mgrPrefs.keyboardParser = 10
|
||||
selKeyboardParser = mgrPrefs.keyboardParser
|
||||
mgrPrefs.basicKeyboardLayout = "com.apple.keylayout.ABC"
|
||||
selBasicKeyboardLayout = mgrPrefs.basicKeyboardLayout
|
||||
PrefMgr.shared.keyboardParser = 10
|
||||
selKeyboardParser = PrefMgr.shared.keyboardParser
|
||||
PrefMgr.shared.basicKeyboardLayout = "com.apple.keylayout.ABC"
|
||||
selBasicKeyboardLayout = PrefMgr.shared.basicKeyboardLayout
|
||||
} label: {
|
||||
Text("↻A")
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ struct suiPrefPaneKeyboard: View {
|
|||
NSLocalizedString(
|
||||
"Choose the phonetic layout for Mandarin parser.",
|
||||
comment: ""
|
||||
) + (mgrPrefs.appleLanguages[0].contains("en") ? " " : "")
|
||||
) + (PrefMgr.shared.appleLanguages[0].contains("en") ? " " : "")
|
||||
+ NSLocalizedString(
|
||||
"Apple Dynamic Bopomofo Basic Keyboard Layouts (Dachen & Eten Traditional) must match the Dachen parser in order to be functional.",
|
||||
comment: ""
|
||||
|
@ -175,10 +175,10 @@ struct suiPrefPaneKeyboard: View {
|
|||
"",
|
||||
selection: $selBasicKeyboardLayout.onChange {
|
||||
let value = selBasicKeyboardLayout
|
||||
mgrPrefs.basicKeyboardLayout = value
|
||||
PrefMgr.shared.basicKeyboardLayout = value
|
||||
if IMKHelper.arrDynamicBasicKeyLayouts.contains(value) {
|
||||
mgrPrefs.keyboardParser = 0
|
||||
selKeyboardParser = mgrPrefs.keyboardParser
|
||||
PrefMgr.shared.keyboardParser = 0
|
||||
selKeyboardParser = PrefMgr.shared.keyboardParser
|
||||
}
|
||||
}
|
||||
) {
|
||||
|
@ -210,7 +210,7 @@ struct suiPrefPaneKeyboard: View {
|
|||
Picker(
|
||||
"",
|
||||
selection: $selAlphanumericalKeyboardLayout.onChange {
|
||||
mgrPrefs.alphanumericalKeyboardLayout = selAlphanumericalKeyboardLayout
|
||||
PrefMgr.shared.alphanumericalKeyboardLayout = selAlphanumericalKeyboardLayout
|
||||
}
|
||||
) {
|
||||
ForEach(0...(IMKHelper.allowedAlphanumericalTISInputSources.count - 1), id: \.self) { id in
|
||||
|
@ -239,25 +239,25 @@ struct suiPrefPaneKeyboard: View {
|
|||
Toggle(
|
||||
LocalizedStringKey("Per-Char Select Mode"),
|
||||
isOn: $selUsingHotKeySCPC.onChange {
|
||||
mgrPrefs.usingHotKeySCPC = selUsingHotKeySCPC
|
||||
PrefMgr.shared.usingHotKeySCPC = selUsingHotKeySCPC
|
||||
}
|
||||
)
|
||||
Toggle(
|
||||
LocalizedStringKey("Per-Char Associated Phrases"),
|
||||
isOn: $selUsingHotKeyAssociates.onChange {
|
||||
mgrPrefs.usingHotKeyAssociates = selUsingHotKeyAssociates
|
||||
PrefMgr.shared.usingHotKeyAssociates = selUsingHotKeyAssociates
|
||||
}
|
||||
)
|
||||
Toggle(
|
||||
LocalizedStringKey("CNS11643 Mode"),
|
||||
isOn: $selUsingHotKeyCNS.onChange {
|
||||
mgrPrefs.usingHotKeyCNS = selUsingHotKeyCNS
|
||||
PrefMgr.shared.usingHotKeyCNS = selUsingHotKeyCNS
|
||||
}
|
||||
)
|
||||
Toggle(
|
||||
LocalizedStringKey("Force KangXi Writing"),
|
||||
isOn: $selUsingHotKeyKangXi.onChange {
|
||||
mgrPrefs.usingHotKeyKangXi = selUsingHotKeyKangXi
|
||||
PrefMgr.shared.usingHotKeyKangXi = selUsingHotKeyKangXi
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -265,19 +265,19 @@ struct suiPrefPaneKeyboard: View {
|
|||
Toggle(
|
||||
LocalizedStringKey("JIS Shinjitai Output"),
|
||||
isOn: $selUsingHotKeyJIS.onChange {
|
||||
mgrPrefs.usingHotKeyJIS = selUsingHotKeyJIS
|
||||
PrefMgr.shared.usingHotKeyJIS = selUsingHotKeyJIS
|
||||
}
|
||||
)
|
||||
Toggle(
|
||||
LocalizedStringKey("Half-Width Punctuation Mode"),
|
||||
isOn: $selUsingHotKeyHalfWidthASCII.onChange {
|
||||
mgrPrefs.usingHotKeyHalfWidthASCII = selUsingHotKeyHalfWidthASCII
|
||||
PrefMgr.shared.usingHotKeyHalfWidthASCII = selUsingHotKeyHalfWidthASCII
|
||||
}
|
||||
)
|
||||
Toggle(
|
||||
LocalizedStringKey("Currency Numeral Output"),
|
||||
isOn: $selUsingHotKeyCurrencyNumerals.onChange {
|
||||
mgrPrefs.usingHotKeyCurrencyNumerals = selUsingHotKeyCurrencyNumerals
|
||||
PrefMgr.shared.usingHotKeyCurrencyNumerals = selUsingHotKeyCurrencyNumerals
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ class ctlClientListMgr: NSWindowController, NSTableViewDelegate, NSTableViewData
|
|||
|
||||
extension ctlClientListMgr {
|
||||
func numberOfRows(in _: NSTableView) -> Int {
|
||||
mgrPrefs.clientsIMKTextInputIncapable.count
|
||||
PrefMgr.shared.clientsIMKTextInputIncapable.count
|
||||
}
|
||||
|
||||
func callAlert(_ window: NSWindow, title: String, text: String? = nil) {
|
||||
|
@ -107,7 +107,7 @@ extension ctlClientListMgr {
|
|||
self.callAlert(window, title: title, text: text)
|
||||
return
|
||||
}
|
||||
if mgrPrefs.clientsIMKTextInputIncapable.contains(identifier) {
|
||||
if PrefMgr.shared.clientsIMKTextInputIncapable.contains(identifier) {
|
||||
title = NSLocalizedString(
|
||||
"The selected item's identifier is already in the list.", comment: ""
|
||||
)
|
||||
|
@ -125,41 +125,41 @@ extension ctlClientListMgr {
|
|||
|
||||
private func applyNewValue(_ newValue: String) {
|
||||
guard !newValue.isEmpty else { return }
|
||||
var arrResult = mgrPrefs.clientsIMKTextInputIncapable
|
||||
var arrResult = PrefMgr.shared.clientsIMKTextInputIncapable
|
||||
arrResult.append(newValue)
|
||||
mgrPrefs.clientsIMKTextInputIncapable = arrResult.sorted()
|
||||
PrefMgr.shared.clientsIMKTextInputIncapable = arrResult.sorted()
|
||||
tblClients.reloadData()
|
||||
btnRemoveClient.isEnabled = (0..<mgrPrefs.clientsIMKTextInputIncapable.count).contains(
|
||||
btnRemoveClient.isEnabled = (0..<PrefMgr.shared.clientsIMKTextInputIncapable.count).contains(
|
||||
tblClients.selectedRow)
|
||||
}
|
||||
|
||||
@IBAction func btnRemoveClientClicked(_: Any) {
|
||||
guard let minIndexSelected = tblClients.selectedRowIndexes.min() else { return }
|
||||
if minIndexSelected >= mgrPrefs.clientsIMKTextInputIncapable.count { return }
|
||||
if minIndexSelected >= PrefMgr.shared.clientsIMKTextInputIncapable.count { return }
|
||||
if minIndexSelected < 0 { return }
|
||||
var isLastRow = false
|
||||
tblClients.selectedRowIndexes.sorted().reversed().forEach { index in
|
||||
isLastRow = {
|
||||
if mgrPrefs.clientsIMKTextInputIncapable.count < 2 { return false }
|
||||
return minIndexSelected == mgrPrefs.clientsIMKTextInputIncapable.count - 1
|
||||
if PrefMgr.shared.clientsIMKTextInputIncapable.count < 2 { return false }
|
||||
return minIndexSelected == PrefMgr.shared.clientsIMKTextInputIncapable.count - 1
|
||||
}()
|
||||
if index < mgrPrefs.clientsIMKTextInputIncapable.count {
|
||||
mgrPrefs.clientsIMKTextInputIncapable.remove(at: index)
|
||||
if index < PrefMgr.shared.clientsIMKTextInputIncapable.count {
|
||||
PrefMgr.shared.clientsIMKTextInputIncapable.remove(at: index)
|
||||
}
|
||||
}
|
||||
if isLastRow {
|
||||
tblClients.selectRowIndexes(.init(arrayLiteral: minIndexSelected - 1), byExtendingSelection: false)
|
||||
}
|
||||
tblClients.reloadData()
|
||||
btnRemoveClient.isEnabled = (0..<mgrPrefs.clientsIMKTextInputIncapable.count).contains(minIndexSelected)
|
||||
btnRemoveClient.isEnabled = (0..<PrefMgr.shared.clientsIMKTextInputIncapable.count).contains(minIndexSelected)
|
||||
}
|
||||
|
||||
func tableView(_: NSTableView, objectValueFor _: NSTableColumn?, row: Int) -> Any? {
|
||||
defer {
|
||||
self.btnRemoveClient.isEnabled = (0..<mgrPrefs.clientsIMKTextInputIncapable.count).contains(
|
||||
self.btnRemoveClient.isEnabled = (0..<PrefMgr.shared.clientsIMKTextInputIncapable.count).contains(
|
||||
self.tblClients.selectedRow)
|
||||
}
|
||||
return mgrPrefs.clientsIMKTextInputIncapable[row]
|
||||
return PrefMgr.shared.clientsIMKTextInputIncapable[row]
|
||||
}
|
||||
|
||||
private func localize() {
|
||||
|
|
|
@ -51,7 +51,7 @@ class ctlPrefWindow: NSWindowController {
|
|||
cmbCandidateFontSize.isEnabled = true
|
||||
|
||||
if #unavailable(macOS 10.14) {
|
||||
if mgrPrefs.useIMKCandidateWindow {
|
||||
if PrefMgr.shared.useIMKCandidateWindow {
|
||||
cmbCandidateFontSize.isEnabled = false
|
||||
}
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ class ctlPrefWindow: NSWindowController {
|
|||
var chosenLanguageItem: NSMenuItem?
|
||||
uiLanguageButton.menu?.removeAllItems()
|
||||
|
||||
let appleLanguages = mgrPrefs.appleLanguages
|
||||
let appleLanguages = PrefMgr.shared.appleLanguages
|
||||
for language in languages {
|
||||
let menuItem = NSMenuItem()
|
||||
menuItem.title = NSLocalizedString(language, comment: language)
|
||||
|
@ -108,7 +108,7 @@ class ctlPrefWindow: NSWindowController {
|
|||
|
||||
basicKeyboardLayoutButton.menu?.removeAllItems()
|
||||
|
||||
let basicKeyboardLayoutID = mgrPrefs.basicKeyboardLayout
|
||||
let basicKeyboardLayoutID = PrefMgr.shared.basicKeyboardLayout
|
||||
|
||||
for source in IMKHelper.allowedBasicLayoutsAsTISInputSources {
|
||||
guard let source = source else {
|
||||
|
@ -129,7 +129,7 @@ class ctlPrefWindow: NSWindowController {
|
|||
selectionKeyComboBox.removeAllItems()
|
||||
selectionKeyComboBox.addItems(withObjectValues: CandidateKey.suggestions)
|
||||
|
||||
var candidateSelectionKeys = mgrPrefs.candidateKeys
|
||||
var candidateSelectionKeys = PrefMgr.shared.candidateKeys
|
||||
if candidateSelectionKeys.isEmpty {
|
||||
candidateSelectionKeys = CandidateKey.defaultKeys
|
||||
}
|
||||
|
@ -140,28 +140,28 @@ class ctlPrefWindow: NSWindowController {
|
|||
// 這裡有必要加上這段處理,用來確保藉由偏好設定介面動過的 CNS 開關能夠立刻生效。
|
||||
// 所有涉及到語言模型開關的內容均需要這樣處理。
|
||||
@IBAction func toggleCNSSupport(_: Any) {
|
||||
LMMgr.setCNSEnabled(mgrPrefs.cns11643Enabled)
|
||||
LMMgr.setCNSEnabled(PrefMgr.shared.cns11643Enabled)
|
||||
}
|
||||
|
||||
@IBAction func toggleSymbolInputEnabled(_: Any) {
|
||||
LMMgr.setSymbolEnabled(mgrPrefs.symbolInputEnabled)
|
||||
LMMgr.setSymbolEnabled(PrefMgr.shared.symbolInputEnabled)
|
||||
}
|
||||
|
||||
@IBAction func toggleTrad2KangXiAction(_: Any) {
|
||||
if chkTrad2KangXi.state == .on, chkTrad2JISShinjitai.state == .on {
|
||||
mgrPrefs.shiftJISShinjitaiOutputEnabled.toggle()
|
||||
PrefMgr.shared.shiftJISShinjitaiOutputEnabled.toggle()
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func toggleTrad2JISShinjitaiAction(_: Any) {
|
||||
if chkTrad2KangXi.state == .on, chkTrad2JISShinjitai.state == .on {
|
||||
mgrPrefs.chineseConversionEnabled.toggle()
|
||||
PrefMgr.shared.chineseConversionEnabled.toggle()
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func updateBasicKeyboardLayoutAction(_: Any) {
|
||||
if let sourceID = basicKeyboardLayoutButton.selectedItem?.representedObject as? String {
|
||||
mgrPrefs.basicKeyboardLayout = sourceID
|
||||
PrefMgr.shared.basicKeyboardLayout = sourceID
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,7 +173,7 @@ class ctlPrefWindow: NSWindowController {
|
|||
}
|
||||
if let language = uiLanguageButton.selectedItem?.representedObject as? String {
|
||||
if language != "auto" {
|
||||
mgrPrefs.appleLanguages = [language]
|
||||
PrefMgr.shared.appleLanguages = [language]
|
||||
} else {
|
||||
UserDefaults.standard.removeObject(forKey: "AppleLanguages")
|
||||
}
|
||||
|
@ -203,15 +203,15 @@ class ctlPrefWindow: NSWindowController {
|
|||
}
|
||||
do {
|
||||
try CandidateKey.validate(keys: keys)
|
||||
mgrPrefs.candidateKeys = keys
|
||||
selectionKeyComboBox.stringValue = mgrPrefs.candidateKeys
|
||||
PrefMgr.shared.candidateKeys = keys
|
||||
selectionKeyComboBox.stringValue = PrefMgr.shared.candidateKeys
|
||||
} catch CandidateKey.ErrorType.empty {
|
||||
selectionKeyComboBox.stringValue = mgrPrefs.candidateKeys
|
||||
selectionKeyComboBox.stringValue = PrefMgr.shared.candidateKeys
|
||||
} catch {
|
||||
if let window = window {
|
||||
let alert = NSAlert(error: error)
|
||||
alert.beginSheetModal(for: window) { _ in
|
||||
self.selectionKeyComboBox.stringValue = mgrPrefs.candidateKeys
|
||||
self.selectionKeyComboBox.stringValue = PrefMgr.shared.candidateKeys
|
||||
}
|
||||
IMEApp.buzz()
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ class ctlPrefWindow: NSWindowController {
|
|||
dlgOpenPath.canChooseDirectories = true
|
||||
|
||||
let bolPreviousFolderValidity = LMMgr.checkIfSpecifiedUserDataFolderValid(
|
||||
mgrPrefs.userDataFolderSpecified.expandingTildeInPath)
|
||||
PrefMgr.shared.userDataFolderSpecified.expandingTildeInPath)
|
||||
|
||||
dlgOpenPath.beginSheetModal(for: window) { result in
|
||||
if result == NSApplication.ModalResponse.OK {
|
||||
|
@ -244,7 +244,7 @@ class ctlPrefWindow: NSWindowController {
|
|||
var newPath = url.path
|
||||
newPath.ensureTrailingSlash()
|
||||
if LMMgr.checkIfSpecifiedUserDataFolderValid(newPath) {
|
||||
mgrPrefs.userDataFolderSpecified = newPath
|
||||
PrefMgr.shared.userDataFolderSpecified = newPath
|
||||
BookmarkManager.shared.saveBookmark(for: url)
|
||||
(NSApplication.shared.delegate as! AppDelegate).updateDirectoryMonitorPath()
|
||||
} else {
|
||||
|
|
|
@ -28,7 +28,7 @@ class ctlInputMethod: IMKInputController {
|
|||
|
||||
/// 目前在用的的選字窗副本。
|
||||
static var ctlCandidateCurrent: ctlCandidateProtocol =
|
||||
mgrPrefs.useIMKCandidateWindow ? ctlCandidateIMK.init(.horizontal) : ctlCandidateUniversal.init(.horizontal)
|
||||
PrefMgr.shared.useIMKCandidateWindow ? ctlCandidateIMK.init(.horizontal) : ctlCandidateUniversal.init(.horizontal)
|
||||
|
||||
/// 工具提示視窗的共用副本。
|
||||
static var tooltipInstance = ctlTooltip()
|
||||
|
@ -41,7 +41,7 @@ class ctlInputMethod: IMKInputController {
|
|||
/// 當前這個 ctlInputMethod 副本是否處於英數輸入模式。
|
||||
var isASCIIMode = false { didSet { setKeyLayout() } }
|
||||
/// 按鍵調度模組的副本。
|
||||
var keyHandler: KeyHandler = .init(lm: LMMgr.currentLM(), uom: LMMgr.currentUOM())
|
||||
var keyHandler = KeyHandler(lm: LMMgr.currentLM(), uom: LMMgr.currentUOM(), pref: PrefMgr.shared)
|
||||
/// 用以記錄當前輸入法狀態的變數。
|
||||
var state: IMEStateProtocol = IMEState.ofEmpty() {
|
||||
didSet {
|
||||
|
@ -51,7 +51,7 @@ class ctlInputMethod: IMKInputController {
|
|||
|
||||
/// Shift 按鍵事件分析器的副本。
|
||||
/// - Remark: 警告:該工具必須為 Struct 且全專案只能有一個唯一初期化副本。否則會在動 CapsLock 的時候誤以為是在摁 Shift。
|
||||
static var theShiftKeyDetector = ShiftKeyUpChecker(useLShift: mgrPrefs.togglingAlphanumericalModeWithLShift)
|
||||
static var theShiftKeyDetector = ShiftKeyUpChecker(useLShift: PrefMgr.shared.togglingAlphanumericalModeWithLShift)
|
||||
|
||||
/// 切換當前 ctlInputMethod 副本的英數輸入模式開關。
|
||||
func toggleASCIIMode() -> Bool {
|
||||
|
@ -82,20 +82,20 @@ class ctlInputMethod: IMKInputController {
|
|||
func setKeyLayout() {
|
||||
guard let client = client() else { return }
|
||||
if isASCIIMode, IMKHelper.isDynamicBasicKeyboardLayoutEnabled {
|
||||
client.overrideKeyboard(withKeyboardNamed: mgrPrefs.alphanumericalKeyboardLayout)
|
||||
client.overrideKeyboard(withKeyboardNamed: PrefMgr.shared.alphanumericalKeyboardLayout)
|
||||
return
|
||||
}
|
||||
client.overrideKeyboard(withKeyboardNamed: mgrPrefs.basicKeyboardLayout)
|
||||
client.overrideKeyboard(withKeyboardNamed: PrefMgr.shared.basicKeyboardLayout)
|
||||
}
|
||||
|
||||
/// 重設按鍵調度模組,會將當前尚未遞交的內容遞交出去。
|
||||
func resetKeyHandler() {
|
||||
// 過濾掉尚未完成拼寫的注音。
|
||||
if state.type == .ofInputting, mgrPrefs.trimUnfinishedReadingsOnCommit {
|
||||
if state.type == .ofInputting, PrefMgr.shared.trimUnfinishedReadingsOnCommit {
|
||||
keyHandler.composer.clear()
|
||||
handle(state: keyHandler.buildInputtingState)
|
||||
}
|
||||
let isSecureMode = mgrPrefs.clientsIMKTextInputIncapable.contains(clientBundleIdentifier)
|
||||
let isSecureMode = PrefMgr.shared.clientsIMKTextInputIncapable.contains(clientBundleIdentifier)
|
||||
if state.hasComposition, !isSecureMode {
|
||||
/// 將傳回的新狀態交給調度函式。
|
||||
handle(state: IMEState.ofCommitting(textToCommit: state.displayedText))
|
||||
|
@ -137,7 +137,7 @@ class ctlInputMethod: IMKInputController {
|
|||
keyHandler.clear() // 這句不要砍,因為後面 handle State.Empty() 不一定執行。
|
||||
keyHandler.ensureKeyboardParser()
|
||||
|
||||
if isASCIIMode, mgrPrefs.disableShiftTogglingAlphanumericalMode { isASCIIMode = false }
|
||||
if isASCIIMode, PrefMgr.shared.disableShiftTogglingAlphanumericalMode { isASCIIMode = false }
|
||||
|
||||
/// 必須加上下述條件,否則會在每次切換至輸入法本體的視窗(比如偏好設定視窗)時會卡死。
|
||||
/// 這是很多 macOS 副廠輸入法的常見失誤之處。
|
||||
|
@ -199,7 +199,7 @@ class ctlInputMethod: IMKInputController {
|
|||
willSet {
|
||||
/// 將新的簡繁輸入模式提報給 Prefs 與 IME 模組。
|
||||
IMEApp.currentInputMode = newValue
|
||||
mgrPrefs.mostRecentInputMode = IMEApp.currentInputMode.rawValue
|
||||
PrefMgr.shared.mostRecentInputMode = IMEApp.currentInputMode.rawValue
|
||||
}
|
||||
didSet {
|
||||
/// 重設所有語言模組。這裡不需要做按需重設,因為對運算量沒有影響。
|
||||
|
@ -214,11 +214,11 @@ class ctlInputMethod: IMKInputController {
|
|||
|
||||
/// 將輸入法偏好設定同步至語言模組內。
|
||||
func syncBaseLMPrefs() {
|
||||
LMMgr.currentLM().isPhraseReplacementEnabled = mgrPrefs.phraseReplacementEnabled
|
||||
LMMgr.currentLM().isCNSEnabled = mgrPrefs.cns11643Enabled
|
||||
LMMgr.currentLM().isSymbolEnabled = mgrPrefs.symbolInputEnabled
|
||||
LMMgr.currentLM().isSCPCEnabled = mgrPrefs.useSCPCTypingMode
|
||||
LMMgr.currentLM().deltaOfCalendarYears = mgrPrefs.deltaOfCalendarYears
|
||||
LMMgr.currentLM().isPhraseReplacementEnabled = PrefMgr.shared.phraseReplacementEnabled
|
||||
LMMgr.currentLM().isCNSEnabled = PrefMgr.shared.cns11643Enabled
|
||||
LMMgr.currentLM().isSymbolEnabled = PrefMgr.shared.symbolInputEnabled
|
||||
LMMgr.currentLM().isSCPCEnabled = PrefMgr.shared.useSCPCTypingMode
|
||||
LMMgr.currentLM().deltaOfCalendarYears = PrefMgr.shared.deltaOfCalendarYears
|
||||
}
|
||||
|
||||
// MARK: - IMKServerInput 協定規定的方法
|
||||
|
@ -261,7 +261,7 @@ class ctlInputMethod: IMKInputController {
|
|||
|
||||
// 用 Shift 開關半形英數模式,僅對 macOS 10.15 及之後的 macOS 有效。
|
||||
let shouldUseShiftToggleHandle: Bool = {
|
||||
switch mgrPrefs.shiftKeyAccommodationBehavior {
|
||||
switch PrefMgr.shared.shiftKeyAccommodationBehavior {
|
||||
case 0: return false
|
||||
case 1: return Shared.arrClientShiftHandlingExceptionList.contains(clientBundleIdentifier)
|
||||
case 2: return true
|
||||
|
@ -271,7 +271,7 @@ class ctlInputMethod: IMKInputController {
|
|||
|
||||
/// 警告:這裡的 event 必須是原始 event 且不能被 var,否則會影響 Shift 中英模式判定。
|
||||
if #available(macOS 10.15, *) {
|
||||
if Self.theShiftKeyDetector.check(event), !mgrPrefs.disableShiftTogglingAlphanumericalMode {
|
||||
if Self.theShiftKeyDetector.check(event), !PrefMgr.shared.disableShiftTogglingAlphanumericalMode {
|
||||
if !shouldUseShiftToggleHandle || (!rencentKeyHandledByKeyHandlerEtc && shouldUseShiftToggleHandle) {
|
||||
NotifierController.notify(
|
||||
message: toggleASCIIMode()
|
||||
|
@ -375,7 +375,7 @@ class ctlInputMethod: IMKInputController {
|
|||
var result = (theCandidate.1 == theConverted) ? theCandidate.1 : "\(theConverted)\u{1A}(\(theCandidate.1))"
|
||||
if arrResult.contains(result) {
|
||||
let reading: String =
|
||||
mgrPrefs.showHanyuPinyinInCompositionBuffer
|
||||
PrefMgr.shared.showHanyuPinyinInCompositionBuffer
|
||||
? Tekkon.cnvPhonaToHanyuPinyin(target: Tekkon.restoreToneOneInZhuyinKey(target: theCandidate.0))
|
||||
: theCandidate.0
|
||||
result = "\(result)\u{17}(\(reading))"
|
||||
|
@ -423,7 +423,7 @@ class ctlInputMethod: IMKInputController {
|
|||
override open func candidateSelected(_ candidateString: NSAttributedString!) {
|
||||
let candidateString: String = candidateString?.string ?? ""
|
||||
if state.type == .ofAssociates {
|
||||
if !mgrPrefs.alsoConfirmAssociatedCandidatesByEnter {
|
||||
if !PrefMgr.shared.alsoConfirmAssociatedCandidatesByEnter {
|
||||
handle(state: IMEState.ofAbortion())
|
||||
return
|
||||
}
|
||||
|
@ -437,7 +437,7 @@ class ctlInputMethod: IMKInputController {
|
|||
let theConverted = ChineseConverter.kanjiConversionIfRequired(neta.1)
|
||||
let netaShown = (neta.1 == theConverted) ? neta.1 : "\(theConverted)\u{1A}(\(neta.1))"
|
||||
let reading: String =
|
||||
mgrPrefs.showHanyuPinyinInCompositionBuffer
|
||||
PrefMgr.shared.showHanyuPinyinInCompositionBuffer
|
||||
? Tekkon.cnvPhonaToHanyuPinyin(target: Tekkon.restoreToneOneInZhuyinKey(target: neta.0)) : neta.0
|
||||
let netaShownWithPronunciation = "\(netaShown)\u{17}(\(reading))"
|
||||
if candidateString == prefix + netaShownWithPronunciation {
|
||||
|
|
|
@ -106,15 +106,15 @@ extension ctlInputMethod: ctlCandidateDelegate {
|
|||
let selectedValue = state.candidates[index]
|
||||
keyHandler.fixNode(
|
||||
candidate: selectedValue, respectCursorPushing: true,
|
||||
preConsolidate: mgrPrefs.consolidateContextOnCandidateSelection
|
||||
preConsolidate: PrefMgr.shared.consolidateContextOnCandidateSelection
|
||||
)
|
||||
|
||||
let inputting = keyHandler.buildInputtingState
|
||||
|
||||
if mgrPrefs.useSCPCTypingMode {
|
||||
if PrefMgr.shared.useSCPCTypingMode {
|
||||
handle(state: IMEState.ofCommitting(textToCommit: inputting.displayedText))
|
||||
// 此時是逐字選字模式,所以「selectedValue.1」是單個字、不用追加處理。
|
||||
if mgrPrefs.associatedPhrasesEnabled {
|
||||
if PrefMgr.shared.associatedPhrasesEnabled {
|
||||
let associates = keyHandler.buildAssociatePhraseState(
|
||||
withPair: .init(key: selectedValue.0, value: selectedValue.1)
|
||||
)
|
||||
|
@ -137,7 +137,7 @@ extension ctlInputMethod: ctlCandidateDelegate {
|
|||
handle(state: IMEState.ofEmpty())
|
||||
return
|
||||
}
|
||||
if mgrPrefs.associatedPhrasesEnabled {
|
||||
if PrefMgr.shared.associatedPhrasesEnabled {
|
||||
let associates = keyHandler.buildAssociatePhraseState(
|
||||
withPair: .init(key: selectedValue.0, value: String(valueKept))
|
||||
)
|
||||
|
|
|
@ -18,7 +18,7 @@ extension ctlInputMethod {
|
|||
// 對此類 App 有疑慮者,可以將這類 App 登記到客體管理員當中。
|
||||
// 這樣,不但強制使用(限制讀音 20 個的)浮動組字窗,而且內文組字區只會顯示一個空格。
|
||||
var attributedStringSecured: (NSAttributedString, NSRange) {
|
||||
mgrPrefs.clientsIMKTextInputIncapable.contains(clientBundleIdentifier)
|
||||
PrefMgr.shared.clientsIMKTextInputIncapable.contains(clientBundleIdentifier)
|
||||
? (state.data.attributedStringPlaceholder, NSRange(location: 0, length: 0))
|
||||
: (state.attributedString, NSRange(state.data.u16MarkedRange))
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ extension ctlInputMethod {
|
|||
)
|
||||
}
|
||||
let tooltipContentDirection: NSAttributedTextView.writingDirection = {
|
||||
if mgrPrefs.alwaysShowTooltipTextsHorizontally { return .horizontal }
|
||||
if PrefMgr.shared.alwaysShowTooltipTextsHorizontally { return .horizontal }
|
||||
return isVerticalTyping ? .vertical : .horizontal
|
||||
}()
|
||||
// 強制重新初期化,因為 NSAttributedTextView 有顯示滯後性。
|
||||
|
@ -88,13 +88,13 @@ extension ctlInputMethod {
|
|||
// 因為在拿候選字陣列時已經排序過了,所以這裡不用再多排序。
|
||||
// 測量每頁顯示候選字的累計總長度。如果太長的話就強制使用縱排候選字窗。
|
||||
// 範例:「屬實牛逼」(會有一大串各種各樣的「鼠食牛Beer」的 emoji)。
|
||||
let maxCandidatesPerPage = mgrPrefs.candidateKeys.count
|
||||
let maxCandidatesPerPage = PrefMgr.shared.candidateKeys.count
|
||||
let firstPageCandidates = candidates[0..<min(maxCandidatesPerPage, candidates.count)].map(\.1)
|
||||
return firstPageCandidates.joined().count > Int(round(Double(maxCandidatesPerPage) * 1.8))
|
||||
// 上面這句如果是 true 的話,就會是縱排;反之則為橫排。
|
||||
}
|
||||
|
||||
state.isVerticalCandidateWindow = (isCandidateWindowVertical || !mgrPrefs.useHorizontalCandidateList)
|
||||
state.isVerticalCandidateWindow = (isCandidateWindowVertical || !PrefMgr.shared.useHorizontalCandidateList)
|
||||
|
||||
ctlInputMethod.ctlCandidateCurrent.delegate = nil
|
||||
|
||||
|
@ -105,16 +105,16 @@ extension ctlInputMethod {
|
|||
/// 該問題徹底解決的價值並不大,直接等到 macOS 10.x 全線淘汰之後用 SwiftUI 重寫選字窗吧。
|
||||
|
||||
let candidateLayout: CandidateLayout =
|
||||
((isCandidateWindowVertical || !mgrPrefs.useHorizontalCandidateList)
|
||||
((isCandidateWindowVertical || !PrefMgr.shared.useHorizontalCandidateList)
|
||||
? CandidateLayout.vertical
|
||||
: CandidateLayout.horizontal)
|
||||
|
||||
ctlInputMethod.ctlCandidateCurrent =
|
||||
mgrPrefs.useIMKCandidateWindow
|
||||
PrefMgr.shared.useIMKCandidateWindow
|
||||
? ctlCandidateIMK.init(candidateLayout) : ctlCandidateUniversal.init(candidateLayout)
|
||||
|
||||
// set the attributes for the candidate panel (which uses NSAttributedString)
|
||||
let textSize = mgrPrefs.candidateListTextSize
|
||||
let textSize = PrefMgr.shared.candidateListTextSize
|
||||
let minimumKeyLabelSize: Double = 10
|
||||
let keyLabelSize = max(textSize / 2, minimumKeyLabelSize)
|
||||
|
||||
|
@ -126,13 +126,13 @@ extension ctlInputMethod {
|
|||
}
|
||||
|
||||
ctlInputMethod.ctlCandidateCurrent.keyLabelFont = labelFont(
|
||||
name: mgrPrefs.candidateKeyLabelFontName, size: keyLabelSize
|
||||
name: PrefMgr.shared.candidateKeyLabelFontName, size: keyLabelSize
|
||||
)
|
||||
ctlInputMethod.ctlCandidateCurrent.candidateFont = ctlInputMethod.candidateFont(
|
||||
name: mgrPrefs.candidateTextFontName, size: textSize
|
||||
name: PrefMgr.shared.candidateTextFontName, size: textSize
|
||||
)
|
||||
|
||||
let candidateKeys = mgrPrefs.candidateKeys
|
||||
let candidateKeys = PrefMgr.shared.candidateKeys
|
||||
let keyLabels =
|
||||
candidateKeys.count > 4 ? Array(candidateKeys) : Array(CandidateKey.defaultKeys)
|
||||
let keyLabelSuffix = state.type == .ofAssociates ? "^" : ""
|
||||
|
@ -195,7 +195,7 @@ extension ctlInputMethod {
|
|||
case InputMode.imeModeCHS:
|
||||
return CTFontCreateUIFontForLanguage(.system, size, "zh-Hans" as CFString)
|
||||
case InputMode.imeModeCHT:
|
||||
return (mgrPrefs.shiftJISShinjitaiOutputEnabled || mgrPrefs.chineseConversionEnabled)
|
||||
return (PrefMgr.shared.shiftJISShinjitaiOutputEnabled || PrefMgr.shared.chineseConversionEnabled)
|
||||
? CTFontCreateUIFontForLanguage(.system, size, "ja" as CFString)
|
||||
: CTFontCreateUIFontForLanguage(.system, size, "zh-Hant" as CFString)
|
||||
default:
|
||||
|
|
|
@ -80,7 +80,7 @@ extension ctlInputMethod {
|
|||
default: break
|
||||
}
|
||||
// 浮動組字窗的顯示判定
|
||||
if state.hasComposition, mgrPrefs.clientsIMKTextInputIncapable.contains(clientBundleIdentifier) {
|
||||
if state.hasComposition, PrefMgr.shared.clientsIMKTextInputIncapable.contains(clientBundleIdentifier) {
|
||||
ctlInputMethod.popupCompositionBuffer.isTypingDirectionVertical = isVerticalTyping
|
||||
ctlInputMethod.popupCompositionBuffer.show(
|
||||
state: state, at: lineHeightRect(zeroCursor: true).origin
|
||||
|
|
|
@ -28,61 +28,64 @@ extension ctlInputMethod {
|
|||
|
||||
let useSCPCTypingModeItem = menu.addItem(
|
||||
withTitle: NSLocalizedString("Per-Char Select Mode", comment: ""),
|
||||
action: #selector(toggleSCPCTypingMode(_:)), keyEquivalent: mgrPrefs.usingHotKeySCPC ? "P" : ""
|
||||
action: #selector(toggleSCPCTypingMode(_:)), keyEquivalent: PrefMgr.shared.usingHotKeySCPC ? "P" : ""
|
||||
)
|
||||
useSCPCTypingModeItem.keyEquivalentModifierMask = [.command, .control]
|
||||
useSCPCTypingModeItem.state = mgrPrefs.useSCPCTypingMode.state
|
||||
useSCPCTypingModeItem.state = PrefMgr.shared.useSCPCTypingMode.state
|
||||
|
||||
let userAssociatedPhrasesItem = menu.addItem(
|
||||
withTitle: NSLocalizedString("Per-Char Associated Phrases", comment: ""),
|
||||
action: #selector(toggleAssociatedPhrasesEnabled(_:)), keyEquivalent: mgrPrefs.usingHotKeyAssociates ? "O" : ""
|
||||
action: #selector(toggleAssociatedPhrasesEnabled(_:)),
|
||||
keyEquivalent: PrefMgr.shared.usingHotKeyAssociates ? "O" : ""
|
||||
)
|
||||
userAssociatedPhrasesItem.keyEquivalentModifierMask = [.command, .control]
|
||||
userAssociatedPhrasesItem.state = mgrPrefs.associatedPhrasesEnabled.state
|
||||
userAssociatedPhrasesItem.state = PrefMgr.shared.associatedPhrasesEnabled.state
|
||||
|
||||
let useCNS11643SupportItem = menu.addItem(
|
||||
withTitle: NSLocalizedString("CNS11643 Mode", comment: ""),
|
||||
action: #selector(toggleCNS11643Enabled(_:)), keyEquivalent: mgrPrefs.usingHotKeyCNS ? "L" : ""
|
||||
action: #selector(toggleCNS11643Enabled(_:)), keyEquivalent: PrefMgr.shared.usingHotKeyCNS ? "L" : ""
|
||||
)
|
||||
useCNS11643SupportItem.keyEquivalentModifierMask = [.command, .control]
|
||||
useCNS11643SupportItem.state = mgrPrefs.cns11643Enabled.state
|
||||
useCNS11643SupportItem.state = PrefMgr.shared.cns11643Enabled.state
|
||||
|
||||
if IMEApp.currentInputMode == InputMode.imeModeCHT {
|
||||
let chineseConversionItem = menu.addItem(
|
||||
withTitle: NSLocalizedString("Force KangXi Writing", comment: ""),
|
||||
action: #selector(toggleChineseConverter(_:)), keyEquivalent: mgrPrefs.usingHotKeyKangXi ? "K" : ""
|
||||
action: #selector(toggleChineseConverter(_:)), keyEquivalent: PrefMgr.shared.usingHotKeyKangXi ? "K" : ""
|
||||
)
|
||||
chineseConversionItem.keyEquivalentModifierMask = [.command, .control]
|
||||
chineseConversionItem.state = mgrPrefs.chineseConversionEnabled.state
|
||||
chineseConversionItem.state = PrefMgr.shared.chineseConversionEnabled.state
|
||||
|
||||
let shiftJISConversionItem = menu.addItem(
|
||||
withTitle: NSLocalizedString("JIS Shinjitai Output", comment: ""),
|
||||
action: #selector(toggleShiftJISShinjitaiOutput(_:)), keyEquivalent: mgrPrefs.usingHotKeyJIS ? "J" : ""
|
||||
action: #selector(toggleShiftJISShinjitaiOutput(_:)), keyEquivalent: PrefMgr.shared.usingHotKeyJIS ? "J" : ""
|
||||
)
|
||||
shiftJISConversionItem.keyEquivalentModifierMask = [.command, .control]
|
||||
shiftJISConversionItem.state = mgrPrefs.shiftJISShinjitaiOutputEnabled.state
|
||||
shiftJISConversionItem.state = PrefMgr.shared.shiftJISShinjitaiOutputEnabled.state
|
||||
}
|
||||
|
||||
let currencyNumeralsItem = menu.addItem(
|
||||
withTitle: NSLocalizedString("Currency Numeral Output", comment: ""),
|
||||
action: #selector(toggleCurrencyNumerals(_:)), keyEquivalent: mgrPrefs.usingHotKeyCurrencyNumerals ? "M" : ""
|
||||
action: #selector(toggleCurrencyNumerals(_:)),
|
||||
keyEquivalent: PrefMgr.shared.usingHotKeyCurrencyNumerals ? "M" : ""
|
||||
)
|
||||
currencyNumeralsItem.keyEquivalentModifierMask = [.command, .control]
|
||||
currencyNumeralsItem.state = mgrPrefs.currencyNumeralsEnabled.state
|
||||
currencyNumeralsItem.state = PrefMgr.shared.currencyNumeralsEnabled.state
|
||||
|
||||
let halfWidthPunctuationItem = menu.addItem(
|
||||
withTitle: NSLocalizedString("Half-Width Punctuation Mode", comment: ""),
|
||||
action: #selector(toggleHalfWidthPunctuation(_:)), keyEquivalent: mgrPrefs.usingHotKeyHalfWidthASCII ? "H" : ""
|
||||
action: #selector(toggleHalfWidthPunctuation(_:)),
|
||||
keyEquivalent: PrefMgr.shared.usingHotKeyHalfWidthASCII ? "H" : ""
|
||||
)
|
||||
halfWidthPunctuationItem.keyEquivalentModifierMask = [.command, .control]
|
||||
halfWidthPunctuationItem.state = mgrPrefs.halfWidthPunctuationEnabled.state
|
||||
halfWidthPunctuationItem.state = PrefMgr.shared.halfWidthPunctuationEnabled.state
|
||||
|
||||
if optionKeyPressed || mgrPrefs.phraseReplacementEnabled {
|
||||
if optionKeyPressed || PrefMgr.shared.phraseReplacementEnabled {
|
||||
let phaseReplacementItem = menu.addItem(
|
||||
withTitle: NSLocalizedString("Use Phrase Replacement", comment: ""),
|
||||
action: #selector(togglePhraseReplacement(_:)), keyEquivalent: ""
|
||||
)
|
||||
phaseReplacementItem.state = mgrPrefs.phraseReplacementEnabled.state
|
||||
phaseReplacementItem.state = PrefMgr.shared.phraseReplacementEnabled.state
|
||||
}
|
||||
|
||||
if optionKeyPressed {
|
||||
|
@ -90,7 +93,7 @@ extension ctlInputMethod {
|
|||
withTitle: NSLocalizedString("Symbol & Emoji Input", comment: ""),
|
||||
action: #selector(toggleSymbolEnabled(_:)), keyEquivalent: ""
|
||||
)
|
||||
toggleSymbolInputItem.state = mgrPrefs.symbolInputEnabled.state
|
||||
toggleSymbolInputItem.state = PrefMgr.shared.symbolInputEnabled.state
|
||||
}
|
||||
|
||||
menu.addItem(NSMenuItem.separator()) // ---------------------
|
||||
|
@ -108,7 +111,7 @@ extension ctlInputMethod {
|
|||
action: #selector(openExcludedPhrases(_:)), keyEquivalent: ""
|
||||
)
|
||||
|
||||
if optionKeyPressed || mgrPrefs.associatedPhrasesEnabled {
|
||||
if optionKeyPressed || PrefMgr.shared.associatedPhrasesEnabled {
|
||||
menu.addItem(
|
||||
withTitle: NSLocalizedString("Edit Associated Phrases…", comment: ""),
|
||||
action: #selector(openAssociatedPhrases(_:)), keyEquivalent: ""
|
||||
|
@ -126,7 +129,7 @@ extension ctlInputMethod {
|
|||
)
|
||||
}
|
||||
|
||||
if optionKeyPressed || !mgrPrefs.shouldAutoReloadUserDataFiles {
|
||||
if optionKeyPressed || !PrefMgr.shared.shouldAutoReloadUserDataFiles {
|
||||
menu.addItem(
|
||||
withTitle: NSLocalizedString("Reload User Phrases", comment: ""),
|
||||
action: #selector(reloadUserPhrasesData(_:)), keyEquivalent: ""
|
||||
|
@ -222,7 +225,7 @@ extension ctlInputMethod {
|
|||
resetKeyHandler()
|
||||
NotifierController.notify(
|
||||
message: NSLocalizedString("Per-Char Select Mode", comment: "") + "\n"
|
||||
+ (mgrPrefs.useSCPCTypingMode.toggled()
|
||||
+ (PrefMgr.shared.useSCPCTypingMode.toggled()
|
||||
? NSLocalizedString("NotificationSwitchON", comment: "")
|
||||
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
|
||||
)
|
||||
|
@ -232,7 +235,7 @@ extension ctlInputMethod {
|
|||
resetKeyHandler()
|
||||
NotifierController.notify(
|
||||
message: NSLocalizedString("Force KangXi Writing", comment: "") + "\n"
|
||||
+ (mgrPrefs.chineseConversionEnabled.toggled()
|
||||
+ (PrefMgr.shared.chineseConversionEnabled.toggled()
|
||||
? NSLocalizedString("NotificationSwitchON", comment: "")
|
||||
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
|
||||
)
|
||||
|
@ -242,7 +245,7 @@ extension ctlInputMethod {
|
|||
resetKeyHandler()
|
||||
NotifierController.notify(
|
||||
message: NSLocalizedString("JIS Shinjitai Output", comment: "") + "\n"
|
||||
+ (mgrPrefs.shiftJISShinjitaiOutputEnabled.toggled()
|
||||
+ (PrefMgr.shared.shiftJISShinjitaiOutputEnabled.toggled()
|
||||
? NSLocalizedString("NotificationSwitchON", comment: "")
|
||||
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
|
||||
)
|
||||
|
@ -252,7 +255,7 @@ extension ctlInputMethod {
|
|||
resetKeyHandler()
|
||||
NotifierController.notify(
|
||||
message: NSLocalizedString("Currency Numeral Output", comment: "") + "\n"
|
||||
+ (mgrPrefs.currencyNumeralsEnabled.toggled()
|
||||
+ (PrefMgr.shared.currencyNumeralsEnabled.toggled()
|
||||
? NSLocalizedString("NotificationSwitchON", comment: "")
|
||||
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
|
||||
)
|
||||
|
@ -262,7 +265,7 @@ extension ctlInputMethod {
|
|||
resetKeyHandler()
|
||||
NotifierController.notify(
|
||||
message: NSLocalizedString("Half-Width Punctuation Mode", comment: "") + "\n"
|
||||
+ (mgrPrefs.halfWidthPunctuationEnabled.toggled()
|
||||
+ (PrefMgr.shared.halfWidthPunctuationEnabled.toggled()
|
||||
? NSLocalizedString("NotificationSwitchON", comment: "")
|
||||
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
|
||||
)
|
||||
|
@ -272,7 +275,7 @@ extension ctlInputMethod {
|
|||
resetKeyHandler()
|
||||
NotifierController.notify(
|
||||
message: NSLocalizedString("CNS11643 Mode", comment: "") + "\n"
|
||||
+ (mgrPrefs.cns11643Enabled.toggled()
|
||||
+ (PrefMgr.shared.cns11643Enabled.toggled()
|
||||
? NSLocalizedString("NotificationSwitchON", comment: "")
|
||||
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
|
||||
)
|
||||
|
@ -282,7 +285,7 @@ extension ctlInputMethod {
|
|||
resetKeyHandler()
|
||||
NotifierController.notify(
|
||||
message: NSLocalizedString("Symbol & Emoji Input", comment: "") + "\n"
|
||||
+ (mgrPrefs.symbolInputEnabled.toggled()
|
||||
+ (PrefMgr.shared.symbolInputEnabled.toggled()
|
||||
? NSLocalizedString("NotificationSwitchON", comment: "")
|
||||
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
|
||||
)
|
||||
|
@ -292,7 +295,7 @@ extension ctlInputMethod {
|
|||
resetKeyHandler()
|
||||
NotifierController.notify(
|
||||
message: NSLocalizedString("Per-Char Associated Phrases", comment: "") + "\n"
|
||||
+ (mgrPrefs.associatedPhrasesEnabled.toggled()
|
||||
+ (PrefMgr.shared.associatedPhrasesEnabled.toggled()
|
||||
? NSLocalizedString("NotificationSwitchON", comment: "")
|
||||
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
|
||||
)
|
||||
|
@ -302,7 +305,7 @@ extension ctlInputMethod {
|
|||
resetKeyHandler()
|
||||
NotifierController.notify(
|
||||
message: NSLocalizedString("Use Phrase Replacement", comment: "") + "\n"
|
||||
+ (mgrPrefs.phraseReplacementEnabled.toggled()
|
||||
+ (PrefMgr.shared.phraseReplacementEnabled.toggled()
|
||||
? NSLocalizedString("NotificationSwitchON", comment: "")
|
||||
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
|
||||
)
|
||||
|
|
|
@ -94,10 +94,10 @@ public enum InputMode: String, CaseIterable {
|
|||
public enum IMEApp {
|
||||
// MARK: - 輸入法的當前的簡繁體中文模式
|
||||
|
||||
public static var currentInputMode: InputMode = .init(rawValue: mgrPrefs.mostRecentInputMode) ?? .imeModeNULL
|
||||
public static var currentInputMode: InputMode = .init(rawValue: PrefMgr.shared.mostRecentInputMode) ?? .imeModeNULL
|
||||
|
||||
/// Fart or Beep?
|
||||
static func buzz() {
|
||||
NSSound.buzz(fart: !mgrPrefs.shouldNotFartInLieuOfBeep)
|
||||
NSSound.buzz(fart: !PrefMgr.shared.shouldNotFartInLieuOfBeep)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue