diff --git a/Packages/vChewing_MainAssembly/Sources/MainAssembly/AboutUI/CtlAboutUI.swift b/Packages/vChewing_MainAssembly/Sources/MainAssembly/AboutUI/CtlAboutUI.swift index 3f9713f5..dc942bfb 100644 --- a/Packages/vChewing_MainAssembly/Sources/MainAssembly/AboutUI/CtlAboutUI.swift +++ b/Packages/vChewing_MainAssembly/Sources/MainAssembly/AboutUI/CtlAboutUI.swift @@ -7,6 +7,7 @@ // requirements defined in MIT License. import AppKit +import Shared import SwiftUI public class CtlAboutUI: NSWindowController, NSWindowDelegate { diff --git a/Packages/vChewing_MainAssembly/Sources/MainAssembly/AboutUI/VwrAboutUI.swift b/Packages/vChewing_MainAssembly/Sources/MainAssembly/AboutUI/VwrAboutUI.swift index 92d9c81a..860b805c 100644 --- a/Packages/vChewing_MainAssembly/Sources/MainAssembly/AboutUI/VwrAboutUI.swift +++ b/Packages/vChewing_MainAssembly/Sources/MainAssembly/AboutUI/VwrAboutUI.swift @@ -7,6 +7,7 @@ // requirements defined in MIT License. import AppKit +import Shared import SwiftUI public struct VwrAboutUI { diff --git a/Packages/vChewing_MainAssembly/Sources/MainAssembly/ChineseConverterBridge.swift b/Packages/vChewing_MainAssembly/Sources/MainAssembly/ChineseConverterBridge.swift index 0ae4702b..eb522ddf 100644 --- a/Packages/vChewing_MainAssembly/Sources/MainAssembly/ChineseConverterBridge.swift +++ b/Packages/vChewing_MainAssembly/Sources/MainAssembly/ChineseConverterBridge.swift @@ -7,6 +7,7 @@ // requirements defined in MIT License. import Hotenka +import Shared public enum ChineseConverter { public static let shared = HotenkaChineseConverter( diff --git a/Packages/vChewing_MainAssembly/Sources/MainAssembly/InputHandler/InputHandler_TypingMethod.swift b/Packages/vChewing_MainAssembly/Sources/MainAssembly/InputHandler/InputHandler_TypingMethod.swift index bf0d97c5..47e29340 100644 --- a/Packages/vChewing_MainAssembly/Sources/MainAssembly/InputHandler/InputHandler_TypingMethod.swift +++ b/Packages/vChewing_MainAssembly/Sources/MainAssembly/InputHandler/InputHandler_TypingMethod.swift @@ -7,6 +7,7 @@ // requirements defined in MIT License. import Foundation +import Shared import SwiftExtension // MARK: - Typing Method diff --git a/Packages/vChewing_MainAssembly/Sources/MainAssembly/PrefMgr_Singleton.swift b/Packages/vChewing_MainAssembly/Sources/MainAssembly/PrefMgr_Singleton.swift new file mode 100644 index 00000000..0ed65518 --- /dev/null +++ b/Packages/vChewing_MainAssembly/Sources/MainAssembly/PrefMgr_Singleton.swift @@ -0,0 +1,36 @@ +// (c) 2021 and onwards The vChewing Project (MIT-NTL License). +// ==================== +// This code is released under the MIT license (SPDX-License-Identifier: MIT) +// ... with NTL restriction stating that: +// 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 defined in MIT License. + +import Shared + +public extension PrefMgr { + static let shared: PrefMgr = { + let result = PrefMgr() + result.assignDidSetActions() + return result + }() + + private func assignDidSetActions() { + didAskForSyncingLMPrefs = { + if PrefMgr.shared.phraseReplacementEnabled { + LMMgr.loadUserPhraseReplacement() + } + if PrefMgr.shared.associatedPhrasesEnabled { + LMMgr.loadUserAssociatesData() + } + LMMgr.syncLMPrefs() + } + didAskForRefreshingSpeechSputnik = { + SpeechSputnik.shared.refreshStatus() + } + didAskForSyncingShiftKeyDetectorPrefs = { + SessionCtl.theShiftKeyDetector.toggleWithLShift = PrefMgr.shared.togglingAlphanumericalModeWithLShift + SessionCtl.theShiftKeyDetector.toggleWithRShift = PrefMgr.shared.togglingAlphanumericalModeWithRShift + } + } +} diff --git a/Packages/vChewing_MainAssembly/Sources/MainAssembly/SpeechSputnik.swift b/Packages/vChewing_MainAssembly/Sources/MainAssembly/SpeechSputnik.swift index 867854e7..9db5921f 100644 --- a/Packages/vChewing_MainAssembly/Sources/MainAssembly/SpeechSputnik.swift +++ b/Packages/vChewing_MainAssembly/Sources/MainAssembly/SpeechSputnik.swift @@ -8,6 +8,7 @@ import AppKit import AVFoundation +import Shared public class SpeechSputnik { public static var shared: SpeechSputnik = .init() diff --git a/Packages/vChewing_Shared/Package.swift b/Packages/vChewing_Shared/Package.swift index bef58572..a78a3d4d 100644 --- a/Packages/vChewing_Shared/Package.swift +++ b/Packages/vChewing_Shared/Package.swift @@ -26,5 +26,9 @@ let package = Package( .product(name: "SwiftExtension", package: "vChewing_SwiftExtension"), ] ), + .testTarget( + name: "SharedTests", + dependencies: ["Shared"] + ), ] ) diff --git a/Packages/vChewing_MainAssembly/Sources/MainAssembly/IMEApp.swift b/Packages/vChewing_Shared/Sources/Shared/IMEApp.swift similarity index 90% rename from Packages/vChewing_MainAssembly/Sources/MainAssembly/IMEApp.swift rename to Packages/vChewing_Shared/Sources/Shared/IMEApp.swift index 20b5f461..5b25b30f 100644 --- a/Packages/vChewing_MainAssembly/Sources/MainAssembly/IMEApp.swift +++ b/Packages/vChewing_Shared/Sources/Shared/IMEApp.swift @@ -8,7 +8,6 @@ import AppKit import Carbon -import Shared // MARK: - Top-level Enums relating to Input Mode and Language Supports. @@ -52,7 +51,7 @@ public enum IMEApp { // MARK: - 輸入法的當前的簡繁體中文模式 public static var currentInputMode: Shared.InputMode { - .init(rawValue: PrefMgr.shared.mostRecentInputMode) ?? .imeModeNULL + .init(rawValue: PrefMgr().mostRecentInputMode) ?? .imeModeNULL } /// 當前鍵盤是否是 JIS 佈局 @@ -62,9 +61,10 @@ public enum IMEApp { /// Fart or Beep? public static func buzz() { - if PrefMgr.shared.isDebugModeEnabled { - NSSound.buzz(fart: !PrefMgr.shared.shouldNotFartInLieuOfBeep) - } else if !PrefMgr.shared.shouldNotFartInLieuOfBeep { + let prefs = PrefMgr() + if prefs.isDebugModeEnabled { + NSSound.buzz(fart: !prefs.shouldNotFartInLieuOfBeep) + } else if !prefs.shouldNotFartInLieuOfBeep { NSSound.buzz(fart: true) } else { NSSound.beep() diff --git a/Packages/vChewing_MainAssembly/Sources/MainAssembly/PrefMgr_Core.swift b/Packages/vChewing_Shared/Sources/Shared/PrefMgr_Core.swift similarity index 95% rename from Packages/vChewing_MainAssembly/Sources/MainAssembly/PrefMgr_Core.swift rename to Packages/vChewing_Shared/Sources/Shared/PrefMgr_Core.swift index 520b8994..1c32a259 100644 --- a/Packages/vChewing_MainAssembly/Sources/MainAssembly/PrefMgr_Core.swift +++ b/Packages/vChewing_Shared/Sources/Shared/PrefMgr_Core.swift @@ -6,14 +6,12 @@ // marks, or product names of Contributor, except as required to fulfill notice // requirements defined in MIT License. -import AppKit -import Shared +import Foundation import SwiftExtension // MARK: - @objcMembers public class PrefMgr: NSObject, PrefMgrProtocol { - public static let shared = PrefMgr() public static let kDefaultCandidateKeys = "123456" public static let kDefaultBasicKeyboardLayout = "com.apple.keylayout.ZhuyinBopomofo" public static let kDefaultAlphanumericalKeyboardLayout = { @@ -27,6 +25,10 @@ import SwiftExtension "com.valvesoftware.steam": true, "jp.naver.line.mac": true, ] + public var didAskForSyncingLMPrefs: (() -> Void)? + public var didAskForRefreshingSpeechSputnik: (() -> Void)? + public var didAskForSyncingShiftKeyDetectorPrefs: (() -> Void)? + // MARK: - Settings (Tier 1) @AppProperty(key: UserDef.kIsDebugModeEnabled.rawValue, defaultValue: false) @@ -135,9 +137,7 @@ import SwiftExtension @AppProperty(key: UserDef.kReadingNarrationCoverage.rawValue, defaultValue: 0) public dynamic var readingNarrationCoverage: Int { - didSet { - SpeechSputnik.shared.refreshStatus() - } + didSet { didAskForRefreshingSpeechSputnik?() } } @AppProperty(key: UserDef.kAlsoConfirmAssociatedCandidatesByEnter.rawValue, defaultValue: false) @@ -160,16 +160,12 @@ import SwiftExtension @AppProperty(key: UserDef.kTogglingAlphanumericalModeWithLShift.rawValue, defaultValue: true) public dynamic var togglingAlphanumericalModeWithLShift: Bool { - didSet { - SessionCtl.theShiftKeyDetector.toggleWithLShift = togglingAlphanumericalModeWithLShift - } + didSet { didAskForSyncingShiftKeyDetectorPrefs?() } } @AppProperty(key: UserDef.kTogglingAlphanumericalModeWithRShift.rawValue, defaultValue: true) public dynamic var togglingAlphanumericalModeWithRShift: Bool { - didSet { - SessionCtl.theShiftKeyDetector.toggleWithRShift = togglingAlphanumericalModeWithRShift - } + didSet { didAskForSyncingShiftKeyDetectorPrefs?() } } @AppProperty(key: UserDef.kConsolidateContextOnCandidateSelection.rawValue, defaultValue: true) @@ -244,23 +240,17 @@ import SwiftExtension @AppProperty(key: UserDef.kCNS11643Enabled.rawValue, defaultValue: false) public dynamic var cns11643Enabled: Bool { - didSet { - LMMgr.syncLMPrefs() - } + didSet { didAskForSyncingLMPrefs?() } } @AppProperty(key: UserDef.kSymbolInputEnabled.rawValue, defaultValue: true) public dynamic var symbolInputEnabled: Bool { - didSet { - LMMgr.syncLMPrefs() - } + didSet { didAskForSyncingLMPrefs?() } } @AppProperty(key: UserDef.kCassetteEnabled.rawValue, defaultValue: false) public dynamic var cassetteEnabled: Bool { - didSet { - LMMgr.syncLMPrefs() - } + didSet { didAskForSyncingLMPrefs?() } } @AppProperty(key: UserDef.kChineseConversionEnabled.rawValue, defaultValue: false) @@ -340,33 +330,17 @@ import SwiftExtension @AppProperty(key: UserDef.kUseSCPCTypingMode.rawValue, defaultValue: false) public dynamic var useSCPCTypingMode: Bool { - didSet { - LMMgr.syncLMPrefs() - } + didSet { didAskForSyncingLMPrefs?() } } @AppProperty(key: UserDef.kPhraseReplacementEnabled.rawValue, defaultValue: false) public dynamic var phraseReplacementEnabled: Bool { - didSet { - LMMgr.syncLMPrefs() - } - willSet { - if newValue { - LMMgr.loadUserPhraseReplacement() - } - } + didSet { didAskForSyncingLMPrefs?() } } @AppProperty(key: UserDef.kAssociatedPhrasesEnabled.rawValue, defaultValue: false) public dynamic var associatedPhrasesEnabled: Bool { - didSet { - LMMgr.syncLMPrefs() - } - willSet { - if newValue { - LMMgr.loadUserAssociatesData() - } - } + didSet { didAskForSyncingLMPrefs?() } } // MARK: - Keyboard HotKey Enable / Disable diff --git a/Packages/vChewing_MainAssembly/Sources/MainAssembly/PrefMgr_Extension.swift b/Packages/vChewing_Shared/Sources/Shared/PrefMgr_Utilities.swift similarity index 95% rename from Packages/vChewing_MainAssembly/Sources/MainAssembly/PrefMgr_Extension.swift rename to Packages/vChewing_Shared/Sources/Shared/PrefMgr_Utilities.swift index ab52323a..83cc62b5 100644 --- a/Packages/vChewing_MainAssembly/Sources/MainAssembly/PrefMgr_Extension.swift +++ b/Packages/vChewing_Shared/Sources/Shared/PrefMgr_Utilities.swift @@ -7,22 +7,7 @@ // requirements defined in MIT License. import InputMethodKit -import Shared import SwiftExtension -import SwiftUI - -// MARK: ObservableProject. - -@available(macOS 10.15, *) -extension PrefMgr: ObservableObject {} - -extension PrefMgr { - func sendObjWillChange() { - if #available(macOS 10.15, *) { - objectWillChange.send() - } - } -} // MARK: Guarded Method for Validating Candidate Keys. @@ -90,7 +75,7 @@ public extension PrefMgr { public extension PrefMgr { @discardableResult func dumpShellScriptBackup() -> String? { - let mirror = Mirror(reflecting: PrefMgr.shared) + let mirror = Mirror(reflecting: self) guard let bundleIdentifier = Bundle.main.bundleIdentifier else { return nil } let strDoubleDashLine = String(String(repeating: "=", count: 70)) let consoleOutput = NSMutableString(string: "#!/bin/sh\n\n") diff --git a/Packages/vChewing_Shared/Tests/SharedTests/SharedTests.swift b/Packages/vChewing_Shared/Tests/SharedTests/SharedTests.swift new file mode 100644 index 00000000..28ea972a --- /dev/null +++ b/Packages/vChewing_Shared/Tests/SharedTests/SharedTests.swift @@ -0,0 +1,18 @@ +// (c) 2022 and onwards The vChewing Project (MIT-NTL License). +// ==================== +// This code is released under the MIT license (SPDX-License-Identifier: MIT) +// ... with NTL restriction stating that: +// 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 defined in MIT License. + +@testable import Shared +import XCTest + +final class SharedTests: XCTestCase { + func testDumpedPrefs() throws { + let prefs = PrefMgr() + let fetched = prefs.dumpShellScriptBackup() ?? "" + XCTAssertFalse(fetched.isEmpty) + } +} diff --git a/Source/Modules/main.swift b/Source/Modules/main.swift index e40fd887..a7a972d7 100644 --- a/Source/Modules/main.swift +++ b/Source/Modules/main.swift @@ -10,6 +10,7 @@ import AppKit import IMKUtils import InputMethodKit import MainAssembly +import Shared import Uninstaller let cmdParameters = CommandLine.arguments.dropFirst(1)