diff --git a/Source/Modules/AppDelegate.swift b/Source/Modules/AppDelegate.swift
index dee2398f..debe25c1 100644
--- a/Source/Modules/AppDelegate.swift
+++ b/Source/Modules/AppDelegate.swift
@@ -29,6 +29,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, ctlNonModalAlertWindowDelega
@IBOutlet var window: NSWindow?
private var ctlPrefWindowInstance: ctlPrefWindow?
private var ctlAboutWindowInstance: ctlAboutWindow? // New About Window
+ private var WebWindowInstance: Any?
private var checkTask: URLSessionTask?
private var updateNextStepURL: URL?
public var fsStreamHelper = FSEventStreamHelper(
@@ -97,6 +98,22 @@ class AppDelegate: NSObject, NSApplicationDelegate, ctlNonModalAlertWindowDelega
NSApp.setActivationPolicy(.accessory)
}
+ func showCheatSheet() {
+ if #available(macOS 10.13, *) {
+ WebWindowInstance = ctlWebWindow.init(windowNibName: "frmWebWindow")
+ guard let WebWindowInstance = WebWindowInstance as? ctlWebWindow else { return }
+ guard let theWindow = WebWindowInstance.window else { return }
+ theWindow.center()
+ theWindow.orderFrontRegardless() // 逼著屬性視窗往最前方顯示
+ theWindow.level = .statusBar
+ theWindow.titlebarAppearsTransparent = true
+ theWindow.title = NSLocalizedString("CheatSheet", comment: "")
+ return
+ }
+ guard let url = Bundle.main.url(forResource: "shortcuts", withExtension: "html") else { return }
+ NSWorkspace.shared.openFile(url.path, withApplication: "Safari")
+ }
+
// New About Window
func showAbout() {
if ctlAboutWindowInstance == nil {
diff --git a/Source/Modules/ControllerModules/ctlInputMethod_Menu.swift b/Source/Modules/ControllerModules/ctlInputMethod_Menu.swift
index c6fabfe7..c891a03e 100644
--- a/Source/Modules/ControllerModules/ctlInputMethod_Menu.swift
+++ b/Source/Modules/ControllerModules/ctlInputMethod_Menu.swift
@@ -169,6 +169,10 @@ extension ctlInputMethod {
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: ""),
@@ -199,7 +203,12 @@ extension ctlInputMethod {
NSApp.activate(ignoringOtherApps: true)
}
- @objc func toggleSCPCTypingMode(_: Any?) {
+ @objc func showCheatSheet(_: Any?) {
+ (NSApp.delegate as? AppDelegate)?.showCheatSheet()
+ NSApp.activate(ignoringOtherApps: true)
+ }
+
+ @objc func toggleSCPCTypingMode(_: Any? = nil) {
resetKeyHandler()
NotifierController.notify(
message: String(
diff --git a/Source/Resources/Base.lproj/Localizable.strings b/Source/Resources/Base.lproj/Localizable.strings
index cc973995..f9e3112b 100644
--- a/Source/Resources/Base.lproj/Localizable.strings
+++ b/Source/Resources/Base.lproj/Localizable.strings
@@ -2,6 +2,7 @@
"vChewing crashed while handling previously loaded UOM observation data. These data files are cleaned now to ensure the usability." = "vChewing crashed while handling previously loaded UOM observation data. These data files are cleaned now to ensure the usability.";
"About vChewing…" = "About vChewing…";
"vChewing Preferences…" = "vChewing Preferences…";
+"CheatSheet" = "CheatSheet";
"Uninstallation" = "Uninstallation";
"Uninstall vChewing…" = "Uninstall vChewing…";
"This will remove vChewing Input Method from this user account, requiring your confirmation." = "This will remove vChewing Input Method from this user account, requiring your confirmation.";
diff --git a/Source/Resources/en.lproj/Localizable.strings b/Source/Resources/en.lproj/Localizable.strings
index cc973995..f9e3112b 100644
--- a/Source/Resources/en.lproj/Localizable.strings
+++ b/Source/Resources/en.lproj/Localizable.strings
@@ -2,6 +2,7 @@
"vChewing crashed while handling previously loaded UOM observation data. These data files are cleaned now to ensure the usability." = "vChewing crashed while handling previously loaded UOM observation data. These data files are cleaned now to ensure the usability.";
"About vChewing…" = "About vChewing…";
"vChewing Preferences…" = "vChewing Preferences…";
+"CheatSheet" = "CheatSheet";
"Uninstallation" = "Uninstallation";
"Uninstall vChewing…" = "Uninstall vChewing…";
"This will remove vChewing Input Method from this user account, requiring your confirmation." = "This will remove vChewing Input Method from this user account, requiring your confirmation.";
diff --git a/Source/Resources/ja.lproj/Localizable.strings b/Source/Resources/ja.lproj/Localizable.strings
index feb2120a..05ad98d4 100644
--- a/Source/Resources/ja.lproj/Localizable.strings
+++ b/Source/Resources/ja.lproj/Localizable.strings
@@ -3,6 +3,7 @@
"About vChewing…" = "威注音について…";
"vChewing Preferences…" = "入力機能設定…";
"Uninstallation" = "入力アプリの卸除(おろしのぞき)";
+"CheatSheet" = "取扱説明";
"Uninstall vChewing…" = "入力アプリを卸除く…";
"This will remove vChewing Input Method from this user account, requiring your confirmation." = "これにて威注音入力アプリをこのアカウントから卸除しますが、宜しいですか。";
"Check Later" = "後でやる";
diff --git a/Source/Resources/zh-Hans.lproj/Localizable.strings b/Source/Resources/zh-Hans.lproj/Localizable.strings
index be202492..b5169091 100644
--- a/Source/Resources/zh-Hans.lproj/Localizable.strings
+++ b/Source/Resources/zh-Hans.lproj/Localizable.strings
@@ -2,6 +2,7 @@
"vChewing crashed while handling previously loaded UOM observation data. These data files are cleaned now to ensure the usability." = "威注音输入法的使用者半衰记忆模组在观测时崩溃,相关半衰记忆资料档案内容已全部清空。";
"About vChewing…" = "关于威注音…";
"vChewing Preferences…" = "威注音偏好设定…";
+"CheatSheet" = "热键指南";
"Uninstallation" = "卸除输入法";
"Uninstall vChewing…" = "卸除威注音…";
"This will remove vChewing Input Method from this user account, requiring your confirmation." = "此举会将威注音自当前系统使用者帐户卸除。请确认。";
diff --git a/Source/Resources/zh-Hant.lproj/Localizable.strings b/Source/Resources/zh-Hant.lproj/Localizable.strings
index e7db5705..d0c5c1ac 100644
--- a/Source/Resources/zh-Hant.lproj/Localizable.strings
+++ b/Source/Resources/zh-Hant.lproj/Localizable.strings
@@ -2,6 +2,7 @@
"vChewing crashed while handling previously loaded UOM observation data. These data files are cleaned now to ensure the usability." = "威注音輸入法的使用者半衰記憶模組在觀測時崩潰,相關半衰記憶資料檔案內容已全部清空。";
"About vChewing…" = "關於威注音…";
"vChewing Preferences…" = "威注音偏好設定…";
+"CheatSheet" = "熱鍵指南";
"Uninstallation" = "卸除輸入法";
"Uninstall vChewing…" = "卸除威注音…";
"This will remove vChewing Input Method from this user account, requiring your confirmation." = "此舉會將威注音自當前系統使用者帳戶卸除。請確認。";
diff --git a/Source/WindowControllers/ctlWebWindow.swift b/Source/WindowControllers/ctlWebWindow.swift
new file mode 100644
index 00000000..901e8515
--- /dev/null
+++ b/Source/WindowControllers/ctlWebWindow.swift
@@ -0,0 +1,21 @@
+// Copyright (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
+import WebKit
+
+@available(macOS 10.13, *)
+class ctlWebWindow: NSWindowController, WKUIDelegate {
+ @IBOutlet var webView: WKWebView!
+
+ override func windowDidLoad() {
+ super.windowDidLoad()
+ guard let webPageURL = Bundle.main.url(forResource: "shortcuts", withExtension: "html") else { return }
+ webView.loadFileURL(webPageURL, allowingReadAccessTo: webPageURL)
+ }
+}
diff --git a/Source/WindowNIBs/Base.lproj/frmWebWindow.xib b/Source/WindowNIBs/Base.lproj/frmWebWindow.xib
new file mode 100644
index 00000000..64690365
--- /dev/null
+++ b/Source/WindowNIBs/Base.lproj/frmWebWindow.xib
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vChewing.xcodeproj/project.pbxproj b/vChewing.xcodeproj/project.pbxproj
index 005e6ba6..f30855b6 100644
--- a/vChewing.xcodeproj/project.pbxproj
+++ b/vChewing.xcodeproj/project.pbxproj
@@ -27,6 +27,8 @@
5B3A87BC28597CDB0090E163 /* LMSymbolNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B3A87BB28597CDB0090E163 /* LMSymbolNode.swift */; };
5B40730C281672610023DFFF /* lmAssociates.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B407309281672610023DFFF /* lmAssociates.swift */; };
5B40730D281672610023DFFF /* lmReplacements.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B40730A281672610023DFFF /* lmReplacements.swift */; };
+ 5B46794728B790A600941452 /* frmWebWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5B46794528B790A600941452 /* frmWebWindow.xib */; };
+ 5B46794928B790B900941452 /* ctlWebWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B46794828B790B900941452 /* ctlWebWindow.swift */; };
5B54E743283A7D89001ECBDC /* lmCoreNS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B54E742283A7D89001ECBDC /* lmCoreNS.swift */; };
5B5948CE289CC04500C85824 /* LMInstantiator_DateTimeExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B5948CD289CC04500C85824 /* LMInstantiator_DateTimeExtension.swift */; };
5B5E535227EF261400C6AA1E /* IME.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B5E535127EF261400C6AA1E /* IME.swift */; };
@@ -238,6 +240,8 @@
5B3A87BB28597CDB0090E163 /* LMSymbolNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LMSymbolNode.swift; sourceTree = ""; };
5B407309281672610023DFFF /* lmAssociates.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; lineEnding = 0; path = lmAssociates.swift; sourceTree = ""; usesTabs = 0; };
5B40730A281672610023DFFF /* lmReplacements.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; lineEnding = 0; path = lmReplacements.swift; sourceTree = ""; usesTabs = 0; };
+ 5B46794628B790A600941452 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/frmWebWindow.xib; sourceTree = ""; };
+ 5B46794828B790B900941452 /* ctlWebWindow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ctlWebWindow.swift; sourceTree = ""; };
5B54E742283A7D89001ECBDC /* lmCoreNS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = lmCoreNS.swift; sourceTree = ""; };
5B5948CD289CC04500C85824 /* LMInstantiator_DateTimeExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LMInstantiator_DateTimeExtension.swift; sourceTree = ""; };
5B5E535127EF261400C6AA1E /* IME.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = IME.swift; sourceTree = ""; tabWidth = 2; usesTabs = 0; };
@@ -571,6 +575,7 @@
5B62A33C27AE7CC100A19448 /* ctlAboutWindow.swift */,
D47F7DCF278C0897002F9DD7 /* ctlNonModalAlertWindow.swift */,
D47F7DCD278BFB57002F9DD7 /* ctlPrefWindow.swift */,
+ 5B46794828B790B900941452 /* ctlWebWindow.swift */,
);
path = WindowControllers;
sourceTree = "";
@@ -581,6 +586,7 @@
5BBBB76927AED5DB0023B93A /* frmAboutWindow.xib */,
5BBBB76527AED5DB0023B93A /* frmNonModalAlertWindow.xib */,
5B7BC4AE27AFFBE800F66C24 /* frmPrefWindow.xib */,
+ 5B46794528B790A600941452 /* frmWebWindow.xib */,
6A187E2816004C5900466B2E /* MainMenu.xib */,
);
path = WindowNIBs;
@@ -1045,6 +1051,7 @@
5BBBB77427AED70B0023B93A /* MenuIcon-SCVIM@2x.png in Resources */,
D4E33D8A27A838CF006DB1CF /* Localizable.strings in Resources */,
5BF9DA2828840E6200DBD48E /* template-exclusions.txt in Resources */,
+ 5B46794728B790A600941452 /* frmWebWindow.xib in Resources */,
5BDCBB2E27B4E67A00D0CC59 /* vChewingPhraseEditor.app in Resources */,
5BBBB76027AED54C0023B93A /* Fart.m4a in Resources */,
6A2E40F6253A69DA00D1AE1D /* Images.xcassets in Resources */,
@@ -1205,6 +1212,7 @@
5B2170E1289FACAD00BE7304 /* 0_Megrez.swift in Sources */,
5BF9EC1628A2BFC600333639 /* lmPlainBopomofo.swift in Sources */,
5B3A87BC28597CDB0090E163 /* LMSymbolNode.swift in Sources */,
+ 5B46794928B790B900941452 /* ctlWebWindow.swift in Sources */,
5BA9FD4327FEF3C8002DE248 /* Preferences.swift in Sources */,
5BA9FD4427FEF3C8002DE248 /* SegmentedControlStyleViewController.swift in Sources */,
5B78EE0D28A562B4009456C1 /* suiPrefPaneDevZone.swift in Sources */,
@@ -1299,6 +1307,14 @@
name = shortcuts.html;
sourceTree = "";
};
+ 5B46794528B790A600941452 /* frmWebWindow.xib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 5B46794628B790A600941452 /* Base */,
+ );
+ name = frmWebWindow.xib;
+ sourceTree = "";
+ };
5B73FB6027B2BE1300E9BF49 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (