diff --git a/Packages/vChewing_Shared/Sources/Shared/Protocols/PrefMgrProtocol.swift b/Packages/vChewing_Shared/Sources/Shared/Protocols/PrefMgrProtocol.swift index c65fc572..50811888 100644 --- a/Packages/vChewing_Shared/Sources/Shared/Protocols/PrefMgrProtocol.swift +++ b/Packages/vChewing_Shared/Sources/Shared/Protocols/PrefMgrProtocol.swift @@ -86,4 +86,5 @@ public protocol PrefMgrProtocol { var usingHotKeyCurrencyNumerals: Bool { get set } var usingHotKeyCassette: Bool { get set } var usingHotKeyRevLookup: Bool { get set } + var usingHotKeyInputMode: Bool { get set } } diff --git a/Packages/vChewing_Shared/Sources/Shared/Shared.swift b/Packages/vChewing_Shared/Sources/Shared/Shared.swift index d12e9161..3da958c2 100644 --- a/Packages/vChewing_Shared/Sources/Shared/Shared.swift +++ b/Packages/vChewing_Shared/Sources/Shared/Shared.swift @@ -94,6 +94,7 @@ public enum UserDef: String, CaseIterable { case kUsingHotKeyCurrencyNumerals = "UsingHotKeyCurrencyNumerals" case kUsingHotKeyCassette = "UsingHotKeyCassette" case kUsingHotKeyRevLookup = "UsingHotKeyRevLookup" + case kUsingHotKeyInputMode = "UsingHotKeyInputMode" public static func resetAll() { UserDef.allCases.forEach { diff --git a/Source/Modules/PrefMgr_Core.swift b/Source/Modules/PrefMgr_Core.swift index bcffefd0..4c516b1f 100644 --- a/Source/Modules/PrefMgr_Core.swift +++ b/Source/Modules/PrefMgr_Core.swift @@ -358,4 +358,7 @@ public class PrefMgr: PrefMgrProtocol { @AppProperty(key: UserDef.kUsingHotKeyRevLookup.rawValue, defaultValue: true) public var usingHotKeyRevLookup: Bool + + @AppProperty(key: UserDef.kUsingHotKeyInputMode.rawValue, defaultValue: true) + public var usingHotKeyInputMode: Bool } diff --git a/Source/Modules/SessionCtl_Core.swift b/Source/Modules/SessionCtl_Core.swift index e033e662..18b53302 100644 --- a/Source/Modules/SessionCtl_Core.swift +++ b/Source/Modules/SessionCtl_Core.swift @@ -9,6 +9,7 @@ import CandidateWindow import CocoaExtension import IMKUtils +import NotifierUI import PopupCompositionBuffer import Shared import ShiftKeyUpChecker @@ -120,6 +121,15 @@ public class SessionCtl: IMKInputController { } } + private let sharedAlertForInputModeToggling: NSAlert = { + let alert = NSAlert() + alert.alertStyle = .informational + alert.messageText = "Target Input Mode Activation Required".localized + alert.informativeText = "You are proceeding to System Preferences to enable the Input Source which corresponds to the input mode you are going to switch to.".localized + alert.addButton(withTitle: "OK".localized) + return alert + }() + public func updateVerticalTypingStatus() { guard let client = client() else { isVerticalTyping = false @@ -322,6 +332,38 @@ public extension SessionCtl { super.setValue(value, forTag: tag, client: sender) } + /// 專門用來就地切換繁簡模式的函式。 + @objc func switchInputMode(_: Any? = nil) { + guard let client: IMKTextInput = client() else { return } + let nowMode = IMEApp.currentInputMode + guard nowMode != .imeModeNULL else { return } + modeCheck: for neta in TISInputSource.allRegisteredInstancesOfThisInputMethod { + guard !neta.isActivated else { continue } + osCheck: if #unavailable(macOS 12) { + neta.activate() + if !neta.isActivated { + break osCheck + } + break modeCheck + } + let result = sharedAlertForInputModeToggling.runModal() + NSApp.activate(ignoringOtherApps: true) + if result == NSApplication.ModalResponse.alertFirstButtonReturn { + neta.activate() + } + return + } + let status = "NotificationSwitchRevolver".localized + DispatchQueue.main.async { + if LMMgr.lmCHT.isCoreLMLoaded, LMMgr.lmCHS.isCoreLMLoaded { + Notifier.notify( + message: nowMode.reversed.localizedDescription + "\n" + status + ) + } + } + client.selectMode(nowMode.reversed.rawValue) + } + /// 將輸入法偏好設定同步至語言模組內。 func syncBaseLMPrefs() { LMMgr.currentLM.isPhraseReplacementEnabled = PrefMgr.shared.phraseReplacementEnabled diff --git a/Source/Modules/SessionCtl_Menu.swift b/Source/Modules/SessionCtl_Menu.swift index ba090b3b..120da837 100644 --- a/Source/Modules/SessionCtl_Menu.swift +++ b/Source/Modules/SessionCtl_Menu.swift @@ -27,6 +27,15 @@ extension SessionCtl { override public func menu() -> NSMenu! { let menu = NSMenu(title: "Input Method Menu") + let switchInputModeItem = menu.addItem( + withTitle: String( + format: "Switch to %@ Input Mode".localized, + IMEApp.currentInputMode.reversed.localizedDescription + ), + action: #selector(switchInputMode(_:)), keyEquivalent: PrefMgr.shared.usingHotKeyInputMode ? "D" : "" + ) + switchInputModeItem.keyEquivalentModifierMask = [.command, .control] + let useSCPCTypingModeItem = menu.addItem( withTitle: "Per-Char Select Mode".localized, action: #selector(toggleSCPCTypingMode(_:)), keyEquivalent: PrefMgr.shared.usingHotKeySCPC ? "P" : "" @@ -155,8 +164,6 @@ extension SessionCtl { ) revLookupMenuItem.keyEquivalentModifierMask = [.command, .control] - menu.addItem(NSMenuItem.separator()) // --------------------- - menu.addItem( withTitle: "Optimize Memorized Phrases".localized, action: #selector(removeUnigramsFromUOM(_:)), keyEquivalent: "" diff --git a/Source/Modules/UIModules/PrefUI/VwrPrefPaneKeyboard.swift b/Source/Modules/UIModules/PrefUI/VwrPrefPaneKeyboard.swift index 7d514bd0..79add6c8 100644 --- a/Source/Modules/UIModules/PrefUI/VwrPrefPaneKeyboard.swift +++ b/Source/Modules/UIModules/PrefUI/VwrPrefPaneKeyboard.swift @@ -169,6 +169,9 @@ private struct VwrPrefPaneKeyboard_KeyboardShortcuts: View { @Backport.AppStorage(wrappedValue: true, UserDef.kUsingHotKeyRevLookup.rawValue) private var usingHotKeyRevLookup: Bool + @Backport.AppStorage(wrappedValue: true, UserDef.kUsingHotKeyInputMode.rawValue) + private var usingHotKeyInputMode: Bool + // MARK: - Main View var body: some View { @@ -212,6 +215,10 @@ private struct VwrPrefPaneKeyboard_KeyboardShortcuts: View { LocalizedStringKey("CIN Cassette Mode"), isOn: $usingHotKeyCassette ) + Toggle( + LocalizedStringKey("CHS / CHT Input Mode Switch"), + isOn: $usingHotKeyInputMode + ) } } } diff --git a/Source/Resources/Base.lproj/Localizable.strings b/Source/Resources/Base.lproj/Localizable.strings index 65da193d..0974aae3 100644 --- a/Source/Resources/Base.lproj/Localizable.strings +++ b/Source/Resources/Base.lproj/Localizable.strings @@ -1,4 +1,8 @@ "vChewing" = "vChewing"; +"CHS / CHT Input Mode Switch" = "CHS / CHT Input Mode Switch"; +"Switch to %@ Input Mode" = "Switch to %@ Input Mode"; +"Target Input Mode Activation Required" = "Target Input Mode Activation Required"; +"You are proceeding to System Preferences to enable the Input Source which corresponds to the input mode you are going to switch to." = "You are proceeding to System Preferences to enable the Input Source which corresponds to the input mode you are going to switch to."; "IMK Candidate Window has been automatically disabled due to its recent crash with force-exposed necessary internal APIs. As an experimental feature, we advise against using IMK Candidate Window in productive environments." = "IMK Candidate Window has been automatically disabled due to its recent crash with force-exposed necessary internal APIs. As an experimental feature, we advise against using IMK Candidate Window in productive environments."; "Do you want to enable the popup composition buffer for this client?" = "Do you want to enable the popup composition buffer for this client?"; "Some client apps may have different compatibility issues in IMKTextInput implementation." = "Some client apps may have different compatibility issues in IMKTextInput implementation."; diff --git a/Source/Resources/en.lproj/Localizable.strings b/Source/Resources/en.lproj/Localizable.strings index 65da193d..0974aae3 100644 --- a/Source/Resources/en.lproj/Localizable.strings +++ b/Source/Resources/en.lproj/Localizable.strings @@ -1,4 +1,8 @@ "vChewing" = "vChewing"; +"CHS / CHT Input Mode Switch" = "CHS / CHT Input Mode Switch"; +"Switch to %@ Input Mode" = "Switch to %@ Input Mode"; +"Target Input Mode Activation Required" = "Target Input Mode Activation Required"; +"You are proceeding to System Preferences to enable the Input Source which corresponds to the input mode you are going to switch to." = "You are proceeding to System Preferences to enable the Input Source which corresponds to the input mode you are going to switch to."; "IMK Candidate Window has been automatically disabled due to its recent crash with force-exposed necessary internal APIs. As an experimental feature, we advise against using IMK Candidate Window in productive environments." = "IMK Candidate Window has been automatically disabled due to its recent crash with force-exposed necessary internal APIs. As an experimental feature, we advise against using IMK Candidate Window in productive environments."; "Do you want to enable the popup composition buffer for this client?" = "Do you want to enable the popup composition buffer for this client?"; "Some client apps may have different compatibility issues in IMKTextInput implementation." = "Some client apps may have different compatibility issues in IMKTextInput implementation."; diff --git a/Source/Resources/ja.lproj/Localizable.strings b/Source/Resources/ja.lproj/Localizable.strings index 4618bcb1..ec72a5ab 100644 --- a/Source/Resources/ja.lproj/Localizable.strings +++ b/Source/Resources/ja.lproj/Localizable.strings @@ -1,4 +1,8 @@ "vChewing" = "威注音入力アプリ"; +"CHS / CHT Input Mode Switch" = "簡体・繁体中国語入力の切り替え"; +"Switch to %@ Input Mode" = "%@入力モードに切り替え"; +"Target Input Mode Activation Required" = "関連の入力ソースの追加が必要"; +"You are proceeding to System Preferences to enable the Input Source which corresponds to the input mode you are going to switch to." = "ご希望の入力モードのご利用の前に、それに対応するの入力ソースの追加が必要である。これからはシステム環境設定の該当ページへ案内します。"; "IMK Candidate Window has been automatically disabled due to its recent crash with force-exposed necessary internal APIs. As an experimental feature, we advise against using IMK Candidate Window in productive environments." = "IMK 文字候補ウィンドウの利用できるようのために、システム内部の必要のある API の強引的アクセスが必要ですが、前回のその利用で威注音入力アプリが崩れました。故に今は IMK 文字候補ウィンドウを OFF にしました。IMK 文字候補ウィンドウはあくまで実験的な機能として提供していたため、業務用にはお勧めできません。"; "Do you want to enable the popup composition buffer for this client?" = "この客体アプリに「吹き出し入力緩衝列ウィンドウ」を起用しますか?"; "Some client apps may have different compatibility issues in IMKTextInput implementation." = "それぞれの客体アプリには、それぞれの IMKTextInput 不具合はあるかもしれません。"; diff --git a/Source/Resources/zh-Hans.lproj/Localizable.strings b/Source/Resources/zh-Hans.lproj/Localizable.strings index 7f4f93bc..0e45341a 100644 --- a/Source/Resources/zh-Hans.lproj/Localizable.strings +++ b/Source/Resources/zh-Hans.lproj/Localizable.strings @@ -1,4 +1,8 @@ "vChewing" = "威注音输入法"; +"CHS / CHT Input Mode Switch" = "简体/繁体中文输入模式切换"; +"Switch to %@ Input Mode" = "切换至%@输入模式"; +"Target Input Mode Activation Required" = "得启用对应的「輸入法」"; +"You are proceeding to System Preferences to enable the Input Source which corresponds to the input mode you are going to switch to." = "若要使用您想切换到的输入模式,您必须得先在系统偏好设定内启用对应的「輸入法/输入源」。接下来将会弹出对应的系统偏好设定画面。"; "IMK Candidate Window has been automatically disabled due to its recent crash with force-exposed necessary internal APIs. As an experimental feature, we advise against using IMK Candidate Window in productive environments." = "IMK 选字窗在最近一次存取被强制曝露的必需 API 时令输入法崩溃,所以被自动停用。请勿在生产力场合使用该实验型功能。"; "Do you want to enable the popup composition buffer for this client?" = "您要對該客體啟用浮動組字窗嗎?"; "Some client apps may have different compatibility issues in IMKTextInput implementation." = "有些客體應用可能會有不同的 IMKTextInput 實作相容問題。"; diff --git a/Source/Resources/zh-Hant.lproj/Localizable.strings b/Source/Resources/zh-Hant.lproj/Localizable.strings index da9b42fc..99419cee 100644 --- a/Source/Resources/zh-Hant.lproj/Localizable.strings +++ b/Source/Resources/zh-Hant.lproj/Localizable.strings @@ -1,4 +1,8 @@ "vChewing" = "威注音輸入法"; +"CHS / CHT Input Mode Switch" = "簡體/繁體中文輸入模式切換"; +"Switch to %@ Input Mode" = "切換至%@輸入模式"; +"Target Input Mode Activation Required" = "得啟用對應的「輸入方式」"; +"You are proceeding to System Preferences to enable the Input Source which corresponds to the input mode you are going to switch to." = "若要使用您想切換到的輸入模式,您必須得先在系統偏好設定內啟用對應的「輸入方式」。接下來將會彈出對應的系統偏好設定畫面。"; "IMK Candidate Window has been automatically disabled due to its recent crash with force-exposed necessary internal APIs. As an experimental feature, we advise against using IMK Candidate Window in productive environments." = "IMK 選字窗在最近一次存取被強制曝露的必需 API 時令輸入法崩潰,所以被自動停用。請勿在生產力場合使用該實驗型功能。"; "Do you want to enable the popup composition buffer for this client?" = "您要对该客体启用浮动组字窗吗?"; "Some client apps may have different compatibility issues in IMKTextInput implementation." = "有些客体应用可能会有不同的 IMKTextInput 实作相容问题。"; diff --git a/Source/WindowNIBs/Base.lproj/frmPrefWindow.xib b/Source/WindowNIBs/Base.lproj/frmPrefWindow.xib index 7c774771..fc64cdf3 100644 --- a/Source/WindowNIBs/Base.lproj/frmPrefWindow.xib +++ b/Source/WindowNIBs/Base.lproj/frmPrefWindow.xib @@ -2137,7 +2137,7 @@ DQ - + @@ -2148,7 +2148,7 @@ DQ - + @@ -2235,10 +2235,10 @@ DQ - + + + + diff --git a/Source/WindowNIBs/en.lproj/frmPrefWindow.strings b/Source/WindowNIBs/en.lproj/frmPrefWindow.strings index 62f043a7..79499117 100644 --- a/Source/WindowNIBs/en.lproj/frmPrefWindow.strings +++ b/Source/WindowNIBs/en.lproj/frmPrefWindow.strings @@ -12,8 +12,6 @@ "17.title" = "Cursor at the rear of the phrase (like Microsoft New Phonetic)"; "18.title" = "Radio"; "1AW-xf-c2f.label" = "Keyboard"; -"1ll-Jn-OD5.title" = "CIN Cassette Mode"; -"1Pn-EV-mui.title" = "Reverse Lookup (Phonabets)"; "20.title" = "Radio"; "21.title" = "Horizontal"; "22.title" = "Vertical"; @@ -134,10 +132,13 @@ "xibOutputSettings.title" = "Output Settings"; "xibUsingCurrencyNumerals.title" = "Currency Numeral Output"; "xibUsingHotKeyAssociates.title" = "Per-Char Associated Phrases"; +"xibUsingHotKeyCassette.title" = "CIN Cassette Mode"; "xibUsingHotKeyCNS.title" = "CNS11643 Mode"; "xibUsingHotKeyHalfWidthASCII.title" = "Half-Width Punctuation Mode"; +"xibUsingHotKeyInputMode.title" = "CHS / CHT Input Mode Switch"; "xibUsingHotKeyJIS.title" = "JIS Shinjitai Output"; "xibUsingHotKeyKangXi.title" = "Force KangXi Writing"; +"xibUsingHotKeyRevLookup.title" = "Reverse Lookup (Phonabets)"; "xibUsingHotKeySCPC.title" = "Per-Char Select Mode"; "xjP-r7-GaK.title" = "Dachen 26 (libChewing)"; "XqL-rf-X6d.title" = "Space to +revolve pages, Shift+Space to +revolve candidates"; diff --git a/Source/WindowNIBs/ja.lproj/frmPrefWindow.strings b/Source/WindowNIBs/ja.lproj/frmPrefWindow.strings index 2c799906..cc2574e2 100644 --- a/Source/WindowNIBs/ja.lproj/frmPrefWindow.strings +++ b/Source/WindowNIBs/ja.lproj/frmPrefWindow.strings @@ -12,8 +12,6 @@ "17.title" = "単語の後で // Microsoft 新注音入力のやり方"; "18.title" = "Radio"; "1AW-xf-c2f.label" = "キーボード"; -"1ll-Jn-OD5.title" = "CIN カセットモード"; -"1Pn-EV-mui.title" = "注音音読逆引参照"; "20.title" = "Radio"; "21.title" = "横型陳列"; "22.title" = "縦型陳列"; @@ -134,10 +132,13 @@ "xibOutputSettings.title" = "出力設定"; "xibUsingCurrencyNumerals.title" = "数字大字変換"; "xibUsingHotKeyAssociates.title" = "全候補入力で連想語彙"; +"xibUsingHotKeyCassette.title" = "CIN カセットモード"; "xibUsingHotKeyCNS.title" = "全字庫モード"; "xibUsingHotKeyHalfWidthASCII.title" = "半角句読モード"; +"xibUsingHotKeyInputMode.title" = "簡体・繁体中国語入力の切り替え"; "xibUsingHotKeyJIS.title" = "JIS 新字体モード"; "xibUsingHotKeyKangXi.title" = "康熙文字変換モード"; +"xibUsingHotKeyRevLookup.title" = "注音音読逆引参照"; "xibUsingHotKeySCPC.title" = "全候補入力モード"; "xjP-r7-GaK.title" = "酷音大千 26 キー配列"; "XqL-rf-X6d.title" = "Space で次のページ、Shift+Space で次の候補文字を"; diff --git a/Source/WindowNIBs/zh-Hans.lproj/frmPrefWindow.strings b/Source/WindowNIBs/zh-Hans.lproj/frmPrefWindow.strings index 506ff733..d7d94bde 100644 --- a/Source/WindowNIBs/zh-Hans.lproj/frmPrefWindow.strings +++ b/Source/WindowNIBs/zh-Hans.lproj/frmPrefWindow.strings @@ -12,8 +12,6 @@ "17.title" = "光标置于词语后方 // Windows 微软新注音风格"; "18.title" = "Radio"; "1AW-xf-c2f.label" = "键盘"; -"1ll-Jn-OD5.title" = "CIN 磁带模式"; -"1Pn-EV-mui.title" = "注音反查"; "20.title" = "Radio"; "21.title" = "横向布局"; "22.title" = "纵向布局"; @@ -134,10 +132,13 @@ "xibOutputSettings.title" = "输出设定"; "xibUsingCurrencyNumerals.title" = "大写汉字数字输出"; "xibUsingHotKeyAssociates.title" = "逐字选字联想模式"; +"xibUsingHotKeyCassette.title" = "CIN 磁带模式"; "xibUsingHotKeyCNS.title" = "全字库模式"; "xibUsingHotKeyHalfWidthASCII.title" = "半形标点模式"; +"xibUsingHotKeyInputMode.title" = "简体/繁体中文输入模式切换"; "xibUsingHotKeyJIS.title" = "JIS 新字体模式"; "xibUsingHotKeyKangXi.title" = "康熙正体字模式"; +"xibUsingHotKeyRevLookup.title" = "注音反查"; "xibUsingHotKeySCPC.title" = "模拟逐字选字输入"; "xjP-r7-GaK.title" = "酷音大千二十六键"; "XqL-rf-X6d.title" = "Space 换下一页,Shift+Space 换选下一个候选字。"; diff --git a/Source/WindowNIBs/zh-Hant.lproj/frmPrefWindow.strings b/Source/WindowNIBs/zh-Hant.lproj/frmPrefWindow.strings index bbf83aef..e372e795 100644 --- a/Source/WindowNIBs/zh-Hant.lproj/frmPrefWindow.strings +++ b/Source/WindowNIBs/zh-Hant.lproj/frmPrefWindow.strings @@ -12,8 +12,6 @@ "17.title" = "游標置於詞語後方 // Windows 微軟新注音風格"; "18.title" = "Radio"; "1AW-xf-c2f.label" = "鍵盤"; -"1ll-Jn-OD5.title" = "CIN 磁帶模式"; -"1Pn-EV-mui.title" = "注音反查"; "20.title" = "Radio"; "21.title" = "橫向佈局"; "22.title" = "縱向佈局"; @@ -134,10 +132,13 @@ "xibOutputSettings.title" = "輸出設定"; "xibUsingCurrencyNumerals.title" = "大寫漢字數字輸出"; "xibUsingHotKeyAssociates.title" = "逐字選字聯想模式"; +"xibUsingHotKeyCassette.title" = "CIN 磁帶模式"; "xibUsingHotKeyCNS.title" = "全字庫模式"; "xibUsingHotKeyHalfWidthASCII.title" = "半形標點模式"; +"xibUsingHotKeyInputMode.title" = "簡體/繁體中文輸入模式切換"; "xibUsingHotKeyJIS.title" = "JIS 新字體模式"; "xibUsingHotKeyKangXi.title" = "康熙正體字模式"; +"xibUsingHotKeyRevLookup.title" = "注音反查"; "xibUsingHotKeySCPC.title" = "模擬逐字選字輸入"; "xjP-r7-GaK.title" = "酷音大千二十六鍵"; "XqL-rf-X6d.title" = "Space 換下一頁,Shift+Space 換選下一個候選字";