2.6.0 // Steam support, etc. Merge PR #131 from upd/2.6.0
This commit is contained in:
commit
da9cccbb2a
2
AUTHORS
2
AUTHORS
|
@ -17,7 +17,7 @@ $ Contributors and volunteers of the upstream repo, having no responsibility in
|
||||||
- Zonble Yang:
|
- Zonble Yang:
|
||||||
- McBopomofo for macOS 2.x architect.
|
- McBopomofo for macOS 2.x architect.
|
||||||
- Voltaire candidate window MK2 (massively modified as MK3 in vChewing by Shiki Suen).
|
- Voltaire candidate window MK2 (massively modified as MK3 in vChewing by Shiki Suen).
|
||||||
- Notifier window and Tooltip UI.
|
- Notifier window.
|
||||||
- App-style installer (only preserved for developer purposes).
|
- App-style installer (only preserved for developer purposes).
|
||||||
- mgrPrefs (userdefaults manager).
|
- mgrPrefs (userdefaults manager).
|
||||||
- Mengjuei Hsieh:
|
- Mengjuei Hsieh:
|
||||||
|
|
|
@ -101,6 +101,7 @@ class AppDelegate: NSWindowController, NSApplicationDelegate {
|
||||||
window.standardWindowButton(.closeButton)?.isHidden = true
|
window.standardWindowButton(.closeButton)?.isHidden = true
|
||||||
window.standardWindowButton(.miniaturizeButton)?.isHidden = true
|
window.standardWindowButton(.miniaturizeButton)?.isHidden = true
|
||||||
window.standardWindowButton(.zoomButton)?.isHidden = true
|
window.standardWindowButton(.zoomButton)?.isHidden = true
|
||||||
|
window.titlebarAppearsTransparent = true
|
||||||
|
|
||||||
if FileManager.default.fileExists(
|
if FileManager.default.fileExists(
|
||||||
atPath: kTargetPartialPath)
|
atPath: kTargetPartialPath)
|
||||||
|
|
|
@ -198,7 +198,7 @@ DQ
|
||||||
</textField>
|
</textField>
|
||||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="XLb-mv-73s">
|
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="XLb-mv-73s">
|
||||||
<rect key="frame" x="89" y="387" width="431" height="15"/>
|
<rect key="frame" x="89" y="387" width="431" height="15"/>
|
||||||
<textFieldCell key="cell" selectable="YES" title="Placeholder for detailed credits." id="VW8-s5-Wpn">
|
<textFieldCell key="cell" title="Placeholder for detailed credits." id="VW8-s5-Wpn">
|
||||||
<font key="font" size="12" name="Tahoma"/>
|
<font key="font" size="12" name="Tahoma"/>
|
||||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
@ -220,7 +220,7 @@ DQ
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="width" constant="356" id="pu3-zr-hJy"/>
|
<constraint firstAttribute="width" constant="356" id="pu3-zr-hJy"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<textFieldCell key="cell" selectable="YES" id="Q9M-ni-kUM">
|
<textFieldCell key="cell" id="Q9M-ni-kUM">
|
||||||
<font key="font" size="12" name="Tahoma"/>
|
<font key="font" size="12" name="Tahoma"/>
|
||||||
<string key="title">DISCLAIMER: The vChewing project, having no relationship of cooperation or affiliation with the OpenVanilla project, is not responsible for the phrase database shipped in the original McBopomofo project. Certain geopolitical and ideological contents, which are potentially harmful to the global spread of this software, are not included in vChewing official phrase database.</string>
|
<string key="title">DISCLAIMER: The vChewing project, having no relationship of cooperation or affiliation with the OpenVanilla project, is not responsible for the phrase database shipped in the original McBopomofo project. Certain geopolitical and ideological contents, which are potentially harmful to the global spread of this software, are not included in vChewing official phrase database.</string>
|
||||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
|
|
@ -65,9 +65,11 @@ public class NSAttributedTextView: NSView {
|
||||||
let isVertical: Bool = !(direction == .horizontal)
|
let isVertical: Bool = !(direction == .horizontal)
|
||||||
newAttributes[.verticalGlyphForm] = isVertical
|
newAttributes[.verticalGlyphForm] = isVertical
|
||||||
let newStyle: NSMutableParagraphStyle = newAttributes[.paragraphStyle] as! NSMutableParagraphStyle
|
let newStyle: NSMutableParagraphStyle = newAttributes[.paragraphStyle] as! NSMutableParagraphStyle
|
||||||
newStyle.lineSpacing = isVertical ? (fontSize / -2) : fontSize * 0.1
|
if #available(macOS 10.13, *) {
|
||||||
newStyle.maximumLineHeight = fontSize
|
newStyle.lineSpacing = isVertical ? (fontSize / -2) : fontSize * 0.1
|
||||||
newStyle.minimumLineHeight = fontSize
|
newStyle.maximumLineHeight = fontSize * 1.1
|
||||||
|
newStyle.minimumLineHeight = fontSize * 1.1
|
||||||
|
}
|
||||||
newAttributes[.paragraphStyle] = newStyle
|
newAttributes[.paragraphStyle] = newStyle
|
||||||
var text: String = text ?? ""
|
var text: String = text ?? ""
|
||||||
if !(direction == .horizontal) {
|
if !(direction == .horizontal) {
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 6dba7237957681bfa4c623ab5689248cc02bc7e6
|
Subproject commit eeff2e3f7073873c07b4011717e32430db01227f
|
|
@ -25,6 +25,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
|
||||||
// let vChewingKeyLayoutBundle = Bundle.init(path: URL(fileURLWithPath: Bundle.main.resourcePath ?? "").appendingPathComponent("vChewingKeyLayout.bundle").path)
|
// let vChewingKeyLayoutBundle = Bundle.init(path: URL(fileURLWithPath: Bundle.main.resourcePath ?? "").appendingPathComponent("vChewingKeyLayout.bundle").path)
|
||||||
|
|
||||||
@IBOutlet var window: NSWindow?
|
@IBOutlet var window: NSWindow?
|
||||||
|
private var ctlClientListMgrInstance: ctlClientListMgr?
|
||||||
private var ctlPrefWindowInstance: ctlPrefWindow?
|
private var ctlPrefWindowInstance: ctlPrefWindow?
|
||||||
private var ctlAboutWindowInstance: ctlAboutWindow? // New About Window
|
private var ctlAboutWindowInstance: ctlAboutWindow? // New About Window
|
||||||
public lazy var folderMonitor = FolderMonitor(
|
public lazy var folderMonitor = FolderMonitor(
|
||||||
|
@ -80,6 +81,17 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
|
||||||
folderMonitor.startMonitoring()
|
folderMonitor.startMonitoring()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func showClientListMgr() {
|
||||||
|
if ctlClientListMgrInstance == nil {
|
||||||
|
ctlClientListMgrInstance = ctlClientListMgr.init(windowNibName: "frmClientListMgr")
|
||||||
|
}
|
||||||
|
ctlClientListMgrInstance?.window?.center()
|
||||||
|
ctlClientListMgrInstance?.window?.orderFrontRegardless() // 逼著屬性視窗往最前方顯示
|
||||||
|
ctlClientListMgrInstance?.window?.level = .statusBar
|
||||||
|
ctlClientListMgrInstance?.window?.titlebarAppearsTransparent = true
|
||||||
|
NSApp.setActivationPolicy(.accessory)
|
||||||
|
}
|
||||||
|
|
||||||
func showPreferences() {
|
func showPreferences() {
|
||||||
if ctlPrefWindowInstance == nil {
|
if ctlPrefWindowInstance == nil {
|
||||||
ctlPrefWindowInstance = ctlPrefWindow.init(windowNibName: "frmPrefWindow")
|
ctlPrefWindowInstance = ctlPrefWindow.init(windowNibName: "frmPrefWindow")
|
||||||
|
@ -99,6 +111,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
|
||||||
ctlAboutWindowInstance?.window?.center()
|
ctlAboutWindowInstance?.window?.center()
|
||||||
ctlAboutWindowInstance?.window?.orderFrontRegardless() // 逼著關於視窗往最前方顯示
|
ctlAboutWindowInstance?.window?.orderFrontRegardless() // 逼著關於視窗往最前方顯示
|
||||||
ctlAboutWindowInstance?.window?.level = .statusBar
|
ctlAboutWindowInstance?.window?.level = .statusBar
|
||||||
|
ctlAboutWindowInstance?.window?.titlebarAppearsTransparent = true
|
||||||
NSApp.setActivationPolicy(.accessory)
|
NSApp.setActivationPolicy(.accessory)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,6 +113,7 @@ extension IMEState {
|
||||||
// 注意資料的設定順序,一定得先設定 displayTextSegments。
|
// 注意資料的設定順序,一定得先設定 displayTextSegments。
|
||||||
result.data.displayTextSegments = displayTextSegments
|
result.data.displayTextSegments = displayTextSegments
|
||||||
result.data.cursor = cursor
|
result.data.cursor = cursor
|
||||||
|
result.data.marker = cursor
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,13 +9,16 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public struct StateData {
|
public struct StateData {
|
||||||
var displayedText: String = "" {
|
var displayedText: String = ""
|
||||||
didSet {
|
var displayedTextConverted: String {
|
||||||
let result = IME.kanjiConversionIfRequired(displayedText)
|
/// 先做繁簡轉換
|
||||||
if result.utf16.count == displayedText.utf16.count, result.count == displayedText.count {
|
var result = IME.kanjiConversionIfRequired(displayedText)
|
||||||
displayedText = result
|
if result.utf16.count != displayedText.utf16.count
|
||||||
}
|
|| result.count != displayedText.count
|
||||||
|
{
|
||||||
|
result = displayedText
|
||||||
}
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Cursor & Marker & Range for UTF8
|
// MARK: Cursor & Marker & Range for UTF8
|
||||||
|
@ -86,7 +89,7 @@ public struct StateData {
|
||||||
var attributedStringNormal: NSAttributedString {
|
var attributedStringNormal: NSAttributedString {
|
||||||
/// 考慮到因為滑鼠點擊等其它行為導致的組字區內容遞交情況,
|
/// 考慮到因為滑鼠點擊等其它行為導致的組字區內容遞交情況,
|
||||||
/// 這裡對組字區內容也加上康熙字轉換或者 JIS 漢字轉換處理。
|
/// 這裡對組字區內容也加上康熙字轉換或者 JIS 漢字轉換處理。
|
||||||
let attributedString = NSMutableAttributedString(string: displayedText)
|
let attributedString = NSMutableAttributedString(string: displayedTextConverted)
|
||||||
var newBegin = 0
|
var newBegin = 0
|
||||||
for (i, neta) in displayTextSegments.enumerated() {
|
for (i, neta) in displayTextSegments.enumerated() {
|
||||||
attributedString.setAttributes(
|
attributedString.setAttributes(
|
||||||
|
@ -104,7 +107,7 @@ public struct StateData {
|
||||||
var attributedStringMarking: NSAttributedString {
|
var attributedStringMarking: NSAttributedString {
|
||||||
/// 考慮到因為滑鼠點擊等其它行為導致的組字區內容遞交情況,
|
/// 考慮到因為滑鼠點擊等其它行為導致的組字區內容遞交情況,
|
||||||
/// 這裡對組字區內容也加上康熙字轉換或者 JIS 漢字轉換處理。
|
/// 這裡對組字區內容也加上康熙字轉換或者 JIS 漢字轉換處理。
|
||||||
let attributedString = NSMutableAttributedString(string: displayedText)
|
let attributedString = NSMutableAttributedString(string: displayedTextConverted)
|
||||||
let end = u16MarkedRange.upperBound
|
let end = u16MarkedRange.upperBound
|
||||||
|
|
||||||
attributedString.setAttributes(
|
attributedString.setAttributes(
|
||||||
|
@ -130,7 +133,7 @@ public struct StateData {
|
||||||
],
|
],
|
||||||
range: NSRange(
|
range: NSRange(
|
||||||
location: end,
|
location: end,
|
||||||
length: displayedText.utf16.count - end
|
length: displayedTextConverted.utf16.count - end
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return attributedString
|
return attributedString
|
||||||
|
|
|
@ -438,3 +438,52 @@ public class KeyHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Components for Popup Composition Buffer (PCB) Window.
|
||||||
|
|
||||||
|
/// 組字區文字上限。
|
||||||
|
/// - Remark: 該選項僅對不支援 IMKTextInput 協定的應用有用,就不交給 mgrPrefs 了。
|
||||||
|
private let compositorWidthLimit = 20
|
||||||
|
|
||||||
|
extension KeyHandler {
|
||||||
|
/// 在爬取組字結果之前,先將即將從組字區溢出的內容遞交出去。
|
||||||
|
///
|
||||||
|
/// 在理想狀況之下,組字區多長都無所謂。但是,螢幕浮動組字窗的尺寸是有限的。
|
||||||
|
/// 於是,有必要限定組字區的長度。超過該長度的內容會在爬軌之前先遞交出去,
|
||||||
|
/// 使其不再記入最大相似度估算的估算對象範圍。
|
||||||
|
/// 用比較形象且生動卻有點噁心的解釋的話,蒼蠅一邊吃一邊屙。
|
||||||
|
var commitOverflownComposition: String {
|
||||||
|
guard !compositor.walkedNodes.isEmpty,
|
||||||
|
compositor.width > compositorWidthLimit,
|
||||||
|
let identifier = delegate?.clientBundleIdentifier,
|
||||||
|
mgrPrefs.clientsIMKTextInputIncapable.contains(identifier)
|
||||||
|
else {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
// 回頭在這裡插上對 Steam 的 Client Identifier 的要求。
|
||||||
|
var textToCommit = ""
|
||||||
|
while compositor.width > compositorWidthLimit {
|
||||||
|
var delta = compositor.width - compositorWidthLimit
|
||||||
|
let node = compositor.walkedNodes[0]
|
||||||
|
if node.isReadingMismatched {
|
||||||
|
delta = node.keyArray.count
|
||||||
|
textToCommit += node.currentPair.value
|
||||||
|
} else {
|
||||||
|
delta = min(delta, node.keyArray.count)
|
||||||
|
textToCommit += node.currentPair.value.charComponents[0..<delta].joined()
|
||||||
|
}
|
||||||
|
let newCursor = max(compositor.cursor - delta, 0)
|
||||||
|
compositor.cursor = 0
|
||||||
|
if !node.isReadingMismatched {
|
||||||
|
consolidateCursorContext(with: node.currentPair)
|
||||||
|
}
|
||||||
|
// 威注音不支援 Bigram,所以無須考慮前後節點「是否需要鞏固」。
|
||||||
|
for _ in 0..<delta {
|
||||||
|
compositor.dropKey(direction: .front)
|
||||||
|
}
|
||||||
|
compositor.cursor = newCursor
|
||||||
|
walk()
|
||||||
|
}
|
||||||
|
return textToCommit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -111,6 +111,9 @@ extension KeyHandler {
|
||||||
// 讓組字器反爬軌格。
|
// 讓組字器反爬軌格。
|
||||||
walk()
|
walk()
|
||||||
|
|
||||||
|
// 一邊吃一邊屙(僅對位列黑名單的 App 用這招限制組字區長度)。
|
||||||
|
let textToCommit = commitOverflownComposition
|
||||||
|
|
||||||
// 看看半衰記憶模組是否會對目前的狀態給出自動選字建議。
|
// 看看半衰記憶模組是否會對目前的狀態給出自動選字建議。
|
||||||
fetchSuggestionsFromUOM(apply: true)
|
fetchSuggestionsFromUOM(apply: true)
|
||||||
|
|
||||||
|
@ -118,7 +121,8 @@ extension KeyHandler {
|
||||||
composer.clear()
|
composer.clear()
|
||||||
|
|
||||||
// 再以回呼組字狀態的方式來執行 updateClientdisplayedText()。
|
// 再以回呼組字狀態的方式來執行 updateClientdisplayedText()。
|
||||||
let inputting = buildInputtingState
|
var inputting = buildInputtingState
|
||||||
|
inputting.textToCommit = textToCommit
|
||||||
stateCallback(inputting)
|
stateCallback(inputting)
|
||||||
|
|
||||||
/// 逐字選字模式的處理。
|
/// 逐字選字模式的處理。
|
||||||
|
|
|
@ -22,15 +22,19 @@ extension NSEvent {
|
||||||
isARepeat: Bool? = nil,
|
isARepeat: Bool? = nil,
|
||||||
keyCode: UInt16? = nil
|
keyCode: UInt16? = nil
|
||||||
) -> NSEvent? {
|
) -> NSEvent? {
|
||||||
NSEvent.keyEvent(
|
let oldChars: String = {
|
||||||
|
if self.type == .flagsChanged { return "" }
|
||||||
|
return self.characters ?? ""
|
||||||
|
}()
|
||||||
|
return NSEvent.keyEvent(
|
||||||
with: type ?? self.type,
|
with: type ?? self.type,
|
||||||
location: location ?? locationInWindow,
|
location: location ?? locationInWindow,
|
||||||
modifierFlags: modifierFlags ?? self.modifierFlags,
|
modifierFlags: modifierFlags ?? self.modifierFlags,
|
||||||
timestamp: timestamp ?? self.timestamp,
|
timestamp: timestamp ?? self.timestamp,
|
||||||
windowNumber: windowNumber ?? self.windowNumber,
|
windowNumber: windowNumber ?? self.windowNumber,
|
||||||
context: nil,
|
context: nil,
|
||||||
characters: characters ?? self.characters ?? "",
|
characters: characters ?? oldChars,
|
||||||
charactersIgnoringModifiers: charactersIgnoringModifiers ?? self.characters ?? "",
|
charactersIgnoringModifiers: charactersIgnoringModifiers ?? characters ?? oldChars,
|
||||||
isARepeat: isARepeat ?? self.isARepeat,
|
isARepeat: isARepeat ?? self.isARepeat,
|
||||||
keyCode: keyCode ?? self.keyCode
|
keyCode: keyCode ?? self.keyCode
|
||||||
)
|
)
|
||||||
|
@ -81,6 +85,8 @@ extension NSEvent: InputSignalProtocol {
|
||||||
}
|
}
|
||||||
|
|
||||||
public var charCode: UInt16 {
|
public var charCode: UInt16 {
|
||||||
|
guard type != .flagsChanged else { return 0 }
|
||||||
|
guard characters != nil else { return 0 }
|
||||||
// 這裡不用「count > 0」,因為該整數變數只要「!isEmpty」那就必定滿足這個條件。
|
// 這裡不用「count > 0」,因為該整數變數只要「!isEmpty」那就必定滿足這個條件。
|
||||||
guard !text.isEmpty else { return 0 }
|
guard !text.isEmpty else { return 0 }
|
||||||
let scalars = text.unicodeScalars
|
let scalars = text.unicodeScalars
|
||||||
|
|
|
@ -16,59 +16,9 @@ extension ctlInputMethod {
|
||||||
/// - Parameter event: 由 IMK 選字窗接收的裝置操作輸入事件。
|
/// - Parameter event: 由 IMK 選字窗接收的裝置操作輸入事件。
|
||||||
/// - Returns: 回「`true`」以將該案件已攔截處理的訊息傳遞給 IMK;回「`false`」則放行、不作處理。
|
/// - Returns: 回「`true`」以將該案件已攔截處理的訊息傳遞給 IMK;回「`false`」則放行、不作處理。
|
||||||
func commonEventHandler(_ event: NSEvent) -> Bool {
|
func commonEventHandler(_ event: NSEvent) -> Bool {
|
||||||
// 用 Shift 開關半形英數模式,僅對 macOS 10.15 及之後的 macOS 有效。
|
|
||||||
let shouldUseHandle: Bool = {
|
|
||||||
switch mgrPrefs.shiftKeyAccommodationBehavior {
|
|
||||||
case 0: return false
|
|
||||||
case 1: return IME.arrClientShiftHandlingExceptionList.contains(clientBundleIdentifier)
|
|
||||||
case 2: return true
|
|
||||||
default: return false
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
if #available(macOS 10.15, *) {
|
|
||||||
if ShiftKeyUpChecker.check(event), !mgrPrefs.disableShiftTogglingAlphanumericalMode {
|
|
||||||
if !shouldUseHandle || (!rencentKeyHandledByKeyHandler && shouldUseHandle) {
|
|
||||||
NotifierController.notify(
|
|
||||||
message: NSLocalizedString("Alphanumerical Mode", comment: "") + "\n"
|
|
||||||
+ (toggleASCIIMode()
|
|
||||||
? NSLocalizedString("NotificationSwitchON", comment: "")
|
|
||||||
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if shouldUseHandle {
|
|
||||||
rencentKeyHandledByKeyHandler = false
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 沒有文字輸入客體的話,就不要再往下處理了。
|
|
||||||
guard client() != nil else { return false }
|
|
||||||
|
|
||||||
var event = event
|
|
||||||
// 使 NSEvent 自翻譯,這樣可以讓 Emacs NSEvent 變成標準 NSEvent。
|
|
||||||
if event.isEmacsKey {
|
|
||||||
let verticalProcessing =
|
|
||||||
(state.isCandidateContainer)
|
|
||||||
? ctlInputMethod.isVerticalCandidateSituation : ctlInputMethod.isVerticalTypingSituation
|
|
||||||
event = event.convertFromEmacKeyEvent(isVerticalContext: verticalProcessing)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 這裡仍舊需要判斷 flags。之前使輸入法狀態卡住無法敲漢字的問題已在 KeyHandler 內修復。
|
|
||||||
/// 這裡不判斷 flags 的話,用方向鍵前後定位光標之後,再次試圖觸發組字區時、反而會在首次按鍵時失敗。
|
|
||||||
/// 同時注意:必須在 event.type == .flagsChanged 結尾插入 return false,
|
|
||||||
/// 否則,每次處理這種判斷時都會觸發 NSInternalInconsistencyException。
|
|
||||||
if event.type == .flagsChanged { return false }
|
|
||||||
|
|
||||||
// 準備修飾鍵,用來判定要新增的詞彙是否需要賦以非常低的權重。
|
|
||||||
ctlInputMethod.areWeNerfing = event.modifierFlags.contains([.shift, .command])
|
|
||||||
|
|
||||||
// 無法列印的訊號輸入,一概不作處理。
|
// 無法列印的訊號輸入,一概不作處理。
|
||||||
// 這個過程不能放在 KeyHandler 內,否則不會起作用。
|
// 這個過程不能放在 KeyHandler 內,否則不會起作用。
|
||||||
if !event.charCode.isPrintable {
|
if !event.charCode.isPrintable { return false }
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 將按鍵行為與當前輸入法狀態結合起來、交給按鍵調度模組來處理。
|
/// 將按鍵行為與當前輸入法狀態結合起來、交給按鍵調度模組來處理。
|
||||||
/// 再根據返回的 result bool 數值來告知 IMK「這個按鍵事件是被處理了還是被放行了」。
|
/// 再根據返回的 result bool 數值來告知 IMK「這個按鍵事件是被處理了還是被放行了」。
|
||||||
|
@ -78,9 +28,43 @@ extension ctlInputMethod {
|
||||||
} errorCallback: {
|
} errorCallback: {
|
||||||
clsSFX.beep()
|
clsSFX.beep()
|
||||||
}
|
}
|
||||||
if shouldUseHandle {
|
|
||||||
rencentKeyHandledByKeyHandler = result
|
|
||||||
}
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 完成 handle() 函式本該完成的內容,但專門處理與 IMK 選字窗有關的判斷語句。
|
||||||
|
/// 這樣分開處理很有必要,不然 handle() 函式會陷入無限迴圈。
|
||||||
|
/// - Parameter event: 由 IMK 選字窗接收的裝置操作輸入事件。
|
||||||
|
/// - Returns: 回「`true`」以將該案件已攔截處理的訊息傳遞給 IMK;回「`false`」則放行、不作處理。
|
||||||
|
func imkCandidatesEventHandler(event eventToDeal: NSEvent) -> Bool? {
|
||||||
|
// IMK 選字窗處理,當且僅當啟用了 IMK 選字窗的時候才會生效。
|
||||||
|
// 這樣可以讓 interpretKeyEvents() 函式自行判斷:
|
||||||
|
// - 是就地交給 super.interpretKeyEvents() 處理?
|
||||||
|
// - 還是藉由 delegate 扔回 ctlInputMethod 給 KeyHandler 處理?
|
||||||
|
if let imkCandidates = ctlInputMethod.ctlCandidateCurrent as? ctlCandidateIMK, imkCandidates.visible {
|
||||||
|
let event: NSEvent = ctlCandidateIMK.replaceNumPadKeyCodes(target: eventToDeal) ?? eventToDeal
|
||||||
|
|
||||||
|
// Shift+Enter 是個特殊情形,不提前攔截處理的話、會有垃圾參數傳給 delegate 的 keyHandler 從而崩潰。
|
||||||
|
// 所以這裡直接將 Shift Flags 清空。
|
||||||
|
if event.isShiftHold, event.isEnter {
|
||||||
|
guard let newEvent = event.reinitiate(modifierFlags: []) else {
|
||||||
|
NSSound.beep()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
imkCandidates.interpretKeyEvents([newEvent])
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 聯想詞選字。
|
||||||
|
if let newChar = ctlCandidateIMK.defaultIMKSelectionKey[event.keyCode],
|
||||||
|
event.isShiftHold, isAssociatedPhrasesState,
|
||||||
|
let newEvent = event.reinitiate(modifierFlags: [], characters: newChar)
|
||||||
|
{
|
||||||
|
imkCandidates.handleKeyboardEvent(newEvent)
|
||||||
|
}
|
||||||
|
|
||||||
|
imkCandidates.interpretKeyEvents([event])
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,9 +27,12 @@ class ctlInputMethod: IMKInputController {
|
||||||
static var ctlCandidateCurrent: ctlCandidateProtocol =
|
static var ctlCandidateCurrent: ctlCandidateProtocol =
|
||||||
mgrPrefs.useIMKCandidateWindow ? ctlCandidateIMK.init(.horizontal) : ctlCandidateUniversal.init(.horizontal)
|
mgrPrefs.useIMKCandidateWindow ? ctlCandidateIMK.init(.horizontal) : ctlCandidateUniversal.init(.horizontal)
|
||||||
|
|
||||||
/// 工具提示視窗的副本,每次都重新初始化。
|
/// 工具提示視窗的共用副本。
|
||||||
static var tooltipInstance = ctlTooltip()
|
static var tooltipInstance = ctlTooltip()
|
||||||
|
|
||||||
|
/// 浮動組字窗的共用副本。
|
||||||
|
static var popupCompositionBuffer = ctlPopupCompositionBuffer()
|
||||||
|
|
||||||
// MARK: -
|
// MARK: -
|
||||||
|
|
||||||
/// 當前這個 ctlInputMethod 副本是否處於英數輸入模式(滯後項)。
|
/// 當前這個 ctlInputMethod 副本是否處於英數輸入模式(滯後項)。
|
||||||
|
@ -57,7 +60,7 @@ class ctlInputMethod: IMKInputController {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `handle(event:)` 會利用這個參數判定某次 Shift 按鍵是否用來切換中英文輸入。
|
/// `handle(event:)` 會利用這個參數判定某次 Shift 按鍵是否用來切換中英文輸入。
|
||||||
var rencentKeyHandledByKeyHandler = false
|
var rencentKeyHandledByKeyHandlerEtc = false
|
||||||
|
|
||||||
// MARK: - 工具函式
|
// MARK: - 工具函式
|
||||||
|
|
||||||
|
@ -115,18 +118,7 @@ class ctlInputMethod: IMKInputController {
|
||||||
keyHandler.clear() // 這句不要砍,因為後面 handle State.Empty() 不一定執行。
|
keyHandler.clear() // 這句不要砍,因為後面 handle State.Empty() 不一定執行。
|
||||||
keyHandler.ensureParser()
|
keyHandler.ensureParser()
|
||||||
|
|
||||||
if isASCIIMode {
|
if isASCIIMode, mgrPrefs.disableShiftTogglingAlphanumericalMode { isASCIIMode = false }
|
||||||
if mgrPrefs.disableShiftTogglingAlphanumericalMode {
|
|
||||||
isASCIIMode = false
|
|
||||||
} else {
|
|
||||||
NotifierController.notify(
|
|
||||||
message: NSLocalizedString("Alphanumerical Mode", comment: "") + "\n"
|
|
||||||
+ (isASCIIMode
|
|
||||||
? NSLocalizedString("NotificationSwitchON", comment: "")
|
|
||||||
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 必須加上下述條件,否則會在每次切換至輸入法本體的視窗(比如偏好設定視窗)時會卡死。
|
/// 必須加上下述條件,否則會在每次切換至輸入法本體的視窗(比如偏好設定視窗)時會卡死。
|
||||||
/// 這是很多 macOS 副廠輸入法的常見失誤之處。
|
/// 這是很多 macOS 副廠輸入法的常見失誤之處。
|
||||||
|
@ -207,6 +199,8 @@ class ctlInputMethod: IMKInputController {
|
||||||
@objc(handleEvent:client:) override func handle(_ event: NSEvent!, client sender: Any!) -> Bool {
|
@objc(handleEvent:client:) override func handle(_ event: NSEvent!, client sender: Any!) -> Bool {
|
||||||
_ = sender // 防止格式整理工具毀掉與此對應的參數。
|
_ = sender // 防止格式整理工具毀掉與此對應的參數。
|
||||||
|
|
||||||
|
// MARK: 前置處理
|
||||||
|
|
||||||
// 更新此時的靜態狀態標記。
|
// 更新此時的靜態狀態標記。
|
||||||
ctlInputMethod.isASCIIModeSituation = isASCIIMode
|
ctlInputMethod.isASCIIModeSituation = isASCIIMode
|
||||||
ctlInputMethod.isVerticalTypingSituation = isVerticalTyping
|
ctlInputMethod.isVerticalTypingSituation = isVerticalTyping
|
||||||
|
@ -218,44 +212,72 @@ class ctlInputMethod: IMKInputController {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// IMK 選字窗處理,當且僅當啟用了 IMK 選字窗的時候才會生效。
|
// 用 Shift 開關半形英數模式,僅對 macOS 10.15 及之後的 macOS 有效。
|
||||||
// 這樣可以讓 interpretKeyEvents() 函式自行判斷:
|
let shouldUseShiftToggleHandle: Bool = {
|
||||||
// - 是就地交給 super.interpretKeyEvents() 處理?
|
switch mgrPrefs.shiftKeyAccommodationBehavior {
|
||||||
// - 還是藉由 delegate 扔回 ctlInputMethod 給 KeyHandler 處理?
|
case 0: return false
|
||||||
proc: if let ctlCandidateCurrent = ctlInputMethod.ctlCandidateCurrent as? ctlCandidateIMK {
|
case 1: return IME.arrClientShiftHandlingExceptionList.contains(clientBundleIdentifier)
|
||||||
guard ctlCandidateCurrent.visible else { break proc }
|
case 2: return true
|
||||||
var event: NSEvent = ctlCandidateIMK.replaceNumPadKeyCodes(target: event) ?? event
|
default: return false
|
||||||
// 使 NSEvent 自翻譯,這樣可以讓 Emacs NSEvent 變成標準 NSEvent。
|
|
||||||
if event.isEmacsKey {
|
|
||||||
event = event.convertFromEmacKeyEvent(isVerticalContext: ctlInputMethod.isVerticalCandidateSituation)
|
|
||||||
}
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
// Shift+Enter 是個特殊情形,不提前攔截處理的話、會有垃圾參數傳給 delegate 的 keyHandler 從而崩潰。
|
/// 警告:這裡的 event 必須是原始 event 且不能被 var,否則會影響 Shift 中英模式判定。
|
||||||
// 所以這裡直接將 Shift Flags 清空。
|
if #available(macOS 10.15, *) {
|
||||||
if event.isShiftHold, event.isEnter {
|
if ShiftKeyUpChecker.check(event), !mgrPrefs.disableShiftTogglingAlphanumericalMode {
|
||||||
guard let newEvent = event.reinitiate(modifierFlags: []) else {
|
if !shouldUseShiftToggleHandle || (!rencentKeyHandledByKeyHandlerEtc && shouldUseShiftToggleHandle) {
|
||||||
NSSound.beep()
|
NotifierController.notify(
|
||||||
return true
|
message: NSLocalizedString("Alphanumerical Mode", comment: "") + "\n"
|
||||||
|
+ (toggleASCIIMode()
|
||||||
|
? NSLocalizedString("NotificationSwitchON", comment: "")
|
||||||
|
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
|
||||||
|
)
|
||||||
}
|
}
|
||||||
ctlCandidateCurrent.interpretKeyEvents([newEvent])
|
if shouldUseShiftToggleHandle {
|
||||||
return true
|
rencentKeyHandledByKeyHandlerEtc = false
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// 聯想詞選字。
|
|
||||||
if let newChar = ctlCandidateIMK.defaultIMKSelectionKey[event.keyCode], event.isShiftHold,
|
|
||||||
isAssociatedPhrasesState, let newEvent = event.reinitiate(modifierFlags: [], characters: newChar)
|
|
||||||
{
|
|
||||||
ctlCandidateCurrent.handleKeyboardEvent(newEvent)
|
|
||||||
}
|
|
||||||
|
|
||||||
ctlCandidateCurrent.interpretKeyEvents([event])
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 我們不在這裡處理了,直接交給 commonEventHandler 來處理。
|
// MARK: 針對客體的具體處理
|
||||||
|
|
||||||
|
/// 這裡仍舊需要判斷 flags。之前使輸入法狀態卡住無法敲漢字的問題已在 KeyHandler 內修復。
|
||||||
|
/// 這裡不判斷 flags 的話,用方向鍵前後定位光標之後,再次試圖觸發組字區時、反而會在首次按鍵時失敗。
|
||||||
|
/// 同時注意:必須在 event.type == .flagsChanged 結尾插入 return false,
|
||||||
|
/// 否則,每次處理這種判斷時都會觸發 NSInternalInconsistencyException。
|
||||||
|
if event.type == .flagsChanged { return false }
|
||||||
|
|
||||||
|
/// 沒有文字輸入客體的話,就不要再往下處理了。
|
||||||
|
guard client() != nil else { return false }
|
||||||
|
|
||||||
|
var eventToDeal = event
|
||||||
|
// 使 NSEvent 自翻譯,這樣可以讓 Emacs NSEvent 變成標準 NSEvent。
|
||||||
|
if eventToDeal.isEmacsKey {
|
||||||
|
let verticalProcessing =
|
||||||
|
(state.isCandidateContainer)
|
||||||
|
? ctlInputMethod.isVerticalCandidateSituation : ctlInputMethod.isVerticalTypingSituation
|
||||||
|
eventToDeal = eventToDeal.convertFromEmacKeyEvent(isVerticalContext: verticalProcessing)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 準備修飾鍵,用來判定要新增的詞彙是否需要賦以非常低的權重。
|
||||||
|
ctlInputMethod.areWeNerfing = eventToDeal.modifierFlags.contains([.shift, .command])
|
||||||
|
|
||||||
|
// IMK 選字窗處理,當且僅當啟用了 IMK 選字窗的時候才會生效。
|
||||||
|
if let result = imkCandidatesEventHandler(event: eventToDeal) {
|
||||||
|
if shouldUseShiftToggleHandle {
|
||||||
|
rencentKeyHandledByKeyHandlerEtc = result
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 剩下的 NSEvent 直接交給 commonEventHandler 來處理。
|
||||||
/// 這樣可以與 IMK 選字窗共用按鍵處理資源,維護起來也比較方便。
|
/// 這樣可以與 IMK 選字窗共用按鍵處理資源,維護起來也比較方便。
|
||||||
/// 警告:這裡的 event 必須是原始 event 且不能被 var,否則會影響 Shift 中英模式判定。
|
let result = commonEventHandler(eventToDeal)
|
||||||
return commonEventHandler(event)
|
if shouldUseShiftToggleHandle {
|
||||||
|
rencentKeyHandledByKeyHandlerEtc = result
|
||||||
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 有時會出現某些 App 攔截輸入法的 Ctrl+Enter / Shift+Enter 熱鍵的情況。
|
/// 有時會出現某些 App 攔截輸入法的 Ctrl+Enter / Shift+Enter 熱鍵的情況。
|
||||||
|
|
|
@ -16,7 +16,7 @@ extension ctlInputMethod: KeyHandlerDelegate {
|
||||||
/// 記錄當前輸入環境是縱排輸入還是橫排輸入。
|
/// 記錄當前輸入環境是縱排輸入還是橫排輸入。
|
||||||
public var isVerticalTyping: Bool {
|
public var isVerticalTyping: Bool {
|
||||||
guard let client = client() else { return false }
|
guard let client = client() else { return false }
|
||||||
var textFrame = NSRect.zero
|
var textFrame = NSRect.seniorTheBeast
|
||||||
let attributes: [AnyHashable: Any]? = client.attributes(
|
let attributes: [AnyHashable: Any]? = client.attributes(
|
||||||
forCharacterIndex: 0, lineHeightRectangle: &textFrame
|
forCharacterIndex: 0, lineHeightRectangle: &textFrame
|
||||||
)
|
)
|
||||||
|
|
|
@ -13,19 +13,31 @@ import Cocoa
|
||||||
// MARK: - Tooltip Display and Candidate Display Methods
|
// MARK: - Tooltip Display and Candidate Display Methods
|
||||||
|
|
||||||
extension ctlInputMethod {
|
extension ctlInputMethod {
|
||||||
func show(tooltip: String, displayedText: String, u16Cursor: Int) {
|
func lineHeightRect(zeroCursor: Bool = false) -> NSRect {
|
||||||
guard let client = client() else { return }
|
var lineHeightRect = NSRect.seniorTheBeast
|
||||||
var lineHeightRect = NSRect(x: 0.0, y: 0.0, width: 16.0, height: 16.0)
|
guard let client = client() else {
|
||||||
var cursor = u16Cursor
|
return lineHeightRect
|
||||||
if cursor == displayedText.count, cursor != 0 {
|
|
||||||
cursor -= 1
|
|
||||||
}
|
}
|
||||||
while lineHeightRect.origin.x == 0, lineHeightRect.origin.y == 0, cursor >= 0 {
|
var u16Cursor: Int = {
|
||||||
|
// iMessage 在 cursor == 0 時的計算會有一些偏差,所以例外處理。
|
||||||
|
if clientBundleIdentifier == "com.apple.MobileSMS" { return state.data.u16Cursor }
|
||||||
|
if state.data.marker >= state.data.cursor { return state.data.u16Cursor }
|
||||||
|
return state.data.u16Marker // 這樣可以讓工具提示視窗始終盡量往書寫方向的後方顯示。
|
||||||
|
}()
|
||||||
|
u16Cursor = max(min(state.data.displayedTextConverted.utf16.count, u16Cursor), 0)
|
||||||
|
if zeroCursor { u16Cursor = 0 }
|
||||||
|
while lineHeightRect.origin.x == 0, lineHeightRect.origin.y == 0, u16Cursor >= 0 {
|
||||||
client.attributes(
|
client.attributes(
|
||||||
forCharacterIndex: cursor, lineHeightRectangle: &lineHeightRect
|
forCharacterIndex: u16Cursor, lineHeightRectangle: &lineHeightRect
|
||||||
)
|
)
|
||||||
cursor -= 1
|
u16Cursor -= 1
|
||||||
}
|
}
|
||||||
|
return lineHeightRect
|
||||||
|
}
|
||||||
|
|
||||||
|
func show(tooltip: String) {
|
||||||
|
guard client() != nil else { return }
|
||||||
|
let lineHeightRect = lineHeightRect()
|
||||||
var finalOrigin: NSPoint = lineHeightRect.origin
|
var finalOrigin: NSPoint = lineHeightRect.origin
|
||||||
let delta: CGFloat = lineHeightRect.size.height + 4.0 // bottomOutOfScreenAdjustmentHeight
|
let delta: CGFloat = lineHeightRect.size.height + 4.0 // bottomOutOfScreenAdjustmentHeight
|
||||||
if isVerticalTyping {
|
if isVerticalTyping {
|
||||||
|
@ -120,34 +132,17 @@ extension ctlInputMethod {
|
||||||
|
|
||||||
ctlInputMethod.ctlCandidateCurrent.visible = true
|
ctlInputMethod.ctlCandidateCurrent.visible = true
|
||||||
|
|
||||||
var lineHeightRect = NSRect(x: 0.0, y: 0.0, width: 16.0, height: 16.0)
|
|
||||||
var cursor = 0
|
|
||||||
|
|
||||||
if [.ofCandidates, .ofSymbolTable].contains(state.type) {
|
|
||||||
cursor = state.data.cursor
|
|
||||||
if cursor == state.displayedText.count, cursor != 0 {
|
|
||||||
cursor -= 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while lineHeightRect.origin.x == 0, lineHeightRect.origin.y == 0, cursor >= 0 {
|
|
||||||
client.attributes(
|
|
||||||
forCharacterIndex: cursor, lineHeightRectangle: &lineHeightRect
|
|
||||||
)
|
|
||||||
cursor -= 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if isVerticalTyping {
|
if isVerticalTyping {
|
||||||
ctlInputMethod.ctlCandidateCurrent.set(
|
ctlInputMethod.ctlCandidateCurrent.set(
|
||||||
windowTopLeftPoint: NSPoint(
|
windowTopLeftPoint: NSPoint(
|
||||||
x: lineHeightRect.origin.x + lineHeightRect.size.width + 4.0, y: lineHeightRect.origin.y - 4.0
|
x: lineHeightRect().origin.x + lineHeightRect().size.width + 4.0, y: lineHeightRect().origin.y - 4.0
|
||||||
),
|
),
|
||||||
bottomOutOfScreenAdjustmentHeight: lineHeightRect.size.height + 4.0
|
bottomOutOfScreenAdjustmentHeight: lineHeightRect().size.height + 4.0
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
ctlInputMethod.ctlCandidateCurrent.set(
|
ctlInputMethod.ctlCandidateCurrent.set(
|
||||||
windowTopLeftPoint: NSPoint(x: lineHeightRect.origin.x, y: lineHeightRect.origin.y - 4.0),
|
windowTopLeftPoint: NSPoint(x: lineHeightRect().origin.x, y: lineHeightRect().origin.y - 4.0),
|
||||||
bottomOutOfScreenAdjustmentHeight: lineHeightRect.size.height + 4.0
|
bottomOutOfScreenAdjustmentHeight: lineHeightRect().size.height + 4.0
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,10 +65,7 @@ extension ctlInputMethod {
|
||||||
if !textToCommit.isEmpty { commit(text: textToCommit) }
|
if !textToCommit.isEmpty { commit(text: textToCommit) }
|
||||||
setInlineDisplayWithCursor()
|
setInlineDisplayWithCursor()
|
||||||
if !state.tooltip.isEmpty {
|
if !state.tooltip.isEmpty {
|
||||||
show(
|
show(tooltip: state.tooltip)
|
||||||
tooltip: state.tooltip, displayedText: state.displayedText,
|
|
||||||
u16Cursor: state.data.u16Cursor
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
case .ofMarking:
|
case .ofMarking:
|
||||||
ctlInputMethod.ctlCandidateCurrent.visible = false
|
ctlInputMethod.ctlCandidateCurrent.visible = false
|
||||||
|
@ -76,14 +73,7 @@ extension ctlInputMethod {
|
||||||
if state.tooltip.isEmpty {
|
if state.tooltip.isEmpty {
|
||||||
ctlInputMethod.tooltipInstance.hide()
|
ctlInputMethod.tooltipInstance.hide()
|
||||||
} else {
|
} else {
|
||||||
let cursorReference: Int = {
|
show(tooltip: state.tooltip)
|
||||||
if state.data.marker >= state.data.cursor { return state.data.u16Cursor }
|
|
||||||
return state.data.u16Marker // 這樣可以讓工具提示視窗始終盡量往書寫方向的後方顯示。
|
|
||||||
}()
|
|
||||||
show(
|
|
||||||
tooltip: state.tooltip, displayedText: state.displayedText,
|
|
||||||
u16Cursor: cursorReference
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
case .ofCandidates, .ofAssociates, .ofSymbolTable:
|
case .ofCandidates, .ofAssociates, .ofSymbolTable:
|
||||||
ctlInputMethod.tooltipInstance.hide()
|
ctlInputMethod.tooltipInstance.hide()
|
||||||
|
@ -91,6 +81,14 @@ extension ctlInputMethod {
|
||||||
show(candidateWindowWith: state)
|
show(candidateWindowWith: state)
|
||||||
default: break
|
default: break
|
||||||
}
|
}
|
||||||
|
// 浮動組字窗的顯示判定
|
||||||
|
if state.hasComposition, mgrPrefs.clientsIMKTextInputIncapable.contains(clientBundleIdentifier) {
|
||||||
|
ctlInputMethod.popupCompositionBuffer.show(
|
||||||
|
state: state, at: lineHeightRect(zeroCursor: true).origin
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
ctlInputMethod.popupCompositionBuffer.hide()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 針對受 .NotEmpty() 管轄的非空狀態,在組字區內顯示游標。
|
/// 針對受 .NotEmpty() 管轄的非空狀態,在組字區內顯示游標。
|
||||||
|
@ -109,7 +107,7 @@ extension ctlInputMethod {
|
||||||
/// 是 0 且取代範圍(replacementRange)為「NSNotFound」罷了。
|
/// 是 0 且取代範圍(replacementRange)為「NSNotFound」罷了。
|
||||||
/// 也就是說,內文組字區該在哪裡出現,得由客體軟體來作主。
|
/// 也就是說,內文組字區該在哪裡出現,得由客體軟體來作主。
|
||||||
client.setMarkedText(
|
client.setMarkedText(
|
||||||
state.attributedString, selectionRange: NSRange(location: state.data.u16Cursor, length: 0),
|
state.attributedString, selectionRange: NSRange(state.data.u16MarkedRange),
|
||||||
replacementRange: NSRange(location: NSNotFound, length: NSNotFound)
|
replacementRange: NSRange(location: NSNotFound, length: NSNotFound)
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
|
@ -156,6 +156,12 @@ extension ctlInputMethod {
|
||||||
withTitle: NSLocalizedString("vChewing Preferences…", comment: ""),
|
withTitle: NSLocalizedString("vChewing Preferences…", comment: ""),
|
||||||
action: #selector(showPreferences(_:)), keyEquivalent: ""
|
action: #selector(showPreferences(_:)), keyEquivalent: ""
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
menu.addItem(
|
||||||
|
withTitle: NSLocalizedString("Client Manager", comment: "") + "…",
|
||||||
|
action: #selector(showClientListMgr(_:)), keyEquivalent: ""
|
||||||
|
)
|
||||||
|
if !optionKeyPressed {
|
||||||
menu.addItem(
|
menu.addItem(
|
||||||
withTitle: NSLocalizedString("Check for Updates…", comment: ""),
|
withTitle: NSLocalizedString("Check for Updates…", comment: ""),
|
||||||
action: #selector(checkForUpdate(_:)), keyEquivalent: ""
|
action: #selector(checkForUpdate(_:)), keyEquivalent: ""
|
||||||
|
@ -208,6 +214,11 @@ extension ctlInputMethod {
|
||||||
NSWorkspace.shared.openFile(url.path, withApplication: "Safari")
|
NSWorkspace.shared.openFile(url.path, withApplication: "Safari")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc func showClientListMgr(_: Any?) {
|
||||||
|
(NSApp.delegate as? AppDelegate)?.showClientListMgr()
|
||||||
|
NSApp.activate(ignoringOtherApps: true)
|
||||||
|
}
|
||||||
|
|
||||||
@objc func toggleSCPCTypingMode(_: Any? = nil) {
|
@objc func toggleSCPCTypingMode(_: Any? = nil) {
|
||||||
resetKeyHandler()
|
resetKeyHandler()
|
||||||
NotifierController.notify(
|
NotifierController.notify(
|
||||||
|
|
|
@ -348,3 +348,11 @@ extension NSApplication {
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: NSRect Extension
|
||||||
|
|
||||||
|
extension NSRect {
|
||||||
|
public static var seniorTheBeast: NSRect {
|
||||||
|
NSRect(x: 0.0, y: 0.0, width: 0.114, height: 0.514)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -152,7 +152,7 @@ class UpdateSputnik: NSObject, URLSessionDataDelegate {
|
||||||
let content = NSLocalizedString(message, comment: "")
|
let content = NSLocalizedString(message, comment: "")
|
||||||
alert.messageText = NSLocalizedString("Update Check Failed", comment: "")
|
alert.messageText = NSLocalizedString("Update Check Failed", comment: "")
|
||||||
alert.informativeText = content
|
alert.informativeText = content
|
||||||
alert.addButton(withTitle: NSLocalizedString("Dismiss", comment: ""))
|
alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
|
||||||
alert.runModal()
|
alert.runModal()
|
||||||
NSApp.setActivationPolicy(.accessory)
|
NSApp.setActivationPolicy(.accessory)
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,7 @@ public enum UserDef: String, CaseIterable {
|
||||||
case kHardenVerticalPunctuations = "HardenVerticalPunctuations"
|
case kHardenVerticalPunctuations = "HardenVerticalPunctuations"
|
||||||
case kTrimUnfinishedReadingsOnCommit = "TrimUnfinishedReadingsOnCommit"
|
case kTrimUnfinishedReadingsOnCommit = "TrimUnfinishedReadingsOnCommit"
|
||||||
case kAlwaysShowTooltipTextsHorizontally = "AlwaysShowTooltipTextsHorizontally"
|
case kAlwaysShowTooltipTextsHorizontally = "AlwaysShowTooltipTextsHorizontally"
|
||||||
|
case kClientsIMKTextInputIncapable = "ClientsIMKTextInputIncapable"
|
||||||
|
|
||||||
case kUseIMKCandidateWindow = "UseIMKCandidateWindow"
|
case kUseIMKCandidateWindow = "UseIMKCandidateWindow"
|
||||||
case kHandleDefaultCandidateFontsByLangIdentifier = "HandleDefaultCandidateFontsByLangIdentifier"
|
case kHandleDefaultCandidateFontsByLangIdentifier = "HandleDefaultCandidateFontsByLangIdentifier"
|
||||||
|
@ -306,6 +307,9 @@ public enum mgrPrefs {
|
||||||
UserDefaults.standard.setDefault(
|
UserDefaults.standard.setDefault(
|
||||||
mgrPrefs.trimUnfinishedReadingsOnCommit, forKey: UserDef.kTrimUnfinishedReadingsOnCommit.rawValue
|
mgrPrefs.trimUnfinishedReadingsOnCommit, forKey: UserDef.kTrimUnfinishedReadingsOnCommit.rawValue
|
||||||
)
|
)
|
||||||
|
UserDefaults.standard.setDefault(
|
||||||
|
mgrPrefs.clientsIMKTextInputIncapable, forKey: UserDef.kClientsIMKTextInputIncapable.rawValue
|
||||||
|
)
|
||||||
|
|
||||||
// -----
|
// -----
|
||||||
|
|
||||||
|
@ -443,6 +447,9 @@ public enum mgrPrefs {
|
||||||
@UserDefault(key: UserDef.kAlwaysShowTooltipTextsHorizontally.rawValue, defaultValue: false)
|
@UserDefault(key: UserDef.kAlwaysShowTooltipTextsHorizontally.rawValue, defaultValue: false)
|
||||||
static var alwaysShowTooltipTextsHorizontally: Bool
|
static var alwaysShowTooltipTextsHorizontally: Bool
|
||||||
|
|
||||||
|
@UserDefault(key: UserDef.kClientsIMKTextInputIncapable.rawValue, defaultValue: ["com.valvesoftware.steam"])
|
||||||
|
static var clientsIMKTextInputIncapable: [String]
|
||||||
|
|
||||||
// MARK: - Settings (Tier 2)
|
// MARK: - Settings (Tier 2)
|
||||||
|
|
||||||
@UserDefault(key: UserDef.kUseIMKCandidateWindow.rawValue, defaultValue: false)
|
@UserDefault(key: UserDef.kUseIMKCandidateWindow.rawValue, defaultValue: false)
|
||||||
|
@ -738,6 +745,8 @@ extension mgrPrefs {
|
||||||
mgrPrefs.disableShiftTogglingAlphanumericalMode = false
|
mgrPrefs.disableShiftTogglingAlphanumericalMode = false
|
||||||
mgrPrefs.togglingAlphanumericalModeWithLShift = false
|
mgrPrefs.togglingAlphanumericalModeWithLShift = false
|
||||||
}
|
}
|
||||||
|
// 客體黑名單自動排序去重複。
|
||||||
|
clientsIMKTextInputIncapable = Array(Set(clientsIMKTextInputIncapable)).sorted()
|
||||||
// 注拼槽注音排列選項糾錯。
|
// 注拼槽注音排列選項糾錯。
|
||||||
var isMandarinParserOptionValid = false
|
var isMandarinParserOptionValid = false
|
||||||
MandarinParser.allCases.forEach {
|
MandarinParser.allCases.forEach {
|
||||||
|
|
|
@ -160,7 +160,7 @@ public class ctlCandidate: NSWindowController, ctlCandidateProtocol {
|
||||||
|
|
||||||
var adjustedPoint = windowTopLeftPoint
|
var adjustedPoint = windowTopLeftPoint
|
||||||
var delta = heightDelta
|
var delta = heightDelta
|
||||||
var screenFrame = NSScreen.main?.visibleFrame ?? NSRect.zero
|
var screenFrame = NSScreen.main?.visibleFrame ?? NSRect.seniorTheBeast
|
||||||
for frame in NSScreen.screens.map(\.visibleFrame).filter({ !$0.contains(windowTopLeftPoint) }) {
|
for frame in NSScreen.screens.map(\.visibleFrame).filter({ !$0.contains(windowTopLeftPoint) }) {
|
||||||
screenFrame = frame
|
screenFrame = frame
|
||||||
break
|
break
|
||||||
|
|
|
@ -167,7 +167,7 @@ public class ctlCandidateIMK: IMKCandidates, ctlCandidateProtocol {
|
||||||
var adjustedPoint = windowTopLeftPoint
|
var adjustedPoint = windowTopLeftPoint
|
||||||
var adjustedHeight = height
|
var adjustedHeight = height
|
||||||
|
|
||||||
var screenFrame = NSScreen.main?.visibleFrame ?? NSRect.zero
|
var screenFrame = NSScreen.main?.visibleFrame ?? NSRect.seniorTheBeast
|
||||||
for screen in NSScreen.screens {
|
for screen in NSScreen.screens {
|
||||||
let frame = screen.visibleFrame
|
let frame = screen.visibleFrame
|
||||||
if windowTopLeftPoint.x >= frame.minX, windowTopLeftPoint.x <= frame.maxX,
|
if windowTopLeftPoint.x >= frame.minX, windowTopLeftPoint.x <= frame.maxX,
|
||||||
|
|
|
@ -346,7 +346,7 @@ public class ctlCandidateUniversal: ctlCandidate {
|
||||||
let panel = NSPanel(
|
let panel = NSPanel(
|
||||||
contentRect: contentRect, styleMask: styleMask, backing: .buffered, defer: false
|
contentRect: contentRect, styleMask: styleMask, backing: .buffered, defer: false
|
||||||
)
|
)
|
||||||
panel.level = NSWindow.Level(Int(kCGPopUpMenuWindowLevel) + 1)
|
panel.level = NSWindow.Level(Int(kCGPopUpMenuWindowLevel) + 2)
|
||||||
panel.hasShadow = true
|
panel.hasShadow = true
|
||||||
panel.isOpaque = false
|
panel.isOpaque = false
|
||||||
panel.backgroundColor = NSColor.clear
|
panel.backgroundColor = NSColor.clear
|
||||||
|
@ -600,7 +600,7 @@ extension ctlCandidateUniversal {
|
||||||
pageCounterLabel.isHidden = true
|
pageCounterLabel.isHidden = true
|
||||||
}
|
}
|
||||||
|
|
||||||
frameRect = window?.frame ?? NSRect.zero
|
frameRect = window?.frame ?? NSRect.seniorTheBeast
|
||||||
|
|
||||||
let topLeftPoint = NSPoint(x: frameRect.origin.x, y: frameRect.origin.y + frameRect.size.height)
|
let topLeftPoint = NSPoint(x: frameRect.origin.x, y: frameRect.origin.y + frameRect.size.height)
|
||||||
frameRect.size = newSize
|
frameRect.size = newSize
|
||||||
|
|
|
@ -90,7 +90,7 @@ public class NotifierController: NSWindowController, NotifierWindowDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
private init() {
|
private init() {
|
||||||
let screenRect = NSScreen.main?.visibleFrame ?? NSRect.zero
|
let screenRect = NSScreen.main?.visibleFrame ?? NSRect.seniorTheBeast
|
||||||
let contentRect = NSRect(x: 0, y: 0, width: kWindowWidth, height: kWindowHeight)
|
let contentRect = NSRect(x: 0, y: 0, width: kWindowWidth, height: kWindowHeight)
|
||||||
var windowRect = contentRect
|
var windowRect = contentRect
|
||||||
windowRect.origin.x = screenRect.maxX - windowRect.width - 10
|
windowRect.origin.x = screenRect.maxX - windowRect.width - 10
|
||||||
|
@ -144,8 +144,8 @@ public class NotifierController: NSWindowController, NotifierWindowDelegate {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let lastLocation = NotifierController.lastLocation
|
let lastLocation = NotifierController.lastLocation
|
||||||
let screenRect = NSScreen.main?.visibleFrame ?? NSRect.zero
|
let screenRect = NSScreen.main?.visibleFrame ?? NSRect.seniorTheBeast
|
||||||
var windowRect = window?.frame ?? NSRect.zero
|
var windowRect = window?.frame ?? NSRect.seniorTheBeast
|
||||||
windowRect.origin.x = lastLocation.x
|
windowRect.origin.x = lastLocation.x
|
||||||
windowRect.origin.y = lastLocation.y - 10 - windowRect.height
|
windowRect.origin.y = lastLocation.y - 10 - windowRect.height
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ public class NotifierController: NSWindowController, NotifierWindowDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
func moveIn() {
|
func moveIn() {
|
||||||
let afterRect = window?.frame ?? NSRect.zero
|
let afterRect = window?.frame ?? NSRect.seniorTheBeast
|
||||||
NotifierController.lastLocation = afterRect.origin
|
NotifierController.lastLocation = afterRect.origin
|
||||||
var beforeRect = afterRect
|
var beforeRect = afterRect
|
||||||
beforeRect.origin.y += 10
|
beforeRect.origin.y += 10
|
||||||
|
|
|
@ -0,0 +1,127 @@
|
||||||
|
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
||||||
|
// ====================
|
||||||
|
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
|
||||||
|
// ... with NTL restriction stating that:
|
||||||
|
// No trademark license is granted to use the trade names, trademarks, service
|
||||||
|
// marks, or product names of Contributor, except as required to fulfill notice
|
||||||
|
// requirements defined in MIT License.
|
||||||
|
|
||||||
|
import Cocoa
|
||||||
|
|
||||||
|
public class ctlPopupCompositionBuffer: NSWindowController {
|
||||||
|
private var messageTextField: NSTextField
|
||||||
|
private var textShown: NSAttributedString = .init(string: "") {
|
||||||
|
didSet {
|
||||||
|
messageTextField.attributedStringValue = textShown
|
||||||
|
adjustSize()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public init() {
|
||||||
|
let transparentVisualEffect = NSVisualEffectView()
|
||||||
|
transparentVisualEffect.blendingMode = .behindWindow
|
||||||
|
transparentVisualEffect.state = .active
|
||||||
|
let contentRect = NSRect(x: 128.0, y: 128.0, width: 300.0, height: 20.0)
|
||||||
|
let styleMask: NSWindow.StyleMask = [.borderless, .nonactivatingPanel]
|
||||||
|
let panel = NSPanel(
|
||||||
|
contentRect: contentRect, styleMask: styleMask, backing: .buffered, defer: false
|
||||||
|
)
|
||||||
|
panel.contentView = transparentVisualEffect
|
||||||
|
panel.level = NSWindow.Level(Int(kCGPopUpMenuWindowLevel) + 1)
|
||||||
|
panel.hasShadow = true
|
||||||
|
panel.backgroundColor = NSColor.clear
|
||||||
|
|
||||||
|
messageTextField = NSTextField()
|
||||||
|
messageTextField.isEditable = false
|
||||||
|
messageTextField.isSelectable = false
|
||||||
|
messageTextField.isBezeled = false
|
||||||
|
messageTextField.textColor = NSColor.textColor
|
||||||
|
messageTextField.drawsBackground = true
|
||||||
|
messageTextField.backgroundColor = NSColor.clear
|
||||||
|
messageTextField.font = .systemFont(ofSize: 18)
|
||||||
|
panel.contentView?.addSubview(messageTextField)
|
||||||
|
super.init(window: panel)
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(*, unavailable)
|
||||||
|
public required init?(coder _: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
public func show(state: IMEStateProtocol, at point: NSPoint) {
|
||||||
|
if !state.hasComposition {
|
||||||
|
hide()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 在這個視窗內的下畫線繪製方法就得單獨設計了。
|
||||||
|
let attrString: NSMutableAttributedString = .init(string: state.data.displayedTextConverted)
|
||||||
|
attrString.setAttributes(
|
||||||
|
[
|
||||||
|
.backgroundColor: NSColor.alternateSelectedControlColor,
|
||||||
|
.foregroundColor: NSColor.alternateSelectedControlTextColor,
|
||||||
|
.markedClauseSegment: 0,
|
||||||
|
],
|
||||||
|
range: NSRange(
|
||||||
|
location: state.data.u16MarkedRange.lowerBound,
|
||||||
|
length: state.data.u16MarkedRange.upperBound - state.data.u16MarkedRange.lowerBound
|
||||||
|
)
|
||||||
|
)
|
||||||
|
let attrCursor = NSMutableAttributedString(string: "_")
|
||||||
|
if #available(macOS 10.13, *) {
|
||||||
|
attrCursor.setAttributes(
|
||||||
|
[
|
||||||
|
.kern: -18,
|
||||||
|
.baselineOffset: -2,
|
||||||
|
.markedClauseSegment: 1,
|
||||||
|
],
|
||||||
|
range: NSRange(location: 0, length: attrCursor.string.utf16.count)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
attrString.insert(attrCursor, at: state.data.u16Cursor)
|
||||||
|
textShown = attrString
|
||||||
|
messageTextField.maximumNumberOfLines = 1
|
||||||
|
if let editor = messageTextField.currentEditor() {
|
||||||
|
editor.selectedRange = NSRange(state.data.u16MarkedRange)
|
||||||
|
}
|
||||||
|
window?.orderFront(nil)
|
||||||
|
set(windowOrigin: point)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func hide() {
|
||||||
|
window?.orderOut(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func set(windowOrigin: NSPoint) {
|
||||||
|
guard let window = window else { return }
|
||||||
|
let windowSize = window.frame.size
|
||||||
|
|
||||||
|
var adjustedPoint = windowOrigin
|
||||||
|
var screenFrame = NSScreen.main?.visibleFrame ?? NSRect.seniorTheBeast
|
||||||
|
for frame in NSScreen.screens.map(\.visibleFrame).filter({ !$0.contains(windowOrigin) }) {
|
||||||
|
screenFrame = frame
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
adjustedPoint.y = min(max(adjustedPoint.y, screenFrame.minY + windowSize.height), screenFrame.maxY)
|
||||||
|
adjustedPoint.x = min(max(adjustedPoint.x, screenFrame.minX), screenFrame.maxX - windowSize.width)
|
||||||
|
|
||||||
|
window.setFrameOrigin(adjustedPoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func adjustSize() {
|
||||||
|
let attrString = messageTextField.attributedStringValue
|
||||||
|
var rect = attrString.boundingRect(
|
||||||
|
with: NSSize(width: 1600.0, height: 1600.0),
|
||||||
|
options: [.usesLineFragmentOrigin, .usesFontLeading]
|
||||||
|
)
|
||||||
|
rect.size.width = max(rect.size.width, 20 * CGFloat(attrString.string.count)) + 2
|
||||||
|
rect.size.height = 22
|
||||||
|
var bigRect = rect
|
||||||
|
bigRect.size.width += NSFont.systemFontSize
|
||||||
|
bigRect.size.height += NSFont.systemFontSize
|
||||||
|
rect.origin.x += NSFont.systemFontSize / 2
|
||||||
|
rect.origin.y += NSFont.systemFontSize / 2
|
||||||
|
messageTextField.frame = rect
|
||||||
|
window?.setFrame(bigRect, display: true)
|
||||||
|
}
|
||||||
|
}
|
|
@ -40,7 +40,7 @@ public class ctlTooltip: NSWindowController {
|
||||||
let panel = NSPanel(
|
let panel = NSPanel(
|
||||||
contentRect: contentRect, styleMask: styleMask, backing: .buffered, defer: false
|
contentRect: contentRect, styleMask: styleMask, backing: .buffered, defer: false
|
||||||
)
|
)
|
||||||
panel.level = NSWindow.Level(Int(kCGPopUpMenuWindowLevel) + 1)
|
panel.level = NSWindow.Level(Int(kCGPopUpMenuWindowLevel) + 2)
|
||||||
panel.hasShadow = true
|
panel.hasShadow = true
|
||||||
panel.backgroundColor = NSColor.controlBackgroundColor
|
panel.backgroundColor = NSColor.controlBackgroundColor
|
||||||
messageText = NSAttributedTextView()
|
messageText = NSAttributedTextView()
|
||||||
|
@ -129,7 +129,7 @@ public class ctlTooltip: NSWindowController {
|
||||||
|
|
||||||
var adjustedPoint = windowTopLeftPoint
|
var adjustedPoint = windowTopLeftPoint
|
||||||
var delta = heightDelta
|
var delta = heightDelta
|
||||||
var screenFrame = NSScreen.main?.visibleFrame ?? NSRect.zero
|
var screenFrame = NSScreen.main?.visibleFrame ?? NSRect.seniorTheBeast
|
||||||
for frame in NSScreen.screens.map(\.visibleFrame).filter({ !$0.contains(windowTopLeftPoint) }) {
|
for frame in NSScreen.screens.map(\.visibleFrame).filter({ !$0.contains(windowTopLeftPoint) }) {
|
||||||
screenFrame = frame
|
screenFrame = frame
|
||||||
break
|
break
|
||||||
|
|
|
@ -1,4 +1,15 @@
|
||||||
"vChewing" = "vChewing";
|
"vChewing" = "vChewing";
|
||||||
|
"Please enter the client app bundle identifier(s) you want to register." = "Please enter the client app bundle identifier(s) you want to register.";
|
||||||
|
"One record per line. Use Option+Enter to break lines.\nBlank lines will be dismissed." = "One record per line. Use Option+Enter to break lines.\nBlank lines will be dismissed.";
|
||||||
|
"Just Select" = "Just Select";
|
||||||
|
"Client Manager" = "Client Manager";
|
||||||
|
"Please manage the list of IMKTextInput-incompatible clients here. Clients listed here will trigger vChewing's built-in popup composition buffer window with maximum 20 reading counts holdable." = "Please manage the list of IMKTextInput-incompatible clients here. Clients listed here will trigger vChewing's built-in popup composition buffer window with maximum 20 reading counts holdable.";
|
||||||
|
"Add Client" = "Add Client";
|
||||||
|
"Remove Selected" = "Remove Selected";
|
||||||
|
"Choose the target application bundle." = "Choose the target application bundle.";
|
||||||
|
"The selected item is not a valid macOS application bundle." = "The selected item is not a valid macOS application bundle.";
|
||||||
|
"Please try again." = "Please try again.";
|
||||||
|
"The selected item's identifier is already in the list." = "The selected item's identifier is already in the list.";
|
||||||
"Update Check Completed" = "Update Check Completed";
|
"Update Check Completed" = "Update Check Completed";
|
||||||
"You are already using the latest version." = "You are already using the latest version.";
|
"You are already using the latest version." = "You are already using the latest version.";
|
||||||
"Plist downloaded is nil." = "Plist downloaded is nil.";
|
"Plist downloaded is nil." = "Plist downloaded is nil.";
|
||||||
|
@ -17,7 +28,7 @@
|
||||||
"Update Check Failed" = "Update Check Failed";
|
"Update Check Failed" = "Update Check Failed";
|
||||||
"There may be no internet connection or the server failed to respond.\n\nError message: %@" = "There may be no internet connection or the server failed to respond.\n\nError message: %@";
|
"There may be no internet connection or the server failed to respond.\n\nError message: %@" = "There may be no internet connection or the server failed to respond.\n\nError message: %@";
|
||||||
"OK" = "OK";
|
"OK" = "OK";
|
||||||
"Dismiss" = "Dismiss";
|
"Cancel" = "Cancel";
|
||||||
"New Version Available" = "New Version Available";
|
"New Version Available" = "New Version Available";
|
||||||
"Not Now" = "Not Now";
|
"Not Now" = "Not Now";
|
||||||
"Visit Website" = "Visit Website";
|
"Visit Website" = "Visit Website";
|
||||||
|
|
|
@ -1,4 +1,15 @@
|
||||||
"vChewing" = "vChewing";
|
"vChewing" = "vChewing";
|
||||||
|
"Please enter the client app bundle identifier(s) you want to register." = "Please enter the client app bundle identifier(s) you want to register.";
|
||||||
|
"One record per line. Use Option+Enter to break lines.\nBlank lines will be dismissed." = "One record per line. Use Option+Enter to break lines.\nBlank lines will be dismissed.";
|
||||||
|
"Just Select" = "Just Select";
|
||||||
|
"Client Manager" = "Client Manager";
|
||||||
|
"Please manage the list of IMKTextInput-incompatible clients here. Clients listed here will trigger vChewing's built-in popup composition buffer window with maximum 20 reading counts holdable." = "Please manage the list of IMKTextInput-incompatible clients here. Clients listed here will trigger vChewing's built-in popup composition buffer window with maximum 20 reading counts holdable.";
|
||||||
|
"Add Client" = "Add Client";
|
||||||
|
"Remove Selected" = "Remove Selected";
|
||||||
|
"Choose the target application bundle." = "Choose the target application bundle.";
|
||||||
|
"The selected item is not a valid macOS application bundle." = "The selected item is not a valid macOS application bundle.";
|
||||||
|
"Please try again." = "Please try again.";
|
||||||
|
"The selected item's identifier is already in the list." = "The selected item's identifier is already in the list.";
|
||||||
"Update Check Completed" = "Update Check Completed";
|
"Update Check Completed" = "Update Check Completed";
|
||||||
"You are already using the latest version." = "You are already using the latest version.";
|
"You are already using the latest version." = "You are already using the latest version.";
|
||||||
"Plist downloaded is nil." = "Plist downloaded is nil.";
|
"Plist downloaded is nil." = "Plist downloaded is nil.";
|
||||||
|
@ -17,7 +28,7 @@
|
||||||
"Update Check Failed" = "Update Check Failed";
|
"Update Check Failed" = "Update Check Failed";
|
||||||
"There may be no internet connection or the server failed to respond.\n\nError message: %@" = "There may be no internet connection or the server failed to respond.\n\nError message: %@";
|
"There may be no internet connection or the server failed to respond.\n\nError message: %@" = "There may be no internet connection or the server failed to respond.\n\nError message: %@";
|
||||||
"OK" = "OK";
|
"OK" = "OK";
|
||||||
"Dismiss" = "Dismiss";
|
"Cancel" = "Cancel";
|
||||||
"New Version Available" = "New Version Available";
|
"New Version Available" = "New Version Available";
|
||||||
"Not Now" = "Not Now";
|
"Not Now" = "Not Now";
|
||||||
"Visit Website" = "Visit Website";
|
"Visit Website" = "Visit Website";
|
||||||
|
|
|
@ -1,4 +1,15 @@
|
||||||
"vChewing" = "威注音入力アプリ";
|
"vChewing" = "威注音入力アプリ";
|
||||||
|
"Please enter the client app bundle identifier(s) you want to register." = "登録したい客体アプリの唯一識別子(Bundle Identifier)をご入力ください。";
|
||||||
|
"One record per line. Use Option+Enter to break lines.\nBlank lines will be dismissed." = "毎行は1つ記録とみなす。Option+Enter キーで改行。\n空白の記録値は無視される。";
|
||||||
|
"Just Select" = "直接に選ぶ";
|
||||||
|
"Client Manager" = "客体アプリの管理";
|
||||||
|
"Please manage the list of IMKTextInput-incompatible clients here. Clients listed here will trigger vChewing's built-in popup composition buffer window with maximum 20 reading counts holdable." = "IMKTextInput 議定規約に従っていない客体アプリはここでご登録ください。登録済みのアプリは客体アプリ(文字入力を受くアプリ)とされた時に、威注音入力アプリは「吹き出し入力緩衝列ウィンドウ」と「緩衝列容量制限」を起用し、その容量制限は最大限音読み20箇とする。";
|
||||||
|
"Add Client" = "入れる";
|
||||||
|
"Remove Selected" = "外す";
|
||||||
|
"Choose the target application bundle." = "登録したいアプリのバンドルのお選びを。";
|
||||||
|
"The selected item is not a valid macOS application bundle." = "今選んだんのは正しい macOS アプリバンドルではないと考えられる。";
|
||||||
|
"Please try again." = "お選び直しください。";
|
||||||
|
"The selected item's identifier is already in the list." = "今選んだバンドルの唯一識別子(Bundle Identifier)は既に登録済みである。";
|
||||||
"Update Check Completed" = "新バージョンチェック完了";
|
"Update Check Completed" = "新バージョンチェック完了";
|
||||||
"You are already using the latest version." = "現在稼働中のは最新バージョンである。";
|
"You are already using the latest version." = "現在稼働中のは最新バージョンである。";
|
||||||
"Plist downloaded is nil." = "受けた新バージョンお知らせ情報データは Plist ではないため、失敗とみなす。";
|
"Plist downloaded is nil." = "受けた新バージョンお知らせ情報データは Plist ではないため、失敗とみなす。";
|
||||||
|
@ -17,7 +28,7 @@
|
||||||
"Update Check Failed" = "更新通知受信失敗";
|
"Update Check Failed" = "更新通知受信失敗";
|
||||||
"There may be no internet connection or the server failed to respond.\n\nError message: %@" = "ネットの接続の有無の問題か、サーバー側の反応の問題か。\n\nいずれにせよ、エラーメッセージ:「%@」";
|
"There may be no internet connection or the server failed to respond.\n\nError message: %@" = "ネットの接続の有無の問題か、サーバー側の反応の問題か。\n\nいずれにせよ、エラーメッセージ:「%@」";
|
||||||
"OK" = "うむ";
|
"OK" = "うむ";
|
||||||
"Dismiss" = "却下";
|
"Cancel" = "取り消す";
|
||||||
"New Version Available" = "最新版利用可能";
|
"New Version Available" = "最新版利用可能";
|
||||||
"Not Now" = "後で";
|
"Not Now" = "後で";
|
||||||
"Visit Website" = "公式サイト";
|
"Visit Website" = "公式サイト";
|
||||||
|
|
|
@ -1,4 +1,15 @@
|
||||||
"vChewing" = "威注音输入法";
|
"vChewing" = "威注音输入法";
|
||||||
|
"Please enter the client app bundle identifier(s) you want to register." = "请键入您要登记的客体应用的唯一标帜(Bundle Identifier)。";
|
||||||
|
"One record per line. Use Option+Enter to break lines.\nBlank lines will be dismissed." = "每行一笔记录,用 Option+Enter 换行。\n空白值会被无视。";
|
||||||
|
"Just Select" = "直接选取";
|
||||||
|
"Client Manager" = "管理客体应用";
|
||||||
|
"Please manage the list of IMKTextInput-incompatible clients here. Clients listed here will trigger vChewing's built-in popup composition buffer window with maximum 20 reading counts holdable." = "请在此管理那些不遵守 IMKTextInput 协定的客体应用。威注音输入法对于任何位列在此的客体应用均启用浮动组字窗、且对组字区内容设定容量上限(最多二十个读音)。";
|
||||||
|
"Add Client" = "登记新客体";
|
||||||
|
"Remove Selected" = "移除所选条目";
|
||||||
|
"Choose the target application bundle." = "请选择要登记的应用程式的封包。";
|
||||||
|
"The selected item is not a valid macOS application bundle." = "当前所选之物并非 macOS 应用程式封包。";
|
||||||
|
"Please try again." = "请重试。";
|
||||||
|
"The selected item's identifier is already in the list." = "当前所选之封包的唯一标帜(Bundle Identifier)已被登记。";
|
||||||
"Update Check Completed" = "更新检查完毕";
|
"Update Check Completed" = "更新检查完毕";
|
||||||
"You are already using the latest version." = "您正在使用目前最新的发行版。";
|
"You are already using the latest version." = "您正在使用目前最新的发行版。";
|
||||||
"Plist downloaded is nil." = "下载来的更新资讯并非 Plist 档案。";
|
"Plist downloaded is nil." = "下载来的更新资讯并非 Plist 档案。";
|
||||||
|
@ -17,7 +28,7 @@
|
||||||
"Update Check Failed" = "无法检查新版";
|
"Update Check Failed" = "无法检查新版";
|
||||||
"There may be no internet connection or the server failed to respond.\n\nError message: %@" = "网路连线失败,或是伺服器没有回应。\n\n错误说明:%@";
|
"There may be no internet connection or the server failed to respond.\n\nError message: %@" = "网路连线失败,或是伺服器没有回应。\n\n错误说明:%@";
|
||||||
"OK" = "确定";
|
"OK" = "确定";
|
||||||
"Dismiss" = "关闭本视窗";
|
"Cancel" = "取消";
|
||||||
"New Version Available" = "有新版可下载";
|
"New Version Available" = "有新版可下载";
|
||||||
"Not Now" = "以后再说";
|
"Not Now" = "以后再说";
|
||||||
"Visit Website" = "前往网站";
|
"Visit Website" = "前往网站";
|
||||||
|
|
|
@ -1,4 +1,15 @@
|
||||||
"vChewing" = "威注音輸入法";
|
"vChewing" = "威注音輸入法";
|
||||||
|
"Please enter the client app bundle identifier(s) you want to register." = "請鍵入您要登記的客體應用的唯一標幟(Bundle Identifier)。";
|
||||||
|
"One record per line. Use Option+Enter to break lines.\nBlank lines will be dismissed." = "每行一筆記錄,用 Option+Enter 換行。\n空白值會被無視。";
|
||||||
|
"Just Select" = "直接選取";
|
||||||
|
"Client Manager" = "管理客體應用";
|
||||||
|
"Please manage the list of IMKTextInput-incompatible clients here. Clients listed here will trigger vChewing's built-in popup composition buffer window with maximum 20 reading counts holdable." = "請在此管理那些不遵守 IMKTextInput 協定的客體應用。威注音輸入法對於任何位列在此的客體應用均啟用浮動組字窗、且對組字區內容設定容量上限(最多二十個讀音)。";
|
||||||
|
"Add Client" = "登記新客體";
|
||||||
|
"Remove Selected" = "移除所選條目";
|
||||||
|
"Choose the target application bundle." = "請選擇要登記的應用程式的封包。";
|
||||||
|
"The selected item is not a valid macOS application bundle." = "當前所選之物並非 macOS 應用程式封包。";
|
||||||
|
"Please try again." = "請重試。";
|
||||||
|
"The selected item's identifier is already in the list." = "當前所選之封包的唯一標幟(Bundle Identifier)已被登記。";
|
||||||
"Update Check Completed" = "更新檢查完畢";
|
"Update Check Completed" = "更新檢查完畢";
|
||||||
"You are already using the latest version." = "您正在使用目前最新的發行版。";
|
"You are already using the latest version." = "您正在使用目前最新的發行版。";
|
||||||
"Plist downloaded is nil." = "下載來的更新資訊並非 Plist 檔案。";
|
"Plist downloaded is nil." = "下載來的更新資訊並非 Plist 檔案。";
|
||||||
|
@ -17,7 +28,7 @@
|
||||||
"Update Check Failed" = "無法檢查新版";
|
"Update Check Failed" = "無法檢查新版";
|
||||||
"There may be no internet connection or the server failed to respond.\n\nError message: %@" = "網路連線失敗,或是伺服器沒有回應。\n\n錯誤說明:%@";
|
"There may be no internet connection or the server failed to respond.\n\nError message: %@" = "網路連線失敗,或是伺服器沒有回應。\n\n錯誤說明:%@";
|
||||||
"OK" = "確定";
|
"OK" = "確定";
|
||||||
"Dismiss" = "關閉本視窗";
|
"Cancel" = "取消";
|
||||||
"New Version Available" = "有新版可下載";
|
"New Version Available" = "有新版可下載";
|
||||||
"Not Now" = "以後再說";
|
"Not Now" = "以後再說";
|
||||||
"Visit Website" = "前往網站";
|
"Visit Website" = "前往網站";
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
// (c) 2011 and onwards The OpenVanilla Project (MIT License).
|
|
||||||
// All possible vChewing-specific modifications are of:
|
|
||||||
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
||||||
// ====================
|
// ====================
|
||||||
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
|
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
|
||||||
|
|
|
@ -0,0 +1,167 @@
|
||||||
|
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
||||||
|
// ====================
|
||||||
|
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
|
||||||
|
// ... with NTL restriction stating that:
|
||||||
|
// No trademark license is granted to use the trade names, trademarks, service
|
||||||
|
// marks, or product names of Contributor, except as required to fulfill notice
|
||||||
|
// requirements defined in MIT License.
|
||||||
|
|
||||||
|
import Cocoa
|
||||||
|
|
||||||
|
class ctlClientListMgr: NSWindowController, NSTableViewDelegate, NSTableViewDataSource {
|
||||||
|
@IBOutlet var tblClients: NSTableView!
|
||||||
|
@IBOutlet var btnRemoveClient: NSButton!
|
||||||
|
@IBOutlet var btnAddClient: NSButton!
|
||||||
|
@IBOutlet var lblClientMgrWindow: NSTextField!
|
||||||
|
override func windowDidLoad() {
|
||||||
|
super.windowDidLoad()
|
||||||
|
localize()
|
||||||
|
tblClients.delegate = self
|
||||||
|
tblClients.dataSource = self
|
||||||
|
tblClients.reloadData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Implementations
|
||||||
|
|
||||||
|
extension ctlClientListMgr {
|
||||||
|
func numberOfRows(in _: NSTableView) -> Int {
|
||||||
|
mgrPrefs.clientsIMKTextInputIncapable.count
|
||||||
|
}
|
||||||
|
|
||||||
|
func callAlert(_ window: NSWindow, title: String, text: String? = nil) {
|
||||||
|
let alert = NSAlert()
|
||||||
|
alert.messageText = title
|
||||||
|
if let text = text {
|
||||||
|
alert.informativeText = text
|
||||||
|
}
|
||||||
|
alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
|
||||||
|
alert.beginSheetModal(for: window)
|
||||||
|
}
|
||||||
|
|
||||||
|
@IBAction func btnAddClientClicked(_: Any) {
|
||||||
|
guard let window = window else { return }
|
||||||
|
let alert = NSAlert()
|
||||||
|
alert.messageText = NSLocalizedString(
|
||||||
|
"Please enter the client app bundle identifier(s) you want to register.", comment: ""
|
||||||
|
)
|
||||||
|
alert.informativeText = NSLocalizedString(
|
||||||
|
"One record per line. Use Option+Enter to break lines.\nBlank lines will be dismissed.", comment: ""
|
||||||
|
)
|
||||||
|
alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
|
||||||
|
alert.addButton(withTitle: NSLocalizedString("Just Select", comment: "") + "…")
|
||||||
|
alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
|
||||||
|
|
||||||
|
let maxFloat = CGFloat(Float.greatestFiniteMagnitude)
|
||||||
|
let scrollview = NSScrollView(frame: NSRect(x: 0, y: 0, width: 370, height: 380))
|
||||||
|
let contentSize = scrollview.contentSize
|
||||||
|
scrollview.borderType = .noBorder
|
||||||
|
scrollview.hasVerticalScroller = true
|
||||||
|
scrollview.hasHorizontalScroller = true
|
||||||
|
scrollview.horizontalScroller?.scrollerStyle = .legacy
|
||||||
|
scrollview.verticalScroller?.scrollerStyle = .legacy
|
||||||
|
scrollview.autoresizingMask = [.width, .height]
|
||||||
|
let theTextView = NSTextView(frame: NSRect(x: 0, y: 0, width: contentSize.width, height: contentSize.height))
|
||||||
|
theTextView.minSize = NSSize(width: 0.0, height: contentSize.height)
|
||||||
|
theTextView.maxSize = NSSize(width: maxFloat, height: maxFloat)
|
||||||
|
theTextView.isVerticallyResizable = true
|
||||||
|
theTextView.isHorizontallyResizable = false
|
||||||
|
theTextView.autoresizingMask = .width
|
||||||
|
theTextView.textContainer?.containerSize = NSSize(width: contentSize.width, height: maxFloat)
|
||||||
|
theTextView.textContainer?.widthTracksTextView = true
|
||||||
|
scrollview.documentView = theTextView
|
||||||
|
theTextView.enclosingScrollView?.hasHorizontalScroller = true
|
||||||
|
theTextView.isHorizontallyResizable = true
|
||||||
|
theTextView.autoresizingMask = [.width, .height]
|
||||||
|
theTextView.textContainer?.containerSize = NSSize(width: maxFloat, height: maxFloat)
|
||||||
|
theTextView.textContainer?.widthTracksTextView = false
|
||||||
|
|
||||||
|
alert.accessoryView = scrollview
|
||||||
|
alert.beginSheetModal(for: window) { result in
|
||||||
|
switch result {
|
||||||
|
case .alertFirstButtonReturn:
|
||||||
|
theTextView.textContainer?.textView?.string.components(separatedBy: "\n").filter { !$0.isEmpty }.forEach {
|
||||||
|
self.applyNewValue($0)
|
||||||
|
}
|
||||||
|
case .alertSecondButtonReturn:
|
||||||
|
IME.dlgOpenPath.title = NSLocalizedString(
|
||||||
|
"Choose the target application bundle.", comment: ""
|
||||||
|
)
|
||||||
|
IME.dlgOpenPath.showsResizeIndicator = true
|
||||||
|
IME.dlgOpenPath.showsHiddenFiles = true
|
||||||
|
IME.dlgOpenPath.canChooseFiles = true
|
||||||
|
IME.dlgOpenPath.canChooseDirectories = false
|
||||||
|
IME.dlgOpenPath.beginSheetModal(for: window) { result in
|
||||||
|
switch result {
|
||||||
|
case .OK:
|
||||||
|
guard let url = IME.dlgOpenPath.url else { return }
|
||||||
|
var title = NSLocalizedString("The selected item is not a valid macOS application bundle.", comment: "")
|
||||||
|
let text = NSLocalizedString("Please try again.", comment: "")
|
||||||
|
guard let bundle = Bundle(url: url) else {
|
||||||
|
self.callAlert(window, title: title, text: text)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
guard let identifier = bundle.bundleIdentifier else {
|
||||||
|
self.callAlert(window, title: title, text: text)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if mgrPrefs.clientsIMKTextInputIncapable.contains(identifier) {
|
||||||
|
title = NSLocalizedString(
|
||||||
|
"The selected item's identifier is already in the list.", comment: ""
|
||||||
|
)
|
||||||
|
self.callAlert(window, title: title)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.applyNewValue(identifier)
|
||||||
|
default: return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default: return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func applyNewValue(_ newValue: String) {
|
||||||
|
guard !newValue.isEmpty else { return }
|
||||||
|
var arrResult = mgrPrefs.clientsIMKTextInputIncapable
|
||||||
|
arrResult.append(newValue)
|
||||||
|
mgrPrefs.clientsIMKTextInputIncapable = arrResult.sorted()
|
||||||
|
tblClients.reloadData()
|
||||||
|
btnRemoveClient.isEnabled = (0..<mgrPrefs.clientsIMKTextInputIncapable.count).contains(
|
||||||
|
tblClients.selectedRow)
|
||||||
|
}
|
||||||
|
|
||||||
|
@IBAction func btnRemoveClientClicked(_: Any) {
|
||||||
|
if tblClients.selectedRow >= mgrPrefs.clientsIMKTextInputIncapable.count { return }
|
||||||
|
if tblClients.selectedRow < 0 { return }
|
||||||
|
let isLastRow: Bool = {
|
||||||
|
if mgrPrefs.clientsIMKTextInputIncapable.count < 2 { return false }
|
||||||
|
return tblClients.selectedRow == mgrPrefs.clientsIMKTextInputIncapable.count - 1
|
||||||
|
}()
|
||||||
|
mgrPrefs.clientsIMKTextInputIncapable.remove(at: tblClients.selectedRow)
|
||||||
|
if isLastRow {
|
||||||
|
tblClients.selectRowIndexes(.init(arrayLiteral: tblClients.selectedRow - 1), byExtendingSelection: false)
|
||||||
|
}
|
||||||
|
tblClients.reloadData()
|
||||||
|
btnRemoveClient.isEnabled = (0..<mgrPrefs.clientsIMKTextInputIncapable.count).contains(tblClients.selectedRow)
|
||||||
|
}
|
||||||
|
|
||||||
|
func tableView(_: NSTableView, objectValueFor _: NSTableColumn?, row: Int) -> Any? {
|
||||||
|
defer {
|
||||||
|
self.btnRemoveClient.isEnabled = (0..<mgrPrefs.clientsIMKTextInputIncapable.count).contains(
|
||||||
|
self.tblClients.selectedRow)
|
||||||
|
}
|
||||||
|
return mgrPrefs.clientsIMKTextInputIncapable[row]
|
||||||
|
}
|
||||||
|
|
||||||
|
private func localize() {
|
||||||
|
guard let window = window else { return }
|
||||||
|
window.title = NSLocalizedString("Client Manager", comment: "")
|
||||||
|
lblClientMgrWindow.stringValue = NSLocalizedString(
|
||||||
|
"Please manage the list of IMKTextInput-incompatible clients here. Clients listed here will trigger vChewing's built-in popup composition buffer window with maximum 20 reading counts holdable.",
|
||||||
|
comment: ""
|
||||||
|
)
|
||||||
|
btnAddClient.title = NSLocalizedString("Add Client", comment: "")
|
||||||
|
btnRemoveClient.title = NSLocalizedString("Remove Selected", comment: "")
|
||||||
|
}
|
||||||
|
}
|
|
@ -55,7 +55,7 @@
|
||||||
</textField>
|
</textField>
|
||||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8M8-3C-BZO">
|
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8M8-3C-BZO">
|
||||||
<rect key="frame" x="89" y="387" width="431" height="15"/>
|
<rect key="frame" x="89" y="387" width="431" height="15"/>
|
||||||
<textFieldCell key="cell" selectable="YES" title="Placeholder for detailed credits." id="lblCredits">
|
<textFieldCell key="cell" title="Placeholder for detailed credits." id="lblCredits">
|
||||||
<font key="font" size="12" name="Tahoma"/>
|
<font key="font" size="12" name="Tahoma"/>
|
||||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
@ -77,7 +77,7 @@
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="width" constant="356" id="B0d-48-3we"/>
|
<constraint firstAttribute="width" constant="356" id="B0d-48-3we"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<textFieldCell key="cell" selectable="YES" id="lblDisclaimer">
|
<textFieldCell key="cell" id="lblDisclaimer">
|
||||||
<font key="font" size="12" name="Tahoma"/>
|
<font key="font" size="12" name="Tahoma"/>
|
||||||
<string key="title">DISCLAIMER: The vChewing project, having no relationship of cooperation or affiliation with the OpenVanilla project, is not responsible for the phrase database shipped in the original McBopomofo project. Certain geopolitical and ideological contents, which are potentially harmful to the global spread of this software, are not included in vChewing official phrase database.</string>
|
<string key="title">DISCLAIMER: The vChewing project, having no relationship of cooperation or affiliation with the OpenVanilla project, is not responsible for the phrase database shipped in the original McBopomofo project. Certain geopolitical and ideological contents, which are potentially harmful to the global spread of this software, are not included in vChewing official phrase database.</string>
|
||||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21225" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||||
|
<dependencies>
|
||||||
|
<deployment identifier="macosx"/>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21225"/>
|
||||||
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
|
</dependencies>
|
||||||
|
<objects>
|
||||||
|
<customObject id="-2" userLabel="File's Owner" customClass="ctlClientListMgr" customModule="vChewing" customModuleProvider="target">
|
||||||
|
<connections>
|
||||||
|
<outlet property="btnAddClient" destination="JcI-Ff-tDM" id="XbA-OK-zl8"/>
|
||||||
|
<outlet property="btnRemoveClient" destination="UNR-wG-8n1" id="vkb-81-1hA"/>
|
||||||
|
<outlet property="lblClientMgrWindow" destination="3ev-ns-FKY" id="VqL-RC-OdY"/>
|
||||||
|
<outlet property="tblClients" destination="vIw-vc-WKJ" id="2lw-U5-JAh"/>
|
||||||
|
<outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
|
||||||
|
</connections>
|
||||||
|
</customObject>
|
||||||
|
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||||
|
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||||
|
<window title="Client Manager" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" titlebarAppearsTransparent="YES" id="F0z-JX-Cv5">
|
||||||
|
<windowStyleMask key="styleMask" titled="YES" closable="YES" fullSizeContentView="YES"/>
|
||||||
|
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||||
|
<rect key="contentRect" x="196" y="240" width="664" height="335"/>
|
||||||
|
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1055"/>
|
||||||
|
<view key="contentView" id="se5-gp-TjO" customClass="NSVisualEffectView" customModule="vChewing" customModuleProvider="target">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="664" height="335"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<subviews>
|
||||||
|
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="3ev-ns-FKY" userLabel="lblClientMgrWindow">
|
||||||
|
<rect key="frame" x="18" y="20" width="494" height="46"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="height" constant="46" id="HDu-vv-Kcv"/>
|
||||||
|
<constraint firstAttribute="width" constant="490" id="LhL-fH-PVL"/>
|
||||||
|
</constraints>
|
||||||
|
<textFieldCell key="cell" title="Placeholder for description texts." id="hvd-Wx-n7n">
|
||||||
|
<font key="font" metaFont="smallSystem"/>
|
||||||
|
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
</textField>
|
||||||
|
<scrollView autohidesScrollers="YES" horizontalLineScroll="24" horizontalPageScroll="10" verticalLineScroll="24" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="MUP-Im-g6c">
|
||||||
|
<rect key="frame" x="20" y="76" width="624" height="232"/>
|
||||||
|
<clipView key="contentView" id="wKQ-IV-k62">
|
||||||
|
<rect key="frame" x="1" y="1" width="622" height="230"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<subviews>
|
||||||
|
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" tableStyle="inset" multipleSelection="NO" autosaveColumns="NO" rowHeight="24" id="vIw-vc-WKJ" userLabel="tblClients">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="622" height="230"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<size key="intercellSpacing" width="17" height="0.0"/>
|
||||||
|
<color key="backgroundColor" name="_sourceListBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<tableColumns>
|
||||||
|
<tableColumn identifier="AutomaticTableColumnIdentifier.0" width="590" minWidth="40" maxWidth="1000" id="kWw-Lj-EFx">
|
||||||
|
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
|
||||||
|
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</tableHeaderCell>
|
||||||
|
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="evF-0c-DTr">
|
||||||
|
<font key="font" metaFont="system" size="20"/>
|
||||||
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||||
|
</tableColumn>
|
||||||
|
</tableColumns>
|
||||||
|
</tableView>
|
||||||
|
</subviews>
|
||||||
|
<nil key="backgroundColor"/>
|
||||||
|
</clipView>
|
||||||
|
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="6Wq-mB-m8K">
|
||||||
|
<rect key="frame" x="1" y="215" width="622" height="16"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
</scroller>
|
||||||
|
<scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="rYb-HR-4th">
|
||||||
|
<rect key="frame" x="224" y="17" width="15" height="102"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
</scroller>
|
||||||
|
</scrollView>
|
||||||
|
<customView translatesAutoresizingMaskIntoConstraints="NO" id="qCN-8Z-3x3">
|
||||||
|
<rect key="frame" x="518" y="20" width="126" height="46"/>
|
||||||
|
<subviews>
|
||||||
|
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="JcI-Ff-tDM" userLabel="btnAddClient">
|
||||||
|
<rect key="frame" x="-7" y="19" width="140" height="32"/>
|
||||||
|
<buttonCell key="cell" type="push" title="Add" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="7rO-JZ-kgV">
|
||||||
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
</buttonCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="btnAddClientClicked:" target="-2" id="klb-NT-gqr"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="UNR-wG-8n1" userLabel="btnRemoveClient">
|
||||||
|
<rect key="frame" x="-7" y="-7" width="140" height="32"/>
|
||||||
|
<buttonCell key="cell" type="push" title="Remove" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="wNc-xy-U4i">
|
||||||
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
</buttonCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="btnRemoveClientClicked:" target="-2" id="VbY-dw-fRP"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
</subviews>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstItem="JcI-Ff-tDM" firstAttribute="trailing" secondItem="UNR-wG-8n1" secondAttribute="trailing" id="3Fe-KL-u9x"/>
|
||||||
|
<constraint firstAttribute="bottom" secondItem="UNR-wG-8n1" secondAttribute="bottom" id="5MS-Xg-KDM"/>
|
||||||
|
<constraint firstItem="JcI-Ff-tDM" firstAttribute="top" secondItem="qCN-8Z-3x3" secondAttribute="top" id="DZc-Jc-kVr"/>
|
||||||
|
<constraint firstAttribute="trailing" secondItem="JcI-Ff-tDM" secondAttribute="trailing" id="foA-xu-NF8"/>
|
||||||
|
<constraint firstItem="JcI-Ff-tDM" firstAttribute="leading" secondItem="UNR-wG-8n1" secondAttribute="leading" id="hOp-FU-UKN"/>
|
||||||
|
<constraint firstItem="JcI-Ff-tDM" firstAttribute="leading" secondItem="qCN-8Z-3x3" secondAttribute="leading" id="r1x-vo-9qt"/>
|
||||||
|
</constraints>
|
||||||
|
</customView>
|
||||||
|
</subviews>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstItem="3ev-ns-FKY" firstAttribute="top" secondItem="MUP-Im-g6c" secondAttribute="bottom" constant="10" id="2tx-uw-Zdh"/>
|
||||||
|
<constraint firstAttribute="bottom" secondItem="3ev-ns-FKY" secondAttribute="bottom" constant="20" symbolic="YES" id="9KE-bP-0Yi"/>
|
||||||
|
<constraint firstItem="MUP-Im-g6c" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="27" id="BkF-ED-Uva"/>
|
||||||
|
<constraint firstAttribute="trailing" secondItem="MUP-Im-g6c" secondAttribute="trailing" constant="20" symbolic="YES" id="E0U-Vh-g3t"/>
|
||||||
|
<constraint firstItem="MUP-Im-g6c" firstAttribute="trailing" secondItem="qCN-8Z-3x3" secondAttribute="trailing" id="TqZ-q6-quu"/>
|
||||||
|
<constraint firstItem="MUP-Im-g6c" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="20" symbolic="YES" id="WXt-cJ-HaW"/>
|
||||||
|
<constraint firstItem="3ev-ns-FKY" firstAttribute="top" secondItem="qCN-8Z-3x3" secondAttribute="top" id="b4O-RW-K56"/>
|
||||||
|
<constraint firstItem="MUP-Im-g6c" firstAttribute="leading" secondItem="3ev-ns-FKY" secondAttribute="leading" id="g8i-I5-2Dw"/>
|
||||||
|
<constraint firstItem="3ev-ns-FKY" firstAttribute="bottom" secondItem="qCN-8Z-3x3" secondAttribute="bottom" id="ktC-2I-aWz"/>
|
||||||
|
<constraint firstItem="qCN-8Z-3x3" firstAttribute="leading" secondItem="3ev-ns-FKY" secondAttribute="trailing" constant="8" symbolic="YES" id="opE-OC-8Dh"/>
|
||||||
|
</constraints>
|
||||||
|
</view>
|
||||||
|
<connections>
|
||||||
|
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
|
||||||
|
</connections>
|
||||||
|
<point key="canvasLocation" x="231" y="176.5"/>
|
||||||
|
</window>
|
||||||
|
</objects>
|
||||||
|
</document>
|
|
@ -3,9 +3,9 @@
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>2.5.0</string>
|
<string>2.6.0</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>2500</string>
|
<string>2600</string>
|
||||||
<key>UpdateInfoEndpoint</key>
|
<key>UpdateInfoEndpoint</key>
|
||||||
<string>https://gitee.com/vchewing/vChewing-macOS/raw/main/Update-Info.plist</string>
|
<string>https://gitee.com/vchewing/vChewing-macOS/raw/main/Update-Info.plist</string>
|
||||||
<key>UpdateInfoSite</key>
|
<key>UpdateInfoSite</key>
|
||||||
|
|
|
@ -32,6 +32,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
ctlAboutWindowInstance?.window?.center()
|
ctlAboutWindowInstance?.window?.center()
|
||||||
ctlAboutWindowInstance?.window?.orderFrontRegardless() // 逼著關於視窗往最前方顯示
|
ctlAboutWindowInstance?.window?.orderFrontRegardless() // 逼著關於視窗往最前方顯示
|
||||||
ctlAboutWindowInstance?.window?.level = .statusBar
|
ctlAboutWindowInstance?.window?.level = .statusBar
|
||||||
|
ctlAboutWindowInstance?.window?.titlebarAppearsTransparent = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call the New About Window
|
// Call the New About Window
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
</textField>
|
</textField>
|
||||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8M8-3C-BZO">
|
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8M8-3C-BZO">
|
||||||
<rect key="frame" x="89" y="372" width="431" height="30"/>
|
<rect key="frame" x="89" y="372" width="431" height="30"/>
|
||||||
<textFieldCell key="cell" selectable="YES" id="lblCredits">
|
<textFieldCell key="cell" id="lblCredits">
|
||||||
<font key="font" size="12" name="Tahoma"/>
|
<font key="font" size="12" name="Tahoma"/>
|
||||||
<string key="title">vChewing Phrase Editor developed by Shiki Suen.
|
<string key="title">vChewing Phrase Editor developed by Shiki Suen.
|
||||||
vChewing Phrase Database Maintained by Shiki Suen.</string>
|
vChewing Phrase Database Maintained by Shiki Suen.</string>
|
||||||
|
@ -79,7 +79,7 @@ vChewing Phrase Database Maintained by Shiki Suen.</string>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="width" constant="356" id="B0d-48-3we"/>
|
<constraint firstAttribute="width" constant="356" id="B0d-48-3we"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<textFieldCell key="cell" selectable="YES" id="lblDisclaimer">
|
<textFieldCell key="cell" id="lblDisclaimer">
|
||||||
<font key="font" size="12" name="Tahoma"/>
|
<font key="font" size="12" name="Tahoma"/>
|
||||||
<string key="title">DISCLAIMER: The vChewing project, having no relationship of cooperation or affiliation with the OpenVanilla project, is not responsible for the phrase database shipped in the original McBopomofo project. Certain geopolitical and ideological contents, which are potentially harmful to the global spread of this software, are not included in vChewing official phrase database.</string>
|
<string key="title">DISCLAIMER: The vChewing project, having no relationship of cooperation or affiliation with the OpenVanilla project, is not responsible for the phrase database shipped in the original McBopomofo project. Certain geopolitical and ideological contents, which are potentially harmful to the global spread of this software, are not included in vChewing official phrase database.</string>
|
||||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
// (c) 2011 and onwards The OpenVanilla Project (MIT License).
|
|
||||||
// All possible vChewing-specific modifications are of:
|
|
||||||
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
||||||
// ====================
|
// ====================
|
||||||
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
|
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
|
||||||
|
|
|
@ -726,7 +726,7 @@
|
||||||
<key>USE_HFS+_COMPRESSION</key>
|
<key>USE_HFS+_COMPRESSION</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>VERSION</key>
|
<key>VERSION</key>
|
||||||
<string>2.5.0</string>
|
<string>2.6.0</string>
|
||||||
</dict>
|
</dict>
|
||||||
<key>TYPE</key>
|
<key>TYPE</key>
|
||||||
<integer>0</integer>
|
<integer>0</integer>
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
5B09307628B6FC3B0021F8C5 /* shortcuts.html in Resources */ = {isa = PBXBuildFile; fileRef = 5B09307828B6FC3B0021F8C5 /* shortcuts.html */; };
|
5B09307628B6FC3B0021F8C5 /* shortcuts.html in Resources */ = {isa = PBXBuildFile; fileRef = 5B09307828B6FC3B0021F8C5 /* shortcuts.html */; };
|
||||||
5B0AF8B527B2C8290096FE54 /* StringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B0AF8B427B2C8290096FE54 /* StringExtension.swift */; };
|
5B0AF8B527B2C8290096FE54 /* StringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B0AF8B427B2C8290096FE54 /* StringExtension.swift */; };
|
||||||
|
5B0EF55D28CDBF7100F8F7CE /* frmClientListMgr.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5B0EF55C28CDBF7100F8F7CE /* frmClientListMgr.xib */; };
|
||||||
|
5B0EF55F28CDBF8E00F8F7CE /* ctlClientListMgr.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B0EF55E28CDBF8E00F8F7CE /* ctlClientListMgr.swift */; };
|
||||||
5B11328927B94CFB00E58451 /* AppleKeyboardConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B11328827B94CFB00E58451 /* AppleKeyboardConverter.swift */; };
|
5B11328927B94CFB00E58451 /* AppleKeyboardConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B11328827B94CFB00E58451 /* AppleKeyboardConverter.swift */; };
|
||||||
5B16B84C28C9A89000ABA692 /* FolderMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B16B84B28C9A89000ABA692 /* FolderMonitor.swift */; };
|
5B16B84C28C9A89000ABA692 /* FolderMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B16B84B28C9A89000ABA692 /* FolderMonitor.swift */; };
|
||||||
5B175FFB28C5CDDC0078D1B4 /* IMKHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B175FFA28C5CDDC0078D1B4 /* IMKHelper.swift */; };
|
5B175FFB28C5CDDC0078D1B4 /* IMKHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B175FFA28C5CDDC0078D1B4 /* IMKHelper.swift */; };
|
||||||
|
@ -39,6 +41,7 @@
|
||||||
5B62A33D27AE7CC100A19448 /* ctlAboutWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A33C27AE7CC100A19448 /* ctlAboutWindow.swift */; };
|
5B62A33D27AE7CC100A19448 /* ctlAboutWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A33C27AE7CC100A19448 /* ctlAboutWindow.swift */; };
|
||||||
5B62A34727AE7CD900A19448 /* ctlCandidate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A34027AE7CD900A19448 /* ctlCandidate.swift */; };
|
5B62A34727AE7CD900A19448 /* ctlCandidate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A34027AE7CD900A19448 /* ctlCandidate.swift */; };
|
||||||
5B62A34A27AE7CD900A19448 /* NotifierController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A34527AE7CD900A19448 /* NotifierController.swift */; };
|
5B62A34A27AE7CD900A19448 /* NotifierController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A34527AE7CD900A19448 /* NotifierController.swift */; };
|
||||||
|
5B630A3C28CC97020010D076 /* ctlPopupCompositionBuffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B630A3B28CC97020010D076 /* ctlPopupCompositionBuffer.swift */; };
|
||||||
5B6C141228A9D4B30098ADF8 /* ctlInputMethod_Common.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6C141128A9D4B30098ADF8 /* ctlInputMethod_Common.swift */; };
|
5B6C141228A9D4B30098ADF8 /* ctlInputMethod_Common.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6C141128A9D4B30098ADF8 /* ctlInputMethod_Common.swift */; };
|
||||||
5B73FB5E27B2BE1300E9BF49 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5B73FB6027B2BE1300E9BF49 /* InfoPlist.strings */; };
|
5B73FB5E27B2BE1300E9BF49 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5B73FB6027B2BE1300E9BF49 /* InfoPlist.strings */; };
|
||||||
5B782EC4280C243C007276DE /* KeyHandler_HandleCandidate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B782EC3280C243C007276DE /* KeyHandler_HandleCandidate.swift */; };
|
5B782EC4280C243C007276DE /* KeyHandler_HandleCandidate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B782EC3280C243C007276DE /* KeyHandler_HandleCandidate.swift */; };
|
||||||
|
@ -210,6 +213,8 @@
|
||||||
5B09307B28B6FC410021F8C5 /* ja */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; lineEnding = 0; name = ja; path = ja.lproj/shortcuts.html; sourceTree = "<group>"; };
|
5B09307B28B6FC410021F8C5 /* ja */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; lineEnding = 0; name = ja; path = ja.lproj/shortcuts.html; sourceTree = "<group>"; };
|
||||||
5B0AF8B427B2C8290096FE54 /* StringExtension.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = StringExtension.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
5B0AF8B427B2C8290096FE54 /* StringExtension.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = StringExtension.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
||||||
5B0C5EDF27C7D9870078037C /* dataCompiler.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = dataCompiler.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
5B0C5EDF27C7D9870078037C /* dataCompiler.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = dataCompiler.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
||||||
|
5B0EF55C28CDBF7100F8F7CE /* frmClientListMgr.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = frmClientListMgr.xib; sourceTree = "<group>"; };
|
||||||
|
5B0EF55E28CDBF8E00F8F7CE /* ctlClientListMgr.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ctlClientListMgr.swift; sourceTree = "<group>"; };
|
||||||
5B11328827B94CFB00E58451 /* AppleKeyboardConverter.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = AppleKeyboardConverter.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
5B11328827B94CFB00E58451 /* AppleKeyboardConverter.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = AppleKeyboardConverter.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
||||||
5B16B84B28C9A89000ABA692 /* FolderMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FolderMonitor.swift; sourceTree = "<group>"; };
|
5B16B84B28C9A89000ABA692 /* FolderMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FolderMonitor.swift; sourceTree = "<group>"; };
|
||||||
5B175FFA28C5CDDC0078D1B4 /* IMKHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IMKHelper.swift; sourceTree = "<group>"; };
|
5B175FFA28C5CDDC0078D1B4 /* IMKHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IMKHelper.swift; sourceTree = "<group>"; };
|
||||||
|
@ -253,6 +258,7 @@
|
||||||
5B62A33C27AE7CC100A19448 /* ctlAboutWindow.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = ctlAboutWindow.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
5B62A33C27AE7CC100A19448 /* ctlAboutWindow.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = ctlAboutWindow.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
||||||
5B62A34027AE7CD900A19448 /* ctlCandidate.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = ctlCandidate.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
5B62A34027AE7CD900A19448 /* ctlCandidate.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = ctlCandidate.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
||||||
5B62A34527AE7CD900A19448 /* NotifierController.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = NotifierController.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
5B62A34527AE7CD900A19448 /* NotifierController.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = NotifierController.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
||||||
|
5B630A3B28CC97020010D076 /* ctlPopupCompositionBuffer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ctlPopupCompositionBuffer.swift; sourceTree = "<group>"; };
|
||||||
5B65B919284D0185007C558B /* README-CHT.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = "README-CHT.md"; sourceTree = "<group>"; };
|
5B65B919284D0185007C558B /* README-CHT.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = "README-CHT.md"; sourceTree = "<group>"; };
|
||||||
5B6C141128A9D4B30098ADF8 /* ctlInputMethod_Common.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ctlInputMethod_Common.swift; sourceTree = "<group>"; };
|
5B6C141128A9D4B30098ADF8 /* ctlInputMethod_Common.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ctlInputMethod_Common.swift; sourceTree = "<group>"; };
|
||||||
5B73FB5427B2BD6900E9BF49 /* PhraseEditor-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "PhraseEditor-Info.plist"; path = "UserPhraseEditor/PhraseEditor-Info.plist"; sourceTree = SOURCE_ROOT; };
|
5B73FB5427B2BD6900E9BF49 /* PhraseEditor-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "PhraseEditor-Info.plist"; path = "UserPhraseEditor/PhraseEditor-Info.plist"; sourceTree = SOURCE_ROOT; };
|
||||||
|
@ -581,6 +587,7 @@
|
||||||
children = (
|
children = (
|
||||||
5B62A33E27AE7CD900A19448 /* CandidateUI */,
|
5B62A33E27AE7CD900A19448 /* CandidateUI */,
|
||||||
5B62A34427AE7CD900A19448 /* NotifierUI */,
|
5B62A34427AE7CD900A19448 /* NotifierUI */,
|
||||||
|
5B630A3A28CC96D80010D076 /* PopupCompositionBufferUI */,
|
||||||
5BA9FD0927FED9F3002DE248 /* PrefUI */,
|
5BA9FD0927FED9F3002DE248 /* PrefUI */,
|
||||||
5B62A34227AE7CD900A19448 /* TooltipUI */,
|
5B62A34227AE7CD900A19448 /* TooltipUI */,
|
||||||
);
|
);
|
||||||
|
@ -591,6 +598,7 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
5B62A33C27AE7CC100A19448 /* ctlAboutWindow.swift */,
|
5B62A33C27AE7CC100A19448 /* ctlAboutWindow.swift */,
|
||||||
|
5B0EF55E28CDBF8E00F8F7CE /* ctlClientListMgr.swift */,
|
||||||
D47F7DCD278BFB57002F9DD7 /* ctlPrefWindow.swift */,
|
D47F7DCD278BFB57002F9DD7 /* ctlPrefWindow.swift */,
|
||||||
);
|
);
|
||||||
path = WindowControllers;
|
path = WindowControllers;
|
||||||
|
@ -599,6 +607,7 @@
|
||||||
5B62A33B27AE7C7F00A19448 /* WindowNIBs */ = {
|
5B62A33B27AE7C7F00A19448 /* WindowNIBs */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
5B0EF55C28CDBF7100F8F7CE /* frmClientListMgr.xib */,
|
||||||
5BBBB76927AED5DB0023B93A /* frmAboutWindow.xib */,
|
5BBBB76927AED5DB0023B93A /* frmAboutWindow.xib */,
|
||||||
5B7BC4AE27AFFBE800F66C24 /* frmPrefWindow.xib */,
|
5B7BC4AE27AFFBE800F66C24 /* frmPrefWindow.xib */,
|
||||||
6A187E2816004C5900466B2E /* MainMenu.xib */,
|
6A187E2816004C5900466B2E /* MainMenu.xib */,
|
||||||
|
@ -645,6 +654,14 @@
|
||||||
name = Data;
|
name = Data;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
5B630A3A28CC96D80010D076 /* PopupCompositionBufferUI */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
5B630A3B28CC97020010D076 /* ctlPopupCompositionBuffer.swift */,
|
||||||
|
);
|
||||||
|
path = PopupCompositionBufferUI;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
5B84579B2871AD2200C93B01 /* HotenkaChineseConverter */ = {
|
5B84579B2871AD2200C93B01 /* HotenkaChineseConverter */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -1068,6 +1085,7 @@
|
||||||
D4E33D8A27A838CF006DB1CF /* Localizable.strings in Resources */,
|
D4E33D8A27A838CF006DB1CF /* Localizable.strings in Resources */,
|
||||||
5BF9DA2828840E6200DBD48E /* template-exclusions.txt in Resources */,
|
5BF9DA2828840E6200DBD48E /* template-exclusions.txt in Resources */,
|
||||||
5B7DA80328BF6BC600D7B2AD /* fixinstall.sh in Resources */,
|
5B7DA80328BF6BC600D7B2AD /* fixinstall.sh in Resources */,
|
||||||
|
5B0EF55D28CDBF7100F8F7CE /* frmClientListMgr.xib in Resources */,
|
||||||
5BDCBB2E27B4E67A00D0CC59 /* vChewingPhraseEditor.app in Resources */,
|
5BDCBB2E27B4E67A00D0CC59 /* vChewingPhraseEditor.app in Resources */,
|
||||||
5BBBB76027AED54C0023B93A /* Fart.m4a in Resources */,
|
5BBBB76027AED54C0023B93A /* Fart.m4a in Resources */,
|
||||||
6A2E40F6253A69DA00D1AE1D /* Images.xcassets in Resources */,
|
6A2E40F6253A69DA00D1AE1D /* Images.xcassets in Resources */,
|
||||||
|
@ -1214,6 +1232,7 @@
|
||||||
5B5F8AEE28C8826D007C11F1 /* ctlTooltip.swift in Sources */,
|
5B5F8AEE28C8826D007C11F1 /* ctlTooltip.swift in Sources */,
|
||||||
5BD0113B28180D6100609769 /* LMInstantiator.swift in Sources */,
|
5BD0113B28180D6100609769 /* LMInstantiator.swift in Sources */,
|
||||||
5B2170E7289FACAD00BE7304 /* 1_Compositor.swift in Sources */,
|
5B2170E7289FACAD00BE7304 /* 1_Compositor.swift in Sources */,
|
||||||
|
5B0EF55F28CDBF8E00F8F7CE /* ctlClientListMgr.swift in Sources */,
|
||||||
5B21177028753B9D000443A9 /* ctlInputMethod_Delegates.swift in Sources */,
|
5B21177028753B9D000443A9 /* ctlInputMethod_Delegates.swift in Sources */,
|
||||||
5B21176E28753B35000443A9 /* ctlInputMethod_HandleDisplay.swift in Sources */,
|
5B21176E28753B35000443A9 /* ctlInputMethod_HandleDisplay.swift in Sources */,
|
||||||
5B84579F2871AD2200C93B01 /* HotenkaChineseConverter.swift in Sources */,
|
5B84579F2871AD2200C93B01 /* HotenkaChineseConverter.swift in Sources */,
|
||||||
|
@ -1268,6 +1287,7 @@
|
||||||
5BA9FD1327FEDB6B002DE248 /* suiPrefPaneDictionary.swift in Sources */,
|
5BA9FD1327FEDB6B002DE248 /* suiPrefPaneDictionary.swift in Sources */,
|
||||||
5B2170E8289FACAD00BE7304 /* 5_Vertex.swift in Sources */,
|
5B2170E8289FACAD00BE7304 /* 5_Vertex.swift in Sources */,
|
||||||
5BBBB77A27AEDC690023B93A /* clsSFX.swift in Sources */,
|
5BBBB77A27AEDC690023B93A /* clsSFX.swift in Sources */,
|
||||||
|
5B630A3C28CC97020010D076 /* ctlPopupCompositionBuffer.swift in Sources */,
|
||||||
5BA9FD4727FEF3C9002DE248 /* PreferencesStyleController.swift in Sources */,
|
5BA9FD4727FEF3C9002DE248 /* PreferencesStyleController.swift in Sources */,
|
||||||
5B949BDB2816DDBC00D87B5D /* LMConsolidator.swift in Sources */,
|
5B949BDB2816DDBC00D87B5D /* LMConsolidator.swift in Sources */,
|
||||||
5BFDF011289635C100417BBC /* ctlCandidateIMK.swift in Sources */,
|
5BFDF011289635C100417BBC /* ctlCandidateIMK.swift in Sources */,
|
||||||
|
@ -1463,7 +1483,7 @@
|
||||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 2500;
|
CURRENT_PROJECT_VERSION = 2600;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GCC_DYNAMIC_NO_PIC = NO;
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
@ -1473,7 +1493,7 @@
|
||||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
MARKETING_VERSION = 2.5.0;
|
MARKETING_VERSION = 2.6.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewingTests;
|
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewingTests;
|
||||||
|
@ -1502,13 +1522,13 @@
|
||||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 2500;
|
CURRENT_PROJECT_VERSION = 2600;
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
MARKETING_VERSION = 2.5.0;
|
MARKETING_VERSION = 2.6.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewingTests;
|
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewingTests;
|
||||||
|
@ -1540,7 +1560,7 @@
|
||||||
CODE_SIGN_IDENTITY = "-";
|
CODE_SIGN_IDENTITY = "-";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 2500;
|
CURRENT_PROJECT_VERSION = 2600;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
|
@ -1562,7 +1582,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 2.5.0;
|
MARKETING_VERSION = 2.6.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewing.vChewingPhraseEditor;
|
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewing.vChewingPhraseEditor;
|
||||||
|
@ -1592,7 +1612,7 @@
|
||||||
CODE_SIGN_IDENTITY = "-";
|
CODE_SIGN_IDENTITY = "-";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 2500;
|
CURRENT_PROJECT_VERSION = 2600;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
|
@ -1610,7 +1630,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 2.5.0;
|
MARKETING_VERSION = 2.6.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewing.vChewingPhraseEditor;
|
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewing.vChewingPhraseEditor;
|
||||||
|
@ -1726,7 +1746,7 @@
|
||||||
CODE_SIGN_IDENTITY = "-";
|
CODE_SIGN_IDENTITY = "-";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 2500;
|
CURRENT_PROJECT_VERSION = 2600;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEVELOPMENT_ASSET_PATHS = "";
|
DEVELOPMENT_ASSET_PATHS = "";
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
|
@ -1755,7 +1775,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 2.5.0;
|
MARKETING_VERSION = 2.6.0;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.inputmethod.vChewing;
|
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.inputmethod.vChewing;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
@ -1785,7 +1805,7 @@
|
||||||
CODE_SIGN_IDENTITY = "-";
|
CODE_SIGN_IDENTITY = "-";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 2500;
|
CURRENT_PROJECT_VERSION = 2600;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEVELOPMENT_ASSET_PATHS = "";
|
DEVELOPMENT_ASSET_PATHS = "";
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
|
@ -1808,7 +1828,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 2.5.0;
|
MARKETING_VERSION = 2.6.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.inputmethod.vChewing;
|
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.inputmethod.vChewing;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
@ -1832,7 +1852,7 @@
|
||||||
CODE_SIGN_IDENTITY = "-";
|
CODE_SIGN_IDENTITY = "-";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 2500;
|
CURRENT_PROJECT_VERSION = 2600;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
|
@ -1853,7 +1873,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 2.5.0;
|
MARKETING_VERSION = 2.6.0;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewing.vChewingInstaller;
|
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewing.vChewingInstaller;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
@ -1876,7 +1896,7 @@
|
||||||
CODE_SIGN_IDENTITY = "-";
|
CODE_SIGN_IDENTITY = "-";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 2500;
|
CURRENT_PROJECT_VERSION = 2600;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
|
@ -1891,7 +1911,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 2.5.0;
|
MARKETING_VERSION = 2.6.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewing.vChewingInstaller;
|
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewing.vChewingInstaller;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
|
Loading…
Reference in New Issue