vChewing-macOS/Source/Modules/SessionCtl_Menu.swift

394 lines
15 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) 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 NotifierUI
import Preferences
extension Bool {
fileprivate var state: NSControl.StateValue {
self ? .on : .off
}
}
// MARK: - IME Menu Manager
//
extension SessionCtl {
public 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: PrefMgr.shared.usingHotKeySCPC ? "P" : ""
)
useSCPCTypingModeItem.keyEquivalentModifierMask = [.command, .control]
useSCPCTypingModeItem.state = PrefMgr.shared.useSCPCTypingMode.state
let userAssociatedPhrasesItem = menu.addItem(
withTitle: NSLocalizedString("Per-Char Associated Phrases", comment: ""),
action: #selector(toggleAssociatedPhrasesEnabled(_:)),
keyEquivalent: PrefMgr.shared.usingHotKeyAssociates ? "O" : ""
)
userAssociatedPhrasesItem.keyEquivalentModifierMask = [.command, .control]
userAssociatedPhrasesItem.state = PrefMgr.shared.associatedPhrasesEnabled.state
let useCNS11643SupportItem = menu.addItem(
withTitle: NSLocalizedString("CNS11643 Mode", comment: ""),
action: #selector(toggleCNS11643Enabled(_:)), keyEquivalent: PrefMgr.shared.usingHotKeyCNS ? "L" : ""
)
useCNS11643SupportItem.keyEquivalentModifierMask = [.command, .control]
useCNS11643SupportItem.state = PrefMgr.shared.cns11643Enabled.state
if IMEApp.currentInputMode == .imeModeCHT {
let chineseConversionItem = menu.addItem(
withTitle: NSLocalizedString("Force KangXi Writing", comment: ""),
action: #selector(toggleChineseConverter(_:)), keyEquivalent: PrefMgr.shared.usingHotKeyKangXi ? "K" : ""
)
chineseConversionItem.keyEquivalentModifierMask = [.command, .control]
chineseConversionItem.state = PrefMgr.shared.chineseConversionEnabled.state
let shiftJISConversionItem = menu.addItem(
withTitle: NSLocalizedString("JIS Shinjitai Output", comment: ""),
action: #selector(toggleShiftJISShinjitaiOutput(_:)), keyEquivalent: PrefMgr.shared.usingHotKeyJIS ? "J" : ""
)
shiftJISConversionItem.keyEquivalentModifierMask = [.command, .control]
shiftJISConversionItem.state = PrefMgr.shared.shiftJISShinjitaiOutputEnabled.state
}
let currencyNumeralsItem = menu.addItem(
withTitle: NSLocalizedString("Currency Numeral Output", comment: ""),
action: #selector(toggleCurrencyNumerals(_:)),
keyEquivalent: PrefMgr.shared.usingHotKeyCurrencyNumerals ? "M" : ""
)
currencyNumeralsItem.keyEquivalentModifierMask = [.command, .control]
currencyNumeralsItem.state = PrefMgr.shared.currencyNumeralsEnabled.state
let halfWidthPunctuationItem = menu.addItem(
withTitle: NSLocalizedString("Half-Width Punctuation Mode", comment: ""),
action: #selector(toggleHalfWidthPunctuation(_:)),
keyEquivalent: PrefMgr.shared.usingHotKeyHalfWidthASCII ? "H" : ""
)
halfWidthPunctuationItem.keyEquivalentModifierMask = [.command, .control]
halfWidthPunctuationItem.state = PrefMgr.shared.halfWidthPunctuationEnabled.state
if optionKeyPressed || PrefMgr.shared.phraseReplacementEnabled {
let phaseReplacementItem = menu.addItem(
withTitle: NSLocalizedString("Use Phrase Replacement", comment: ""),
action: #selector(togglePhraseReplacement(_:)), keyEquivalent: ""
)
phaseReplacementItem.state = PrefMgr.shared.phraseReplacementEnabled.state
}
if optionKeyPressed {
let toggleSymbolInputItem = menu.addItem(
withTitle: NSLocalizedString("Symbol & Emoji Input", comment: ""),
action: #selector(toggleSymbolEnabled(_:)), keyEquivalent: ""
)
toggleSymbolInputItem.state = PrefMgr.shared.symbolInputEnabled.state
}
menu.addItem(NSMenuItem.separator()) // ---------------------
menu.addItem(
withTitle: NSLocalizedString("Open User Dictionary Folder", comment: ""),
action: #selector(openUserDataFolder(_:)), keyEquivalent: ""
)
menu.addItem(
withTitle: NSLocalizedString("Edit vChewing User Phrases…", comment: ""),
action: #selector(openUserPhrases(_:)), keyEquivalent: ""
)
menu.addItem(
withTitle: NSLocalizedString("Edit Excluded Phrases…", comment: ""),
action: #selector(openExcludedPhrases(_:)), keyEquivalent: ""
)
if optionKeyPressed || PrefMgr.shared.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 || !PrefMgr.shared.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 SessionCtl {
@objc public 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
}
}
public func showLegacyPreferences() {
(NSApp.delegate as? AppDelegate)?.showPreferences()
NSApp.activate(ignoringOtherApps: true)
}
@objc public 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 public func showClientListMgr(_: Any?) {
(NSApp.delegate as? AppDelegate)?.showClientListMgr()
NSApp.activate(ignoringOtherApps: true)
}
@objc public func toggleSCPCTypingMode(_: Any? = nil) {
resetInputHandler()
Notifier.notify(
message: NSLocalizedString("Per-Char Select Mode", comment: "") + "\n"
+ (PrefMgr.shared.useSCPCTypingMode.toggled()
? NSLocalizedString("NotificationSwitchON", comment: "")
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
)
}
@objc public func toggleChineseConverter(_: Any?) {
resetInputHandler()
Notifier.notify(
message: NSLocalizedString("Force KangXi Writing", comment: "") + "\n"
+ (PrefMgr.shared.chineseConversionEnabled.toggled()
? NSLocalizedString("NotificationSwitchON", comment: "")
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
)
}
@objc public func toggleShiftJISShinjitaiOutput(_: Any?) {
resetInputHandler()
Notifier.notify(
message: NSLocalizedString("JIS Shinjitai Output", comment: "") + "\n"
+ (PrefMgr.shared.shiftJISShinjitaiOutputEnabled.toggled()
? NSLocalizedString("NotificationSwitchON", comment: "")
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
)
}
@objc public func toggleCurrencyNumerals(_: Any?) {
resetInputHandler()
Notifier.notify(
message: NSLocalizedString("Currency Numeral Output", comment: "") + "\n"
+ (PrefMgr.shared.currencyNumeralsEnabled.toggled()
? NSLocalizedString("NotificationSwitchON", comment: "")
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
)
}
@objc public func toggleHalfWidthPunctuation(_: Any?) {
resetInputHandler()
Notifier.notify(
message: NSLocalizedString("Half-Width Punctuation Mode", comment: "") + "\n"
+ (PrefMgr.shared.halfWidthPunctuationEnabled.toggled()
? NSLocalizedString("NotificationSwitchON", comment: "")
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
)
}
@objc public func toggleCNS11643Enabled(_: Any?) {
resetInputHandler()
Notifier.notify(
message: NSLocalizedString("CNS11643 Mode", comment: "") + "\n"
+ (PrefMgr.shared.cns11643Enabled.toggled()
? NSLocalizedString("NotificationSwitchON", comment: "")
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
)
}
@objc public func toggleSymbolEnabled(_: Any?) {
resetInputHandler()
Notifier.notify(
message: NSLocalizedString("Symbol & Emoji Input", comment: "") + "\n"
+ (PrefMgr.shared.symbolInputEnabled.toggled()
? NSLocalizedString("NotificationSwitchON", comment: "")
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
)
}
@objc public func toggleAssociatedPhrasesEnabled(_: Any?) {
resetInputHandler()
Notifier.notify(
message: NSLocalizedString("Per-Char Associated Phrases", comment: "") + "\n"
+ (PrefMgr.shared.associatedPhrasesEnabled.toggled()
? NSLocalizedString("NotificationSwitchON", comment: "")
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
)
}
@objc public func togglePhraseReplacement(_: Any?) {
resetInputHandler()
Notifier.notify(
message: NSLocalizedString("Use Phrase Replacement", comment: "") + "\n"
+ (PrefMgr.shared.phraseReplacementEnabled.toggled()
? NSLocalizedString("NotificationSwitchON", comment: "")
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
)
}
@objc public func selfUninstall(_: Any?) {
(NSApp.delegate as? AppDelegate)?.selfUninstall()
}
@objc public func selfTerminate(_: Any?) {
NSApp.activate(ignoringOtherApps: true)
NSApp.terminate(nil)
}
@objc public func checkForUpdate(_: Any?) {
(NSApp.delegate as? AppDelegate)?.updateSputnik.checkForUpdate(forced: true, url: kUpdateInfoSourceURL)
}
@objc public func openUserDataFolder(_: Any?) {
if !LMMgr.userDataFolderExists {
return
}
NSWorkspace.shared.openFile(
LMMgr.dataFolderPath(isDefaultFolder: false), withApplication: "Finder"
)
}
@objc public func openUserPhrases(_: Any?) {
LMMgr.openPhraseFile(fromURL: LMMgr.userPhrasesDataURL(IMEApp.currentInputMode))
if NSEvent.modifierFlags.contains(.option) {
LMMgr.openPhraseFile(fromURL: LMMgr.userPhrasesDataURL(IMEApp.currentInputMode.reversed))
}
}
@objc public func openExcludedPhrases(_: Any?) {
LMMgr.openPhraseFile(fromURL: LMMgr.userFilteredDataURL(IMEApp.currentInputMode))
if NSEvent.modifierFlags.contains(.option) {
LMMgr.openPhraseFile(fromURL: LMMgr.userFilteredDataURL(IMEApp.currentInputMode.reversed))
}
}
@objc public func openUserSymbols(_: Any?) {
LMMgr.openPhraseFile(fromURL: LMMgr.userSymbolDataURL(IMEApp.currentInputMode))
if NSEvent.modifierFlags.contains(.option) {
LMMgr.openPhraseFile(fromURL: LMMgr.userSymbolDataURL(IMEApp.currentInputMode.reversed))
}
}
@objc public func openPhraseReplacement(_: Any?) {
LMMgr.openPhraseFile(fromURL: LMMgr.userReplacementsDataURL(IMEApp.currentInputMode))
if NSEvent.modifierFlags.contains(.option) {
LMMgr.openPhraseFile(fromURL: LMMgr.userReplacementsDataURL(IMEApp.currentInputMode.reversed))
}
}
@objc public func openAssociatedPhrases(_: Any?) {
LMMgr.openPhraseFile(fromURL: LMMgr.userAssociatesDataURL(IMEApp.currentInputMode))
if NSEvent.modifierFlags.contains(.option) {
LMMgr.openPhraseFile(
fromURL: LMMgr.userAssociatesDataURL(IMEApp.currentInputMode.reversed))
}
}
@objc public func reloadUserPhrasesData(_: Any?) {
LMMgr.initUserLangModels()
}
@objc public func removeUnigramsFromUOM(_: Any?) {
LMMgr.removeUnigramsFromUserOverrideModel(IMEApp.currentInputMode)
if NSEvent.modifierFlags.contains(.option) {
LMMgr.removeUnigramsFromUserOverrideModel(IMEApp.currentInputMode.reversed)
}
}
@objc public func clearUOM(_: Any?) {
LMMgr.clearUserOverrideModelData(IMEApp.currentInputMode)
if NSEvent.modifierFlags.contains(.option) {
LMMgr.clearUserOverrideModelData(IMEApp.currentInputMode.reversed)
}
}
@objc public func showAbout(_: Any?) {
(NSApp.delegate as? AppDelegate)?.showAbout()
NSApp.activate(ignoringOtherApps: true)
}
}