vChewing-macOS/Source/Modules/ControllerModules/ctlInputMethod_Menu.swift

392 lines
14 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// (c) 2011 and onwards The OpenVanilla Project (MIT License).
// All possible vChewing-specific modifications are of:
// (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 Cocoa
extension Bool {
fileprivate var state: NSControl.StateValue {
self ? .on : .off
}
}
// MARK: - IME Menu Manager
//
extension ctlInputMethod {
override func menu() -> NSMenu! {
let optionKeyPressed = NSEvent.modifierFlags.contains(.option)
let menu = NSMenu(title: "Input Method Menu")
let useSCPCTypingModeItem = menu.addItem(
withTitle: NSLocalizedString("Per-Char Select Mode", comment: ""),
action: #selector(toggleSCPCTypingMode(_:)), keyEquivalent: mgrPrefs.usingHotKeySCPC ? "P" : ""
)
useSCPCTypingModeItem.keyEquivalentModifierMask = [.command, .control]
useSCPCTypingModeItem.state = mgrPrefs.useSCPCTypingMode.state
let userAssociatedPhrasesItem = menu.addItem(
withTitle: NSLocalizedString("Per-Char Associated Phrases", comment: ""),
action: #selector(toggleAssociatedPhrasesEnabled(_:)), keyEquivalent: mgrPrefs.usingHotKeyAssociates ? "O" : ""
)
userAssociatedPhrasesItem.keyEquivalentModifierMask = [.command, .control]
userAssociatedPhrasesItem.state = mgrPrefs.associatedPhrasesEnabled.state
let useCNS11643SupportItem = menu.addItem(
withTitle: NSLocalizedString("CNS11643 Mode", comment: ""),
action: #selector(toggleCNS11643Enabled(_:)), keyEquivalent: mgrPrefs.usingHotKeyCNS ? "L" : ""
)
useCNS11643SupportItem.keyEquivalentModifierMask = [.command, .control]
useCNS11643SupportItem.state = mgrPrefs.cns11643Enabled.state
if IME.getInputMode() == InputMode.imeModeCHT {
let chineseConversionItem = menu.addItem(
withTitle: NSLocalizedString("Force KangXi Writing", comment: ""),
action: #selector(toggleChineseConverter(_:)), keyEquivalent: mgrPrefs.usingHotKeyKangXi ? "K" : ""
)
chineseConversionItem.keyEquivalentModifierMask = [.command, .control]
chineseConversionItem.state = mgrPrefs.chineseConversionEnabled.state
let shiftJISConversionItem = menu.addItem(
withTitle: NSLocalizedString("JIS Shinjitai Output", comment: ""),
action: #selector(toggleShiftJISShinjitaiOutput(_:)), keyEquivalent: mgrPrefs.usingHotKeyJIS ? "J" : ""
)
shiftJISConversionItem.keyEquivalentModifierMask = [.command, .control]
shiftJISConversionItem.state = mgrPrefs.shiftJISShinjitaiOutputEnabled.state
}
let currencyNumeralsItem = menu.addItem(
withTitle: NSLocalizedString("Currency Numeral Output", comment: ""),
action: #selector(toggleCurrencyNumerals(_:)), keyEquivalent: mgrPrefs.usingHotKeyCurrencyNumerals ? "M" : ""
)
currencyNumeralsItem.keyEquivalentModifierMask = [.command, .control]
currencyNumeralsItem.state = mgrPrefs.currencyNumeralsEnabled.state
let halfWidthPunctuationItem = menu.addItem(
withTitle: NSLocalizedString("Half-Width Punctuation Mode", comment: ""),
action: #selector(toggleHalfWidthPunctuation(_:)), keyEquivalent: mgrPrefs.usingHotKeyHalfWidthASCII ? "H" : ""
)
halfWidthPunctuationItem.keyEquivalentModifierMask = [.command, .control]
halfWidthPunctuationItem.state = mgrPrefs.halfWidthPunctuationEnabled.state
if optionKeyPressed || mgrPrefs.phraseReplacementEnabled {
let phaseReplacementItem = menu.addItem(
withTitle: NSLocalizedString("Use Phrase Replacement", comment: ""),
action: #selector(togglePhraseReplacement(_:)), keyEquivalent: ""
)
phaseReplacementItem.state = mgrPrefs.phraseReplacementEnabled.state
}
if optionKeyPressed {
let toggleSymbolInputItem = menu.addItem(
withTitle: NSLocalizedString("Symbol & Emoji Input", comment: ""),
action: #selector(toggleSymbolEnabled(_:)), keyEquivalent: ""
)
toggleSymbolInputItem.state = mgrPrefs.symbolInputEnabled.state
}
menu.addItem(NSMenuItem.separator()) // ---------------------
menu.addItem(
withTitle: NSLocalizedString("Open User Dictionary Folder", comment: ""),
action: #selector(openUserDataFolder(_:)), keyEquivalent: ""
)
menu.addItem(
withTitle: NSLocalizedString("Edit User Phrases…", comment: ""),
action: #selector(openUserPhrases(_:)), keyEquivalent: ""
)
menu.addItem(
withTitle: NSLocalizedString("Edit Excluded Phrases…", comment: ""),
action: #selector(openExcludedPhrases(_:)), keyEquivalent: ""
)
if optionKeyPressed || mgrPrefs.associatedPhrasesEnabled {
menu.addItem(
withTitle: NSLocalizedString("Edit Associated Phrases…", comment: ""),
action: #selector(openAssociatedPhrases(_:)), keyEquivalent: ""
)
}
if optionKeyPressed {
menu.addItem(
withTitle: NSLocalizedString("Edit Phrase Replacement Table…", comment: ""),
action: #selector(openPhraseReplacement(_:)), keyEquivalent: ""
)
menu.addItem(
withTitle: NSLocalizedString("Edit User Symbol & Emoji Data…", comment: ""),
action: #selector(openUserSymbols(_:)), keyEquivalent: ""
)
}
if optionKeyPressed || !mgrPrefs.shouldAutoReloadUserDataFiles {
menu.addItem(
withTitle: NSLocalizedString("Reload User Phrases", comment: ""),
action: #selector(reloadUserPhrasesData(_:)), keyEquivalent: ""
)
}
menu.addItem(NSMenuItem.separator()) // ---------------------
menu.addItem(
withTitle: NSLocalizedString("Optimize Memorized Phrases", comment: ""),
action: #selector(removeUnigramsFromUOM(_:)), keyEquivalent: ""
)
menu.addItem(
withTitle: NSLocalizedString("Clear Memorized Phrases", comment: ""),
action: #selector(clearUOM(_:)), keyEquivalent: ""
)
menu.addItem(NSMenuItem.separator()) // ---------------------
menu.addItem(
withTitle: NSLocalizedString("vChewing Preferences…", comment: ""),
action: #selector(showPreferences(_:)), keyEquivalent: ""
)
menu.addItem(
withTitle: NSLocalizedString("Client Manager", comment: "") + "",
action: #selector(showClientListMgr(_:)), keyEquivalent: ""
)
if !optionKeyPressed {
menu.addItem(
withTitle: NSLocalizedString("Check for Updates…", comment: ""),
action: #selector(checkForUpdate(_:)), keyEquivalent: ""
)
}
menu.addItem(
withTitle: NSLocalizedString("Reboot vChewing…", comment: ""),
action: #selector(selfTerminate(_:)), keyEquivalent: ""
)
menu.addItem(
withTitle: NSLocalizedString("About vChewing…", comment: ""),
action: #selector(showAbout(_:)), keyEquivalent: ""
)
menu.addItem(
withTitle: NSLocalizedString("CheatSheet", comment: "") + "",
action: #selector(showCheatSheet(_:)), keyEquivalent: ""
)
if optionKeyPressed {
menu.addItem(
withTitle: NSLocalizedString("Uninstall vChewing…", comment: ""),
action: #selector(selfUninstall(_:)), keyEquivalent: ""
)
}
// NSMenu
setKeyLayout()
return menu
}
}
// MARK: - IME Menu Items
extension ctlInputMethod {
@objc override func showPreferences(_: Any?) {
if #unavailable(macOS 10.15) {
showLegacyPreferences()
} else if NSEvent.modifierFlags.contains(.option) {
showLegacyPreferences()
} else {
NSApp.setActivationPolicy(.accessory)
ctlPrefUI.shared.controller.show(preferencePane: Preferences.PaneIdentifier(rawValue: "General"))
ctlPrefUI.shared.controller.window?.level = .statusBar
}
}
func showLegacyPreferences() {
(NSApp.delegate as? AppDelegate)?.showPreferences()
NSApp.activate(ignoringOtherApps: true)
}
@objc func showCheatSheet(_: Any?) {
guard let url = Bundle.main.url(forResource: "shortcuts", withExtension: "html") else { return }
DispatchQueue.main.async {
NSWorkspace.shared.openFile(url.path, withApplication: "Safari")
}
}
@objc func showClientListMgr(_: Any?) {
(NSApp.delegate as? AppDelegate)?.showClientListMgr()
NSApp.activate(ignoringOtherApps: true)
}
@objc func toggleSCPCTypingMode(_: Any? = nil) {
resetKeyHandler()
NotifierController.notify(
message: NSLocalizedString("Per-Char Select Mode", comment: "") + "\n"
+ (mgrPrefs.toggleSCPCTypingModeEnabled()
? NSLocalizedString("NotificationSwitchON", comment: "")
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
)
}
@objc func toggleChineseConverter(_: Any?) {
resetKeyHandler()
NotifierController.notify(
message: NSLocalizedString("Force KangXi Writing", comment: "") + "\n"
+ (mgrPrefs.toggleChineseConversionEnabled()
? NSLocalizedString("NotificationSwitchON", comment: "")
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
)
}
@objc func toggleShiftJISShinjitaiOutput(_: Any?) {
resetKeyHandler()
NotifierController.notify(
message: NSLocalizedString("JIS Shinjitai Output", comment: "") + "\n"
+ (mgrPrefs.toggleShiftJISShinjitaiOutputEnabled()
? NSLocalizedString("NotificationSwitchON", comment: "")
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
)
}
@objc func toggleCurrencyNumerals(_: Any?) {
resetKeyHandler()
NotifierController.notify(
message: NSLocalizedString("Currency Numeral Output", comment: "") + "\n"
+ (mgrPrefs.toggleCurrencyNumeralsEnabled()
? NSLocalizedString("NotificationSwitchON", comment: "")
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
)
}
@objc func toggleHalfWidthPunctuation(_: Any?) {
resetKeyHandler()
NotifierController.notify(
message: NSLocalizedString("Half-Width Punctuation Mode", comment: "") + "\n"
+ (mgrPrefs.toggleHalfWidthPunctuationEnabled()
? NSLocalizedString("NotificationSwitchON", comment: "")
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
)
}
@objc func toggleCNS11643Enabled(_: Any?) {
resetKeyHandler()
NotifierController.notify(
message: NSLocalizedString("CNS11643 Mode", comment: "") + "\n"
+ (mgrPrefs.toggleCNS11643Enabled()
? NSLocalizedString("NotificationSwitchON", comment: "")
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
)
}
@objc func toggleSymbolEnabled(_: Any?) {
resetKeyHandler()
NotifierController.notify(
message: NSLocalizedString("Symbol & Emoji Input", comment: "") + "\n"
+ (mgrPrefs.toggleSymbolInputEnabled()
? NSLocalizedString("NotificationSwitchON", comment: "")
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
)
}
@objc func toggleAssociatedPhrasesEnabled(_: Any?) {
resetKeyHandler()
NotifierController.notify(
message: NSLocalizedString("Per-Char Associated Phrases", comment: "") + "\n"
+ (mgrPrefs.toggleAssociatedPhrasesEnabled()
? NSLocalizedString("NotificationSwitchON", comment: "")
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
)
}
@objc func togglePhraseReplacement(_: Any?) {
resetKeyHandler()
NotifierController.notify(
message: NSLocalizedString("Use Phrase Replacement", comment: "") + "\n"
+ (mgrPrefs.togglePhraseReplacementEnabled()
? NSLocalizedString("NotificationSwitchON", comment: "")
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
)
}
@objc func selfUninstall(_: Any?) {
(NSApp.delegate as? AppDelegate)?.selfUninstall()
}
@objc func selfTerminate(_: Any?) {
NSApp.activate(ignoringOtherApps: true)
NSApp.terminate(nil)
}
@objc func checkForUpdate(_: Any?) {
UpdateSputnik.shared.checkForUpdate(forced: true)
}
@objc func openUserDataFolder(_: Any?) {
if !mgrLangModel.userDataFolderExists {
return
}
NSWorkspace.shared.openFile(
mgrLangModel.dataFolderPath(isDefaultFolder: false), withApplication: "Finder"
)
}
@objc func openUserPhrases(_: Any?) {
IME.openPhraseFile(fromURL: mgrLangModel.userPhrasesDataURL(IME.getInputMode()))
if NSEvent.modifierFlags.contains(.option) {
IME.openPhraseFile(fromURL: mgrLangModel.userPhrasesDataURL(IME.getInputMode(isReversed: true)))
}
}
@objc func openExcludedPhrases(_: Any?) {
IME.openPhraseFile(fromURL: mgrLangModel.userFilteredDataURL(IME.getInputMode()))
if NSEvent.modifierFlags.contains(.option) {
IME.openPhraseFile(fromURL: mgrLangModel.userFilteredDataURL(IME.getInputMode(isReversed: true)))
}
}
@objc func openUserSymbols(_: Any?) {
IME.openPhraseFile(fromURL: mgrLangModel.userSymbolDataURL(IME.getInputMode()))
if NSEvent.modifierFlags.contains(.option) {
IME.openPhraseFile(fromURL: mgrLangModel.userSymbolDataURL(IME.getInputMode(isReversed: true)))
}
}
@objc func openPhraseReplacement(_: Any?) {
IME.openPhraseFile(fromURL: mgrLangModel.userReplacementsDataURL(IME.getInputMode()))
if NSEvent.modifierFlags.contains(.option) {
IME.openPhraseFile(fromURL: mgrLangModel.userReplacementsDataURL(IME.getInputMode(isReversed: true)))
}
}
@objc func openAssociatedPhrases(_: Any?) {
IME.openPhraseFile(fromURL: mgrLangModel.userAssociatesDataURL(IME.getInputMode()))
if NSEvent.modifierFlags.contains(.option) {
IME.openPhraseFile(
fromURL: mgrLangModel.userAssociatesDataURL(IME.getInputMode(isReversed: true)))
}
}
@objc func reloadUserPhrasesData(_: Any?) {
IME.initLangModels(userOnly: true)
}
@objc func removeUnigramsFromUOM(_: Any?) {
mgrLangModel.removeUnigramsFromUserOverrideModel(IME.getInputMode())
if NSEvent.modifierFlags.contains(.option) {
mgrLangModel.removeUnigramsFromUserOverrideModel(IME.getInputMode(isReversed: true))
}
}
@objc func clearUOM(_: Any?) {
mgrLangModel.clearUserOverrideModelData(IME.getInputMode())
if NSEvent.modifierFlags.contains(.option) {
mgrLangModel.clearUserOverrideModelData(IME.getInputMode(isReversed: true))
}
}
@objc func showAbout(_: Any?) {
(NSApp.delegate as? AppDelegate)?.showAbout()
NSApp.activate(ignoringOtherApps: true)
}
}