diff --git a/DataCompiler/dataCompiler.swift b/DataCompiler/dataCompiler.swift index 7565a568..081a5f2d 100644 --- a/DataCompiler/dataCompiler.swift +++ b/DataCompiler/dataCompiler.swift @@ -21,9 +21,10 @@ import Foundation // MARK: - 前導工作 fileprivate extension String { mutating func regReplace(pattern: String, replaceWith: String = "") { + // Ref: https://stackoverflow.com/a/40993403/4162914 && https://stackoverflow.com/a/71291137/4162914 do { let regex = try NSRegularExpression(pattern: pattern, options: .caseInsensitive) - let range = NSRange(location: 0, length: count) + let range = NSRange(location: 0, length: self.utf16.count) self = regex.stringByReplacingMatches(in: self, options: [], range: range, withTemplate: replaceWith) } catch { return } } @@ -117,16 +118,13 @@ func rawDictForPhrases(isCHS: Bool) -> [Entry] { } // 預處理格式 strRAW = strRAW.replacingOccurrences(of: " #MACOS", with: "") // 去掉 macOS 標記 - strRAW = strRAW.replacingOccurrences(of: " ", with: " ") // CJKWhiteSpace (\x{3000}) to ASCII Space - strRAW = strRAW.replacingOccurrences(of: " ", with: " ") // NonBreakWhiteSpace (\x{A0}) to ASCII Space - strRAW = strRAW.replacingOccurrences(of: "\t", with: " ") // Tab to ASCII Space - strRAW.regReplace(pattern: "\\f", replaceWith: "\n") // Form Feed to LF - strRAW = strRAW.replacingOccurrences(of: "\r", with: "\n") // CR to LF - strRAW.regReplace(pattern: " +", replaceWith: " ") // 統整連續空格為一個 ASCII 空格 - // strRAW.regReplace(pattern: "\\n+", replaceWith: "\n") // 統整連續 LF 為一個 LF - // (不需要處理純空行,因為空記錄不會被轉為 Entry) - strRAW = strRAW.replacingOccurrences(of: " \n", with: "\n") // 去除行尾空格 - strRAW = strRAW.replacingOccurrences(of: "\n ", with: "\n") // 去除行首空格 + // CJKWhiteSpace (\x{3000}) to ASCII Space + // NonBreakWhiteSpace (\x{A0}) to ASCII Space + // Tab to ASCII Space + // 統整連續空格為一個 ASCII 空格 + strRAW.regReplace(pattern: #"( +| +| +|\t+)+"#, replaceWith: " ") + strRAW.regReplace(pattern: #"(\f+|\r+)+"#, replaceWith: "\n") // CR & Form Feed to LF + strRAW.regReplace(pattern: #"(\n+| \n+|\n+ )"#, replaceWith: "\n") // 去除行尾行首空格與重複行 if strRAW.prefix(1) == " " { // 去除檔案開頭空格 strRAW.removeFirst() } @@ -194,16 +192,13 @@ func rawDictForKanjis(isCHS: Bool) -> [Entry] { } // 預處理格式 strRAW = strRAW.replacingOccurrences(of: " #MACOS", with: "") // 去掉 macOS 標記 - strRAW = strRAW.replacingOccurrences(of: " ", with: " ") // CJKWhiteSpace (\x{3000}) to ASCII Space - strRAW = strRAW.replacingOccurrences(of: " ", with: " ") // NonBreakWhiteSpace (\x{A0}) to ASCII Space - strRAW = strRAW.replacingOccurrences(of: "\t", with: " ") // Tab to ASCII Space - strRAW.regReplace(pattern: "\\f", replaceWith: "\n") // Form Feed to LF - strRAW = strRAW.replacingOccurrences(of: "\r", with: "\n") // CR to LF - strRAW.regReplace(pattern: " +", replaceWith: " ") // 統整連續空格為一個 ASCII 空格 - // strRAW.regReplace(pattern: "\\n+", replaceWith: "\n") // 統整連續 LF 為一個 LF - // (不需要處理純空行,因為空記錄不會被轉為 Entry) - strRAW = strRAW.replacingOccurrences(of: " \n", with: "\n") // 去除行尾空格 - strRAW = strRAW.replacingOccurrences(of: "\n ", with: "\n") // 去除行首空格 + // CJKWhiteSpace (\x{3000}) to ASCII Space + // NonBreakWhiteSpace (\x{A0}) to ASCII Space + // Tab to ASCII Space + // 統整連續空格為一個 ASCII 空格 + strRAW.regReplace(pattern: #"( +| +| +|\t+)+"#, replaceWith: " ") + strRAW.regReplace(pattern: #"(\f+|\r+)+"#, replaceWith: "\n") // CR & Form Feed to LF + strRAW.regReplace(pattern: #"(\n+| \n+|\n+ )"#, replaceWith: "\n") // 去除行尾行首空格與重複行 if strRAW.prefix(1) == " " { // 去除檔案開頭空格 strRAW.removeFirst() } @@ -276,16 +271,13 @@ func rawDictForNonKanjis(isCHS: Bool) -> [Entry] { } // 預處理格式 strRAW = strRAW.replacingOccurrences(of: " #MACOS", with: "") // 去掉 macOS 標記 - strRAW = strRAW.replacingOccurrences(of: " ", with: " ") // CJKWhiteSpace (\x{3000}) to ASCII Space - strRAW = strRAW.replacingOccurrences(of: " ", with: " ") // NonBreakWhiteSpace (\x{A0}) to ASCII Space - strRAW = strRAW.replacingOccurrences(of: "\t", with: " ") // Tab to ASCII Space - strRAW.regReplace(pattern: "\\f", replaceWith: "\n") // Form Feed to LF - strRAW = strRAW.replacingOccurrences(of: "\r", with: "\n") // CR to LF - strRAW.regReplace(pattern: " +", replaceWith: " ") // 統整連續空格為一個 ASCII 空格 - // strRAW.regReplace(pattern: "\\n+", replaceWith: "\n") // 統整連續 LF 為一個 LF - // (不需要處理純空行,因為空記錄不會被轉為 Entry) - strRAW = strRAW.replacingOccurrences(of: " \n", with: "\n") // 去除行尾空格 - strRAW = strRAW.replacingOccurrences(of: "\n ", with: "\n") // 去除行首空格 + // CJKWhiteSpace (\x{3000}) to ASCII Space + // NonBreakWhiteSpace (\x{A0}) to ASCII Space + // Tab to ASCII Space + // 統整連續空格為一個 ASCII 空格 + strRAW.regReplace(pattern: #"( +| +| +|\t+)+"#, replaceWith: " ") + strRAW.regReplace(pattern: #"(\f+|\r+)+"#, replaceWith: "\n") // CR & Form Feed to LF + strRAW.regReplace(pattern: #"(\n+| \n+|\n+ )"#, replaceWith: "\n") // 去除行尾行首空格與重複行 if strRAW.prefix(1) == " " { // 去除檔案開頭空格 strRAW.removeFirst() } @@ -343,17 +335,23 @@ func weightAndSort(_ arrStructUncalculated: [Entry], isCHS: Bool) -> [Entry] { let fscale: Float = 2.7 var norm: Float = 0.0 for entry in arrStructUncalculated { - norm += fscale**(Float(entry.valPhrase.count) / 3.0 - 1.0) * Float(entry.valCount) // Credit: MJHsieh. + if entry.valCount >= 0 { + norm += fscale**(Float(entry.valPhrase.count) / 3.0 - 1.0) * Float(entry.valCount) + } } // norm 計算完畢,開始將 norm 作為新的固定常數來為每個詞條記錄計算權重。 // 將新酷音的詞語出現次數數據轉換成小麥引擎可讀的數據形式。 // 對出現次數小於 1 的詞條,將 0 當成 0.5 來處理、以防止除零。 - // 統計公式著作權歸 MJHsieh 所有(MIT License)。 for entry in arrStructUncalculated { - let weight: Float = (entry.valCount < 1) ? - log10(fscale**(Float(entry.valPhrase.count) / 3.0 - 1.0) * 0.5 / norm) // Credit: MJHsieh. - : - log10(fscale**(Float(entry.valPhrase.count) / 3.0 - 1.0) * Float(entry.valCount) / norm) // Credit: MJHsieh. + var weight: Float = 0 + switch entry.valCount { + case -1: // 假名 + weight = -13 + case 0: // 墊底低頻漢字與詞語 + weight = log10(fscale**(Float(entry.valPhrase.count) / 3.0 - 1.0) * 0.5 / norm) + default: + weight = log10(fscale**(Float(entry.valPhrase.count) / 3.0 - 1.0) * Float(entry.valCount) / norm) // Credit: MJHsieh. + } let weightRounded: Float = weight.rounded(toPlaces: 3) // 為了節省生成的檔案體積,僅保留小數點後三位。 arrStructCalculated += [Entry.init(valPhone: entry.valPhone, valPhrase: entry.valPhrase, valWeight: weightRounded, valCount: entry.valCount)] } diff --git a/Installer/pkgPostInstall.sh b/Installer/pkgPostInstall.sh new file mode 100644 index 00000000..737f7c4a --- /dev/null +++ b/Installer/pkgPostInstall.sh @@ -0,0 +1,3 @@ +#!/bin/sh +killall vChewing +rm -rf ~/Library/Input\ Methods/vChewing.app diff --git a/KeyboardExtension/Base.lproj/ShareViewController.xib b/KeyboardExtension/Base.lproj/ShareViewController.xib deleted file mode 100644 index bc80e0d6..00000000 --- a/KeyboardExtension/Base.lproj/ShareViewController.xib +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/KeyboardExtension/Info.plist b/KeyboardExtension/Info.plist deleted file mode 100644 index f275862c..00000000 --- a/KeyboardExtension/Info.plist +++ /dev/null @@ -1,23 +0,0 @@ - - - - - CFBundleIconFile - icon - NSExtension - - NSExtensionAttributes - - NSExtensionActivationRule - - NSExtensionActivationSupportsText - - - - NSExtensionPointIdentifier - com.apple.share-services - NSExtensionPrincipalClass - $(PRODUCT_MODULE_NAME).ShareViewController - - - diff --git a/KeyboardExtension/KeyboardExtension.entitlements b/KeyboardExtension/KeyboardExtension.entitlements deleted file mode 100644 index 33ede3bb..00000000 --- a/KeyboardExtension/KeyboardExtension.entitlements +++ /dev/null @@ -1,12 +0,0 @@ - - - - - com.apple.security.temporary-exception.mach-register.global-name - org_atelierInmu_inputmethod_vChewing - com.apple.security.app-sandbox - - com.apple.security.files.user-selected.read-only - - - diff --git a/KeyboardExtension/ShareViewController.swift b/KeyboardExtension/ShareViewController.swift deleted file mode 100644 index 75910d4c..00000000 --- a/KeyboardExtension/ShareViewController.swift +++ /dev/null @@ -1,41 +0,0 @@ -// -// ShareViewController.swift -// KeyboardExtension -// -// Created by ShikiSuen on 2022/2/20. -// - -import Cocoa - -class ShareViewController: NSViewController { - - override var nibName: NSNib.Name? { - return NSNib.Name("ShareViewController") - } - - override func loadView() { - super.loadView() - - // Insert code here to customize the view - let item = self.extensionContext!.inputItems[0] as! NSExtensionItem - if let attachments = item.attachments { - NSLog("Attachments = %@", attachments as NSArray) - } else { - NSLog("No Attachments") - } - } - - @IBAction func send(_ sender: AnyObject?) { - let outputItem = NSExtensionItem() - // Complete implementation by setting the appropriate value on the output item - - let outputItems = [outputItem] - self.extensionContext!.completeRequest(returningItems: outputItems, completionHandler: nil) -} - - @IBAction func cancel(_ sender: AnyObject?) { - let cancelError = NSError(domain: NSCocoaErrorDomain, code: NSUserCancelledError, userInfo: nil) - self.extensionContext!.cancelRequest(withError: cancelError) - } - -} diff --git a/KeyboardExtension/icon.icns b/KeyboardExtension/icon.icns deleted file mode 100644 index 84ae85cd..00000000 Binary files a/KeyboardExtension/icon.icns and /dev/null differ diff --git a/KeyboardExtension/vChewingKeyLayout.bundle/Contents/Info.plist b/KeyboardExtension/vChewingKeyLayout.bundle/Contents/Info.plist index 594e7ab6..fb4a77df 100644 --- a/KeyboardExtension/vChewingKeyLayout.bundle/Contents/Info.plist +++ b/KeyboardExtension/vChewingKeyLayout.bundle/Contents/Info.plist @@ -8,48 +8,48 @@ vChewingKeyLayout CFBundleVersion 1.0 - KLInfo_vChewingDachen + KLInfo_vChewing Dachen TICapsLockLanguageSwitchCapable TISInputSourceID - org.atelierInmu.keyboardlayout.vChewingKeyLayout.vChewingDachen + org.atelierInmu.vChewing.keyLayouts.vchewingdachen TISIntendedLanguage zh-Hanb - KLInfo_vChewingETen + KLInfo_vChewing ETen TICapsLockLanguageSwitchCapable TISInputSourceID - org.atelierInmu.keyboardlayout.vChewingKeyLayout.vChewingETen + org.atelierInmu.vChewing.keyLayouts.vchewingeten TISIntendedLanguage zh-Hanb - KLInfo_vChewingIBM + KLInfo_vChewing FakeSeigyou TICapsLockLanguageSwitchCapable TISInputSourceID - org.atelierInmu.keyboardlayout.vChewingKeyLayout.vChewingIBM + org.atelierInmu.vChewing.keyLayouts.vchewingfakeseigyou TISIntendedLanguage zh-Hanb - KLInfo_vChewingMiTAC + KLInfo_vChewing IBM TICapsLockLanguageSwitchCapable TISInputSourceID - org.atelierInmu.keyboardlayout.vChewingKeyLayout.vChewingMiTAC + org.atelierInmu.vChewing.keyLayouts.vchewingibm TISIntendedLanguage zh-Hanb - KLInfo_vChewingSeigyou + KLInfo_vChewing MiTAC TICapsLockLanguageSwitchCapable TISInputSourceID - org.atelierInmu.keyboardlayout.vChewingKeyLayout.vChewingSeigyou + org.atelierInmu.vChewing.keyLayouts.vchewingmitac TISIntendedLanguage zh-Hanb diff --git a/KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewingDachen.keylayout b/KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewing Dachen.keylayout similarity index 99% rename from KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewingDachen.keylayout rename to KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewing Dachen.keylayout index 19c784b8..c3057e80 100644 --- a/KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewingDachen.keylayout +++ b/KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewing Dachen.keylayout @@ -1,6 +1,6 @@ - + @@ -817,6 +817,7 @@ + diff --git a/KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewingETen.keylayout b/KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewing ETen.keylayout similarity index 99% rename from KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewingETen.keylayout rename to KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewing ETen.keylayout index 918c7780..4cc83d13 100644 --- a/KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewingETen.keylayout +++ b/KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewing ETen.keylayout @@ -1,6 +1,6 @@ - + @@ -817,6 +817,7 @@ + diff --git a/KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewingSeigyou.keylayout b/KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewing FakeSeigyou.keylayout similarity index 99% rename from KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewingSeigyou.keylayout rename to KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewing FakeSeigyou.keylayout index d153ef26..f52ebd3a 100644 --- a/KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewingSeigyou.keylayout +++ b/KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewing FakeSeigyou.keylayout @@ -1,7 +1,7 @@ - - + + @@ -66,19 +66,19 @@ - + - - + + - - + + - + @@ -492,6 +492,7 @@ + @@ -817,6 +818,7 @@ + diff --git a/KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewingIBM.keylayout b/KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewing IBM.keylayout similarity index 99% rename from KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewingIBM.keylayout rename to KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewing IBM.keylayout index 66ea8e1b..88e1c7ad 100644 --- a/KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewingIBM.keylayout +++ b/KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewing IBM.keylayout @@ -1,6 +1,6 @@ - + @@ -817,6 +817,7 @@ + diff --git a/KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewingMiTAC.keylayout b/KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewing MiTAC.keylayout similarity index 99% rename from KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewingMiTAC.keylayout rename to KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewing MiTAC.keylayout index c459b76a..248fbbb2 100644 --- a/KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewingMiTAC.keylayout +++ b/KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewing MiTAC.keylayout @@ -1,6 +1,6 @@ - + @@ -817,6 +817,7 @@ + diff --git a/KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/zh.lproj/InfoPlist.strings b/KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/zh.lproj/InfoPlist.strings index 128b7a66..17944c96 100644 Binary files a/KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/zh.lproj/InfoPlist.strings and b/KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/zh.lproj/InfoPlist.strings differ diff --git a/Source/3rdParty/OVMandarin/Mandarin.cpp b/Source/3rdParty/OVMandarin/Mandarin.cpp index d1f6d08e..53cbd299 100644 --- a/Source/3rdParty/OVMandarin/Mandarin.cpp +++ b/Source/3rdParty/OVMandarin/Mandarin.cpp @@ -22,7 +22,6 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH #include #include -namespace Taiyan { namespace Mandarin { class PinyinParseHelper { @@ -1034,5 +1033,5 @@ const BopomofoKeyboardLayout* BopomofoKeyboardLayout::HanyuPinyinLayout() { } } // namespace Mandarin -} // namespace Taiyan + diff --git a/Source/3rdParty/OVMandarin/Mandarin.h b/Source/3rdParty/OVMandarin/Mandarin.h index bb0ec5de..e8a24708 100644 --- a/Source/3rdParty/OVMandarin/Mandarin.h +++ b/Source/3rdParty/OVMandarin/Mandarin.h @@ -25,7 +25,6 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH #include #include -namespace Taiyan { namespace Mandarin { class BopomofoSyllable { @@ -471,6 +470,6 @@ protected: std::string pinyin_sequence_; }; } // namespace Mandarin -} // namespace Taiyan + #endif // MANDARIN_H_ diff --git a/Source/Data b/Source/Data index 4d01ae8b..8090069b 160000 --- a/Source/Data +++ b/Source/Data @@ -1 +1 @@ -Subproject commit 4d01ae8b9bd650c4f501b3ef4f5294b7e217ef9a +Subproject commit 8090069bc5eefa2a58ade7dda1aaadb0d11855e9 diff --git a/Source/Modules/AppDelegate.swift b/Source/Modules/AppDelegate.swift index 3c5133b1..c0e51087 100644 --- a/Source/Modules/AppDelegate.swift +++ b/Source/Modules/AppDelegate.swift @@ -198,6 +198,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, ctlNonModalAlertWindowDelega } ctlPrefWindowInstance?.window?.center() ctlPrefWindowInstance?.window?.orderFrontRegardless() // 逼著屬性視窗往最前方顯示 + ctlPrefWindowInstance?.window?.level = .statusBar } // New About Window @@ -207,6 +208,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, ctlNonModalAlertWindowDelega } ctlAboutWindowInstance?.window?.center() ctlAboutWindowInstance?.window?.orderFrontRegardless() // 逼著關於視窗往最前方顯示 + ctlAboutWindowInstance?.window?.level = .statusBar } @objc(checkForUpdate) diff --git a/Source/Modules/ControllerModules/AppleKeyboardConverter.swift b/Source/Modules/ControllerModules/AppleKeyboardConverter.swift index 187ffb4c..bd5adf67 100644 --- a/Source/Modules/ControllerModules/AppleKeyboardConverter.swift +++ b/Source/Modules/ControllerModules/AppleKeyboardConverter.swift @@ -25,18 +25,85 @@ import Cocoa return true case "com.apple.keylayout.ZhuyinEten": return true + case "org.atelierInmu.vChewing.keyLayouts.vchewingdachen": + return true + case "org.atelierInmu.vChewing.keyLayouts.vchewingmitac": + return true + case "org.atelierInmu.vChewing.keyLayouts.vchewingibm": + return true + case "org.atelierInmu.vChewing.keyLayouts.vchewingseigyou": + return true + case "org.atelierInmu.vChewing.keyLayouts.vchewingeten": + return true default: return false } } - // 處理 Apple 注音鍵盤佈局類型 + // 處理 Apple 注音鍵盤佈局類型。 @objc class func cnvApple2ABC(_ charCode: UniChar) -> UniChar { var charCode = charCode // 在按鍵資訊被送往 OVMandarin 之前,先轉換為可以被 OVMandarin 正常處理的資訊。 if self.isDynamicBaseKeyboardLayoutEnabled() { - // 保證 Apple 大千佈局內的符號鍵正常工作 - if charCode == 45 && (Preferences.basisKeyboardLayout == "com.apple.keylayout.ZhuyinBopomofo") { charCode = UniChar(96) } - if charCode == 183 && (Preferences.basisKeyboardLayout == "com.apple.keylayout.ZhuyinEten") { charCode = UniChar(96) } + // 針對不同的 Apple 動態鍵盤佈局糾正大寫英文輸入。 + switch Preferences.basisKeyboardLayout { + case "com.apple.keylayout.ZhuyinBopomofo": do { + if (charCode == 97) {charCode = UniChar(65)} + if (charCode == 98) {charCode = UniChar(66)} + if (charCode == 99) {charCode = UniChar(67)} + if (charCode == 100) {charCode = UniChar(68)} + if (charCode == 101) {charCode = UniChar(69)} + if (charCode == 102) {charCode = UniChar(70)} + if (charCode == 103) {charCode = UniChar(71)} + if (charCode == 104) {charCode = UniChar(72)} + if (charCode == 105) {charCode = UniChar(73)} + if (charCode == 106) {charCode = UniChar(74)} + if (charCode == 107) {charCode = UniChar(75)} + if (charCode == 108) {charCode = UniChar(76)} + if (charCode == 109) {charCode = UniChar(77)} + if (charCode == 110) {charCode = UniChar(78)} + if (charCode == 111) {charCode = UniChar(79)} + if (charCode == 112) {charCode = UniChar(80)} + if (charCode == 113) {charCode = UniChar(81)} + if (charCode == 114) {charCode = UniChar(82)} + if (charCode == 115) {charCode = UniChar(83)} + if (charCode == 116) {charCode = UniChar(84)} + if (charCode == 117) {charCode = UniChar(85)} + if (charCode == 118) {charCode = UniChar(86)} + if (charCode == 119) {charCode = UniChar(87)} + if (charCode == 120) {charCode = UniChar(88)} + if (charCode == 121) {charCode = UniChar(89)} + if (charCode == 122) {charCode = UniChar(90)} + } + case "com.apple.keylayout.ZhuyinEten": do { + if (charCode == 65345) {charCode = UniChar(65)} + if (charCode == 65346) {charCode = UniChar(66)} + if (charCode == 65347) {charCode = UniChar(67)} + if (charCode == 65348) {charCode = UniChar(68)} + if (charCode == 65349) {charCode = UniChar(69)} + if (charCode == 65350) {charCode = UniChar(70)} + if (charCode == 65351) {charCode = UniChar(71)} + if (charCode == 65352) {charCode = UniChar(72)} + if (charCode == 65353) {charCode = UniChar(73)} + if (charCode == 65354) {charCode = UniChar(74)} + if (charCode == 65355) {charCode = UniChar(75)} + if (charCode == 65356) {charCode = UniChar(76)} + if (charCode == 65357) {charCode = UniChar(77)} + if (charCode == 65358) {charCode = UniChar(78)} + if (charCode == 65359) {charCode = UniChar(79)} + if (charCode == 65360) {charCode = UniChar(80)} + if (charCode == 65361) {charCode = UniChar(81)} + if (charCode == 65362) {charCode = UniChar(82)} + if (charCode == 65363) {charCode = UniChar(83)} + if (charCode == 65364) {charCode = UniChar(84)} + if (charCode == 65365) {charCode = UniChar(85)} + if (charCode == 65366) {charCode = UniChar(86)} + if (charCode == 65367) {charCode = UniChar(87)} + if (charCode == 65368) {charCode = UniChar(88)} + if (charCode == 65369) {charCode = UniChar(89)} + if (charCode == 65370) {charCode = UniChar(90)} + } + default: break + } // 注音鍵群。 if (charCode == 12573) {charCode = UniChar(44)} if (charCode == 12582) {charCode = UniChar(45)} @@ -98,6 +165,14 @@ import Cocoa if (charCode == 65290) {charCode = UniChar(42)} if (charCode == 65288) {charCode = UniChar(40)} if (charCode == 65289) {charCode = UniChar(41)} + // Apple 倚天注音佈局追加符號糾正項目。 + if Preferences.basisKeyboardLayout == "com.apple.keylayout.ZhuyinEten" { + if (charCode == 65343) {charCode = UniChar(95)} + if (charCode == 65306) {charCode = UniChar(58)} + if (charCode == 65311) {charCode = UniChar(63)} + if (charCode == 65291) {charCode = UniChar(43)} + if (charCode == 65372) {charCode = UniChar(124)} + } } return charCode } @@ -105,9 +180,66 @@ import Cocoa @objc class func cnvStringApple2ABC(_ strProcessed: String) -> String { var strProcessed = strProcessed if self.isDynamicBaseKeyboardLayoutEnabled() { - // 保證 Apple 大千佈局內的符號鍵正常工作 - if (strProcessed == "-" && Preferences.basisKeyboardLayout == "com.apple.keylayout.ZhuyinBopomofo") { strProcessed = "`" } - if (strProcessed == "·" && Preferences.basisKeyboardLayout == "com.apple.keylayout.ZhuyinEten") { strProcessed = "`" } + // 針對不同的 Apple 動態鍵盤佈局糾正大寫英文輸入。 + switch Preferences.basisKeyboardLayout { + case "com.apple.keylayout.ZhuyinBopomofo": do { + if (strProcessed == "a") {strProcessed = "A"} + if (strProcessed == "b") {strProcessed = "B"} + if (strProcessed == "c") {strProcessed = "C"} + if (strProcessed == "d") {strProcessed = "D"} + if (strProcessed == "e") {strProcessed = "E"} + if (strProcessed == "f") {strProcessed = "F"} + if (strProcessed == "g") {strProcessed = "G"} + if (strProcessed == "h") {strProcessed = "H"} + if (strProcessed == "i") {strProcessed = "I"} + if (strProcessed == "j") {strProcessed = "J"} + if (strProcessed == "k") {strProcessed = "K"} + if (strProcessed == "l") {strProcessed = "L"} + if (strProcessed == "m") {strProcessed = "M"} + if (strProcessed == "n") {strProcessed = "N"} + if (strProcessed == "o") {strProcessed = "O"} + if (strProcessed == "p") {strProcessed = "P"} + if (strProcessed == "q") {strProcessed = "Q"} + if (strProcessed == "r") {strProcessed = "R"} + if (strProcessed == "s") {strProcessed = "S"} + if (strProcessed == "t") {strProcessed = "T"} + if (strProcessed == "u") {strProcessed = "U"} + if (strProcessed == "v") {strProcessed = "V"} + if (strProcessed == "w") {strProcessed = "W"} + if (strProcessed == "x") {strProcessed = "X"} + if (strProcessed == "y") {strProcessed = "Y"} + if (strProcessed == "z") {strProcessed = "Z"} + } + case "com.apple.keylayout.ZhuyinEten": do { + if (strProcessed == "a") {strProcessed = "A"} + if (strProcessed == "b") {strProcessed = "B"} + if (strProcessed == "c") {strProcessed = "C"} + if (strProcessed == "d") {strProcessed = "D"} + if (strProcessed == "e") {strProcessed = "E"} + if (strProcessed == "f") {strProcessed = "F"} + if (strProcessed == "g") {strProcessed = "G"} + if (strProcessed == "h") {strProcessed = "H"} + if (strProcessed == "i") {strProcessed = "I"} + if (strProcessed == "j") {strProcessed = "J"} + if (strProcessed == "k") {strProcessed = "K"} + if (strProcessed == "l") {strProcessed = "L"} + if (strProcessed == "m") {strProcessed = "M"} + if (strProcessed == "n") {strProcessed = "N"} + if (strProcessed == "o") {strProcessed = "O"} + if (strProcessed == "p") {strProcessed = "P"} + if (strProcessed == "q") {strProcessed = "Q"} + if (strProcessed == "r") {strProcessed = "R"} + if (strProcessed == "s") {strProcessed = "S"} + if (strProcessed == "t") {strProcessed = "T"} + if (strProcessed == "u") {strProcessed = "U"} + if (strProcessed == "v") {strProcessed = "V"} + if (strProcessed == "w") {strProcessed = "W"} + if (strProcessed == "x") {strProcessed = "X"} + if (strProcessed == "y") {strProcessed = "Y"} + if (strProcessed == "z") {strProcessed = "Z"} + } + default: break + } // 注音鍵群。 if (strProcessed == "ㄝ") {strProcessed = ","} if (strProcessed == "ㄦ") {strProcessed = "-"} @@ -169,6 +301,14 @@ import Cocoa if (strProcessed == "*") {strProcessed = "*"} if (strProcessed == "(") {strProcessed = "("} if (strProcessed == ")") {strProcessed = ")"} + // Apple 倚天注音佈局追加符號糾正項目。 + if Preferences.basisKeyboardLayout == "com.apple.keylayout.ZhuyinEten" { + if (strProcessed == "_") {strProcessed = "_"} + if (strProcessed == ":") {strProcessed = ":"} + if (strProcessed == "?") {strProcessed = "?"} + if (strProcessed == "+") {strProcessed = "+"} + if (strProcessed == "|") {strProcessed = "|"} + } } return strProcessed } diff --git a/Source/Modules/ControllerModules/KeyHandler.mm b/Source/Modules/ControllerModules/KeyHandler.mm index 78e760e8..e7dc6a61 100644 --- a/Source/Modules/ControllerModules/KeyHandler.mm +++ b/Source/Modules/ControllerModules/KeyHandler.mm @@ -33,7 +33,7 @@ InputMode imeModeNULL = @"org.atelierInmu.inputmethod.vChewing.IMENULL"; static const double kEpsilon = 0.000001; -static double FindHighestScore(const std::vector &nodes, double epsilon) { +static double FindHighestScore(const std::vector &nodes, double epsilon) { double highestScore = 0.0; for (auto ni = nodes.begin(), ne = nodes.end(); ni != ne; ++ni) { double score = ni->node->highestUnigramScore(); @@ -46,7 +46,7 @@ static double FindHighestScore(const std::vectorkey().length() > b.node->key().length(); } @@ -62,7 +62,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot"; @implementation KeyHandler { // the reading buffer that takes user input - Taiyan::Mandarin::BopomofoReadingBuffer *_bpmfReadingBuffer; + Mandarin::BopomofoReadingBuffer *_bpmfReadingBuffer; // language model vChewing::LMInstantiator *_languageModel; @@ -71,10 +71,10 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot"; vChewing::UserOverrideModel *_userOverrideModel; // the grid (lattice) builder for the unigrams (and bigrams) - Taiyan::Gramambular::BlockReadingBuilder *_builder; + Gramambular::BlockReadingBuilder *_builder; // latest walked path (trellis) using the Viterbi algorithm - std::vector _walkedNodes; + std::vector _walkedNodes; NSString *_inputMode; } @@ -111,7 +111,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot"; newUserOverrideModel = [mgrLangModel userOverrideModelCHT]; } - // Symchronize the Preference Setting "setPhraseReplacementEnabled" to the new LM. + // Synchronize the Preference Setting "setPhraseReplacementEnabled" to the new LM. newLanguageModel->setPhraseReplacementEnabled(Preferences.phraseReplacementEnabled); // Only apply the changes if the value is changed @@ -122,7 +122,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot"; if (_builder) { delete _builder; - _builder = new Taiyan::Gramambular::BlockReadingBuilder(_languageModel); + _builder = new Gramambular::BlockReadingBuilder(_languageModel); _builder->setJoinSeparator("-"); } @@ -148,15 +148,16 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot"; { self = [super init]; if (self) { - _bpmfReadingBuffer = new Taiyan::Mandarin::BopomofoReadingBuffer(Taiyan::Mandarin::BopomofoKeyboardLayout::StandardLayout()); + _bpmfReadingBuffer = new Mandarin::BopomofoReadingBuffer(Mandarin::BopomofoKeyboardLayout::StandardLayout()); // create the lattice builder _languageModel = [mgrLangModel lmCHT]; _languageModel->setPhraseReplacementEnabled(Preferences.phraseReplacementEnabled); _languageModel->setCNSEnabled(Preferences.cns11643Enabled); + _languageModel->setSymbolEnabled(Preferences.symbolInputEnabled); _userOverrideModel = [mgrLangModel userOverrideModelCHT]; - _builder = new Taiyan::Gramambular::BlockReadingBuilder(_languageModel); + _builder = new Gramambular::BlockReadingBuilder(_languageModel); // each Mandarin syllable is separated by a hyphen _builder->setJoinSeparator("-"); @@ -170,31 +171,31 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot"; NSInteger layout = Preferences.keyboardLayout; switch (layout) { case KeyboardLayoutStandard: - _bpmfReadingBuffer->setKeyboardLayout(Taiyan::Mandarin::BopomofoKeyboardLayout::StandardLayout()); + _bpmfReadingBuffer->setKeyboardLayout(Mandarin::BopomofoKeyboardLayout::StandardLayout()); break; case KeyboardLayoutEten: - _bpmfReadingBuffer->setKeyboardLayout(Taiyan::Mandarin::BopomofoKeyboardLayout::ETenLayout()); + _bpmfReadingBuffer->setKeyboardLayout(Mandarin::BopomofoKeyboardLayout::ETenLayout()); break; case KeyboardLayoutHsu: - _bpmfReadingBuffer->setKeyboardLayout(Taiyan::Mandarin::BopomofoKeyboardLayout::HsuLayout()); + _bpmfReadingBuffer->setKeyboardLayout(Mandarin::BopomofoKeyboardLayout::HsuLayout()); break; case KeyboardLayoutEten26: - _bpmfReadingBuffer->setKeyboardLayout(Taiyan::Mandarin::BopomofoKeyboardLayout::ETen26Layout()); + _bpmfReadingBuffer->setKeyboardLayout(Mandarin::BopomofoKeyboardLayout::ETen26Layout()); break; case KeyboardLayoutIBM: - _bpmfReadingBuffer->setKeyboardLayout(Taiyan::Mandarin::BopomofoKeyboardLayout::IBMLayout()); + _bpmfReadingBuffer->setKeyboardLayout(Mandarin::BopomofoKeyboardLayout::IBMLayout()); break; case KeyboardLayoutMiTAC: - _bpmfReadingBuffer->setKeyboardLayout(Taiyan::Mandarin::BopomofoKeyboardLayout::MiTACLayout()); + _bpmfReadingBuffer->setKeyboardLayout(Mandarin::BopomofoKeyboardLayout::MiTACLayout()); break; case KeyboardLayoutFakeSeigyou: - _bpmfReadingBuffer->setKeyboardLayout(Taiyan::Mandarin::BopomofoKeyboardLayout::FakeSeigyouLayout()); + _bpmfReadingBuffer->setKeyboardLayout(Mandarin::BopomofoKeyboardLayout::FakeSeigyouLayout()); break; case KeyboardLayoutHanyuPinyin: - _bpmfReadingBuffer->setKeyboardLayout(Taiyan::Mandarin::BopomofoKeyboardLayout::HanyuPinyinLayout()); + _bpmfReadingBuffer->setKeyboardLayout(Mandarin::BopomofoKeyboardLayout::HanyuPinyinLayout()); break; default: - _bpmfReadingBuffer->setKeyboardLayout(Taiyan::Mandarin::BopomofoKeyboardLayout::StandardLayout()); + _bpmfReadingBuffer->setKeyboardLayout(Mandarin::BopomofoKeyboardLayout::StandardLayout()); Preferences.keyboardLayout = KeyboardLayoutStandard; } } @@ -203,7 +204,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot"; { size_t cursorIndex = [self _actualCandidateCursorIndex]; std::string stringValue(value.UTF8String); - Taiyan::Gramambular::NodeAnchor selectedNode = _builder->grid().fixNodeSelectedCandidate(cursorIndex, stringValue); + Gramambular::NodeAnchor selectedNode = _builder->grid().fixNodeSelectedCandidate(cursorIndex, stringValue); if (!Preferences.useSCPCTypingMode) { // 不要針對逐字選字模式啟用臨時半衰記憶模型。 // If the length of the readings and the characters do not match, // it often means it is a special symbol and it should not be stored @@ -272,18 +273,23 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot"; return NO; } - // Caps Lock processing : if Caps Lock is on, temporarily disable bopomofo. + // Caps Lock processing: if Caps Lock is on or Preferences.isAlphanumericalModeEnabled, temporarily disable bopomofo. + // Also: Alphanumerical mode processing. if ([input isBackSpace] || [input isEnter] || [input isAbsorbedArrowKey] || [input isExtraChooseCandidateKey] || [input isExtraChooseCandidateKeyReverse] || [input isCursorForward] || [input isCursorBackward]) { // do nothing if backspace is pressed -- we ignore the key - } else if ([input isCapsLockOn]) { + } else if (Preferences.isAlphanumericalModeEnabled || [input isCapsLockOn]) { // process all possible combination, we hope. [self clear]; InputStateEmpty *emptyState = [[InputStateEmpty alloc] init]; stateCallback(emptyState); - // first commit everything in the buffer. - if ([input isShiftHold]) { - return NO; + // Non-Dynamic Keyboard Layouts Only: When shift is pressed, don't do further processing, since it outputs capital letter anyway. + if ((![Preferences.basisKeyboardLayout isEqual: @"com.apple.keylayout.ZhuyinBopomofo"] + && ![Preferences.basisKeyboardLayout isEqual: @"com.apple.keylayout.ZhuyinEten"]) + || [input isCapsLockOn]){ + if ([input isShiftHold]) { + return NO; + } } // if ASCII but not printable, don't use insertText:replacementRange: as many apps don't handle non-ASCII char insertions. @@ -291,10 +297,11 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot"; return NO; } - // when shift is pressed, don't do further processing, since it outputs capital letter anyway. + // commit everything in the buffer. InputStateCommitting *committingState = [[InputStateCommitting alloc] initWithPoppedText:[input.inputText lowercaseString]]; stateCallback(committingState); stateCallback(emptyState); + return YES; } @@ -383,7 +390,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot"; if (!overrideValue.empty()) { size_t cursorIndex = [self _actualCandidateCursorIndex]; - std::vector nodes = _builder->grid().nodesCrossingOrEndingAt(cursorIndex); + std::vector nodes = _builder->grid().nodesCrossingOrEndingAt(cursorIndex); double highestScore = FindHighestScore(nodes, kEpsilon); _builder->grid().overrideNodeScoreForSelectedCandidate(cursorIndex, overrideValue, static_cast(highestScore)); } @@ -518,7 +525,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot"; // MARK: Enter if ([input isEnter]) { if ([input isControlHold]) { - if (ctlInputMethod.areWeUsingOurOwnPhraseEditor) { + if (ctlInputMethod.areWeUsingOurOwnPhraseEditor || [input isCommandHold]) { return [self _handleCtrlEnterWithState:state stateCallback:stateCallback errorCallback:errorCallback]; } } @@ -526,7 +533,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot"; } // MARK: Punctuation list - if ([input isSymbolMenuKey]) { + if ([input isSymbolMenuPhysicalKey] && ![input isShiftHold]) { // 得在這裡先 commit buffer,不然會導致「在摁 ESC 離開符號選單時會重複輸入上一次的組字區的內容」的不當行為。 // 於是這裡用「模擬一次 Enter 鍵的操作」使其代為執行這個 commit buffer 的動作。 @@ -844,12 +851,10 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot"; - (BOOL)_handleCtrlEnterWithState:(InputState *)state stateCallback:(void (^)(InputState *))stateCallback errorCallback:(void (^)(void))errorCallback { - if (![state isKindOfClass:[InputStateInputting class]]) { - return NO; - } + if (![state isKindOfClass:[InputStateInputting class]]) return NO; NSArray *readings = [self _currentReadings]; - NSString *composingBuffer = [readings componentsJoinedByString:@"-"]; + NSString *composingBuffer = (ctlInputMethod.areWeUsingOurOwnPhraseEditor) ? [readings componentsJoinedByString:@"-"] : [readings componentsJoinedByString:@" "] ; [self clear]; @@ -1046,7 +1051,21 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot"; return YES; } - if ([input isSpace] || [input isPageDown] || input.emacsKey == vChewingEmacsKeyNextPage) { + if ([input isSpace]) { + BOOL updated = + Preferences.specifySpaceKeyBehavior? + ([input isShiftHold] ? [gCurrentCandidateController highlightNextCandidate] : [gCurrentCandidateController showNextPage]) + : + ([input isShiftHold] ? [gCurrentCandidateController showNextPage] : [gCurrentCandidateController highlightNextCandidate]) + ; + if (!updated) { + [IME prtDebugIntel:@"A11C781F"]; + errorCallback(); + } + return YES; + } + + if ([input isPageDown] || input.emacsKey == vChewingEmacsKeyNextPage) { BOOL updated = [gCurrentCandidateController showNextPage]; if (!updated) { [IME prtDebugIntel:@"9B691919"]; @@ -1275,7 +1294,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot"; // we must do some Unicode codepoint counting to find the actual cursor location for the client // i.e. we need to take UTF-16 into consideration, for which a surrogate pair takes 2 UniChars // locations - for (std::vector::iterator wi = _walkedNodes.begin(), we = _walkedNodes.end(); wi != we; ++wi) { + for (std::vector::iterator wi = _walkedNodes.begin(), we = _walkedNodes.end(); wi != we; ++wi) { if ((*wi).node) { std::string nodeStr = (*wi).node->currentKeyValue().value; NSString *valueString = [NSString stringWithUTF8String:nodeStr.c_str()]; @@ -1343,7 +1362,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot"; // retrieve the most likely trellis, i.e. a Maximum Likelihood Estimation // of the best possible Mandarain characters given the input syllables, // using the Viterbi algorithm implemented in the Gramambular library - Taiyan::Gramambular::Walker walker(&_builder->grid()); + Gramambular::Walker walker(&_builder->grid()); // the reverse walk traces the trellis from the end _walkedNodes = walker.reverseWalk(_builder->grid().width()); @@ -1376,7 +1395,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot"; if (_builder->grid().width() > (size_t) composingBufferSize) { if (_walkedNodes.size() > 0) { - Taiyan::Gramambular::NodeAnchor &anchor = _walkedNodes[0]; + Gramambular::NodeAnchor &anchor = _walkedNodes[0]; poppedText = [NSString stringWithUTF8String:anchor.node->currentKeyValue().value.c_str()]; _builder->removeHeadReadings(anchor.spanningLength); } @@ -1391,15 +1410,15 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot"; NSMutableArray *candidatesArray = [[NSMutableArray alloc] init]; size_t cursorIndex = [self _actualCandidateCursorIndex]; - std::vector nodes = _builder->grid().nodesCrossingOrEndingAt(cursorIndex); + std::vector nodes = _builder->grid().nodesCrossingOrEndingAt(cursorIndex); // sort the nodes, so that longer nodes (representing longer phrases) are placed at the top of the candidate list stable_sort(nodes.begin(), nodes.end(), NodeAnchorDescendingSorter()); // then use the C++ trick to retrieve the candidates for each node at/crossing the cursor - for (std::vector::iterator ni = nodes.begin(), ne = nodes.end(); ni != ne; ++ni) { - const std::vector &candidates = (*ni).node->candidates(); - for (std::vector::const_iterator ci = candidates.begin(), ce = candidates.end(); ci != ce; ++ci) { + for (std::vector::iterator ni = nodes.begin(), ne = nodes.end(); ni != ne; ++ni) { + const std::vector &candidates = (*ni).node->candidates(); + for (std::vector::const_iterator ci = candidates.begin(), ce = candidates.end(); ci != ce; ++ci) { [candidatesArray addObject:[NSString stringWithUTF8String:(*ci).value.c_str()]]; } } @@ -1411,15 +1430,10 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot"; - (size_t)_actualCandidateCursorIndex { size_t cursorIndex = _builder->cursorIndex(); - if (Preferences.selectPhraseAfterCursorAsCandidate) { - // MS Phonetics IME style, phrase is *after* the cursor, i.e. cursor is always *before* the phrase - if (cursorIndex < _builder->length()) { - ++cursorIndex; - } - } else { - if (!cursorIndex) { - ++cursorIndex; - } + // MS Phonetics IME style, phrase is *after* the cursor, i.e. cursor is always *before* the phrase + if ((Preferences.selectPhraseAfterCursorAsCandidate && (cursorIndex < _builder->length())) + || !cursorIndex) { + ++cursorIndex; } return cursorIndex; diff --git a/Source/Modules/ControllerModules/KeyHandlerInput.swift b/Source/Modules/ControllerModules/KeyHandlerInput.swift index dc087714..7ab70873 100644 --- a/Source/Modules/ControllerModules/KeyHandlerInput.swift +++ b/Source/Modules/ControllerModules/KeyHandlerInput.swift @@ -21,7 +21,7 @@ import Cocoa // Use KeyCodes as much as possible since its recognition won't be affected by macOS Base Keyboard Layouts. // KeyCodes: https://eastmanreference.com/complete-list-of-applescript-key-codes -enum KeyCode: UInt16 { +@objc enum KeyCode: UInt16 { case none = 0 case space = 49 case backSpace = 51 @@ -38,11 +38,16 @@ enum KeyCode: UInt16 { case home = 115 case end = 119 case delete = 117 + case leftShift = 56 + case rightShift = 60 + case capsLock = 57 + case symbolMenuPhysicalKey = 50 } // CharCodes: https://theasciicode.com.ar/ascii-control-characters/horizontal-tab-ascii-code-9.html -enum CharCode: UInt16 { - case symbolMenuKey_ABC = 96 +enum CharCode: UInt/*16*/ { + case yajuusenpai = 1145141919810893 + // - CharCode is not reliable at all. KeyCode is the most accurate. KeyCode doesn't give a phuque about the character sent through macOS keyboard layouts but only focuses on which physical key is pressed. } class KeyHandlerInput: NSObject { @@ -51,6 +56,7 @@ class KeyHandlerInput: NSObject { @objc private (set) var inputTextIgnoringModifiers: String? @objc private (set) var charCode: UInt16 @objc private (set) var keyCode: UInt16 + private var isFlagChanged: Bool private var flags: NSEvent.ModifierFlags private var cursorForwardKey: KeyCode private var cursorBackwardKey: KeyCode @@ -68,6 +74,7 @@ class KeyHandlerInput: NSObject { self.keyCode = keyCode self.charCode = AppleKeyboardConverter.cnvApple2ABC(charCode) self.flags = flags + self.isFlagChanged = false useVerticalMode = isVerticalMode emacsKey = EmacsKeyHelper.detect(charCode: AppleKeyboardConverter.cnvApple2ABC(charCode), flags: flags) cursorForwardKey = useVerticalMode ? .down : .right @@ -84,6 +91,7 @@ class KeyHandlerInput: NSObject { inputTextIgnoringModifiers = AppleKeyboardConverter.cnvStringApple2ABC(event.charactersIgnoringModifiers ?? "") keyCode = event.keyCode flags = event.modifierFlags + isFlagChanged = (event.type == .flagsChanged) ? true : false useVerticalMode = isVerticalMode let charCode: UInt16 = { guard let inputText = event.characters, inputText.count > 0 else { @@ -225,9 +233,10 @@ class KeyHandlerInput: NSObject { KeyCode(rawValue: keyCode) == verticalModeOnlyChooseCandidateKey } - @objc var isSymbolMenuKey: Bool { - // 這裡用 CharCode 更合適,不然就無法輸入波浪鍵了。 - CharCode(rawValue: charCode) == CharCode.symbolMenuKey_ABC + @objc var isSymbolMenuPhysicalKey: Bool { + // 這裡必須用 KeyCode,這樣才不會受隨 macOS 版本更動的 Apple 動態注音鍵盤排列內容的影響。 + // 只是必須得與 ![input isShift] 搭配使用才可以(也就是僅判定 Shift 沒被摁下的情形)。 + KeyCode(rawValue: keyCode) == KeyCode.symbolMenuPhysicalKey } } diff --git a/Source/Modules/ControllerModules/vChewingKanjiConverter.swift b/Source/Modules/ControllerModules/vChewingKanjiConverter.swift index e778b53c..ef8b52fd 100644 --- a/Source/Modules/ControllerModules/vChewingKanjiConverter.swift +++ b/Source/Modules/ControllerModules/vChewingKanjiConverter.swift @@ -21,10 +21,11 @@ import Cocoa // 這個模組果然還是要用 Regex 轉換會比較爽。 // 為防止與其他模組彼此發生可能的衝突,這段 String 擴展就用 private 開頭來私有化。 private extension String { + // Ref: https://stackoverflow.com/a/40993403/4162914 && https://stackoverflow.com/a/71291137/4162914 mutating func regReplace(pattern: String, replaceWith: String = "") { do { let regex = try NSRegularExpression(pattern: pattern, options: .caseInsensitive) - let range = NSRange(location: 0, length: count) + let range = NSRange(location: 0, length: self.utf16.count) self = regex.stringByReplacingMatches(in: self, options: [], range: range, withTemplate: replaceWith) } catch { return } } diff --git a/Source/Modules/FileHandlers/LMConsolidator.mm b/Source/Modules/FileHandlers/LMConsolidator.mm index f0a3cbb6..cd4fd9b3 100644 --- a/Source/Modules/FileHandlers/LMConsolidator.mm +++ b/Source/Modules/FileHandlers/LMConsolidator.mm @@ -86,15 +86,19 @@ bool LMConsolidator::ConsolidateContent(const char *path, bool shouldCheckPragma } // 第一遍 for 用來統整每行內的內容。 // regex sedCJKWhiteSpace("\\x{3000}"), sedNonBreakWhiteSpace("\\x{A0}"), sedWhiteSpace("\\s+"), sedLeadingSpace("^\\s"), sedTrailingSpace("\\s$"); // 這樣寫會導致輸入法敲不了任何字,推測 Xcode 13 支援的 cpp / objCpp 可能對某些 Regex 寫法有相容性問題。 - regex sedCJKWhiteSpace(" "), sedNonBreakWhiteSpace(" "), sedWhiteSpace("\\s+"), sedLeadingSpace("^\\s"), sedTrailingSpace("\\s$"); // RegEx 先定義好。 + // regex sedCJKWhiteSpace(" "), sedNonBreakWhiteSpace(" "), sedWhiteSpace("\\s+"), sedLeadingSpace("^\\s"), sedTrailingSpace("\\s$"); // RegEx 先定義好。 + regex sedToConsolidate("( +| +| +|\t+)+"), sedToTrim("(^\\s|\\s$)"); for(int i=0;i Bool { + isAlphanumericalModeEnabled = !isAlphanumericalModeEnabled + UserDefaults.standard.set(isAlphanumericalModeEnabled, forKey: kIsAlphanumericalModeEnabled) + NotifierController.notify(message: String(format: "%@%@%@", NSLocalizedString("Alphanumerical Input Mode", comment: ""), "\n", isAlphanumericalModeEnabled ? NSLocalizedString("NotificationSwitchON", comment: "") : NSLocalizedString("NotificationSwitchOFF", comment: ""))) + return isAlphanumericalModeEnabled + } + @UserDefault(key: kAppleLanguagesPreferences, defaultValue: []) @objc static var appleLanguages: Array @@ -345,19 +383,22 @@ struct ComposingBufferSize { @UserDefault(key: kBasisKeyboardLayoutPreference, defaultValue: "com.apple.keylayout.ZhuyinBopomofo") @objc static var basisKeyboardLayout: String - @UserDefault(key: kFunctionKeyKeyboardLayoutPreference, defaultValue: "com.apple.keylayout.ZhuyinBopomofo") + @UserDefault(key: kFunctionKeyKeyboardLayoutPreference, defaultValue: "com.apple.keylayout.ABC") @objc static var functionKeyboardLayout: String @UserDefault(key: kFunctionKeyKeyboardLayoutOverrideIncludeShift, defaultValue: false) @objc static var functionKeyKeyboardLayoutOverrideIncludeShiftKey: Bool + @UserDefault(key: kShowPageButtonsInCandidateWindow, defaultValue: true) + @objc static var showPageButtonsInCandidateWindow: Bool + @CandidateListTextSize(key: kCandidateListTextSize) @objc static var candidateListTextSize: CGFloat - + @UserDefault(key: kShouldAutoReloadUserDataFiles, defaultValue: true) @objc static var shouldAutoReloadUserDataFiles: Bool - @UserDefault(key: kSelectPhraseAfterCursorAsCandidatePreference, defaultValue: true) + @UserDefault(key: kSelectPhraseAfterCursorAsCandidatePreference, defaultValue: false) @objc static var selectPhraseAfterCursorAsCandidate: Bool @UserDefault(key: kMoveCursorAfterSelectingCandidate, defaultValue: false) @@ -371,22 +412,22 @@ struct ComposingBufferSize { @UserDefault(key: kChooseCandidateUsingSpace, defaultValue: true) @objc static var chooseCandidateUsingSpace: Bool - + @UserDefault(key: kUseSCPCTypingMode, defaultValue: false) @objc static var useSCPCTypingMode: Bool - + @objc static func toggleSCPCTypingModeEnabled() -> Bool { useSCPCTypingMode = !useSCPCTypingMode UserDefaults.standard.set(useSCPCTypingMode, forKey: kUseSCPCTypingMode) return useSCPCTypingMode } - + @UserDefault(key: kMaxCandidateLength, defaultValue: kDefaultComposingBufferSize * 2) @objc static var maxCandidateLength: Int - + @UserDefault(key: kShouldNotFartInLieuOfBeep, defaultValue: true) @objc static var shouldNotFartInLieuOfBeep: Bool - + @objc static func toggleShouldNotFartInLieuOfBeep() -> Bool { shouldNotFartInLieuOfBeep = !shouldNotFartInLieuOfBeep UserDefaults.standard.set(shouldNotFartInLieuOfBeep, forKey: kShouldNotFartInLieuOfBeep) @@ -398,17 +439,31 @@ struct ComposingBufferSize { @objc static func toggleCNS11643Enabled() -> Bool { cns11643Enabled = !cns11643Enabled + mgrLangModel.setCNSEnabled(cns11643Enabled) // 很重要 UserDefaults.standard.set(cns11643Enabled, forKey: kCNS11643Enabled) return cns11643Enabled } + @UserDefault(key: kSymbolInputEnabled, defaultValue: true) + @objc static var symbolInputEnabled: Bool + + @objc static func toggleSymbolInputEnabled() -> Bool { + symbolInputEnabled = !symbolInputEnabled + mgrLangModel.setSymbolEnabled(symbolInputEnabled) // 很重要 + UserDefaults.standard.set(symbolInputEnabled, forKey: kSymbolInputEnabled) + return symbolInputEnabled + } + @UserDefault(key: kChineseConversionEnabled, defaultValue: false) @objc static var chineseConversionEnabled: Bool @objc @discardableResult static func toggleChineseConversionEnabled() -> Bool { chineseConversionEnabled = !chineseConversionEnabled // 康熙轉換與 JIS 轉換不能同時開啟,否則會出現某些奇奇怪怪的情況 - if chineseConversionEnabled && shiftJISShinjitaiOutputEnabled {self.toggleShiftJISShinjitaiOutputEnabled()} + if chineseConversionEnabled && shiftJISShinjitaiOutputEnabled { + self.toggleShiftJISShinjitaiOutputEnabled() + UserDefaults.standard.set(shiftJISShinjitaiOutputEnabled, forKey: kShiftJISShinjitaiOutputEnabled) + } UserDefaults.standard.set(chineseConversionEnabled, forKey: kChineseConversionEnabled) return chineseConversionEnabled } @@ -435,9 +490,13 @@ struct ComposingBufferSize { @UserDefault(key: kEscToCleanInputBuffer, defaultValue: true) @objc static var escToCleanInputBuffer: Bool + @UserDefault(key: kSpecifyTabKeyBehavior, defaultValue: false) @objc static var specifyTabKeyBehavior: Bool + @UserDefault(key: kSpecifySpaceKeyBehavior, defaultValue: false) + @objc static var specifySpaceKeyBehavior: Bool + // MARK: - Optional settings @UserDefault(key: kCandidateTextFontName, defaultValue: nil) @objc static var candidateTextFontName: String? @@ -491,7 +550,7 @@ struct ComposingBufferSize { case .empty: return NSLocalizedString("Candidates keys cannot be empty.", comment: "") case .invalidCharacters: - return NSLocalizedString("Candidate keys can only contain ASCII characters like alphanumerals.", comment: "") + return NSLocalizedString("Candidate keys can only contain ASCII characters like alphanumericals.", comment: "") case .containSpace: return NSLocalizedString("Candidate keys cannot contain space.", comment: "") case .duplicatedCharacters: @@ -510,6 +569,7 @@ struct ComposingBufferSize { @objc static func togglePhraseReplacementEnabled() -> Bool { phraseReplacementEnabled = !phraseReplacementEnabled + mgrLangModel.setPhraseReplacementEnabled(phraseReplacementEnabled) UserDefaults.standard.set(phraseReplacementEnabled, forKey: kPhraseReplacementEnabled) return phraseReplacementEnabled } @@ -522,5 +582,5 @@ struct ComposingBufferSize { UserDefaults.standard.set(associatedPhrasesEnabled, forKey: kAssociatedPhrasesEnabled) return associatedPhrasesEnabled } - + } diff --git a/Source/Modules/IMEModules/ctlInputMethod.swift b/Source/Modules/IMEModules/ctlInputMethod.swift index 5a04837a..e020b95e 100644 --- a/Source/Modules/IMEModules/ctlInputMethod.swift +++ b/Source/Modules/IMEModules/ctlInputMethod.swift @@ -92,9 +92,16 @@ class ctlInputMethod: IMKInputController { userAssociatedPhrasesItem.keyEquivalentModifierMask = [.command, .control] userAssociatedPhrasesItem.state = Preferences.associatedPhrasesEnabled.state + let alphaNumericalModeItem = menu.addItem(withTitle: NSLocalizedString("Alphanumerical Input Mode", comment: ""), action: #selector(toggleAlphanumericalModeEnabled(_:)), keyEquivalent: "I") + alphaNumericalModeItem.keyEquivalentModifierMask = [.command, .control] + alphaNumericalModeItem.state = Preferences.isAlphanumericalModeEnabled.state + if optionKeyPressed { let phaseReplacementItem = menu.addItem(withTitle: NSLocalizedString("Use Phrase Replacement", comment: ""), action: #selector(togglePhraseReplacement(_:)), keyEquivalent: "") phaseReplacementItem.state = Preferences.phraseReplacementEnabled.state + + let toggleSymbolInputItem = menu.addItem(withTitle: NSLocalizedString("Symbol & Emoji Input", comment: ""), action: #selector(toggleSymbolEnabled(_:)), keyEquivalent: "") + toggleSymbolInputItem.state = Preferences.symbolInputEnabled.state } menu.addItem(NSMenuItem.separator()) // --------------------- @@ -178,6 +185,12 @@ class ctlInputMethod: IMKInputController { } override func handle(_ event: NSEvent!, client: Any!) -> Bool { + + if (Preferences.isAlphanumericalModeEnabled) { + (client as? IMKTextInput)?.overrideKeyboard(withKeyboardNamed: Preferences.functionKeyboardLayout) + return false + } + if event.type == .flagsChanged { let functionKeyKeyboardLayoutID = Preferences.functionKeyboardLayout let basisKeyboardLayoutID = Preferences.basisKeyboardLayout @@ -188,6 +201,15 @@ class ctlInputMethod: IMKInputController { let includeShift = Preferences.functionKeyKeyboardLayoutOverrideIncludeShiftKey let notShift = NSEvent.ModifierFlags(rawValue: ~(NSEvent.ModifierFlags.shift.rawValue)) + + // Shift Click Handling: Toggling Alphanumerical Mode. // STILL BUGGY, hence being commented out. + // if !event.modifierFlags.contains(.shift) + // && event.modifierFlags == .init(rawValue: 0) + // && !event.modifierFlags.contains(notShift) + // && (event.keyCode == KeyCode.leftShift.rawValue || event.keyCode == KeyCode.rightShift.rawValue) { + // Preferences.toggleAlphanumericalModeEnabled() + // } + if event.modifierFlags.contains(notShift) || (event.modifierFlags.contains(.shift) && includeShift) { (client as? IMKTextInput)?.overrideKeyboard(withKeyboardNamed: functionKeyKeyboardLayoutID) @@ -200,7 +222,7 @@ class ctlInputMethod: IMKInputController { var textFrame = NSRect.zero let attributes: [AnyHashable: Any]? = (client as? IMKTextInput)?.attributes(forCharacterIndex: 0, lineHeightRectangle: &textFrame) let useVerticalMode = (attributes?["IMKTextOrientation"] as? NSNumber)?.intValue == 0 || false - + if (client as? IMKTextInput)?.bundleIdentifier() == "org.atelierInmu.vChewing.vChewingPhraseEditor" { ctlInputMethod.areWeUsingOurOwnPhraseEditor = true } else { @@ -241,16 +263,23 @@ class ctlInputMethod: IMKInputController { } @objc func toggleCNS11643Enabled(_ sender: Any?) { - mgrLangModel.setCNSEnabled(Preferences.toggleCNS11643Enabled()) - NotifierController.notify(message: String(format: "%@%@%@", NSLocalizedString("CNS11643 Mode", comment: ""), "\n", Preferences.cns11643Enabled ? NSLocalizedString("NotificationSwitchON", comment: "") : NSLocalizedString("NotificationSwitchOFF", comment: ""))) + NotifierController.notify(message: String(format: "%@%@%@", NSLocalizedString("CNS11643 Mode", comment: ""), "\n", Preferences.toggleCNS11643Enabled() ? NSLocalizedString("NotificationSwitchON", comment: "") : NSLocalizedString("NotificationSwitchOFF", comment: ""))) + } + + @objc func toggleSymbolEnabled(_ sender: Any?) { + NotifierController.notify(message: String(format: "%@%@%@", NSLocalizedString("Symbol & Emoji Input", comment: ""), "\n", Preferences.toggleSymbolInputEnabled() ? NSLocalizedString("NotificationSwitchON", comment: "") : NSLocalizedString("NotificationSwitchOFF", comment: ""))) } @objc func toggleAssociatedPhrasesEnabled(_ sender: Any?) { NotifierController.notify(message: String(format: "%@%@%@", NSLocalizedString("Per-Char Associated Phrases", comment: ""), "\n", Preferences.toggleAssociatedPhrasesEnabled() ? NSLocalizedString("NotificationSwitchON", comment: "") : NSLocalizedString("NotificationSwitchOFF", comment: ""))) } + @objc func toggleAlphanumericalModeEnabled(_ sender: Any?) { + Preferences.toggleAlphanumericalModeEnabled() + } + @objc func togglePhraseReplacement(_ sender: Any?) { - mgrLangModel.setPhraseReplacementEnabled(Preferences.togglePhraseReplacementEnabled()) + NotifierController.notify(message: String(format: "%@%@%@", NSLocalizedString("Use Phrase Replacement", comment: ""), "\n", Preferences.togglePhraseReplacementEnabled() ? NSLocalizedString("NotificationSwitchON", comment: "") : NSLocalizedString("NotificationSwitchOFF", comment: ""))) } @objc func selfTerminate(_ sender: Any?) { diff --git a/Source/Modules/LangModelRelated/LMInstantiator.h b/Source/Modules/LangModelRelated/LMInstantiator.h index 594cbe23..0357a464 100644 --- a/Source/Modules/LangModelRelated/LMInstantiator.h +++ b/Source/Modules/LangModelRelated/LMInstantiator.h @@ -32,7 +32,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH namespace vChewing { -using namespace Taiyan::Gramambular; +using namespace Gramambular; /// LMInstantiator is a facade for managing a set of models including /// the input method language model, user phrases and excluded phrases. @@ -56,7 +56,7 @@ using namespace Taiyan::Gramambular; /// model while launching and to load the user phrases anytime if the custom /// files are modified. It does not keep the reference of the data pathes but /// you have to pass the paths when you ask it to do loading. -class LMInstantiator : public Taiyan::Gramambular::LanguageModel { +class LMInstantiator : public Gramambular::LanguageModel { public: LMInstantiator(); ~LMInstantiator(); @@ -97,11 +97,11 @@ public: void loadPhraseReplacementMap(const char* phraseReplacementPath); /// Not implemented since we do not have data to provide bigram function. - const std::vector bigramsForKeys(const std::string& preceedingKey, const std::string& key); + const std::vector bigramsForKeys(const std::string& preceedingKey, const std::string& key); /// Returns a list of available unigram for the given key. /// @param key A std::string represents the BPMF reading or a symbol key. For /// example, it you pass "ㄇㄚ", it returns "嗎", "媽", and so on. - const std::vector unigramsForKey(const std::string& key); + const std::vector unigramsForKey(const std::string& key); /// If the model has unigrams for the given key. /// @param key The key. bool hasUnigramsForKey(const std::string& key); @@ -111,6 +111,11 @@ public: /// If phrase replacement is enabled or not. bool phraseReplacementEnabled(); + /// Enables or disables symbol input. + void setSymbolEnabled(bool enabled); + /// If symbol input is enabled or not. + bool symbolEnabled(); + /// Enables or disables CNS11643 input. void setCNSEnabled(bool enabled); /// If CNS11643 input is enabled or not. @@ -135,7 +140,7 @@ protected: /// @param insertedValues The values for unigrams already in the results. /// It helps to prevent duplicated unigrams. Please note that the method /// has a side effect that it inserts values to `insertedValues`. - const std::vector filterAndTransformUnigrams(const std::vector unigrams, + const std::vector filterAndTransformUnigrams(const std::vector unigrams, const std::unordered_set& excludedValues, std::unordered_set& insertedValues); @@ -149,6 +154,7 @@ protected: AssociatedPhrases m_associatedPhrases; bool m_phraseReplacementEnabled; bool m_cnsEnabled; + bool m_symbolEnabled; bool m_externalConverterEnabled; std::function m_externalConverter; }; diff --git a/Source/Modules/LangModelRelated/LMInstantiator.mm b/Source/Modules/LangModelRelated/LMInstantiator.mm index 4fe8d376..948f9aff 100644 --- a/Source/Modules/LangModelRelated/LMInstantiator.mm +++ b/Source/Modules/LangModelRelated/LMInstantiator.mm @@ -119,16 +119,16 @@ void LMInstantiator::loadPhraseReplacementMap(const char* phraseReplacementPath) } } -const std::vector LMInstantiator::bigramsForKeys(const std::string& preceedingKey, const std::string& key) +const std::vector LMInstantiator::bigramsForKeys(const std::string& preceedingKey, const std::string& key) { - return std::vector(); + return std::vector(); } -const std::vector LMInstantiator::unigramsForKey(const std::string& key) +const std::vector LMInstantiator::unigramsForKey(const std::string& key) { if (key == " ") { - std::vector spaceUnigrams; - Taiyan::Gramambular::Unigram g; + std::vector spaceUnigrams; + Gramambular::Unigram g; g.keyValue.key = " "; g.keyValue.value = " "; g.score = 0; @@ -136,24 +136,24 @@ const std::vector LMInstantiator::unigramsForKey(c return spaceUnigrams; } - std::vector allUnigrams; - std::vector miscUnigrams; - std::vector symbolUnigrams; - std::vector userUnigrams; - std::vector cnsUnigrams; + std::vector allUnigrams; + std::vector miscUnigrams; + std::vector symbolUnigrams; + std::vector userUnigrams; + std::vector cnsUnigrams; std::unordered_set excludedValues; std::unordered_set insertedValues; if (m_excludedPhrases.hasUnigramsForKey(key)) { - std::vector excludedUnigrams = m_excludedPhrases.unigramsForKey(key); + std::vector excludedUnigrams = m_excludedPhrases.unigramsForKey(key); transform(excludedUnigrams.begin(), excludedUnigrams.end(), inserter(excludedValues, excludedValues.end()), - [](const Taiyan::Gramambular::Unigram& u) { return u.keyValue.value; }); + [](const Gramambular::Unigram& u) { return u.keyValue.value; }); } if (m_userPhrases.hasUnigramsForKey(key)) { - std::vector rawUserUnigrams = m_userPhrases.unigramsForKey(key); + std::vector rawUserUnigrams = m_userPhrases.unigramsForKey(key); // 用這句指令讓使用者語彙檔案內的詞條優先順序隨著行數增加而逐漸增高。 // 這樣一來就可以在就地新增語彙時徹底複寫優先權。 std::reverse(rawUserUnigrams.begin(), rawUserUnigrams.end()); @@ -161,22 +161,22 @@ const std::vector LMInstantiator::unigramsForKey(c } if (m_languageModel.hasUnigramsForKey(key)) { - std::vector rawGlobalUnigrams = m_languageModel.unigramsForKey(key); + std::vector rawGlobalUnigrams = m_languageModel.unigramsForKey(key); allUnigrams = filterAndTransformUnigrams(rawGlobalUnigrams, excludedValues, insertedValues); } if (m_miscModel.hasUnigramsForKey(key)) { - std::vector rawMiscUnigrams = m_miscModel.unigramsForKey(key); + std::vector rawMiscUnigrams = m_miscModel.unigramsForKey(key); miscUnigrams = filterAndTransformUnigrams(rawMiscUnigrams, excludedValues, insertedValues); } - if (m_symbolModel.hasUnigramsForKey(key)) { - std::vector rawSymbolUnigrams = m_symbolModel.unigramsForKey(key); + if (m_symbolModel.hasUnigramsForKey(key) && m_symbolEnabled) { + std::vector rawSymbolUnigrams = m_symbolModel.unigramsForKey(key); symbolUnigrams = filterAndTransformUnigrams(rawSymbolUnigrams, excludedValues, insertedValues); } if (m_cnsModel.hasUnigramsForKey(key) && m_cnsEnabled) { - std::vector rawCNSUnigrams = m_cnsModel.unigramsForKey(key); + std::vector rawCNSUnigrams = m_cnsModel.unigramsForKey(key); cnsUnigrams = filterAndTransformUnigrams(rawCNSUnigrams, excludedValues, insertedValues); } @@ -214,11 +214,22 @@ void LMInstantiator::setCNSEnabled(bool enabled) { m_cnsEnabled = enabled; } + bool LMInstantiator::cnsEnabled() { return m_cnsEnabled; } +void LMInstantiator::setSymbolEnabled(bool enabled) +{ + m_symbolEnabled = enabled; +} + +bool LMInstantiator::symbolEnabled() +{ + return m_symbolEnabled; +} + void LMInstantiator::setExternalConverterEnabled(bool enabled) { m_externalConverterEnabled = enabled; @@ -234,9 +245,9 @@ void LMInstantiator::setExternalConverter(std::function LMInstantiator::filterAndTransformUnigrams(const std::vector unigrams, const std::unordered_set& excludedValues, std::unordered_set& insertedValues) +const std::vector LMInstantiator::filterAndTransformUnigrams(const std::vector unigrams, const std::unordered_set& excludedValues, std::unordered_set& insertedValues) { - std::vector results; + std::vector results; for (auto&& unigram : unigrams) { // excludedValues filters out the unigrams with the original value. @@ -258,7 +269,7 @@ const std::vector LMInstantiator::filterAndTransfo value = replacement; } if (insertedValues.find(value) == insertedValues.end()) { - Taiyan::Gramambular::Unigram g; + Gramambular::Unigram g; g.keyValue.value = value; g.keyValue.key = unigram.keyValue.key; g.score = unigram.score; diff --git a/Source/Modules/LangModelRelated/SubLanguageModels/CoreLM.h b/Source/Modules/LangModelRelated/SubLanguageModels/CoreLM.h index 178ee21a..0beffc83 100644 --- a/Source/Modules/LangModelRelated/SubLanguageModels/CoreLM.h +++ b/Source/Modules/LangModelRelated/SubLanguageModels/CoreLM.h @@ -31,11 +31,11 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH // to avoid creating new string objects; the parser is a simple DFA using namespace std; -using namespace Taiyan::Gramambular; +using namespace Gramambular; namespace vChewing { -class CoreLM : public Taiyan::Gramambular::LanguageModel { +class CoreLM : public Gramambular::LanguageModel { public: CoreLM(); ~CoreLM(); @@ -45,8 +45,8 @@ public: void close(); void dump(); - virtual const std::vector bigramsForKeys(const string& preceedingKey, const string& key); - virtual const std::vector unigramsForKey(const string& key); + virtual const std::vector bigramsForKeys(const string& preceedingKey, const string& key); + virtual const std::vector unigramsForKey(const string& key); virtual bool hasUnigramsForKey(const string& key); protected: diff --git a/Source/Modules/LangModelRelated/SubLanguageModels/CoreLM.mm b/Source/Modules/LangModelRelated/SubLanguageModels/CoreLM.mm index 42cf9aae..2f84c4c3 100644 --- a/Source/Modules/LangModelRelated/SubLanguageModels/CoreLM.mm +++ b/Source/Modules/LangModelRelated/SubLanguageModels/CoreLM.mm @@ -25,7 +25,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH #include #include -using namespace Taiyan::Gramambular; +using namespace Gramambular; vChewing::CoreLM::CoreLM() : fd(-1) @@ -292,14 +292,14 @@ void vChewing::CoreLM::dump() } } -const std::vector vChewing::CoreLM::bigramsForKeys(const string& preceedingKey, const string& key) +const std::vector vChewing::CoreLM::bigramsForKeys(const string& preceedingKey, const string& key) { - return std::vector(); + return std::vector(); } -const std::vector vChewing::CoreLM::unigramsForKey(const string& key) +const std::vector vChewing::CoreLM::unigramsForKey(const string& key) { - std::vector v; + std::vector v; map >::const_iterator i = keyRowMap.find(key.c_str()); if (i != keyRowMap.end()) { diff --git a/Source/Modules/LangModelRelated/SubLanguageModels/ParselessLM.cpp b/Source/Modules/LangModelRelated/SubLanguageModels/ParselessLM.cpp index 2fd63f03..92104c22 100644 --- a/Source/Modules/LangModelRelated/SubLanguageModels/ParselessLM.cpp +++ b/Source/Modules/LangModelRelated/SubLanguageModels/ParselessLM.cpp @@ -80,23 +80,23 @@ void vChewing::ParselessLM::close() } } -const std::vector +const std::vector vChewing::ParselessLM::bigramsForKeys( const std::string& preceedingKey, const std::string& key) { - return std::vector(); + return std::vector(); } -const std::vector +const std::vector vChewing::ParselessLM::unigramsForKey(const std::string& key) { if (db_ == nullptr) { - return std::vector(); + return std::vector(); } - std::vector results; + std::vector results; for (const auto& row : db_->findRows(key + " ")) { - Taiyan::Gramambular::Unigram unigram; + Gramambular::Unigram unigram; // Move ahead until we encounter the first space. This is the key. auto it = row.begin(); diff --git a/Source/Modules/LangModelRelated/SubLanguageModels/ParselessLM.h b/Source/Modules/LangModelRelated/SubLanguageModels/ParselessLM.h index df25c494..984054a2 100644 --- a/Source/Modules/LangModelRelated/SubLanguageModels/ParselessLM.h +++ b/Source/Modules/LangModelRelated/SubLanguageModels/ParselessLM.h @@ -29,7 +29,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH namespace vChewing { -class ParselessLM : public Taiyan::Gramambular::LanguageModel { +class ParselessLM : public Gramambular::LanguageModel { public: ~ParselessLM() override; @@ -37,9 +37,9 @@ public: bool open(const std::string_view& path); void close(); - const std::vector bigramsForKeys( + const std::vector bigramsForKeys( const std::string& preceedingKey, const std::string& key) override; - const std::vector unigramsForKey( + const std::vector unigramsForKey( const std::string& key) override; bool hasUnigramsForKey(const std::string& key) override; diff --git a/Source/Modules/LangModelRelated/SubLanguageModels/UserOverrideModel.cpp b/Source/Modules/LangModelRelated/SubLanguageModels/UserOverrideModel.cpp index 2e0a7096..8d30149a 100644 --- a/Source/Modules/LangModelRelated/SubLanguageModels/UserOverrideModel.cpp +++ b/Source/Modules/LangModelRelated/SubLanguageModels/UserOverrideModel.cpp @@ -34,7 +34,7 @@ static double Score(size_t eventCount, double timestamp, double lambda); static bool IsEndingPunctuation(const std::string& value); -static std::string WalkedNodesToKey(const std::vector& walkedNodes, +static std::string WalkedNodesToKey(const std::vector& walkedNodes, size_t cursorIndex); UserOverrideModel::UserOverrideModel(size_t capacity, double decayConstant) @@ -43,7 +43,7 @@ UserOverrideModel::UserOverrideModel(size_t capacity, double decayConstant) m_decayExponent = log(0.5) / decayConstant; } -void UserOverrideModel::observe(const std::vector& walkedNodes, +void UserOverrideModel::observe(const std::vector& walkedNodes, size_t cursorIndex, const std::string& candidate, double timestamp) { @@ -76,7 +76,7 @@ void UserOverrideModel::observe(const std::vector& walkedNodes, +std::string UserOverrideModel::suggest(const std::vector& walkedNodes, size_t cursorIndex, double timestamp) { std::string key = WalkedNodesToKey(walkedNodes, cursorIndex); @@ -138,12 +138,12 @@ static bool IsEndingPunctuation(const std::string& value) { return value == "," || value == "。" || value== "!" || value == "?" || value == "」" || value == "』" || value== "”" || value == "’"; } -static std::string WalkedNodesToKey(const std::vector& walkedNodes, +static std::string WalkedNodesToKey(const std::vector& walkedNodes, size_t cursorIndex) { std::stringstream s; - std::vector n; + std::vector n; size_t ll = 0; - for (std::vector::const_iterator i = walkedNodes.begin(); + for (std::vector::const_iterator i = walkedNodes.begin(); i != walkedNodes.end(); ++i) { const auto& nn = *i; @@ -154,7 +154,7 @@ static std::string WalkedNodesToKey(const std::vector::const_reverse_iterator r = n.rbegin(); + std::vector::const_reverse_iterator r = n.rbegin(); if (r == n.rend()) { return ""; diff --git a/Source/Modules/LangModelRelated/SubLanguageModels/UserOverrideModel.h b/Source/Modules/LangModelRelated/SubLanguageModels/UserOverrideModel.h index 7189f5d2..10824c4b 100644 --- a/Source/Modules/LangModelRelated/SubLanguageModels/UserOverrideModel.h +++ b/Source/Modules/LangModelRelated/SubLanguageModels/UserOverrideModel.h @@ -27,18 +27,18 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH namespace vChewing { -using namespace Taiyan::Gramambular; +using namespace Gramambular; class UserOverrideModel { public: UserOverrideModel(size_t capacity, double decayConstant); - void observe(const std::vector& walkedNodes, + void observe(const std::vector& walkedNodes, size_t cursorIndex, const std::string& candidate, double timestamp); - std::string suggest(const std::vector& walkedNodes, + std::string suggest(const std::vector& walkedNodes, size_t cursorIndex, double timestamp); diff --git a/Source/Modules/LangModelRelated/SubLanguageModels/UserPhrasesLM.h b/Source/Modules/LangModelRelated/SubLanguageModels/UserPhrasesLM.h index 33d57c61..05881911 100644 --- a/Source/Modules/LangModelRelated/SubLanguageModels/UserPhrasesLM.h +++ b/Source/Modules/LangModelRelated/SubLanguageModels/UserPhrasesLM.h @@ -27,7 +27,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH namespace vChewing { -class UserPhrasesLM : public Taiyan::Gramambular::LanguageModel +class UserPhrasesLM : public Gramambular::LanguageModel { public: UserPhrasesLM(); @@ -46,8 +46,8 @@ public: return 0.0; } - virtual const std::vector bigramsForKeys(const std::string& preceedingKey, const std::string& key); - virtual const std::vector unigramsForKey(const std::string& key); + virtual const std::vector bigramsForKeys(const std::string& preceedingKey, const std::string& key); + virtual const std::vector unigramsForKey(const std::string& key); virtual bool hasUnigramsForKey(const std::string& key); protected: diff --git a/Source/Modules/LangModelRelated/SubLanguageModels/UserPhrasesLM.mm b/Source/Modules/LangModelRelated/SubLanguageModels/UserPhrasesLM.mm index 6ae55429..f530f21f 100644 --- a/Source/Modules/LangModelRelated/SubLanguageModels/UserPhrasesLM.mm +++ b/Source/Modules/LangModelRelated/SubLanguageModels/UserPhrasesLM.mm @@ -121,19 +121,19 @@ void UserPhrasesLM::dump() } } -const std::vector UserPhrasesLM::bigramsForKeys(const std::string& preceedingKey, const std::string& key) +const std::vector UserPhrasesLM::bigramsForKeys(const std::string& preceedingKey, const std::string& key) { - return std::vector(); + return std::vector(); } -const std::vector UserPhrasesLM::unigramsForKey(const std::string& key) +const std::vector UserPhrasesLM::unigramsForKey(const std::string& key) { - std::vector v; + std::vector v; auto iter = keyRowMap.find(key); if (iter != keyRowMap.end()) { const std::vector& rows = iter->second; for (const auto& row : rows) { - Taiyan::Gramambular::Unigram g; + Gramambular::Unigram g; g.keyValue.key = row.key; g.keyValue.value = row.value; g.score = overridedValue(); diff --git a/Source/Modules/LangModelRelated/mgrLangModel.h b/Source/Modules/LangModelRelated/mgrLangModel.h index e003fd70..34c3dc48 100644 --- a/Source/Modules/LangModelRelated/mgrLangModel.h +++ b/Source/Modules/LangModelRelated/mgrLangModel.h @@ -36,6 +36,8 @@ NS_ASSUME_NONNULL_BEGIN + (BOOL)writeUserPhrase:(NSString *)userPhrase inputMode:(InputMode)mode areWeDuplicating:(BOOL)areWeDuplicating; + (void)setPhraseReplacementEnabled:(BOOL)phraseReplacementEnabled; + (void)setCNSEnabled:(BOOL)cnsEnabled; ++ (void)setSymbolEnabled:(BOOL)symbolEnabled; + + (NSString *)specifyBundleDataPath:(NSString *)filename; + (NSString *)userPhrasesDataPath:(InputMode)mode; + (NSString *)userAssociatedPhrasesDataPath:(InputMode)mode; diff --git a/Source/Modules/LangModelRelated/mgrLangModel.mm b/Source/Modules/LangModelRelated/mgrLangModel.mm index 9c696d6c..6e211979 100644 --- a/Source/Modules/LangModelRelated/mgrLangModel.mm +++ b/Source/Modules/LangModelRelated/mgrLangModel.mm @@ -371,4 +371,10 @@ static void LTLoadLanguageModelFile(NSString *filenameWithoutExtension, vChewing gLangModelCHS.setCNSEnabled(cnsEnabled); } ++ (void)setSymbolEnabled:(BOOL)symbolEnabled +{ + gLangModelCHT.setSymbolEnabled(symbolEnabled); + gLangModelCHS.setSymbolEnabled(symbolEnabled); +} + @end diff --git a/Source/Modules/LanguageParsers/Gramambular/Bigram.h b/Source/Modules/LanguageParsers/Gramambular/Bigram.h index 5995238d..16576b31 100644 --- a/Source/Modules/LanguageParsers/Gramambular/Bigram.h +++ b/Source/Modules/LanguageParsers/Gramambular/Bigram.h @@ -24,7 +24,6 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH #include "KeyValuePair.h" -namespace Taiyan { namespace Gramambular { class Bigram { public: @@ -88,6 +87,6 @@ inline bool Bigram::operator<(const Bigram& another) const { return false; } } // namespace Gramambular -} // namespace Taiyan + #endif diff --git a/Source/Modules/LanguageParsers/Gramambular/BlockReadingBuilder.h b/Source/Modules/LanguageParsers/Gramambular/BlockReadingBuilder.h index a74a79f4..4ece863b 100644 --- a/Source/Modules/LanguageParsers/Gramambular/BlockReadingBuilder.h +++ b/Source/Modules/LanguageParsers/Gramambular/BlockReadingBuilder.h @@ -26,7 +26,6 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH #include "Grid.h" #include "LanguageModel.h" -namespace Taiyan { namespace Gramambular { class BlockReadingBuilder { @@ -201,6 +200,6 @@ inline const std::string BlockReadingBuilder::Join( return result; } } // namespace Gramambular -} // namespace Taiyan + #endif diff --git a/Source/Modules/LanguageParsers/Gramambular/Grid.h b/Source/Modules/LanguageParsers/Gramambular/Grid.h index f81c9301..6113bb8c 100644 --- a/Source/Modules/LanguageParsers/Gramambular/Grid.h +++ b/Source/Modules/LanguageParsers/Gramambular/Grid.h @@ -27,7 +27,6 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH #include "NodeAnchor.h" #include "Span.h" -namespace Taiyan { namespace Gramambular { class Grid { @@ -61,7 +60,46 @@ public: const std::string& value, float overridingScore); - std::string dumpDOT(); + std::string dumpDOT() { + std::stringstream sst; + sst << "digraph {" << std::endl; + sst << "graph [ rankdir=LR ];" << std::endl; + sst << "BOS;" << std::endl; + + for (size_t p = 0; p < m_spans.size(); p++) { + Span& span = m_spans[p]; + for (size_t ni = 0; ni <= span.maximumLength(); ni++) { + Node* np = span.nodeOfLength(ni); + if (np) { + if (!p) { + sst << "BOS -> " << np->currentKeyValue().value << ";" << std::endl; + } + + sst << np->currentKeyValue().value << ";" << std::endl; + + if (p + ni < m_spans.size()) { + Span& dstSpan = m_spans[p + ni]; + for (size_t q = 0; q <= dstSpan.maximumLength(); q++) { + Node* dn = dstSpan.nodeOfLength(q); + if (dn) { + sst << np->currentKeyValue().value << " -> " + << dn->currentKeyValue().value << ";" << std::endl; + } + } + } + + if (p + ni == m_spans.size()) { + sst << np->currentKeyValue().value << " -> " + << "EOS;" << std::endl; + } + } + } + } + + sst << "EOS;" << std::endl; + sst << "}"; + return sst.str(); + } protected: std::vector m_spans; @@ -218,6 +256,6 @@ inline void Grid::overrideNodeScoreForSelectedCandidate( } } // namespace Gramambular -} // namespace Taiyan + #endif diff --git a/Source/Modules/LanguageParsers/Gramambular/Grid.mm b/Source/Modules/LanguageParsers/Gramambular/Grid.mm deleted file mode 100644 index ba76a6e0..00000000 --- a/Source/Modules/LanguageParsers/Gramambular/Grid.mm +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) 2011 and onwards The OpenVanilla Project (MIT License). -// All possible vChewing-specific modifications are (c) 2021 and onwards The vChewing Project (MIT-NTL License). -/* -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and -to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -1. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -2. 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 above. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#include "Grid.h" - -#include -#include - -namespace Taiyan { -namespace Gramambular { - -std::string Grid::dumpDOT() { - std::stringstream sst; - sst << "digraph {" << std::endl; - sst << "graph [ rankdir=LR ];" << std::endl; - sst << "BOS;" << std::endl; - - for (size_t p = 0; p < m_spans.size(); p++) { - Span& span = m_spans[p]; - for (size_t ni = 0; ni <= span.maximumLength(); ni++) { - Node* np = span.nodeOfLength(ni); - if (np) { - if (!p) { - sst << "BOS -> " << np->currentKeyValue().value << ";" << std::endl; - } - - sst << np->currentKeyValue().value << ";" << std::endl; - - if (p + ni < m_spans.size()) { - Span& dstSpan = m_spans[p + ni]; - for (size_t q = 0; q <= dstSpan.maximumLength(); q++) { - Node* dn = dstSpan.nodeOfLength(q); - if (dn) { - sst << np->currentKeyValue().value << " -> " - << dn->currentKeyValue().value << ";" << std::endl; - } - } - } - - if (p + ni == m_spans.size()) { - sst << np->currentKeyValue().value << " -> " - << "EOS;" << std::endl; - } - } - } - } - - sst << "EOS;" << std::endl; - sst << "}"; - return sst.str(); -} - -} // namespace Gramambular -} // namespace Taiyan diff --git a/Source/Modules/LanguageParsers/Gramambular/KeyValuePair.h b/Source/Modules/LanguageParsers/Gramambular/KeyValuePair.h index e22a96bd..569687ed 100644 --- a/Source/Modules/LanguageParsers/Gramambular/KeyValuePair.h +++ b/Source/Modules/LanguageParsers/Gramambular/KeyValuePair.h @@ -23,7 +23,6 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH #include #include -namespace Taiyan { namespace Gramambular { class KeyValuePair { @@ -54,6 +53,6 @@ inline bool KeyValuePair::operator<(const KeyValuePair& another) const { return false; } } // namespace Gramambular -} // namespace Taiyan + #endif diff --git a/Source/Modules/LanguageParsers/Gramambular/LanguageModel.h b/Source/Modules/LanguageParsers/Gramambular/LanguageModel.h index b24f7fff..bed61ab5 100644 --- a/Source/Modules/LanguageParsers/Gramambular/LanguageModel.h +++ b/Source/Modules/LanguageParsers/Gramambular/LanguageModel.h @@ -26,7 +26,6 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH #include "Bigram.h" #include "Unigram.h" -namespace Taiyan { namespace Gramambular { class LanguageModel { @@ -39,6 +38,6 @@ public: virtual bool hasUnigramsForKey(const std::string& key) = 0; }; } // namespace Gramambular -} // namespace Taiyan + #endif diff --git a/Source/Modules/LanguageParsers/Gramambular/Node.h b/Source/Modules/LanguageParsers/Gramambular/Node.h index dfc961c5..42de5910 100644 --- a/Source/Modules/LanguageParsers/Gramambular/Node.h +++ b/Source/Modules/LanguageParsers/Gramambular/Node.h @@ -27,7 +27,6 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH #include "LanguageModel.h" -namespace Taiyan { namespace Gramambular { class Node { @@ -209,6 +208,6 @@ inline const KeyValuePair Node::currentKeyValue() const { } } } // namespace Gramambular -} // namespace Taiyan + #endif diff --git a/Source/Modules/LanguageParsers/Gramambular/NodeAnchor.h b/Source/Modules/LanguageParsers/Gramambular/NodeAnchor.h index f215c92e..485bb51f 100644 --- a/Source/Modules/LanguageParsers/Gramambular/NodeAnchor.h +++ b/Source/Modules/LanguageParsers/Gramambular/NodeAnchor.h @@ -24,7 +24,6 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH #include "Node.h" -namespace Taiyan { namespace Gramambular { struct NodeAnchor { @@ -59,6 +58,6 @@ inline std::ostream& operator<<(std::ostream& stream, return stream; } } // namespace Gramambular -} // namespace Taiyan + #endif diff --git a/Source/Modules/LanguageParsers/Gramambular/Span.h b/Source/Modules/LanguageParsers/Gramambular/Span.h index e46df777..30c12692 100644 --- a/Source/Modules/LanguageParsers/Gramambular/Span.h +++ b/Source/Modules/LanguageParsers/Gramambular/Span.h @@ -26,7 +26,6 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH #include "Node.h" -namespace Taiyan { namespace Gramambular { class Span { public: @@ -88,6 +87,6 @@ inline Node* Span::nodeOfLength(size_t length) { inline size_t Span::maximumLength() const { return m_maximumLength; } } // namespace Gramambular -} // namespace Taiyan + #endif diff --git a/Source/Modules/LanguageParsers/Gramambular/Unigram.h b/Source/Modules/LanguageParsers/Gramambular/Unigram.h index b05e55f6..45b461d4 100644 --- a/Source/Modules/LanguageParsers/Gramambular/Unigram.h +++ b/Source/Modules/LanguageParsers/Gramambular/Unigram.h @@ -24,7 +24,6 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH #include "KeyValuePair.h" -namespace Taiyan { namespace Gramambular { class Unigram { @@ -86,6 +85,6 @@ inline bool Unigram::ScoreCompare(const Unigram& a, const Unigram& b) { return a.score > b.score; } } // namespace Gramambular -} // namespace Taiyan + #endif diff --git a/Source/Modules/LanguageParsers/Gramambular/Walker.h b/Source/Modules/LanguageParsers/Gramambular/Walker.h index fdb035d6..b694c7e7 100644 --- a/Source/Modules/LanguageParsers/Gramambular/Walker.h +++ b/Source/Modules/LanguageParsers/Gramambular/Walker.h @@ -25,7 +25,6 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH #include "Grid.h" -namespace Taiyan { namespace Gramambular { class Walker { @@ -80,6 +79,6 @@ inline const std::vector Walker::reverseWalk( return *result; } } // namespace Gramambular -} // namespace Taiyan + #endif diff --git a/Source/Resources/Base.lproj/Localizable.strings b/Source/Resources/Base.lproj/Localizable.strings index fac28d72..778638a9 100644 --- a/Source/Resources/Base.lproj/Localizable.strings +++ b/Source/Resources/Base.lproj/Localizable.strings @@ -28,7 +28,7 @@ "Edit Phrase Replacement Table…" = "Edit Phrase Replacement Table…"; "Use Phrase Replacement" = "Use Phrase Replacement"; "Candidates keys cannot be empty." = "Candidates keys cannot be empty."; -"Candidate keys can only contain ASCII characters like alphanumerals." = "Candidate keys can only contain ASCII characters like alphanumerals."; +"Candidate keys can only contain ASCII characters like alphanumericals." = "Candidate keys can only contain ASCII characters like alphanumericals."; "Candidate keys cannot contain space." = "Candidate keys cannot contain space."; "There should not be duplicated keys." = "There should not be duplicated keys."; "Please specify at least 4 candidate keys." = "Please specify at least 4 candidate keys."; @@ -47,8 +47,10 @@ "zh-Hans" = "Simplified Chinese"; "zh-Hant" = "Traditional Chinese"; "ja" = "Japanese"; +"Alphanumerical Input Mode" = "Alphanumerical Input Mode"; "Apple Zhuyin Bopomofo" = "Apple Zhuyin Bopomofo (Standard)"; "Apple Zhuyin Eten" = "Apple Zhuyin Eten"; +"Symbol & Emoji Input" = "Symbol & Emoji Input"; // The followings are the category names used in the Symbol menu. "catCommonSymbols" = "CommonSymbols"; diff --git a/Source/Resources/en.lproj/Localizable.strings b/Source/Resources/en.lproj/Localizable.strings index fac28d72..778638a9 100644 --- a/Source/Resources/en.lproj/Localizable.strings +++ b/Source/Resources/en.lproj/Localizable.strings @@ -28,7 +28,7 @@ "Edit Phrase Replacement Table…" = "Edit Phrase Replacement Table…"; "Use Phrase Replacement" = "Use Phrase Replacement"; "Candidates keys cannot be empty." = "Candidates keys cannot be empty."; -"Candidate keys can only contain ASCII characters like alphanumerals." = "Candidate keys can only contain ASCII characters like alphanumerals."; +"Candidate keys can only contain ASCII characters like alphanumericals." = "Candidate keys can only contain ASCII characters like alphanumericals."; "Candidate keys cannot contain space." = "Candidate keys cannot contain space."; "There should not be duplicated keys." = "There should not be duplicated keys."; "Please specify at least 4 candidate keys." = "Please specify at least 4 candidate keys."; @@ -47,8 +47,10 @@ "zh-Hans" = "Simplified Chinese"; "zh-Hant" = "Traditional Chinese"; "ja" = "Japanese"; +"Alphanumerical Input Mode" = "Alphanumerical Input Mode"; "Apple Zhuyin Bopomofo" = "Apple Zhuyin Bopomofo (Standard)"; "Apple Zhuyin Eten" = "Apple Zhuyin Eten"; +"Symbol & Emoji Input" = "Symbol & Emoji Input"; // The followings are the category names used in the Symbol menu. "catCommonSymbols" = "CommonSymbols"; diff --git a/Source/Resources/ja.lproj/Localizable.strings b/Source/Resources/ja.lproj/Localizable.strings index 00026872..4dea78fb 100644 --- a/Source/Resources/ja.lproj/Localizable.strings +++ b/Source/Resources/ja.lproj/Localizable.strings @@ -28,7 +28,7 @@ "Edit Phrase Replacement Table…" = "言葉置換表を編集…"; "Use Phrase Replacement" = "言葉置換機能"; "Candidates keys cannot be empty." = "言選り用キー陣列に何かキーをご登録ください。"; -"Candidate keys can only contain ASCII characters like alphanumerals." = "言選り用キー陣列にはASCII文字だけをご登録ください(英数など)。"; +"Candidate keys can only contain ASCII characters like alphanumericals." = "言選り用キー陣列にはASCII文字だけをご登録ください(英数など)。"; "Candidate keys cannot contain space." = "言選り用キー陣列にスペースキーは登録できません。"; "There should not be duplicated keys." = "言選り用キー陣列に同じキーの重複登録はできません。"; "Please specify at least 4 candidate keys." = "言選り用キー陣列に少なくとも4つのキーをご登録ください。"; @@ -47,8 +47,10 @@ "zh-Hans" = "簡體中国語"; "zh-Hant" = "繁體中国語"; "ja" = "和語"; +"Alphanumerical Input Mode" = "英数入力モード"; "Apple Zhuyin Bopomofo" = "Apple 注音ボポモフォ配列(大千標準)"; -"Apple Zhuyin Bopomofo" = "Apple 注音ボポモフォ配列(倚天伝統)"; +"Apple Zhuyin Eten" = "Apple 注音ボポモフォ配列(倚天伝統)"; +"Symbol & Emoji Input" = "符号&絵文字入力"; // The followings are the category names used in the Symbol menu. "catCommonSymbols" = "常用"; diff --git a/Source/Resources/zh-Hans.lproj/Localizable.strings b/Source/Resources/zh-Hans.lproj/Localizable.strings index bee4cf8e..01ce1d54 100644 --- a/Source/Resources/zh-Hans.lproj/Localizable.strings +++ b/Source/Resources/zh-Hans.lproj/Localizable.strings @@ -28,7 +28,7 @@ "Edit Phrase Replacement Table…" = "编辑语汇置换表…"; "Use Phrase Replacement" = "使用语汇置换"; "Candidates keys cannot be empty." = "您必须指定选字键。"; -"Candidate keys can only contain ASCII characters like alphanumerals." = "选字键只能是英数等 ASCII 字符。"; +"Candidate keys can only contain ASCII characters like alphanumericals." = "选字键只能是英数等 ASCII 字符。"; "Candidate keys cannot contain space." = "选字键不得包含空格。"; "There should not be duplicated keys." = "选字键不得重复。"; "Please specify at least 4 candidate keys." = "请至少指定四个选字键。"; @@ -47,8 +47,10 @@ "zh-Hans" = "简体中文"; "zh-Hant" = "繁体中文"; "ja" = "和文"; +"Alphanumerical Input Mode" = "原生英数输入模式"; "Apple Zhuyin Bopomofo" = "Apple 标准注音键盘布局"; "Apple Zhuyin Eten" = "Apple 倚天注音键盘布局"; +"Symbol & Emoji Input" = "符号&绘文字输入"; // The followings are the category names used in the Symbol menu. "catCommonSymbols" = "常用"; diff --git a/Source/Resources/zh-Hant.lproj/Localizable.strings b/Source/Resources/zh-Hant.lproj/Localizable.strings index 3a1b9998..dd6aec31 100644 --- a/Source/Resources/zh-Hant.lproj/Localizable.strings +++ b/Source/Resources/zh-Hant.lproj/Localizable.strings @@ -28,7 +28,7 @@ "Edit Phrase Replacement Table…" = "編輯語彙置換表…"; "Use Phrase Replacement" = "使用語彙置換"; "Candidates keys cannot be empty." = "您必須指定選字鍵。"; -"Candidate keys can only contain ASCII characters like alphanumerals." = "選字鍵只能是英數等 ASCII 字符。"; +"Candidate keys can only contain ASCII characters like alphanumericals." = "選字鍵只能是英數等 ASCII 字符。"; "Candidate keys cannot contain space." = "選字鍵不得包含空格。"; "There should not be duplicated keys." = "選字鍵不得重複。"; "Please specify at least 4 candidate keys." = "請至少指定四個選字鍵。"; @@ -47,8 +47,10 @@ "zh-Hans" = "簡體中文"; "zh-Hant" = "繁體中文"; "ja" = "和文"; +"Alphanumerical Input Mode" = "原生英數輸入模式"; "Apple Zhuyin Bopomofo" = "Apple 標準注音鍵盤佈局"; "Apple Zhuyin Eten" = "Apple 倚天注音鍵盤佈局"; +"Symbol & Emoji Input" = "符號&繪文字輸入"; // The followings are the category names used in the Symbol menu. "catCommonSymbols" = "常用"; diff --git a/Source/UI/CandidateUI/HorizontalCandidateController.swift b/Source/UI/CandidateUI/HorizontalCandidateController.swift index ffe8ee48..a8faeb52 100644 --- a/Source/UI/CandidateUI/HorizontalCandidateController.swift +++ b/Source/UI/CandidateUI/HorizontalCandidateController.swift @@ -100,22 +100,11 @@ fileprivate class HorizontalCandidateView: NSView { } override func draw(_ dirtyRect: NSRect) { - - // Give a standalone layer to the candidate list panel - self.wantsLayer = true - self.layer?.borderColor = NSColor.selectedMenuItemTextColor.withAlphaComponent(0.30).cgColor - self.layer?.borderWidth = 1.0 - self.layer?.cornerRadius = 6.0 - let bounds = self.bounds NSColor.controlBackgroundColor.setFill() // Candidate list panel base background NSBezierPath.fill(bounds) - if #available(macOS 10.14, *) { - NSColor.separatorColor.setStroke() - } else { - NSColor.darkGray.setStroke() - } + NSColor.systemGray.withAlphaComponent(0.75).setStroke() NSBezierPath.strokeLine(from: NSPoint(x: bounds.size.width, y: 0.0), to: NSPoint(x: bounds.size.width, y: bounds.size.height)) @@ -129,7 +118,15 @@ fileprivate class HorizontalCandidateView: NSView { var activeCandidateIndexAttr = keyLabelAttrDict var activeCandidateAttr = candidateAttrDict if index == highlightedIndex { - NSColor.alternateSelectedControlColor.setFill() // The background color of the highlightened candidate + // The background color of the highlightened candidate + switch ctlInputMethod.currentKeyHandler.inputMode { + case InputMode.imeModeCHS: + NSColor.systemRed.withAlphaComponent(0.75).setFill() + case InputMode.imeModeCHT: + NSColor.systemBlue.withAlphaComponent(0.75).setFill() + default: + NSColor.alternateSelectedControlColor.setFill() + } activeCandidateIndexAttr[.foregroundColor] = NSColor.selectedMenuItemTextColor.withAlphaComponent(0.84) // The index text color of the highlightened candidate activeCandidateAttr[.foregroundColor] = NSColor.selectedMenuItemTextColor // The phrase text color of the highlightened candidate } else { @@ -199,36 +196,50 @@ public class HorizontalCandidateController: CandidateController { public init() { var contentRect = NSRect(x: 128.0, y: 128.0, width: 0.0, height: 0.0) - let styleMask: NSWindow.StyleMask = [.borderless, .nonactivatingPanel] + let styleMask: NSWindow.StyleMask = [.nonactivatingPanel] let panel = NSPanel(contentRect: contentRect, styleMask: styleMask, backing: .buffered, defer: false) panel.level = NSWindow.Level(Int(kCGPopUpMenuWindowLevel) + 1) panel.hasShadow = true panel.isOpaque = false - panel.backgroundColor = NSColor.clear // Transparentify everything outside of the candidate list panel + panel.backgroundColor = NSColor.clear contentRect.origin = NSPoint.zero candidateView = HorizontalCandidateView(frame: contentRect) + + candidateView.wantsLayer = true + candidateView.layer?.borderColor = NSColor.selectedMenuItemTextColor.withAlphaComponent(0.30).cgColor + candidateView.layer?.borderWidth = 1.0 + if #available(macOS 10.13, *) { + candidateView.layer?.cornerRadius = 6.0 + } + panel.contentView?.addSubview(candidateView) - contentRect.size = NSSize(width: 20.0, height: 15.0) // Reduce the button width + contentRect.size = NSSize(width: 20.0, height: 10.0) // Reduce the button width + let buttonAttribute: [NSAttributedString.Key : Any] = [.font : NSFont.systemFont(ofSize: 9.0)] + nextPageButton = NSButton(frame: contentRect) - nextPageButton.setButtonType(.momentaryLight) - nextPageButton.bezelStyle = .shadowlessSquare + NSColor.controlBackgroundColor.setFill() + NSBezierPath.fill(nextPageButton.bounds) nextPageButton.wantsLayer = true nextPageButton.layer?.masksToBounds = true - nextPageButton.layer?.borderColor = NSColor.clear.cgColor // Attempt to remove the system default layer border color - step 1 - nextPageButton.layer?.borderWidth = 0.0 // Attempt to remove the system default layer border color - step 2 - nextPageButton.layer?.backgroundColor = NSColor.black.cgColor // Button Background Color. Otherwise the button will be half-transparent in macOS Monterey Dark Mode. - nextPageButton.attributedTitle = NSMutableAttributedString(string: "⬇︎") // Next Page Arrow + nextPageButton.layer?.borderColor = NSColor.clear.cgColor + nextPageButton.layer?.borderWidth = 0.0 + nextPageButton.setButtonType(.momentaryLight) + nextPageButton.bezelStyle = .disclosure + nextPageButton.userInterfaceLayoutDirection = .leftToRight + nextPageButton.attributedTitle = NSMutableAttributedString(string: " ", attributes: buttonAttribute) // Next Page Arrow prevPageButton = NSButton(frame: contentRect) - prevPageButton.setButtonType(.momentaryLight) - prevPageButton.bezelStyle = .shadowlessSquare + NSColor.controlBackgroundColor.setFill() + NSBezierPath.fill(prevPageButton.bounds) prevPageButton.wantsLayer = true prevPageButton.layer?.masksToBounds = true - prevPageButton.layer?.borderColor = NSColor.clear.cgColor // Attempt to remove the system default layer border color - step 1 - prevPageButton.layer?.borderWidth = 0.0 // Attempt to remove the system default layer border color - step 2 - prevPageButton.layer?.backgroundColor = NSColor.black.cgColor // Button Background Color. Otherwise the button will be half-transparent in macOS Monterey Dark Mode. - prevPageButton.attributedTitle = NSMutableAttributedString(string: "⬆︎") // Previous Page Arrow + prevPageButton.layer?.borderColor = NSColor.clear.cgColor + prevPageButton.layer?.borderWidth = 0.0 + prevPageButton.setButtonType(.momentaryLight) + prevPageButton.bezelStyle = .disclosure + prevPageButton.userInterfaceLayoutDirection = .rightToLeft + prevPageButton.attributedTitle = NSMutableAttributedString(string: " ", attributes: buttonAttribute) // Previous Page Arrow panel.contentView?.addSubview(nextPageButton) panel.contentView?.addSubview(prevPageButton) @@ -343,20 +354,20 @@ extension HorizontalCandidateController { frameRect.size = newSize candidateView.frame = frameRect - if pageCount > 1 { + if pageCount > 1 && Preferences.showPageButtonsInCandidateWindow { var buttonRect = nextPageButton.frame let spacing:CGFloat = 0.0 buttonRect.size.height = floor(newSize.height / 2) let buttonOriginY = (newSize.height - (buttonRect.size.height * 2.0 + spacing)) / 2.0 - buttonRect.origin = NSPoint(x: newSize.width + 8.0, y: buttonOriginY) + buttonRect.origin = NSPoint(x: newSize.width, y: buttonOriginY) nextPageButton.frame = buttonRect - buttonRect.origin = NSPoint(x: newSize.width + 8.0, y: buttonOriginY + buttonRect.size.height + spacing) + buttonRect.origin = NSPoint(x: newSize.width, y: buttonOriginY + buttonRect.size.height + spacing) prevPageButton.frame = buttonRect - newSize.width += 52.0 + newSize.width += 20 nextPageButton.isHidden = false prevPageButton.isHidden = false } else { diff --git a/Source/UI/CandidateUI/VerticalCandidateController.swift b/Source/UI/CandidateUI/VerticalCandidateController.swift index 50fe09f7..64b67eae 100644 --- a/Source/UI/CandidateUI/VerticalCandidateController.swift +++ b/Source/UI/CandidateUI/VerticalCandidateController.swift @@ -69,7 +69,7 @@ fileprivate class VerticalCandidateView: NSView { let cellWidth = rctCandidate.size.width + cellPadding let cellHeight = rctCandidate.size.height + cellPadding if (calculatedWindowWidth < rctCandidate.size.width) { - calculatedWindowWidth = rctCandidate.size.width + calculatedWindowWidth = rctCandidate.size.width + cellPadding } newWidths.append(cellWidth) newHeights.append(cellHeight) @@ -106,22 +106,11 @@ fileprivate class VerticalCandidateView: NSView { } override func draw(_ dirtyRect: NSRect) { - - // Give a standalone layer to the candidate list panel - self.wantsLayer = true - self.layer?.borderColor = NSColor.selectedMenuItemTextColor.withAlphaComponent(0.30).cgColor - self.layer?.borderWidth = 1.0 - self.layer?.cornerRadius = 6.0 - let bounds = self.bounds NSColor.controlBackgroundColor.setFill() // Candidate list panel base background NSBezierPath.fill(bounds) - if #available(macOS 10.14, *) { - NSColor.separatorColor.setStroke() - } else { - NSColor.darkGray.setStroke() - } + NSColor.systemGray.withAlphaComponent(0.75).setStroke() NSBezierPath.strokeLine(from: NSPoint(x: bounds.size.width, y: 0.0), to: NSPoint(x: bounds.size.width, y: bounds.size.height)) @@ -135,7 +124,15 @@ fileprivate class VerticalCandidateView: NSView { var activeCandidateIndexAttr = keyLabelAttrDict var activeCandidateAttr = candidateAttrDict if index == highlightedIndex { - NSColor.alternateSelectedControlColor.setFill() // The background color of the highlightened candidate + // The background color of the highlightened candidate + switch ctlInputMethod.currentKeyHandler.inputMode { + case InputMode.imeModeCHS: + NSColor.systemRed.withAlphaComponent(0.75).setFill() + case InputMode.imeModeCHT: + NSColor.systemBlue.withAlphaComponent(0.75).setFill() + default: + NSColor.alternateSelectedControlColor.setFill() + } activeCandidateIndexAttr[.foregroundColor] = NSColor.selectedMenuItemTextColor.withAlphaComponent(0.84) // The index text color of the highlightened candidate activeCandidateAttr[.foregroundColor] = NSColor.selectedMenuItemTextColor // The phrase text color of the highlightened candidate } else { @@ -205,36 +202,50 @@ public class VerticalCandidateController: CandidateController { public init() { var contentRect = NSRect(x: 128.0, y: 128.0, width: 0.0, height: 0.0) - let styleMask: NSWindow.StyleMask = [.borderless, .nonactivatingPanel] + let styleMask: NSWindow.StyleMask = [.nonactivatingPanel] let panel = NSPanel(contentRect: contentRect, styleMask: styleMask, backing: .buffered, defer: false) panel.level = NSWindow.Level(Int(kCGPopUpMenuWindowLevel) + 1) panel.hasShadow = true panel.isOpaque = false - panel.backgroundColor = NSColor.clear // Transparentify everything outside of the candidate list panel + panel.backgroundColor = NSColor.clear contentRect.origin = NSPoint.zero candidateView = VerticalCandidateView(frame: contentRect) + + candidateView.wantsLayer = true + candidateView.layer?.borderColor = NSColor.selectedMenuItemTextColor.withAlphaComponent(0.30).cgColor + candidateView.layer?.borderWidth = 1.0 + if #available(macOS 10.13, *) { + candidateView.layer?.cornerRadius = 6.0 + } + panel.contentView?.addSubview(candidateView) - - contentRect.size = NSSize(width: 20.0, height: 15.0) // Reduce the button width + + contentRect.size = NSSize(width: 20.0, height: 10.0) // Reduce the button width + let buttonAttribute: [NSAttributedString.Key : Any] = [.font : NSFont.systemFont(ofSize: 9.0)] + nextPageButton = NSButton(frame: contentRect) - nextPageButton.setButtonType(.momentaryLight) - nextPageButton.bezelStyle = .shadowlessSquare + NSColor.controlBackgroundColor.setFill() + NSBezierPath.fill(nextPageButton.bounds) nextPageButton.wantsLayer = true nextPageButton.layer?.masksToBounds = true - nextPageButton.layer?.borderColor = NSColor.clear.cgColor // Attempt to remove the system default layer border color - step 1 - nextPageButton.layer?.borderWidth = 0.0 // Attempt to remove the system default layer border color - step 2 - nextPageButton.layer?.backgroundColor = NSColor.black.cgColor // Button Background Color. Otherwise the button will be half-transparent in macOS Monterey Dark Mode. - nextPageButton.attributedTitle = NSMutableAttributedString(string: "➡︎") // Next Page Arrow + nextPageButton.layer?.borderColor = NSColor.clear.cgColor + nextPageButton.layer?.borderWidth = 0.0 + nextPageButton.setButtonType(.momentaryLight) + nextPageButton.bezelStyle = .disclosure + nextPageButton.userInterfaceLayoutDirection = .leftToRight + nextPageButton.attributedTitle = NSMutableAttributedString(string: " ", attributes: buttonAttribute) // Next Page Arrow prevPageButton = NSButton(frame: contentRect) - prevPageButton.setButtonType(.momentaryLight) - prevPageButton.bezelStyle = .shadowlessSquare + NSColor.controlBackgroundColor.setFill() + NSBezierPath.fill(prevPageButton.bounds) prevPageButton.wantsLayer = true prevPageButton.layer?.masksToBounds = true - prevPageButton.layer?.borderColor = NSColor.clear.cgColor // Attempt to remove the system default layer border color - step 1 - prevPageButton.layer?.borderWidth = 0.0 // Attempt to remove the system default layer border color - step 2 - prevPageButton.layer?.backgroundColor = NSColor.black.cgColor // Button Background Color. Otherwise the button will be half-transparent in macOS Monterey Dark Mode. - prevPageButton.attributedTitle = NSMutableAttributedString(string: "⬅︎") // Previous Page Arrow + prevPageButton.layer?.borderColor = NSColor.clear.cgColor + prevPageButton.layer?.borderWidth = 0.0 + prevPageButton.setButtonType(.momentaryLight) + prevPageButton.bezelStyle = .disclosure + prevPageButton.userInterfaceLayoutDirection = .rightToLeft + prevPageButton.attributedTitle = NSMutableAttributedString(string: " ", attributes: buttonAttribute) // Previous Page Arrow panel.contentView?.addSubview(nextPageButton) panel.contentView?.addSubview(prevPageButton) @@ -349,20 +360,20 @@ extension VerticalCandidateController { frameRect.size = newSize candidateView.frame = frameRect - if pageCount > 1 { + if pageCount > 1 && Preferences.showPageButtonsInCandidateWindow { var buttonRect = nextPageButton.frame let spacing:CGFloat = 0.0 // buttonRect.size.height = floor(candidateTextHeight + cellPadding / 2) let buttonOriginY = (newSize.height - (buttonRect.size.height * 2.0 + spacing)) // / 2.0 - buttonRect.origin = NSPoint(x: newSize.width + 8.0, y: buttonOriginY) + buttonRect.origin = NSPoint(x: newSize.width, y: buttonOriginY) nextPageButton.frame = buttonRect - buttonRect.origin = NSPoint(x: newSize.width + 8.0, y: buttonOriginY + buttonRect.size.height + spacing) + buttonRect.origin = NSPoint(x: newSize.width, y: buttonOriginY + buttonRect.size.height + spacing) prevPageButton.frame = buttonRect - newSize.width += 52.0 + newSize.width += 20 nextPageButton.isHidden = false prevPageButton.isHidden = false } else { diff --git a/Source/WindowControllers/ctlPrefWindow.swift b/Source/WindowControllers/ctlPrefWindow.swift index b2b11896..9f3a1756 100644 --- a/Source/WindowControllers/ctlPrefWindow.swift +++ b/Source/WindowControllers/ctlPrefWindow.swift @@ -84,58 +84,44 @@ extension RangeReplaceableCollection where Element: Hashable { menuItem_AppleZhuyinEten.representedObject = String("com.apple.keylayout.ZhuyinEten") basisKeyboardLayoutButton.menu?.addItem(menuItem_AppleZhuyinEten) - let menuItem_vChewingDachen = NSMenuItem() - menuItem_vChewingDachen.title = String(format: NSLocalizedString("vChewing Dachen (Not Finished Yet)", comment: "")) - menuItem_vChewingDachen.representedObject = String("org.atelierInmu.keyboardlayout.vChewingKeyLayout.vChewingDachen") - basisKeyboardLayoutButton.menu?.addItem(menuItem_vChewingDachen) - let basisKeyboardLayoutID = Preferences.basisKeyboardLayout - + for source in list { - - func getString(_ key: CFString) -> String? { - if let ptr = TISGetInputSourceProperty(source, key) { - return String(Unmanaged.fromOpaque(ptr).takeUnretainedValue()) - } - return nil - } - - func getBool(_ key: CFString) -> Bool? { - if let ptr = TISGetInputSourceProperty(source, key) { - return Unmanaged.fromOpaque(ptr).takeUnretainedValue() == kCFBooleanTrue - } - return nil - } - - if let category = getString(kTISPropertyInputSourceCategory) { - if category != String(kTISCategoryKeyboardInputSource) { + if let categoryPtr = TISGetInputSourceProperty(source, kTISPropertyInputSourceCategory) { + let category = Unmanaged.fromOpaque(categoryPtr).takeUnretainedValue() + if category != kTISCategoryKeyboardInputSource { continue } } else { continue } - if let asciiCapable = getBool(kTISPropertyInputSourceIsASCIICapable) { - if !asciiCapable { + if let asciiCapablePtr = TISGetInputSourceProperty(source, kTISPropertyInputSourceIsASCIICapable) { + let asciiCapable = Unmanaged.fromOpaque(asciiCapablePtr).takeUnretainedValue() + if asciiCapable != kCFBooleanTrue { continue } } else { continue } - if let sourceType = getString(kTISPropertyInputSourceType) { - if sourceType != String(kTISTypeKeyboardLayout) { + if let sourceTypePtr = TISGetInputSourceProperty(source, kTISPropertyInputSourceType) { + let sourceType = Unmanaged.fromOpaque(sourceTypePtr).takeUnretainedValue() + if sourceType != kTISTypeKeyboardLayout { continue } } else { continue } - guard let sourceID = getString(kTISPropertyInputSourceID), - let localizedName = getString(kTISPropertyLocalizedName) else { + guard let sourceIDPtr = TISGetInputSourceProperty(source, kTISPropertyInputSourceID), + let localizedNamePtr = TISGetInputSourceProperty(source, kTISPropertyLocalizedName) else { continue } + let sourceID = String(Unmanaged.fromOpaque(sourceIDPtr).takeUnretainedValue()) + let localizedName = String(Unmanaged.fromOpaque(localizedNamePtr).takeUnretainedValue()) + let menuItem = NSMenuItem() menuItem.title = localizedName menuItem.representedObject = sourceID @@ -154,8 +140,6 @@ extension RangeReplaceableCollection where Element: Hashable { chosenBaseKeyboardLayoutItem = menuItem_AppleZhuyinBopomofo case "com.apple.keylayout.ZhuyinEten": chosenBaseKeyboardLayoutItem = menuItem_AppleZhuyinEten - case "org.atelierInmu.keyboardlayout.vChewingKeyLayout.zhuyindachen": - chosenBaseKeyboardLayoutItem = menuItem_vChewingDachen default: break // nothing to do } @@ -177,6 +161,16 @@ extension RangeReplaceableCollection where Element: Hashable { } + // 這裡有必要加上這段處理,用來確保藉由偏好設定介面動過的 CNS 開關能夠立刻生效。 + // 所有涉及到語言模型開關的內容均需要這樣處理。 + @IBAction func toggleCNSSupport(_ sender: Any) { + mgrLangModel.setCNSEnabled(Preferences.cns11643Enabled) + } + + @IBAction func toggleSymbolInputEnabled(_ sender: Any) { + mgrLangModel.setSymbolEnabled(Preferences.symbolInputEnabled) + } + @IBAction func toggleTrad2KangXiAction(_ sender: Any) { if chkTrad2KangXi.state == .on && chkTrad2JISShinjitai.state == .on { Preferences.toggleShiftJISShinjitaiOutputEnabled() diff --git a/Source/WindowNIBs/Source/WindowNIBs/Base.lproj/frmPrefWindow.xib b/Source/WindowNIBs/Source/WindowNIBs/Base.lproj/frmPrefWindow.xib index 8cf4f8fd..e59f26c0 100644 --- a/Source/WindowNIBs/Source/WindowNIBs/Base.lproj/frmPrefWindow.xib +++ b/Source/WindowNIBs/Source/WindowNIBs/Base.lproj/frmPrefWindow.xib @@ -22,7 +22,7 @@ - + @@ -51,7 +51,7 @@ - + @@ -62,7 +62,7 @@ - + @@ -87,7 +87,7 @@ - + @@ -95,7 +95,7 @@ - + @@ -114,7 +114,7 @@ - + @@ -126,7 +126,7 @@ - + @@ -134,12 +134,9 @@ - - - - + - + @@ -151,6 +148,8 @@ + + @@ -161,8 +160,19 @@ + - + @@ -172,35 +182,33 @@ - - - - + + + - - + - + - + - - + + + - - + + - - + - + @@ -224,7 +232,7 @@ - @@ -259,18 +268,8 @@ - - + @@ -468,16 +448,62 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + - - - + + + + + + - - - - - - - - - - + + + + @@ -586,8 +655,26 @@ + + + + + + + + Regarding On-Screen Keyboard Viewer Support: + + Since v1.3.2, vChewing supports on-screen keyboard by supporting "Apple Zhuyin Bopomofo" and "Apple Zhuyin Eten" alphanumeric layout. Theoreotically, these two dynamic layouts work with all types of Apple physical keyboards, and you can report failure cases through macOS Feedback Assistant app if macOS built-in Zhuyin / Eten-Zhuyin Input Method fails from working with your non-US keyboard. + + HOWEVER, choosing such dynamic alphanumeric layouts REQUIRING THAT you have to choose the Bopomofo layout above to Standard (Microsoft / Dachen) since the Bopomofo / Eten layout support in this case is already finished by the macOS system. + + Note that If you have chosen those "vChewing****" Alphanumerical layouts, then the Bopomofo layouts MUST MATCH the choices. + + + + - + @@ -599,7 +686,7 @@ - + @@ -624,7 +711,7 @@ - + @@ -638,49 +725,33 @@ - + - - - - - - - - Regarding On-Screen Keyboard Viewer Support: - - Since v1.3.2, vChewing supports on-screen keyboard by supporting "Apple Zhuyin Bopomofo" and "Apple Zhuyin Eten" alphanumeric layout. Theoreotically, these two dynamic layouts work with all types of Apple physical keyboards, and you can report failure cases through macOS Feedback Assistant app if macOS built-in Zhuyin / Eten-Zhuyin Input Method fails from working with your non-US keyboard. - - HOWEVER, choosing such dynamic alphanumeric layouts REQUIRING THAT you have to choose the Bopomofo layout above to Standard (Microsoft / Dachen) since the Bopomofo / Eten layout support in this case is already finished by the macOS system. - - - - - + - + - + - + @@ -705,7 +776,7 @@ - + diff --git a/Source/WindowNIBs/Source/WindowNIBs/en.lproj/frmPrefWindow.strings b/Source/WindowNIBs/Source/WindowNIBs/en.lproj/frmPrefWindow.strings index 0f699ea3..738aa27a 100644 --- a/Source/WindowNIBs/Source/WindowNIBs/en.lproj/frmPrefWindow.strings +++ b/Source/WindowNIBs/Source/WindowNIBs/en.lproj/frmPrefWindow.strings @@ -47,6 +47,9 @@ /* Class = "NSButtonCell"; title = "Vertical"; ObjectID = "22"; */ "22.title" = "Vertical"; +/* Class = "NSButtonCell"; title = "Show page buttons in candidate list"; ObjectID = "shc-Nu-UsM"; */ +"shc-Nu-UsM.title" = "Show page buttons in candidate list"; + /* Class = "NSTextFieldCell"; title = "Candidate List Layout:"; ObjectID = "24"; */ "24.title" = "Candidate List Layout:"; @@ -80,8 +83,8 @@ /* Class = "NSMenuItem"; title = "96"; ObjectID = "101"; */ "101.title" = "96"; -/* Class = "NSButtonCell"; title = "Enable SPACE key for calling candidate window"; ObjectID = "110"; */ -"110.title" = "Enable SPACE key for calling candidate window"; +/* Class = "NSButtonCell"; title = "Enable Space key for calling candidate window"; ObjectID = "110"; */ +"110.title" = "Enable Space key for calling candidate window"; /* Class = "NSTextFieldCell"; title = "Alphanumeric:"; ObjectID = "126"; */ "126.title" = "Alphanumeric:"; @@ -140,8 +143,8 @@ /* Class = "NSTextFieldCell"; title = "Choose your preferred keyboard layout."; ObjectID = "RQ6-MS-m4C"; */ "RQ6-MS-m4C.title" = "Choose your preferred keyboard layout."; -/* Class = "NSButtonCell"; title = "Push the cursor to the front of the phrase after candidate selection"; ObjectID = "RUG-ls-KyA"; */ -"RUG-ls-KyA.title" = "Push the cursor to the front of the phrase after candidate selection"; +/* Class = "NSButtonCell"; title = "Push the cursor to the front of the phrase after selection"; ObjectID = "RUG-ls-KyA"; */ +"RUG-ls-KyA.title" = "Push the cursor to the front of the phrase after selection"; /* Class = "NSMenuItem"; title = "Traditional Chinese"; ObjectID = "TXr-FF-ehw"; */ "TXr-FF-ehw.title" = "Traditional Chinese"; @@ -185,8 +188,8 @@ /* Class = "NSMenuItem"; title = "Japanese"; ObjectID = "rVQ-Hx-cGi"; */ "rVQ-Hx-cGi.title" = "Japanese"; -/* Class = "NSBox"; title = "Dictionary Settings"; ObjectID = "s4r-ji-vbr"; */ -"s4r-ji-vbr.title" = "Dictionary Settings"; +/* Class = "NSBox"; title = "Dictionary and Language Models"; ObjectID = "cf2-se-PDO"; */ +"cf2-se-PDO.title" = "Dictionary and Language Models"; /* Class = "NSTextFieldCell"; title = "Choose your preferred layout of the candidate window."; ObjectID = "xC5-yV-1W1"; */ "xC5-yV-1W1.title" = "Choose your preferred layout of the candidate window."; @@ -194,8 +197,14 @@ /* Class = "NSTabViewItem"; label = "Advanced"; ObjectID = "xrE-8T-WKO"; */ "xrE-8T-WKO.label" = "Advanced"; +/* Class = "NSTabViewItem"; label = "Dictionary"; ObjectID = "2iG-Ic-gbl"; */ +"2iG-Ic-gbl.label" = "Dictionary"; + /* Class = "NSTextFieldCell"; title = "Regarding On-Screen Keyboard Support:"; ObjectID = "wQ9-px-b07"; */ -"wQ9-px-b07.title" = "Regarding On-Screen Keyboard Viewer Support:\n\n\tSince v1.3.2, vChewing supports on-screen keyboard by supporting \"Apple Zhuyin Bopomofo\" and \"Apple Zhuyin Eten\" alphanumeric layout. Theoreotically, these two dynamic layouts work with all types of Apple physical keyboards, and you can report failure cases through macOS Feedback Assistant app if macOS built-in Zhuyin / Eten-Zhuyin Input Method fails from working with your non-US keyboard.\n\n\tHOWEVER, choosing such dynamic alphanumeric layouts REQUIRING THAT you have to choose the Bopomofo layout above to Standard (Microsoft / Dachen) since the Bopomofo / Eten layout support in this case is already finished by the macOS system."; +"wQ9-px-b07.title" = "Regarding On-Screen Keyboard Viewer Support:\n\n\tSince v1.3.2, vChewing supports on-screen keyboard by supporting \"Apple Zhuyin Bopomofo\" and \"Apple Zhuyin Eten\" alphanumeric layout. Theoreotically, these two dynamic layouts work with all types of Apple physical keyboards, and you can report failure cases through macOS Feedback Assistant app if macOS built-in Zhuyin / Eten-Zhuyin Input Method fails from working with your non-US keyboard. HOWEVER, choosing such dynamic alphanumeric layouts REQUIRING THAT you have to choose the Bopomofo layout above to Standard (Microsoft / Dachen) since the Bopomofo / Eten layout support in this case is already finished by the macOS system.\n\n\tAlso: If you have chosen those \"vChewing****\" Alphanumerical layouts, then the Bopomofo layouts MUST MATCH the choices."; + +/* Class = "NSTextFieldCell"; title = "Choose the behavior of (Shift+)Tab key in the candidate window."; ObjectID = "ueU-Rz-a1C"; */ +"ueU-Rz-a1C.title" = "Choose the behavior of (Shift+)Tab key in the candidate window."; /* Class = "NSButtonCell"; title = "Cycling Pages"; ObjectID = "s7u-Fm-dVg"; */ "s7u-Fm-dVg.title" = "Cycling Pages"; @@ -203,5 +212,14 @@ /* Class = "NSButtonCell"; title = "Cycling Candidates"; ObjectID = "FVC-br-H57"; */ "FVC-br-H57.title" = "Cycling Candidates"; -/* Class = "NSTextFieldCell"; title = "Choose the behavior of (Shift+)Tab key in the candidate window."; ObjectID = "ueU-Rz-a1C"; */ -"ueU-Rz-a1C.title" = "Choose the behavior of (Shift+)Tab key in the candidate window."; +/* Class = "NSTextFieldCell"; title = "Choose the behavior of (Shift+)Space key in the candidate window."; ObjectID = "Pg5-G9-pY5"; */ +"Pg5-G9-pY5.title" = "Choose the behavior of (Shift+)Space key in the candidate window."; + +/* Class = "NSButtonCell"; title = "Space to +cycle pages, Shift+Space to +cycle candidates"; ObjectID = "XqL-rf-X6d"; */ +"XqL-rf-X6d.title" = "Space to +cycle pages, Shift+Space to +cycle candidates"; + +/* Class = "NSButtonCell"; title = "Space to +cycle candidates, Shift+Space to +cycle pages"; ObjectID = "dIN-TZ-67g"; */ +"dIN-TZ-67g.title" = "Space to +cycle candidates, Shift+Space to +cycle pages"; + +/* Class = "NSButtonCell"; title = "Enable symbol input support (incl. certain emoji symbols)"; ObjectID = "hSv-LJ-Cq3"; */ +"hSv-LJ-Cq3.title" = "Enable symbol input support (incl. certain emoji symbols)"; diff --git a/Source/WindowNIBs/Source/WindowNIBs/ja.lproj/frmPrefWindow.strings b/Source/WindowNIBs/Source/WindowNIBs/ja.lproj/frmPrefWindow.strings index 27296d66..15794051 100644 --- a/Source/WindowNIBs/Source/WindowNIBs/ja.lproj/frmPrefWindow.strings +++ b/Source/WindowNIBs/Source/WindowNIBs/ja.lproj/frmPrefWindow.strings @@ -47,6 +47,9 @@ /* Class = "NSButtonCell"; title = "Vertical"; ObjectID = "22"; */ "22.title" = "縦型陳列"; +/* Class = "NSButtonCell"; title = "Show page buttons in candidate list"; ObjectID = "shc-Nu-UsM"; */ +"shc-Nu-UsM.title" = "ページボタンを表示"; + /* Class = "NSTextFieldCell"; title = "Candidate List Layout:"; ObjectID = "24"; */ "24.title" = "入力候補陳列の仕様:"; @@ -80,8 +83,8 @@ /* Class = "NSMenuItem"; title = "96"; ObjectID = "101"; */ "101.title" = "96"; -/* Class = "NSButtonCell"; title = "Enable SPACE key for calling candidate window"; ObjectID = "110"; */ -"110.title" = "スペースキーで入力候補を呼び出す"; +/* Class = "NSButtonCell"; title = "Enable Space key for calling candidate window"; ObjectID = "110"; */ +"110.title" = "Space キーで入力候補を呼び出す"; /* Class = "NSTextFieldCell"; title = "Alphanumeric:"; ObjectID = "126"; */ "126.title" = "英数キーボード配列:"; @@ -140,7 +143,7 @@ /* Class = "NSTextFieldCell"; title = "Choose your preferred keyboard layout."; ObjectID = "RQ6-MS-m4C"; */ "RQ6-MS-m4C.title" = "お好きなるキーボード配列をお選びください。"; -/* Class = "NSButtonCell"; title = "Push the cursor to the front of the phrase after candidate selection"; ObjectID = "RUG-ls-KyA"; */ +/* Class = "NSButtonCell"; title = "Push the cursor to the front of the phrase after selection"; ObjectID = "RUG-ls-KyA"; */ "RUG-ls-KyA.title" = "候補選択の直後、すぐカーソルを単語の後ろに移す"; /* Class = "NSMenuItem"; title = "Traditional Chinese"; ObjectID = "TXr-FF-ehw"; */ @@ -185,8 +188,8 @@ /* Class = "NSMenuItem"; title = "Japanese"; ObjectID = "rVQ-Hx-cGi"; */ "rVQ-Hx-cGi.title" = "和語"; -/* Class = "NSBox"; title = "Dictionary Settings"; ObjectID = "s4r-ji-vbr"; */ -"s4r-ji-vbr.title" = "辞書設定"; +/* Class = "NSBox"; title = "Dictionary and Language Models"; ObjectID = "cf2-se-PDO"; */ +"cf2-se-PDO.title" = "辞書と言語モデル"; /* Class = "NSTextFieldCell"; title = "Choose your preferred layout of the candidate window."; ObjectID = "xC5-yV-1W1"; */ "xC5-yV-1W1.title" = "入力候補陳列の仕様をご指定ください。"; @@ -194,8 +197,14 @@ /* Class = "NSTabViewItem"; label = "Advanced"; ObjectID = "xrE-8T-WKO"; */ "xrE-8T-WKO.label" = "詳細"; +/* Class = "NSTabViewItem"; label = "Dictionary"; ObjectID = "2iG-Ic-gbl"; */ +"2iG-Ic-gbl.label" = "辞書"; + /* Class = "NSTextFieldCell"; title = "Regarding On-Screen Keyboard Support:"; ObjectID = "wQ9-px-b07"; */ -"wQ9-px-b07.title" = "macOS 内蔵のキーボードビューアについて:\n\n\t威注音は v1.3.2 版にて macOS 内蔵のキーボードビューアをサポートし始めたが、「Apple Zhuyin Bopomofo」と「Apple Zhuyin Eten」この2つダイナミック英数キーボード配列をサポートしたためである。基本的には、この機能は全ての言語の Apple キーボードと一緒に動けるはず。macOS 内蔵の注音入力と倚天注音入力が支障なく使える限り(支障があったら Feedback Assistant.app で Apple にご報告を)、この2つダイナミック英数キーボード配列も威注音で作動できるだと考えられる。\n\n\tだが、もし、ダイナミック英数キーボード配列を起用すると、今のこの画面の上の「注音キーボード配列」を標準配列にしなければならぬこと。なぜなら、この場合、倚天などの注音配列のサポート役割は macOS である。"; +"wQ9-px-b07.title" = "macOS 内蔵のキーボードビューアについて:\n\n\t威注音は v1.3.2 版にて macOS 内蔵のキーボードビューアをサポートし始めたが、「Apple Zhuyin Bopomofo」と「Apple Zhuyin Eten」この2つダイナミック英数キーボード配列をサポートしたためである。基本的には、この機能は全ての言語の Apple キーボードと一緒に動けるはず。macOS 内蔵の注音入力と倚天注音入力が支障なく使える限り(支障があったら Feedback Assistant.app で Apple にご報告を)、この2つダイナミック英数キーボード配列も威注音で作動できるだと考えられる。だが、もし、ダイナミック英数キーボード配列を起用すると、今のこの画面の上の「注音キーボード配列」を標準配列にしなければならぬこと。なぜなら、この場合、倚天などの注音配列のサポート役割は macOS である。\n\n\t他に注意:英数配列を「vChewing○○○○」と名付けた配列に設定した場合、注音配列も必ず一致して下さい。"; + +/* Class = "NSTextFieldCell"; title = "Choose the behavior of (Shift+)Tab key in the candidate window."; ObjectID = "ueU-Rz-a1C"; */ +"ueU-Rz-a1C.title" = "入力候補陳列での (Shift+)Tab キーの輪番切替対象をご指定ください。"; /* Class = "NSButtonCell"; title = "Cycling Pages"; ObjectID = "s7u-Fm-dVg"; */ "s7u-Fm-dVg.title" = "ページ"; @@ -203,5 +212,14 @@ /* Class = "NSButtonCell"; title = "Cycling Candidates"; ObjectID = "FVC-br-H57"; */ "FVC-br-H57.title" = "候補文字そのもの"; -/* Class = "NSTextFieldCell"; title = "Choose the behavior of (Shift+)Tab key in the candidate window."; ObjectID = "ueU-Rz-a1C"; */ -"ueU-Rz-a1C.title" = "入力候補陳列での (Shift+)Tab キーの輪番切替対象をご指定ください。"; +/* Class = "NSTextFieldCell"; title = "Choose the behavior of (Shift+)Space key in the candidate window."; ObjectID = "Pg5-G9-pY5"; */ +"Pg5-G9-pY5.title" = "入力候補陳列での (Shift+)Space キーの輪番切替対象をご指定ください。"; + +/* Class = "NSButtonCell"; title = "Space to +cycle pages, Shift+Space to +cycle candidates"; ObjectID = "XqL-rf-X6d"; */ +"XqL-rf-X6d.title" = "Space で次のページ、Shift+Space で次の候補文字を"; + +/* Class = "NSButtonCell"; title = "Space to +cycle candidates, Shift+Space to +cycle pages"; ObjectID = "dIN-TZ-67g"; */ +"dIN-TZ-67g.title" = "Shift+Space で次のページ、Space で次の候補文字を"; + +/* Class = "NSButtonCell"; title = "Enable symbol input support (incl. certain emoji symbols)"; ObjectID = "hSv-LJ-Cq3"; */ +"hSv-LJ-Cq3.title" = "僅かなる絵文字も含む符号入力サポートを起用"; diff --git a/Source/WindowNIBs/Source/WindowNIBs/zh-Hans.lproj/frmPrefWindow.strings b/Source/WindowNIBs/Source/WindowNIBs/zh-Hans.lproj/frmPrefWindow.strings index 600874d5..323eb6c9 100644 --- a/Source/WindowNIBs/Source/WindowNIBs/zh-Hans.lproj/frmPrefWindow.strings +++ b/Source/WindowNIBs/Source/WindowNIBs/zh-Hans.lproj/frmPrefWindow.strings @@ -47,6 +47,9 @@ /* Class = "NSButtonCell"; title = "Vertical"; ObjectID = "22"; */ "22.title" = "纵向布局"; +/* Class = "NSButtonCell"; title = "Show page buttons in candidate list"; ObjectID = "shc-Nu-UsM"; */ +"shc-Nu-UsM.title" = "在选字窗内显示翻页按钮"; + /* Class = "NSTextFieldCell"; title = "Candidate List Layout:"; ObjectID = "24"; */ "24.title" = "候选字窗布局:"; @@ -80,7 +83,7 @@ /* Class = "NSMenuItem"; title = "96"; ObjectID = "101"; */ "101.title" = "96"; -/* Class = "NSButtonCell"; title = "Enable SPACE key for calling candidate window"; ObjectID = "110"; */ +/* Class = "NSButtonCell"; title = "Enable Space key for calling candidate window"; ObjectID = "110"; */ "110.title" = "敲空格键以选字"; /* Class = "NSTextFieldCell"; title = "Alphanumeric:"; ObjectID = "126"; */ @@ -140,7 +143,7 @@ /* Class = "NSTextFieldCell"; title = "Choose your preferred keyboard layout."; ObjectID = "RQ6-MS-m4C"; */ "RQ6-MS-m4C.title" = "选择您所偏好的键盘布局。"; -/* Class = "NSButtonCell"; title = "Push the cursor to the front of the phrase after candidate selection"; ObjectID = "RUG-ls-KyA"; */ +/* Class = "NSButtonCell"; title = "Push the cursor to the front of the phrase after selection"; ObjectID = "RUG-ls-KyA"; */ "RUG-ls-KyA.title" = "在选字后将光标置于该字词的前方"; /* Class = "NSMenuItem"; title = "Traditional Chinese"; ObjectID = "TXr-FF-ehw"; */ @@ -185,8 +188,8 @@ /* Class = "NSMenuItem"; title = "Japanese"; ObjectID = "rVQ-Hx-cGi"; */ "rVQ-Hx-cGi.title" = "和语"; -/* Class = "NSBox"; title = "Dictionary Settings"; ObjectID = "s4r-ji-vbr"; */ -"s4r-ji-vbr.title" = "辞典设定"; +/* Class = "NSBox"; title = "Dictionary and Language Models"; ObjectID = "cf2-se-PDO"; */ +"cf2-se-PDO.title" = "辞典&語言模型"; /* Class = "NSTextFieldCell"; title = "Choose your preferred layout of the candidate window."; ObjectID = "xC5-yV-1W1"; */ "xC5-yV-1W1.title" = "选择您所偏好的候选字窗布局。"; @@ -194,8 +197,14 @@ /* Class = "NSTabViewItem"; label = "Advanced"; ObjectID = "xrE-8T-WKO"; */ "xrE-8T-WKO.label" = "进阶"; +/* Class = "NSTabViewItem"; label = "Dictionary"; ObjectID = "2iG-Ic-gbl"; */ +"2iG-Ic-gbl.label" = "辞典"; + /* Class = "NSTextFieldCell"; title = "Regarding On-Screen Keyboard Support:"; ObjectID = "wQ9-px-b07"; */ -"wQ9-px-b07.title" = "关于 macOS 内建萤幕模拟键盘支援:\n\n\t自 v1.3.2 版开始,威注音支援 macOS 内建的萤幕小键盘。该功能是借由对「Apple 标准注音键盘布局」与「Apple 倚天注音键盘布局」这两个动态英数键盘布局来完成的。理论上来讲,这两个动态英数键盘布局应该可以与所有语种的 Apple 物理键盘相容。如果有不相容的情况的话,macOS 内建的注音与倚天注音输入法一定也会有相同的故障(可以借由 Feedback Assistant.app 向 Apple 反馈这种键盘布局问题)。\n\n\t然而,如果您启用了这种动态英数键盘布局的话,请将当前画面顶端的注音键盘布局设为「微软/大千……」,因为对诸如倚天等异种键盘的支援已经交给 macOS 系统来事先完成了。"; +"wQ9-px-b07.title" = "关于 macOS 内建萤幕模拟键盘支援:\n\n\t自 v1.3.2 版开始,威注音支援 macOS 内建的萤幕小键盘。该功能是借由对「Apple 标准注音键盘布局」与「Apple 倚天注音键盘布局」这两个动态英数键盘布局来完成的。理论上来讲,这两个动态英数键盘布局应该可以与所有语种的 Apple 物理键盘相容。如果有不相容的情况的话,macOS 内建的注音与倚天注音输入法一定也会有相同的故障(可以借由 Feedback Assistant.app 向 Apple 反馈这种键盘布局问题)。然而,如果您启用了这种动态英数键盘布局的话,请将当前画面顶端的注音键盘布局设为「微软/大千……」,因为对诸如倚天等异种键盘的支援已经交给 macOS 系统来事先完成了。\n\n\t另外:如果您在「英数键盘布局」内选了所有以「vChewing」开头的键盘配列的话,对应的「注音键盘布局」也要选成相同的配列才可以。比如说前者选「vChewing Dachen」那后者就得选「微软/大千……」、前者选「vChewing FakeSeigyou」那后者就得选「伪精业」,依此类推。"; + +/* Class = "NSTextFieldCell"; title = "Choose the behavior of (Shift+)Tab key in the candidate window."; ObjectID = "ueU-Rz-a1C"; */ +"ueU-Rz-a1C.title" = "指定 (Shift+)Tab 热键在选字窗内的轮替操作对象。"; /* Class = "NSButtonCell"; title = "Cycling Pages"; ObjectID = "s7u-Fm-dVg"; */ "s7u-Fm-dVg.title" = "轮替页面"; @@ -203,5 +212,14 @@ /* Class = "NSButtonCell"; title = "Cycling Candidates"; ObjectID = "FVC-br-H57"; */ "FVC-br-H57.title" = "轮替候选字"; -/* Class = "NSTextFieldCell"; title = "Choose the behavior of (Shift+)Tab key in the candidate window."; ObjectID = "ueU-Rz-a1C"; */ -"ueU-Rz-a1C.title" = "指定 (Shift+)Tab 热键在选字窗内的轮替操作对象。"; +/* Class = "NSTextFieldCell"; title = "Choose the behavior of (Shift+)Space key in the candidate window."; ObjectID = "Pg5-G9-pY5"; */ +"Pg5-G9-pY5.title" = "指定 (Shift+)Space 热键在选字窗内的轮替操作对象。"; + +/* Class = "NSButtonCell"; title = "Space to +cycle pages, Shift+Space to +cycle candidates"; ObjectID = "XqL-rf-X6d"; */ +"XqL-rf-X6d.title" = "Space 换下一页,Shift+Space 换选下一个候选字。"; + +/* Class = "NSButtonCell"; title = "Space to +cycle candidates, Shift+Space to +cycle pages"; ObjectID = "dIN-TZ-67g"; */ +"dIN-TZ-67g.title" = "Shift+Space 换下一页,Space 换选下一个候选字。"; + +/* Class = "NSButtonCell"; title = "Enable symbol input support (incl. certain emoji symbols)"; ObjectID = "hSv-LJ-Cq3"; */ +"hSv-LJ-Cq3.title" = "启用包括少许绘文字在内的符号输入支援"; diff --git a/Source/WindowNIBs/Source/WindowNIBs/zh-Hant.lproj/frmPrefWindow.strings b/Source/WindowNIBs/Source/WindowNIBs/zh-Hant.lproj/frmPrefWindow.strings index 0fff1e88..03e9557c 100644 --- a/Source/WindowNIBs/Source/WindowNIBs/zh-Hant.lproj/frmPrefWindow.strings +++ b/Source/WindowNIBs/Source/WindowNIBs/zh-Hant.lproj/frmPrefWindow.strings @@ -47,6 +47,9 @@ /* Class = "NSButtonCell"; title = "Vertical"; ObjectID = "22"; */ "22.title" = "縱向佈局"; +/* Class = "NSButtonCell"; title = "Show page buttons in candidate list"; ObjectID = "shc-Nu-UsM"; */ +"shc-Nu-UsM.title" = "在選字窗內顯示翻頁按鈕"; + /* Class = "NSTextFieldCell"; title = "Candidate List Layout:"; ObjectID = "24"; */ "24.title" = "候選字窗佈局:"; @@ -80,7 +83,7 @@ /* Class = "NSMenuItem"; title = "96"; ObjectID = "101"; */ "101.title" = "96"; -/* Class = "NSButtonCell"; title = "Enable SPACE key for calling candidate window"; ObjectID = "110"; */ +/* Class = "NSButtonCell"; title = "Enable Space key for calling candidate window"; ObjectID = "110"; */ "110.title" = "敲空格鍵以選字"; /* Class = "NSTextFieldCell"; title = "Alphanumeric:"; ObjectID = "126"; */ @@ -140,7 +143,7 @@ /* Class = "NSTextFieldCell"; title = "Choose your preferred keyboard layout."; ObjectID = "RQ6-MS-m4C"; */ "RQ6-MS-m4C.title" = "選擇您所偏好的鍵盤佈局。"; -/* Class = "NSButtonCell"; title = "Push the cursor to the front of the phrase after candidate selection"; ObjectID = "RUG-ls-KyA"; */ +/* Class = "NSButtonCell"; title = "Push the cursor to the front of the phrase after selection"; ObjectID = "RUG-ls-KyA"; */ "RUG-ls-KyA.title" = "在選字後將游標置於該字詞的前方"; /* Class = "NSMenuItem"; title = "Traditional Chinese"; ObjectID = "TXr-FF-ehw"; */ @@ -185,8 +188,8 @@ /* Class = "NSMenuItem"; title = "Japanese"; ObjectID = "rVQ-Hx-cGi"; */ "rVQ-Hx-cGi.title" = "和語"; -/* Class = "NSBox"; title = "Dictionary Settings"; ObjectID = "s4r-ji-vbr"; */ -"s4r-ji-vbr.title" = "辭典設定"; +/* Class = "NSBox"; title = "Dictionary and Language Models"; ObjectID = "cf2-se-PDO"; */ +"cf2-se-PDO.title" = "辭典&語言模型"; /* Class = "NSTextFieldCell"; title = "Choose your preferred layout of the candidate window."; ObjectID = "xC5-yV-1W1"; */ "xC5-yV-1W1.title" = "選擇您所偏好的候選字窗佈局。"; @@ -194,8 +197,14 @@ /* Class = "NSTabViewItem"; label = "Advanced"; ObjectID = "xrE-8T-WKO"; */ "xrE-8T-WKO.label" = "進階"; +/* Class = "NSTabViewItem"; label = "Dictionary"; ObjectID = "2iG-Ic-gbl"; */ +"2iG-Ic-gbl.label" = "辭典"; + /* Class = "NSTextFieldCell"; title = "Regarding On-Screen Keyboard Support:"; ObjectID = "wQ9-px-b07"; */ -"wQ9-px-b07.title" = "關於 macOS 內建螢幕模擬鍵盤支援:\n\n\t自 v1.3.2 版開始,威注音支援 macOS 內建的螢幕小鍵盤。該功能是藉由對「Apple 標準注音鍵盤佈局」與「Apple 倚天注音鍵盤佈局」這兩個動態英數鍵盤佈局來完成的。理論上來講,這兩個動態英數鍵盤佈局應該可以與所有語種的 Apple 物理鍵盤相容。如果有不相容的情況的話,macOS 內建的注音與倚天注音輸入法一定也會有相同的故障(可以藉由 Feedback Assistant.app 向 Apple 反饋這種鍵盤佈局問題)。\n\n\t然而,如果您啟用了這種動態英數鍵盤佈局的話,請將當前畫面頂端的注音鍵盤佈局設為「微軟/大千……」,因為對諸如倚天等異種鍵盤的支援已經交給 macOS 系統來事先完成了。"; +"wQ9-px-b07.title" = "關於 macOS 內建螢幕模擬鍵盤支援:\n\n\t自 v1.3.2 版開始,威注音支援 macOS 內建的螢幕小鍵盤。該功能是藉由對「Apple 標準注音鍵盤佈局」與「Apple 倚天注音鍵盤佈局」這兩個動態英數鍵盤佈局來完成的。理論上來講,這兩個動態英數鍵盤佈局應該可以與所有語種的 Apple 物理鍵盤相容。如果有不相容的情況的話,macOS 內建的注音與倚天注音輸入法一定也會有相同的故障(可以藉由 Feedback Assistant.app 向 Apple 反饋這種鍵盤佈局問題)。然而,如果您啟用了這種動態英數鍵盤佈局的話,請將當前畫面頂端的注音鍵盤佈局設為「微軟/大千……」,因為對諸如倚天等異種鍵盤的支援已經交給 macOS 系統來事先完成了。\n\n\t另外:如果您在「英數鍵盤佈局」內選了所有以「vChewing」開頭的鍵盤配列的話,對應的「注音鍵盤佈局」也要選成相同的配列才可以。比如說前者選「vChewing Dachen」那後者就得選「微軟/大千……」、前者選「vChewing FakeSeigyou」那後者就得選「偽精業」,依此類推。"; + +/* Class = "NSTextFieldCell"; title = "Choose the behavior of (Shift+)Tab key in the candidate window."; ObjectID = "ueU-Rz-a1C"; */ +"ueU-Rz-a1C.title" = "指定 (Shift+)Tab 熱鍵在選字窗內的輪替操作對象。"; /* Class = "NSButtonCell"; title = "Cycling Pages"; ObjectID = "s7u-Fm-dVg"; */ "s7u-Fm-dVg.title" = "輪替頁面"; @@ -203,5 +212,15 @@ /* Class = "NSButtonCell"; title = "Cycling Candidates"; ObjectID = "FVC-br-H57"; */ "FVC-br-H57.title" = "輪替候選字"; -/* Class = "NSTextFieldCell"; title = "Choose the behavior of (Shift+)Tab key in the candidate window."; ObjectID = "ueU-Rz-a1C"; */ -"ueU-Rz-a1C.title" = "指定 (Shift+)Tab 熱鍵在選字窗內的輪替操作對象。"; +/* Class = "NSTextFieldCell"; title = "Choose the behavior of (Shift+)Space key in the candidate window."; ObjectID = "Pg5-G9-pY5"; */ +"Pg5-G9-pY5.title" = "指定 (Shift+)Space 熱鍵在選字窗內的輪替操作對象。"; + +/* Class = "NSButtonCell"; title = "Space to +cycle pages, Shift+Space to +cycle candidates"; ObjectID = "XqL-rf-X6d"; */ +"XqL-rf-X6d.title" = "Space 換下一頁,Shift+Space 換選下一個候選字"; + +/* Class = "NSButtonCell"; title = "Space to +cycle candidates, Shift+Space to +cycle pages"; ObjectID = "dIN-TZ-67g"; */ +"dIN-TZ-67g.title" = "Shift+Space 換下一頁,Space 換選下一個候選字"; + +/* Class = "NSButtonCell"; title = "Enable symbol input support (incl. certain emoji symbols)"; ObjectID = "hSv-LJ-Cq3"; */ +"hSv-LJ-Cq3.title" = "啟用包括少許繪文字在內的符號輸入支援"; + diff --git a/Update-Info.plist b/Update-Info.plist index 40e16d4a..e4ade5b1 100644 --- a/Update-Info.plist +++ b/Update-Info.plist @@ -7,8 +7,8 @@ UpdateInfoSite https://gitee.com/vChewing/vChewing-macOS/releases CFBundleVersion - 1925 + 1927 CFBundleShortVersionString - 1.3.6 + 1.3.7 diff --git a/UserPhraseEditor/AppDelegate.swift b/UserPhraseEditor/AppDelegate.swift index 895e5327..dd33c82a 100644 --- a/UserPhraseEditor/AppDelegate.swift +++ b/UserPhraseEditor/AppDelegate.swift @@ -41,6 +41,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { } ctlAboutWindowInstance?.window?.center() ctlAboutWindowInstance?.window?.orderFrontRegardless() // 逼著關於視窗往最前方顯示 + ctlAboutWindowInstance?.window?.level = .statusBar } // Call the New About Window @IBAction func about(_ sender: Any) { diff --git a/UserPhraseEditor/StringExtension.swift b/UserPhraseEditor/StringExtension.swift index 70faf0f0..fc3ca498 100644 --- a/UserPhraseEditor/StringExtension.swift +++ b/UserPhraseEditor/StringExtension.swift @@ -20,9 +20,10 @@ import Foundation extension String { mutating func regReplace(pattern: String, replaceWith: String = "") { + // Ref: https://stackoverflow.com/a/40993403/4162914 && https://stackoverflow.com/a/71291137/4162914 do { let regex = try NSRegularExpression(pattern: pattern, options: .caseInsensitive) - let range = NSRange(location: 0, length: count) + let range = NSRange(location: 0, length: self.utf16.count) self = regex.stringByReplacingMatches(in: self, options: [], range: range, withTemplate: replaceWith) } catch { return } } @@ -31,15 +32,13 @@ extension String { var strProcessed = self // 預處理格式 strProcessed = strProcessed.replacingOccurrences(of: " #MACOS", with: "") // 去掉 macOS 標記 - strProcessed = strProcessed.replacingOccurrences(of: " ", with: " ") // CJKWhiteSpace (\x{3000}) to ASCII Space - strProcessed = strProcessed.replacingOccurrences(of: " ", with: " ") // NonBreakWhiteSpace (\x{A0}) to ASCII Space - strProcessed = strProcessed.replacingOccurrences(of: "\t", with: " ") // Tab to ASCII Space - strProcessed.regReplace(pattern: "\\f", replaceWith: "\n") // Form Feed to LF - strProcessed = strProcessed.replacingOccurrences(of: "\r", with: "\n") // CR to LF - strProcessed.regReplace(pattern: " +", replaceWith: " ") // 統整連續空格為一個 ASCII 空格 - strProcessed.regReplace(pattern: "\\n+", replaceWith: "\n") // 統整連續 LF 為一個 LF - strProcessed = strProcessed.replacingOccurrences(of: " \n", with: "\n") // 去除行尾空格 - strProcessed = strProcessed.replacingOccurrences(of: "\n ", with: "\n") // 去除行首空格 + // CJKWhiteSpace (\x{3000}) to ASCII Space + // NonBreakWhiteSpace (\x{A0}) to ASCII Space + // Tab to ASCII Space + // 統整連續空格為一個 ASCII 空格 + strProcessed.regReplace(pattern: #"( +| +| +|\t+)+"#, replaceWith: " ") + strProcessed.regReplace(pattern: #"(\f+|\r+)+"#, replaceWith: "\n") // CR & Form Feed to LF + strProcessed.regReplace(pattern: #"(\n+| \n+|\n+ )"#, replaceWith: "\n") // 去除行尾行首空格與重複行 if strProcessed.prefix(1) == " " { // 去除檔案開頭空格 strProcessed.removeFirst() } diff --git a/vChewing.pkgproj b/vChewing.pkgproj new file mode 100644 index 00000000..8d355fef --- /dev/null +++ b/vChewing.pkgproj @@ -0,0 +1,1188 @@ + + + + + PACKAGES + + + MUST-CLOSE-APPLICATION-ITEMS + + MUST-CLOSE-APPLICATIONS + + PACKAGE_FILES + + DEFAULT_INSTALL_LOCATION + / + HIERARCHY + + CHILDREN + + + CHILDREN + + GID + 80 + PATH + Applications + PATH_TYPE + 0 + PERMISSIONS + 509 + TYPE + 1 + UID + 0 + + + CHILDREN + + + CHILDREN + + GID + 80 + PATH + Application Support + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Automator + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Documentation + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Extensions + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Filesystems + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Frameworks + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + + BUNDLE_CAN_DOWNGRADE + + BUNDLE_POSTINSTALL_PATH + + PATH_TYPE + 1 + + BUNDLE_PREINSTALL_PATH + + PATH_TYPE + 1 + + CHILDREN + + GID + 0 + PATH + Build/Products/Release/vChewing.app + PATH_TYPE + 1 + PERMISSIONS + 493 + TYPE + 3 + UID + 0 + + + GID + 0 + PATH + Input Methods + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Internet Plug-Ins + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + + CHILDREN + + GID + 0 + PATH + KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewing Dachen.keylayout + PATH_TYPE + 1 + PERMISSIONS + 420 + TYPE + 3 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewing ETen.keylayout + PATH_TYPE + 1 + PERMISSIONS + 420 + TYPE + 3 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewing FakeSeigyou.keylayout + PATH_TYPE + 1 + PERMISSIONS + 420 + TYPE + 3 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewing IBM.keylayout + PATH_TYPE + 1 + PERMISSIONS + 420 + TYPE + 3 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + KeyboardExtension/vChewingKeyLayout.bundle/Contents/Resources/vChewing MiTAC.keylayout + PATH_TYPE + 1 + PERMISSIONS + 420 + TYPE + 3 + UID + 0 + + + BUNDLE_CAN_DOWNGRADE + + BUNDLE_POSTINSTALL_PATH + + PATH_TYPE + 1 + + BUNDLE_PREINSTALL_PATH + + PATH_TYPE + 1 + + CHILDREN + + GID + 0 + PATH + KeyboardExtension/vChewingKeyLayout.bundle + PATH_TYPE + 1 + PERMISSIONS + 493 + TYPE + 3 + UID + 0 + + + GID + 0 + PATH + Keyboard Layouts + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + LaunchAgents + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + LaunchDaemons + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + PreferencePanes + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Preferences + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 80 + PATH + Printers + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + PrivilegedHelperTools + PATH_TYPE + 0 + PERMISSIONS + 1005 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + QuickLook + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + QuickTime + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Screen Savers + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Scripts + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Services + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + GID + 0 + PATH + Widgets + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + GID + 0 + PATH + Library + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + CHILDREN + + + CHILDREN + + GID + 0 + PATH + Shared + PATH_TYPE + 0 + PERMISSIONS + 1023 + TYPE + 1 + UID + 0 + + + GID + 80 + PATH + Users + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + + GID + 0 + PATH + / + PATH_TYPE + 0 + PERMISSIONS + 493 + TYPE + 1 + UID + 0 + + PAYLOAD_TYPE + 0 + PRESERVE_EXTENDED_ATTRIBUTES + + SHOW_INVISIBLE + + SPLIT_FORKS + + TREAT_MISSING_FILES_AS_WARNING + + VERSION + 5 + + PACKAGE_SCRIPTS + + POSTINSTALL_PATH + + PATH_TYPE + 1 + + PREINSTALL_PATH + + PATH + Installer/pkgPostInstall.sh + PATH_TYPE + 1 + + RESOURCES + + + PACKAGE_SETTINGS + + AUTHENTICATION + 0 + CONCLUSION_ACTION + 0 + FOLLOW_SYMBOLIC_LINKS + + IDENTIFIER + org.atelierInmu.vChewing + LOCATION + 0 + NAME + vChewing + OVERWRITE_PERMISSIONS + + PAYLOAD_SIZE + -1 + REFERENCE_PATH + + RELOCATABLE + + USE_HFS+_COMPRESSION + + VERSION + 1.3.7 + + TYPE + 0 + UUID + 2D0C3907-5C56-430B-A525-65B19DB6B70A + + + PROJECT + + PROJECT_COMMENTS + + NOTES + + + + PROJECT_PRESENTATION + + BACKGROUND + + ALIGNMENT + 6 + APPAREANCES + + DARK_AQUA + + ALIGNMENT + 6 + BACKGROUND_PATH + + PATH + Source/Resources/Images/Images.xcassets/AppIcon.appiconset/128X128.png + PATH_TYPE + 1 + + CUSTOM + + LAYOUT_DIRECTION + 0 + SCALING + 2 + + LIGHT_AQUA + + ALIGNMENT + 6 + BACKGROUND_PATH + + PATH + Source/Resources/Images/Images.xcassets/AppIcon.appiconset/128X128.png + PATH_TYPE + 1 + + CUSTOM + + LAYOUT_DIRECTION + 0 + SCALING + 2 + + + BACKGROUND_PATH + + PATH + Source/Resources/Images/Images.xcassets/AppIcon.appiconset/128X128.png + PATH_TYPE + 1 + + CUSTOM + + LAYOUT_DIRECTION + 0 + SCALING + 2 + SHARED_SETTINGS_FOR_ALL_APPAREANCES + + + INSTALLATION TYPE + + HIERARCHIES + + INSTALLER + + LIST + + + CHILDREN + + DESCRIPTION + + OPTIONS + + HIDDEN + + STATE + 0 + + PACKAGE_UUID + 2D0C3907-5C56-430B-A525-65B19DB6B70A + TITLE + + + LANGUAGE + English + VALUE + vChewing Input Method + + + LANGUAGE + Simplified Chinese + VALUE + 威注音输入法 + + + LANGUAGE + Japanese + VALUE + 威注音入力アプリ + + + LANGUAGE + Traditional Chinese + VALUE + 威注音輸入法 + + + TYPE + 0 + UUID + 1DE7EA6D-01C2-4702-B0EC-A7ACACF623AE + + + REMOVED + + + + MODE + 1 + + INSTALLATION_STEPS + + + ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS + ICPresentationViewIntroductionController + INSTALLER_PLUGIN + Introduction + LIST_TITLE_KEY + InstallerSectionTitle + + + ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS + ICPresentationViewReadMeController + INSTALLER_PLUGIN + ReadMe + LIST_TITLE_KEY + InstallerSectionTitle + + + ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS + ICPresentationViewLicenseController + INSTALLER_PLUGIN + License + LIST_TITLE_KEY + InstallerSectionTitle + + + ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS + ICPresentationViewDestinationSelectController + INSTALLER_PLUGIN + TargetSelect + LIST_TITLE_KEY + InstallerSectionTitle + + + ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS + ICPresentationViewInstallationTypeController + INSTALLER_PLUGIN + PackageSelection + LIST_TITLE_KEY + InstallerSectionTitle + + + ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS + ICPresentationViewInstallationController + INSTALLER_PLUGIN + Install + LIST_TITLE_KEY + InstallerSectionTitle + + + ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS + ICPresentationViewSummaryController + INSTALLER_PLUGIN + Summary + LIST_TITLE_KEY + InstallerSectionTitle + + + INTRODUCTION + + LOCALIZATIONS + + + LICENSE + + LOCALIZATIONS + + + LANGUAGE + English + VALUE + + PATH + LICENSE.txt + PATH_TYPE + 1 + + + + LANGUAGE + Simplified Chinese + VALUE + + PATH + LICENSE-CHS.txt + PATH_TYPE + 1 + + + + LANGUAGE + Japanese + VALUE + + PATH + LICENSE-JPN.txt + PATH_TYPE + 1 + + + + LANGUAGE + Traditional Chinese + VALUE + + PATH + LICENSE-CHT.txt + PATH_TYPE + 1 + + + + MODE + 0 + + README + + LOCALIZATIONS + + + SUMMARY + + LOCALIZATIONS + + + TITLE + + LOCALIZATIONS + + + LANGUAGE + English + VALUE + vChewing Input Method + + + LANGUAGE + Traditional Chinese + VALUE + 威注音輸入法 + + + LANGUAGE + Japanese + VALUE + 威注音入力アプリ + + + LANGUAGE + Simplified Chinese + VALUE + 威注音输入法 + + + + + PROJECT_REQUIREMENTS + + LIST + + + BEHAVIOR + 3 + DICTIONARY + + IC_REQUIREMENT_OS_DISK_TYPE + 1 + IC_REQUIREMENT_OS_DISTRIBUTION_TYPE + 0 + IC_REQUIREMENT_OS_MINIMUM_VERSION + 101105 + + IC_REQUIREMENT_CHECK_TYPE + 0 + IDENTIFIER + fr.whitebox.Packages.requirement.os + MESSAGE + + + LANGUAGE + English + SECONDARY_VALUE + Requiring at least macOS 10.11.5 for Unicode Support. + VALUE + Minimum OS Version Not Met. + + + LANGUAGE + Traditional Chinese + SECONDARY_VALUE + 至少 macOS 10.11.5 方可滿足威注音對系統內的萬國碼版本支援的需要。 + VALUE + 作業系統版本太舊 + + + LANGUAGE + Japanese + SECONDARY_VALUE + Unicode バージョン依頼のため、macOS 10.11.5 以降が必要。 + VALUE + OSのバージョンは古すぎ + + + LANGUAGE + Simplified Chinese + SECONDARY_VALUE + 至少 macOS 10.11.5 方可满足威注音对系统内的万国码版本支援的需要。 + VALUE + 作业系统版本太旧 + + + NAME + Operating System + STATE + + + + RESOURCES + + ROOT_VOLUME_ONLY + + + PROJECT_SETTINGS + + ADVANCED_OPTIONS + + installer-script.domains:enable_currentUserHome + 1 + + BUILD_FORMAT + 0 + BUILD_PATH + + PATH + Build + PATH_TYPE + 1 + + EXCLUDED_FILES + + + PATTERNS_ARRAY + + + REGULAR_EXPRESSION + + STRING + .DS_Store + TYPE + 0 + + + PROTECTED + + PROXY_NAME + Remove .DS_Store files + PROXY_TOOLTIP + Remove ".DS_Store" files created by the Finder. + STATE + + + + PATTERNS_ARRAY + + + REGULAR_EXPRESSION + + STRING + .pbdevelopment + TYPE + 0 + + + PROTECTED + + PROXY_NAME + Remove .pbdevelopment files + PROXY_TOOLTIP + Remove ".pbdevelopment" files created by ProjectBuilder or Xcode. + STATE + + + + PATTERNS_ARRAY + + + REGULAR_EXPRESSION + + STRING + CVS + TYPE + 1 + + + REGULAR_EXPRESSION + + STRING + .cvsignore + TYPE + 0 + + + REGULAR_EXPRESSION + + STRING + .cvspass + TYPE + 0 + + + REGULAR_EXPRESSION + + STRING + .svn + TYPE + 1 + + + REGULAR_EXPRESSION + + STRING + .git + TYPE + 1 + + + REGULAR_EXPRESSION + + STRING + .gitignore + TYPE + 0 + + + PROTECTED + + PROXY_NAME + Remove SCM metadata + PROXY_TOOLTIP + Remove helper files and folders used by the CVS, SVN or Git Source Code Management systems. + STATE + + + + PATTERNS_ARRAY + + + REGULAR_EXPRESSION + + STRING + classes.nib + TYPE + 0 + + + REGULAR_EXPRESSION + + STRING + designable.db + TYPE + 0 + + + REGULAR_EXPRESSION + + STRING + info.nib + TYPE + 0 + + + PROTECTED + + PROXY_NAME + Optimize nib files + PROXY_TOOLTIP + Remove "classes.nib", "info.nib" and "designable.nib" files within .nib bundles. + STATE + + + + PATTERNS_ARRAY + + + REGULAR_EXPRESSION + + STRING + Resources Disabled + TYPE + 1 + + + PROTECTED + + PROXY_NAME + Remove Resources Disabled folders + PROXY_TOOLTIP + Remove "Resources Disabled" folders. + STATE + + + + SEPARATOR + + + + NAME + vChewing + PAYLOAD_ONLY + + TREAT_MISSING_PRESENTATION_DOCUMENTS_AS_WARNING + + + + TYPE + 0 + VERSION + 2 + + diff --git a/vChewing.xcodeproj/project.pbxproj b/vChewing.xcodeproj/project.pbxproj index f4bbfa91..7658f9d0 100644 --- a/vChewing.xcodeproj/project.pbxproj +++ b/vChewing.xcodeproj/project.pbxproj @@ -33,6 +33,7 @@ 5B62A35327AE89C400A19448 /* InputSourceHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A33127AE792F00A19448 /* InputSourceHelper.swift */; }; 5B73FB5E27B2BE1300E9BF49 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5B73FB6027B2BE1300E9BF49 /* InfoPlist.strings */; }; 5B7BC4B027AFFBE800F66C24 /* frmPrefWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5B7BC4AE27AFFBE800F66C24 /* frmPrefWindow.xib */; }; + 5BAD0CD527D701F6003D127F /* vChewingKeyLayout.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 5B30F11227BA568800484E24 /* vChewingKeyLayout.bundle */; }; 5BBBB75F27AED54C0023B93A /* Beep.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 5BBBB75D27AED54C0023B93A /* Beep.m4a */; }; 5BBBB76027AED54C0023B93A /* Fart.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 5BBBB75E27AED54C0023B93A /* Fart.m4a */; }; 5BBBB76B27AED5DB0023B93A /* frmNonModalAlertWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5BBBB76527AED5DB0023B93A /* frmNonModalAlertWindow.xib */; }; @@ -50,12 +51,6 @@ 5BD05C6827B2BBEF004C4F1D /* Content.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD05C6327B2BBEF004C4F1D /* Content.swift */; }; 5BD05C6927B2BBEF004C4F1D /* WindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD05C6427B2BBEF004C4F1D /* WindowController.swift */; }; 5BD05C6A27B2BBEF004C4F1D /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD05C6527B2BBEF004C4F1D /* ViewController.swift */; }; - 5BDC5CAB27C2873D00E1CCE2 /* Grid.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5BDC5CAA27C2873D00E1CCE2 /* Grid.mm */; }; - 5BDC5CB327C28E8B00E1CCE2 /* icon.icns in Resources */ = {isa = PBXBuildFile; fileRef = 5BDC5CB227C28E8B00E1CCE2 /* icon.icns */; }; - 5BDC5CB527C28E8B00E1CCE2 /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BDC5CB427C28E8B00E1CCE2 /* ShareViewController.swift */; }; - 5BDC5CB827C28E8B00E1CCE2 /* ShareViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5BDC5CB627C28E8B00E1CCE2 /* ShareViewController.xib */; }; - 5BDC5CBD27C28E8B00E1CCE2 /* KeyboardExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 5BDC5CB027C28E8B00E1CCE2 /* KeyboardExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 5BDC5CC227C2941F00E1CCE2 /* vChewingKeyLayout.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 5B30F11227BA568800484E24 /* vChewingKeyLayout.bundle */; }; 5BDCBB2E27B4E67A00D0CC59 /* vChewingPhraseEditor.app in Resources */ = {isa = PBXBuildFile; fileRef = 5BD05BB827B2A429004C4F1D /* vChewingPhraseEditor.app */; }; 5BE78BD927B3775B005EA1BE /* ctlAboutWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BE78BD827B37750005EA1BE /* ctlAboutWindow.swift */; }; 5BE78BDD27B3776D005EA1BE /* frmAboutWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5BE78BDA27B37764005EA1BE /* frmAboutWindow.xib */; }; @@ -102,13 +97,6 @@ remoteGlobalIDString = 5BD05BB727B2A429004C4F1D; remoteInfo = vChewingPhraseEditor; }; - 5BDC5CBB27C28E8B00E1CCE2 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 6A0D4E9415FC0CFA00ABF4B3 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 5BDC5CAF27C28E8B00E1CCE2; - remoteInfo = KeyboardExtension; - }; 6A38BC2515FC131100A8A51F /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 6A0D4E9415FC0CFA00ABF4B3 /* Project object */; @@ -132,7 +120,6 @@ dstPath = ""; dstSubfolderSpec = 13; files = ( - 5BDC5CBD27C28E8B00E1CCE2 /* KeyboardExtension.appex in Embed App Extensions */, ); name = "Embed App Extensions"; runOnlyForDeploymentPostprocessing = 0; @@ -231,13 +218,6 @@ 5BD05C6327B2BBEF004C4F1D /* Content.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Content.swift; sourceTree = ""; }; 5BD05C6427B2BBEF004C4F1D /* WindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WindowController.swift; sourceTree = ""; }; 5BD05C6527B2BBEF004C4F1D /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; - 5BDC5CAA27C2873D00E1CCE2 /* Grid.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = Grid.mm; sourceTree = ""; }; - 5BDC5CB027C28E8B00E1CCE2 /* KeyboardExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = KeyboardExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; - 5BDC5CB227C28E8B00E1CCE2 /* icon.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = icon.icns; sourceTree = ""; }; - 5BDC5CB427C28E8B00E1CCE2 /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = ""; }; - 5BDC5CB727C28E8B00E1CCE2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ShareViewController.xib; sourceTree = ""; }; - 5BDC5CB927C28E8B00E1CCE2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 5BDC5CBA27C28E8B00E1CCE2 /* KeyboardExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = KeyboardExtension.entitlements; sourceTree = ""; }; 5BDCBB4227B4F6C600D0CC59 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/MainMenu.strings"; sourceTree = ""; }; 5BDCBB4327B4F6C600D0CC59 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/frmAboutWindow.strings"; sourceTree = ""; }; 5BDCBB4527B4F6C600D0CC59 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "Source/WindowNIBs/zh-Hant.lproj/frmPrefWindow.strings"; sourceTree = ""; }; @@ -323,13 +303,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 5BDC5CAD27C28E8B00E1CCE2 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; 6A0D4E9F15FC0D2D00ABF4B3 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -671,11 +644,6 @@ isa = PBXGroup; children = ( 5B30F11227BA568800484E24 /* vChewingKeyLayout.bundle */, - 5BDC5CB227C28E8B00E1CCE2 /* icon.icns */, - 5BDC5CB427C28E8B00E1CCE2 /* ShareViewController.swift */, - 5BDC5CB627C28E8B00E1CCE2 /* ShareViewController.xib */, - 5BDC5CB927C28E8B00E1CCE2 /* Info.plist */, - 5BDC5CBA27C28E8B00E1CCE2 /* KeyboardExtension.entitlements */, ); path = KeyboardExtension; sourceTree = ""; @@ -702,7 +670,6 @@ 6A0D4EA215FC0D2D00ABF4B3 /* vChewing.app */, 6ACA41CB15FC1D7500935EF6 /* vChewingInstaller.app */, 5BD05BB827B2A429004C4F1D /* vChewingPhraseEditor.app */, - 5BDC5CB027C28E8B00E1CCE2 /* KeyboardExtension.appex */, ); name = Products; sourceTree = ""; @@ -752,7 +719,6 @@ 6A0D4F1515FC0EB100ABF4B3 /* BlockReadingBuilder.h */, 6A0D4F1615FC0EB100ABF4B3 /* Gramambular.h */, 6A0D4F1715FC0EB100ABF4B3 /* Grid.h */, - 5BDC5CAA27C2873D00E1CCE2 /* Grid.mm */, 6A0D4F1815FC0EB100ABF4B3 /* KeyValuePair.h */, 6A0D4F1915FC0EB100ABF4B3 /* LanguageModel.h */, 6A0D4F1A15FC0EB100ABF4B3 /* Node.h */, @@ -792,11 +758,11 @@ /* Begin PBXLegacyTarget section */ 6A38BC2115FC12FD00A8A51F /* Data */ = { isa = PBXLegacyTarget; - buildArgumentsString = "$(ACTION) macv"; + buildArgumentsString = "$(ACTION) ../../DataCompiler/dataCompiler.swift"; buildConfigurationList = 6A38BC2215FC12FD00A8A51F /* Build configuration list for PBXLegacyTarget "Data" */; buildPhases = ( ); - buildToolPath = /usr/bin/make; + buildToolPath = /usr/bin/swift; buildWorkingDirectory = "$(SRCROOT)/Source/Data"; dependencies = ( ); @@ -824,23 +790,6 @@ productReference = 5BD05BB827B2A429004C4F1D /* vChewingPhraseEditor.app */; productType = "com.apple.product-type.application"; }; - 5BDC5CAF27C28E8B00E1CCE2 /* KeyboardExtension */ = { - isa = PBXNativeTarget; - buildConfigurationList = 5BDC5CC127C28E8B00E1CCE2 /* Build configuration list for PBXNativeTarget "KeyboardExtension" */; - buildPhases = ( - 5BDC5CAC27C28E8B00E1CCE2 /* Sources */, - 5BDC5CAD27C28E8B00E1CCE2 /* Frameworks */, - 5BDC5CAE27C28E8B00E1CCE2 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = KeyboardExtension; - productName = KeyboardExtension; - productReference = 5BDC5CB027C28E8B00E1CCE2 /* KeyboardExtension.appex */; - productType = "com.apple.product-type.app-extension"; - }; 6A0D4EA115FC0D2D00ABF4B3 /* vChewing */ = { isa = PBXNativeTarget; buildConfigurationList = 6A0D4EC015FC0D2E00ABF4B3 /* Build configuration list for PBXNativeTarget "vChewing" */; @@ -855,7 +804,6 @@ dependencies = ( 5B0AF8B327B2C4E20096FE54 /* PBXTargetDependency */, 6A38BC2615FC131100A8A51F /* PBXTargetDependency */, - 5BDC5CBC27C28E8B00E1CCE2 /* PBXTargetDependency */, ); name = vChewing; packageProductDependencies = ( @@ -899,10 +847,6 @@ LastSwiftMigration = 1320; ProvisioningStyle = Automatic; }; - 5BDC5CAF27C28E8B00E1CCE2 = { - CreatedOnToolsVersion = 13.2; - ProvisioningStyle = Automatic; - }; 6A0D4EA115FC0D2D00ABF4B3 = { LastSwiftMigration = 1240; ProvisioningStyle = Automatic; @@ -934,7 +878,6 @@ 6A0D4EA115FC0D2D00ABF4B3 /* vChewing */, 6ACA41CA15FC1D7500935EF6 /* vChewingInstaller */, 5BD05BB727B2A429004C4F1D /* vChewingPhraseEditor */, - 5BDC5CAF27C28E8B00E1CCE2 /* KeyboardExtension */, 6A38BC2115FC12FD00A8A51F /* Data */, ); }; @@ -952,16 +895,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 5BDC5CAE27C28E8B00E1CCE2 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5BDC5CB827C28E8B00E1CCE2 /* ShareViewController.xib in Resources */, - 5BDC5CC227C2941F00E1CCE2 /* vChewingKeyLayout.bundle in Resources */, - 5BDC5CB327C28E8B00E1CCE2 /* icon.icns in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 6A0D4EA015FC0D2D00ABF4B3 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -984,6 +917,7 @@ 5BBBB77627AED70B0023B93A /* MenuIcon-TCVIM.png in Resources */, 6A187E2616004C5900466B2E /* MainMenu.xib in Resources */, 5BBBB75F27AED54C0023B93A /* Beep.m4a in Resources */, + 5BAD0CD527D701F6003D127F /* vChewingKeyLayout.bundle in Resources */, 5B2DB16F27AF6891006D874E /* data-chs.txt in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1038,14 +972,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 5BDC5CAC27C28E8B00E1CCE2 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5BDC5CB527C28E8B00E1CCE2 /* ShareViewController.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 6A0D4E9E15FC0D2D00ABF4B3 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -1075,7 +1001,6 @@ D47F7DD3278C1263002F9DD7 /* UserOverrideModel.cpp in Sources */, 5B62A33627AE795800A19448 /* PreferencesModule.swift in Sources */, 5B62A33827AE79CD00A19448 /* NSStringUtils.swift in Sources */, - 5BDC5CAB27C2873D00E1CCE2 /* Grid.mm in Sources */, 5B62A33227AE792F00A19448 /* InputSourceHelper.swift in Sources */, 5B62A34927AE7CD900A19448 /* TooltipController.swift in Sources */, 6A0D4F4515FC0EB100ABF4B3 /* Mandarin.cpp in Sources */, @@ -1112,11 +1037,6 @@ target = 5BD05BB727B2A429004C4F1D /* vChewingPhraseEditor */; targetProxy = 5B0AF8B227B2C4E20096FE54 /* PBXContainerItemProxy */; }; - 5BDC5CBC27C28E8B00E1CCE2 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 5BDC5CAF27C28E8B00E1CCE2 /* KeyboardExtension */; - targetProxy = 5BDC5CBB27C28E8B00E1CCE2 /* PBXContainerItemProxy */; - }; 6A38BC2615FC131100A8A51F /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 6A38BC2115FC12FD00A8A51F /* Data */; @@ -1184,14 +1104,6 @@ name = Main.storyboard; sourceTree = ""; }; - 5BDC5CB627C28E8B00E1CCE2 /* ShareViewController.xib */ = { - isa = PBXVariantGroup; - children = ( - 5BDC5CB727C28E8B00E1CCE2 /* Base */, - ); - name = ShareViewController.xib; - sourceTree = ""; - }; 5BE78BDA27B37764005EA1BE /* frmAboutWindow.xib */ = { isa = PBXVariantGroup; children = ( @@ -1293,7 +1205,7 @@ CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1925; + CURRENT_PROJECT_VERSION = 1926; DEBUG_INFORMATION_FORMAT = dwarf; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; @@ -1306,13 +1218,14 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = "UserPhraseEditor/PhraseEditor-Info.plist"; + INFOPLIST_KEY_CFBundleDisplayName = "$(PRODUCT_NAME)"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; INFOPLIST_KEY_NSHumanReadableCopyright = "© 2021-2022 vChewing Project."; INFOPLIST_KEY_NSMainStoryboardFile = Main; INFOPLIST_KEY_NSPrincipalClass = NSApplication; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.11.5; - MARKETING_VERSION = 1.3.6; + MARKETING_VERSION = 1.3.7; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewing.vChewingPhraseEditor; @@ -1345,7 +1258,7 @@ CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1925; + CURRENT_PROJECT_VERSION = 1926; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -1353,13 +1266,14 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = "UserPhraseEditor/PhraseEditor-Info.plist"; + INFOPLIST_KEY_CFBundleDisplayName = "$(PRODUCT_NAME)"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; INFOPLIST_KEY_NSHumanReadableCopyright = "© 2021-2022 vChewing Project."; INFOPLIST_KEY_NSMainStoryboardFile = Main; INFOPLIST_KEY_NSPrincipalClass = NSApplication; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.11.5; - MARKETING_VERSION = 1.3.6; + MARKETING_VERSION = 1.3.7; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewing.vChewingPhraseEditor; @@ -1371,102 +1285,6 @@ }; name = Release; }; - 5BDC5CBF27C28E8B00E1CCE2 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_ENTITLEMENTS = KeyboardExtension/KeyboardExtension.entitlements; - CODE_SIGN_IDENTITY = "-"; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1925; - DEBUG_INFORMATION_FORMAT = dwarf; - DEVELOPMENT_ASSET_PATHS = KeyboardExtension/vChewingKeyLayout.bundle; - DEVELOPMENT_TEAM = ""; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_FILE = KeyboardExtension/Info.plist; - INFOPLIST_KEY_CFBundleDisplayName = KeyboardExtension; - INFOPLIST_KEY_NSHumanReadableCopyright = ""; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @executable_path/../../../../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 12.1; - MARKETING_VERSION = 1.3.6; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.inputmethod.vChewing.KeyboardExtension; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - }; - name = Debug; - }; - 5BDC5CC027C28E8B00E1CCE2 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_ENTITLEMENTS = KeyboardExtension/KeyboardExtension.entitlements; - CODE_SIGN_IDENTITY = "-"; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1925; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_ASSET_PATHS = KeyboardExtension/vChewingKeyLayout.bundle; - DEVELOPMENT_TEAM = ""; - ENABLE_NS_ASSERTIONS = NO; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_FILE = KeyboardExtension/Info.plist; - INFOPLIST_KEY_CFBundleDisplayName = KeyboardExtension; - INFOPLIST_KEY_NSHumanReadableCopyright = ""; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @executable_path/../../../../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 12.1; - MARKETING_VERSION = 1.3.6; - MTL_ENABLE_DEBUG_INFO = NO; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.inputmethod.vChewing.KeyboardExtension; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; - SKIP_INSTALL = YES; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - SWIFT_VERSION = 5.0; - }; - name = Release; - }; 6A0D4E9915FC0CFA00ABF4B3 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1570,7 +1388,7 @@ CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1925; + CURRENT_PROJECT_VERSION = 1926; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = ""; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -1602,7 +1420,7 @@ INFOPLIST_FILE = "Source/Resources/IME-Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.11.5; - MARKETING_VERSION = 1.3.6; + MARKETING_VERSION = 1.3.7; ONLY_ACTIVE_ARCH = YES; PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.inputmethod.vChewing; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -1635,7 +1453,7 @@ CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1925; + CURRENT_PROJECT_VERSION = 1926; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = ""; @@ -1661,7 +1479,7 @@ INFOPLIST_FILE = "Source/Resources/IME-Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.11.5; - MARKETING_VERSION = 1.3.6; + MARKETING_VERSION = 1.3.7; PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.inputmethod.vChewing; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1744,7 +1562,7 @@ CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1925; + CURRENT_PROJECT_VERSION = 1927; DEVELOPMENT_TEAM = ""; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; @@ -1766,7 +1584,7 @@ INFOPLIST_FILE = "Installer/Installer-Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.11.5; - MARKETING_VERSION = 1.3.6; + MARKETING_VERSION = 1.3.7; ONLY_ACTIVE_ARCH = YES; PRODUCT_BUNDLE_IDENTIFIER = "org.atelierInmu.vChewing.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -1794,7 +1612,7 @@ CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1925; + CURRENT_PROJECT_VERSION = 1927; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ""; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -1810,7 +1628,7 @@ INFOPLIST_FILE = "Installer/Installer-Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.11.5; - MARKETING_VERSION = 1.3.6; + MARKETING_VERSION = 1.3.7; PRODUCT_BUNDLE_IDENTIFIER = "org.atelierInmu.vChewing.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1833,15 +1651,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 5BDC5CC127C28E8B00E1CCE2 /* Build configuration list for PBXNativeTarget "KeyboardExtension" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 5BDC5CBF27C28E8B00E1CCE2 /* Debug */, - 5BDC5CC027C28E8B00E1CCE2 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 6A0D4E9715FC0CFA00ABF4B3 /* Build configuration list for PBXProject "vChewing" */ = { isa = XCConfigurationList; buildConfigurations = (