2.5.0 // Tooltip, etc. Merge PR #129 from upd/2.5.0
This commit is contained in:
commit
738aec4260
2
AUTHORS
2
AUTHORS
|
@ -18,10 +18,8 @@ $ Contributors and volunteers of the upstream repo, having no responsibility in
|
||||||
- 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 and Tooltip UI.
|
||||||
- FSEventStreamHelper.
|
|
||||||
- App-style installer (only preserved for developer purposes).
|
- App-style installer (only preserved for developer purposes).
|
||||||
- mgrPrefs (userdefaults manager).
|
- mgrPrefs (userdefaults manager).
|
||||||
- apiUpdate.
|
|
||||||
- Mengjuei Hsieh:
|
- Mengjuei Hsieh:
|
||||||
- McBopomofo for macOS 1.x main developer and architect.
|
- McBopomofo for macOS 1.x main developer and architect.
|
||||||
- The original C++ version of the User Override Module.
|
- The original C++ version of the User Override Module.
|
||||||
|
|
|
@ -82,13 +82,11 @@
|
||||||
|
|
||||||
## 應用授權
|
## 應用授權
|
||||||
|
|
||||||
威注音專案僅用到小麥注音的下述程式組件(MIT License):
|
威注音專案目前僅用到小麥注音的下述程式組件(MIT License):
|
||||||
|
|
||||||
- 狀態管理引擎 & NSStringUtils & FSEventStreamHelper (by Zonble Yang),基於狀態設計模式:
|
|
||||||
- ctlInputMethod 輸入法主控制器內則採用策略設計模式來處理各種狀態。
|
|
||||||
- 半衰記憶模組的 C++ 原版作者是 Mengjuei Hsieh,且由 Shiki Suen 用 Swift 與 C# 分別重寫、繼續開發。
|
- 半衰記憶模組的 C++ 原版作者是 Mengjuei Hsieh,且由 Shiki Suen 用 Swift 與 C# 分別重寫、繼續開發。
|
||||||
- 僅供研發人員調試方便而使用的 App 版安裝程式 (by Zonble Yang),不對公眾使用。
|
- 僅供研發人員調試方便而使用的 App 版安裝程式 (by Zonble Yang),不對公眾使用。
|
||||||
- Voltaire MK2 選字窗、飄雲通知視窗、工具提示 (by Zonble Yang),有大幅度修改。
|
- Voltaire MK2 選字窗、飄雲通知視窗 (by Zonble Yang),有大幅度修改。
|
||||||
|
|
||||||
威注音輸入法 macOS 版以 MIT-NTL License 授權釋出 (與 MIT 相容):© 2021-2022 vChewing 專案。
|
威注音輸入法 macOS 版以 MIT-NTL License 授權釋出 (與 MIT 相容):© 2021-2022 vChewing 專案。
|
||||||
|
|
||||||
|
|
|
@ -82,13 +82,11 @@
|
||||||
|
|
||||||
## 应用授权
|
## 应用授权
|
||||||
|
|
||||||
威注音专案仅用到小麦注音的下述程式组件(MIT License):
|
威注音专案目前仅用到小麦注音的下述程式组件(MIT License):
|
||||||
|
|
||||||
- 状态管理引擎 & NSStringUtils & FSEventStreamHelper (by Zonble Yang),基于状态设计模式:
|
|
||||||
- ctlInputMethod 输入法主控制器内则采用策略设计模式来处理各种状态。
|
|
||||||
- 半衰记忆模组的 C++ 原版作者是 Mengjuei Hsieh,且由 Shiki Suen 用 Swift 与 C# 分别重写、继续开发。
|
- 半衰记忆模组的 C++ 原版作者是 Mengjuei Hsieh,且由 Shiki Suen 用 Swift 与 C# 分别重写、继续开发。
|
||||||
- 仅供研发人员调试方便而使用的 App 版安装程式 (by Zonble Yang),不对公众使用。
|
- 仅供研发人员调试方便而使用的 App 版安装程式 (by Zonble Yang),不对公众使用。
|
||||||
- Voltaire MK2 选字窗、飘云通知视窗、工具提示 (by Zonble Yang),有大幅度修改。
|
- Voltaire MK2 选字窗、飘云通知视窗 (by Zonble Yang),有大幅度修改。
|
||||||
|
|
||||||
威注音输入法 macOS 版以 MIT-NTL License 授权释出 (与 MIT 相容):© 2021-2022 vChewing 专案。
|
威注音输入法 macOS 版以 MIT-NTL License 授权释出 (与 MIT 相容):© 2021-2022 vChewing 专案。
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
// (c) 2018 Daniel Galasko
|
||||||
|
// Ref: https://medium.com/over-engineering/monitoring-a-folder-for-changes-in-ios-dc3f8614f902
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
class FolderMonitor {
|
||||||
|
// MARK: Properties
|
||||||
|
|
||||||
|
/// A file descriptor for the monitored directory.
|
||||||
|
private var monitoredFolderFileDescriptor: CInt = -1
|
||||||
|
/// A dispatch queue used for sending file changes in the directory.
|
||||||
|
private let folderMonitorQueue = DispatchQueue(label: "FolderMonitorQueue", attributes: .concurrent)
|
||||||
|
/// A dispatch source to monitor a file descriptor created from the directory.
|
||||||
|
private var folderMonitorSource: DispatchSourceFileSystemObject?
|
||||||
|
/// URL for the directory being monitored.
|
||||||
|
let url: URL
|
||||||
|
|
||||||
|
var folderDidChange: (() -> Void)?
|
||||||
|
|
||||||
|
// MARK: Initializers
|
||||||
|
|
||||||
|
init(url: URL) {
|
||||||
|
self.url = url
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Monitoring
|
||||||
|
|
||||||
|
/// Listen for changes to the directory (if we are not already).
|
||||||
|
func startMonitoring() {
|
||||||
|
guard folderMonitorSource == nil, monitoredFolderFileDescriptor == -1 else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Open the directory referenced by URL for monitoring only.
|
||||||
|
monitoredFolderFileDescriptor = open(url.path, O_EVTONLY)
|
||||||
|
// Define a dispatch source monitoring the directory for additions, deletions, and renamings.
|
||||||
|
folderMonitorSource = DispatchSource.makeFileSystemObjectSource(
|
||||||
|
fileDescriptor: monitoredFolderFileDescriptor, eventMask: .write, queue: folderMonitorQueue
|
||||||
|
)
|
||||||
|
// Define the block to call when a file change is detected.
|
||||||
|
folderMonitorSource?.setEventHandler { [weak self] in
|
||||||
|
self?.folderDidChange?()
|
||||||
|
}
|
||||||
|
// Define a cancel handler to ensure the directory is closed when the source is cancelled.
|
||||||
|
folderMonitorSource?.setCancelHandler { [weak self] in
|
||||||
|
guard let strongSelf = self else { return }
|
||||||
|
close(strongSelf.monitoredFolderFileDescriptor)
|
||||||
|
strongSelf.monitoredFolderFileDescriptor = -1
|
||||||
|
strongSelf.folderMonitorSource = nil
|
||||||
|
}
|
||||||
|
// Start monitoring the directory via the source.
|
||||||
|
folderMonitorSource?.resume()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Stop listening for changes to the directory, if the source has been created.
|
||||||
|
func stopMonitoring() {
|
||||||
|
folderMonitorSource?.cancel()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,134 @@
|
||||||
|
// (c) 2021 and onwards Fuziki (MIT License).
|
||||||
|
// ====================
|
||||||
|
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
|
||||||
|
|
||||||
|
// Ref: https://qiita.com/fuziki/items/b31055a69330a3ce55a5
|
||||||
|
// Modified by The vChewing Project in order to use it with AppKit.
|
||||||
|
|
||||||
|
import Cocoa
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
@available(macOS 10.15, *)
|
||||||
|
public struct VText: NSViewRepresentable {
|
||||||
|
public var text: String?
|
||||||
|
|
||||||
|
public func makeNSView(context _: Context) -> NSAttributedTextView {
|
||||||
|
let nsView = NSAttributedTextView()
|
||||||
|
nsView.direction = .vertical
|
||||||
|
nsView.text = text
|
||||||
|
return nsView
|
||||||
|
}
|
||||||
|
|
||||||
|
public func updateNSView(_ nsView: NSAttributedTextView, context _: Context) {
|
||||||
|
nsView.text = text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(macOS 10.15, *)
|
||||||
|
public struct HText: NSViewRepresentable {
|
||||||
|
public var text: String?
|
||||||
|
|
||||||
|
public func makeNSView(context _: Context) -> NSAttributedTextView {
|
||||||
|
let nsView = NSAttributedTextView()
|
||||||
|
nsView.direction = .horizontal
|
||||||
|
nsView.text = text
|
||||||
|
return nsView
|
||||||
|
}
|
||||||
|
|
||||||
|
public func updateNSView(_ nsView: NSAttributedTextView, context _: Context) {
|
||||||
|
nsView.text = text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NSAttributedTextView: NSView {
|
||||||
|
public enum writingDirection: String {
|
||||||
|
case horizontal
|
||||||
|
case vertical
|
||||||
|
case verticalReversed
|
||||||
|
}
|
||||||
|
|
||||||
|
public var direction: writingDirection = .horizontal
|
||||||
|
public var fontSize: CGFloat = NSFont.systemFontSize {
|
||||||
|
didSet {
|
||||||
|
attributes[.font] = NSFont.systemFont(ofSize: fontSize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public var textColor: NSColor = .textColor {
|
||||||
|
didSet {
|
||||||
|
attributes[.foregroundColor] = textColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public var attributedStringValue: NSAttributedString {
|
||||||
|
var newAttributes = attributes
|
||||||
|
let isVertical: Bool = !(direction == .horizontal)
|
||||||
|
newAttributes[.verticalGlyphForm] = isVertical
|
||||||
|
let newStyle: NSMutableParagraphStyle = newAttributes[.paragraphStyle] as! NSMutableParagraphStyle
|
||||||
|
newStyle.lineSpacing = isVertical ? (fontSize / -2) : fontSize * 0.1
|
||||||
|
newStyle.maximumLineHeight = fontSize
|
||||||
|
newStyle.minimumLineHeight = fontSize
|
||||||
|
newAttributes[.paragraphStyle] = newStyle
|
||||||
|
var text: String = text ?? ""
|
||||||
|
if !(direction == .horizontal) {
|
||||||
|
text = text.replacingOccurrences(of: "˙", with: "・")
|
||||||
|
text = text.replacingOccurrences(of: "\u{A0}", with: " ")
|
||||||
|
text = text.replacingOccurrences(of: "+", with: "")
|
||||||
|
text = text.replacingOccurrences(of: "Shift", with: "⇧")
|
||||||
|
text = text.replacingOccurrences(of: "Control", with: "⌃")
|
||||||
|
text = text.replacingOccurrences(of: "Enter", with: "⏎")
|
||||||
|
text = text.replacingOccurrences(of: "Command", with: "⌘")
|
||||||
|
text = text.replacingOccurrences(of: "Delete", with: "⌦")
|
||||||
|
text = text.replacingOccurrences(of: "BackSpace", with: "⌫")
|
||||||
|
text = text.replacingOccurrences(of: "SHIFT", with: "⇧")
|
||||||
|
text = text.replacingOccurrences(of: "CONTROL", with: "⌃")
|
||||||
|
text = text.replacingOccurrences(of: "ENTER", with: "⏎")
|
||||||
|
text = text.replacingOccurrences(of: "COMMAND", with: "⌘")
|
||||||
|
text = text.replacingOccurrences(of: "DELETE", with: "⌦")
|
||||||
|
text = text.replacingOccurrences(of: "BACKSPACE", with: "⌫")
|
||||||
|
}
|
||||||
|
let attributedText = NSMutableAttributedString(string: text, attributes: newAttributes)
|
||||||
|
return attributedText
|
||||||
|
}
|
||||||
|
|
||||||
|
public var backgroundColor: NSColor = .controlBackgroundColor
|
||||||
|
|
||||||
|
public var attributes: [NSAttributedString.Key: Any] = [
|
||||||
|
.verticalGlyphForm: true,
|
||||||
|
.font: NSFont.systemFont(ofSize: NSFont.systemFontSize),
|
||||||
|
.foregroundColor: NSColor.textColor,
|
||||||
|
.paragraphStyle: {
|
||||||
|
let paragraphStyle = NSMutableParagraphStyle()
|
||||||
|
paragraphStyle.alignment = .left
|
||||||
|
return paragraphStyle
|
||||||
|
}(),
|
||||||
|
]
|
||||||
|
public var text: String? { didSet { ctFrame = nil } }
|
||||||
|
private var ctFrame: CTFrame?
|
||||||
|
private(set) var currentRect: NSRect?
|
||||||
|
|
||||||
|
override public func draw(_ rect: CGRect) {
|
||||||
|
let context = NSGraphicsContext.current?.cgContext
|
||||||
|
guard let context = context else { return }
|
||||||
|
let setter = CTFramesetterCreateWithAttributedString(attributedStringValue)
|
||||||
|
let path = CGPath(rect: rect, transform: nil)
|
||||||
|
let theCTFrameProgression: CTFrameProgression = {
|
||||||
|
switch direction {
|
||||||
|
case .horizontal: return CTFrameProgression.topToBottom
|
||||||
|
case .vertical: return CTFrameProgression.rightToLeft
|
||||||
|
case .verticalReversed: return CTFrameProgression.leftToRight
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
let frameAttrs: CFDictionary =
|
||||||
|
[
|
||||||
|
kCTFrameProgressionAttributeName: theCTFrameProgression.rawValue
|
||||||
|
] as CFDictionary
|
||||||
|
let newFrame = CTFramesetterCreateFrame(setter, CFRangeMake(0, 0), path, frameAttrs)
|
||||||
|
ctFrame = newFrame
|
||||||
|
backgroundColor.setFill()
|
||||||
|
let bgPath: NSBezierPath = .init(roundedRect: rect, xRadius: 0, yRadius: 0)
|
||||||
|
bgPath.fill()
|
||||||
|
currentRect = rect
|
||||||
|
CTFrameDraw(newFrame, context)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1 +1 @@
|
||||||
Subproject commit 0293f06c92ba9b95dd42debf662b8f8bb5834bdd
|
Subproject commit 6dba7237957681bfa4c623ab5689248cc02bc7e6
|
|
@ -12,10 +12,8 @@ import Cocoa
|
||||||
import InputMethodKit
|
import InputMethodKit
|
||||||
|
|
||||||
@objc(AppDelegate)
|
@objc(AppDelegate)
|
||||||
class AppDelegate: NSObject, NSApplicationDelegate,
|
class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDelegate {
|
||||||
FSEventStreamHelperDelegate, NSUserNotificationCenterDelegate
|
private func reloadOnFolderChangeHappens() {
|
||||||
{
|
|
||||||
func helper(_: FSEventStreamHelper, didReceive _: [FSEventStreamHelper.Event]) {
|
|
||||||
// 拖 100ms 再重載,畢竟有些有特殊需求的使用者可能會想使用巨型自訂語彙檔案。
|
// 拖 100ms 再重載,畢竟有些有特殊需求的使用者可能會想使用巨型自訂語彙檔案。
|
||||||
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1) {
|
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1) {
|
||||||
if mgrPrefs.shouldAutoReloadUserDataFiles {
|
if mgrPrefs.shouldAutoReloadUserDataFiles {
|
||||||
|
@ -29,22 +27,11 @@ class AppDelegate: NSObject, NSApplicationDelegate,
|
||||||
@IBOutlet var window: NSWindow?
|
@IBOutlet var window: NSWindow?
|
||||||
private var ctlPrefWindowInstance: ctlPrefWindow?
|
private var ctlPrefWindowInstance: ctlPrefWindow?
|
||||||
private var ctlAboutWindowInstance: ctlAboutWindow? // New About Window
|
private var ctlAboutWindowInstance: ctlAboutWindow? // New About Window
|
||||||
private var checkTask: URLSessionTask?
|
public lazy var folderMonitor = FolderMonitor(
|
||||||
public var fsStreamHelper = FSEventStreamHelper(
|
url: URL(fileURLWithPath: mgrLangModel.dataFolderPath(isDefaultFolder: false))
|
||||||
path: mgrLangModel.dataFolderPath(isDefaultFolder: false),
|
|
||||||
queue: DispatchQueue(label: "vChewing User Phrases")
|
|
||||||
)
|
)
|
||||||
private var currentAlertType: String = ""
|
private var currentAlertType: String = ""
|
||||||
|
|
||||||
// 補上 dealloc
|
|
||||||
deinit {
|
|
||||||
ctlPrefWindowInstance = nil
|
|
||||||
ctlAboutWindowInstance = nil
|
|
||||||
checkTask = nil
|
|
||||||
fsStreamHelper.stop()
|
|
||||||
fsStreamHelper.delegate = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func userNotificationCenter(_: NSUserNotificationCenter, shouldPresent _: NSUserNotification) -> Bool {
|
func userNotificationCenter(_: NSUserNotificationCenter, shouldPresent _: NSUserNotification) -> Bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
@ -68,20 +55,29 @@ class AppDelegate: NSObject, NSApplicationDelegate,
|
||||||
IME.initLangModels(userOnly: false)
|
IME.initLangModels(userOnly: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fsStreamHelper.delegate = self
|
folderMonitor.folderDidChange = { [weak self] in
|
||||||
_ = fsStreamHelper.start()
|
self?.reloadOnFolderChangeHappens()
|
||||||
|
}
|
||||||
|
folderMonitor.startMonitoring()
|
||||||
|
|
||||||
mgrPrefs.fixOddPreferences()
|
mgrPrefs.fixOddPreferences()
|
||||||
mgrPrefs.setMissingDefaults()
|
mgrPrefs.setMissingDefaults()
|
||||||
|
|
||||||
// 只要使用者沒有勾選檢查更新、沒有主動做出要檢查更新的操作,就不要檢查更新。
|
// 只要使用者沒有勾選檢查更新、沒有主動做出要檢查更新的操作,就不要檢查更新。
|
||||||
if mgrPrefs.checkUpdateAutomatically {
|
if mgrPrefs.checkUpdateAutomatically {
|
||||||
checkForUpdate()
|
UpdateSputnik.shared.checkForUpdate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateStreamHelperPath() {
|
func updateDirectoryMonitorPath() {
|
||||||
fsStreamHelper.path = mgrPrefs.userDataFolderSpecified
|
folderMonitor.stopMonitoring()
|
||||||
|
folderMonitor = FolderMonitor(
|
||||||
|
url: URL(fileURLWithPath: mgrLangModel.dataFolderPath(isDefaultFolder: false))
|
||||||
|
)
|
||||||
|
folderMonitor.folderDidChange = { [weak self] in
|
||||||
|
self?.reloadOnFolderChangeHappens()
|
||||||
|
}
|
||||||
|
folderMonitor.startMonitoring()
|
||||||
}
|
}
|
||||||
|
|
||||||
func showPreferences() {
|
func showPreferences() {
|
||||||
|
@ -106,88 +102,6 @@ class AppDelegate: NSObject, NSApplicationDelegate,
|
||||||
NSApp.setActivationPolicy(.accessory)
|
NSApp.setActivationPolicy(.accessory)
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkForUpdate(forced: Bool = false) {
|
|
||||||
if checkTask != nil {
|
|
||||||
// busy
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// time for update?
|
|
||||||
if !forced {
|
|
||||||
if !mgrPrefs.checkUpdateAutomatically {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let now = Date()
|
|
||||||
let date = UserDefaults.standard.object(forKey: VersionUpdateApi.kNextUpdateCheckDateKey) as? Date ?? now
|
|
||||||
if now.compare(date) == .orderedAscending {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let nextUpdateDate = Date(timeInterval: VersionUpdateApi.kNextCheckInterval, since: Date())
|
|
||||||
UserDefaults.standard.set(nextUpdateDate, forKey: VersionUpdateApi.kNextUpdateCheckDateKey)
|
|
||||||
|
|
||||||
checkTask = VersionUpdateApi.check(forced: forced) { [self] result in
|
|
||||||
defer {
|
|
||||||
checkTask = nil
|
|
||||||
}
|
|
||||||
switch result {
|
|
||||||
case .success(let apiResult):
|
|
||||||
switch apiResult {
|
|
||||||
case .shouldUpdate(let report):
|
|
||||||
let content = String(
|
|
||||||
format: NSLocalizedString(
|
|
||||||
"You're currently using vChewing %@ (%@), a new version %@ (%@) is now available. Do you want to visit vChewing's website to download the version?%@",
|
|
||||||
comment: ""
|
|
||||||
),
|
|
||||||
report.currentShortVersion,
|
|
||||||
report.currentVersion,
|
|
||||||
report.remoteShortVersion,
|
|
||||||
report.remoteVersion,
|
|
||||||
report.versionDescription
|
|
||||||
)
|
|
||||||
IME.prtDebugIntel("vChewingDebug: \(content)")
|
|
||||||
let alert = NSAlert()
|
|
||||||
alert.messageText = NSLocalizedString("New Version Available", comment: "")
|
|
||||||
alert.informativeText = content
|
|
||||||
alert.addButton(withTitle: NSLocalizedString("Visit Website", comment: ""))
|
|
||||||
alert.addButton(withTitle: NSLocalizedString("Not Now", comment: ""))
|
|
||||||
let result = alert.runModal()
|
|
||||||
if result == NSApplication.ModalResponse.alertFirstButtonReturn {
|
|
||||||
if let siteURL = report.siteUrl {
|
|
||||||
NSWorkspace.shared.open(siteURL)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
NSApp.setActivationPolicy(.accessory)
|
|
||||||
case .noNeedToUpdate, .ignored:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case .failure(let error):
|
|
||||||
switch error {
|
|
||||||
case VersionUpdateApiError.connectionError(let message):
|
|
||||||
let title = NSLocalizedString("Update Check Failed", comment: "")
|
|
||||||
let content = String(
|
|
||||||
format: NSLocalizedString(
|
|
||||||
"There may be no internet connection or the server failed to respond.\n\nError message: %@",
|
|
||||||
comment: ""
|
|
||||||
), message
|
|
||||||
)
|
|
||||||
let buttonTitle = NSLocalizedString("Dismiss", comment: "")
|
|
||||||
IME.prtDebugIntel("vChewingDebug: \(content)")
|
|
||||||
|
|
||||||
let alert = NSAlert()
|
|
||||||
alert.messageText = title
|
|
||||||
alert.informativeText = content
|
|
||||||
alert.addButton(withTitle: buttonTitle)
|
|
||||||
alert.runModal()
|
|
||||||
NSApp.setActivationPolicy(.accessory)
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func selfUninstall() {
|
func selfUninstall() {
|
||||||
currentAlertType = "Uninstall"
|
currentAlertType = "Uninstall"
|
||||||
let content = String(
|
let content = String(
|
||||||
|
|
|
@ -35,6 +35,7 @@ public protocol IMEStateProtocol {
|
||||||
var attributedString: NSAttributedString { get }
|
var attributedString: NSAttributedString { get }
|
||||||
var convertedToInputting: IMEState { get }
|
var convertedToInputting: IMEState { get }
|
||||||
var isFilterable: Bool { get }
|
var isFilterable: Bool { get }
|
||||||
|
var isMarkedLengthValid: Bool { get }
|
||||||
var node: SymbolNode { get set }
|
var node: SymbolNode { get set }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,6 +155,7 @@ extension IMEState {
|
||||||
|
|
||||||
extension IMEState {
|
extension IMEState {
|
||||||
public var isFilterable: Bool { data.isFilterable }
|
public var isFilterable: Bool { data.isFilterable }
|
||||||
|
public var isMarkedLengthValid: Bool { data.isMarkedLengthValid }
|
||||||
public var candidates: [(String, String)] { data.candidates }
|
public var candidates: [(String, String)] { data.candidates }
|
||||||
public var convertedToInputting: IMEState {
|
public var convertedToInputting: IMEState {
|
||||||
if type == .ofInputting { return self }
|
if type == .ofInputting { return self }
|
||||||
|
|
|
@ -76,7 +76,11 @@ public struct StateData {
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
var isFilterable: Bool {
|
var isFilterable: Bool {
|
||||||
markedTargetExists ? mgrPrefs.allowedMarkRange.contains(markedRange.count) : false
|
markedTargetExists ? isMarkedLengthValid : false
|
||||||
|
}
|
||||||
|
|
||||||
|
var isMarkedLengthValid: Bool {
|
||||||
|
mgrPrefs.allowedMarkLengthRange.contains(markedRange.count)
|
||||||
}
|
}
|
||||||
|
|
||||||
var attributedStringNormal: NSAttributedString {
|
var attributedStringNormal: NSAttributedString {
|
||||||
|
@ -170,7 +174,10 @@ extension StateData {
|
||||||
arrOutput.append("??")
|
arrOutput.append("??")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if mgrPrefs.showHanyuPinyinInCompositionBuffer { // 恢復陰平標記->注音轉拼音->轉教科書式標調
|
if mgrPrefs.showHanyuPinyinInCompositionBuffer,
|
||||||
|
mgrPrefs.alwaysShowTooltipTextsHorizontally || !ctlInputMethod.isVerticalTypingSituation
|
||||||
|
{
|
||||||
|
// 恢復陰平標記->注音轉拼音->轉教科書式標調
|
||||||
neta = Tekkon.restoreToneOneInZhuyinKey(target: neta)
|
neta = Tekkon.restoreToneOneInZhuyinKey(target: neta)
|
||||||
neta = Tekkon.cnvPhonaToHanyuPinyin(target: neta)
|
neta = Tekkon.cnvPhonaToHanyuPinyin(target: neta)
|
||||||
neta = Tekkon.cnvHanyuPinyinToTextbookStyle(target: neta)
|
neta = Tekkon.cnvHanyuPinyinToTextbookStyle(target: neta)
|
||||||
|
@ -179,7 +186,7 @@ extension StateData {
|
||||||
}
|
}
|
||||||
arrOutput.append(neta)
|
arrOutput.append(neta)
|
||||||
}
|
}
|
||||||
return arrOutput.joined(separator: " ")
|
return arrOutput.joined(separator: "\u{A0}")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 更新工具提示內容、以及對應配對是否在庫。
|
/// 更新工具提示內容、以及對應配對是否在庫。
|
||||||
|
@ -187,7 +194,7 @@ extension StateData {
|
||||||
public static func updateParameters(_ data: inout StateData) {
|
public static func updateParameters(_ data: inout StateData) {
|
||||||
var tooltipGenerated: String {
|
var tooltipGenerated: String {
|
||||||
if mgrPrefs.phraseReplacementEnabled {
|
if mgrPrefs.phraseReplacementEnabled {
|
||||||
ctlInputMethod.tooltipController.setColor(state: .warning)
|
ctlInputMethod.tooltipInstance.setColor(state: .warning)
|
||||||
return NSLocalizedString(
|
return NSLocalizedString(
|
||||||
"⚠︎ Phrase replacement mode enabled, interfering user phrase entry.", comment: ""
|
"⚠︎ Phrase replacement mode enabled, interfering user phrase entry.", comment: ""
|
||||||
)
|
)
|
||||||
|
@ -197,19 +204,19 @@ extension StateData {
|
||||||
}
|
}
|
||||||
|
|
||||||
let text = data.displayedText.charComponents[data.markedRange].joined()
|
let text = data.displayedText.charComponents[data.markedRange].joined()
|
||||||
if data.markedRange.count < mgrPrefs.allowedMarkRange.lowerBound {
|
if data.markedRange.count < mgrPrefs.allowedMarkLengthRange.lowerBound {
|
||||||
ctlInputMethod.tooltipController.setColor(state: .denialInsufficiency)
|
ctlInputMethod.tooltipInstance.setColor(state: .denialInsufficiency)
|
||||||
return String(
|
return String(
|
||||||
format: NSLocalizedString(
|
format: NSLocalizedString(
|
||||||
"\"%@\" length must ≥ 2 for a user phrase.", comment: ""
|
"\"%@\" length must ≥ 2 for a user phrase.", comment: ""
|
||||||
) + "\n// " + generateReadingThread(data), text
|
) + "\n◆ " + generateReadingThread(data), text
|
||||||
)
|
)
|
||||||
} else if data.markedRange.count > mgrPrefs.allowedMarkRange.upperBound {
|
} else if data.markedRange.count > mgrPrefs.allowedMarkLengthRange.upperBound {
|
||||||
ctlInputMethod.tooltipController.setColor(state: .denialOverflow)
|
ctlInputMethod.tooltipInstance.setColor(state: .denialOverflow)
|
||||||
return String(
|
return String(
|
||||||
format: NSLocalizedString(
|
format: NSLocalizedString(
|
||||||
"\"%@\" length should ≤ %d for a user phrase.", comment: ""
|
"\"%@\" length should ≤ %d for a user phrase.", comment: ""
|
||||||
) + "\n// " + generateReadingThread(data), text, mgrPrefs.allowedMarkRange.upperBound
|
) + "\n◆ " + generateReadingThread(data), text, mgrPrefs.allowedMarkLengthRange.upperBound
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,17 +226,17 @@ extension StateData {
|
||||||
)
|
)
|
||||||
if exist {
|
if exist {
|
||||||
data.markedTargetExists = exist
|
data.markedTargetExists = exist
|
||||||
ctlInputMethod.tooltipController.setColor(state: .prompt)
|
ctlInputMethod.tooltipInstance.setColor(state: .prompt)
|
||||||
return String(
|
return String(
|
||||||
format: NSLocalizedString(
|
format: NSLocalizedString(
|
||||||
"\"%@\" already exists: ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude.",
|
"\"%@\" already exists:\n ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude.",
|
||||||
comment: ""
|
comment: ""
|
||||||
) + "\n// " + generateReadingThread(data), text
|
) + "\n◆ " + generateReadingThread(data), text
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ctlInputMethod.tooltipController.resetColor()
|
ctlInputMethod.tooltipInstance.resetColor()
|
||||||
return String(
|
return String(
|
||||||
format: NSLocalizedString("\"%@\" selected. ENTER to add user phrase.", comment: "") + "\n// "
|
format: NSLocalizedString("\"%@\" selected. ENTER to add user phrase.", comment: "") + "\n◆ "
|
||||||
+ generateReadingThread(data),
|
+ generateReadingThread(data),
|
||||||
text
|
text
|
||||||
)
|
)
|
||||||
|
|
|
@ -253,7 +253,7 @@ extension KeyHandler {
|
||||||
return handleClockKey(state: state, stateCallback: stateCallback, errorCallback: errorCallback)
|
return handleClockKey(state: state, stateCallback: stateCallback, errorCallback: errorCallback)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Backspace
|
// MARK: BackSpace
|
||||||
|
|
||||||
if input.isBackSpace {
|
if input.isBackSpace {
|
||||||
return handleBackSpace(state: state, input: input, stateCallback: stateCallback, errorCallback: errorCallback)
|
return handleBackSpace(state: state, input: input, stateCallback: stateCallback, errorCallback: errorCallback)
|
||||||
|
|
|
@ -161,7 +161,13 @@ extension KeyHandler {
|
||||||
IME.prtDebugIntel("2EAC1F7A")
|
IME.prtDebugIntel("2EAC1F7A")
|
||||||
errorCallback()
|
errorCallback()
|
||||||
return true
|
return true
|
||||||
} else if !keyHandlerDelegate.keyHandler(self, didRequestWriteUserPhraseWith: state, addToFilter: false) {
|
}
|
||||||
|
if !state.isMarkedLengthValid {
|
||||||
|
IME.prtDebugIntel("9AAFAC00")
|
||||||
|
errorCallback()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if !keyHandlerDelegate.keyHandler(self, didRequestWriteUserPhraseWith: state, addToFilter: false) {
|
||||||
IME.prtDebugIntel("5B69CC8D")
|
IME.prtDebugIntel("5B69CC8D")
|
||||||
errorCallback()
|
errorCallback()
|
||||||
return true
|
return true
|
||||||
|
@ -374,9 +380,9 @@ extension KeyHandler {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - 處理 Backspace (macOS Delete) 按鍵行為
|
// MARK: - 處理 BackSpace (macOS Delete) 按鍵行為
|
||||||
|
|
||||||
/// 處理 Backspace (macOS Delete) 按鍵行為。
|
/// 處理 BackSpace (macOS Delete) 按鍵行為。
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - state: 當前狀態。
|
/// - state: 當前狀態。
|
||||||
/// - input: 輸入按鍵訊號。
|
/// - input: 輸入按鍵訊號。
|
||||||
|
|
|
@ -27,8 +27,8 @@ 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 let tooltipController = TooltipController()
|
static var tooltipInstance = ctlTooltip()
|
||||||
|
|
||||||
// MARK: -
|
// MARK: -
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ class ctlInputMethod: IMKInputController {
|
||||||
setKeyLayout()
|
setKeyLayout()
|
||||||
handle(state: IMEState.ofEmpty())
|
handle(state: IMEState.ofEmpty())
|
||||||
} // 除此之外就不要動了,免得在點開輸入法自身的視窗時卡死。
|
} // 除此之外就不要動了,免得在點開輸入法自身的視窗時卡死。
|
||||||
(NSApp.delegate as? AppDelegate)?.checkForUpdate()
|
UpdateSputnik.shared.checkForUpdate()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 停用輸入法時,會觸發該函式。
|
/// 停用輸入法時,會觸發該函式。
|
||||||
|
@ -207,15 +207,16 @@ 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 // 防止格式整理工具毀掉與此對應的參數。
|
||||||
|
|
||||||
// 只針對特定類型的 client() 進行處理。
|
|
||||||
if !(sender is IMKTextInput) { return false }
|
|
||||||
|
|
||||||
// 更新此時的靜態狀態標記。
|
// 更新此時的靜態狀態標記。
|
||||||
ctlInputMethod.isASCIIModeSituation = isASCIIMode
|
ctlInputMethod.isASCIIModeSituation = isASCIIMode
|
||||||
ctlInputMethod.isVerticalTypingSituation = isVerticalTyping
|
ctlInputMethod.isVerticalTypingSituation = isVerticalTyping
|
||||||
|
|
||||||
// 就這傳入的 NSEvent 都還有可能是 nil,Apple InputMethodKit 團隊到底在搞三小。
|
// 就這傳入的 NSEvent 都還有可能是 nil,Apple InputMethodKit 團隊到底在搞三小。
|
||||||
guard let event = event else { return false }
|
// 只針對特定類型的 client() 進行處理。
|
||||||
|
guard let event = event, sender is IMKTextInput else {
|
||||||
|
resetKeyHandler()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// IMK 選字窗處理,當且僅當啟用了 IMK 選字窗的時候才會生效。
|
// IMK 選字窗處理,當且僅當啟用了 IMK 選字窗的時候才會生效。
|
||||||
// 這樣可以讓 interpretKeyEvents() 函式自行判斷:
|
// 這樣可以讓 interpretKeyEvents() 函式自行判斷:
|
||||||
|
|
|
@ -27,15 +27,20 @@ extension ctlInputMethod {
|
||||||
cursor -= 1
|
cursor -= 1
|
||||||
}
|
}
|
||||||
var finalOrigin: NSPoint = lineHeightRect.origin
|
var finalOrigin: NSPoint = lineHeightRect.origin
|
||||||
|
let delta: CGFloat = lineHeightRect.size.height + 4.0 // bottomOutOfScreenAdjustmentHeight
|
||||||
if isVerticalTyping {
|
if isVerticalTyping {
|
||||||
finalOrigin = NSPoint(
|
finalOrigin = NSPoint(
|
||||||
x: lineHeightRect.origin.x + lineHeightRect.size.width + 4.0, y: lineHeightRect.origin.y - 4.0
|
x: lineHeightRect.origin.x + lineHeightRect.size.width + 5, y: lineHeightRect.origin.y
|
||||||
)
|
)
|
||||||
ctlInputMethod.tooltipController.direction = .vertical
|
|
||||||
} else {
|
|
||||||
ctlInputMethod.tooltipController.direction = .horizontal
|
|
||||||
}
|
}
|
||||||
ctlInputMethod.tooltipController.show(tooltip: tooltip, at: finalOrigin)
|
let tooltipContentDirection: NSAttributedTextView.writingDirection = {
|
||||||
|
if mgrPrefs.alwaysShowTooltipTextsHorizontally { return .horizontal }
|
||||||
|
return isVerticalTyping ? .vertical : .horizontal
|
||||||
|
}()
|
||||||
|
ctlInputMethod.tooltipInstance.show(
|
||||||
|
tooltip: tooltip, at: finalOrigin,
|
||||||
|
bottomOutOfScreenAdjustmentHeight: delta, direction: tooltipContentDirection
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func show(candidateWindowWith state: IMEStateProtocol) {
|
func show(candidateWindowWith state: IMEStateProtocol) {
|
||||||
|
|
|
@ -25,7 +25,7 @@ extension ctlInputMethod {
|
||||||
case .ofDeactivated:
|
case .ofDeactivated:
|
||||||
ctlInputMethod.ctlCandidateCurrent.delegate = nil
|
ctlInputMethod.ctlCandidateCurrent.delegate = nil
|
||||||
ctlInputMethod.ctlCandidateCurrent.visible = false
|
ctlInputMethod.ctlCandidateCurrent.visible = false
|
||||||
ctlInputMethod.tooltipController.hide()
|
ctlInputMethod.tooltipInstance.hide()
|
||||||
if previous.hasComposition {
|
if previous.hasComposition {
|
||||||
commit(text: previous.displayedText)
|
commit(text: previous.displayedText)
|
||||||
}
|
}
|
||||||
|
@ -39,20 +39,20 @@ extension ctlInputMethod {
|
||||||
previous = state
|
previous = state
|
||||||
}
|
}
|
||||||
ctlInputMethod.ctlCandidateCurrent.visible = false
|
ctlInputMethod.ctlCandidateCurrent.visible = false
|
||||||
ctlInputMethod.tooltipController.hide()
|
ctlInputMethod.tooltipInstance.hide()
|
||||||
// 全專案用以判斷「.Abortion」的地方僅此一處。
|
// 全專案用以判斷「.Abortion」的地方僅此一處。
|
||||||
if previous.hasComposition, state.type != .ofAbortion {
|
if previous.hasComposition, state.type != .ofAbortion {
|
||||||
commit(text: previous.displayedText)
|
commit(text: previous.displayedText)
|
||||||
}
|
}
|
||||||
// 在這裡手動再取消一次選字窗與工具提示的顯示,可謂雙重保險。
|
// 在這裡手動再取消一次選字窗與工具提示的顯示,可謂雙重保險。
|
||||||
ctlInputMethod.ctlCandidateCurrent.visible = false
|
ctlInputMethod.ctlCandidateCurrent.visible = false
|
||||||
ctlInputMethod.tooltipController.hide()
|
ctlInputMethod.tooltipInstance.hide()
|
||||||
clearInlineDisplay()
|
clearInlineDisplay()
|
||||||
// 最後一道保險
|
// 最後一道保險
|
||||||
keyHandler.clear()
|
keyHandler.clear()
|
||||||
case .ofCommitting:
|
case .ofCommitting:
|
||||||
ctlInputMethod.ctlCandidateCurrent.visible = false
|
ctlInputMethod.ctlCandidateCurrent.visible = false
|
||||||
ctlInputMethod.tooltipController.hide()
|
ctlInputMethod.tooltipInstance.hide()
|
||||||
let textToCommit = state.textToCommit
|
let textToCommit = state.textToCommit
|
||||||
if !textToCommit.isEmpty { commit(text: textToCommit) }
|
if !textToCommit.isEmpty { commit(text: textToCommit) }
|
||||||
clearInlineDisplay()
|
clearInlineDisplay()
|
||||||
|
@ -60,7 +60,7 @@ extension ctlInputMethod {
|
||||||
keyHandler.clear()
|
keyHandler.clear()
|
||||||
case .ofInputting:
|
case .ofInputting:
|
||||||
ctlInputMethod.ctlCandidateCurrent.visible = false
|
ctlInputMethod.ctlCandidateCurrent.visible = false
|
||||||
ctlInputMethod.tooltipController.hide()
|
ctlInputMethod.tooltipInstance.hide()
|
||||||
let textToCommit = state.textToCommit
|
let textToCommit = state.textToCommit
|
||||||
if !textToCommit.isEmpty { commit(text: textToCommit) }
|
if !textToCommit.isEmpty { commit(text: textToCommit) }
|
||||||
setInlineDisplayWithCursor()
|
setInlineDisplayWithCursor()
|
||||||
|
@ -74,7 +74,7 @@ extension ctlInputMethod {
|
||||||
ctlInputMethod.ctlCandidateCurrent.visible = false
|
ctlInputMethod.ctlCandidateCurrent.visible = false
|
||||||
setInlineDisplayWithCursor()
|
setInlineDisplayWithCursor()
|
||||||
if state.tooltip.isEmpty {
|
if state.tooltip.isEmpty {
|
||||||
ctlInputMethod.tooltipController.hide()
|
ctlInputMethod.tooltipInstance.hide()
|
||||||
} else {
|
} else {
|
||||||
let cursorReference: Int = {
|
let cursorReference: Int = {
|
||||||
if state.data.marker >= state.data.cursor { return state.data.u16Cursor }
|
if state.data.marker >= state.data.cursor { return state.data.u16Cursor }
|
||||||
|
@ -86,7 +86,7 @@ extension ctlInputMethod {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
case .ofCandidates, .ofAssociates, .ofSymbolTable:
|
case .ofCandidates, .ofAssociates, .ofSymbolTable:
|
||||||
ctlInputMethod.tooltipController.hide()
|
ctlInputMethod.tooltipInstance.hide()
|
||||||
setInlineDisplayWithCursor()
|
setInlineDisplayWithCursor()
|
||||||
show(candidateWindowWith: state)
|
show(candidateWindowWith: state)
|
||||||
default: break
|
default: break
|
||||||
|
|
|
@ -308,7 +308,7 @@ extension ctlInputMethod {
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func checkForUpdate(_: Any?) {
|
@objc func checkForUpdate(_: Any?) {
|
||||||
(NSApp.delegate as? AppDelegate)?.checkForUpdate(forced: true)
|
UpdateSputnik.shared.checkForUpdate(forced: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func openUserDataFolder(_: Any?) {
|
@objc func openUserDataFolder(_: Any?) {
|
||||||
|
|
|
@ -1,88 +0,0 @@
|
||||||
// (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).
|
|
||||||
// ====================
|
|
||||||
// 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 protocol FSEventStreamHelperDelegate: AnyObject {
|
|
||||||
func helper(_ helper: FSEventStreamHelper, didReceive events: [FSEventStreamHelper.Event])
|
|
||||||
}
|
|
||||||
|
|
||||||
public class FSEventStreamHelper {
|
|
||||||
public struct Event {
|
|
||||||
var path: String
|
|
||||||
var flags: FSEventStreamEventFlags
|
|
||||||
var id: FSEventStreamEventId
|
|
||||||
}
|
|
||||||
|
|
||||||
public var path: String
|
|
||||||
public let dispatchQueue: DispatchQueue
|
|
||||||
public weak var delegate: FSEventStreamHelperDelegate?
|
|
||||||
|
|
||||||
public init(path: String, queue: DispatchQueue) {
|
|
||||||
self.path = path
|
|
||||||
dispatchQueue = queue
|
|
||||||
}
|
|
||||||
|
|
||||||
private var stream: FSEventStreamRef?
|
|
||||||
|
|
||||||
public func start() -> Bool {
|
|
||||||
if stream != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
var context = FSEventStreamContext()
|
|
||||||
context.info = Unmanaged.passUnretained(self).toOpaque()
|
|
||||||
guard
|
|
||||||
let stream = FSEventStreamCreate(
|
|
||||||
nil,
|
|
||||||
{
|
|
||||||
_, clientCallBackInfo, eventCount, eventPaths, eventFlags, eventIds in
|
|
||||||
let helper = Unmanaged<FSEventStreamHelper>.fromOpaque(clientCallBackInfo!)
|
|
||||||
.takeUnretainedValue()
|
|
||||||
let pathsBase = eventPaths.assumingMemoryBound(to: UnsafePointer<CChar>.self)
|
|
||||||
let pathsPtr = UnsafeBufferPointer(start: pathsBase, count: eventCount)
|
|
||||||
let flagsPtr = UnsafeBufferPointer(start: eventFlags, count: eventCount)
|
|
||||||
let eventIDsPtr = UnsafeBufferPointer(start: eventIds, count: eventCount)
|
|
||||||
let events = (0..<eventCount).map {
|
|
||||||
FSEventStreamHelper.Event(
|
|
||||||
path: String(cString: pathsPtr[$0]),
|
|
||||||
flags: flagsPtr[$0],
|
|
||||||
id: eventIDsPtr[$0]
|
|
||||||
)
|
|
||||||
}
|
|
||||||
helper.delegate?.helper(helper, didReceive: events)
|
|
||||||
},
|
|
||||||
&context,
|
|
||||||
[path] as CFArray,
|
|
||||||
UInt64(kFSEventStreamEventIdSinceNow),
|
|
||||||
1.0,
|
|
||||||
FSEventStreamCreateFlags(kFSEventStreamCreateFlagNone)
|
|
||||||
)
|
|
||||||
else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
FSEventStreamSetDispatchQueue(stream, dispatchQueue)
|
|
||||||
if !FSEventStreamStart(stream) {
|
|
||||||
FSEventStreamInvalidate(stream)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
self.stream = stream
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func stop() {
|
|
||||||
guard let stream = stream else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
FSEventStreamStop(stream)
|
|
||||||
FSEventStreamInvalidate(stream)
|
|
||||||
self.stream = nil
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -111,6 +111,7 @@ public enum IME {
|
||||||
// MARK: - System Dark Mode Status Detector.
|
// MARK: - System Dark Mode Status Detector.
|
||||||
|
|
||||||
static var isDarkMode: Bool {
|
static var isDarkMode: Bool {
|
||||||
|
if #unavailable(macOS 10.14) { return false }
|
||||||
if #available(macOS 10.15, *) {
|
if #available(macOS 10.15, *) {
|
||||||
let appearanceDescription = NSApplication.shared.effectiveAppearance.debugDescription
|
let appearanceDescription = NSApplication.shared.effectiveAppearance.debugDescription
|
||||||
.lowercased()
|
.lowercased()
|
||||||
|
@ -138,12 +139,14 @@ public enum IME {
|
||||||
),
|
),
|
||||||
mgrLangModel.dataFolderPath(isDefaultFolder: false)
|
mgrLangModel.dataFolderPath(isDefaultFolder: false)
|
||||||
)
|
)
|
||||||
|
DispatchQueue.main.async {
|
||||||
let alert = NSAlert()
|
let alert = NSAlert()
|
||||||
alert.messageText = NSLocalizedString("Unable to create the user phrase file.", comment: "")
|
alert.messageText = NSLocalizedString("Unable to create the user phrase file.", comment: "")
|
||||||
alert.informativeText = content
|
alert.informativeText = content
|
||||||
alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
|
alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
|
||||||
alert.runModal()
|
alert.runModal()
|
||||||
NSApp.setActivationPolicy(.accessory)
|
NSApp.setActivationPolicy(.accessory)
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -0,0 +1,159 @@
|
||||||
|
// (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 UpdateSputnik: NSObject, URLSessionDataDelegate {
|
||||||
|
static let kUpdateInfoPageURLKey: String = "UpdateInfoSite"
|
||||||
|
static let kUpdateCheckDateKeyPrevious: String = "PreviousUpdateCheckDate"
|
||||||
|
static let kUpdateCheckDateKeyNext: String = "NextUpdateCheckDate"
|
||||||
|
static let kUpdateCheckInterval: TimeInterval = 114_514
|
||||||
|
static var shared = UpdateSputnik()
|
||||||
|
|
||||||
|
func checkForUpdate(forced: Bool = false) {
|
||||||
|
guard !busy else { return }
|
||||||
|
|
||||||
|
if !forced {
|
||||||
|
if !mgrPrefs.checkUpdateAutomatically { return }
|
||||||
|
if let nextCheckDate = nextUpdateCheckDate, Date().compare(nextCheckDate) == .orderedAscending {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isCurrentCheckForced = forced // 留著用來生成錯誤報告
|
||||||
|
let request = URLRequest(
|
||||||
|
url: kUpdateInfoSourceURL, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 5
|
||||||
|
)
|
||||||
|
|
||||||
|
let task = URLSession.shared.dataTask(with: request) { data, _, error in
|
||||||
|
if let error = error {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.showError(message: error.localizedDescription)
|
||||||
|
self.currentTask = nil
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.data = data
|
||||||
|
}
|
||||||
|
task.resume()
|
||||||
|
currentTask = task
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Private properties
|
||||||
|
|
||||||
|
private var isCurrentCheckForced = false
|
||||||
|
var sessionConfiguration = URLSessionConfiguration.background(withIdentifier: Bundle.main.bundleIdentifier!)
|
||||||
|
|
||||||
|
private var busy: Bool { currentTask != nil }
|
||||||
|
private var currentTask: URLSessionDataTask?
|
||||||
|
private var data: Data? {
|
||||||
|
didSet {
|
||||||
|
if let data = data {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.dataDidSet(data: data)
|
||||||
|
self.currentTask = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var nextUpdateCheckDate: Date? {
|
||||||
|
get {
|
||||||
|
UserDefaults.standard.object(forKey: UpdateSputnik.kUpdateCheckDateKeyNext) as? Date
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
UserDefaults.standard.set(newValue, forKey: UpdateSputnik.kUpdateCheckDateKeyNext)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Private functions.
|
||||||
|
|
||||||
|
internal func dataDidSet(data: Data) {
|
||||||
|
var plist: [AnyHashable: Any]?
|
||||||
|
plist = try? PropertyListSerialization.propertyList(from: data, options: [], format: nil) as? [AnyHashable: Any]
|
||||||
|
nextUpdateCheckDate = .init().addingTimeInterval(UpdateSputnik.kUpdateCheckInterval)
|
||||||
|
cleanUp()
|
||||||
|
|
||||||
|
guard let plist = plist else {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.showError(message: "Plist downloaded is nil.")
|
||||||
|
self.currentTask = nil
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
NSLog("update check plist: \(plist)")
|
||||||
|
|
||||||
|
guard let intRemoteVersion = Int(plist[kCFBundleVersionKey] as? String ?? ""),
|
||||||
|
let strRemoteVersionShortened = plist["CFBundleShortVersionString"] as? String
|
||||||
|
else {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.showError(message: "Plist downloaded cannot be parsed correctly.")
|
||||||
|
self.currentTask = nil
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let dicMainBundle = Bundle.main.infoDictionary,
|
||||||
|
let intCurrentVersion = Int(dicMainBundle[kCFBundleVersionKey as String] as? String ?? ""),
|
||||||
|
let strCurrentVersionShortened = dicMainBundle["CFBundleShortVersionString"] as? String
|
||||||
|
else { return } // Shouldn't happen.
|
||||||
|
if intRemoteVersion <= intCurrentVersion, isCurrentCheckForced {
|
||||||
|
let alert = NSAlert()
|
||||||
|
alert.messageText = NSLocalizedString("Update Check Completed", comment: "")
|
||||||
|
alert.informativeText = NSLocalizedString("You are already using the latest version.", comment: "")
|
||||||
|
alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
|
||||||
|
alert.runModal()
|
||||||
|
NSApp.setActivationPolicy(.accessory)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let content = String(
|
||||||
|
format: NSLocalizedString(
|
||||||
|
"You're currently using vChewing %@ (%@), a new version %@ (%@) is now available. Do you want to visit vChewing's website to download the version?",
|
||||||
|
comment: ""
|
||||||
|
),
|
||||||
|
strCurrentVersionShortened,
|
||||||
|
intCurrentVersion.description,
|
||||||
|
strRemoteVersionShortened,
|
||||||
|
intRemoteVersion.description
|
||||||
|
)
|
||||||
|
let alert = NSAlert()
|
||||||
|
alert.messageText = NSLocalizedString("New Version Available", comment: "")
|
||||||
|
alert.informativeText = content
|
||||||
|
alert.addButton(withTitle: NSLocalizedString("Visit Website", comment: ""))
|
||||||
|
alert.addButton(withTitle: NSLocalizedString("Not Now", comment: ""))
|
||||||
|
NSApp.setActivationPolicy(.accessory)
|
||||||
|
let result = alert.runModal()
|
||||||
|
if result == NSApplication.ModalResponse.alertFirstButtonReturn {
|
||||||
|
if let siteInfoURLString = plist[UpdateSputnik.kUpdateInfoPageURLKey] as? String,
|
||||||
|
let siteURL = URL(string: siteInfoURLString)
|
||||||
|
{
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
NSWorkspace.shared.open(siteURL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func cleanUp() {
|
||||||
|
currentTask = nil
|
||||||
|
data = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
private func showError(message: String = "") {
|
||||||
|
NSLog("Update check: plist error, forced check: \(isCurrentCheckForced)")
|
||||||
|
if !isCurrentCheckForced { return }
|
||||||
|
let alert = NSAlert()
|
||||||
|
let content = NSLocalizedString(message, comment: "")
|
||||||
|
alert.messageText = NSLocalizedString("Update Check Failed", comment: "")
|
||||||
|
alert.informativeText = content
|
||||||
|
alert.addButton(withTitle: NSLocalizedString("Dismiss", comment: ""))
|
||||||
|
alert.runModal()
|
||||||
|
NSApp.setActivationPolicy(.accessory)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,164 +0,0 @@
|
||||||
// (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).
|
|
||||||
// ====================
|
|
||||||
// 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
|
|
||||||
|
|
||||||
struct VersionUpdateReport {
|
|
||||||
var siteUrl: URL?
|
|
||||||
var currentShortVersion: String = ""
|
|
||||||
var currentVersion: String = ""
|
|
||||||
var remoteShortVersion: String = ""
|
|
||||||
var remoteVersion: String = ""
|
|
||||||
var versionDescription: String = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
enum VersionUpdateApiResult {
|
|
||||||
case shouldUpdate(report: VersionUpdateReport)
|
|
||||||
case noNeedToUpdate
|
|
||||||
case ignored
|
|
||||||
}
|
|
||||||
|
|
||||||
enum VersionUpdateApiError: Error, LocalizedError {
|
|
||||||
case connectionError(message: String)
|
|
||||||
|
|
||||||
var errorDescription: String? {
|
|
||||||
switch self {
|
|
||||||
case .connectionError(let message):
|
|
||||||
return String(
|
|
||||||
format: NSLocalizedString(
|
|
||||||
"There may be no internet connection or the server failed to respond.\n\nError message: %@",
|
|
||||||
comment: ""
|
|
||||||
), message
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum VersionUpdateApi {
|
|
||||||
static let kCheckUpdateAutomatically = "CheckUpdateAutomatically"
|
|
||||||
static let kNextUpdateCheckDateKey = "NextUpdateCheckDate"
|
|
||||||
static let kUpdateInfoEndpointKey = "UpdateInfoEndpoint"
|
|
||||||
static let kUpdateInfoSiteKey = "UpdateInfoSite"
|
|
||||||
static let kVersionDescription = "VersionDescription"
|
|
||||||
static let kNextCheckInterval: TimeInterval = 86400.0
|
|
||||||
static let kTimeoutInterval: TimeInterval = 60.0
|
|
||||||
static func check(
|
|
||||||
forced: Bool, callback: @escaping (Result<VersionUpdateApiResult, Error>) -> Void
|
|
||||||
) -> URLSessionTask? {
|
|
||||||
guard let infoDict = Bundle.main.infoDictionary,
|
|
||||||
let updateInfoURLString = infoDict[kUpdateInfoEndpointKey] as? String,
|
|
||||||
let updateInfoURL = URL(string: updateInfoURLString)
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
let request = URLRequest(
|
|
||||||
url: updateInfoURL, cachePolicy: .reloadIgnoringLocalCacheData,
|
|
||||||
timeoutInterval: kTimeoutInterval
|
|
||||||
)
|
|
||||||
let task = URLSession.shared.dataTask(with: request) { data, _, error in
|
|
||||||
if let error = error {
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
forced
|
|
||||||
? callback(
|
|
||||||
.failure(
|
|
||||||
VersionUpdateApiError.connectionError(
|
|
||||||
message: error.localizedDescription)))
|
|
||||||
: callback(.success(.ignored))
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
guard
|
|
||||||
let plist = try PropertyListSerialization.propertyList(
|
|
||||||
from: data ?? Data(), options: [], format: nil
|
|
||||||
) as? [AnyHashable: Any],
|
|
||||||
let remoteVersion = plist[kCFBundleVersionKey] as? String,
|
|
||||||
let infoDict = Bundle.main.infoDictionary
|
|
||||||
else {
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
forced
|
|
||||||
? callback(.success(.noNeedToUpdate))
|
|
||||||
: callback(.success(.ignored))
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Validate info (e.g. bundle identifier)
|
|
||||||
// TODO: Use HTML to display change log, need a new key like UpdateInfoChangeLogURL for this
|
|
||||||
|
|
||||||
let currentVersion = infoDict[kCFBundleVersionKey as String] as? String ?? ""
|
|
||||||
let result = currentVersion.compare(
|
|
||||||
remoteVersion, options: .numeric, range: nil, locale: nil
|
|
||||||
)
|
|
||||||
|
|
||||||
if result != .orderedAscending {
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
forced
|
|
||||||
? callback(.success(.noNeedToUpdate))
|
|
||||||
: callback(.success(.ignored))
|
|
||||||
}
|
|
||||||
IME.prtDebugIntel(
|
|
||||||
"vChewingDebug: Update // Order is not Ascending, assuming that there's no new version available."
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
IME.prtDebugIntel(
|
|
||||||
"vChewingDebug: Update // New version detected, proceeding to the next phase.")
|
|
||||||
guard let siteInfoURLString = plist[kUpdateInfoSiteKey] as? String,
|
|
||||||
let siteInfoURL = URL(string: siteInfoURLString)
|
|
||||||
else {
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
forced
|
|
||||||
? callback(.success(.noNeedToUpdate))
|
|
||||||
: callback(.success(.ignored))
|
|
||||||
}
|
|
||||||
IME.prtDebugIntel(
|
|
||||||
"vChewingDebug: Update // Failed from retrieving / parsing URL intel.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
IME.prtDebugIntel(
|
|
||||||
"vChewingDebug: Update // URL intel retrieved, proceeding to the next phase.")
|
|
||||||
var report = VersionUpdateReport(siteUrl: siteInfoURL)
|
|
||||||
var versionDescription = ""
|
|
||||||
let versionDescriptions = plist[kVersionDescription] as? [AnyHashable: Any]
|
|
||||||
if let versionDescriptions = versionDescriptions {
|
|
||||||
var locale = "en"
|
|
||||||
let preferredTags = Bundle.preferredLocalizations(from: IME.arrSupportedLocales)
|
|
||||||
if let first = preferredTags.first {
|
|
||||||
locale = first
|
|
||||||
}
|
|
||||||
versionDescription =
|
|
||||||
versionDescriptions[locale] as? String ?? versionDescriptions["en"]
|
|
||||||
as? String ?? ""
|
|
||||||
if !versionDescription.isEmpty {
|
|
||||||
versionDescription = "\n\n" + versionDescription
|
|
||||||
}
|
|
||||||
}
|
|
||||||
report.currentShortVersion = infoDict["CFBundleShortVersionString"] as? String ?? ""
|
|
||||||
report.currentVersion = currentVersion
|
|
||||||
report.remoteShortVersion = plist["CFBundleShortVersionString"] as? String ?? ""
|
|
||||||
report.remoteVersion = remoteVersion
|
|
||||||
report.versionDescription = versionDescription
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
callback(.success(.shouldUpdate(report: report)))
|
|
||||||
}
|
|
||||||
IME.prtDebugIntel("vChewingDebug: Update // Callbck Complete.")
|
|
||||||
} catch {
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
forced ? callback(.success(.noNeedToUpdate)) : callback(.success(.ignored))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
task.resume()
|
|
||||||
return task
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -55,6 +55,7 @@ public enum UserDef: String, CaseIterable {
|
||||||
case kConsolidateContextOnCandidateSelection = "ConsolidateContextOnCandidateSelection"
|
case kConsolidateContextOnCandidateSelection = "ConsolidateContextOnCandidateSelection"
|
||||||
case kHardenVerticalPunctuations = "HardenVerticalPunctuations"
|
case kHardenVerticalPunctuations = "HardenVerticalPunctuations"
|
||||||
case kTrimUnfinishedReadingsOnCommit = "TrimUnfinishedReadingsOnCommit"
|
case kTrimUnfinishedReadingsOnCommit = "TrimUnfinishedReadingsOnCommit"
|
||||||
|
case kAlwaysShowTooltipTextsHorizontally = "AlwaysShowTooltipTextsHorizontally"
|
||||||
|
|
||||||
case kUseIMKCandidateWindow = "UseIMKCandidateWindow"
|
case kUseIMKCandidateWindow = "UseIMKCandidateWindow"
|
||||||
case kHandleDefaultCandidateFontsByLangIdentifier = "HandleDefaultCandidateFontsByLangIdentifier"
|
case kHandleDefaultCandidateFontsByLangIdentifier = "HandleDefaultCandidateFontsByLangIdentifier"
|
||||||
|
@ -439,6 +440,9 @@ public enum mgrPrefs {
|
||||||
@UserDefault(key: UserDef.kTrimUnfinishedReadingsOnCommit.rawValue, defaultValue: true)
|
@UserDefault(key: UserDef.kTrimUnfinishedReadingsOnCommit.rawValue, defaultValue: true)
|
||||||
static var trimUnfinishedReadingsOnCommit: Bool
|
static var trimUnfinishedReadingsOnCommit: Bool
|
||||||
|
|
||||||
|
@UserDefault(key: UserDef.kAlwaysShowTooltipTextsHorizontally.rawValue, defaultValue: false)
|
||||||
|
static var alwaysShowTooltipTextsHorizontally: Bool
|
||||||
|
|
||||||
// MARK: - Settings (Tier 2)
|
// MARK: - Settings (Tier 2)
|
||||||
|
|
||||||
@UserDefault(key: UserDef.kUseIMKCandidateWindow.rawValue, defaultValue: false)
|
@UserDefault(key: UserDef.kUseIMKCandidateWindow.rawValue, defaultValue: false)
|
||||||
|
@ -459,7 +463,7 @@ public enum mgrPrefs {
|
||||||
@UserDefault(key: UserDef.kMaxCandidateLength.rawValue, defaultValue: 10)
|
@UserDefault(key: UserDef.kMaxCandidateLength.rawValue, defaultValue: 10)
|
||||||
static var maxCandidateLength: Int
|
static var maxCandidateLength: Int
|
||||||
|
|
||||||
static var allowedMarkRange: ClosedRange<Int> = mgrPrefs.minCandidateLength...mgrPrefs.maxCandidateLength
|
static var allowedMarkLengthRange: ClosedRange<Int> = mgrPrefs.minCandidateLength...mgrPrefs.maxCandidateLength
|
||||||
|
|
||||||
@UserDefault(key: UserDef.kShouldNotFartInLieuOfBeep.rawValue, defaultValue: true)
|
@UserDefault(key: UserDef.kShouldNotFartInLieuOfBeep.rawValue, defaultValue: true)
|
||||||
static var shouldNotFartInLieuOfBeep: Bool
|
static var shouldNotFartInLieuOfBeep: Bool
|
||||||
|
|
|
@ -194,6 +194,7 @@ extension vChewing.LMUserOverride {
|
||||||
let decoder = JSONDecoder()
|
let decoder = JSONDecoder()
|
||||||
do {
|
do {
|
||||||
let data = try Data(contentsOf: fileURL, options: .mappedIfSafe)
|
let data = try Data(contentsOf: fileURL, options: .mappedIfSafe)
|
||||||
|
if ["", "{}"].contains(String(data: data, encoding: .utf8)) { return }
|
||||||
guard let jsonResult = try? decoder.decode([String: KeyObservationPair].self, from: data) else {
|
guard let jsonResult = try? decoder.decode([String: KeyObservationPair].self, from: data) else {
|
||||||
IME.prtDebugIntel("UOM Error: Read file content type invalid, abort loading.")
|
IME.prtDebugIntel("UOM Error: Read file content type invalid, abort loading.")
|
||||||
return
|
return
|
||||||
|
|
|
@ -271,8 +271,10 @@ enum mgrLangModel {
|
||||||
static func userOverrideModelDataURL(_ mode: InputMode) -> URL {
|
static func userOverrideModelDataURL(_ mode: InputMode) -> URL {
|
||||||
let fileName =
|
let fileName =
|
||||||
(mode == InputMode.imeModeCHT)
|
(mode == InputMode.imeModeCHT)
|
||||||
? "../vChewing_override-model-data-cht.dat" : "../vChewing_override-model-data-chs.dat"
|
? "vChewing_override-model-data-cht.dat" : "vChewing_override-model-data-chs.dat"
|
||||||
return URL(fileURLWithPath: dataFolderPath(isDefaultFolder: true)).appendingPathComponent(fileName)
|
return URL(
|
||||||
|
fileURLWithPath: dataFolderPath(isDefaultFolder: true)
|
||||||
|
).deletingLastPathComponent().appendingPathComponent(fileName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - 檢查具體的使用者語彙檔案是否存在
|
// MARK: - 檢查具體的使用者語彙檔案是否存在
|
||||||
|
@ -459,11 +461,10 @@ enum mgrLangModel {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// We use FSEventStream to monitor possible changes of the user phrase folder, hence the
|
// The new FolderMonitor module does NOT monitor cases that files are modified
|
||||||
// lack of the needs of manually load data here unless FSEventStream is disabled by user.
|
// by the current application itself, requiring additional manual loading process here.
|
||||||
if !mgrPrefs.shouldAutoReloadUserDataFiles {
|
// if !mgrPrefs.shouldAutoReloadUserDataFiles {}
|
||||||
loadUserPhrasesData()
|
loadUserPhrasesData()
|
||||||
}
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -154,47 +154,26 @@ public class ctlCandidate: NSWindowController, ctlCandidateProtocol {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func doSet(windowTopLeftPoint: NSPoint, bottomOutOfScreenAdjustmentHeight height: CGFloat) {
|
func doSet(windowTopLeftPoint: NSPoint, bottomOutOfScreenAdjustmentHeight heightDelta: CGFloat) {
|
||||||
var adjustedPoint = windowTopLeftPoint
|
guard let window = window else { return }
|
||||||
var adjustedHeight = height
|
let windowSize = window.frame.size
|
||||||
|
|
||||||
|
var adjustedPoint = windowTopLeftPoint
|
||||||
|
var delta = heightDelta
|
||||||
var screenFrame = NSScreen.main?.visibleFrame ?? NSRect.zero
|
var screenFrame = NSScreen.main?.visibleFrame ?? NSRect.zero
|
||||||
for screen in NSScreen.screens {
|
for frame in NSScreen.screens.map(\.visibleFrame).filter({ !$0.contains(windowTopLeftPoint) }) {
|
||||||
let frame = screen.visibleFrame
|
|
||||||
if windowTopLeftPoint.x >= frame.minX, windowTopLeftPoint.x <= frame.maxX,
|
|
||||||
windowTopLeftPoint.y >= frame.minY, windowTopLeftPoint.y <= frame.maxY
|
|
||||||
{
|
|
||||||
screenFrame = frame
|
screenFrame = frame
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if delta > screenFrame.size.height / 2.0 { delta = 0.0 }
|
||||||
|
|
||||||
|
if adjustedPoint.y < screenFrame.minY + windowSize.height {
|
||||||
|
adjustedPoint.y = windowTopLeftPoint.y + windowSize.height + delta
|
||||||
}
|
}
|
||||||
|
adjustedPoint.y = min(adjustedPoint.y, screenFrame.maxY - 1.0)
|
||||||
|
adjustedPoint.x = min(max(adjustedPoint.x, screenFrame.minX), screenFrame.maxX - windowSize.width - 1.0)
|
||||||
|
|
||||||
if adjustedHeight > screenFrame.size.height / 2.0 {
|
window.setFrameTopLeftPoint(adjustedPoint)
|
||||||
adjustedHeight = 0.0
|
|
||||||
}
|
|
||||||
|
|
||||||
let windowSize = window?.frame.size ?? NSSize.zero
|
|
||||||
|
|
||||||
// bottom beneath the screen?
|
|
||||||
if adjustedPoint.y - windowSize.height < screenFrame.minY {
|
|
||||||
adjustedPoint.y = windowTopLeftPoint.y + adjustedHeight + windowSize.height
|
|
||||||
}
|
|
||||||
|
|
||||||
// top over the screen?
|
|
||||||
if adjustedPoint.y >= screenFrame.maxY {
|
|
||||||
adjustedPoint.y = screenFrame.maxY - 1.0
|
|
||||||
}
|
|
||||||
|
|
||||||
// right
|
|
||||||
if adjustedPoint.x + windowSize.width >= screenFrame.maxX {
|
|
||||||
adjustedPoint.x = screenFrame.maxX - windowSize.width
|
|
||||||
}
|
|
||||||
|
|
||||||
// left
|
|
||||||
if adjustedPoint.x < screenFrame.minX {
|
|
||||||
adjustedPoint.x = screenFrame.minX
|
|
||||||
}
|
|
||||||
|
|
||||||
window?.setFrameTopLeftPoint(adjustedPoint)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ struct suiPrefPaneDictionary: View {
|
||||||
tbxUserDataPathSpecified = mgrPrefs.userDataFolderSpecified
|
tbxUserDataPathSpecified = mgrPrefs.userDataFolderSpecified
|
||||||
BookmarkManager.shared.saveBookmark(for: url)
|
BookmarkManager.shared.saveBookmark(for: url)
|
||||||
IME.initLangModels(userOnly: true)
|
IME.initLangModels(userOnly: true)
|
||||||
(NSApplication.shared.delegate as! AppDelegate).updateStreamHelperPath()
|
(NSApplication.shared.delegate as! AppDelegate).updateDirectoryMonitorPath()
|
||||||
} else {
|
} else {
|
||||||
clsSFX.beep()
|
clsSFX.beep()
|
||||||
if !bolPreviousFolderValidity {
|
if !bolPreviousFolderValidity {
|
||||||
|
|
|
@ -43,6 +43,8 @@ struct suiPrefPaneExperience: View {
|
||||||
forKey: UserDef.kSpecifyShiftBackSpaceKeyBehavior.rawValue)
|
forKey: UserDef.kSpecifyShiftBackSpaceKeyBehavior.rawValue)
|
||||||
@State private var selTrimUnfinishedReadingsOnCommit = UserDefaults.standard.bool(
|
@State private var selTrimUnfinishedReadingsOnCommit = UserDefaults.standard.bool(
|
||||||
forKey: UserDef.kTrimUnfinishedReadingsOnCommit.rawValue)
|
forKey: UserDef.kTrimUnfinishedReadingsOnCommit.rawValue)
|
||||||
|
@State private var selAlwaysShowTooltipTextsHorizontally = UserDefaults.standard.bool(
|
||||||
|
forKey: UserDef.kAlwaysShowTooltipTextsHorizontally.rawValue)
|
||||||
|
|
||||||
private let contentMaxHeight: Double = 432
|
private let contentMaxHeight: Double = 432
|
||||||
private let contentWidth: Double = {
|
private let contentWidth: Double = {
|
||||||
|
@ -236,6 +238,17 @@ struct suiPrefPaneExperience: View {
|
||||||
)
|
)
|
||||||
Text(LocalizedStringKey("An accommodation for elder computer users."))
|
Text(LocalizedStringKey("An accommodation for elder computer users."))
|
||||||
.preferenceDescription()
|
.preferenceDescription()
|
||||||
|
Toggle(
|
||||||
|
LocalizedStringKey("Always show tooltip texts horizontally"),
|
||||||
|
isOn: $selAlwaysShowTooltipTextsHorizontally.onChange {
|
||||||
|
mgrPrefs.alwaysShowTooltipTextsHorizontally = selAlwaysShowTooltipTextsHorizontally
|
||||||
|
}
|
||||||
|
).disabled(Bundle.main.preferredLocalizations[0] == "en")
|
||||||
|
Text(
|
||||||
|
LocalizedStringKey(
|
||||||
|
"Key names in tooltip will be shown as symbols when the tooltip is vertical. However, this option will be ignored since tooltip will always be horizontal if the UI language is English."
|
||||||
|
)
|
||||||
|
).preferenceDescription()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,7 +154,7 @@ struct suiPrefPaneGeneral: View {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
Toggle(
|
Toggle(
|
||||||
LocalizedStringKey("Show Hanyu-Pinyin in the inline composition buffer & tooltip"),
|
LocalizedStringKey("Show Hanyu-Pinyin in the inline composition buffer"),
|
||||||
isOn: $selShowHanyuPinyinInCompositionBuffer.onChange {
|
isOn: $selShowHanyuPinyinInCompositionBuffer.onChange {
|
||||||
mgrPrefs.showHanyuPinyinInCompositionBuffer = selShowHanyuPinyinInCompositionBuffer
|
mgrPrefs.showHanyuPinyinInCompositionBuffer = selShowHanyuPinyinInCompositionBuffer
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,172 +0,0 @@
|
||||||
// (c) 2021 and onwards Weizhong Yang (MIT License).
|
|
||||||
// All possible vChewing-specific modifications are of:
|
|
||||||
// (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 TooltipController: NSWindowController {
|
|
||||||
public enum ColorStates {
|
|
||||||
case normal
|
|
||||||
case redAlert
|
|
||||||
case warning
|
|
||||||
case denialOverflow
|
|
||||||
case denialInsufficiency
|
|
||||||
case prompt
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum displayDirection {
|
|
||||||
case horizontal
|
|
||||||
case vertical
|
|
||||||
}
|
|
||||||
|
|
||||||
private var backgroundColor = NSColor.windowBackgroundColor
|
|
||||||
private var textColor = NSColor.windowBackgroundColor
|
|
||||||
private var messageTextField: NSTextField
|
|
||||||
private var tooltip: String = "" {
|
|
||||||
didSet {
|
|
||||||
messageTextField.stringValue = tooltip
|
|
||||||
adjustSize()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public var direction: displayDirection = .horizontal
|
|
||||||
|
|
||||||
public init() {
|
|
||||||
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.level = NSWindow.Level(Int(kCGPopUpMenuWindowLevel) + 1)
|
|
||||||
panel.hasShadow = true
|
|
||||||
|
|
||||||
messageTextField = NSTextField()
|
|
||||||
messageTextField.isEditable = false
|
|
||||||
messageTextField.isSelectable = false
|
|
||||||
messageTextField.isBezeled = false
|
|
||||||
messageTextField.textColor = textColor
|
|
||||||
messageTextField.drawsBackground = true
|
|
||||||
messageTextField.backgroundColor = backgroundColor
|
|
||||||
messageTextField.font = .systemFont(ofSize: NSFont.systemFontSize(for: .small))
|
|
||||||
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(tooltip: String, at point: NSPoint) {
|
|
||||||
messageTextField.textColor = textColor
|
|
||||||
messageTextField.backgroundColor = backgroundColor
|
|
||||||
self.tooltip = tooltip
|
|
||||||
window?.orderFront(nil)
|
|
||||||
set(windowLocation: point)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func setColor(state: ColorStates) {
|
|
||||||
switch state {
|
|
||||||
case .normal:
|
|
||||||
backgroundColor = NSColor(
|
|
||||||
red: 0.18, green: 0.18, blue: 0.18, alpha: 1.00
|
|
||||||
)
|
|
||||||
textColor = NSColor.white
|
|
||||||
case .redAlert:
|
|
||||||
backgroundColor = NSColor(
|
|
||||||
red: 0.55, green: 0.00, blue: 0.00, alpha: 1.00
|
|
||||||
)
|
|
||||||
textColor = NSColor.white
|
|
||||||
case .warning:
|
|
||||||
backgroundColor = NSColor.purple
|
|
||||||
textColor = NSColor.white
|
|
||||||
case .denialOverflow:
|
|
||||||
backgroundColor = NSColor(
|
|
||||||
red: 0.13, green: 0.08, blue: 0.00, alpha: 1.00
|
|
||||||
)
|
|
||||||
textColor = NSColor(
|
|
||||||
red: 1.00, green: 0.60, blue: 0.00, alpha: 1.00
|
|
||||||
)
|
|
||||||
case .denialInsufficiency:
|
|
||||||
backgroundColor = NSColor(
|
|
||||||
red: 0.18, green: 0.18, blue: 0.18, alpha: 1.00
|
|
||||||
)
|
|
||||||
textColor = NSColor(
|
|
||||||
red: 0.86, green: 0.86, blue: 0.86, alpha: 1.00
|
|
||||||
)
|
|
||||||
case .prompt:
|
|
||||||
backgroundColor = NSColor(
|
|
||||||
red: 0.00, green: 0.18, blue: 0.13, alpha: 1.00
|
|
||||||
)
|
|
||||||
textColor = NSColor(
|
|
||||||
red: 0.00, green: 1.00, blue: 0.74, alpha: 1.00
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func resetColor() {
|
|
||||||
setColor(state: .normal)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc
|
|
||||||
public func hide() {
|
|
||||||
window?.orderOut(nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func set(windowLocation windowTopLeftPoint: NSPoint) {
|
|
||||||
var adjustedPoint = windowTopLeftPoint
|
|
||||||
adjustedPoint.y -= 5
|
|
||||||
|
|
||||||
var screenFrame = NSScreen.main?.visibleFrame ?? NSRect.zero
|
|
||||||
for screen in NSScreen.screens {
|
|
||||||
let frame = screen.visibleFrame
|
|
||||||
if windowTopLeftPoint.x >= frame.minX, windowTopLeftPoint.x <= frame.maxX,
|
|
||||||
windowTopLeftPoint.y >= frame.minY, windowTopLeftPoint.y <= frame.maxY
|
|
||||||
{
|
|
||||||
screenFrame = frame
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let windowSize = window?.frame.size ?? NSSize.zero
|
|
||||||
|
|
||||||
// bottom beneath the screen?
|
|
||||||
if adjustedPoint.y - windowSize.height < screenFrame.minY {
|
|
||||||
adjustedPoint.y = screenFrame.minY + windowSize.height
|
|
||||||
}
|
|
||||||
|
|
||||||
// top over the screen?
|
|
||||||
if adjustedPoint.y >= screenFrame.maxY {
|
|
||||||
adjustedPoint.y = screenFrame.maxY - 1.0
|
|
||||||
}
|
|
||||||
|
|
||||||
// right
|
|
||||||
if adjustedPoint.x + windowSize.width >= screenFrame.maxX {
|
|
||||||
adjustedPoint.x = screenFrame.maxX - windowSize.width
|
|
||||||
}
|
|
||||||
|
|
||||||
// left
|
|
||||||
if adjustedPoint.x < screenFrame.minX {
|
|
||||||
adjustedPoint.x = screenFrame.minX
|
|
||||||
}
|
|
||||||
|
|
||||||
window?.setFrameTopLeftPoint(adjustedPoint)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func adjustSize() {
|
|
||||||
let attrString = messageTextField.attributedStringValue
|
|
||||||
var rect = attrString.boundingRect(
|
|
||||||
with: NSSize(width: 1600.0, height: 1600.0), options: .usesLineFragmentOrigin
|
|
||||||
)
|
|
||||||
|
|
||||||
rect.size.width += 10
|
|
||||||
messageTextField.frame = rect
|
|
||||||
window?.setFrame(rect, display: true)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,177 @@
|
||||||
|
// (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 ctlTooltip: NSWindowController {
|
||||||
|
public enum ColorStates {
|
||||||
|
case normal
|
||||||
|
case redAlert
|
||||||
|
case warning
|
||||||
|
case denialOverflow
|
||||||
|
case denialInsufficiency
|
||||||
|
case prompt
|
||||||
|
}
|
||||||
|
|
||||||
|
private var messageText: NSAttributedTextView
|
||||||
|
private var tooltip: String = "" {
|
||||||
|
didSet {
|
||||||
|
messageText.text = tooltip.isEmpty ? nil : tooltip
|
||||||
|
adjustSize()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public var direction: NSAttributedTextView.writingDirection = .horizontal {
|
||||||
|
didSet {
|
||||||
|
if #unavailable(macOS 10.13) { direction = .horizontal }
|
||||||
|
if Bundle.main.preferredLocalizations[0] == "en" { direction = .horizontal }
|
||||||
|
messageText.direction = direction
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public init() {
|
||||||
|
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.level = NSWindow.Level(Int(kCGPopUpMenuWindowLevel) + 1)
|
||||||
|
panel.hasShadow = true
|
||||||
|
panel.backgroundColor = NSColor.controlBackgroundColor
|
||||||
|
messageText = NSAttributedTextView()
|
||||||
|
messageText.backgroundColor = NSColor.controlBackgroundColor
|
||||||
|
messageText.textColor = NSColor.textColor
|
||||||
|
panel.contentView?.addSubview(messageText)
|
||||||
|
super.init(window: panel)
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(*, unavailable)
|
||||||
|
public required init?(coder _: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
public func show(
|
||||||
|
tooltip: String = "", at point: NSPoint,
|
||||||
|
bottomOutOfScreenAdjustmentHeight heightDelta: CGFloat,
|
||||||
|
direction: NSAttributedTextView.writingDirection = .horizontal
|
||||||
|
) {
|
||||||
|
self.direction = direction
|
||||||
|
self.tooltip = tooltip
|
||||||
|
window?.orderFront(nil)
|
||||||
|
set(windowTopLeftPoint: point, bottomOutOfScreenAdjustmentHeight: heightDelta)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func setColor(state: ColorStates) {
|
||||||
|
var backgroundColor = NSColor.controlBackgroundColor
|
||||||
|
var textColor = NSColor.textColor
|
||||||
|
switch state {
|
||||||
|
case .normal:
|
||||||
|
backgroundColor = NSColor(
|
||||||
|
red: 0.18, green: 0.18, blue: 0.18, alpha: 1.00
|
||||||
|
)
|
||||||
|
textColor = NSColor.white
|
||||||
|
case .redAlert:
|
||||||
|
backgroundColor = NSColor(
|
||||||
|
red: 0.55, green: 0.00, blue: 0.00, alpha: 1.00
|
||||||
|
)
|
||||||
|
textColor = NSColor.white
|
||||||
|
case .warning:
|
||||||
|
backgroundColor = NSColor.purple
|
||||||
|
textColor = NSColor.white
|
||||||
|
case .denialOverflow:
|
||||||
|
backgroundColor = NSColor(
|
||||||
|
red: 0.13, green: 0.08, blue: 0.00, alpha: 1.00
|
||||||
|
)
|
||||||
|
textColor = NSColor(
|
||||||
|
red: 1.00, green: 0.60, blue: 0.00, alpha: 1.00
|
||||||
|
)
|
||||||
|
case .denialInsufficiency:
|
||||||
|
backgroundColor = NSColor.windowBackgroundColor
|
||||||
|
textColor = NSColor.labelColor
|
||||||
|
case .prompt:
|
||||||
|
backgroundColor = NSColor(
|
||||||
|
red: 0.09, green: 0.15, blue: 0.15, alpha: 1.00
|
||||||
|
)
|
||||||
|
textColor = NSColor(
|
||||||
|
red: 0.91, green: 0.95, blue: 0.92, alpha: 1.00
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if !IME.isDarkMode {
|
||||||
|
switch state {
|
||||||
|
case .denialInsufficiency: break
|
||||||
|
default:
|
||||||
|
let colorInterchange = backgroundColor
|
||||||
|
backgroundColor = textColor
|
||||||
|
textColor = colorInterchange
|
||||||
|
}
|
||||||
|
}
|
||||||
|
window?.backgroundColor = backgroundColor
|
||||||
|
messageText.backgroundColor = backgroundColor
|
||||||
|
messageText.textColor = textColor
|
||||||
|
}
|
||||||
|
|
||||||
|
public func resetColor() {
|
||||||
|
setColor(state: .normal)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func hide() {
|
||||||
|
window?.orderOut(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func set(windowTopLeftPoint: NSPoint, bottomOutOfScreenAdjustmentHeight heightDelta: CGFloat) {
|
||||||
|
guard let window = window else { return }
|
||||||
|
let windowSize = window.frame.size
|
||||||
|
|
||||||
|
var adjustedPoint = windowTopLeftPoint
|
||||||
|
var delta = heightDelta
|
||||||
|
var screenFrame = NSScreen.main?.visibleFrame ?? NSRect.zero
|
||||||
|
for frame in NSScreen.screens.map(\.visibleFrame).filter({ !$0.contains(windowTopLeftPoint) }) {
|
||||||
|
screenFrame = frame
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if delta > screenFrame.size.height / 2.0 { delta = 0.0 }
|
||||||
|
|
||||||
|
if adjustedPoint.y < screenFrame.minY + windowSize.height {
|
||||||
|
adjustedPoint.y = windowTopLeftPoint.y + windowSize.height + delta
|
||||||
|
}
|
||||||
|
adjustedPoint.y = min(adjustedPoint.y, screenFrame.maxY - 1.0)
|
||||||
|
adjustedPoint.x = min(max(adjustedPoint.x, screenFrame.minX), screenFrame.maxX - windowSize.width - 1.0)
|
||||||
|
|
||||||
|
window.setFrameTopLeftPoint(adjustedPoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func adjustSize() {
|
||||||
|
let attrString = messageText.attributedStringValue
|
||||||
|
var rect = attrString.boundingRect(
|
||||||
|
with: NSSize(width: 1600.0, height: 1600.0),
|
||||||
|
options: [.usesLineFragmentOrigin, .usesFontLeading, .usesDeviceMetrics]
|
||||||
|
)
|
||||||
|
if direction != .horizontal {
|
||||||
|
rect = .init(x: rect.minX, y: rect.minY, width: rect.height, height: rect.width)
|
||||||
|
rect.size.height += NSFont.systemFontSize
|
||||||
|
rect.size.width *= 1.03
|
||||||
|
rect.size.width = max(rect.size.width, NSFont.systemFontSize * 1.05)
|
||||||
|
rect.size.width = ceil(rect.size.width)
|
||||||
|
} else {
|
||||||
|
rect = .init(x: rect.minX, y: rect.minY, width: rect.width, height: rect.height)
|
||||||
|
rect.size.width += NSFont.systemFontSize
|
||||||
|
rect.size.height *= 1.03
|
||||||
|
rect.size.height = max(rect.size.height, NSFont.systemFontSize * 1.05)
|
||||||
|
rect.size.height = ceil(rect.size.height)
|
||||||
|
}
|
||||||
|
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
|
||||||
|
messageText.frame = rect
|
||||||
|
window?.setFrame(bigRect, display: true)
|
||||||
|
messageText.draw(messageText.frame)
|
||||||
|
}
|
||||||
|
}
|
|
@ -55,6 +55,15 @@ else {
|
||||||
exit(-1)
|
exit(-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
guard let mainBundleInfoDict = Bundle.main.infoDictionary,
|
||||||
|
let strUpdateInfoSource = mainBundleInfoDict["UpdateInfoEndpoint"] as? String,
|
||||||
|
let urlUpdateInfoSource = URL(string: strUpdateInfoSource)
|
||||||
|
else {
|
||||||
|
NSLog("Fatal error: Info.plist wrecked It needs to have correct 'UpdateInfoEndpoint' value.")
|
||||||
|
exit(-1)
|
||||||
|
}
|
||||||
|
|
||||||
public let theServer = server
|
public let theServer = server
|
||||||
|
public let kUpdateInfoSourceURL = urlUpdateInfoSource
|
||||||
|
|
||||||
NSApp.run()
|
NSApp.run()
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
"vChewing" = "vChewing";
|
"vChewing" = "vChewing";
|
||||||
|
"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 downloaded is nil.";
|
||||||
|
"Plist downloaded cannot be parsed correctly." = "Plist downloaded cannot be parsed correctly.";
|
||||||
"vChewing crashed while handling previously loaded UOM observation data. These data files are cleaned now to ensure the usability." = "vChewing crashed while handling previously loaded UOM observation data. These data files are cleaned now to ensure the usability.";
|
"vChewing crashed while handling previously loaded UOM observation data. These data files are cleaned now to ensure the usability." = "vChewing crashed while handling previously loaded UOM observation data. These data files are cleaned now to ensure the usability.";
|
||||||
"About vChewing…" = "About vChewing…";
|
"About vChewing…" = "About vChewing…";
|
||||||
"vChewing Preferences…" = "vChewing Preferences…";
|
"vChewing Preferences…" = "vChewing Preferences…";
|
||||||
|
@ -17,7 +21,7 @@
|
||||||
"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";
|
||||||
"You're currently using vChewing %@ (%@), a new version %@ (%@) is now available. Do you want to visit vChewing's website to download the version?%@" = "You're currently using vChewing %@ (%@), a new version %@ (%@) is now available. Do you want to visit vChewing's website to download the version?%@";
|
"You're currently using vChewing %@ (%@), a new version %@ (%@) is now available. Do you want to visit vChewing's website to download the version?" = "You're currently using vChewing %@ (%@), a new version %@ (%@) is now available. Do you want to visit vChewing's website to download the version?";
|
||||||
"Force KangXi Writing" = "Force KangXi Writing";
|
"Force KangXi Writing" = "Force KangXi Writing";
|
||||||
"NotificationSwitchON" = "✔ ON";
|
"NotificationSwitchON" = "✔ ON";
|
||||||
"NotificationSwitchOFF" = "✘ OFF";
|
"NotificationSwitchOFF" = "✘ OFF";
|
||||||
|
@ -30,7 +34,7 @@
|
||||||
"\"%@\" length must ≥ 2 for a user phrase." = "\"%@\" length must ≥ 2 for a user phrase.";
|
"\"%@\" length must ≥ 2 for a user phrase." = "\"%@\" length must ≥ 2 for a user phrase.";
|
||||||
"\"%@\" length should ≤ %d for a user phrase." = "\"%@\" length should ≤ %d for a user phrase.";
|
"\"%@\" length should ≤ %d for a user phrase." = "\"%@\" length should ≤ %d for a user phrase.";
|
||||||
"\"%@\" selected. ENTER to add user phrase." = "\"%@\" selected. ENTER to add user phrase.";
|
"\"%@\" selected. ENTER to add user phrase." = "\"%@\" selected. ENTER to add user phrase.";
|
||||||
"\"%@\" already exists: ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude." = "\"%@\" already exists: ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude.";
|
"\"%@\" already exists:\n ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude." = "\"%@\" already exists:\n ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude.";
|
||||||
"Edit Phrase Replacement Table…" = "Edit Phrase Replacement Table…";
|
"Edit Phrase Replacement Table…" = "Edit Phrase Replacement Table…";
|
||||||
"Use Phrase Replacement" = "Use Phrase Replacement";
|
"Use Phrase Replacement" = "Use Phrase Replacement";
|
||||||
"Candidates keys cannot be empty." = "Candidates keys cannot be empty.";
|
"Candidates keys cannot be empty." = "Candidates keys cannot be empty.";
|
||||||
|
@ -96,11 +100,13 @@
|
||||||
// SwiftUI Preferences
|
// SwiftUI Preferences
|
||||||
"(Shift+)Space:" = "(Shift+)Space:";
|
"(Shift+)Space:" = "(Shift+)Space:";
|
||||||
"⚠︎ This feature in IMK Candidate Window defects. Please consult Apple Developer Relations\nand tell them the related Radar ID: #FB11300759." = "⚠︎ This feature in IMK Candidate Window defects. Please consult Apple Developer Relations\nand tell them the related Radar ID: #FB11300759.";
|
"⚠︎ This feature in IMK Candidate Window defects. Please consult Apple Developer Relations\nand tell them the related Radar ID: #FB11300759." = "⚠︎ This feature in IMK Candidate Window defects. Please consult Apple Developer Relations\nand tell them the related Radar ID: #FB11300759.";
|
||||||
|
"⚠︎ This feature is useful ONLY WHEN the font you are using doesn't support dynamic vertical punctuations. However, typed vertical punctuations will always shown as vertical punctuations EVEN IF your editor has changed the typing direction to horizontal." = "⚠︎ This feature is useful ONLY WHEN the font you are using doesn't support dynamic vertical punctuations. However, typed vertical punctuations will always shown as vertical punctuations EVEN IF your editor has changed the typing direction to horizontal.";
|
||||||
"Allow backspace-editing miscomposed readings" = "Allow backspace-editing miscomposed readings";
|
"Allow backspace-editing miscomposed readings" = "Allow backspace-editing miscomposed readings";
|
||||||
"Allow boosting / excluding a candidate of single kanji" = "Allow boosting / excluding a candidate of single kanji";
|
"Allow boosting / excluding a candidate of single kanji" = "Allow boosting / excluding a candidate of single kanji";
|
||||||
"Allow using Enter key to confirm associated candidate selection" = "Allow using Enter key to confirm associated candidate selection";
|
"Allow using Enter key to confirm associated candidate selection" = "Allow using Enter key to confirm associated candidate selection";
|
||||||
"Also toggle alphanumerical mode with Left-Shift" = "Also toggle alphanumerical mode with Left-Shift";
|
"Also toggle alphanumerical mode with Left-Shift" = "Also toggle alphanumerical mode with Left-Shift";
|
||||||
"Always drop the previous reading" = "Always drop the previous reading";
|
"Always drop the previous reading" = "Always drop the previous reading";
|
||||||
|
"Always show tooltip texts horizontally" = "Always show tooltip texts horizontally";
|
||||||
"Always type intonations to the inline composition buffer" = "Always type intonations to the inline composition buffer";
|
"Always type intonations to the inline composition buffer" = "Always type intonations to the inline composition buffer";
|
||||||
"Always use fixed listing order in candidate window" = "Always use fixed listing order in candidate window";
|
"Always use fixed listing order in candidate window" = "Always use fixed listing order in candidate window";
|
||||||
"An accommodation for elder computer users." = "An accommodation for elder computer users.";
|
"An accommodation for elder computer users." = "An accommodation for elder computer users.";
|
||||||
|
@ -141,6 +147,7 @@
|
||||||
"Dictionary" = "Dictionary";
|
"Dictionary" = "Dictionary";
|
||||||
"Directly commit lowercased letters" = "Directly commit lowercased letters";
|
"Directly commit lowercased letters" = "Directly commit lowercased letters";
|
||||||
"Directly commit uppercased letters" = "Directly commit uppercased letters";
|
"Directly commit uppercased letters" = "Directly commit uppercased letters";
|
||||||
|
"Disable Shift key accomodation in all cases" = "Disable Shift key accomodation in all cases";
|
||||||
"Disassemble the previous reading, dropping its intonation" = "Disassemble the previous reading, dropping its intonation";
|
"Disassemble the previous reading, dropping its intonation" = "Disassemble the previous reading, dropping its intonation";
|
||||||
"Disassembling process does not work with non-phonetic reading keys." = "Disassembling process does not work with non-phonetic reading keys.";
|
"Disassembling process does not work with non-phonetic reading keys." = "Disassembling process does not work with non-phonetic reading keys.";
|
||||||
"Emulating select-candidate-per-character mode" = "Emulating select-candidate-per-character mode";
|
"Emulating select-candidate-per-character mode" = "Emulating select-candidate-per-character mode";
|
||||||
|
@ -155,10 +162,10 @@
|
||||||
"Follow OS settings" = "Follow OS settings";
|
"Follow OS settings" = "Follow OS settings";
|
||||||
"for cycling candidates" = "for cycling candidates";
|
"for cycling candidates" = "for cycling candidates";
|
||||||
"for cycling pages" = "for cycling pages";
|
"for cycling pages" = "for cycling pages";
|
||||||
|
"For example: When typing “章太炎” and you want to override the “太” with “泰”, and the raw operation index range [1,2) which bounds are cutting the current node “章太炎” in range [0,3). If having lack of the pre-consolidation process, this word will become something like “張泰言” after the candidate selection. Only if we enable this consolidation, this word will become “章泰炎” which is the expected result that the context is kept as-is." = "For example: When typing “章太炎” and you want to override the “太” with “泰”, and the raw operation index range [1,2) which bounds are cutting the current node “章太炎” in range [0,3). If having lack of the pre-consolidation process, this word will become something like “張泰言” after the candidate selection. Only if we enable this consolidation, this word will become “章泰炎” which is the expected result that the context is kept as-is.";
|
||||||
"General" = "General";
|
"General" = "General";
|
||||||
"Hanyu Pinyin with Numeral Intonation" = "Hanyu Pinyin with Numeral Intonation";
|
"Hanyu Pinyin with Numeral Intonation" = "Hanyu Pinyin with Numeral Intonation";
|
||||||
"Harden vertical punctuations during vertical typing (not recommended)" = "Harden vertical punctuations during vertical typing (not recommended)";
|
"Harden vertical punctuations during vertical typing (not recommended)" = "Harden vertical punctuations during vertical typing (not recommended)";
|
||||||
"⚠︎ This feature is useful ONLY WHEN the font you are using doesn't support dynamic vertical punctuations. However, typed vertical punctuations will always shown as vertical punctuations EVEN IF your editor has changed the typing direction to horizontal." = "⚠︎ This feature is useful ONLY WHEN the font you are using doesn't support dynamic vertical punctuations. However, typed vertical punctuations will always shown as vertical punctuations EVEN IF your editor has changed the typing direction to horizontal.";
|
|
||||||
"Horizontal" = "Horizontal";
|
"Horizontal" = "Horizontal";
|
||||||
"Hsu" = "Hsu";
|
"Hsu" = "Hsu";
|
||||||
"Hualuo Pinyin with Numeral Intonation" = "Hualuo Pinyin with Numeral Intonation";
|
"Hualuo Pinyin with Numeral Intonation" = "Hualuo Pinyin with Numeral Intonation";
|
||||||
|
@ -167,6 +174,7 @@
|
||||||
"in front of the phrase (like macOS built-in Zhuyin IME)" = "in front of the phrase (like macOS built-in Zhuyin IME)";
|
"in front of the phrase (like macOS built-in Zhuyin IME)" = "in front of the phrase (like macOS built-in Zhuyin IME)";
|
||||||
"Intonation Key:" = "Intonation Key:";
|
"Intonation Key:" = "Intonation Key:";
|
||||||
"Japanese" = "Japanese";
|
"Japanese" = "Japanese";
|
||||||
|
"Key names in tooltip will be shown as symbols when the tooltip is vertical. However, this option will be ignored since tooltip will always be horizontal if the UI language is English." = "Key names in tooltip will be shown as symbols when the tooltip is vertical. However, this option will be ignored since tooltip will always be horizontal if the UI language is English.";
|
||||||
"Keyboard Shortcuts:" = "Keyboard Shortcuts:";
|
"Keyboard Shortcuts:" = "Keyboard Shortcuts:";
|
||||||
"Keyboard" = "Keyboard";
|
"Keyboard" = "Keyboard";
|
||||||
"Misc Settings:" = "Misc Settings:";
|
"Misc Settings:" = "Misc Settings:";
|
||||||
|
@ -174,6 +182,7 @@
|
||||||
"Non-QWERTY alphanumerical keyboard layouts are for Pinyin parser only." = "Non-QWERTY alphanumerical keyboard layouts are for Pinyin parser only.";
|
"Non-QWERTY alphanumerical keyboard layouts are for Pinyin parser only." = "Non-QWERTY alphanumerical keyboard layouts are for Pinyin parser only.";
|
||||||
"Note: The “Delete ⌫” key on Mac keyboard is named as “BackSpace ⌫” here in order to distinguish the real “Delete ⌦” key from full-sized desktop keyboards. If you want to use the real “Delete ⌦” key on a Mac keyboard with no numpad equipped, you have to press “Fn+⌫” instead." = "Note: The “Delete ⌫” key on Mac keyboard is named as “BackSpace ⌫” here in order to distinguish the real “Delete ⌦” key from full-sized desktop keyboards. If you want to use the real “Delete ⌦” key on a Mac keyboard with no numpad equipped, you have to press “Fn+⌫” instead.";
|
"Note: The “Delete ⌫” key on Mac keyboard is named as “BackSpace ⌫” here in order to distinguish the real “Delete ⌦” key from full-sized desktop keyboards. If you want to use the real “Delete ⌦” key on a Mac keyboard with no numpad equipped, you have to press “Fn+⌫” instead." = "Note: The “Delete ⌫” key on Mac keyboard is named as “BackSpace ⌫” here in order to distinguish the real “Delete ⌦” key from full-sized desktop keyboards. If you want to use the real “Delete ⌦” key on a Mac keyboard with no numpad equipped, you have to press “Fn+⌫” instead.";
|
||||||
"Only override the intonation of the previous reading if different" = "Only override the intonation of the previous reading if different";
|
"Only override the intonation of the previous reading if different" = "Only override the intonation of the previous reading if different";
|
||||||
|
"Only use this with known Chromium-based browsers" = "Only use this with known Chromium-based browsers";
|
||||||
"Output Settings:" = "Output Settings:";
|
"Output Settings:" = "Output Settings:";
|
||||||
"Override the previous reading's intonation with candidate-reset" = "Override the previous reading's intonation with candidate-reset";
|
"Override the previous reading's intonation with candidate-reset" = "Override the previous reading's intonation with candidate-reset";
|
||||||
"Phonetic Parser:" = "Phonetic Parser:";
|
"Phonetic Parser:" = "Phonetic Parser:";
|
||||||
|
@ -184,7 +193,7 @@
|
||||||
"Selection Keys:" = "Selection Keys:";
|
"Selection Keys:" = "Selection Keys:";
|
||||||
"Shift+BackSpace:" = "Shift+BackSpace:";
|
"Shift+BackSpace:" = "Shift+BackSpace:";
|
||||||
"Shift+Letter:" = "Shift+Letter:";
|
"Shift+Letter:" = "Shift+Letter:";
|
||||||
"Show Hanyu-Pinyin in the inline composition buffer & tooltip" = "Show Hanyu-Pinyin in the inline composition buffer & tooltip";
|
"Show Hanyu-Pinyin in the inline composition buffer" = "Show Hanyu-Pinyin in the inline composition buffer";
|
||||||
"Show page buttons in candidate window" = "Show page buttons in candidate window";
|
"Show page buttons in candidate window" = "Show page buttons in candidate window";
|
||||||
"Simplified Chinese" = "Simplified Chinese";
|
"Simplified Chinese" = "Simplified Chinese";
|
||||||
"Some client apps (like Chromium-cored browsers: MS Edge, Google Chrome, etc.) may duplicate Shift-key inputs due to their internal bugs, and their devs are less likely to fix their bugs of such. vChewing has its accommodation procedures enabled by default for known Chromium-cored browsers. Here you can customize how the accommodation should work." = "Some client apps (like Chromium-cored browsers: MS Edge, Google Chrome, etc.) may duplicate Shift-key inputs due to their internal bugs, and their devs are less likely to fix their bugs of such. vChewing has its accommodation procedures enabled by default for known Chromium-cored browsers. Here you can customize how the accommodation should work.";
|
"Some client apps (like Chromium-cored browsers: MS Edge, Google Chrome, etc.) may duplicate Shift-key inputs due to their internal bugs, and their devs are less likely to fix their bugs of such. vChewing has its accommodation procedures enabled by default for known Chromium-cored browsers. Here you can customize how the accommodation should work." = "Some client apps (like Chromium-cored browsers: MS Edge, Google Chrome, etc.) may duplicate Shift-key inputs due to their internal bugs, and their devs are less likely to fix their bugs of such. vChewing has its accommodation procedures enabled by default for known Chromium-cored browsers. Here you can customize how the accommodation should work.";
|
||||||
|
@ -206,7 +215,4 @@
|
||||||
"Use Shift key accommodation in all cases" = "Use Shift key accommodation in all cases";
|
"Use Shift key accommodation in all cases" = "Use Shift key accommodation in all cases";
|
||||||
"Vertical" = "Vertical";
|
"Vertical" = "Vertical";
|
||||||
"Warning: This page is for testing future features. \nFeatures listed here may not work as expected." = "Warning: This page is for testing future features. \nFeatures listed here may not work as expected.";
|
"Warning: This page is for testing future features. \nFeatures listed here may not work as expected." = "Warning: This page is for testing future features. \nFeatures listed here may not work as expected.";
|
||||||
"For example: When typing “章太炎” and you want to override the “太” with “泰”, and the raw operation index range [1,2) which bounds are cutting the current node “章太炎” in range [0,3). If having lack of the pre-consolidation process, this word will become something like “張泰言” after the candidate selection. Only if we enable this consolidation, this word will become “章泰炎” which is the expected result that the context is kept as-is." = "For example: When typing “章太炎” and you want to override the “太” with “泰”, and the raw operation index range [1,2) which bounds are cutting the current node “章太炎” in range [0,3). If having lack of the pre-consolidation process, this word will become something like “張泰言” after the candidate selection. Only if we enable this consolidation, this word will become “章泰炎” which is the expected result that the context is kept as-is.";
|
|
||||||
"Yale Pinyin with Numeral Intonation" = "Yale Pinyin with Numeral Intonation";
|
"Yale Pinyin with Numeral Intonation" = "Yale Pinyin with Numeral Intonation";
|
||||||
"Only use this with known Chromium-based browsers" = "Only use this with known Chromium-based browsers";
|
|
||||||
"Disable Shift key accomodation in all cases" = "Disable Shift key accomodation in all cases";
|
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
"vChewing" = "vChewing";
|
"vChewing" = "vChewing";
|
||||||
|
"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 downloaded is nil.";
|
||||||
|
"Plist downloaded cannot be parsed correctly." = "Plist downloaded cannot be parsed correctly.";
|
||||||
"vChewing crashed while handling previously loaded UOM observation data. These data files are cleaned now to ensure the usability." = "vChewing crashed while handling previously loaded UOM observation data. These data files are cleaned now to ensure the usability.";
|
"vChewing crashed while handling previously loaded UOM observation data. These data files are cleaned now to ensure the usability." = "vChewing crashed while handling previously loaded UOM observation data. These data files are cleaned now to ensure the usability.";
|
||||||
"About vChewing…" = "About vChewing…";
|
"About vChewing…" = "About vChewing…";
|
||||||
"vChewing Preferences…" = "vChewing Preferences…";
|
"vChewing Preferences…" = "vChewing Preferences…";
|
||||||
|
@ -17,7 +21,7 @@
|
||||||
"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";
|
||||||
"You're currently using vChewing %@ (%@), a new version %@ (%@) is now available. Do you want to visit vChewing's website to download the version?%@" = "You're currently using vChewing %@ (%@), a new version %@ (%@) is now available. Do you want to visit vChewing's website to download the version?%@";
|
"You're currently using vChewing %@ (%@), a new version %@ (%@) is now available. Do you want to visit vChewing's website to download the version?" = "You're currently using vChewing %@ (%@), a new version %@ (%@) is now available. Do you want to visit vChewing's website to download the version?";
|
||||||
"Force KangXi Writing" = "Force KangXi Writing";
|
"Force KangXi Writing" = "Force KangXi Writing";
|
||||||
"NotificationSwitchON" = "✔ ON";
|
"NotificationSwitchON" = "✔ ON";
|
||||||
"NotificationSwitchOFF" = "✘ OFF";
|
"NotificationSwitchOFF" = "✘ OFF";
|
||||||
|
@ -30,7 +34,7 @@
|
||||||
"\"%@\" length must ≥ 2 for a user phrase." = "\"%@\" length must ≥ 2 for a user phrase.";
|
"\"%@\" length must ≥ 2 for a user phrase." = "\"%@\" length must ≥ 2 for a user phrase.";
|
||||||
"\"%@\" length should ≤ %d for a user phrase." = "\"%@\" length should ≤ %d for a user phrase.";
|
"\"%@\" length should ≤ %d for a user phrase." = "\"%@\" length should ≤ %d for a user phrase.";
|
||||||
"\"%@\" selected. ENTER to add user phrase." = "\"%@\" selected. ENTER to add user phrase.";
|
"\"%@\" selected. ENTER to add user phrase." = "\"%@\" selected. ENTER to add user phrase.";
|
||||||
"\"%@\" already exists: ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude." = "\"%@\" already exists: ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude.";
|
"\"%@\" already exists:\n ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude." = "\"%@\" already exists:\n ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude.";
|
||||||
"Edit Phrase Replacement Table…" = "Edit Phrase Replacement Table…";
|
"Edit Phrase Replacement Table…" = "Edit Phrase Replacement Table…";
|
||||||
"Use Phrase Replacement" = "Use Phrase Replacement";
|
"Use Phrase Replacement" = "Use Phrase Replacement";
|
||||||
"Candidates keys cannot be empty." = "Candidates keys cannot be empty.";
|
"Candidates keys cannot be empty." = "Candidates keys cannot be empty.";
|
||||||
|
@ -96,11 +100,13 @@
|
||||||
// SwiftUI Preferences
|
// SwiftUI Preferences
|
||||||
"(Shift+)Space:" = "(Shift+)Space:";
|
"(Shift+)Space:" = "(Shift+)Space:";
|
||||||
"⚠︎ This feature in IMK Candidate Window defects. Please consult Apple Developer Relations\nand tell them the related Radar ID: #FB11300759." = "⚠︎ This feature in IMK Candidate Window defects. Please consult Apple Developer Relations\nand tell them the related Radar ID: #FB11300759.";
|
"⚠︎ This feature in IMK Candidate Window defects. Please consult Apple Developer Relations\nand tell them the related Radar ID: #FB11300759." = "⚠︎ This feature in IMK Candidate Window defects. Please consult Apple Developer Relations\nand tell them the related Radar ID: #FB11300759.";
|
||||||
|
"⚠︎ This feature is useful ONLY WHEN the font you are using doesn't support dynamic vertical punctuations. However, typed vertical punctuations will always shown as vertical punctuations EVEN IF your editor has changed the typing direction to horizontal." = "⚠︎ This feature is useful ONLY WHEN the font you are using doesn't support dynamic vertical punctuations. However, typed vertical punctuations will always shown as vertical punctuations EVEN IF your editor has changed the typing direction to horizontal.";
|
||||||
"Allow backspace-editing miscomposed readings" = "Allow backspace-editing miscomposed readings";
|
"Allow backspace-editing miscomposed readings" = "Allow backspace-editing miscomposed readings";
|
||||||
"Allow boosting / excluding a candidate of single kanji" = "Allow boosting / excluding a candidate of single kanji";
|
"Allow boosting / excluding a candidate of single kanji" = "Allow boosting / excluding a candidate of single kanji";
|
||||||
"Allow using Enter key to confirm associated candidate selection" = "Allow using Enter key to confirm associated candidate selection";
|
"Allow using Enter key to confirm associated candidate selection" = "Allow using Enter key to confirm associated candidate selection";
|
||||||
"Also toggle alphanumerical mode with Left-Shift" = "Also toggle alphanumerical mode with Left-Shift";
|
"Also toggle alphanumerical mode with Left-Shift" = "Also toggle alphanumerical mode with Left-Shift";
|
||||||
"Always drop the previous reading" = "Always drop the previous reading";
|
"Always drop the previous reading" = "Always drop the previous reading";
|
||||||
|
"Always show tooltip texts horizontally" = "Always show tooltip texts horizontally";
|
||||||
"Always type intonations to the inline composition buffer" = "Always type intonations to the inline composition buffer";
|
"Always type intonations to the inline composition buffer" = "Always type intonations to the inline composition buffer";
|
||||||
"Always use fixed listing order in candidate window" = "Always use fixed listing order in candidate window";
|
"Always use fixed listing order in candidate window" = "Always use fixed listing order in candidate window";
|
||||||
"An accommodation for elder computer users." = "An accommodation for elder computer users.";
|
"An accommodation for elder computer users." = "An accommodation for elder computer users.";
|
||||||
|
@ -141,6 +147,7 @@
|
||||||
"Dictionary" = "Dictionary";
|
"Dictionary" = "Dictionary";
|
||||||
"Directly commit lowercased letters" = "Directly commit lowercased letters";
|
"Directly commit lowercased letters" = "Directly commit lowercased letters";
|
||||||
"Directly commit uppercased letters" = "Directly commit uppercased letters";
|
"Directly commit uppercased letters" = "Directly commit uppercased letters";
|
||||||
|
"Disable Shift key accomodation in all cases" = "Disable Shift key accomodation in all cases";
|
||||||
"Disassemble the previous reading, dropping its intonation" = "Disassemble the previous reading, dropping its intonation";
|
"Disassemble the previous reading, dropping its intonation" = "Disassemble the previous reading, dropping its intonation";
|
||||||
"Disassembling process does not work with non-phonetic reading keys." = "Disassembling process does not work with non-phonetic reading keys.";
|
"Disassembling process does not work with non-phonetic reading keys." = "Disassembling process does not work with non-phonetic reading keys.";
|
||||||
"Emulating select-candidate-per-character mode" = "Emulating select-candidate-per-character mode";
|
"Emulating select-candidate-per-character mode" = "Emulating select-candidate-per-character mode";
|
||||||
|
@ -155,10 +162,10 @@
|
||||||
"Follow OS settings" = "Follow OS settings";
|
"Follow OS settings" = "Follow OS settings";
|
||||||
"for cycling candidates" = "for cycling candidates";
|
"for cycling candidates" = "for cycling candidates";
|
||||||
"for cycling pages" = "for cycling pages";
|
"for cycling pages" = "for cycling pages";
|
||||||
|
"For example: When typing “章太炎” and you want to override the “太” with “泰”, and the raw operation index range [1,2) which bounds are cutting the current node “章太炎” in range [0,3). If having lack of the pre-consolidation process, this word will become something like “張泰言” after the candidate selection. Only if we enable this consolidation, this word will become “章泰炎” which is the expected result that the context is kept as-is." = "For example: When typing “章太炎” and you want to override the “太” with “泰”, and the raw operation index range [1,2) which bounds are cutting the current node “章太炎” in range [0,3). If having lack of the pre-consolidation process, this word will become something like “張泰言” after the candidate selection. Only if we enable this consolidation, this word will become “章泰炎” which is the expected result that the context is kept as-is.";
|
||||||
"General" = "General";
|
"General" = "General";
|
||||||
"Hanyu Pinyin with Numeral Intonation" = "Hanyu Pinyin with Numeral Intonation";
|
"Hanyu Pinyin with Numeral Intonation" = "Hanyu Pinyin with Numeral Intonation";
|
||||||
"Harden vertical punctuations during vertical typing (not recommended)" = "Harden vertical punctuations during vertical typing (not recommended)";
|
"Harden vertical punctuations during vertical typing (not recommended)" = "Harden vertical punctuations during vertical typing (not recommended)";
|
||||||
"⚠︎ This feature is useful ONLY WHEN the font you are using doesn't support dynamic vertical punctuations. However, typed vertical punctuations will always shown as vertical punctuations EVEN IF your editor has changed the typing direction to horizontal." = "⚠︎ This feature is useful ONLY WHEN the font you are using doesn't support dynamic vertical punctuations. However, typed vertical punctuations will always shown as vertical punctuations EVEN IF your editor has changed the typing direction to horizontal.";
|
|
||||||
"Horizontal" = "Horizontal";
|
"Horizontal" = "Horizontal";
|
||||||
"Hsu" = "Hsu";
|
"Hsu" = "Hsu";
|
||||||
"Hualuo Pinyin with Numeral Intonation" = "Hualuo Pinyin with Numeral Intonation";
|
"Hualuo Pinyin with Numeral Intonation" = "Hualuo Pinyin with Numeral Intonation";
|
||||||
|
@ -167,6 +174,7 @@
|
||||||
"in front of the phrase (like macOS built-in Zhuyin IME)" = "in front of the phrase (like macOS built-in Zhuyin IME)";
|
"in front of the phrase (like macOS built-in Zhuyin IME)" = "in front of the phrase (like macOS built-in Zhuyin IME)";
|
||||||
"Intonation Key:" = "Intonation Key:";
|
"Intonation Key:" = "Intonation Key:";
|
||||||
"Japanese" = "Japanese";
|
"Japanese" = "Japanese";
|
||||||
|
"Key names in tooltip will be shown as symbols when the tooltip is vertical. However, this option will be ignored since tooltip will always be horizontal if the UI language is English." = "Key names in tooltip will be shown as symbols when the tooltip is vertical. However, this option will be ignored since tooltip will always be horizontal if the UI language is English.";
|
||||||
"Keyboard Shortcuts:" = "Keyboard Shortcuts:";
|
"Keyboard Shortcuts:" = "Keyboard Shortcuts:";
|
||||||
"Keyboard" = "Keyboard";
|
"Keyboard" = "Keyboard";
|
||||||
"Misc Settings:" = "Misc Settings:";
|
"Misc Settings:" = "Misc Settings:";
|
||||||
|
@ -174,6 +182,7 @@
|
||||||
"Non-QWERTY alphanumerical keyboard layouts are for Pinyin parser only." = "Non-QWERTY alphanumerical keyboard layouts are for Pinyin parser only.";
|
"Non-QWERTY alphanumerical keyboard layouts are for Pinyin parser only." = "Non-QWERTY alphanumerical keyboard layouts are for Pinyin parser only.";
|
||||||
"Note: The “Delete ⌫” key on Mac keyboard is named as “BackSpace ⌫” here in order to distinguish the real “Delete ⌦” key from full-sized desktop keyboards. If you want to use the real “Delete ⌦” key on a Mac keyboard with no numpad equipped, you have to press “Fn+⌫” instead." = "Note: The “Delete ⌫” key on Mac keyboard is named as “BackSpace ⌫” here in order to distinguish the real “Delete ⌦” key from full-sized desktop keyboards. If you want to use the real “Delete ⌦” key on a Mac keyboard with no numpad equipped, you have to press “Fn+⌫” instead.";
|
"Note: The “Delete ⌫” key on Mac keyboard is named as “BackSpace ⌫” here in order to distinguish the real “Delete ⌦” key from full-sized desktop keyboards. If you want to use the real “Delete ⌦” key on a Mac keyboard with no numpad equipped, you have to press “Fn+⌫” instead." = "Note: The “Delete ⌫” key on Mac keyboard is named as “BackSpace ⌫” here in order to distinguish the real “Delete ⌦” key from full-sized desktop keyboards. If you want to use the real “Delete ⌦” key on a Mac keyboard with no numpad equipped, you have to press “Fn+⌫” instead.";
|
||||||
"Only override the intonation of the previous reading if different" = "Only override the intonation of the previous reading if different";
|
"Only override the intonation of the previous reading if different" = "Only override the intonation of the previous reading if different";
|
||||||
|
"Only use this with known Chromium-based browsers" = "Only use this with known Chromium-based browsers";
|
||||||
"Output Settings:" = "Output Settings:";
|
"Output Settings:" = "Output Settings:";
|
||||||
"Override the previous reading's intonation with candidate-reset" = "Override the previous reading's intonation with candidate-reset";
|
"Override the previous reading's intonation with candidate-reset" = "Override the previous reading's intonation with candidate-reset";
|
||||||
"Phonetic Parser:" = "Phonetic Parser:";
|
"Phonetic Parser:" = "Phonetic Parser:";
|
||||||
|
@ -184,7 +193,7 @@
|
||||||
"Selection Keys:" = "Selection Keys:";
|
"Selection Keys:" = "Selection Keys:";
|
||||||
"Shift+BackSpace:" = "Shift+BackSpace:";
|
"Shift+BackSpace:" = "Shift+BackSpace:";
|
||||||
"Shift+Letter:" = "Shift+Letter:";
|
"Shift+Letter:" = "Shift+Letter:";
|
||||||
"Show Hanyu-Pinyin in the inline composition buffer & tooltip" = "Show Hanyu-Pinyin in the inline composition buffer & tooltip";
|
"Show Hanyu-Pinyin in the inline composition buffer" = "Show Hanyu-Pinyin in the inline composition buffer";
|
||||||
"Show page buttons in candidate window" = "Show page buttons in candidate window";
|
"Show page buttons in candidate window" = "Show page buttons in candidate window";
|
||||||
"Simplified Chinese" = "Simplified Chinese";
|
"Simplified Chinese" = "Simplified Chinese";
|
||||||
"Some client apps (like Chromium-cored browsers: MS Edge, Google Chrome, etc.) may duplicate Shift-key inputs due to their internal bugs, and their devs are less likely to fix their bugs of such. vChewing has its accommodation procedures enabled by default for known Chromium-cored browsers. Here you can customize how the accommodation should work." = "Some client apps (like Chromium-cored browsers: MS Edge, Google Chrome, etc.) may duplicate Shift-key inputs due to their internal bugs, and their devs are less likely to fix their bugs of such. vChewing has its accommodation procedures enabled by default for known Chromium-cored browsers. Here you can customize how the accommodation should work.";
|
"Some client apps (like Chromium-cored browsers: MS Edge, Google Chrome, etc.) may duplicate Shift-key inputs due to their internal bugs, and their devs are less likely to fix their bugs of such. vChewing has its accommodation procedures enabled by default for known Chromium-cored browsers. Here you can customize how the accommodation should work." = "Some client apps (like Chromium-cored browsers: MS Edge, Google Chrome, etc.) may duplicate Shift-key inputs due to their internal bugs, and their devs are less likely to fix their bugs of such. vChewing has its accommodation procedures enabled by default for known Chromium-cored browsers. Here you can customize how the accommodation should work.";
|
||||||
|
@ -206,7 +215,4 @@
|
||||||
"Use Shift key accommodation in all cases" = "Use Shift key accommodation in all cases";
|
"Use Shift key accommodation in all cases" = "Use Shift key accommodation in all cases";
|
||||||
"Vertical" = "Vertical";
|
"Vertical" = "Vertical";
|
||||||
"Warning: This page is for testing future features. \nFeatures listed here may not work as expected." = "Warning: This page is for testing future features. \nFeatures listed here may not work as expected.";
|
"Warning: This page is for testing future features. \nFeatures listed here may not work as expected." = "Warning: This page is for testing future features. \nFeatures listed here may not work as expected.";
|
||||||
"For example: When typing “章太炎” and you want to override the “太” with “泰”, and the raw operation index range [1,2) which bounds are cutting the current node “章太炎” in range [0,3). If having lack of the pre-consolidation process, this word will become something like “張泰言” after the candidate selection. Only if we enable this consolidation, this word will become “章泰炎” which is the expected result that the context is kept as-is." = "For example: When typing “章太炎” and you want to override the “太” with “泰”, and the raw operation index range [1,2) which bounds are cutting the current node “章太炎” in range [0,3). If having lack of the pre-consolidation process, this word will become something like “張泰言” after the candidate selection. Only if we enable this consolidation, this word will become “章泰炎” which is the expected result that the context is kept as-is.";
|
|
||||||
"Yale Pinyin with Numeral Intonation" = "Yale Pinyin with Numeral Intonation";
|
"Yale Pinyin with Numeral Intonation" = "Yale Pinyin with Numeral Intonation";
|
||||||
"Only use this with known Chromium-based browsers" = "Only use this with known Chromium-based browsers";
|
|
||||||
"Disable Shift key accomodation in all cases" = "Disable Shift key accomodation in all cases";
|
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
"vChewing" = "威注音入力アプリ";
|
"vChewing" = "威注音入力アプリ";
|
||||||
|
"Update Check Completed" = "新バージョンチェック完了";
|
||||||
|
"You are already using the latest version." = "現在稼働中のは最新バージョンである。";
|
||||||
|
"Plist downloaded is nil." = "受けた新バージョンお知らせ情報データは Plist ではないため、失敗とみなす。";
|
||||||
|
"Plist downloaded cannot be parsed correctly." = "受けた新バージョンお知らせ情報 Plist データは解読できないため、失敗とみなす。";
|
||||||
"vChewing crashed while handling previously loaded UOM observation data. These data files are cleaned now to ensure the usability." = "臨時記憶モジュールの観測行為による威注音入力アプリの意外中止は発生した。威注音入力アプリの無事利用のために、既存臨時記憶データは全てお消しした。";
|
"vChewing crashed while handling previously loaded UOM observation data. These data files are cleaned now to ensure the usability." = "臨時記憶モジュールの観測行為による威注音入力アプリの意外中止は発生した。威注音入力アプリの無事利用のために、既存臨時記憶データは全てお消しした。";
|
||||||
"About vChewing…" = "威注音について…";
|
"About vChewing…" = "威注音について…";
|
||||||
"vChewing Preferences…" = "入力機能設定…";
|
"vChewing Preferences…" = "入力機能設定…";
|
||||||
|
@ -17,7 +21,7 @@
|
||||||
"New Version Available" = "最新版利用可能";
|
"New Version Available" = "最新版利用可能";
|
||||||
"Not Now" = "後で";
|
"Not Now" = "後で";
|
||||||
"Visit Website" = "公式サイト";
|
"Visit Website" = "公式サイト";
|
||||||
"You're currently using vChewing %@ (%@), a new version %@ (%@) is now available. Do you want to visit vChewing's website to download the version?%@" = "今のご使用していた威注音入力アプリのバージョンは「%1$@ (%2$@)」であり、ネットでもっと新しいバージョン「%3$@ (%4$@)」の下載せはできるらしい。公式サイトへバージョン「%5$@」を下載せますか?";
|
"You're currently using vChewing %@ (%@), a new version %@ (%@) is now available. Do you want to visit vChewing's website to download the version?" = "今のご使用していた威注音入力アプリのバージョンは「%1$@ (%2$@)」であり、ネットでもっと新しいバージョン「%3$@ (%4$@)」の下載せはできるらしい。お下載せしますか?";
|
||||||
"Force KangXi Writing" = "康熙文字変換モード";
|
"Force KangXi Writing" = "康熙文字変換モード";
|
||||||
"NotificationSwitchON" = "✔ 機能起動";
|
"NotificationSwitchON" = "✔ 機能起動";
|
||||||
"NotificationSwitchOFF" = "✘ 機能停止";
|
"NotificationSwitchOFF" = "✘ 機能停止";
|
||||||
|
@ -30,7 +34,7 @@
|
||||||
"\"%@\" length must ≥ 2 for a user phrase." = "「%@」もう1つ文字のお選びを。";
|
"\"%@\" length must ≥ 2 for a user phrase." = "「%@」もう1つ文字のお選びを。";
|
||||||
"\"%@\" length should ≤ %d for a user phrase." = "「%@」文字数過剰で登録不可、%d 文字以内にして下さい。";
|
"\"%@\" length should ≤ %d for a user phrase." = "「%@」文字数過剰で登録不可、%d 文字以内にして下さい。";
|
||||||
"\"%@\" selected. ENTER to add user phrase." = "「%@」を ENTER で辞書に登録。";
|
"\"%@\" selected. ENTER to add user phrase." = "「%@」を ENTER で辞書に登録。";
|
||||||
"\"%@\" already exists: ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude." = "「%@」は既存語彙:ENTER で最優先にし、SHIFT+COMMAND+ENTER で優先順位を下げる;\n BackSpace 或いは Delete で排除。";
|
"\"%@\" already exists:\n ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude." = "「%@」は既存語彙:\n ENTER で最優先にし、SHIFT+COMMAND+ENTER で優先順位を下げる;\n BackSpace 或いは Delete で排除。";
|
||||||
"Edit Phrase Replacement Table…" = "言葉置換表を編集…";
|
"Edit Phrase Replacement Table…" = "言葉置換表を編集…";
|
||||||
"Use Phrase Replacement" = "言葉置換機能";
|
"Use Phrase Replacement" = "言葉置換機能";
|
||||||
"Candidates keys cannot be empty." = "言選り用キー陣列に何かキーをご登録ください。";
|
"Candidates keys cannot be empty." = "言選り用キー陣列に何かキーをご登録ください。";
|
||||||
|
@ -96,11 +100,13 @@
|
||||||
// SwiftUI Preferences
|
// SwiftUI Preferences
|
||||||
"(Shift+)Space:" = "(Shift+)Space:";
|
"(Shift+)Space:" = "(Shift+)Space:";
|
||||||
"⚠︎ This feature in IMK Candidate Window defects. Please consult Apple Developer Relations\nand tell them the related Radar ID: #FB11300759." = "⚠︎ この機能は IMK 候補陳列ウィンドウにサポートされておりません。\nApple Developer Relations に案件番号 #FB11300759 を教えながらクレームしてください。";
|
"⚠︎ This feature in IMK Candidate Window defects. Please consult Apple Developer Relations\nand tell them the related Radar ID: #FB11300759." = "⚠︎ この機能は IMK 候補陳列ウィンドウにサポートされておりません。\nApple Developer Relations に案件番号 #FB11300759 を教えながらクレームしてください。";
|
||||||
|
"⚠︎ This feature is useful ONLY WHEN the font you are using doesn't support dynamic vertical punctuations. However, typed vertical punctuations will always shown as vertical punctuations EVEN IF your editor has changed the typing direction to horizontal." = "⚠︎ 該当の組版用フォントには縦書き(引用符・括弧)変換機能が備えていない限り、この機能を使う甲斐がある。一旦使うと、入力した全ての引用符・括弧は永遠的に縦書きの様式になる。例え入力を受けているアプリ(例えばワープロソフとなど)の書写方向は横書きと変えたとしても、これらの入力済みの引用符・括弧は全て縦書きの見た目であり、削除してから入力し直す必要になる。";
|
||||||
"Allow backspace-editing miscomposed readings" = "効かぬ音読みを BackSpace で再編集";
|
"Allow backspace-editing miscomposed readings" = "効かぬ音読みを BackSpace で再編集";
|
||||||
"Allow boosting / excluding a candidate of single kanji" = "即排除/即最優先にできる候補の文字数の最低限は1字とする";
|
"Allow boosting / excluding a candidate of single kanji" = "即排除/即最優先にできる候補の文字数の最低限は1字とする";
|
||||||
"Allow using Enter key to confirm associated candidate selection" = "Enter キーを連想語彙候補の確認のために使う";
|
"Allow using Enter key to confirm associated candidate selection" = "Enter キーを連想語彙候補の確認のために使う";
|
||||||
"Also toggle alphanumerical mode with Left-Shift" = "左側の Shift キーでも英数入力モードの切り替え";
|
"Also toggle alphanumerical mode with Left-Shift" = "左側の Shift キーでも英数入力モードの切り替え";
|
||||||
"Always drop the previous reading" = "カーソルの後部の音読みを常に削除する";
|
"Always drop the previous reading" = "カーソルの後部の音読みを常に削除する";
|
||||||
|
"Always show tooltip texts horizontally" = "ヒントを常に横書きにする";
|
||||||
"Always type intonations to the inline composition buffer" = "常に入力緩衝列に音調を入力する";
|
"Always type intonations to the inline composition buffer" = "常に入力緩衝列に音調を入力する";
|
||||||
"Always use fixed listing order in candidate window" = "候補文字を固定順番で陳列する";
|
"Always use fixed listing order in candidate window" = "候補文字を固定順番で陳列する";
|
||||||
"An accommodation for elder computer users." = "年配なるユーザーのために提供した機能である。";
|
"An accommodation for elder computer users." = "年配なるユーザーのために提供した機能である。";
|
||||||
|
@ -141,6 +147,7 @@
|
||||||
"Dictionary" = "辞書設定";
|
"Dictionary" = "辞書設定";
|
||||||
"Directly commit lowercased letters" = "ローマ字(小文字)を直接出力";
|
"Directly commit lowercased letters" = "ローマ字(小文字)を直接出力";
|
||||||
"Directly commit uppercased letters" = "ローマ字(大文字)を直接出力";
|
"Directly commit uppercased letters" = "ローマ字(大文字)を直接出力";
|
||||||
|
"Disable Shift key accomodation in all cases" = "いずれの客体アプリにも Shift キーの互換性措置を禁ず";
|
||||||
"Disassemble the previous reading, dropping its intonation" = "カーソルの後部の音読みを解き、その音調を除く";
|
"Disassemble the previous reading, dropping its intonation" = "カーソルの後部の音読みを解き、その音調を除く";
|
||||||
"Disassembling process does not work with non-phonetic reading keys." = "実の意味の音読みだけを解くことができる。";
|
"Disassembling process does not work with non-phonetic reading keys." = "実の意味の音読みだけを解くことができる。";
|
||||||
"Emulating select-candidate-per-character mode" = "漢字1つづつ全候補選択入力モード";
|
"Emulating select-candidate-per-character mode" = "漢字1つづつ全候補選択入力モード";
|
||||||
|
@ -155,10 +162,10 @@
|
||||||
"Follow OS settings" = "システム設定に準ず";
|
"Follow OS settings" = "システム設定に準ず";
|
||||||
"for cycling candidates" = "候補文字そのもの";
|
"for cycling candidates" = "候補文字そのもの";
|
||||||
"for cycling pages" = "候補陳列ページ";
|
"for cycling pages" = "候補陳列ページ";
|
||||||
|
"For example: When typing “章太炎” and you want to override the “太” with “泰”, and the raw operation index range [1,2) which bounds are cutting the current node “章太炎” in range [0,3). If having lack of the pre-consolidation process, this word will become something like “張泰言” after the candidate selection. Only if we enable this consolidation, this word will become “章泰炎” which is the expected result that the context is kept as-is." = "例えば、入力緩衝列には「章太炎」という節点があり、その範囲は [0,3) である。もし、「太」を「泰」にしたいのなら、今回の作業範囲は [1,2) で、「章太炎」の範囲と重ねてしまう。この場合、もし、事前強固措置がなければ、今回の作業でこの単語は「張泰言」のような望ましくない変換結果になってしまう。事前強固措置があるからこそ、「章泰炎」のような正確な作業結果の保証である。";
|
||||||
"General" = "全般設定";
|
"General" = "全般設定";
|
||||||
"Hanyu Pinyin with Numeral Intonation" = "漢語弁音 (ローマ字+数字音調)";
|
"Hanyu Pinyin with Numeral Intonation" = "漢語弁音 (ローマ字+数字音調)";
|
||||||
"Harden vertical punctuations during vertical typing (not recommended)" = "縦書きの時に、引用符・括弧などを強制的に縦書き文字と変換する(不推奨)";
|
"Harden vertical punctuations during vertical typing (not recommended)" = "縦書きの時に、引用符・括弧などを強制的に縦書き文字と変換する(不推奨)";
|
||||||
"⚠︎ This feature is useful ONLY WHEN the font you are using doesn't support dynamic vertical punctuations. However, typed vertical punctuations will always shown as vertical punctuations EVEN IF your editor has changed the typing direction to horizontal." = "⚠︎ 該当の組版用フォントには縦書き(引用符・括弧)変換機能が備えていない限り、この機能を使う甲斐がある。一旦使うと、入力した全ての引用符・括弧は永遠的に縦書きの様式になる。例え入力を受けているアプリ(例えばワープロソフとなど)の書写方向は横書きと変えたとしても、これらの入力済みの引用符・括弧は全て縦書きの見た目であり、削除してから入力し直す必要になる。";
|
|
||||||
"Horizontal" = "横型陳列";
|
"Horizontal" = "横型陳列";
|
||||||
"Hsu" = "許氏国音自然配列";
|
"Hsu" = "許氏国音自然配列";
|
||||||
"Hualuo Pinyin with Numeral Intonation" = "中華ローマ弁音 (ローマ字+数字音調)";
|
"Hualuo Pinyin with Numeral Intonation" = "中華ローマ弁音 (ローマ字+数字音調)";
|
||||||
|
@ -167,6 +174,7 @@
|
||||||
"in front of the phrase (like macOS built-in Zhuyin IME)" = "単語の前で // macOS 内蔵注音入力のやり方";
|
"in front of the phrase (like macOS built-in Zhuyin IME)" = "単語の前で // macOS 内蔵注音入力のやり方";
|
||||||
"Intonation Key:" = "音調キー:";
|
"Intonation Key:" = "音調キー:";
|
||||||
"Japanese" = "和語";
|
"Japanese" = "和語";
|
||||||
|
"Key names in tooltip will be shown as symbols when the tooltip is vertical. However, this option will be ignored since tooltip will always be horizontal if the UI language is English." = "縦書き入力の場合、ヒントにはキーの名前は常に符号で表示する。";
|
||||||
"Keyboard Shortcuts:" = "ショートカット:";
|
"Keyboard Shortcuts:" = "ショートカット:";
|
||||||
"Keyboard" = "配列設定";
|
"Keyboard" = "配列設定";
|
||||||
"Misc Settings:" = "他の設定:";
|
"Misc Settings:" = "他の設定:";
|
||||||
|
@ -174,6 +182,7 @@
|
||||||
"Non-QWERTY alphanumerical keyboard layouts are for Pinyin parser only." = "QWERTY 以外の英数キーボードは弁音以外の配列に不適用。";
|
"Non-QWERTY alphanumerical keyboard layouts are for Pinyin parser only." = "QWERTY 以外の英数キーボードは弁音以外の配列に不適用。";
|
||||||
"Note: The “Delete ⌫” key on Mac keyboard is named as “BackSpace ⌫” here in order to distinguish the real “Delete ⌦” key from full-sized desktop keyboards. If you want to use the real “Delete ⌦” key on a Mac keyboard with no numpad equipped, you have to press “Fn+⌫” instead." = "ご注意:Mac キーボードの「Delete ⌫」キーはここで「BackSpace ⌫」と呼ばれ、それはパソコンの常識としての本物の「Delete ⌦」と区別するためである。もし、テンキーの付いていない Mac キーボードで本物の「Delete ⌦」を使いたければ、代わりに「Fn+⌫」をご使用ください。";
|
"Note: The “Delete ⌫” key on Mac keyboard is named as “BackSpace ⌫” here in order to distinguish the real “Delete ⌦” key from full-sized desktop keyboards. If you want to use the real “Delete ⌦” key on a Mac keyboard with no numpad equipped, you have to press “Fn+⌫” instead." = "ご注意:Mac キーボードの「Delete ⌫」キーはここで「BackSpace ⌫」と呼ばれ、それはパソコンの常識としての本物の「Delete ⌦」と区別するためである。もし、テンキーの付いていない Mac キーボードで本物の「Delete ⌦」を使いたければ、代わりに「Fn+⌫」をご使用ください。";
|
||||||
"Only override the intonation of the previous reading if different" = "カーソルの後部の音読みの異なる音調だけを上書きする";
|
"Only override the intonation of the previous reading if different" = "カーソルの後部の音読みの異なる音調だけを上書きする";
|
||||||
|
"Only use this with known Chromium-based browsers" = "有名なる Chromium 系ブラウザーだけに、この装置を起用";
|
||||||
"Output Settings:" = "出力設定:";
|
"Output Settings:" = "出力設定:";
|
||||||
"Override the previous reading's intonation with candidate-reset" = "カーソルの後部の音読みの音調を上書きし、候補選択状態を戻す";
|
"Override the previous reading's intonation with candidate-reset" = "カーソルの後部の音読みの音調を上書きし、候補選択状態を戻す";
|
||||||
"Phonetic Parser:" = "注音配列:";
|
"Phonetic Parser:" = "注音配列:";
|
||||||
|
@ -184,7 +193,7 @@
|
||||||
"Selection Keys:" = "言選り用キー:";
|
"Selection Keys:" = "言選り用キー:";
|
||||||
"Shift+BackSpace:" = "Shift+BackSpace:";
|
"Shift+BackSpace:" = "Shift+BackSpace:";
|
||||||
"Shift+Letter:" = "Shift+文字キー:";
|
"Shift+Letter:" = "Shift+文字キー:";
|
||||||
"Show Hanyu-Pinyin in the inline composition buffer & tooltip" = "弁音合併入力(入力緩衝列とヒントで音読みを漢語弁音に)";
|
"Show Hanyu-Pinyin in the inline composition buffer" = "弁音合併入力(入力緩衝列で音読みを漢語弁音に)";
|
||||||
"Show page buttons in candidate window" = "入力候補陳列の側にページボタンを表示";
|
"Show page buttons in candidate window" = "入力候補陳列の側にページボタンを表示";
|
||||||
"Simplified Chinese" = "簡体中国語";
|
"Simplified Chinese" = "簡体中国語";
|
||||||
"Some client apps (like Chromium-cored browsers: MS Edge, Google Chrome, etc.) may duplicate Shift-key inputs due to their internal bugs, and their devs are less likely to fix their bugs of such. vChewing has its accommodation procedures enabled by default for known Chromium-cored browsers. Here you can customize how the accommodation should work." = "いくつかのアプリ(例えば MS Edge や Google Chrome などのような Chromium 系ブラウザー)には「Shift キーの入力イベントを複数化してしまう」という支障があり、そしてアプリそれぞれの開発元に修復される可能性はほぼゼロだと言える。威注音入力アプリは対策用の特殊措置を普段に起用している。ご自分の必要によって設定してください。";
|
"Some client apps (like Chromium-cored browsers: MS Edge, Google Chrome, etc.) may duplicate Shift-key inputs due to their internal bugs, and their devs are less likely to fix their bugs of such. vChewing has its accommodation procedures enabled by default for known Chromium-cored browsers. Here you can customize how the accommodation should work." = "いくつかのアプリ(例えば MS Edge や Google Chrome などのような Chromium 系ブラウザー)には「Shift キーの入力イベントを複数化してしまう」という支障があり、そしてアプリそれぞれの開発元に修復される可能性はほぼゼロだと言える。威注音入力アプリは対策用の特殊措置を普段に起用している。ご自分の必要によって設定してください。";
|
||||||
|
@ -206,7 +215,4 @@
|
||||||
"Use Shift key accommodation in all cases" = "いずれの客体アプリにも Shift キーの互換性措置を起用";
|
"Use Shift key accommodation in all cases" = "いずれの客体アプリにも Shift キーの互換性措置を起用";
|
||||||
"Vertical" = "縦型陳列";
|
"Vertical" = "縦型陳列";
|
||||||
"Warning: This page is for testing future features. \nFeatures listed here may not work as expected." = "警告:これからの新機能テストのために作ったページですから、\nここで陳列されている諸機能は予想通り動けるだと思わないでください。";
|
"Warning: This page is for testing future features. \nFeatures listed here may not work as expected." = "警告:これからの新機能テストのために作ったページですから、\nここで陳列されている諸機能は予想通り動けるだと思わないでください。";
|
||||||
"For example: When typing “章太炎” and you want to override the “太” with “泰”, and the raw operation index range [1,2) which bounds are cutting the current node “章太炎” in range [0,3). If having lack of the pre-consolidation process, this word will become something like “張泰言” after the candidate selection. Only if we enable this consolidation, this word will become “章泰炎” which is the expected result that the context is kept as-is." = "例えば、入力緩衝列には「章太炎」という節点があり、その範囲は [0,3) である。もし、「太」を「泰」にしたいのなら、今回の作業範囲は [1,2) で、「章太炎」の範囲と重ねてしまう。この場合、もし、事前強固措置がなければ、今回の作業でこの単語は「張泰言」のような望ましくない変換結果になってしまう。事前強固措置があるからこそ、「章泰炎」のような正確な作業結果の保証である。";
|
|
||||||
"Yale Pinyin with Numeral Intonation" = "イェール弁音 (ローマ字+数字音調)";
|
"Yale Pinyin with Numeral Intonation" = "イェール弁音 (ローマ字+数字音調)";
|
||||||
"Only use this with known Chromium-based browsers" = "有名なる Chromium 系ブラウザーだけに、この装置を起用";
|
|
||||||
"Disable Shift key accomodation in all cases" = "いずれの客体アプリにも Shift キーの互換性措置を禁ず";
|
|
||||||
|
|
|
@ -86,7 +86,7 @@
|
||||||
<div><strong>⌫</strong></div>
|
<div><strong>⌫</strong></div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div>Bksp (Backspace. Apple に "Delete" と呼ばれていますが…)</div>
|
<div>Bksp (BackSpace. Apple に "Delete" と呼ばれていますが…)</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
"vChewing" = "威注音输入法";
|
"vChewing" = "威注音输入法";
|
||||||
|
"Update Check Completed" = "更新检查完毕";
|
||||||
|
"You are already using the latest version." = "您正在使用目前最新的发行版。";
|
||||||
|
"Plist downloaded is nil." = "下载来的更新资讯并非 Plist 档案。";
|
||||||
|
"Plist downloaded cannot be parsed correctly." = "下载来的更新资讯 Plist 档案无法正常解析。";
|
||||||
"vChewing crashed while handling previously loaded UOM observation data. These data files are cleaned now to ensure the usability." = "威注音输入法的使用者半衰记忆模组在观测时崩溃,相关半衰记忆资料档案内容已全部清空。";
|
"vChewing crashed while handling previously loaded UOM observation data. These data files are cleaned now to ensure the usability." = "威注音输入法的使用者半衰记忆模组在观测时崩溃,相关半衰记忆资料档案内容已全部清空。";
|
||||||
"About vChewing…" = "关于威注音…";
|
"About vChewing…" = "关于威注音…";
|
||||||
"vChewing Preferences…" = "威注音偏好设定…";
|
"vChewing Preferences…" = "威注音偏好设定…";
|
||||||
|
@ -17,7 +21,7 @@
|
||||||
"New Version Available" = "有新版可下载";
|
"New Version Available" = "有新版可下载";
|
||||||
"Not Now" = "以后再说";
|
"Not Now" = "以后再说";
|
||||||
"Visit Website" = "前往网站";
|
"Visit Website" = "前往网站";
|
||||||
"You're currently using vChewing %@ (%@), a new version %@ (%@) is now available. Do you want to visit vChewing's website to download the version?%@" = "目前使用的威注音官方版本是 %1$@ (%2$@),网路上有更新版本 %3$@ (%4$@) 可供下载。是否要前往威注音网站下载新版来安装?%5$@";
|
"You're currently using vChewing %@ (%@), a new version %@ (%@) is now available. Do you want to visit vChewing's website to download the version?" = "目前使用的威注音官方版本是 %1$@ (%2$@),网路上有更新版本 %3$@ (%4$@) 可供下载。是否要前往威注音网站下载新版来安装?";
|
||||||
"Force KangXi Writing" = "康熙正体字模式";
|
"Force KangXi Writing" = "康熙正体字模式";
|
||||||
"NotificationSwitchON" = "✔ 已启用";
|
"NotificationSwitchON" = "✔ 已启用";
|
||||||
"NotificationSwitchOFF" = "✘ 已停用";
|
"NotificationSwitchOFF" = "✘ 已停用";
|
||||||
|
@ -30,7 +34,7 @@
|
||||||
"\"%@\" length must ≥ 2 for a user phrase." = "「%@」字数不足以自订语汇。";
|
"\"%@\" length must ≥ 2 for a user phrase." = "「%@」字数不足以自订语汇。";
|
||||||
"\"%@\" length should ≤ %d for a user phrase." = "「%@」字数超过 %d、无法自订。";
|
"\"%@\" length should ≤ %d for a user phrase." = "「%@」字数超过 %d、无法自订。";
|
||||||
"\"%@\" selected. ENTER to add user phrase." = "「%@」敲 Enter 添入自订语汇。";
|
"\"%@\" selected. ENTER to add user phrase." = "「%@」敲 Enter 添入自订语汇。";
|
||||||
"\"%@\" already exists: ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude." = "「%@」已存在:敲 Enter 以升权、敲 Shift+Command+Enter 以降权;\n 敲 BackSpace 或 Delete 以排除。";
|
"\"%@\" already exists:\n ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude." = "「%@」已存在:\n 敲 Enter 以升权、敲 Shift+Command+Enter 以降权;\n 敲 BackSpace 或 Delete 以排除。";
|
||||||
"Edit Phrase Replacement Table…" = "编辑语汇置换表…";
|
"Edit Phrase Replacement Table…" = "编辑语汇置换表…";
|
||||||
"Use Phrase Replacement" = "使用语汇置换";
|
"Use Phrase Replacement" = "使用语汇置换";
|
||||||
"Candidates keys cannot be empty." = "您必须指定选字键。";
|
"Candidates keys cannot be empty." = "您必须指定选字键。";
|
||||||
|
@ -96,11 +100,13 @@
|
||||||
// SwiftUI Preferences
|
// SwiftUI Preferences
|
||||||
"(Shift+)Space:" = "(Shift+)空格键:";
|
"(Shift+)Space:" = "(Shift+)空格键:";
|
||||||
"⚠︎ This feature in IMK Candidate Window defects. Please consult Apple Developer Relations\nand tell them the related Radar ID: #FB11300759." = "⚠︎ 该功能因 IMK 选字窗自身缺陷而无法实作。\n请携 Radar 编号 #FB11300759 找 Apple Developer Relations 投诉。";
|
"⚠︎ This feature in IMK Candidate Window defects. Please consult Apple Developer Relations\nand tell them the related Radar ID: #FB11300759." = "⚠︎ 该功能因 IMK 选字窗自身缺陷而无法实作。\n请携 Radar 编号 #FB11300759 找 Apple Developer Relations 投诉。";
|
||||||
|
"⚠︎ This feature is useful ONLY WHEN the font you are using doesn't support dynamic vertical punctuations. However, typed vertical punctuations will always shown as vertical punctuations EVEN IF your editor has changed the typing direction to horizontal." = "⚠︎ 该功能当且仅当目前的排版字型不支援纵排标点动态显示转义的情况下才有用。一旦使用了,所有敲出去的标点都会被永久转换为静态纵排标点:哪怕当前编辑器的排版模式已经改成横排,这些已经输入的标点也都还是纵排标点字符。";
|
||||||
"Allow backspace-editing miscomposed readings" = "允许对无效的读音使用 BackSpace 编辑";
|
"Allow backspace-editing miscomposed readings" = "允许对无效的读音使用 BackSpace 编辑";
|
||||||
"Allow boosting / excluding a candidate of single kanji" = "将可以就地升权/排除的候选字词的最短词长设为单个汉字";
|
"Allow boosting / excluding a candidate of single kanji" = "将可以就地升权/排除的候选字词的最短词长设为单个汉字";
|
||||||
"Allow using Enter key to confirm associated candidate selection" = "允许使用 Enter 确认当前选中的联想词";
|
"Allow using Enter key to confirm associated candidate selection" = "允许使用 Enter 确认当前选中的联想词";
|
||||||
"Also toggle alphanumerical mode with Left-Shift" = "也允许使用左侧的 Shift 键盘切换英数输入模式";
|
"Also toggle alphanumerical mode with Left-Shift" = "也允许使用左侧的 Shift 键盘切换英数输入模式";
|
||||||
"Always drop the previous reading" = "始终剔除游标正后方的字音";
|
"Always drop the previous reading" = "始终剔除游标正后方的字音";
|
||||||
|
"Always show tooltip texts horizontally" = "始终使用横排来显示工具提示视窗";
|
||||||
"Always type intonations to the inline composition buffer" = "始终在内文组字区内键入声调符号";
|
"Always type intonations to the inline composition buffer" = "始终在内文组字区内键入声调符号";
|
||||||
"Always use fixed listing order in candidate window" = "以固定顺序来陈列选字窗内的候选字";
|
"Always use fixed listing order in candidate window" = "以固定顺序来陈列选字窗内的候选字";
|
||||||
"An accommodation for elder computer users." = "针对年长使用者的习惯而提供。";
|
"An accommodation for elder computer users." = "针对年长使用者的习惯而提供。";
|
||||||
|
@ -141,6 +147,7 @@
|
||||||
"Dictionary" = "辞典设定";
|
"Dictionary" = "辞典设定";
|
||||||
"Directly commit lowercased letters" = "直接递交小写字母";
|
"Directly commit lowercased letters" = "直接递交小写字母";
|
||||||
"Directly commit uppercased letters" = "直接递交大写字母";
|
"Directly commit uppercased letters" = "直接递交大写字母";
|
||||||
|
"Disable Shift key accomodation in all cases" = "对任何客体应用均停用 Shift 键相容性措施";
|
||||||
"Disassemble the previous reading, dropping its intonation" = "析构游标正后方的字音,且剔除其声调";
|
"Disassemble the previous reading, dropping its intonation" = "析构游标正后方的字音,且剔除其声调";
|
||||||
"Disassembling process does not work with non-phonetic reading keys." = "析构行为仅针对组字器内「身为汉字读音」的读音索引单元有效。";
|
"Disassembling process does not work with non-phonetic reading keys." = "析构行为仅针对组字器内「身为汉字读音」的读音索引单元有效。";
|
||||||
"Emulating select-candidate-per-character mode" = "模拟 90 年代前期注音逐字选字输入风格";
|
"Emulating select-candidate-per-character mode" = "模拟 90 年代前期注音逐字选字输入风格";
|
||||||
|
@ -155,10 +162,10 @@
|
||||||
"Follow OS settings" = "依系统设定";
|
"Follow OS settings" = "依系统设定";
|
||||||
"for cycling candidates" = "轮替候选字";
|
"for cycling candidates" = "轮替候选字";
|
||||||
"for cycling pages" = "轮替页面";
|
"for cycling pages" = "轮替页面";
|
||||||
|
"For example: When typing “章太炎” and you want to override the “太” with “泰”, and the raw operation index range [1,2) which bounds are cutting the current node “章太炎” in range [0,3). If having lack of the pre-consolidation process, this word will become something like “張泰言” after the candidate selection. Only if we enable this consolidation, this word will become “章泰炎” which is the expected result that the context is kept as-is." = "打比方说,你敲了「章太炎」,你想将「太」改成「泰」。这个操作的作业索引范围是开闭区间 [1,2),会切到「章太炎」这个节点的所在索引范围 [0,3)。如果没有事前巩固处理的话,这个词会在你选字之后变成诸如「张泰言」这种你不想要的自动选字结果。当且仅当你启用了这个巩固功能的前提下,你选字之后的结果才会是「章泰炎」这种你想要的结果。";
|
||||||
"General" = "通用设定";
|
"General" = "通用设定";
|
||||||
"Hanyu Pinyin with Numeral Intonation" = "汉语拼音+数字标调";
|
"Hanyu Pinyin with Numeral Intonation" = "汉语拼音+数字标调";
|
||||||
"Harden vertical punctuations during vertical typing (not recommended)" = "在纵排书写时,强制转换标点为纵排形式(不推荐)";
|
"Harden vertical punctuations during vertical typing (not recommended)" = "在纵排书写时,强制转换标点为纵排形式(不推荐)";
|
||||||
"⚠︎ This feature is useful ONLY WHEN the font you are using doesn't support dynamic vertical punctuations. However, typed vertical punctuations will always shown as vertical punctuations EVEN IF your editor has changed the typing direction to horizontal." = "⚠︎ 该功能当且仅当目前的排版字型不支援纵排标点动态显示转义的情况下才有用。一旦使用了,所有敲出去的标点都会被永久转换为静态纵排标点:哪怕当前编辑器的排版模式已经改成横排,这些已经输入的标点也都还是纵排标点字符。";
|
|
||||||
"Horizontal" = "横向布局";
|
"Horizontal" = "横向布局";
|
||||||
"Hsu" = "许氏国音自然排列";
|
"Hsu" = "许氏国音自然排列";
|
||||||
"Hualuo Pinyin with Numeral Intonation" = "华罗拼音+数字标调";
|
"Hualuo Pinyin with Numeral Intonation" = "华罗拼音+数字标调";
|
||||||
|
@ -167,6 +174,7 @@
|
||||||
"in front of the phrase (like macOS built-in Zhuyin IME)" = "将游标置于词语前方 // macOS 内建注音风格";
|
"in front of the phrase (like macOS built-in Zhuyin IME)" = "将游标置于词语前方 // macOS 内建注音风格";
|
||||||
"Intonation Key:" = "声调键:";
|
"Intonation Key:" = "声调键:";
|
||||||
"Japanese" = "和语";
|
"Japanese" = "和语";
|
||||||
|
"Key names in tooltip will be shown as symbols when the tooltip is vertical. However, this option will be ignored since tooltip will always be horizontal if the UI language is English." = "纵排输入的情况下,工具提示内的按键名称会以符号显示。";
|
||||||
"Keyboard Shortcuts:" = "键盘快速键:";
|
"Keyboard Shortcuts:" = "键盘快速键:";
|
||||||
"Keyboard" = "键盘设定";
|
"Keyboard" = "键盘设定";
|
||||||
"Misc Settings:" = "杂项:";
|
"Misc Settings:" = "杂项:";
|
||||||
|
@ -174,6 +182,7 @@
|
||||||
"Non-QWERTY alphanumerical keyboard layouts are for Pinyin parser only." = "QWERTY 以外的英数布局是为了拼音排列使用者而准备的。";
|
"Non-QWERTY alphanumerical keyboard layouts are for Pinyin parser only." = "QWERTY 以外的英数布局是为了拼音排列使用者而准备的。";
|
||||||
"Note: The “Delete ⌫” key on Mac keyboard is named as “BackSpace ⌫” here in order to distinguish the real “Delete ⌦” key from full-sized desktop keyboards. If you want to use the real “Delete ⌦” key on a Mac keyboard with no numpad equipped, you have to press “Fn+⌫” instead." = "注意:Mac 键盘的「Delete ⌫」键在此被称作「BackSpace 退格键 ⌫」以与 PC 键盘的真正的「Delete ⌦」键彼此区分开。若您想在没有数字小键盘的 Mac 电脑上使用真正的「Delete ⌦」按键的话,请改用「Fn+⌫」。";
|
"Note: The “Delete ⌫” key on Mac keyboard is named as “BackSpace ⌫” here in order to distinguish the real “Delete ⌦” key from full-sized desktop keyboards. If you want to use the real “Delete ⌦” key on a Mac keyboard with no numpad equipped, you have to press “Fn+⌫” instead." = "注意:Mac 键盘的「Delete ⌫」键在此被称作「BackSpace 退格键 ⌫」以与 PC 键盘的真正的「Delete ⌦」键彼此区分开。若您想在没有数字小键盘的 Mac 电脑上使用真正的「Delete ⌦」按键的话,请改用「Fn+⌫」。";
|
||||||
"Only override the intonation of the previous reading if different" = "仅在键入的声调与游标正后方的字音不同时,尝试覆写";
|
"Only override the intonation of the previous reading if different" = "仅在键入的声调与游标正后方的字音不同时,尝试覆写";
|
||||||
|
"Only use this with known Chromium-based browsers" = "仅针对知名的 Chromium 核心的浏览器启用该措施";
|
||||||
"Output Settings:" = "输出设定:";
|
"Output Settings:" = "输出设定:";
|
||||||
"Override the previous reading's intonation with candidate-reset" = "尝试对游标正后方的字音覆写声调,且重设其选字状态";
|
"Override the previous reading's intonation with candidate-reset" = "尝试对游标正后方的字音覆写声调,且重设其选字状态";
|
||||||
"Phonetic Parser:" = "注音排列:";
|
"Phonetic Parser:" = "注音排列:";
|
||||||
|
@ -184,7 +193,7 @@
|
||||||
"Selection Keys:" = "选字键:";
|
"Selection Keys:" = "选字键:";
|
||||||
"Shift+BackSpace:" = "Shift+退格键:";
|
"Shift+BackSpace:" = "Shift+退格键:";
|
||||||
"Shift+Letter:" = "Shift+字母键:";
|
"Shift+Letter:" = "Shift+字母键:";
|
||||||
"Show Hanyu-Pinyin in the inline composition buffer & tooltip" = "拼音并击(组字区与工具提示内显示汉语拼音)";
|
"Show Hanyu-Pinyin in the inline composition buffer" = "拼音并击(组字区内显示汉语拼音)";
|
||||||
"Show page buttons in candidate window" = "在选字窗内显示翻页按钮";
|
"Show page buttons in candidate window" = "在选字窗内显示翻页按钮";
|
||||||
"Simplified Chinese" = "简体中文";
|
"Simplified Chinese" = "简体中文";
|
||||||
"Some client apps (like Chromium-cored browsers: MS Edge, Google Chrome, etc.) may duplicate Shift-key inputs due to their internal bugs, and their devs are less likely to fix their bugs of such. vChewing has its accommodation procedures enabled by default for known Chromium-cored browsers. Here you can customize how the accommodation should work." = "某些应用(比如像是 MS Edge 或者 Chrome 这样的 Chromium 核心的浏览器)可能会使输入的 Shift 按键讯号被重复输入,且其有关研发方很可能不打算修复这些产品缺陷。威注音针对这些应用预设启用了相容措施。请在此根据您的需求自订。";
|
"Some client apps (like Chromium-cored browsers: MS Edge, Google Chrome, etc.) may duplicate Shift-key inputs due to their internal bugs, and their devs are less likely to fix their bugs of such. vChewing has its accommodation procedures enabled by default for known Chromium-cored browsers. Here you can customize how the accommodation should work." = "某些应用(比如像是 MS Edge 或者 Chrome 这样的 Chromium 核心的浏览器)可能会使输入的 Shift 按键讯号被重复输入,且其有关研发方很可能不打算修复这些产品缺陷。威注音针对这些应用预设启用了相容措施。请在此根据您的需求自订。";
|
||||||
|
@ -206,7 +215,4 @@
|
||||||
"Use Shift key accommodation in all cases" = "对任何客体应用均启用 Shift 键相容性措施";
|
"Use Shift key accommodation in all cases" = "对任何客体应用均启用 Shift 键相容性措施";
|
||||||
"Vertical" = "纵向布局";
|
"Vertical" = "纵向布局";
|
||||||
"Warning: This page is for testing future features. \nFeatures listed here may not work as expected." = "警告:该页面仅作未来功能测试所用。\n在此列出的功能并非处于完全可用之状态。";
|
"Warning: This page is for testing future features. \nFeatures listed here may not work as expected." = "警告:该页面仅作未来功能测试所用。\n在此列出的功能并非处于完全可用之状态。";
|
||||||
"For example: When typing “章太炎” and you want to override the “太” with “泰”, and the raw operation index range [1,2) which bounds are cutting the current node “章太炎” in range [0,3). If having lack of the pre-consolidation process, this word will become something like “張泰言” after the candidate selection. Only if we enable this consolidation, this word will become “章泰炎” which is the expected result that the context is kept as-is." = "打比方说,你敲了「章太炎」,你想将「太」改成「泰」。这个操作的作业索引范围是开闭区间 [1,2),会切到「章太炎」这个节点的所在索引范围 [0,3)。如果没有事前巩固处理的话,这个词会在你选字之后变成诸如「张泰言」这种你不想要的自动选字结果。当且仅当你启用了这个巩固功能的前提下,你选字之后的结果才会是「章泰炎」这种你想要的结果。";
|
|
||||||
"Yale Pinyin with Numeral Intonation" = "耶鲁拼音+数字标调";
|
"Yale Pinyin with Numeral Intonation" = "耶鲁拼音+数字标调";
|
||||||
"Only use this with known Chromium-based browsers" = "仅针对知名的 Chromium 核心的浏览器启用该措施";
|
|
||||||
"Disable Shift key accomodation in all cases" = "对任何客体应用均停用 Shift 键相容性措施";
|
|
||||||
|
|
|
@ -85,7 +85,7 @@
|
||||||
<div>⌫</div>
|
<div>⌫</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div>Bksp (Backspace,被 Apple 称为 Delete)</div>
|
<div>Bksp (BackSpace,被 Apple 称为 Delete)</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
"vChewing" = "威注音輸入法";
|
"vChewing" = "威注音輸入法";
|
||||||
|
"Update Check Completed" = "更新檢查完畢";
|
||||||
|
"You are already using the latest version." = "您正在使用目前最新的發行版。";
|
||||||
|
"Plist downloaded is nil." = "下載來的更新資訊並非 Plist 檔案。";
|
||||||
|
"Plist downloaded cannot be parsed correctly." = "下載來的更新資訊 Plist 檔案無法正常解析。";
|
||||||
"vChewing crashed while handling previously loaded UOM observation data. These data files are cleaned now to ensure the usability." = "威注音輸入法的使用者半衰記憶模組在觀測時崩潰,相關半衰記憶資料檔案內容已全部清空。";
|
"vChewing crashed while handling previously loaded UOM observation data. These data files are cleaned now to ensure the usability." = "威注音輸入法的使用者半衰記憶模組在觀測時崩潰,相關半衰記憶資料檔案內容已全部清空。";
|
||||||
"About vChewing…" = "關於威注音…";
|
"About vChewing…" = "關於威注音…";
|
||||||
"vChewing Preferences…" = "威注音偏好設定…";
|
"vChewing Preferences…" = "威注音偏好設定…";
|
||||||
|
@ -17,7 +21,7 @@
|
||||||
"New Version Available" = "有新版可下載";
|
"New Version Available" = "有新版可下載";
|
||||||
"Not Now" = "以後再說";
|
"Not Now" = "以後再說";
|
||||||
"Visit Website" = "前往網站";
|
"Visit Website" = "前往網站";
|
||||||
"You're currently using vChewing %@ (%@), a new version %@ (%@) is now available. Do you want to visit vChewing's website to download the version?%@" = "目前使用的威注音官方版本是 %1$@ (%2$@),網路上有更新版本 %3$@ (%4$@) 可供下載。是否要前往威注音網站下載新版來安裝?%5$@";
|
"You're currently using vChewing %@ (%@), a new version %@ (%@) is now available. Do you want to visit vChewing's website to download the version?" = "目前使用的威注音官方版本是 %1$@ (%2$@),網路上有更新版本 %3$@ (%4$@) 可供下載。是否要前往威注音網站下載新版來安裝?";
|
||||||
"Force KangXi Writing" = "康熙正體字模式";
|
"Force KangXi Writing" = "康熙正體字模式";
|
||||||
"NotificationSwitchON" = "✔ 已啟用";
|
"NotificationSwitchON" = "✔ 已啟用";
|
||||||
"NotificationSwitchOFF" = "✘ 已停用";
|
"NotificationSwitchOFF" = "✘ 已停用";
|
||||||
|
@ -30,7 +34,7 @@
|
||||||
"\"%@\" length must ≥ 2 for a user phrase." = "「%@」字數不足以自訂語彙。";
|
"\"%@\" length must ≥ 2 for a user phrase." = "「%@」字數不足以自訂語彙。";
|
||||||
"\"%@\" length should ≤ %d for a user phrase." = "「%@」字數超過 %d、無法自訂。";
|
"\"%@\" length should ≤ %d for a user phrase." = "「%@」字數超過 %d、無法自訂。";
|
||||||
"\"%@\" selected. ENTER to add user phrase." = "「%@」敲 Enter 添入自訂語彙。";
|
"\"%@\" selected. ENTER to add user phrase." = "「%@」敲 Enter 添入自訂語彙。";
|
||||||
"\"%@\" already exists: ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude." = "「%@」已存在:敲 Enter 以升權、敲 Shift+Command+Enter 以降權;\n 敲 BackSpace 或 Delete 以排除。";
|
"\"%@\" already exists:\n ENTER to boost, SHIFT+COMMAND+ENTER to nerf, \n BackSpace or Delete key to exclude." = "「%@」已存在:\n 敲 Enter 以升權、敲 Shift+Command+Enter 以降權;\n 敲 BackSpace 或 Delete 以排除。";
|
||||||
"Edit Phrase Replacement Table…" = "編輯語彙置換表…";
|
"Edit Phrase Replacement Table…" = "編輯語彙置換表…";
|
||||||
"Use Phrase Replacement" = "使用語彙置換";
|
"Use Phrase Replacement" = "使用語彙置換";
|
||||||
"Candidates keys cannot be empty." = "您必須指定選字鍵。";
|
"Candidates keys cannot be empty." = "您必須指定選字鍵。";
|
||||||
|
@ -96,11 +100,13 @@
|
||||||
// SwiftUI Preferences
|
// SwiftUI Preferences
|
||||||
"(Shift+)Space:" = "(Shift+)空格鍵:";
|
"(Shift+)Space:" = "(Shift+)空格鍵:";
|
||||||
"⚠︎ This feature in IMK Candidate Window defects. Please consult Apple Developer Relations\nand tell them the related Radar ID: #FB11300759." = "⚠︎ 該功能因 IMK 選字窗自身缺陷而無法實作。\n請攜 Radar 編號 #FB11300759 找 Apple Developer Relations 投訴。";
|
"⚠︎ This feature in IMK Candidate Window defects. Please consult Apple Developer Relations\nand tell them the related Radar ID: #FB11300759." = "⚠︎ 該功能因 IMK 選字窗自身缺陷而無法實作。\n請攜 Radar 編號 #FB11300759 找 Apple Developer Relations 投訴。";
|
||||||
|
"⚠︎ This feature is useful ONLY WHEN the font you are using doesn't support dynamic vertical punctuations. However, typed vertical punctuations will always shown as vertical punctuations EVEN IF your editor has changed the typing direction to horizontal." = "⚠︎ 該功能當且僅當目前的排版字型不支援縱排標點動態顯示轉義的情況下才有用。一旦使用了,所有敲出去的標點都會被永久轉換為靜態縱排標點:哪怕當前編輯器的排版模式已經改成橫排,這些已經輸入的標點也都還是縱排標點字符。";
|
||||||
"Allow backspace-editing miscomposed readings" = "允許對無效的讀音使用 BackSpace 編輯";
|
"Allow backspace-editing miscomposed readings" = "允許對無效的讀音使用 BackSpace 編輯";
|
||||||
"Allow boosting / excluding a candidate of single kanji" = "將可以就地升權/排除的候選字詞的最短詞長設為單個漢字";
|
"Allow boosting / excluding a candidate of single kanji" = "將可以就地升權/排除的候選字詞的最短詞長設為單個漢字";
|
||||||
"Allow using Enter key to confirm associated candidate selection" = "允許使用 Enter 確認當前選中的聯想詞";
|
"Allow using Enter key to confirm associated candidate selection" = "允許使用 Enter 確認當前選中的聯想詞";
|
||||||
"Also toggle alphanumerical mode with Left-Shift" = "也允許使用左側的 Shift 鍵盤切換英數輸入模式";
|
"Also toggle alphanumerical mode with Left-Shift" = "也允許使用左側的 Shift 鍵盤切換英數輸入模式";
|
||||||
"Always drop the previous reading" = "始終剔除游標正後方的字音";
|
"Always drop the previous reading" = "始終剔除游標正後方的字音";
|
||||||
|
"Always show tooltip texts horizontally" = "始終使用橫排來顯示工具提示視窗";
|
||||||
"Always type intonations to the inline composition buffer" = "始終在內文組字區內鍵入聲調符號";
|
"Always type intonations to the inline composition buffer" = "始終在內文組字區內鍵入聲調符號";
|
||||||
"Always use fixed listing order in candidate window" = "以固定順序來陳列選字窗內的候選字";
|
"Always use fixed listing order in candidate window" = "以固定順序來陳列選字窗內的候選字";
|
||||||
"An accommodation for elder computer users." = "針對年長使用者的習慣而提供。";
|
"An accommodation for elder computer users." = "針對年長使用者的習慣而提供。";
|
||||||
|
@ -141,6 +147,7 @@
|
||||||
"Dictionary" = "辭典設定";
|
"Dictionary" = "辭典設定";
|
||||||
"Directly commit lowercased letters" = "直接遞交小寫字母";
|
"Directly commit lowercased letters" = "直接遞交小寫字母";
|
||||||
"Directly commit uppercased letters" = "直接遞交大寫字母";
|
"Directly commit uppercased letters" = "直接遞交大寫字母";
|
||||||
|
"Disable Shift key accomodation in all cases" = "對任何客體應用均停用 Shift 鍵相容性措施";
|
||||||
"Disassemble the previous reading, dropping its intonation" = "析構游標正後方的字音,且剔除其聲調";
|
"Disassemble the previous reading, dropping its intonation" = "析構游標正後方的字音,且剔除其聲調";
|
||||||
"Disassembling process does not work with non-phonetic reading keys." = "析構行為僅針對組字器內「身為漢字讀音」的讀音索引單元有效。";
|
"Disassembling process does not work with non-phonetic reading keys." = "析構行為僅針對組字器內「身為漢字讀音」的讀音索引單元有效。";
|
||||||
"Emulating select-candidate-per-character mode" = "模擬 90 年代前期注音逐字選字輸入風格";
|
"Emulating select-candidate-per-character mode" = "模擬 90 年代前期注音逐字選字輸入風格";
|
||||||
|
@ -155,10 +162,10 @@
|
||||||
"Follow OS settings" = "依系統設定";
|
"Follow OS settings" = "依系統設定";
|
||||||
"for cycling candidates" = "輪替候選字";
|
"for cycling candidates" = "輪替候選字";
|
||||||
"for cycling pages" = "輪替頁面";
|
"for cycling pages" = "輪替頁面";
|
||||||
|
"For example: When typing “章太炎” and you want to override the “太” with “泰”, and the raw operation index range [1,2) which bounds are cutting the current node “章太炎” in range [0,3). If having lack of the pre-consolidation process, this word will become something like “張泰言” after the candidate selection. Only if we enable this consolidation, this word will become “章泰炎” which is the expected result that the context is kept as-is." = "打比方說,你敲了「章太炎」,你想將「太」改成「泰」。這個操作的作業索引範圍是開閉區間 [1,2),會切到「章太炎」這個節點的所在索引範圍 [0,3)。如果沒有事前鞏固處理的話,這個詞會在你選字之後變成諸如「張泰言」這種你不想要的自動選字結果。當且僅當你啟用了這個鞏固功能的前提下,你選字之後的結果才會是「章泰炎」這種你想要的結果。";
|
||||||
"General" = "通用設定";
|
"General" = "通用設定";
|
||||||
"Hanyu Pinyin with Numeral Intonation" = "漢語拼音+數字標調";
|
"Hanyu Pinyin with Numeral Intonation" = "漢語拼音+數字標調";
|
||||||
"Harden vertical punctuations during vertical typing (not recommended)" = "在縱排書寫時,強制轉換標點為縱排形式(不推薦)";
|
"Harden vertical punctuations during vertical typing (not recommended)" = "在縱排書寫時,強制轉換標點為縱排形式(不推薦)";
|
||||||
"⚠︎ This feature is useful ONLY WHEN the font you are using doesn't support dynamic vertical punctuations. However, typed vertical punctuations will always shown as vertical punctuations EVEN IF your editor has changed the typing direction to horizontal." = "⚠︎ 該功能當且僅當目前的排版字型不支援縱排標點動態顯示轉義的情況下才有用。一旦使用了,所有敲出去的標點都會被永久轉換為靜態縱排標點:哪怕當前編輯器的排版模式已經改成橫排,這些已經輸入的標點也都還是縱排標點字符。";
|
|
||||||
"Horizontal" = "橫向佈局";
|
"Horizontal" = "橫向佈局";
|
||||||
"Hsu" = "許氏國音自然排列";
|
"Hsu" = "許氏國音自然排列";
|
||||||
"Hualuo Pinyin with Numeral Intonation" = "華羅拼音+數字標調";
|
"Hualuo Pinyin with Numeral Intonation" = "華羅拼音+數字標調";
|
||||||
|
@ -167,6 +174,7 @@
|
||||||
"in front of the phrase (like macOS built-in Zhuyin IME)" = "將游標置於詞語前方 // macOS 內建注音風格";
|
"in front of the phrase (like macOS built-in Zhuyin IME)" = "將游標置於詞語前方 // macOS 內建注音風格";
|
||||||
"Intonation Key:" = "聲調鍵:";
|
"Intonation Key:" = "聲調鍵:";
|
||||||
"Japanese" = "和語";
|
"Japanese" = "和語";
|
||||||
|
"Key names in tooltip will be shown as symbols when the tooltip is vertical. However, this option will be ignored since tooltip will always be horizontal if the UI language is English." = "縱排輸入的情況下,工具提示內的按鍵名稱會以符號顯示。";
|
||||||
"Keyboard Shortcuts:" = "鍵盤快速鍵:";
|
"Keyboard Shortcuts:" = "鍵盤快速鍵:";
|
||||||
"Keyboard" = "鍵盤設定";
|
"Keyboard" = "鍵盤設定";
|
||||||
"Misc Settings:" = "雜項:";
|
"Misc Settings:" = "雜項:";
|
||||||
|
@ -174,6 +182,7 @@
|
||||||
"Non-QWERTY alphanumerical keyboard layouts are for Pinyin parser only." = "QWERTY 以外的英數佈局是為了拼音排列使用者而準備的。";
|
"Non-QWERTY alphanumerical keyboard layouts are for Pinyin parser only." = "QWERTY 以外的英數佈局是為了拼音排列使用者而準備的。";
|
||||||
"Note: The “Delete ⌫” key on Mac keyboard is named as “BackSpace ⌫” here in order to distinguish the real “Delete ⌦” key from full-sized desktop keyboards. If you want to use the real “Delete ⌦” key on a Mac keyboard with no numpad equipped, you have to press “Fn+⌫” instead." = "注意:Mac 鍵盤的「Delete ⌫」鍵在此被稱作「BackSpace 退格鍵 ⌫」以與 PC 鍵盤的真正的「Delete ⌦」鍵彼此區分開。若您想在沒有數字小鍵盤的 Mac 電腦上使用真正的「Delete ⌦」按鍵的話,請改用「Fn+⌫」。";
|
"Note: The “Delete ⌫” key on Mac keyboard is named as “BackSpace ⌫” here in order to distinguish the real “Delete ⌦” key from full-sized desktop keyboards. If you want to use the real “Delete ⌦” key on a Mac keyboard with no numpad equipped, you have to press “Fn+⌫” instead." = "注意:Mac 鍵盤的「Delete ⌫」鍵在此被稱作「BackSpace 退格鍵 ⌫」以與 PC 鍵盤的真正的「Delete ⌦」鍵彼此區分開。若您想在沒有數字小鍵盤的 Mac 電腦上使用真正的「Delete ⌦」按鍵的話,請改用「Fn+⌫」。";
|
||||||
"Only override the intonation of the previous reading if different" = "僅在鍵入的聲調與游標正後方的字音不同時,嘗試覆寫";
|
"Only override the intonation of the previous reading if different" = "僅在鍵入的聲調與游標正後方的字音不同時,嘗試覆寫";
|
||||||
|
"Only use this with known Chromium-based browsers" = "僅針對知名的 Chromium 核心的瀏覽器啟用該措施";
|
||||||
"Output Settings:" = "輸出設定:";
|
"Output Settings:" = "輸出設定:";
|
||||||
"Override the previous reading's intonation with candidate-reset" = "嘗試對游標正後方的字音覆寫聲調,且重設其選字狀態";
|
"Override the previous reading's intonation with candidate-reset" = "嘗試對游標正後方的字音覆寫聲調,且重設其選字狀態";
|
||||||
"Phonetic Parser:" = "注音排列:";
|
"Phonetic Parser:" = "注音排列:";
|
||||||
|
@ -184,7 +193,7 @@
|
||||||
"Selection Keys:" = "選字鍵:";
|
"Selection Keys:" = "選字鍵:";
|
||||||
"Shift+BackSpace:" = "Shift+退格鍵:";
|
"Shift+BackSpace:" = "Shift+退格鍵:";
|
||||||
"Shift+Letter:" = "Shift+字母鍵:";
|
"Shift+Letter:" = "Shift+字母鍵:";
|
||||||
"Show Hanyu-Pinyin in the inline composition buffer & tooltip" = "拼音並擊(組字區與工具提示內顯示漢語拼音)";
|
"Show Hanyu-Pinyin in the inline composition buffer" = "拼音並擊(組字區內顯示漢語拼音)";
|
||||||
"Show page buttons in candidate window" = "在選字窗內顯示翻頁按鈕";
|
"Show page buttons in candidate window" = "在選字窗內顯示翻頁按鈕";
|
||||||
"Simplified Chinese" = "簡體中文";
|
"Simplified Chinese" = "簡體中文";
|
||||||
"Some client apps (like Chromium-cored browsers: MS Edge, Google Chrome, etc.) may duplicate Shift-key inputs due to their internal bugs, and their devs are less likely to fix their bugs of such. vChewing has its accommodation procedures enabled by default for known Chromium-cored browsers. Here you can customize how the accommodation should work." = "某些應用(比如像是 MS Edge 或者 Chrome 這樣的 Chromium 核心的瀏覽器)可能會使輸入的 Shift 按鍵訊號被重複輸入,且其有關研發方很可能不打算修復這些產品缺陷。威注音針對這些應用預設啟用了相容措施。請在此根據您的需求自訂。";
|
"Some client apps (like Chromium-cored browsers: MS Edge, Google Chrome, etc.) may duplicate Shift-key inputs due to their internal bugs, and their devs are less likely to fix their bugs of such. vChewing has its accommodation procedures enabled by default for known Chromium-cored browsers. Here you can customize how the accommodation should work." = "某些應用(比如像是 MS Edge 或者 Chrome 這樣的 Chromium 核心的瀏覽器)可能會使輸入的 Shift 按鍵訊號被重複輸入,且其有關研發方很可能不打算修復這些產品缺陷。威注音針對這些應用預設啟用了相容措施。請在此根據您的需求自訂。";
|
||||||
|
@ -206,7 +215,4 @@
|
||||||
"Use Shift key accommodation in all cases" = "對任何客體應用均啟用 Shift 鍵相容性措施";
|
"Use Shift key accommodation in all cases" = "對任何客體應用均啟用 Shift 鍵相容性措施";
|
||||||
"Vertical" = "縱向佈局";
|
"Vertical" = "縱向佈局";
|
||||||
"Warning: This page is for testing future features. \nFeatures listed here may not work as expected." = "警告:該頁面僅作未來功能測試所用。\n在此列出的功能並非處於完全可用之狀態。";
|
"Warning: This page is for testing future features. \nFeatures listed here may not work as expected." = "警告:該頁面僅作未來功能測試所用。\n在此列出的功能並非處於完全可用之狀態。";
|
||||||
"For example: When typing “章太炎” and you want to override the “太” with “泰”, and the raw operation index range [1,2) which bounds are cutting the current node “章太炎” in range [0,3). If having lack of the pre-consolidation process, this word will become something like “張泰言” after the candidate selection. Only if we enable this consolidation, this word will become “章泰炎” which is the expected result that the context is kept as-is." = "打比方說,你敲了「章太炎」,你想將「太」改成「泰」。這個操作的作業索引範圍是開閉區間 [1,2),會切到「章太炎」這個節點的所在索引範圍 [0,3)。如果沒有事前鞏固處理的話,這個詞會在你選字之後變成諸如「張泰言」這種你不想要的自動選字結果。當且僅當你啟用了這個鞏固功能的前提下,你選字之後的結果才會是「章泰炎」這種你想要的結果。";
|
|
||||||
"Yale Pinyin with Numeral Intonation" = "耶魯拼音+數字標調";
|
"Yale Pinyin with Numeral Intonation" = "耶魯拼音+數字標調";
|
||||||
"Only use this with known Chromium-based browsers" = "僅針對知名的 Chromium 核心的瀏覽器啟用該措施";
|
|
||||||
"Disable Shift key accomodation in all cases" = "對任何客體應用均停用 Shift 鍵相容性措施";
|
|
||||||
|
|
|
@ -85,7 +85,7 @@
|
||||||
<div>⌫</div>
|
<div>⌫</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div>Bksp (Backspace,被 Apple 稱為 Delete)</div>
|
<div>Bksp (BackSpace,被 Apple 稱為 Delete)</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -236,7 +236,7 @@ class ctlPrefWindow: NSWindowController {
|
||||||
mgrPrefs.userDataFolderSpecified = newPath
|
mgrPrefs.userDataFolderSpecified = newPath
|
||||||
BookmarkManager.shared.saveBookmark(for: url)
|
BookmarkManager.shared.saveBookmark(for: url)
|
||||||
IME.initLangModels(userOnly: true)
|
IME.initLangModels(userOnly: true)
|
||||||
(NSApplication.shared.delegate as! AppDelegate).updateStreamHelperPath()
|
(NSApplication.shared.delegate as! AppDelegate).updateDirectoryMonitorPath()
|
||||||
} else {
|
} else {
|
||||||
clsSFX.beep()
|
clsSFX.beep()
|
||||||
if !bolPreviousFolderValidity {
|
if !bolPreviousFolderValidity {
|
||||||
|
|
|
@ -36,14 +36,14 @@
|
||||||
</window>
|
</window>
|
||||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||||
<visualEffectView blendingMode="behindWindow" material="sidebar" state="followsWindowActiveState" id="XWo-36-xGi" userLabel="vwrExperience">
|
<visualEffectView blendingMode="behindWindow" material="sidebar" state="followsWindowActiveState" id="XWo-36-xGi" userLabel="vwrExperience">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="836" height="365"/>
|
<rect key="frame" x="0.0" y="0.0" width="836" height="384"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<stackView distribution="fill" orientation="horizontal" alignment="top" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="qDj-B9-mZf">
|
<stackView distribution="fill" orientation="horizontal" alignment="top" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="qDj-B9-mZf">
|
||||||
<rect key="frame" x="20" y="33" width="796" height="312"/>
|
<rect key="frame" x="20" y="40" width="796" height="324"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<stackView distribution="fill" orientation="vertical" alignment="leading" spacing="9" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="j9R-fB-ttM">
|
<stackView distribution="fill" orientation="vertical" alignment="leading" spacing="9" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="j9R-fB-ttM">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="402" height="312"/>
|
<rect key="frame" x="0.0" y="12" width="402" height="312"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<stackView distribution="fill" orientation="vertical" alignment="leading" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fO5-4y-X0y">
|
<stackView distribution="fill" orientation="vertical" alignment="leading" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fO5-4y-X0y">
|
||||||
<rect key="frame" x="0.0" y="271" width="365" height="41"/>
|
<rect key="frame" x="0.0" y="271" width="365" height="41"/>
|
||||||
|
@ -266,10 +266,10 @@
|
||||||
</customSpacing>
|
</customSpacing>
|
||||||
</stackView>
|
</stackView>
|
||||||
<stackView distribution="fill" orientation="vertical" alignment="leading" spacing="9" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="VOm-nN-5IB">
|
<stackView distribution="fill" orientation="vertical" alignment="leading" spacing="9" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="VOm-nN-5IB">
|
||||||
<rect key="frame" x="410" y="9" width="386" height="303"/>
|
<rect key="frame" x="410" y="0.0" width="386" height="324"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<stackView distribution="fill" orientation="vertical" alignment="leading" spacing="7" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="s47-wG-vKA">
|
<stackView distribution="fill" orientation="vertical" alignment="leading" spacing="7" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="s47-wG-vKA">
|
||||||
<rect key="frame" x="0.0" y="220" width="386" height="83"/>
|
<rect key="frame" x="0.0" y="241" width="386" height="83"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="iCL-n8-VTP">
|
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="iCL-n8-VTP">
|
||||||
<rect key="frame" x="-2" y="68" width="323" height="15"/>
|
<rect key="frame" x="-2" y="68" width="323" height="15"/>
|
||||||
|
@ -319,7 +319,7 @@
|
||||||
</customSpacing>
|
</customSpacing>
|
||||||
</stackView>
|
</stackView>
|
||||||
<stackView distribution="fill" orientation="vertical" alignment="leading" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="NOW-jd-XBh">
|
<stackView distribution="fill" orientation="vertical" alignment="leading" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="NOW-jd-XBh">
|
||||||
<rect key="frame" x="0.0" y="150" width="386" height="61"/>
|
<rect key="frame" x="0.0" y="171" width="386" height="61"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="J0f-Aw-dxC">
|
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="J0f-Aw-dxC">
|
||||||
<rect key="frame" x="-2" y="46" width="336" height="15"/>
|
<rect key="frame" x="-2" y="46" width="336" height="15"/>
|
||||||
|
@ -365,10 +365,10 @@
|
||||||
</customSpacing>
|
</customSpacing>
|
||||||
</stackView>
|
</stackView>
|
||||||
<stackView distribution="fill" orientation="vertical" alignment="leading" spacing="6" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="jxD-fv-UYx">
|
<stackView distribution="fill" orientation="vertical" alignment="leading" spacing="6" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="jxD-fv-UYx">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="380" height="141"/>
|
<rect key="frame" x="0.0" y="0.0" width="380" height="162"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<button translatesAutoresizingMaskIntoConstraints="NO" id="109">
|
<button translatesAutoresizingMaskIntoConstraints="NO" id="109">
|
||||||
<rect key="frame" x="-1" y="125.5" width="285" height="16"/>
|
<rect key="frame" x="-1" y="146.5" width="285" height="16"/>
|
||||||
<buttonCell key="cell" type="check" title="Enable Space key for calling candidate window" bezelStyle="regularSquare" imagePosition="left" alignment="left" controlSize="small" state="on" inset="2" id="110">
|
<buttonCell key="cell" type="check" title="Enable Space key for calling candidate window" bezelStyle="regularSquare" imagePosition="left" alignment="left" controlSize="small" state="on" inset="2" id="110">
|
||||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||||
<font key="font" metaFont="cellTitle"/>
|
<font key="font" metaFont="cellTitle"/>
|
||||||
|
@ -378,7 +378,7 @@
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="bE0-Lq-Pj7">
|
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="bE0-Lq-Pj7">
|
||||||
<rect key="frame" x="-1" y="104.5" width="266" height="16"/>
|
<rect key="frame" x="-1" y="125.5" width="266" height="16"/>
|
||||||
<buttonCell key="cell" type="check" title="Use ESC key to clear the entire input buffer" bezelStyle="regularSquare" imagePosition="left" controlSize="small" state="on" inset="2" id="f2j-xD-4xK">
|
<buttonCell key="cell" type="check" title="Use ESC key to clear the entire input buffer" bezelStyle="regularSquare" imagePosition="left" controlSize="small" state="on" inset="2" id="f2j-xD-4xK">
|
||||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||||
<font key="font" metaFont="cellTitle"/>
|
<font key="font" metaFont="cellTitle"/>
|
||||||
|
@ -388,7 +388,7 @@
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="mzw-F2-aAQ">
|
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="mzw-F2-aAQ">
|
||||||
<rect key="frame" x="-1" y="83.5" width="295" height="16"/>
|
<rect key="frame" x="-1" y="104.5" width="295" height="16"/>
|
||||||
<buttonCell key="cell" type="check" title="Emulating select-candidate-per-character mode" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="ArK-Vk-OoT">
|
<buttonCell key="cell" type="check" title="Emulating select-candidate-per-character mode" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="ArK-Vk-OoT">
|
||||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||||
<font key="font" metaFont="cellTitle"/>
|
<font key="font" metaFont="cellTitle"/>
|
||||||
|
@ -398,7 +398,7 @@
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="j8R-Hj-3dj">
|
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="j8R-Hj-3dj">
|
||||||
<rect key="frame" x="-1" y="62.5" width="340" height="16"/>
|
<rect key="frame" x="-1" y="83.5" width="340" height="16"/>
|
||||||
<buttonCell key="cell" type="check" title="Automatically correct reading combinations when typing" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="chkAutoCorrectReadingCombination">
|
<buttonCell key="cell" type="check" title="Automatically correct reading combinations when typing" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="chkAutoCorrectReadingCombination">
|
||||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||||
<font key="font" metaFont="cellTitle"/>
|
<font key="font" metaFont="cellTitle"/>
|
||||||
|
@ -408,7 +408,7 @@
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="6MM-WC-Mpd">
|
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="6MM-WC-Mpd">
|
||||||
<rect key="frame" x="-1" y="41.5" width="381" height="16"/>
|
<rect key="frame" x="-1" y="62.5" width="381" height="16"/>
|
||||||
<buttonCell key="cell" type="check" title="Allow using Enter key to confirm associated candidate selection" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="chkAlsoConfirmAssociatedCandidatesByEnter">
|
<buttonCell key="cell" type="check" title="Allow using Enter key to confirm associated candidate selection" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="chkAlsoConfirmAssociatedCandidatesByEnter">
|
||||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||||
<font key="font" metaFont="cellTitle"/>
|
<font key="font" metaFont="cellTitle"/>
|
||||||
|
@ -418,7 +418,7 @@
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="HaB-rc-AcW">
|
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="HaB-rc-AcW">
|
||||||
<rect key="frame" x="-1" y="20.5" width="295" height="16"/>
|
<rect key="frame" x="-1" y="41.5" width="295" height="16"/>
|
||||||
<buttonCell key="cell" type="check" title="Allow backspace-editing miscomposed readings" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="chkKeepReadingUponCompositionError">
|
<buttonCell key="cell" type="check" title="Allow backspace-editing miscomposed readings" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="chkKeepReadingUponCompositionError">
|
||||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||||
<font key="font" metaFont="cellTitle"/>
|
<font key="font" metaFont="cellTitle"/>
|
||||||
|
@ -428,7 +428,7 @@
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="xe6-Pu-3Fa">
|
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="xe6-Pu-3Fa">
|
||||||
<rect key="frame" x="-1" y="-0.5" width="223" height="16"/>
|
<rect key="frame" x="-1" y="20.5" width="223" height="16"/>
|
||||||
<buttonCell key="cell" type="check" title="Trim unfinished readings on commit" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="tglTrimUnfinishedReadingsOnCommit">
|
<buttonCell key="cell" type="check" title="Trim unfinished readings on commit" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="tglTrimUnfinishedReadingsOnCommit">
|
||||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||||
<font key="font" metaFont="cellTitle"/>
|
<font key="font" metaFont="cellTitle"/>
|
||||||
|
@ -437,6 +437,16 @@
|
||||||
<binding destination="32" name="value" keyPath="values.TrimUnfinishedReadingsOnCommit" id="v0T-cw-dzA"/>
|
<binding destination="32" name="value" keyPath="values.TrimUnfinishedReadingsOnCommit" id="v0T-cw-dzA"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
|
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="7QM-7z-tpq">
|
||||||
|
<rect key="frame" x="-1" y="-0.5" width="233" height="16"/>
|
||||||
|
<buttonCell key="cell" type="check" title="Always show tooltip texts horizontally" bezelStyle="regularSquare" imagePosition="left" controlSize="small" inset="2" id="lblAlwaysShowTooltipTextsHorizontally">
|
||||||
|
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||||
|
<font key="font" metaFont="cellTitle"/>
|
||||||
|
</buttonCell>
|
||||||
|
<connections>
|
||||||
|
<binding destination="32" name="value" keyPath="values.AlwaysShowTooltipTextsHorizontally" id="szi-4g-EIC"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
</subviews>
|
</subviews>
|
||||||
<visibilityPriorities>
|
<visibilityPriorities>
|
||||||
<integer value="1000"/>
|
<integer value="1000"/>
|
||||||
|
@ -446,6 +456,7 @@
|
||||||
<integer value="1000"/>
|
<integer value="1000"/>
|
||||||
<integer value="1000"/>
|
<integer value="1000"/>
|
||||||
<integer value="1000"/>
|
<integer value="1000"/>
|
||||||
|
<integer value="1000"/>
|
||||||
</visibilityPriorities>
|
</visibilityPriorities>
|
||||||
<customSpacing>
|
<customSpacing>
|
||||||
<real value="3.4028234663852886e+38"/>
|
<real value="3.4028234663852886e+38"/>
|
||||||
|
@ -455,6 +466,7 @@
|
||||||
<real value="3.4028234663852886e+38"/>
|
<real value="3.4028234663852886e+38"/>
|
||||||
<real value="3.4028234663852886e+38"/>
|
<real value="3.4028234663852886e+38"/>
|
||||||
<real value="3.4028234663852886e+38"/>
|
<real value="3.4028234663852886e+38"/>
|
||||||
|
<real value="3.4028234663852886e+38"/>
|
||||||
</customSpacing>
|
</customSpacing>
|
||||||
</stackView>
|
</stackView>
|
||||||
</subviews>
|
</subviews>
|
||||||
|
@ -484,7 +496,7 @@
|
||||||
<constraint firstItem="qDj-B9-mZf" firstAttribute="top" secondItem="XWo-36-xGi" secondAttribute="top" constant="20" symbolic="YES" id="EmH-pX-s2C"/>
|
<constraint firstItem="qDj-B9-mZf" firstAttribute="top" secondItem="XWo-36-xGi" secondAttribute="top" constant="20" symbolic="YES" id="EmH-pX-s2C"/>
|
||||||
<constraint firstItem="qDj-B9-mZf" firstAttribute="leading" secondItem="XWo-36-xGi" secondAttribute="leading" constant="20" symbolic="YES" id="cs3-Kh-czM"/>
|
<constraint firstItem="qDj-B9-mZf" firstAttribute="leading" secondItem="XWo-36-xGi" secondAttribute="leading" constant="20" symbolic="YES" id="cs3-Kh-czM"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<point key="canvasLocation" x="-1091" y="-207"/>
|
<point key="canvasLocation" x="-1091" y="-198"/>
|
||||||
</visualEffectView>
|
</visualEffectView>
|
||||||
<visualEffectView blendingMode="behindWindow" material="sidebar" state="followsWindowActiveState" id="BUt-lg-GPp" userLabel="vwrGeneral">
|
<visualEffectView blendingMode="behindWindow" material="sidebar" state="followsWindowActiveState" id="BUt-lg-GPp" userLabel="vwrGeneral">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="445" height="405"/>
|
<rect key="frame" x="0.0" y="0.0" width="445" height="405"/>
|
||||||
|
|
|
@ -64,6 +64,7 @@
|
||||||
"jQC-12-UuK.ibShadowedObjectValues[0]" = "Item 1";
|
"jQC-12-UuK.ibShadowedObjectValues[0]" = "Item 1";
|
||||||
"jQC-12-UuK.ibShadowedObjectValues[1]" = "Item 2";
|
"jQC-12-UuK.ibShadowedObjectValues[1]" = "Item 2";
|
||||||
"jQC-12-UuK.ibShadowedObjectValues[2]" = "Item 3";
|
"jQC-12-UuK.ibShadowedObjectValues[2]" = "Item 3";
|
||||||
|
"lblAlwaysShowTooltipTextsHorizontally.title" = "Always show tooltip texts horizontally";
|
||||||
"lblDevZoneIMKCandidate.title" = "IMK candidate window relies on certain Apple private APIs which are force-exposed by using bridging headers. Its usability, at this moment, is only guaranteed from macOS 10.14 Mojave to macOS 13 Ventura. Further tests are required in the future in order to tell whether it is usable in newer macOS releases.";
|
"lblDevZoneIMKCandidate.title" = "IMK candidate window relies on certain Apple private APIs which are force-exposed by using bridging headers. Its usability, at this moment, is only guaranteed from macOS 10.14 Mojave to macOS 13 Ventura. Further tests are required in the future in order to tell whether it is usable in newer macOS releases.";
|
||||||
"lblDevZoneTitleDescription.title" = "Warning: This page is for testing future features. \nFeatures listed here may not work as expected.";
|
"lblDevZoneTitleDescription.title" = "Warning: This page is for testing future features. \nFeatures listed here may not work as expected.";
|
||||||
"lblIntonationKeyBehavior.title" = "Specify what intonation key does when syllable composer is empty.";
|
"lblIntonationKeyBehavior.title" = "Specify what intonation key does when syllable composer is empty.";
|
||||||
|
@ -96,7 +97,7 @@
|
||||||
"VdT-fw-7pQ.title" = "Debug Mode";
|
"VdT-fw-7pQ.title" = "Debug Mode";
|
||||||
"vpd-zx-GIk.title" = "Seigyou (JinYei)";
|
"vpd-zx-GIk.title" = "Seigyou (JinYei)";
|
||||||
"W24-T4-cg0.title" = "Enable CNS11643 Support (2022-08-02)";
|
"W24-T4-cg0.title" = "Enable CNS11643 Support (2022-08-02)";
|
||||||
"wFR-zX-M8H.title" = "Show Hanyu-Pinyin in the inline composition buffer & tooltip";
|
"wFR-zX-M8H.title" = "Show Hanyu-Pinyin in the inline composition buffer";
|
||||||
"wN3-k3-b2a.title" = "Choose your desired user data folder path. Will be omitted if invalid.";
|
"wN3-k3-b2a.title" = "Choose your desired user data folder path. Will be omitted if invalid.";
|
||||||
"wQ9-px-b07.title" = "Apple Dynamic Bopomofo Basic Keyboard Layouts (Dachen & Eten Traditional) must match the Dachen parser in order to be functional.";
|
"wQ9-px-b07.title" = "Apple Dynamic Bopomofo Basic Keyboard Layouts (Dachen & Eten Traditional) must match the Dachen parser in order to be functional.";
|
||||||
"Wvt-HE-LOv.title" = "Keyboard Layout";
|
"Wvt-HE-LOv.title" = "Keyboard Layout";
|
||||||
|
|
|
@ -64,6 +64,7 @@
|
||||||
"jQC-12-UuK.ibShadowedObjectValues[0]" = "Item 1";
|
"jQC-12-UuK.ibShadowedObjectValues[0]" = "Item 1";
|
||||||
"jQC-12-UuK.ibShadowedObjectValues[1]" = "Item 2";
|
"jQC-12-UuK.ibShadowedObjectValues[1]" = "Item 2";
|
||||||
"jQC-12-UuK.ibShadowedObjectValues[2]" = "Item 3";
|
"jQC-12-UuK.ibShadowedObjectValues[2]" = "Item 3";
|
||||||
|
"lblAlwaysShowTooltipTextsHorizontally.title" = "ヒントを常に横書きにする";
|
||||||
"lblDevZoneIMKCandidate.title" = "IMK 候補陳列ウィンドウは、Apple の未公開のAPIを「bridging-header」という強引的な手段で引き出して利用した機能である。現時点で macOS 10.14 Mojave から macOS 13 Ventura まで利用可能であるが、その後の新しい macOS との互換性の話はまだ早い。";
|
"lblDevZoneIMKCandidate.title" = "IMK 候補陳列ウィンドウは、Apple の未公開のAPIを「bridging-header」という強引的な手段で引き出して利用した機能である。現時点で macOS 10.14 Mojave から macOS 13 Ventura まで利用可能であるが、その後の新しい macOS との互換性の話はまだ早い。";
|
||||||
"lblDevZoneTitleDescription.title" = "警告:これからの新機能テストのために作ったページですから、\nここで陳列されている諸機能は予想通り動けるだと思わないでください。";
|
"lblDevZoneTitleDescription.title" = "警告:これからの新機能テストのために作ったページですから、\nここで陳列されている諸機能は予想通り動けるだと思わないでください。";
|
||||||
"lblIntonationKeyBehavior.title" = "音調組立緩衝列が空かされた時の音調キーの行為をご指定ください。";
|
"lblIntonationKeyBehavior.title" = "音調組立緩衝列が空かされた時の音調キーの行為をご指定ください。";
|
||||||
|
@ -96,7 +97,7 @@
|
||||||
"VdT-fw-7pQ.title" = "欠陥辿着モード";
|
"VdT-fw-7pQ.title" = "欠陥辿着モード";
|
||||||
"vpd-zx-GIk.title" = "精業配列";
|
"vpd-zx-GIk.title" = "精業配列";
|
||||||
"W24-T4-cg0.title" = "全字庫モード // 入力可能の漢字数倍増 (2022-08-02)";
|
"W24-T4-cg0.title" = "全字庫モード // 入力可能の漢字数倍増 (2022-08-02)";
|
||||||
"wFR-zX-M8H.title" = "弁音合併入力(入力緩衝列とヒントで音読みを漢語弁音に)";
|
"wFR-zX-M8H.title" = "弁音合併入力(入力緩衝列で音読みを漢語弁音に)";
|
||||||
"wN3-k3-b2a.title" = "欲しがるユーザー辞書保存先をご指定ください。無効の保存先設定は効かぬ。";
|
"wN3-k3-b2a.title" = "欲しがるユーザー辞書保存先をご指定ください。無効の保存先設定は効かぬ。";
|
||||||
"wQ9-px-b07.title" = "Apple 動態注音キーボード (大千と倚天伝統) を使うには、共通語分析器の注音配列を大千と設定すべきである。";
|
"wQ9-px-b07.title" = "Apple 動態注音キーボード (大千と倚天伝統) を使うには、共通語分析器の注音配列を大千と設定すべきである。";
|
||||||
"Wvt-HE-LOv.title" = "キーボード";
|
"Wvt-HE-LOv.title" = "キーボード";
|
||||||
|
|
|
@ -64,6 +64,7 @@
|
||||||
"jQC-12-UuK.ibShadowedObjectValues[0]" = "Item 1";
|
"jQC-12-UuK.ibShadowedObjectValues[0]" = "Item 1";
|
||||||
"jQC-12-UuK.ibShadowedObjectValues[1]" = "Item 2";
|
"jQC-12-UuK.ibShadowedObjectValues[1]" = "Item 2";
|
||||||
"jQC-12-UuK.ibShadowedObjectValues[2]" = "Item 3";
|
"jQC-12-UuK.ibShadowedObjectValues[2]" = "Item 3";
|
||||||
|
"lblAlwaysShowTooltipTextsHorizontally.title" = "始终使用横排来显示工具提示视窗";
|
||||||
"lblDevZoneIMKCandidate.title" = "IMK 选字窗依赖于 Apple 的私有 API,而且是借由桥接档案头强制曝露的方法使用的。目前,该功能仅在 macOS 10.14 Mojave 至 macOS 13 Ventura 系统内有测试过可用性。至于在未来的 macOS 发行版当中是否可用,则需要另行测试、才能下结论。";
|
"lblDevZoneIMKCandidate.title" = "IMK 选字窗依赖于 Apple 的私有 API,而且是借由桥接档案头强制曝露的方法使用的。目前,该功能仅在 macOS 10.14 Mojave 至 macOS 13 Ventura 系统内有测试过可用性。至于在未来的 macOS 发行版当中是否可用,则需要另行测试、才能下结论。";
|
||||||
"lblDevZoneTitleDescription.title" = "警告:该页面仅作未来功能测试所用。\n在此列出的功能并非处于完全可用之状态。";
|
"lblDevZoneTitleDescription.title" = "警告:该页面仅作未来功能测试所用。\n在此列出的功能并非处于完全可用之状态。";
|
||||||
"lblIntonationKeyBehavior.title" = "指定声调键(在注拼槽为「空」状态时)的行为。";
|
"lblIntonationKeyBehavior.title" = "指定声调键(在注拼槽为「空」状态时)的行为。";
|
||||||
|
@ -96,7 +97,7 @@
|
||||||
"VdT-fw-7pQ.title" = "侦错模式";
|
"VdT-fw-7pQ.title" = "侦错模式";
|
||||||
"vpd-zx-GIk.title" = "精业";
|
"vpd-zx-GIk.title" = "精业";
|
||||||
"W24-T4-cg0.title" = "启用 CNS11643 全字库支援 (2022-08-02)";
|
"W24-T4-cg0.title" = "启用 CNS11643 全字库支援 (2022-08-02)";
|
||||||
"wFR-zX-M8H.title" = "拼音并击(组字区与工具提示内显示汉语拼音)";
|
"wFR-zX-M8H.title" = "拼音并击(组字区内显示汉语拼音)";
|
||||||
"wN3-k3-b2a.title" = "请在此指定您想指定的使用者语汇档案目录。无效值会被忽略。";
|
"wN3-k3-b2a.title" = "请在此指定您想指定的使用者语汇档案目录。无效值会被忽略。";
|
||||||
"wQ9-px-b07.title" = "Apple 动态注音键盘布局(大千与倚天)要求普通话/国音分析器的注音排列得配置为大千排列。";
|
"wQ9-px-b07.title" = "Apple 动态注音键盘布局(大千与倚天)要求普通话/国音分析器的注音排列得配置为大千排列。";
|
||||||
"Wvt-HE-LOv.title" = "键盘布局";
|
"Wvt-HE-LOv.title" = "键盘布局";
|
||||||
|
|
|
@ -64,6 +64,7 @@
|
||||||
"jQC-12-UuK.ibShadowedObjectValues[0]" = "Item 1";
|
"jQC-12-UuK.ibShadowedObjectValues[0]" = "Item 1";
|
||||||
"jQC-12-UuK.ibShadowedObjectValues[1]" = "Item 2";
|
"jQC-12-UuK.ibShadowedObjectValues[1]" = "Item 2";
|
||||||
"jQC-12-UuK.ibShadowedObjectValues[2]" = "Item 3";
|
"jQC-12-UuK.ibShadowedObjectValues[2]" = "Item 3";
|
||||||
|
"lblAlwaysShowTooltipTextsHorizontally.title" = "始終使用橫排來顯示工具提示視窗";
|
||||||
"lblDevZoneIMKCandidate.title" = "IMK 選字窗依賴於 Apple 的私有 API,而且是藉由橋接檔案頭強制曝露的方法使用的。目前,該功能僅在 macOS 10.14 Mojave 至 macOS 13 Ventura 系統內有測試過可用性。至於在未來的 macOS 發行版當中是否可用,則需要另行測試、才能下結論。";
|
"lblDevZoneIMKCandidate.title" = "IMK 選字窗依賴於 Apple 的私有 API,而且是藉由橋接檔案頭強制曝露的方法使用的。目前,該功能僅在 macOS 10.14 Mojave 至 macOS 13 Ventura 系統內有測試過可用性。至於在未來的 macOS 發行版當中是否可用,則需要另行測試、才能下結論。";
|
||||||
"lblDevZoneTitleDescription.title" = "警告:該頁面僅作未來功能測試所用。\n在此列出的功能並非處於完全可用之狀態。";
|
"lblDevZoneTitleDescription.title" = "警告:該頁面僅作未來功能測試所用。\n在此列出的功能並非處於完全可用之狀態。";
|
||||||
"lblIntonationKeyBehavior.title" = "指定聲調鍵(在注拼槽為「空」狀態時)的行為。";
|
"lblIntonationKeyBehavior.title" = "指定聲調鍵(在注拼槽為「空」狀態時)的行為。";
|
||||||
|
@ -96,7 +97,7 @@
|
||||||
"VdT-fw-7pQ.title" = "偵錯模式";
|
"VdT-fw-7pQ.title" = "偵錯模式";
|
||||||
"vpd-zx-GIk.title" = "精業";
|
"vpd-zx-GIk.title" = "精業";
|
||||||
"W24-T4-cg0.title" = "啟用 CNS11643 全字庫支援 (2022-08-02)";
|
"W24-T4-cg0.title" = "啟用 CNS11643 全字庫支援 (2022-08-02)";
|
||||||
"wFR-zX-M8H.title" = "拼音並擊(組字區與工具提示內顯示漢語拼音)";
|
"wFR-zX-M8H.title" = "拼音並擊(組字區內顯示漢語拼音)";
|
||||||
"wN3-k3-b2a.title" = "請在此指定您想指定的使用者語彙檔案目錄。無效值會被忽略。";
|
"wN3-k3-b2a.title" = "請在此指定您想指定的使用者語彙檔案目錄。無效值會被忽略。";
|
||||||
"wQ9-px-b07.title" = "Apple 動態注音鍵盤佈局(大千與倚天)要求普通話/國音分析器的注音排列得配置為大千排列。";
|
"wQ9-px-b07.title" = "Apple 動態注音鍵盤佈局(大千與倚天)要求普通話/國音分析器的注音排列得配置為大千排列。";
|
||||||
"Wvt-HE-LOv.title" = "鍵盤佈局";
|
"Wvt-HE-LOv.title" = "鍵盤佈局";
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>2.4.0</string>
|
<string>2.5.0</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>2402</string>
|
<string>2500</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>
|
||||||
|
|
|
@ -726,7 +726,7 @@
|
||||||
<key>USE_HFS+_COMPRESSION</key>
|
<key>USE_HFS+_COMPRESSION</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>VERSION</key>
|
<key>VERSION</key>
|
||||||
<string>2.4.0</string>
|
<string>2.5.0</string>
|
||||||
</dict>
|
</dict>
|
||||||
<key>TYPE</key>
|
<key>TYPE</key>
|
||||||
<integer>0</integer>
|
<integer>0</integer>
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
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 */; };
|
||||||
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 */; };
|
||||||
5B175FFB28C5CDDC0078D1B4 /* IMKHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B175FFA28C5CDDC0078D1B4 /* IMKHelper.swift */; };
|
5B175FFB28C5CDDC0078D1B4 /* IMKHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B175FFA28C5CDDC0078D1B4 /* IMKHelper.swift */; };
|
||||||
5B20430728BEE30900BFC6FD /* BookmarkManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B20430628BEE30900BFC6FD /* BookmarkManager.swift */; };
|
5B20430728BEE30900BFC6FD /* BookmarkManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B20430628BEE30900BFC6FD /* BookmarkManager.swift */; };
|
||||||
5B21176C287539BB000443A9 /* ctlInputMethod_HandleStates.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B21176B287539BB000443A9 /* ctlInputMethod_HandleStates.swift */; };
|
5B21176C287539BB000443A9 /* ctlInputMethod_HandleStates.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B21176B287539BB000443A9 /* ctlInputMethod_HandleStates.swift */; };
|
||||||
|
@ -32,11 +33,11 @@
|
||||||
5B54E743283A7D89001ECBDC /* lmCoreNS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B54E742283A7D89001ECBDC /* lmCoreNS.swift */; };
|
5B54E743283A7D89001ECBDC /* lmCoreNS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B54E742283A7D89001ECBDC /* lmCoreNS.swift */; };
|
||||||
5B5948CE289CC04500C85824 /* LMInstantiator_DateTimeExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B5948CD289CC04500C85824 /* LMInstantiator_DateTimeExtension.swift */; };
|
5B5948CE289CC04500C85824 /* LMInstantiator_DateTimeExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B5948CD289CC04500C85824 /* LMInstantiator_DateTimeExtension.swift */; };
|
||||||
5B5E535227EF261400C6AA1E /* IME.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B5E535127EF261400C6AA1E /* IME.swift */; };
|
5B5E535227EF261400C6AA1E /* IME.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B5E535127EF261400C6AA1E /* IME.swift */; };
|
||||||
5B62A32927AE77D100A19448 /* FSEventStreamHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A32827AE77D100A19448 /* FSEventStreamHelper.swift */; };
|
5B5F8AEB28C86AAD007C11F1 /* NSAttributedTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B5F8AEA28C86AAD007C11F1 /* NSAttributedTextView.swift */; };
|
||||||
|
5B5F8AEE28C8826D007C11F1 /* ctlTooltip.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B5F8AED28C8826D007C11F1 /* ctlTooltip.swift */; };
|
||||||
5B62A33627AE795800A19448 /* mgrPrefs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A33527AE795800A19448 /* mgrPrefs.swift */; };
|
5B62A33627AE795800A19448 /* mgrPrefs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A33527AE795800A19448 /* mgrPrefs.swift */; };
|
||||||
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 */; };
|
||||||
5B62A34927AE7CD900A19448 /* TooltipController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A34327AE7CD900A19448 /* TooltipController.swift */; };
|
|
||||||
5B62A34A27AE7CD900A19448 /* NotifierController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A34527AE7CD900A19448 /* NotifierController.swift */; };
|
5B62A34A27AE7CD900A19448 /* NotifierController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A34527AE7CD900A19448 /* NotifierController.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 */; };
|
||||||
|
@ -84,6 +85,7 @@
|
||||||
5BBBB77527AED70B0023B93A /* MenuIcon-SCVIM.png in Resources */ = {isa = PBXBuildFile; fileRef = 5BBBB77127AED70B0023B93A /* MenuIcon-SCVIM.png */; };
|
5BBBB77527AED70B0023B93A /* MenuIcon-SCVIM.png in Resources */ = {isa = PBXBuildFile; fileRef = 5BBBB77127AED70B0023B93A /* MenuIcon-SCVIM.png */; };
|
||||||
5BBBB77627AED70B0023B93A /* MenuIcon-TCVIM.png in Resources */ = {isa = PBXBuildFile; fileRef = 5BBBB77227AED70B0023B93A /* MenuIcon-TCVIM.png */; };
|
5BBBB77627AED70B0023B93A /* MenuIcon-TCVIM.png in Resources */ = {isa = PBXBuildFile; fileRef = 5BBBB77227AED70B0023B93A /* MenuIcon-TCVIM.png */; };
|
||||||
5BBBB77A27AEDC690023B93A /* clsSFX.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BBBB77927AEDC690023B93A /* clsSFX.swift */; };
|
5BBBB77A27AEDC690023B93A /* clsSFX.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BBBB77927AEDC690023B93A /* clsSFX.swift */; };
|
||||||
|
5BBC9EFC28CA042500041196 /* UpdateSputnik.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BBC9EFB28CA042500041196 /* UpdateSputnik.swift */; };
|
||||||
5BC2652227E04B7E00700291 /* uninstall.sh in Resources */ = {isa = PBXBuildFile; fileRef = 5BC2652127E04B7B00700291 /* uninstall.sh */; };
|
5BC2652227E04B7E00700291 /* uninstall.sh in Resources */ = {isa = PBXBuildFile; fileRef = 5BC2652127E04B7B00700291 /* uninstall.sh */; };
|
||||||
5BC4479D2865686500EDC323 /* data-chs.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5BEDB71C283B4AEA0078EB25 /* data-chs.plist */; };
|
5BC4479D2865686500EDC323 /* data-chs.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5BEDB71C283B4AEA0078EB25 /* data-chs.plist */; };
|
||||||
5BC4479E2865686500EDC323 /* data-cht.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5BEDB720283B4AEA0078EB25 /* data-cht.plist */; };
|
5BC4479E2865686500EDC323 /* data-cht.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5BEDB720283B4AEA0078EB25 /* data-cht.plist */; };
|
||||||
|
@ -91,7 +93,6 @@
|
||||||
5BC447A02865686500EDC323 /* data-symbols.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5BEDB71E283B4AEA0078EB25 /* data-symbols.plist */; };
|
5BC447A02865686500EDC323 /* data-symbols.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5BEDB71E283B4AEA0078EB25 /* data-symbols.plist */; };
|
||||||
5BC447A12865686500EDC323 /* data-zhuyinwen.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5BEDB71F283B4AEA0078EB25 /* data-zhuyinwen.plist */; };
|
5BC447A12865686500EDC323 /* data-zhuyinwen.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5BEDB71F283B4AEA0078EB25 /* data-zhuyinwen.plist */; };
|
||||||
5BC447A628656A1900EDC323 /* PrefManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BC447A228656A1900EDC323 /* PrefManagerTests.swift */; };
|
5BC447A628656A1900EDC323 /* PrefManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BC447A228656A1900EDC323 /* PrefManagerTests.swift */; };
|
||||||
5BC447A928656A1900EDC323 /* UpdateAPITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BC447A528656A1900EDC323 /* UpdateAPITests.swift */; };
|
|
||||||
5BC447AE2865CFC200EDC323 /* KeyHandlerTestsNormalCHS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BC447A428656A1900EDC323 /* KeyHandlerTestsNormalCHS.swift */; };
|
5BC447AE2865CFC200EDC323 /* KeyHandlerTestsNormalCHS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BC447A428656A1900EDC323 /* KeyHandlerTestsNormalCHS.swift */; };
|
||||||
5BC6E03C286692BE00291771 /* KeyHandlerTestsSCPCCHT.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BC447A328656A1900EDC323 /* KeyHandlerTestsSCPCCHT.swift */; };
|
5BC6E03C286692BE00291771 /* KeyHandlerTestsSCPCCHT.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BC447A328656A1900EDC323 /* KeyHandlerTestsSCPCCHT.swift */; };
|
||||||
5BD0113B28180D6100609769 /* LMInstantiator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD0113A28180D6100609769 /* LMInstantiator.swift */; };
|
5BD0113B28180D6100609769 /* LMInstantiator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD0113A28180D6100609769 /* LMInstantiator.swift */; };
|
||||||
|
@ -103,7 +104,6 @@
|
||||||
5BD05C6827B2BBEF004C4F1D /* Content.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD05C6327B2BBEF004C4F1D /* Content.swift */; };
|
5BD05C6827B2BBEF004C4F1D /* Content.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD05C6327B2BBEF004C4F1D /* Content.swift */; };
|
||||||
5BD05C6927B2BBEF004C4F1D /* WindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD05C6427B2BBEF004C4F1D /* WindowController.swift */; };
|
5BD05C6927B2BBEF004C4F1D /* WindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD05C6427B2BBEF004C4F1D /* WindowController.swift */; };
|
||||||
5BD05C6A27B2BBEF004C4F1D /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD05C6527B2BBEF004C4F1D /* ViewController.swift */; };
|
5BD05C6A27B2BBEF004C4F1D /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD05C6527B2BBEF004C4F1D /* ViewController.swift */; };
|
||||||
5BDC1CFA27FDF1310052C2B9 /* apiUpdate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BDC1CF927FDF1310052C2B9 /* apiUpdate.swift */; };
|
|
||||||
5BDCBB2E27B4E67A00D0CC59 /* vChewingPhraseEditor.app in Resources */ = {isa = PBXBuildFile; fileRef = 5BD05BB827B2A429004C4F1D /* vChewingPhraseEditor.app */; };
|
5BDCBB2E27B4E67A00D0CC59 /* vChewingPhraseEditor.app in Resources */ = {isa = PBXBuildFile; fileRef = 5BD05BB827B2A429004C4F1D /* vChewingPhraseEditor.app */; };
|
||||||
5BE377A0288FED8D0037365B /* KeyHandler_HandleComposition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BE3779F288FED8D0037365B /* KeyHandler_HandleComposition.swift */; };
|
5BE377A0288FED8D0037365B /* KeyHandler_HandleComposition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BE3779F288FED8D0037365B /* KeyHandler_HandleComposition.swift */; };
|
||||||
5BE78BD927B3775B005EA1BE /* ctlAboutWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BE78BD827B37750005EA1BE /* ctlAboutWindow.swift */; };
|
5BE78BD927B3775B005EA1BE /* ctlAboutWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BE78BD827B37750005EA1BE /* ctlAboutWindow.swift */; };
|
||||||
|
@ -211,6 +211,7 @@
|
||||||
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; };
|
||||||
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>"; };
|
||||||
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>"; };
|
||||||
5B18BA6F27C7BD8B0056EB19 /* LICENSE-CHS.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "LICENSE-CHS.txt"; sourceTree = "<group>"; };
|
5B18BA6F27C7BD8B0056EB19 /* LICENSE-CHS.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "LICENSE-CHS.txt"; sourceTree = "<group>"; };
|
||||||
5B18BA7027C7BD8B0056EB19 /* Makefile */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
|
5B18BA7027C7BD8B0056EB19 /* Makefile */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
|
||||||
|
@ -246,11 +247,11 @@
|
||||||
5B54E742283A7D89001ECBDC /* lmCoreNS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = lmCoreNS.swift; sourceTree = "<group>"; };
|
5B54E742283A7D89001ECBDC /* lmCoreNS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = lmCoreNS.swift; sourceTree = "<group>"; };
|
||||||
5B5948CD289CC04500C85824 /* LMInstantiator_DateTimeExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LMInstantiator_DateTimeExtension.swift; sourceTree = "<group>"; };
|
5B5948CD289CC04500C85824 /* LMInstantiator_DateTimeExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LMInstantiator_DateTimeExtension.swift; sourceTree = "<group>"; };
|
||||||
5B5E535127EF261400C6AA1E /* IME.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = IME.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
5B5E535127EF261400C6AA1E /* IME.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = IME.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
||||||
5B62A32827AE77D100A19448 /* FSEventStreamHelper.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = FSEventStreamHelper.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
5B5F8AEA28C86AAD007C11F1 /* NSAttributedTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSAttributedTextView.swift; sourceTree = "<group>"; };
|
||||||
|
5B5F8AED28C8826D007C11F1 /* ctlTooltip.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ctlTooltip.swift; sourceTree = "<group>"; };
|
||||||
5B62A33527AE795800A19448 /* mgrPrefs.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = mgrPrefs.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
5B62A33527AE795800A19448 /* mgrPrefs.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = mgrPrefs.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; };
|
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; };
|
||||||
5B62A34327AE7CD900A19448 /* TooltipController.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = TooltipController.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; };
|
||||||
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>"; };
|
||||||
|
@ -301,6 +302,7 @@
|
||||||
5BBBB77227AED70B0023B93A /* MenuIcon-TCVIM.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "MenuIcon-TCVIM.png"; sourceTree = "<group>"; };
|
5BBBB77227AED70B0023B93A /* MenuIcon-TCVIM.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "MenuIcon-TCVIM.png"; sourceTree = "<group>"; };
|
||||||
5BBBB77727AEDB290023B93A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/MainMenu.strings; sourceTree = "<group>"; };
|
5BBBB77727AEDB290023B93A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/MainMenu.strings; sourceTree = "<group>"; };
|
||||||
5BBBB77927AEDC690023B93A /* clsSFX.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = clsSFX.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
5BBBB77927AEDC690023B93A /* clsSFX.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = clsSFX.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
||||||
|
5BBC9EFB28CA042500041196 /* UpdateSputnik.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateSputnik.swift; sourceTree = "<group>"; };
|
||||||
5BBD627827B6C4D900271480 /* Update-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Update-Info.plist"; sourceTree = "<group>"; };
|
5BBD627827B6C4D900271480 /* Update-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Update-Info.plist"; sourceTree = "<group>"; };
|
||||||
5BC0AAC927F58472002D33E9 /* pkgPreInstall.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = pkgPreInstall.sh; sourceTree = "<group>"; };
|
5BC0AAC927F58472002D33E9 /* pkgPreInstall.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = pkgPreInstall.sh; sourceTree = "<group>"; };
|
||||||
5BC0AACA27F58472002D33E9 /* pkgPostInstall.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = pkgPostInstall.sh; sourceTree = "<group>"; };
|
5BC0AACA27F58472002D33E9 /* pkgPostInstall.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = pkgPostInstall.sh; sourceTree = "<group>"; };
|
||||||
|
@ -308,7 +310,6 @@
|
||||||
5BC447A228656A1900EDC323 /* PrefManagerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PrefManagerTests.swift; sourceTree = "<group>"; };
|
5BC447A228656A1900EDC323 /* PrefManagerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PrefManagerTests.swift; sourceTree = "<group>"; };
|
||||||
5BC447A328656A1900EDC323 /* KeyHandlerTestsSCPCCHT.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyHandlerTestsSCPCCHT.swift; sourceTree = "<group>"; };
|
5BC447A328656A1900EDC323 /* KeyHandlerTestsSCPCCHT.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyHandlerTestsSCPCCHT.swift; sourceTree = "<group>"; };
|
||||||
5BC447A428656A1900EDC323 /* KeyHandlerTestsNormalCHS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyHandlerTestsNormalCHS.swift; sourceTree = "<group>"; };
|
5BC447A428656A1900EDC323 /* KeyHandlerTestsNormalCHS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyHandlerTestsNormalCHS.swift; sourceTree = "<group>"; };
|
||||||
5BC447A528656A1900EDC323 /* UpdateAPITests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UpdateAPITests.swift; sourceTree = "<group>"; };
|
|
||||||
5BC447AB2865BEF500EDC323 /* AUTHORS */ = {isa = PBXFileReference; lastKnownFileType = text; path = AUTHORS; sourceTree = "<group>"; };
|
5BC447AB2865BEF500EDC323 /* AUTHORS */ = {isa = PBXFileReference; lastKnownFileType = text; path = AUTHORS; sourceTree = "<group>"; };
|
||||||
5BD0113A28180D6100609769 /* LMInstantiator.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; lineEnding = 0; path = LMInstantiator.swift; sourceTree = "<group>"; usesTabs = 0; };
|
5BD0113A28180D6100609769 /* LMInstantiator.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; lineEnding = 0; path = LMInstantiator.swift; sourceTree = "<group>"; usesTabs = 0; };
|
||||||
5BD0113C2818543900609769 /* KeyHandler_Core.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; lineEnding = 0; path = KeyHandler_Core.swift; sourceTree = "<group>"; usesTabs = 0; };
|
5BD0113C2818543900609769 /* KeyHandler_Core.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; lineEnding = 0; path = KeyHandler_Core.swift; sourceTree = "<group>"; usesTabs = 0; };
|
||||||
|
@ -320,7 +321,6 @@
|
||||||
5BD05C6327B2BBEF004C4F1D /* Content.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = Content.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
5BD05C6327B2BBEF004C4F1D /* Content.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = Content.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
||||||
5BD05C6427B2BBEF004C4F1D /* WindowController.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = WindowController.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
5BD05C6427B2BBEF004C4F1D /* WindowController.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = WindowController.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
||||||
5BD05C6527B2BBEF004C4F1D /* ViewController.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = ViewController.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
5BD05C6527B2BBEF004C4F1D /* ViewController.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = ViewController.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
||||||
5BDC1CF927FDF1310052C2B9 /* apiUpdate.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = apiUpdate.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
|
||||||
5BDCBB4227B4F6C600D0CC59 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/MainMenu.strings"; sourceTree = "<group>"; };
|
5BDCBB4227B4F6C600D0CC59 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/MainMenu.strings"; sourceTree = "<group>"; };
|
||||||
5BDCBB4327B4F6C600D0CC59 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/frmAboutWindow.strings"; sourceTree = "<group>"; };
|
5BDCBB4327B4F6C600D0CC59 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/frmAboutWindow.strings"; sourceTree = "<group>"; };
|
||||||
5BDCBB4527B4F6C600D0CC59 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/frmPrefWindow.strings"; sourceTree = "<group>"; };
|
5BDCBB4527B4F6C600D0CC59 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/frmPrefWindow.strings"; sourceTree = "<group>"; };
|
||||||
|
@ -413,6 +413,14 @@
|
||||||
path = DataCompiler;
|
path = DataCompiler;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
5B16B84A28C9A88300ABA692 /* FolderMonitor */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
5B16B84B28C9A89000ABA692 /* FolderMonitor.swift */,
|
||||||
|
);
|
||||||
|
path = FolderMonitor;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
5B18BA7527C7BF6D0056EB19 /* MiscRootFiles */ = {
|
5B18BA7527C7BF6D0056EB19 /* MiscRootFiles */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -445,7 +453,6 @@
|
||||||
5BC447A428656A1900EDC323 /* KeyHandlerTestsNormalCHS.swift */,
|
5BC447A428656A1900EDC323 /* KeyHandlerTestsNormalCHS.swift */,
|
||||||
5BC447A328656A1900EDC323 /* KeyHandlerTestsSCPCCHT.swift */,
|
5BC447A328656A1900EDC323 /* KeyHandlerTestsSCPCCHT.swift */,
|
||||||
5BC447A228656A1900EDC323 /* PrefManagerTests.swift */,
|
5BC447A228656A1900EDC323 /* PrefManagerTests.swift */,
|
||||||
5BC447A528656A1900EDC323 /* UpdateAPITests.swift */,
|
|
||||||
);
|
);
|
||||||
path = vChewingTests;
|
path = vChewingTests;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -463,11 +470,21 @@
|
||||||
path = SubLMs;
|
path = SubLMs;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
5B5F8AEC28C86AB3007C11F1 /* NSAttributedTextView */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
5B5F8AEA28C86AAD007C11F1 /* NSAttributedTextView.swift */,
|
||||||
|
);
|
||||||
|
path = NSAttributedTextView;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
5B62A30127AE732800A19448 /* 3rdParty */ = {
|
5B62A30127AE732800A19448 /* 3rdParty */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
5B16B84A28C9A88300ABA692 /* FolderMonitor */,
|
||||||
5B84579B2871AD2200C93B01 /* HotenkaChineseConverter */,
|
5B84579B2871AD2200C93B01 /* HotenkaChineseConverter */,
|
||||||
5B949BD72816DC4400D87B5D /* LineReader */,
|
5B949BD72816DC4400D87B5D /* LineReader */,
|
||||||
|
5B5F8AEC28C86AB3007C11F1 /* NSAttributedTextView */,
|
||||||
5BA58644289BCFAC0077D02F /* Qwertyyb */,
|
5BA58644289BCFAC0077D02F /* Qwertyyb */,
|
||||||
5B20430528BEE2F300BFC6FD /* Sandbox */,
|
5B20430528BEE2F300BFC6FD /* Sandbox */,
|
||||||
5BA9FCEA27FED652002DE248 /* SindreSorhus */,
|
5BA9FCEA27FED652002DE248 /* SindreSorhus */,
|
||||||
|
@ -507,21 +524,13 @@
|
||||||
path = ControllerModules;
|
path = ControllerModules;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
5B62A32127AE755D00A19448 /* FileHandlers */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
5B62A32827AE77D100A19448 /* FSEventStreamHelper.swift */,
|
|
||||||
);
|
|
||||||
path = FileHandlers;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
5B62A32227AE756300A19448 /* IMEModules */ = {
|
5B62A32227AE756300A19448 /* IMEModules */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
5BDC1CF927FDF1310052C2B9 /* apiUpdate.swift */,
|
|
||||||
5B5E535127EF261400C6AA1E /* IME.swift */,
|
5B5E535127EF261400C6AA1E /* IME.swift */,
|
||||||
5B175FFA28C5CDDC0078D1B4 /* IMKHelper.swift */,
|
5B175FFA28C5CDDC0078D1B4 /* IMKHelper.swift */,
|
||||||
5B62A33527AE795800A19448 /* mgrPrefs.swift */,
|
5B62A33527AE795800A19448 /* mgrPrefs.swift */,
|
||||||
|
5BBC9EFB28CA042500041196 /* UpdateSputnik.swift */,
|
||||||
);
|
);
|
||||||
path = IMEModules;
|
path = IMEModules;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -610,7 +619,7 @@
|
||||||
5B62A34227AE7CD900A19448 /* TooltipUI */ = {
|
5B62A34227AE7CD900A19448 /* TooltipUI */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
5B62A34327AE7CD900A19448 /* TooltipController.swift */,
|
5B5F8AED28C8826D007C11F1 /* ctlTooltip.swift */,
|
||||||
);
|
);
|
||||||
path = TooltipUI;
|
path = TooltipUI;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -845,7 +854,6 @@
|
||||||
D427F76B278CA1BA004A2160 /* AppDelegate.swift */,
|
D427F76B278CA1BA004A2160 /* AppDelegate.swift */,
|
||||||
D47B92BF27972AC800458394 /* main.swift */,
|
D47B92BF27972AC800458394 /* main.swift */,
|
||||||
5B62A31F27AE74E900A19448 /* ControllerModules */,
|
5B62A31F27AE74E900A19448 /* ControllerModules */,
|
||||||
5B62A32127AE755D00A19448 /* FileHandlers */,
|
|
||||||
5B62A32227AE756300A19448 /* IMEModules */,
|
5B62A32227AE756300A19448 /* IMEModules */,
|
||||||
5B62A32427AE757300A19448 /* LangModelRelated */,
|
5B62A32427AE757300A19448 /* LangModelRelated */,
|
||||||
5B62A32327AE756800A19448 /* LanguageParsers */,
|
5B62A32327AE756800A19448 /* LanguageParsers */,
|
||||||
|
@ -1169,7 +1177,6 @@
|
||||||
files = (
|
files = (
|
||||||
5BC447A628656A1900EDC323 /* PrefManagerTests.swift in Sources */,
|
5BC447A628656A1900EDC323 /* PrefManagerTests.swift in Sources */,
|
||||||
5BC6E03C286692BE00291771 /* KeyHandlerTestsSCPCCHT.swift in Sources */,
|
5BC6E03C286692BE00291771 /* KeyHandlerTestsSCPCCHT.swift in Sources */,
|
||||||
5BC447A928656A1900EDC323 /* UpdateAPITests.swift in Sources */,
|
|
||||||
5BC447AE2865CFC200EDC323 /* KeyHandlerTestsNormalCHS.swift in Sources */,
|
5BC447AE2865CFC200EDC323 /* KeyHandlerTestsNormalCHS.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
@ -1195,6 +1202,7 @@
|
||||||
5B40730C281672610023DFFF /* lmAssociates.swift in Sources */,
|
5B40730C281672610023DFFF /* lmAssociates.swift in Sources */,
|
||||||
D427F76C278CA2B0004A2160 /* AppDelegate.swift in Sources */,
|
D427F76C278CA2B0004A2160 /* AppDelegate.swift in Sources */,
|
||||||
5BA9FD4527FEF3C9002DE248 /* ToolbarItemStyleViewController.swift in Sources */,
|
5BA9FD4527FEF3C9002DE248 /* ToolbarItemStyleViewController.swift in Sources */,
|
||||||
|
5BBC9EFC28CA042500041196 /* UpdateSputnik.swift in Sources */,
|
||||||
5BA9FD4127FEF3C8002DE248 /* PreferencesStyle.swift in Sources */,
|
5BA9FD4127FEF3C8002DE248 /* PreferencesStyle.swift in Sources */,
|
||||||
5B7F225D2808501000DDD3CB /* KeyHandler_HandleInput.swift in Sources */,
|
5B7F225D2808501000DDD3CB /* KeyHandler_HandleInput.swift in Sources */,
|
||||||
5BA9FD1227FEDB6B002DE248 /* suiPrefPaneExperience.swift in Sources */,
|
5BA9FD1227FEDB6B002DE248 /* suiPrefPaneExperience.swift in Sources */,
|
||||||
|
@ -1203,6 +1211,7 @@
|
||||||
D47B92C027972AD100458394 /* main.swift in Sources */,
|
D47B92C027972AD100458394 /* main.swift in Sources */,
|
||||||
D4A13D5A27A59F0B003BE359 /* ctlInputMethod_Core.swift in Sources */,
|
D4A13D5A27A59F0B003BE359 /* ctlInputMethod_Core.swift in Sources */,
|
||||||
5BA9FD4827FEF3C9002DE248 /* PreferencesWindowController.swift in Sources */,
|
5BA9FD4827FEF3C9002DE248 /* PreferencesWindowController.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 */,
|
||||||
5B21177028753B9D000443A9 /* ctlInputMethod_Delegates.swift in Sources */,
|
5B21177028753B9D000443A9 /* ctlInputMethod_Delegates.swift in Sources */,
|
||||||
|
@ -1211,6 +1220,7 @@
|
||||||
5B887F302826AEA400B6651E /* lmCoreEX.swift in Sources */,
|
5B887F302826AEA400B6651E /* lmCoreEX.swift in Sources */,
|
||||||
5BA9FD4627FEF3C9002DE248 /* Container.swift in Sources */,
|
5BA9FD4627FEF3C9002DE248 /* Container.swift in Sources */,
|
||||||
5B2170E5289FACAD00BE7304 /* 6_Node.swift in Sources */,
|
5B2170E5289FACAD00BE7304 /* 6_Node.swift in Sources */,
|
||||||
|
5B5F8AEB28C86AAD007C11F1 /* NSAttributedTextView.swift in Sources */,
|
||||||
5B949BD92816DC5400D87B5D /* LineReader.swift in Sources */,
|
5B949BD92816DC5400D87B5D /* LineReader.swift in Sources */,
|
||||||
5BA9FD1027FEDB6B002DE248 /* suiPrefPaneKeyboard.swift in Sources */,
|
5BA9FD1027FEDB6B002DE248 /* suiPrefPaneKeyboard.swift in Sources */,
|
||||||
5B3133BF280B229700A4A505 /* KeyHandler_States.swift in Sources */,
|
5B3133BF280B229700A4A505 /* KeyHandler_States.swift in Sources */,
|
||||||
|
@ -1233,7 +1243,7 @@
|
||||||
5B62A34A27AE7CD900A19448 /* NotifierController.swift in Sources */,
|
5B62A34A27AE7CD900A19448 /* NotifierController.swift in Sources */,
|
||||||
5B11328927B94CFB00E58451 /* AppleKeyboardConverter.swift in Sources */,
|
5B11328927B94CFB00E58451 /* AppleKeyboardConverter.swift in Sources */,
|
||||||
5B54E743283A7D89001ECBDC /* lmCoreNS.swift in Sources */,
|
5B54E743283A7D89001ECBDC /* lmCoreNS.swift in Sources */,
|
||||||
5B62A32927AE77D100A19448 /* FSEventStreamHelper.swift in Sources */,
|
5B16B84C28C9A89000ABA692 /* FolderMonitor.swift in Sources */,
|
||||||
5B2170E2289FACAD00BE7304 /* 8_Unigram.swift in Sources */,
|
5B2170E2289FACAD00BE7304 /* 8_Unigram.swift in Sources */,
|
||||||
5B21176C287539BB000443A9 /* ctlInputMethod_HandleStates.swift in Sources */,
|
5B21176C287539BB000443A9 /* ctlInputMethod_HandleStates.swift in Sources */,
|
||||||
5B62A33627AE795800A19448 /* mgrPrefs.swift in Sources */,
|
5B62A33627AE795800A19448 /* mgrPrefs.swift in Sources */,
|
||||||
|
@ -1251,7 +1261,6 @@
|
||||||
5B40730D281672610023DFFF /* lmReplacements.swift in Sources */,
|
5B40730D281672610023DFFF /* lmReplacements.swift in Sources */,
|
||||||
5B5E535227EF261400C6AA1E /* IME.swift in Sources */,
|
5B5E535227EF261400C6AA1E /* IME.swift in Sources */,
|
||||||
5B2170E0289FACAD00BE7304 /* 7_LangModel.swift in Sources */,
|
5B2170E0289FACAD00BE7304 /* 7_LangModel.swift in Sources */,
|
||||||
5B62A34927AE7CD900A19448 /* TooltipController.swift in Sources */,
|
|
||||||
5BA9FD4027FEF3C8002DE248 /* Localization.swift in Sources */,
|
5BA9FD4027FEF3C8002DE248 /* Localization.swift in Sources */,
|
||||||
5BF0B84C28C070B000795FC6 /* NSEventExtension.swift in Sources */,
|
5BF0B84C28C070B000795FC6 /* NSEventExtension.swift in Sources */,
|
||||||
5BAA8FBE282CAF380066C406 /* SyllableComposer.swift in Sources */,
|
5BAA8FBE282CAF380066C406 /* SyllableComposer.swift in Sources */,
|
||||||
|
@ -1267,7 +1276,6 @@
|
||||||
5BA9FD3F27FEF3C8002DE248 /* Pane.swift in Sources */,
|
5BA9FD3F27FEF3C8002DE248 /* Pane.swift in Sources */,
|
||||||
5BB802DA27FABA8300CF1C19 /* ctlInputMethod_Menu.swift in Sources */,
|
5BB802DA27FABA8300CF1C19 /* ctlInputMethod_Menu.swift in Sources */,
|
||||||
5BE377A0288FED8D0037365B /* KeyHandler_HandleComposition.swift in Sources */,
|
5BE377A0288FED8D0037365B /* KeyHandler_HandleComposition.swift in Sources */,
|
||||||
5BDC1CFA27FDF1310052C2B9 /* apiUpdate.swift in Sources */,
|
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -1455,7 +1463,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 = 2402;
|
CURRENT_PROJECT_VERSION = 2500;
|
||||||
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 = (
|
||||||
|
@ -1465,7 +1473,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.4.0;
|
MARKETING_VERSION = 2.5.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;
|
||||||
|
@ -1494,13 +1502,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 = 2402;
|
CURRENT_PROJECT_VERSION = 2500;
|
||||||
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.4.0;
|
MARKETING_VERSION = 2.5.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;
|
||||||
|
@ -1532,7 +1540,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 = 2402;
|
CURRENT_PROJECT_VERSION = 2500;
|
||||||
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;
|
||||||
|
@ -1554,7 +1562,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 2.4.0;
|
MARKETING_VERSION = 2.5.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;
|
||||||
|
@ -1584,7 +1592,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 = 2402;
|
CURRENT_PROJECT_VERSION = 2500;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
|
@ -1602,7 +1610,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 2.4.0;
|
MARKETING_VERSION = 2.5.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;
|
||||||
|
@ -1718,7 +1726,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 = 2402;
|
CURRENT_PROJECT_VERSION = 2500;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEVELOPMENT_ASSET_PATHS = "";
|
DEVELOPMENT_ASSET_PATHS = "";
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
|
@ -1747,7 +1755,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 2.4.0;
|
MARKETING_VERSION = 2.5.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)";
|
||||||
|
@ -1777,7 +1785,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 = 2402;
|
CURRENT_PROJECT_VERSION = 2500;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEVELOPMENT_ASSET_PATHS = "";
|
DEVELOPMENT_ASSET_PATHS = "";
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
|
@ -1800,7 +1808,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 2.4.0;
|
MARKETING_VERSION = 2.5.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 = "";
|
||||||
|
@ -1824,7 +1832,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 = 2402;
|
CURRENT_PROJECT_VERSION = 2500;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
|
@ -1845,7 +1853,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 2.4.0;
|
MARKETING_VERSION = 2.5.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)";
|
||||||
|
@ -1868,7 +1876,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 = 2402;
|
CURRENT_PROJECT_VERSION = 2500;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
|
@ -1883,7 +1891,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 2.4.0;
|
MARKETING_VERSION = 2.5.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 = "";
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
// (c) 2021 and onwards Zonble Yang (MIT-NTL License).
|
|
||||||
// All possible vChewing-specific modifications are of:
|
|
||||||
// (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 XCTest
|
|
||||||
|
|
||||||
@testable import vChewing
|
|
||||||
|
|
||||||
class VersionUpdateApiTests: XCTestCase {
|
|
||||||
func testFetchVersionUpdateInfo() {
|
|
||||||
let exp = expectation(description: "wait for 3 seconds")
|
|
||||||
_ = VersionUpdateApi.check(forced: true) { result in
|
|
||||||
exp.fulfill()
|
|
||||||
switch result {
|
|
||||||
case .success:
|
|
||||||
break
|
|
||||||
case .failure(let error):
|
|
||||||
XCTFail(error.localizedDescription)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
wait(for: [exp], timeout: 20.0)
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue