diff --git a/Source/Data b/Source/Data index 1daf4d57..3cb476e7 160000 --- a/Source/Data +++ b/Source/Data @@ -1 +1 @@ -Subproject commit 1daf4d576a248373889889213bea4bd3cbb4b5d4 +Subproject commit 3cb476e7c884198fe91ce7d7ccc1ac0e082e007e diff --git a/Source/Modules/ControllerModules/InputSignal.swift b/Source/Modules/ControllerModules/InputSignal.swift index 180d7cb8..a1cc8b96 100644 --- a/Source/Modules/ControllerModules/InputSignal.swift +++ b/Source/Modules/ControllerModules/InputSignal.swift @@ -214,6 +214,11 @@ struct InputSignal: CustomStringConvertible { 18: "1", 19: "2", 20: "3", 21: "4", 23: "5", 22: "6", 26: "7", 28: "8", 25: "9", 29: "0", ] + var isCandidateKey: Bool { + mgrPrefs.candidateKeys.contains(inputText) + || mgrPrefs.candidateKeys.contains(inputTextIgnoringModifiers ?? "114514") + } + /// 單獨用 flags 來判定數字小鍵盤輸入的方法已經失效了,所以必須再增補用 KeyCode 判定的方法。 var isNumericPadKey: Bool { arrNumpadKeyCodes.contains(keyCode) } var isMainAreaNumKey: Bool { arrMainAreaNumKey.contains(keyCode) } diff --git a/Source/Modules/ControllerModules/InputState.swift b/Source/Modules/ControllerModules/InputState.swift index d75ec67a..77d25bef 100644 --- a/Source/Modules/ControllerModules/InputState.swift +++ b/Source/Modules/ControllerModules/InputState.swift @@ -280,9 +280,9 @@ public enum InputState { private var markedTargetExists = false var tooltip: String { if composingBuffer.count != readings.count { - ctlInputMethod.tooltipController.setColor(state: .denialOverflow) + ctlInputMethod.tooltipController.setColor(state: .redAlert) return NSLocalizedString( - "⚠︎ Beware: Chars and Readings in buffer doesn't match.", comment: "" + "⚠︎ Unhandlable: Chars and Readings in buffer doesn't match.", comment: "" ) } if mgrPrefs.phraseReplacementEnabled { @@ -398,11 +398,9 @@ public enum InputState { return state } - var validToFilter: Bool { - /// 與小麥注音不同,威注音會自動解消「游標插斷字符」的異常狀態,所以允許在字音長度不相符的情況下加詞。 - /// 這裡的 deleteTargetExists 是防止使用者排除「詞庫內尚未存在的詞」。 - markedTargetExists ? allowedMarkRange.contains(literalMarkedRange.count) : false - } + var validToFilter: Bool { markedTargetExists ? allowedMarkRange.contains(literalMarkedRange.count) : false } + + var bufferReadingCountMisMatch: Bool { composingBuffer.count != readings.count } var chkIfUserPhraseExists: Bool { let text = composingBuffer.utf16SubString(with: markedRange) diff --git a/Source/Modules/ControllerModules/KeyHandler_Core.swift b/Source/Modules/ControllerModules/KeyHandler_Core.swift index 85f98a89..7c8f8fe7 100644 --- a/Source/Modules/ControllerModules/KeyHandler_Core.swift +++ b/Source/Modules/ControllerModules/KeyHandler_Core.swift @@ -229,8 +229,6 @@ public class KeyHandler { ) } walk() - } else { - IME.prtDebugIntel("UOM: Blank suggestion retrieved, dismissing.") } } arrResult = arrResult.stableSort { $0.1.score > $1.1.score } diff --git a/Source/Modules/ControllerModules/ctlInputMethod_Core.swift b/Source/Modules/ControllerModules/ctlInputMethod_Core.swift index 02c59768..84c0584b 100644 --- a/Source/Modules/ControllerModules/ctlInputMethod_Core.swift +++ b/Source/Modules/ControllerModules/ctlInputMethod_Core.swift @@ -25,7 +25,8 @@ class ctlInputMethod: IMKInputController { static var areWeNerfing = false /// 目前在用的的選字窗副本。 - static var ctlCandidateCurrent: ctlCandidateProtocol = ctlCandidateUniversal.init(.horizontal) + static var ctlCandidateCurrent: ctlCandidateProtocol = + mgrPrefs.useIMKCandidateWindow ? ctlCandidateIMK.init(.horizontal) : ctlCandidateUniversal.init(.horizontal) /// 工具提示視窗的副本。 static let tooltipController = TooltipController() @@ -47,7 +48,7 @@ class ctlInputMethod: IMKInputController { } /// `handle(event:)` 會利用這個參數判定某次 Shift 按鍵是否用來切換中英文輸入。 - private var rencentKeyHandledByKeyHandler = false + var rencentKeyHandledByKeyHandler = false // MARK: - 工具函式 @@ -205,6 +206,12 @@ class ctlInputMethod: IMKInputController { } } + /// IMK 選字窗處理,當且僅當啟用了 IMK 選字窗的時候才會生效。 + if let ctlCandidateCurrent = ctlInputMethod.ctlCandidateCurrent as? ctlCandidateIMK, ctlCandidateCurrent.visible { + ctlCandidateCurrent.interpretKeyEvents([event]) + return true + } + /// 這裡仍舊需要判斷 flags。之前使輸入法狀態卡住無法敲漢字的問題已在 KeyHandler 內修復。 /// 這裡不判斷 flags 的話,用方向鍵前後定位光標之後,再次試圖觸發組字區時、反而會在首次按鍵時失敗。 /// 同時注意:必須在 event.type == .flagsChanged 結尾插入 return false, @@ -270,14 +277,12 @@ class ctlInputMethod: IMKInputController { let theConverted = IME.kanjiConversionIfRequired(theCandidate.1) return (theCandidate.1 == theConverted) ? theCandidate.1 : "\(theConverted)(\(theCandidate.1))" } - } - if let state = state as? InputState.ChoosingCandidate { + } else if let state = state as? InputState.SymbolTable { return state.candidates.map { theCandidate -> String in let theConverted = IME.kanjiConversionIfRequired(theCandidate.1) return (theCandidate.1 == theConverted) ? theCandidate.1 : "\(theConverted)(\(theCandidate.1))" } - } - if let state = state as? InputState.SymbolTable { + } else if let state = state as? InputState.ChoosingCandidate { return state.candidates.map { theCandidate -> String in let theConverted = IME.kanjiConversionIfRequired(theCandidate.1) return (theCandidate.1 == theConverted) ? theCandidate.1 : "\(theConverted)(\(theCandidate.1))" @@ -285,4 +290,53 @@ class ctlInputMethod: IMKInputController { } return .init() } + + override open func candidateSelectionChanged(_: NSAttributedString!) { + // 暫時不需要擴充這個函數。 + } + + override open func candidateSelected(_ candidateString: NSAttributedString!) { + if state is InputState.AssociatedPhrases { + if !mgrPrefs.alsoConfirmAssociatedCandidatesByEnter { + handle(state: InputState.EmptyIgnoringPreviousState()) + handle(state: InputState.Empty()) + return + } + } + + var indexDeducted = 0 + if let state = state as? InputState.AssociatedPhrases { + for (i, neta) in state.candidates.map(\.1).enumerated() { + let theConverted = IME.kanjiConversionIfRequired(neta) + let netaShown = (neta == theConverted) ? neta : "\(theConverted)(\(neta))" + if candidateString.string == netaShown { + indexDeducted = i + break + } + } + } else if let state = state as? InputState.SymbolTable { + for (i, neta) in state.candidates.map(\.1).enumerated() { + let theConverted = IME.kanjiConversionIfRequired(neta) + let netaShown = (neta == theConverted) ? neta : "\(theConverted)(\(neta))" + if candidateString.string == netaShown { + indexDeducted = i + break + } + } + } else if let state = state as? InputState.ChoosingCandidate { + for (i, neta) in state.candidates.map(\.1).enumerated() { + let theConverted = IME.kanjiConversionIfRequired(neta) + let netaShown = (neta == theConverted) ? neta : "\(theConverted)(\(neta))" + if candidateString.string == netaShown { + indexDeducted = i + break + } + } + } + keyHandler( + keyHandler, + didSelectCandidateAt: indexDeducted, + ctlCandidate: ctlInputMethod.ctlCandidateCurrent + ) + } } diff --git a/Source/Modules/ControllerModules/ctlInputMethod_Delegates.swift b/Source/Modules/ControllerModules/ctlInputMethod_Delegates.swift index ead447f3..6b7a47a4 100644 --- a/Source/Modules/ControllerModules/ctlInputMethod_Delegates.swift +++ b/Source/Modules/ControllerModules/ctlInputMethod_Delegates.swift @@ -26,6 +26,7 @@ extension ctlInputMethod: KeyHandlerDelegate { -> Bool { guard let state = state as? InputState.Marking else { return false } + if state.bufferReadingCountMisMatch { return false } let refInputModeReversed: InputMode = (keyHandler.inputMode == InputMode.imeModeCHT) ? InputMode.imeModeCHS : InputMode.imeModeCHT @@ -49,7 +50,70 @@ extension ctlInputMethod: KeyHandlerDelegate { // MARK: - Candidate Controller Delegate extension ctlInputMethod: ctlCandidateDelegate { - func handleDelegateEvent(_ event: NSEvent!) -> Bool { handle(event, client: client()) } + func handleDelegateEvent(_ event: NSEvent!) -> Bool { + // 用 Shift 開關半形英數模式,僅對 macOS 10.15 及之後的 macOS 有效。 + if #available(macOS 10.15, *) { + if ShiftKeyUpChecker.check(event) { + if !rencentKeyHandledByKeyHandler { + NotifierController.notify( + message: String( + format: "%@%@%@", NSLocalizedString("Alphanumerical Mode", comment: ""), "\n", + toggleASCIIMode() + ? NSLocalizedString("NotificationSwitchON", comment: "") + : NSLocalizedString("NotificationSwitchOFF", comment: "") + ) + ) + } + rencentKeyHandledByKeyHandler = false + return false + } + } + + /// 這裡仍舊需要判斷 flags。之前使輸入法狀態卡住無法敲漢字的問題已在 KeyHandler 內修復。 + /// 這裡不判斷 flags 的話,用方向鍵前後定位光標之後,再次試圖觸發組字區時、反而會在首次按鍵時失敗。 + /// 同時注意:必須在 event.type == .flagsChanged 結尾插入 return false, + /// 否則,每次處理這種判斷時都會觸發 NSInternalInconsistencyException。 + if event.type == .flagsChanged { return false } + + // 準備修飾鍵,用來判定要新增的詞彙是否需要賦以非常低的權重。 + ctlInputMethod.areWeNerfing = event.modifierFlags.contains([.shift, .command]) + + var textFrame = NSRect.zero + + let attributes: [AnyHashable: Any]? = client().attributes( + forCharacterIndex: 0, lineHeightRectangle: &textFrame + ) + + let isTypingVertical = + (attributes?["IMKTextOrientation"] as? NSNumber)?.intValue == 0 || false + + if client().bundleIdentifier() + == "org.atelierInmu.vChewing.vChewingPhraseEditor" + { + IME.areWeUsingOurOwnPhraseEditor = true + } else { + IME.areWeUsingOurOwnPhraseEditor = false + } + + var input = InputSignal(event: event, isVerticalTyping: isTypingVertical) + input.isASCIIModeInput = isASCIIMode + + // 無法列印的訊號輸入,一概不作處理。 + // 這個過程不能放在 KeyHandler 內,否則不會起作用。 + if !input.charCode.isPrintable { + return false + } + + /// 將按鍵行為與當前輸入法狀態結合起來、交給按鍵調度模組來處理。 + /// 再根據返回的 result bool 數值來告知 IMK「這個按鍵事件是被處理了還是被放行了」。 + let result = keyHandler.handleCandidate(state: state, input: input) { newState in + self.handle(state: newState) + } errorCallback: { + clsSFX.beep() + } + rencentKeyHandledByKeyHandler = result + return result + } func candidateCountForController(_ controller: ctlCandidateProtocol) -> Int { _ = controller // 防止格式整理工具毀掉與此對應的參數。 diff --git a/Source/Modules/ControllerModules/ctlInputMethod_HandleDisplay.swift b/Source/Modules/ControllerModules/ctlInputMethod_HandleDisplay.swift index 4ec14a69..2ee724b1 100644 --- a/Source/Modules/ControllerModules/ctlInputMethod_HandleDisplay.swift +++ b/Source/Modules/ControllerModules/ctlInputMethod_HandleDisplay.swift @@ -46,6 +46,8 @@ extension ctlInputMethod { candidates = state.candidates } if isTypingVertical { return true } + // 接下來的判斷並非適用於 IMK 選字窗,所以先插入排除語句。 + guard ctlInputMethod.ctlCandidateCurrent is ctlCandidateUniversal else { return false } // 以上是通用情形。接下來決定橫排輸入時是否使用縱排選字窗。 // 因為在拿候選字陣列時已經排序過了,所以這裡不用再多排序。 // 測量每頁顯示候選字的累計總長度。如果太長的話就強制使用縱排候選字窗。 @@ -64,13 +66,14 @@ extension ctlInputMethod { /// layoutCandidateView 在這裡無法起到糾正作用。 /// 該問題徹底解決的價值並不大,直接等到 macOS 10.x 全線淘汰之後用 SwiftUI 重寫選字窗吧。 - if isCandidateWindowVertical { // 縱排輸入時強制使用縱排選字窗 - ctlInputMethod.ctlCandidateCurrent = ctlCandidateUniversal.init(.vertical) - } else if mgrPrefs.useHorizontalCandidateList { - ctlInputMethod.ctlCandidateCurrent = ctlCandidateUniversal.init(.horizontal) - } else { - ctlInputMethod.ctlCandidateCurrent = ctlCandidateUniversal.init(.vertical) - } + let candidateLayout: CandidateLayout = + ((isCandidateWindowVertical || !mgrPrefs.useHorizontalCandidateList) + ? CandidateLayout.vertical + : CandidateLayout.horizontal) + + ctlInputMethod.ctlCandidateCurrent = + mgrPrefs.useIMKCandidateWindow + ? ctlCandidateIMK.init(candidateLayout) : ctlCandidateUniversal.init(candidateLayout) // set the attributes for the candidate panel (which uses NSAttributedString) let textSize = mgrPrefs.candidateListTextSize diff --git a/Source/Modules/ControllerModules/ctlInputMethod_HandleStates.swift b/Source/Modules/ControllerModules/ctlInputMethod_HandleStates.swift index c4fd77ec..16f1028e 100644 --- a/Source/Modules/ControllerModules/ctlInputMethod_HandleStates.swift +++ b/Source/Modules/ControllerModules/ctlInputMethod_HandleStates.swift @@ -103,7 +103,8 @@ extension ctlInputMethod { /// 在處理不受 .NotEmpty() 管轄的狀態時可能要用到的函式,會清空螢幕上顯示的內文組字區。 /// 當 setInlineDisplayWithCursor() 在錯誤的狀態下被呼叫時,也會觸發這個函式。 private func clearInlineDisplay() { - client().setMarkedText( + guard let theClient = client() else { return } + theClient.setMarkedText( "", selectionRange: NSRange(location: 0, length: 0), replacementRange: NSRange(location: NSNotFound, length: NSNotFound) ) diff --git a/Source/Modules/IMEModules/mgrPrefs.swift b/Source/Modules/IMEModules/mgrPrefs.swift index c766ad1a..c7ecb77b 100644 --- a/Source/Modules/IMEModules/mgrPrefs.swift +++ b/Source/Modules/IMEModules/mgrPrefs.swift @@ -49,6 +49,8 @@ public enum UserDef: String, CaseIterable { case kKeepReadingUponCompositionError = "KeepReadingUponCompositionError" case kTogglingAlphanumericalModeWithLShift = "TogglingAlphanumericalModeWithLShift" case kUpperCaseLetterKeyBehavior = "UpperCaseLetterKeyBehavior" + case kUseIMKCandidateWindow = "UseIMKCandidateWindow" + case kHandleDefaultCandidateFontsByLangIdentifier = "HandleDefaultCandidateFontsByLangIdentifier" case kCandidateTextFontName = "CandidateTextFontName" case kCandidateKeyLabelFontName = "CandidateKeyLabelFontName" @@ -275,6 +277,13 @@ public enum mgrPrefs { UserDefaults.standard.setDefault( mgrPrefs.upperCaseLetterKeyBehavior, forKey: UserDef.kUpperCaseLetterKeyBehavior.rawValue ) + UserDefaults.standard.setDefault( + mgrPrefs.useIMKCandidateWindow, forKey: UserDef.kUseIMKCandidateWindow.rawValue + ) + UserDefaults.standard.setDefault( + mgrPrefs.handleDefaultCandidateFontsByLangIdentifier, + forKey: UserDef.kHandleDefaultCandidateFontsByLangIdentifier.rawValue + ) UserDefaults.standard.setDefault(mgrPrefs.usingHotKeySCPC, forKey: UserDef.kUsingHotKeySCPC.rawValue) UserDefaults.standard.setDefault(mgrPrefs.usingHotKeyAssociates, forKey: UserDef.kUsingHotKeyAssociates.rawValue) @@ -379,6 +388,17 @@ public enum mgrPrefs { @UserDefault(key: UserDef.kUpperCaseLetterKeyBehavior.rawValue, defaultValue: 0) static var upperCaseLetterKeyBehavior: Int + @UserDefault(key: UserDef.kUseIMKCandidateWindow.rawValue, defaultValue: false) + static var useIMKCandidateWindow: Bool { + didSet { + NSLog("vChewing App self-terminated due to enabling / disabling IMK candidate window.") + NSApplication.shared.terminate(nil) + } + } + + @UserDefault(key: UserDef.kHandleDefaultCandidateFontsByLangIdentifier.rawValue, defaultValue: false) + static var handleDefaultCandidateFontsByLangIdentifier: Bool + // MARK: - Settings (Tier 2) @UserDefault(key: UserDef.kTogglingAlphanumericalModeWithLShift.rawValue, defaultValue: true) diff --git a/Source/Modules/LangModelRelated/SubLMs/lmUserOverride.swift b/Source/Modules/LangModelRelated/SubLMs/lmUserOverride.swift index c13e4833..1b1e8a02 100644 --- a/Source/Modules/LangModelRelated/SubLMs/lmUserOverride.swift +++ b/Source/Modules/LangModelRelated/SubLMs/lmUserOverride.swift @@ -278,26 +278,19 @@ extension vChewing.LMUserOverride { saveCallback() return } - // TODO: 降低磁碟寫入次數。唯有失憶的情況下才會更新觀察且記憶。 + // 這裡還是不要做 decayCallback 判定「是否不急著更新觀察」了,不然會在嘗試覆寫掉錯誤的記憶時失敗。 if var theNeta = mutLRUMap[key] { - _ = getSuggestion( - key: key, timestamp: timestamp, headReading: "", - decayCallback: { - theNeta.observation.update( - candidate: candidate, timestamp: timestamp, forceHighScoreOverride: forceHighScoreOverride - ) - self.mutLRUList.insert(theNeta, at: 0) - self.mutLRUMap[key] = theNeta - IME.prtDebugIntel("UOM: Observation finished with existing observation: \(key)") - saveCallback() - } + theNeta.observation.update( + candidate: candidate, timestamp: timestamp, forceHighScoreOverride: forceHighScoreOverride ) + mutLRUList.insert(theNeta, at: 0) + mutLRUMap[key] = theNeta + IME.prtDebugIntel("UOM: Observation finished with existing observation: \(key)") + saveCallback() } } - private func getSuggestion( - key: String, timestamp: Double, headReading: String, decayCallback: @escaping () -> Void = {} - ) -> Suggestion { + private func getSuggestion(key: String, timestamp: Double, headReading: String) -> Suggestion { guard !key.isEmpty, let kvPair = mutLRUMap[key] else { return .init() } let observation: Observation = kvPair.observation var candidates: [(String, Megrez.Unigram)] = .init() @@ -309,11 +302,6 @@ extension vChewing.LMUserOverride { eventTimestamp: theObservation.timestamp, timestamp: timestamp, lambda: mutDecayExponent ) if (0...currentHighScore).contains(overrideScore) { continue } - let overrideDetectionScore: Double = getScore( - eventCount: theObservation.count, totalCount: observation.count, - eventTimestamp: theObservation.timestamp, timestamp: timestamp, lambda: mutDecayExponent * 2 - ) - if (0...currentHighScore).contains(overrideDetectionScore) { decayCallback() } candidates.append((headReading, .init(value: i, score: overrideScore))) forceHighScoreOverride = theObservation.forceHighScoreOverride diff --git a/Source/Modules/SFX/clsSFX.swift b/Source/Modules/SFX/clsSFX.swift index e0260e47..ab7d3bbd 100644 --- a/Source/Modules/SFX/clsSFX.swift +++ b/Source/Modules/SFX/clsSFX.swift @@ -18,6 +18,14 @@ public enum clsSFX { AudioServicesPlaySystemSound(soundID) } + static func fart() { + let filePath = Bundle.main.path(forResource: "Fart", ofType: "m4a")! + let fileURL = URL(fileURLWithPath: filePath) + var soundID: SystemSoundID = 0 + AudioServicesCreateSystemSoundID(fileURL as CFURL, &soundID) + AudioServicesPlaySystemSound(soundID) + } + static func beep(count: Int = 1) { if count <= 1 { clsSFX.beep() diff --git a/Source/Resources/Base.lproj/Localizable.strings b/Source/Resources/Base.lproj/Localizable.strings index 37153273..e936fe79 100644 --- a/Source/Resources/Base.lproj/Localizable.strings +++ b/Source/Resources/Base.lproj/Localizable.strings @@ -39,7 +39,7 @@ "Please specify at least 4 candidate keys." = "Please specify at least 4 candidate keys."; "Maximum 15 candidate keys allowed." = "Maximum 15 candidate keys allowed."; "⚠︎ Phrase replacement mode enabled, interfering user phrase entry." = "⚠︎ Phrase replacement mode enabled, interfering user phrase entry."; -"⚠︎ Beware: Chars and Readings in buffer doesn't match." = "⚠︎ Beware: Chars and Readings in buffer doesn't match."; +"⚠︎ Unhandlable: Chars and Readings in buffer doesn't match." = "⚠︎ Unhandlable: Chars and Readings in buffer doesn't match."; "Per-Char Select Mode" = "Per-Char Select Mode"; "CNS11643 Mode" = "CNS11643 Mode"; "JIS Shinjitai Output" = "JIS Shinjitai Output"; @@ -123,6 +123,7 @@ "Dachen (Microsoft Standard / Wang / 01, etc.)" = "Dachen (Microsoft Standard / Wang / 01, etc.)"; "Dachen 26 (libChewing)" = "Dachen 26 (libChewing)"; "Debug Mode" = "Debug Mode"; +"DevZone" = "DevZone"; "Dictionary" = "Dictionary"; "Directly commit lowercased letters" = "Directly commit lowercased letters"; "Directly commit uppercased letters" = "Directly commit uppercased letters"; @@ -144,6 +145,7 @@ "Hsu" = "Hsu"; "Hualuo Pinyin with Numeral Intonation" = "Hualuo Pinyin with Numeral Intonation"; "IBM" = "IBM"; +"IMK candidate window is plagued with issues like failed selection keys." = "IMK candidate window is plagued with issues like failed selection keys."; "in front of the phrase (like macOS built-in Zhuyin IME)" = "in front of the phrase (like macOS built-in Zhuyin IME)"; "Japanese" = "Japanese"; "Keyboard Shortcuts:" = "Keyboard Shortcuts:"; @@ -166,11 +168,15 @@ "Space to +cycle pages, Shift+Space to +cycle candidates" = "Space to +cycle pages, Shift+Space to +cycle candidates"; "Starlight" = "Starlight"; "Stop farting (when typed phonetic combination is invalid, etc.)" = "Stop farting (when typed phonetic combination is invalid, etc.)"; +"This only works since macOS 12 with non-IMK candidate window as an alternative wordaround of Apple Bug Report #FB10978412. Apple should patch that for macOS 11 and later." = "This only works since macOS 12 with non-IMK candidate window as an alternative wordaround of Apple Bug Report #FB10978412. Apple should patch that for macOS 11 and later."; "Traditional Chinese" = "Traditional Chinese"; "Type them into inline composition buffer" = "Type them into inline composition buffer"; "Typing Style:" = "Typing Style:"; "UI Language:" = "UI Language:"; "Universal Pinyin with Numeral Intonation" = "Universal Pinyin with Numeral Intonation"; +"Use .langIdentifier to handle UI fonts in candidate window" = "Use .langIdentifier to handle UI fonts in candidate window"; "Use ESC key to clear the entire input buffer" = "Use ESC key to clear the entire input buffer"; +"Use IMK Candidate Window instead (will reboot the IME)" = "Use IMK Candidate Window instead (will reboot the IME)"; "Vertical" = "Vertical"; +"Warning: This page is for testing future features. \nFeatures listed here may not work as expected." = "Warning: This page is for testing future features. \nFeatures listed here may not work as expected."; "Yale Pinyin with Numeral Intonation" = "Yale Pinyin with Numeral Intonation"; diff --git a/Source/Resources/Images/Images.xcassets/PrefToolbar-DevZone.imageset/Contents.json b/Source/Resources/Images/Images.xcassets/PrefToolbar-DevZone.imageset/Contents.json new file mode 100644 index 00000000..cc110c92 --- /dev/null +++ b/Source/Resources/Images/Images.xcassets/PrefToolbar-DevZone.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "DevZone.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "DevZone@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Source/Resources/Images/Images.xcassets/PrefToolbar-DevZone.imageset/DevZone.png b/Source/Resources/Images/Images.xcassets/PrefToolbar-DevZone.imageset/DevZone.png new file mode 100644 index 00000000..226a0233 Binary files /dev/null and b/Source/Resources/Images/Images.xcassets/PrefToolbar-DevZone.imageset/DevZone.png differ diff --git a/Source/Resources/Images/Images.xcassets/PrefToolbar-DevZone.imageset/DevZone@2x.png b/Source/Resources/Images/Images.xcassets/PrefToolbar-DevZone.imageset/DevZone@2x.png new file mode 100644 index 00000000..3983f2a1 Binary files /dev/null and b/Source/Resources/Images/Images.xcassets/PrefToolbar-DevZone.imageset/DevZone@2x.png differ diff --git a/Source/Resources/Images/Images.xcassets/PrefToolbar-Dictionary.iconset/icon_32x32.png b/Source/Resources/Images/Images.xcassets/PrefToolbar-Dictionary.iconset/icon_32x32.png deleted file mode 100644 index b7cb8877..00000000 Binary files a/Source/Resources/Images/Images.xcassets/PrefToolbar-Dictionary.iconset/icon_32x32.png and /dev/null differ diff --git a/Source/Resources/Images/Images.xcassets/PrefToolbar-Dictionary.iconset/icon_32x32@2x.png b/Source/Resources/Images/Images.xcassets/PrefToolbar-Dictionary.iconset/icon_32x32@2x.png deleted file mode 100644 index edee48a6..00000000 Binary files a/Source/Resources/Images/Images.xcassets/PrefToolbar-Dictionary.iconset/icon_32x32@2x.png and /dev/null differ diff --git a/Source/Resources/Images/Images.xcassets/PrefToolbar-Dictionary.imageset/Contents.json b/Source/Resources/Images/Images.xcassets/PrefToolbar-Dictionary.imageset/Contents.json new file mode 100644 index 00000000..799d7e72 --- /dev/null +++ b/Source/Resources/Images/Images.xcassets/PrefToolbar-Dictionary.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "Dictionary.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Dictionary@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Source/Resources/Images/Images.xcassets/PrefToolbar-Dictionary.imageset/Dictionary.png b/Source/Resources/Images/Images.xcassets/PrefToolbar-Dictionary.imageset/Dictionary.png new file mode 100644 index 00000000..f77b4f02 Binary files /dev/null and b/Source/Resources/Images/Images.xcassets/PrefToolbar-Dictionary.imageset/Dictionary.png differ diff --git a/Source/Resources/Images/Images.xcassets/PrefToolbar-Dictionary.imageset/Dictionary@2x.png b/Source/Resources/Images/Images.xcassets/PrefToolbar-Dictionary.imageset/Dictionary@2x.png new file mode 100644 index 00000000..5f4a7907 Binary files /dev/null and b/Source/Resources/Images/Images.xcassets/PrefToolbar-Dictionary.imageset/Dictionary@2x.png differ diff --git a/Source/Resources/Images/Images.xcassets/PrefToolbar-Experiences.iconset/icon_32x32.png b/Source/Resources/Images/Images.xcassets/PrefToolbar-Experiences.iconset/icon_32x32.png deleted file mode 100644 index 2d63c06f..00000000 Binary files a/Source/Resources/Images/Images.xcassets/PrefToolbar-Experiences.iconset/icon_32x32.png and /dev/null differ diff --git a/Source/Resources/Images/Images.xcassets/PrefToolbar-Experiences.iconset/icon_32x32@2x.png b/Source/Resources/Images/Images.xcassets/PrefToolbar-Experiences.iconset/icon_32x32@2x.png deleted file mode 100644 index 06c51e4a..00000000 Binary files a/Source/Resources/Images/Images.xcassets/PrefToolbar-Experiences.iconset/icon_32x32@2x.png and /dev/null differ diff --git a/Source/Resources/Images/Images.xcassets/PrefToolbar-Experiences.imageset/Contents.json b/Source/Resources/Images/Images.xcassets/PrefToolbar-Experiences.imageset/Contents.json new file mode 100644 index 00000000..18f84fe1 --- /dev/null +++ b/Source/Resources/Images/Images.xcassets/PrefToolbar-Experiences.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "Experiences.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Experiences@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Source/Resources/Images/Images.xcassets/PrefToolbar-Experiences.imageset/Experiences.png b/Source/Resources/Images/Images.xcassets/PrefToolbar-Experiences.imageset/Experiences.png new file mode 100644 index 00000000..ce7dd387 Binary files /dev/null and b/Source/Resources/Images/Images.xcassets/PrefToolbar-Experiences.imageset/Experiences.png differ diff --git a/Source/Resources/Images/Images.xcassets/PrefToolbar-Experiences.imageset/Experiences@2x.png b/Source/Resources/Images/Images.xcassets/PrefToolbar-Experiences.imageset/Experiences@2x.png new file mode 100644 index 00000000..4e21e4d1 Binary files /dev/null and b/Source/Resources/Images/Images.xcassets/PrefToolbar-Experiences.imageset/Experiences@2x.png differ diff --git a/Source/Resources/Images/Images.xcassets/PrefToolbar-General.iconset/icon_32x32.png b/Source/Resources/Images/Images.xcassets/PrefToolbar-General.iconset/icon_32x32.png deleted file mode 100644 index ae3e4186..00000000 Binary files a/Source/Resources/Images/Images.xcassets/PrefToolbar-General.iconset/icon_32x32.png and /dev/null differ diff --git a/Source/Resources/Images/Images.xcassets/PrefToolbar-General.iconset/icon_32x32@2x.png b/Source/Resources/Images/Images.xcassets/PrefToolbar-General.iconset/icon_32x32@2x.png deleted file mode 100644 index 216066e0..00000000 Binary files a/Source/Resources/Images/Images.xcassets/PrefToolbar-General.iconset/icon_32x32@2x.png and /dev/null differ diff --git a/Source/Resources/Images/Images.xcassets/PrefToolbar-General.imageset/Contents.json b/Source/Resources/Images/Images.xcassets/PrefToolbar-General.imageset/Contents.json new file mode 100644 index 00000000..7898a006 --- /dev/null +++ b/Source/Resources/Images/Images.xcassets/PrefToolbar-General.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "General.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "General@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Source/Resources/Images/Images.xcassets/PrefToolbar-General.imageset/General.png b/Source/Resources/Images/Images.xcassets/PrefToolbar-General.imageset/General.png new file mode 100644 index 00000000..f1429c9c Binary files /dev/null and b/Source/Resources/Images/Images.xcassets/PrefToolbar-General.imageset/General.png differ diff --git a/Source/Resources/Images/Images.xcassets/PrefToolbar-General.imageset/General@2x.png b/Source/Resources/Images/Images.xcassets/PrefToolbar-General.imageset/General@2x.png new file mode 100644 index 00000000..b379d1cd Binary files /dev/null and b/Source/Resources/Images/Images.xcassets/PrefToolbar-General.imageset/General@2x.png differ diff --git a/Source/Resources/Images/Images.xcassets/PrefToolbar-Keyboard.iconset/icon_32x32.png b/Source/Resources/Images/Images.xcassets/PrefToolbar-Keyboard.iconset/icon_32x32.png deleted file mode 100644 index c58382ef..00000000 Binary files a/Source/Resources/Images/Images.xcassets/PrefToolbar-Keyboard.iconset/icon_32x32.png and /dev/null differ diff --git a/Source/Resources/Images/Images.xcassets/PrefToolbar-Keyboard.iconset/icon_32x32@2x.png b/Source/Resources/Images/Images.xcassets/PrefToolbar-Keyboard.iconset/icon_32x32@2x.png deleted file mode 100644 index 0306e75e..00000000 Binary files a/Source/Resources/Images/Images.xcassets/PrefToolbar-Keyboard.iconset/icon_32x32@2x.png and /dev/null differ diff --git a/Source/Resources/Images/Images.xcassets/PrefToolbar-Keyboard.imageset/Contents.json b/Source/Resources/Images/Images.xcassets/PrefToolbar-Keyboard.imageset/Contents.json new file mode 100644 index 00000000..419f277b --- /dev/null +++ b/Source/Resources/Images/Images.xcassets/PrefToolbar-Keyboard.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "Keyboard.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Keyboard@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Source/Resources/Images/Images.xcassets/PrefToolbar-Keyboard.imageset/Keyboard.png b/Source/Resources/Images/Images.xcassets/PrefToolbar-Keyboard.imageset/Keyboard.png new file mode 100644 index 00000000..d566f1b5 Binary files /dev/null and b/Source/Resources/Images/Images.xcassets/PrefToolbar-Keyboard.imageset/Keyboard.png differ diff --git a/Source/Resources/Images/Images.xcassets/PrefToolbar-Keyboard.imageset/Keyboard@2x.png b/Source/Resources/Images/Images.xcassets/PrefToolbar-Keyboard.imageset/Keyboard@2x.png new file mode 100644 index 00000000..2619ca68 Binary files /dev/null and b/Source/Resources/Images/Images.xcassets/PrefToolbar-Keyboard.imageset/Keyboard@2x.png differ diff --git a/Source/Resources/en.lproj/Localizable.strings b/Source/Resources/en.lproj/Localizable.strings index 37153273..e936fe79 100644 --- a/Source/Resources/en.lproj/Localizable.strings +++ b/Source/Resources/en.lproj/Localizable.strings @@ -39,7 +39,7 @@ "Please specify at least 4 candidate keys." = "Please specify at least 4 candidate keys."; "Maximum 15 candidate keys allowed." = "Maximum 15 candidate keys allowed."; "⚠︎ Phrase replacement mode enabled, interfering user phrase entry." = "⚠︎ Phrase replacement mode enabled, interfering user phrase entry."; -"⚠︎ Beware: Chars and Readings in buffer doesn't match." = "⚠︎ Beware: Chars and Readings in buffer doesn't match."; +"⚠︎ Unhandlable: Chars and Readings in buffer doesn't match." = "⚠︎ Unhandlable: Chars and Readings in buffer doesn't match."; "Per-Char Select Mode" = "Per-Char Select Mode"; "CNS11643 Mode" = "CNS11643 Mode"; "JIS Shinjitai Output" = "JIS Shinjitai Output"; @@ -123,6 +123,7 @@ "Dachen (Microsoft Standard / Wang / 01, etc.)" = "Dachen (Microsoft Standard / Wang / 01, etc.)"; "Dachen 26 (libChewing)" = "Dachen 26 (libChewing)"; "Debug Mode" = "Debug Mode"; +"DevZone" = "DevZone"; "Dictionary" = "Dictionary"; "Directly commit lowercased letters" = "Directly commit lowercased letters"; "Directly commit uppercased letters" = "Directly commit uppercased letters"; @@ -144,6 +145,7 @@ "Hsu" = "Hsu"; "Hualuo Pinyin with Numeral Intonation" = "Hualuo Pinyin with Numeral Intonation"; "IBM" = "IBM"; +"IMK candidate window is plagued with issues like failed selection keys." = "IMK candidate window is plagued with issues like failed selection keys."; "in front of the phrase (like macOS built-in Zhuyin IME)" = "in front of the phrase (like macOS built-in Zhuyin IME)"; "Japanese" = "Japanese"; "Keyboard Shortcuts:" = "Keyboard Shortcuts:"; @@ -166,11 +168,15 @@ "Space to +cycle pages, Shift+Space to +cycle candidates" = "Space to +cycle pages, Shift+Space to +cycle candidates"; "Starlight" = "Starlight"; "Stop farting (when typed phonetic combination is invalid, etc.)" = "Stop farting (when typed phonetic combination is invalid, etc.)"; +"This only works since macOS 12 with non-IMK candidate window as an alternative wordaround of Apple Bug Report #FB10978412. Apple should patch that for macOS 11 and later." = "This only works since macOS 12 with non-IMK candidate window as an alternative wordaround of Apple Bug Report #FB10978412. Apple should patch that for macOS 11 and later."; "Traditional Chinese" = "Traditional Chinese"; "Type them into inline composition buffer" = "Type them into inline composition buffer"; "Typing Style:" = "Typing Style:"; "UI Language:" = "UI Language:"; "Universal Pinyin with Numeral Intonation" = "Universal Pinyin with Numeral Intonation"; +"Use .langIdentifier to handle UI fonts in candidate window" = "Use .langIdentifier to handle UI fonts in candidate window"; "Use ESC key to clear the entire input buffer" = "Use ESC key to clear the entire input buffer"; +"Use IMK Candidate Window instead (will reboot the IME)" = "Use IMK Candidate Window instead (will reboot the IME)"; "Vertical" = "Vertical"; +"Warning: This page is for testing future features. \nFeatures listed here may not work as expected." = "Warning: This page is for testing future features. \nFeatures listed here may not work as expected."; "Yale Pinyin with Numeral Intonation" = "Yale Pinyin with Numeral Intonation"; diff --git a/Source/Resources/ja.lproj/Localizable.strings b/Source/Resources/ja.lproj/Localizable.strings index 2bc3c170..ee1e49ad 100644 --- a/Source/Resources/ja.lproj/Localizable.strings +++ b/Source/Resources/ja.lproj/Localizable.strings @@ -39,7 +39,7 @@ "Please specify at least 4 candidate keys." = "言選り用キー陣列に少なくとも4つのキーをご登録ください。"; "Maximum 15 candidate keys allowed." = "言選り用キー陣列には最多15つキー登録できます。"; "⚠︎ Phrase replacement mode enabled, interfering user phrase entry." = "⚠︎ 言葉置換機能稼働中、新添付言葉にも影響。"; -"⚠︎ Beware: Chars and Readings in buffer doesn't match." = "⚠︎ 注意:緩衝列の字数は読みの数と不同等。"; +"⚠︎ Unhandlable: Chars and Readings in buffer doesn't match." = "⚠︎ 対処不可:緩衝列の字数は読みの数と不同等。"; "Per-Char Select Mode" = "全候補入力モード"; "CNS11643 Mode" = "全字庫モード"; "JIS Shinjitai Output" = "JIS 新字体モード"; @@ -123,6 +123,7 @@ "Dachen (Microsoft Standard / Wang / 01, etc.)" = "大千配列 (Microsoft 標準・王安・零壹など)"; "Dachen 26 (libChewing)" = "酷音大千 26 キー配列"; "Debug Mode" = "欠陥辿着モード"; +"DevZone" = "開発道場"; "Dictionary" = "辞書設定"; "Directly commit lowercased letters" = "ローマ字(小文字)を直接出力"; "Directly commit uppercased letters" = "ローマ字(大文字)を直接出力"; @@ -144,6 +145,7 @@ "Hsu" = "許氏国音自然配列"; "Hualuo Pinyin with Numeral Intonation" = "中華ローマ弁音 (ローマ字+数字音調)"; "IBM" = "IBM 配列"; +"IMK candidate window is plagued with issues like failed selection keys." = "IMK 候補陳列ウィンドウで言選り用キーは現時点で利用不可、尚他故障あり。"; "in front of the phrase (like macOS built-in Zhuyin IME)" = "単語の前で // macOS 内蔵注音入力のやり方"; "Japanese" = "和語"; "Keyboard Shortcuts:" = "ショートカット:"; @@ -166,11 +168,15 @@ "Space to +cycle pages, Shift+Space to +cycle candidates" = "Space で次のページ、Shift+Space で次の候補文字を"; "Starlight" = "星光配列"; "Stop farting (when typed phonetic combination is invalid, etc.)" = "マナーモード // 外すと入力間違った時に変な声が出る"; +"This only works since macOS 12 with non-IMK candidate window as an alternative wordaround of Apple Bug Report #FB10978412. Apple should patch that for macOS 11 and later." = "これは Apple Bug Report #FB10978412 の臨時対策であり、macOS 12 からの macOS に効き、IMK 以外の候補陳列ウィンドウに作用する。Apple は macOS 11 からの macOS のために該当 Bug を修復すべきである。"; "Traditional Chinese" = "繁体中国語"; "Type them into inline composition buffer" = "入力緩衝列にローマ字入力"; "Typing Style:" = "入力習慣:"; "UI Language:" = "表示用言語:"; "Universal Pinyin with Numeral Intonation" = "汎用弁音 (ローマ字+数字音調)"; +"Use .langIdentifier to handle UI fonts in candidate window" = "「.langIdentifier」を使って候補陳列ウィンドウのフォントを取り扱う"; "Use ESC key to clear the entire input buffer" = "ESC キーで入力緩衝列を消す"; +"Use IMK Candidate Window instead (will reboot the IME)" = "IMK 候補陳列ウィンドウを起用(入力アプリは自動的に再起動)"; "Vertical" = "縦型陳列"; +"Warning: This page is for testing future features. \nFeatures listed here may not work as expected." = "警告:これからの新機能テストのために作ったページですから、\nここで陳列されている諸機能は予想通り動けるだと思わないでください。"; "Yale Pinyin with Numeral Intonation" = "イェール弁音 (ローマ字+数字音調)"; diff --git a/Source/Resources/zh-Hans.lproj/Localizable.strings b/Source/Resources/zh-Hans.lproj/Localizable.strings index 20a43804..805d740f 100644 --- a/Source/Resources/zh-Hans.lproj/Localizable.strings +++ b/Source/Resources/zh-Hans.lproj/Localizable.strings @@ -39,7 +39,7 @@ "Please specify at least 4 candidate keys." = "请至少指定四个选字键。"; "Maximum 15 candidate keys allowed." = "选字键最多只能指定十五个。"; "⚠︎ Phrase replacement mode enabled, interfering user phrase entry." = "⚠︎ 语汇置换功能已启用,会波及语汇自订。"; -"⚠︎ Beware: Chars and Readings in buffer doesn't match." = "⚠︎ 注意:组字区字数与读音数不对应。"; +"⚠︎ Unhandlable: Chars and Readings in buffer doesn't match." = "⚠︎ 无法处理:组字区字数与读音数不对应。"; "Per-Char Select Mode" = "仿真逐字选字输入"; "CNS11643 Mode" = "全字库模式"; "JIS Shinjitai Output" = "JIS 新字体模式"; @@ -123,7 +123,8 @@ "Dachen (Microsoft Standard / Wang / 01, etc.)" = "大千排列 (微软标准/王安/零壹/仲鼎/国乔)"; "Dachen 26 (libChewing)" = "酷音大千二十六键排列"; "Debug Mode" = "侦错模式"; -"Dictionary" = "辞典"; +"DevZone" = "开发道场"; +"Dictionary" = "辞典设定"; "Directly commit lowercased letters" = "直接递交小写字母"; "Directly commit uppercased letters" = "直接递交大写字母"; "Emulating select-candidate-per-character mode" = "模拟 90 年代前期注音逐字选字输入风格"; @@ -133,22 +134,23 @@ "English" = "英语"; "Eten 26" = "倚天忘形排列 (26 键)"; "Eten Traditional" = "倚天传统排列"; -"Experience" = "体验"; +"Experience" = "体验设定"; "Fake Seigyou" = "伪精业排列"; "Follow OS settings" = "依系统设定"; "for cycling candidates" = "轮替候选字"; "for cycling pages" = "轮替页面"; -"General" = "通用"; +"General" = "通用设定"; "Hanyu Pinyin with Numeral Intonation" = "汉语拼音+数字标调"; "Horizontal" = "横向布局"; "Hsu" = "许氏国音自然排列"; "Hualuo Pinyin with Numeral Intonation" = "华罗拼音+数字标调"; "Hualuo Pinyin with Numeral Intonation" = "華羅拼音+数字标调"; "IBM" = "IBM 排列"; +"IMK candidate window is plagued with issues like failed selection keys." = "IMK 选字窗目前暂时无法正常使用选字键,并具其它未知故障。"; "in front of the phrase (like macOS built-in Zhuyin IME)" = "将游标置于词语前方 // macOS 内建注音风格"; "Japanese" = "和语"; "Keyboard Shortcuts:" = "键盘快捷键:"; -"Keyboard" = "键盘"; +"Keyboard" = "键盘设定"; "Misc Settings:" = "杂项:"; "MiTAC" = "神通排列"; "Non-QWERTY alphanumerical keyboard layouts are for Hanyu Pinyin parser only." = "QWERTY 以外的英数布局是为了汉语拼音排列使用者而准备的。"; @@ -167,12 +169,16 @@ "Space to +cycle pages, Shift+Space to +cycle candidates" = "空格键 换下一页,Shift+空格键 换选下一个后选字"; "Starlight" = "星光排列"; "Stop farting (when typed phonetic combination is invalid, etc.)" = "廉耻模式 // 取消勾选的话,敲错字时会有异音"; +"This only works since macOS 12 with non-IMK candidate window as an alternative wordaround of Apple Bug Report #FB10978412. Apple should patch that for macOS 11 and later." = "该方法是 Apple Bug Report #FB10978412 的保守治疗方案,用来仅针对 macOS 12 开始的系统,且仅对非 IMK 选字窗起作用。Apple 应该对 macOS 11 开始的系统修复这个 Bug。"; "Traditional Chinese" = "繁体中文"; "Type them into inline composition buffer" = "直接键入内文组字区"; "Typing Style:" = "输入风格:"; "UI Language:" = "介面语言:"; "Universal Pinyin with Numeral Intonation" = "通用拼音+数字标调"; "Universal Pinyin with Numeral Intonation" = "通用拼音+数字标调"; +"Use .langIdentifier to handle UI fonts in candidate window" = "使用 .langIdentifier 来管理选字窗的预设介面字型"; "Use ESC key to clear the entire input buffer" = "敲 ESC 键以清空整个组字缓冲区"; +"Use IMK Candidate Window instead (will reboot the IME)" = "启用 IMK 选字窗(会自动重启输入法)"; "Vertical" = "纵向布局"; +"Warning: This page is for testing future features. \nFeatures listed here may not work as expected." = "警告:该页面仅作未来功能测试所用。\n在此列出的功能并非处于完全可用之状态。"; "Yale Pinyin with Numeral Intonation" = "耶鲁拼音+数字标调"; diff --git a/Source/Resources/zh-Hant.lproj/Localizable.strings b/Source/Resources/zh-Hant.lproj/Localizable.strings index 5a0f9e68..12e66a70 100644 --- a/Source/Resources/zh-Hant.lproj/Localizable.strings +++ b/Source/Resources/zh-Hant.lproj/Localizable.strings @@ -39,7 +39,7 @@ "Please specify at least 4 candidate keys." = "請至少指定四個選字鍵。"; "Maximum 15 candidate keys allowed." = "選字鍵最多只能指定十五個。"; "⚠︎ Phrase replacement mode enabled, interfering user phrase entry." = "⚠︎ 語彙置換功能已啟用,會波及語彙自訂。"; -"⚠︎ Beware: Chars and Readings in buffer doesn't match." = "⚠︎ 注意:組字區字數與讀音數不對應。"; +"⚠︎ Unhandlable: Chars and Readings in buffer doesn't match." = "⚠︎ 無法處理:組字區字數與讀音數不對應。"; "Per-Char Select Mode" = "模擬逐字選字輸入"; "CNS11643 Mode" = "全字庫模式"; "JIS Shinjitai Output" = "JIS 新字體模式"; @@ -123,7 +123,8 @@ "Dachen (Microsoft Standard / Wang / 01, etc.)" = "大千排列 (微軟標準/王安/零壹/仲鼎/國喬)"; "Dachen 26 (libChewing)" = "酷音大千二十六鍵排列"; "Debug Mode" = "偵錯模式"; -"Dictionary" = "辭典"; +"DevZone" = "開發道場"; +"Dictionary" = "辭典設定"; "Directly commit lowercased letters" = "直接遞交小寫字母"; "Directly commit uppercased letters" = "直接遞交大寫字母"; "Emulating select-candidate-per-character mode" = "模擬 90 年代前期注音逐字選字輸入風格"; @@ -133,21 +134,22 @@ "English" = "英語"; "Eten 26" = "倚天忘形排列 (26 鍵)"; "Eten Traditional" = "倚天傳統排列"; -"Experience" = "體驗"; +"Experience" = "體驗設定"; "Fake Seigyou" = "偽精業排列"; "Follow OS settings" = "依系統設定"; "for cycling candidates" = "輪替候選字"; "for cycling pages" = "輪替頁面"; -"General" = "通用"; +"General" = "通用設定"; "Hanyu Pinyin with Numeral Intonation" = "漢語拼音+數字標調"; "Horizontal" = "橫向佈局"; "Hsu" = "許氏國音自然排列"; "Hualuo Pinyin with Numeral Intonation" = "華羅拼音+數字標調"; "IBM" = "IBM 排列"; +"IMK candidate window is plagued with issues like failed selection keys." = "IMK 選字窗目前暫時無法正常使用選字鍵,併具其它未知故障。"; "in front of the phrase (like macOS built-in Zhuyin IME)" = "將游標置於詞語前方 // macOS 內建注音風格"; "Japanese" = "和語"; "Keyboard Shortcuts:" = "鍵盤快速鍵:"; -"Keyboard" = "鍵盤"; +"Keyboard" = "鍵盤設定"; "Misc Settings:" = "雜項:"; "MiTAC" = "神通排列"; "Non-QWERTY alphanumerical keyboard layouts are for Hanyu Pinyin parser only." = "QWERTY 以外的英數佈局是為了漢語拼音排列使用者而準備的。"; @@ -166,11 +168,15 @@ "Space to +cycle pages, Shift+Space to +cycle candidates" = "空格鍵 換下一頁,Shift+空格鍵 換選下一個後選字"; "Starlight" = "星光排列"; "Stop farting (when typed phonetic combination is invalid, etc.)" = "廉恥模式 // 取消勾選的話,敲錯字時會有異音"; +"This only works since macOS 12 with non-IMK candidate window as an alternative wordaround of Apple Bug Report #FB10978412. Apple should patch that for macOS 11 and later." = "該方法是 Apple Bug Report #FB10978412 的保守治療方案,用來僅針對 macOS 12 開始的系統,且僅對非 IMK 選字窗起作用。Apple 應該對 macOS 11 開始的系統修復這個 Bug。"; "Traditional Chinese" = "繁體中文"; "Type them into inline composition buffer" = "直接鍵入內文組字區"; "Typing Style:" = "輸入風格:"; "UI Language:" = "介面語言:"; "Universal Pinyin with Numeral Intonation" = "通用拼音+數字標調"; +"Use .langIdentifier to handle UI fonts in candidate window" = "使用 .langIdentifier 來管理選字窗的預設介面字型"; "Use ESC key to clear the entire input buffer" = "敲 ESC 鍵以清空整個組字緩衝區"; +"Use IMK Candidate Window instead (will reboot the IME)" = "啟用 IMK 選字窗(會自動重啟輸入法)"; "Vertical" = "縱向佈局"; +"Warning: This page is for testing future features. \nFeatures listed here may not work as expected." = "警告:該頁面僅作未來功能測試所用。\n在此列出的功能並非處於完全可用之狀態。"; "Yale Pinyin with Numeral Intonation" = "耶魯拼音+數字標調"; diff --git a/Source/UI/CandidateUI/ctlCandidateIMK.swift b/Source/UI/CandidateUI/ctlCandidateIMK.swift index 4d5a415b..1ac5a04e 100644 --- a/Source/UI/CandidateUI/ctlCandidateIMK.swift +++ b/Source/UI/CandidateUI/ctlCandidateIMK.swift @@ -18,8 +18,6 @@ public class ctlCandidateIMK: IMKCandidates, ctlCandidateProtocol { } } - public var selectedCandidateIndex: Int = .max - public var visible: Bool = false { didSet { if visible { @@ -30,10 +28,14 @@ public class ctlCandidateIMK: IMKCandidates, ctlCandidateProtocol { } } - public var windowTopLeftPoint: NSPoint = .init(x: 0, y: 0) { - didSet { + public var windowTopLeftPoint: NSPoint { + get { + let frameRect = candidateFrame() + return NSPoint(x: frameRect.minX, y: frameRect.maxY) + } + set { DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()) { - self.set(windowTopLeftPoint: self.windowTopLeftPoint, bottomOutOfScreenAdjustmentHeight: 0) + self.set(windowTopLeftPoint: newValue, bottomOutOfScreenAdjustmentHeight: 0) } } } @@ -60,7 +62,8 @@ public class ctlCandidateIMK: IMKCandidates, ctlCandidateProtocol { case .vertical: setPanelType(kIMKSingleColumnScrollingCandidatePanel) } - setAttributes([IMKCandidatesSendServerKeyEventFirst: false]) + // 設為 true 表示先交給 ctlIME 處理 + setAttributes([IMKCandidatesSendServerKeyEventFirst: true]) } public required init(_ layout: CandidateLayout = .horizontal) { @@ -86,40 +89,151 @@ public class ctlCandidateIMK: IMKCandidates, ctlCandidateProtocol { update() } + /// 幹話:這裡很多函式內容亂寫也都無所謂了,因為都被 IMKCandidates 代管執行。 + /// 對於所有 IMK 選字窗的選字判斷動作,不是在 keyHandler 中,而是在 `ctlIME_Core` 中。 + + private var currentPageIndex: Int = 0 + + private var pageCount: Int { + guard let delegate = delegate else { + return 0 + } + let totalCount = delegate.candidateCountForController(self) + let keyLabelCount = keyLabels.count + return totalCount / keyLabelCount + ((totalCount % keyLabelCount) != 0 ? 1 : 0) + } + public func showNextPage() -> Bool { + guard delegate != nil else { return false } + if pageCount == 1 { return highlightNextCandidate() } + if currentPageIndex + 1 >= pageCount { clsSFX.beep() } + currentPageIndex = (currentPageIndex + 1 >= pageCount) ? 0 : currentPageIndex + 1 if selectedCandidateIndex == candidates(self).count - 1 { return false } selectedCandidateIndex = min(selectedCandidateIndex + keyCount, candidates(self).count - 1) - return selectCandidate(withIdentifier: selectedCandidateIndex) + pageDownAndModifySelection(self) + return true } public func showPreviousPage() -> Bool { + guard delegate != nil else { return false } + if pageCount == 1 { return highlightPreviousCandidate() } + if currentPageIndex == 0 { clsSFX.beep() } + currentPageIndex = (currentPageIndex == 0) ? pageCount - 1 : currentPageIndex - 1 if selectedCandidateIndex == 0 { return true } selectedCandidateIndex = max(selectedCandidateIndex - keyCount, 0) - return selectCandidate(withIdentifier: selectedCandidateIndex) + pageUpAndModifySelection(self) + return true } public func highlightNextCandidate() -> Bool { - if selectedCandidateIndex == candidates(self).count - 1 { return false } - selectedCandidateIndex = min(selectedCandidateIndex + 1, candidates(self).count - 1) - return selectCandidate(withIdentifier: selectedCandidateIndex) + guard let delegate = delegate else { return false } + selectedCandidateIndex = + (selectedCandidateIndex + 1 >= delegate.candidateCountForController(self)) + ? 0 : selectedCandidateIndex + 1 + switch currentLayout { + case .horizontal: + moveRight(self) + return true + case .vertical: + moveDown(self) + return true + } } public func highlightPreviousCandidate() -> Bool { - if selectedCandidateIndex == 0 { return true } - selectedCandidateIndex = max(selectedCandidateIndex - 1, 0) - return selectCandidate(withIdentifier: selectedCandidateIndex) - } - - public func candidateIndexAtKeyLabelIndex(_: Int) -> Int { - selectedCandidateIndex - } - - public func set(windowTopLeftPoint: NSPoint, bottomOutOfScreenAdjustmentHeight _: CGFloat = 0) { - setCandidateFrameTopLeft(windowTopLeftPoint) - } - - override public func handle(_ event: NSEvent!, client _: Any!) -> Bool { guard let delegate = delegate else { return false } - return delegate.handleDelegateEvent(event) + selectedCandidateIndex = + (selectedCandidateIndex == 0) + ? delegate.candidateCountForController(self) - 1 : selectedCandidateIndex - 1 + switch currentLayout { + case .horizontal: + moveLeft(self) + return true + case .vertical: + moveUp(self) + return true + } + } + + public func candidateIndexAtKeyLabelIndex(_ index: Int) -> Int { + guard let delegate = delegate else { + return Int.max + } + + let result = currentPageIndex * keyLabels.count + index + return result < delegate.candidateCountForController(self) ? result : Int.max + } + + public var selectedCandidateIndex: Int { + get { + selectedCandidate() + } + set { + selectCandidate(withIdentifier: newValue) + } + } + + public func set(windowTopLeftPoint: NSPoint, bottomOutOfScreenAdjustmentHeight height: CGFloat) { + DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()) { + self.doSet( + windowTopLeftPoint: windowTopLeftPoint, bottomOutOfScreenAdjustmentHeight: height + ) + } + } + + func doSet(windowTopLeftPoint: NSPoint, bottomOutOfScreenAdjustmentHeight height: CGFloat) { + var adjustedPoint = windowTopLeftPoint + var adjustedHeight = height + + var screenFrame = NSScreen.main?.visibleFrame ?? NSRect.zero + for screen in NSScreen.screens { + let frame = screen.visibleFrame + if windowTopLeftPoint.x >= frame.minX, windowTopLeftPoint.x <= frame.maxX, + windowTopLeftPoint.y >= frame.minY, windowTopLeftPoint.y <= frame.maxY + { + screenFrame = frame + break + } + } + + if adjustedHeight > screenFrame.size.height / 2.0 { + adjustedHeight = 0.0 + } + + let windowSize = candidateFrame().size + + // bottom beneath the screen? + if adjustedPoint.y - windowSize.height < screenFrame.minY { + adjustedPoint.y = windowTopLeftPoint.y + adjustedHeight + windowSize.height + } + + // top over the screen? + if adjustedPoint.y >= screenFrame.maxY { + adjustedPoint.y = screenFrame.maxY - 1.0 + } + + // right + if adjustedPoint.x + windowSize.width >= screenFrame.maxX { + adjustedPoint.x = screenFrame.maxX - windowSize.width + } + + // left + if adjustedPoint.x < screenFrame.minX { + adjustedPoint.x = screenFrame.minX + } + + setCandidateFrameTopLeft(adjustedPoint) + } + + override public func interpretKeyEvents(_ eventArray: [NSEvent]) { + guard !eventArray.isEmpty else { return } + let event = eventArray[0] + let input = InputSignal(event: event) + guard let delegate = delegate else { return } + if input.isEsc || input.isBackSpace || input.isDelete || input.isShiftHold { + _ = delegate.handleDelegateEvent(event) + } else { + super.interpretKeyEvents(eventArray) + } } } diff --git a/Source/UI/CandidateUI/ctlCandidateUniversal.swift b/Source/UI/CandidateUI/ctlCandidateUniversal.swift index b82cf7e8..f123cd46 100644 --- a/Source/UI/CandidateUI/ctlCandidateUniversal.swift +++ b/Source/UI/CandidateUI/ctlCandidateUniversal.swift @@ -82,7 +82,7 @@ private class vwrCandidateUniversal: NSView { switch isVerticalLayout { case true: if calculatedWindowWidth < rctCandidate.size.width { - calculatedWindowWidth = rctCandidate.size.width + cellPadding + calculatedWindowWidth = rctCandidate.size.width + cellPadding * 2 } case false: if cellWidth < cellHeight * 1.35 { @@ -137,46 +137,40 @@ private class vwrCandidateUniversal: NSView { NSColor.controlBackgroundColor.setFill() // Candidate list panel base background NSBezierPath.fill(bounds) - 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) - ) - switch isVerticalLayout { case true: var accuHeight: CGFloat = 0 for (index, elementHeight) in elementHeights.enumerated() { let currentHeight = elementHeight let rctCandidateArea = NSRect( - x: 0.0, y: accuHeight, width: windowWidth, height: candidateTextHeight + cellPadding + x: 3.0, y: accuHeight + 3.0, width: windowWidth - 6.0, + height: candidateTextHeight + cellPadding - 6.0 ) let rctLabel = NSRect( - x: cellPadding / 2 - 1, y: accuHeight + cellPadding / 2, width: keyLabelWidth, + x: cellPadding / 2 + 2, y: accuHeight + cellPadding / 2, width: keyLabelWidth, height: keyLabelHeight * 2.0 ) let rctCandidatePhrase = NSRect( - x: cellPadding / 2 - 1 + keyLabelWidth, y: accuHeight + cellPadding / 2 - 1, + x: cellPadding / 2 + 2 + keyLabelWidth, y: accuHeight + cellPadding / 2 - 1, width: windowWidth - keyLabelWidth, height: candidateTextHeight ) var activeCandidateIndexAttr = keyLabelAttrDict var activeCandidateAttr = candidateAttrDict if index == highlightedIndex { - let colorBlendAmount: CGFloat = IME.isDarkMode() ? 0.25 : 0 + let colorBlendAmount: CGFloat = IME.isDarkMode() ? 0.3 : 0 // The background color of the highlightened candidate switch IME.currentInputMode { case InputMode.imeModeCHS: NSColor.systemRed.blended( withFraction: colorBlendAmount, - of: NSColor.controlBackgroundColor + of: NSColor.black )! .setFill() case InputMode.imeModeCHT: NSColor.systemBlue.blended( withFraction: colorBlendAmount, - of: NSColor.controlBackgroundColor + of: NSColor.black )! .setFill() default: @@ -190,7 +184,24 @@ private class vwrCandidateUniversal: NSView { } else { NSColor.controlBackgroundColor.setFill() } - NSBezierPath.fill(rctCandidateArea) + if mgrPrefs.handleDefaultCandidateFontsByLangIdentifier { + switch IME.currentInputMode { + case InputMode.imeModeCHS: + if #available(macOS 12.0, *) { + activeCandidateAttr[.languageIdentifier] = "zh-Hans" as AnyObject + } + case InputMode.imeModeCHT: + if #available(macOS 12.0, *) { + activeCandidateAttr[.languageIdentifier] = + (mgrPrefs.shiftJISShinjitaiOutputEnabled || mgrPrefs.chineseConversionEnabled) + ? "ja" as AnyObject : "zh-Hant" as AnyObject + } + default: + break + } + } + let path: NSBezierPath = .init(roundedRect: rctCandidateArea, xRadius: 5, yRadius: 5) + path.fill() (keyLabels[index] as NSString).draw( in: rctLabel, withAttributes: activeCandidateIndexAttr ) @@ -204,8 +215,8 @@ private class vwrCandidateUniversal: NSView { for (index, elementWidth) in elementWidths.enumerated() { let currentWidth = elementWidth let rctCandidateArea = NSRect( - x: accuWidth, y: 0.0, width: currentWidth + 1.0, - height: candidateTextHeight + cellPadding + x: accuWidth + 3.0, y: 3.0, width: currentWidth + 1.0 - 6.0, + height: candidateTextHeight + cellPadding - 6.0 ) let rctLabel = NSRect( x: accuWidth + cellPadding / 2 - 1, y: cellPadding / 2, width: keyLabelWidth, @@ -220,19 +231,19 @@ private class vwrCandidateUniversal: NSView { var activeCandidateIndexAttr = keyLabelAttrDict var activeCandidateAttr = candidateAttrDict if index == highlightedIndex { - let colorBlendAmount: CGFloat = IME.isDarkMode() ? 0.25 : 0 + let colorBlendAmount: CGFloat = IME.isDarkMode() ? 0.3 : 0 // The background color of the highlightened candidate switch IME.currentInputMode { case InputMode.imeModeCHS: NSColor.systemRed.blended( withFraction: colorBlendAmount, - of: NSColor.controlBackgroundColor + of: NSColor.black )! .setFill() case InputMode.imeModeCHT: NSColor.systemBlue.blended( withFraction: colorBlendAmount, - of: NSColor.controlBackgroundColor + of: NSColor.black )! .setFill() default: @@ -246,7 +257,24 @@ private class vwrCandidateUniversal: NSView { } else { NSColor.controlBackgroundColor.setFill() } - NSBezierPath.fill(rctCandidateArea) + if mgrPrefs.handleDefaultCandidateFontsByLangIdentifier { + switch IME.currentInputMode { + case InputMode.imeModeCHS: + if #available(macOS 12.0, *) { + activeCandidateAttr[.languageIdentifier] = "zh-Hans" as AnyObject + } + case InputMode.imeModeCHT: + if #available(macOS 12.0, *) { + activeCandidateAttr[.languageIdentifier] = + (mgrPrefs.shiftJISShinjitaiOutputEnabled || mgrPrefs.chineseConversionEnabled) + ? "ja" as AnyObject : "zh-Hant" as AnyObject + } + default: + break + } + } + let path: NSBezierPath = .init(roundedRect: rctCandidateArea, xRadius: 5, yRadius: 5) + path.fill() (keyLabels[index] as NSString).draw( in: rctLabel, withAttributes: activeCandidateIndexAttr ) @@ -352,10 +380,10 @@ public class ctlCandidateUniversal: ctlCandidate { candidateView.wantsLayer = true candidateView.layer?.borderColor = - NSColor.selectedMenuItemTextColor.withAlphaComponent(0.10).cgColor + NSColor.selectedMenuItemTextColor.withAlphaComponent(0.20).cgColor candidateView.layer?.borderWidth = 1.0 if #available(macOS 10.13, *) { - candidateView.layer?.cornerRadius = 6.0 + candidateView.layer?.cornerRadius = 8.0 } panel.contentView?.addSubview(candidateView) diff --git a/Source/UI/PrefUI/ctlPrefUI.swift b/Source/UI/PrefUI/ctlPrefUI.swift index 40464b82..e78588e0 100644 --- a/Source/UI/PrefUI/ctlPrefUI.swift +++ b/Source/UI/PrefUI/ctlPrefUI.swift @@ -15,6 +15,7 @@ class ctlPrefUI { private(set) var tabImageExperiences: NSImage! = NSImage(named: "PrefToolbar-Experiences") private(set) var tabImageDictionary: NSImage! = NSImage(named: "PrefToolbar-Dictionary") private(set) var tabImageKeyboard: NSImage! = NSImage(named: "PrefToolbar-Keyboard") + private(set) var tabImageDevZone: NSImage! = NSImage(named: "PrefToolbar-DevZone") init() { if #available(macOS 11.0, *) { @@ -30,6 +31,9 @@ class ctlPrefUI { tabImageKeyboard = NSImage( systemSymbolName: "keyboard.macwindow", accessibilityDescription: "Keyboard Preferences" ) + tabImageDevZone = NSImage( + systemSymbolName: "hand.raised.circle", accessibilityDescription: "DevZone Preferences" + ) } } @@ -63,6 +67,13 @@ class ctlPrefUI { ) { suiPrefPaneKeyboard() }, + Preferences.Pane( + identifier: Preferences.PaneIdentifier(rawValue: "DevZone"), + title: NSLocalizedString("DevZone", comment: ""), + toolbarIcon: tabImageDevZone + ) { + suiPrefPaneDevZone() + }, ], style: .toolbarItems ) diff --git a/Source/UI/PrefUI/suiPrefPaneDevZone.swift b/Source/UI/PrefUI/suiPrefPaneDevZone.swift new file mode 100644 index 00000000..2f18036e --- /dev/null +++ b/Source/UI/PrefUI/suiPrefPaneDevZone.swift @@ -0,0 +1,69 @@ +// Copyright (c) 2021 and onwards The vChewing Project (MIT-NTL License). +// ==================== +// This code is released under the MIT license (SPDX-License-Identifier: MIT) +// ... with NTL restriction stating that: +// No trademark license is granted to use the trade names, trademarks, service +// marks, or product names of Contributor, except as required to fulfill notice +// requirements defined in MIT License. + +import SwiftUI + +@available(macOS 10.15, *) +struct suiPrefPaneDevZone: View { + @State private var selUseIMKCandidateWindow: Bool = UserDefaults.standard.bool( + forKey: UserDef.kUseIMKCandidateWindow.rawValue) + @State private var selHandleDefaultCandidateFontsByLangIdentifier: Bool = UserDefaults.standard.bool( + forKey: UserDef.kHandleDefaultCandidateFontsByLangIdentifier.rawValue) + private let contentWidth: Double = { + switch mgrPrefs.appleLanguages[0] { + case "ja": + return 520 + default: + if mgrPrefs.appleLanguages[0].contains("zh-Han") { + return 480 + } else { + return 550 + } + } + }() + + var body: some View { + Preferences.Container(contentWidth: contentWidth) { + Preferences.Section(title: "", bottomDivider: true) { + Text( + LocalizedStringKey( + "Warning: This page is for testing future features. \nFeatures listed here may not work as expected.") + ) + .fixedSize(horizontal: false, vertical: true) + Divider() + Toggle( + LocalizedStringKey("Use IMK Candidate Window instead (will reboot the IME)"), + isOn: $selUseIMKCandidateWindow.onChange { + mgrPrefs.useIMKCandidateWindow = selUseIMKCandidateWindow + } + ) + Text(LocalizedStringKey("IMK candidate window is plagued with issues like failed selection keys.")) + .preferenceDescription().fixedSize(horizontal: false, vertical: true) + Toggle( + LocalizedStringKey("Use .langIdentifier to handle UI fonts in candidate window"), + isOn: $selHandleDefaultCandidateFontsByLangIdentifier.onChange { + mgrPrefs.handleDefaultCandidateFontsByLangIdentifier = selHandleDefaultCandidateFontsByLangIdentifier + } + ) + Text( + LocalizedStringKey( + "This only works since macOS 12 with non-IMK candidate window as an alternative wordaround of Apple Bug Report #FB10978412. Apple should patch that for macOS 11 and later." + ) + ) + .preferenceDescription().fixedSize(horizontal: false, vertical: true) + } + } + } +} + +@available(macOS 11.0, *) +struct suiPrefPaneDevZone_Previews: PreviewProvider { + static var previews: some View { + suiPrefPaneDevZone() + } +} diff --git a/Source/WindowControllers/ctlPrefWindow.swift b/Source/WindowControllers/ctlPrefWindow.swift index fe1d8d14..01d01f3a 100644 --- a/Source/WindowControllers/ctlPrefWindow.swift +++ b/Source/WindowControllers/ctlPrefWindow.swift @@ -18,6 +18,7 @@ extension NSToolbarItem.Identifier { fileprivate static let ofExperience = NSToolbarItem.Identifier(rawValue: "tabExperience") fileprivate static let ofDictionary = NSToolbarItem.Identifier(rawValue: "tabDictionary") fileprivate static let ofKeyboard = NSToolbarItem.Identifier(rawValue: "tabKeyboard") + fileprivate static let ofDevZone = NSToolbarItem.Identifier(rawValue: "tabDevZone") } // Please note that the class should be exposed using the same class name @@ -32,11 +33,13 @@ class ctlPrefWindow: NSWindowController { @IBOutlet var chkTrad2KangXi: NSButton! @IBOutlet var chkTrad2JISShinjitai: NSButton! @IBOutlet var lblCurrentlySpecifiedUserDataFolder: NSTextFieldCell! + @IBOutlet var tglControlDevZoneIMKCandidate: NSButton! @IBOutlet var vwrGeneral: NSView! @IBOutlet var vwrExperience: NSView! @IBOutlet var vwrDictionary: NSView! @IBOutlet var vwrKeyboard: NSView! + @IBOutlet var vwrDevZone: NSView! var currentLanguageSelectItem: NSMenuItem? @@ -236,6 +239,10 @@ class ctlPrefWindow: NSWindowController { } } + @IBAction func updateIMKCandidateEnableStatusAction(_: Any) { + NSApplication.shared.terminate(nil) + } + @IBAction func clickedWhetherIMEShouldNotFartToggleAction(_: Any) { clsSFX.beep() } @@ -329,15 +336,15 @@ extension ctlPrefWindow: NSToolbarDelegate { } func toolbarDefaultItemIdentifiers(_: NSToolbar) -> [NSToolbarItem.Identifier] { - [.ofGeneral, .ofExperience, .ofDictionary, .ofKeyboard] + [.ofGeneral, .ofExperience, .ofDictionary, .ofKeyboard, .ofDevZone] } func toolbarAllowedItemIdentifiers(_: NSToolbar) -> [NSToolbarItem.Identifier] { - [.ofGeneral, .ofExperience, .ofDictionary, .ofKeyboard] + [.ofGeneral, .ofExperience, .ofDictionary, .ofKeyboard, .ofDevZone] } func toolbarSelectableItemIdentifiers(_: NSToolbar) -> [NSToolbarItem.Identifier] { - [.ofGeneral, .ofExperience, .ofDictionary, .ofKeyboard] + [.ofGeneral, .ofExperience, .ofDictionary, .ofKeyboard, .ofDevZone] } @objc func showGeneralView(_: Any?) { @@ -360,6 +367,11 @@ extension ctlPrefWindow: NSToolbarDelegate { window?.toolbar?.selectedItemIdentifier = .ofKeyboard } + @objc func showDevZoneView(_: Any?) { + use(view: vwrDevZone) + window?.toolbar?.selectedItemIdentifier = .ofDevZone + } + func toolbar( _: NSToolbar, itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier, willBeInsertedIntoToolbar _: Bool @@ -413,6 +425,18 @@ extension ctlPrefWindow: NSToolbarDelegate { } item.action = #selector(showKeyboardView(_:)) + case .ofDevZone: + let title = NSLocalizedString("DevZone", comment: "") + item.label = title + if #available(macOS 11.0, *) { + item.image = NSImage( + systemSymbolName: "hand.raised.circle", accessibilityDescription: "DevZone Preferences" + ) + } else { + item.image = NSImage(named: "PrefToolbar-DevZone") + } + item.action = #selector(showDevZoneView(_:)) + default: return nil } diff --git a/Source/WindowNIBs/Base.lproj/frmPrefWindow.xib b/Source/WindowNIBs/Base.lproj/frmPrefWindow.xib index b9b3661b..1f8b3a0b 100644 --- a/Source/WindowNIBs/Base.lproj/frmPrefWindow.xib +++ b/Source/WindowNIBs/Base.lproj/frmPrefWindow.xib @@ -14,7 +14,9 @@ + + @@ -1054,5 +1056,92 @@ + + + + + + + + + Warning: This page is for testing future features. +Features listed here may not work as expected. + + + + + + + + + + + + + + + + + + + + + + + + + This only works since macOS 12 with non-IMK candidate window as an alternative wordaround of Apple Bug Report #FB10978412. Apple should patch that for macOS 11 and later. + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Source/WindowNIBs/en.lproj/frmPrefWindow.strings b/Source/WindowNIBs/en.lproj/frmPrefWindow.strings index ffdd4664..9be7c456 100644 --- a/Source/WindowNIBs/en.lproj/frmPrefWindow.strings +++ b/Source/WindowNIBs/en.lproj/frmPrefWindow.strings @@ -63,6 +63,9 @@ "jQC-12-UuK.ibShadowedObjectValues[0]" = "Item 1"; "jQC-12-UuK.ibShadowedObjectValues[1]" = "Item 2"; "jQC-12-UuK.ibShadowedObjectValues[2]" = "Item 3"; +"lblDevZoneCandidateFont.title" = "This only works since macOS 12 with non-IMK candidate window as an alternative wordaround of Apple Bug Report #FB10978412. Apple should patch that for macOS 11 and later."; +"lblDevZoneIMKCandidate.title" = "IMK candidate window is plagued with issues like failed selection keys."; +"lblDevZoneTitleDescription.title" = "Warning: This page is for testing future features. \nFeatures listed here may not work as expected."; "lblUpperCaseLetterKeyBehavior.title" = "Choose the behavior of Shift+Letter key with letter inputs."; "Parser11.title" = "Secondary Pinyin with Numeral Intonation"; "Parser12.title" = "Yale Pinyin with Numeral Intonation"; @@ -78,6 +81,8 @@ "rVQ-Hx-cGi.title" = "Japanese"; "s7u-Fm-dVg.title" = "Cycling Pages"; "shc-Nu-UsM.title" = "Show page buttons in candidate list"; +"tglDevZoneCandidateFont.title" = "Use .langIdentifier to handle UI fonts in candidate window"; +"tglDevZoneIMKCandidate.title" = "Use IMK Candidate Window instead (will reboot the IME)"; "TXr-FF-ehw.title" = "Traditional Chinese"; "ueU-Rz-a1C.title" = "Choose the behavior of (Shift+)Tab key in the candidate window."; "VdT-fw-7pQ.title" = "Debug Mode"; diff --git a/Source/WindowNIBs/ja.lproj/frmPrefWindow.strings b/Source/WindowNIBs/ja.lproj/frmPrefWindow.strings index 6246c14b..160876a7 100644 --- a/Source/WindowNIBs/ja.lproj/frmPrefWindow.strings +++ b/Source/WindowNIBs/ja.lproj/frmPrefWindow.strings @@ -63,6 +63,9 @@ "jQC-12-UuK.ibShadowedObjectValues[0]" = "Item 1"; "jQC-12-UuK.ibShadowedObjectValues[1]" = "Item 2"; "jQC-12-UuK.ibShadowedObjectValues[2]" = "Item 3"; +"lblDevZoneCandidateFont.title" = "これは Apple Bug Report #FB10978412 の臨時対策であり、macOS 12 からの macOS に効き、IMK 以外の候補陳列ウィンドウに作用する。Apple は macOS 11 からの macOS のために該当 Bug を修復すべきである。"; +"lblDevZoneIMKCandidate.title" = "IMK 候補陳列ウィンドウで言選り用キーは現時点で利用不可、尚他故障あり。"; +"lblDevZoneTitleDescription.title" = "警告:これからの新機能テストのために作ったページですから、\nここで陳列されている諸機能は予想通り動けるだと思わないでください。"; "lblUpperCaseLetterKeyBehavior.title" = "Shift+文字キーの行為をご指定ください。"; "Parser11.title" = "国音二式 (ローマ字+数字音調)"; "Parser12.title" = "イェール弁音 (ローマ字+数字音調)"; @@ -78,6 +81,8 @@ "rVQ-Hx-cGi.title" = "和語"; "s7u-Fm-dVg.title" = "ページ"; "shc-Nu-UsM.title" = "ページボタンを表示"; +"tglDevZoneCandidateFont.title" = "「.langIdentifier」を使って候補陳列ウィンドウのフォントを取り扱う"; +"tglDevZoneIMKCandidate.title" = "IMK 候補陳列ウィンドウを起用(入力アプリは自動的に再起動)"; "TXr-FF-ehw.title" = "繁体中国語"; "ueU-Rz-a1C.title" = "入力候補陳列での (Shift+)Tab キーの輪番切替対象をご指定ください。"; "VdT-fw-7pQ.title" = "欠陥辿着モード"; diff --git a/Source/WindowNIBs/zh-Hans.lproj/frmPrefWindow.strings b/Source/WindowNIBs/zh-Hans.lproj/frmPrefWindow.strings index 0653a16e..8d0f1877 100644 --- a/Source/WindowNIBs/zh-Hans.lproj/frmPrefWindow.strings +++ b/Source/WindowNIBs/zh-Hans.lproj/frmPrefWindow.strings @@ -63,6 +63,9 @@ "jQC-12-UuK.ibShadowedObjectValues[0]" = "Item 1"; "jQC-12-UuK.ibShadowedObjectValues[1]" = "Item 2"; "jQC-12-UuK.ibShadowedObjectValues[2]" = "Item 3"; +"lblDevZoneCandidateFont.title" = "该方法是 Apple Bug Report #FB10978412 的保守治疗方案,用来仅针对 macOS 12 开始的系统,且仅对非 IMK 选字窗起作用。Apple 应该对 macOS 11 开始的系统修复这个 Bug。"; +"lblDevZoneIMKCandidate.title" = "IMK 选字窗目前暂时无法正常使用选字键,并具其它未知故障。"; +"lblDevZoneTitleDescription.title" = "警告:该页面仅作未来功能测试所用。\n在此列出的功能并非处于完全可用之状态。"; "lblUpperCaseLetterKeyBehavior.title" = "指定 Shift+字母键 的行为。"; "Parser11.title" = "国音二式+数字标调"; "Parser12.title" = "耶鲁拼音+数字标调"; @@ -78,6 +81,8 @@ "rVQ-Hx-cGi.title" = "和语"; "s7u-Fm-dVg.title" = "轮替页面"; "shc-Nu-UsM.title" = "在选字窗内显示翻页按钮"; +"tglDevZoneCandidateFont.title" = "使用 .langIdentifier 来管理选字窗的预设介面字型"; +"tglDevZoneIMKCandidate.title" = "启用 IMK 选字窗(会自动重启输入法)"; "TXr-FF-ehw.title" = "繁体中文"; "ueU-Rz-a1C.title" = "指定 (Shift+)Tab 热键在选字窗内的轮替操作对象。"; "VdT-fw-7pQ.title" = "侦错模式"; diff --git a/Source/WindowNIBs/zh-Hant.lproj/frmPrefWindow.strings b/Source/WindowNIBs/zh-Hant.lproj/frmPrefWindow.strings index 31fca5da..50c4cc90 100644 --- a/Source/WindowNIBs/zh-Hant.lproj/frmPrefWindow.strings +++ b/Source/WindowNIBs/zh-Hant.lproj/frmPrefWindow.strings @@ -63,6 +63,9 @@ "jQC-12-UuK.ibShadowedObjectValues[0]" = "Item 1"; "jQC-12-UuK.ibShadowedObjectValues[1]" = "Item 2"; "jQC-12-UuK.ibShadowedObjectValues[2]" = "Item 3"; +"lblDevZoneCandidateFont.title" = "該方法是 Apple Bug Report #FB10978412 的保守治療方案,用來僅針對 macOS 12 開始的系統,且僅對非 IMK 選字窗起作用。Apple 應該對 macOS 11 開始的系統修復這個 Bug。"; +"lblDevZoneIMKCandidate.title" = "IMK 選字窗目前暫時無法正常使用選字鍵,併具其它未知故障。"; +"lblDevZoneTitleDescription.title" = "警告:該頁面僅作未來功能測試所用。\n在此列出的功能並非處於完全可用之狀態。"; "lblUpperCaseLetterKeyBehavior.title" = "指定 Shift+字母鍵 的行為。"; "Parser11.title" = "國音二式+數字標調"; "Parser12.title" = "耶魯拼音+數字標調"; @@ -78,6 +81,8 @@ "rVQ-Hx-cGi.title" = "和語"; "s7u-Fm-dVg.title" = "輪替頁面"; "shc-Nu-UsM.title" = "在選字窗內顯示翻頁按鈕"; +"tglDevZoneCandidateFont.title" = "使用 .langIdentifier 來管理選字窗的預設介面字型"; +"tglDevZoneIMKCandidate.title" = "啟用 IMK 選字窗(會自動重啟輸入法)"; "TXr-FF-ehw.title" = "繁體中文"; "ueU-Rz-a1C.title" = "指定 (Shift+)Tab 熱鍵在選字窗內的輪替操作對象。"; "VdT-fw-7pQ.title" = "偵錯模式"; diff --git a/Update-Info.plist b/Update-Info.plist index ebb02c01..9463db6d 100644 --- a/Update-Info.plist +++ b/Update-Info.plist @@ -3,9 +3,9 @@ CFBundleShortVersionString - 1.9.1 + 1.9.2 CFBundleVersion - 1991 + 1992 UpdateInfoEndpoint https://gitee.com/vchewing/vChewing-macOS/raw/main/Update-Info.plist UpdateInfoSite diff --git a/vChewing.pkgproj b/vChewing.pkgproj index 5f4a2a23..789a5002 100644 --- a/vChewing.pkgproj +++ b/vChewing.pkgproj @@ -726,7 +726,7 @@ USE_HFS+_COMPRESSION VERSION - 1.9.1 + 1.9.2 TYPE 0 diff --git a/vChewing.xcodeproj/project.pbxproj b/vChewing.xcodeproj/project.pbxproj index 5a015025..7c959c59 100644 --- a/vChewing.xcodeproj/project.pbxproj +++ b/vChewing.xcodeproj/project.pbxproj @@ -40,6 +40,7 @@ 5B62A35327AE89C400A19448 /* InputSourceHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A33127AE792F00A19448 /* InputSourceHelper.swift */; }; 5B73FB5E27B2BE1300E9BF49 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5B73FB6027B2BE1300E9BF49 /* InfoPlist.strings */; }; 5B782EC4280C243C007276DE /* KeyHandler_HandleCandidate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B782EC3280C243C007276DE /* KeyHandler_HandleCandidate.swift */; }; + 5B78EE0D28A562B4009456C1 /* suiPrefPaneDevZone.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B78EE0C28A562B4009456C1 /* suiPrefPaneDevZone.swift */; }; 5B7BC4B027AFFBE800F66C24 /* frmPrefWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5B7BC4AE27AFFBE800F66C24 /* frmPrefWindow.xib */; }; 5B7F225D2808501000DDD3CB /* KeyHandler_HandleInput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B7F225C2808501000DDD3CB /* KeyHandler_HandleInput.swift */; }; 5B84579E2871AD2200C93B01 /* convdict.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5B84579C2871AD2200C93B01 /* convdict.plist */; }; @@ -246,6 +247,7 @@ 5B73FB5427B2BD6900E9BF49 /* PhraseEditor-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "PhraseEditor-Info.plist"; path = "UserPhraseEditor/PhraseEditor-Info.plist"; sourceTree = SOURCE_ROOT; }; 5B73FB5F27B2BE1300E9BF49 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 5B782EC3280C243C007276DE /* KeyHandler_HandleCandidate.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = KeyHandler_HandleCandidate.swift; sourceTree = ""; tabWidth = 2; usesTabs = 0; }; + 5B78EE0C28A562B4009456C1 /* suiPrefPaneDevZone.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = suiPrefPaneDevZone.swift; sourceTree = ""; }; 5B7BC4AF27AFFBE800F66C24 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/frmPrefWindow.xib; sourceTree = ""; }; 5B7BC4B227AFFC0B00F66C24 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/frmPrefWindow.strings; sourceTree = ""; }; 5B7F225C2808501000DDD3CB /* KeyHandler_HandleInput.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = KeyHandler_HandleInput.swift; sourceTree = ""; tabWidth = 2; usesTabs = 0; }; @@ -652,6 +654,7 @@ isa = PBXGroup; children = ( 5BA9FD0C27FEDB6B002DE248 /* ctlPrefUI.swift */, + 5B78EE0C28A562B4009456C1 /* suiPrefPaneDevZone.swift */, 5BA9FD0E27FEDB6B002DE248 /* suiPrefPaneDictionary.swift */, 5BA9FD0D27FEDB6B002DE248 /* suiPrefPaneExperience.swift */, 5BA9FD0A27FEDB6B002DE248 /* suiPrefPaneGeneral.swift */, @@ -1184,6 +1187,7 @@ 5B3A87BC28597CDB0090E163 /* LMSymbolNode.swift in Sources */, 5BA9FD4327FEF3C8002DE248 /* Preferences.swift in Sources */, 5BA9FD4427FEF3C8002DE248 /* SegmentedControlStyleViewController.swift in Sources */, + 5B78EE0D28A562B4009456C1 /* suiPrefPaneDevZone.swift in Sources */, D47F7DCE278BFB57002F9DD7 /* ctlPrefWindow.swift in Sources */, 5BD0113D2818543900609769 /* KeyHandler_Core.swift in Sources */, 5B2170E4289FACAD00BE7304 /* 2_Walker.swift in Sources */, @@ -1413,7 +1417,7 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1991; + CURRENT_PROJECT_VERSION = 1992; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_PREPROCESSOR_DEFINITIONS = ( @@ -1423,7 +1427,7 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.9.1; + MARKETING_VERSION = 1.9.2; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewingTests; @@ -1452,13 +1456,13 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1991; + CURRENT_PROJECT_VERSION = 1992; 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; - MARKETING_VERSION = 1.9.1; + MARKETING_VERSION = 1.9.2; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewingTests; @@ -1489,7 +1493,7 @@ CODE_SIGN_IDENTITY = "-"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1991; + CURRENT_PROJECT_VERSION = 1992; DEAD_CODE_STRIPPING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; @@ -1510,7 +1514,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MARKETING_VERSION = 1.9.1; + MARKETING_VERSION = 1.9.2; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewing.vChewingPhraseEditor; @@ -1539,7 +1543,7 @@ CODE_SIGN_IDENTITY = "-"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1991; + CURRENT_PROJECT_VERSION = 1992; DEAD_CODE_STRIPPING = YES; ENABLE_NS_ASSERTIONS = NO; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -1556,7 +1560,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MARKETING_VERSION = 1.9.1; + MARKETING_VERSION = 1.9.2; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewing.vChewingPhraseEditor; @@ -1670,7 +1674,7 @@ CODE_SIGN_IDENTITY = "-"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1991; + CURRENT_PROJECT_VERSION = 1992; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = ""; @@ -1698,7 +1702,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MARKETING_VERSION = 1.9.1; + MARKETING_VERSION = 1.9.2; ONLY_ACTIVE_ARCH = YES; PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.inputmethod.vChewing; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -1725,7 +1729,7 @@ CODE_SIGN_IDENTITY = "-"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1991; + CURRENT_PROJECT_VERSION = 1992; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = ""; @@ -1747,7 +1751,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MARKETING_VERSION = 1.9.1; + MARKETING_VERSION = 1.9.2; PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.inputmethod.vChewing; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1769,7 +1773,7 @@ CODE_SIGN_IDENTITY = "-"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1991; + CURRENT_PROJECT_VERSION = 1992; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = ""; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -1789,7 +1793,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MARKETING_VERSION = 1.9.1; + MARKETING_VERSION = 1.9.2; ONLY_ACTIVE_ARCH = YES; PRODUCT_BUNDLE_IDENTIFIER = "org.atelierInmu.vChewing.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -1811,7 +1815,7 @@ CODE_SIGN_IDENTITY = "-"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1991; + CURRENT_PROJECT_VERSION = 1992; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = ""; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -1825,7 +1829,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MARKETING_VERSION = 1.9.1; + MARKETING_VERSION = 1.9.2; PRODUCT_BUNDLE_IDENTIFIER = "org.atelierInmu.vChewing.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = "";