Repo // Introducing reverse-lookup window.
This commit is contained in:
parent
9ec8428af6
commit
892a574378
|
@ -0,0 +1,193 @@
|
||||||
|
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
||||||
|
// ====================
|
||||||
|
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
|
||||||
|
// ... with NTL restriction stating that:
|
||||||
|
// No trademark license is granted to use the trade names, trademarks, service
|
||||||
|
// marks, or product names of Contributor, except as required to fulfill notice
|
||||||
|
// requirements defined in MIT License.
|
||||||
|
|
||||||
|
import Cocoa
|
||||||
|
import LangModelAssembly
|
||||||
|
|
||||||
|
class CtlRevLookupWindow: NSWindowController, NSWindowDelegate {
|
||||||
|
static var shared: CtlRevLookupWindow?
|
||||||
|
|
||||||
|
static func show() {
|
||||||
|
if shared == nil { Self.shared = .init(window: FrmRevLookupWindow()) }
|
||||||
|
guard let shared = Self.shared, let window = shared.window as? FrmRevLookupWindow else { return }
|
||||||
|
shared.window = window
|
||||||
|
window.delegate = shared
|
||||||
|
window.setPosition(vertical: .bottom, horizontal: .right, padding: 20)
|
||||||
|
window.orderFrontRegardless() // 逼著視窗往最前方顯示
|
||||||
|
window.level = .statusBar
|
||||||
|
window.titlebarAppearsTransparent = true
|
||||||
|
shared.showWindow(shared)
|
||||||
|
NSApp.activate(ignoringOtherApps: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FrmRevLookupWindow: NSWindow {
|
||||||
|
typealias LMRevLookup = vChewingLM.LMRevLookup
|
||||||
|
|
||||||
|
static let lmRevLookupCore = LMRevLookup(path: LMMgr.getBundleDataPath("data-bpmf-reverse-lookup"))
|
||||||
|
|
||||||
|
// 全字庫資料接近十萬筆索引,只放到單個 Dictionary 內的話、每次查詢時都會把輸入法搞崩潰。只能分卷處理。
|
||||||
|
static let lmRevLookupCNS1 = LMRevLookup(path: LMMgr.getBundleDataPath("data-bpmf-reverse-lookup-CNS1"))
|
||||||
|
static let lmRevLookupCNS2 = LMRevLookup(path: LMMgr.getBundleDataPath("data-bpmf-reverse-lookup-CNS2"))
|
||||||
|
static let lmRevLookupCNS3 = LMRevLookup(path: LMMgr.getBundleDataPath("data-bpmf-reverse-lookup-CNS3"))
|
||||||
|
static let lmRevLookupCNS4 = LMRevLookup(path: LMMgr.getBundleDataPath("data-bpmf-reverse-lookup-CNS4"))
|
||||||
|
static let lmRevLookupCNS5 = LMRevLookup(path: LMMgr.getBundleDataPath("data-bpmf-reverse-lookup-CNS5"))
|
||||||
|
static let lmRevLookupCNS6 = LMRevLookup(path: LMMgr.getBundleDataPath("data-bpmf-reverse-lookup-CNS6"))
|
||||||
|
|
||||||
|
public lazy var inputField = NSTextField()
|
||||||
|
public lazy var resultView = NSTextView()
|
||||||
|
private lazy var clipView = NSClipView()
|
||||||
|
private lazy var scrollView = NSScrollView()
|
||||||
|
private lazy var button = NSButton()
|
||||||
|
private lazy var view = NSView()
|
||||||
|
|
||||||
|
init() {
|
||||||
|
super.init(
|
||||||
|
contentRect: CGRect(x: 196, y: 240, width: 480, height: 340),
|
||||||
|
styleMask: [.titled, .closable],
|
||||||
|
backing: .buffered, defer: true
|
||||||
|
)
|
||||||
|
setupUI()
|
||||||
|
setupLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
private func setupUI() {
|
||||||
|
contentView = view
|
||||||
|
|
||||||
|
allowsToolTipsWhenApplicationIsInactive = false
|
||||||
|
autorecalculatesKeyViewLoop = false
|
||||||
|
isReleasedWhenClosed = false
|
||||||
|
title = "Reverse Lookup (Phonabets)".localized
|
||||||
|
|
||||||
|
view.addSubview(inputField)
|
||||||
|
view.addSubview(scrollView)
|
||||||
|
view.addSubview(button)
|
||||||
|
|
||||||
|
view.wantsLayer = true
|
||||||
|
|
||||||
|
button.setContentHuggingPriority(.defaultHigh, for: .vertical)
|
||||||
|
button.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
button.alignment = .center
|
||||||
|
button.bezelStyle = .recessed
|
||||||
|
button.font = NSFont.systemFont(ofSize: 12, weight: .bold)
|
||||||
|
button.imageScaling = .scaleProportionallyDown
|
||||||
|
button.title = "👓"
|
||||||
|
button.cell.map { $0 as? NSButtonCell }??.isBordered = true
|
||||||
|
button.target = self
|
||||||
|
button.action = #selector(keyboardConfirmed(_:))
|
||||||
|
button.keyEquivalent = String(utf16CodeUnits: [unichar(NSEvent.SpecialKey.enter.rawValue)], count: 1) as String
|
||||||
|
|
||||||
|
scrollView.borderType = .noBorder
|
||||||
|
scrollView.hasHorizontalScroller = false
|
||||||
|
scrollView.horizontalLineScroll = 10
|
||||||
|
scrollView.horizontalPageScroll = 10
|
||||||
|
scrollView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
scrollView.verticalLineScroll = 10
|
||||||
|
scrollView.verticalPageScroll = 10
|
||||||
|
|
||||||
|
clipView.documentView = resultView
|
||||||
|
|
||||||
|
clipView.autoresizingMask = [.width, .height]
|
||||||
|
clipView.drawsBackground = false
|
||||||
|
clipView.frame = CGRect(x: 0, y: 0, width: 480, height: 320)
|
||||||
|
|
||||||
|
resultView.autoresizingMask = [.width, .height]
|
||||||
|
resultView.backgroundColor = NSColor.textBackgroundColor
|
||||||
|
resultView.frame = CGRect(x: 0, y: 0, width: 480, height: 320)
|
||||||
|
resultView.importsGraphics = false
|
||||||
|
resultView.insertionPointColor = NSColor.textColor
|
||||||
|
resultView.isEditable = false
|
||||||
|
resultView.isRichText = false
|
||||||
|
resultView.isVerticallyResizable = true
|
||||||
|
resultView.maxSize = CGSize(width: 774, height: 10_000_000)
|
||||||
|
resultView.minSize = CGSize(width: 480, height: 320)
|
||||||
|
resultView.smartInsertDeleteEnabled = true
|
||||||
|
resultView.textColor = NSColor.textColor
|
||||||
|
resultView.wantsLayer = true
|
||||||
|
resultView.font = NSFont.systemFont(ofSize: 13)
|
||||||
|
resultView.string = "Maximum 15 results returnable.".localized
|
||||||
|
|
||||||
|
scrollView.contentView = clipView
|
||||||
|
|
||||||
|
inputField.setContentHuggingPriority(.defaultHigh, for: .vertical)
|
||||||
|
inputField.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
inputField.backgroundColor = NSColor.textBackgroundColor
|
||||||
|
inputField.drawsBackground = true
|
||||||
|
inputField.font = NSFont.systemFont(ofSize: 13)
|
||||||
|
inputField.isBezeled = true
|
||||||
|
inputField.isEditable = true
|
||||||
|
inputField.isSelectable = true
|
||||||
|
inputField.lineBreakMode = .byClipping
|
||||||
|
inputField.textColor = NSColor.controlTextColor
|
||||||
|
inputField.cell.map { $0 as? NSTextFieldCell }??.isScrollable = true
|
||||||
|
inputField.cell.map { $0 as? NSTextFieldCell }??.sendsActionOnEndEditing = true
|
||||||
|
inputField.cell.map { $0 as? NSTextFieldCell }??.usesSingleLineMode = true
|
||||||
|
inputField.action = #selector(keyboardConfirmed(_:))
|
||||||
|
inputField.toolTip =
|
||||||
|
"Maximum 15 results returnable.".localized
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc func keyboardConfirmed(_: Any?) {
|
||||||
|
if inputField.stringValue.isEmpty { return }
|
||||||
|
resultView.string = "\n" + "Loading…".localized
|
||||||
|
DispatchQueue.main.async { [self] in
|
||||||
|
self.updateResult(with: self.inputField.stringValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func updateResult(with input: String) {
|
||||||
|
guard !input.isEmpty else { return }
|
||||||
|
button.isEnabled = false
|
||||||
|
inputField.isEnabled = false
|
||||||
|
let strBuilder = NSMutableString()
|
||||||
|
strBuilder.append("\n")
|
||||||
|
strBuilder.append("Char\tReading(s)\n".localized)
|
||||||
|
strBuilder.append("==\t====\n")
|
||||||
|
var i = 0
|
||||||
|
theLoop: for char in input.charComponents {
|
||||||
|
if i == 15 {
|
||||||
|
strBuilder.append("Maximum 15 results returnable.".localized + "\n")
|
||||||
|
break theLoop
|
||||||
|
}
|
||||||
|
var arrResult = Self.lmRevLookupCore.query(with: char) ?? []
|
||||||
|
// 一般情況下,威注音語彙庫的倉庫內的全字庫資料檔案有做過排序,所以每個分卷的索引都是不重複的。
|
||||||
|
arrResult +=
|
||||||
|
Self.lmRevLookupCNS1.query(with: char)
|
||||||
|
?? Self.lmRevLookupCNS2.query(with: char)
|
||||||
|
?? Self.lmRevLookupCNS3.query(with: char)
|
||||||
|
?? Self.lmRevLookupCNS4.query(with: char)
|
||||||
|
?? Self.lmRevLookupCNS5.query(with: char)
|
||||||
|
?? Self.lmRevLookupCNS6.query(with: char)
|
||||||
|
?? []
|
||||||
|
arrResult = arrResult.deduplicated
|
||||||
|
if !arrResult.isEmpty {
|
||||||
|
strBuilder.append(char + "\t")
|
||||||
|
strBuilder.append(arrResult.joined(separator: ", "))
|
||||||
|
strBuilder.append("\n")
|
||||||
|
i += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resultView.string = strBuilder.description
|
||||||
|
button.isEnabled = true
|
||||||
|
inputField.isEnabled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
private func setupLayout() {
|
||||||
|
inputField.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
|
||||||
|
button.leadingAnchor.constraint(equalTo: inputField.trailingAnchor, constant: 5).isActive = true
|
||||||
|
scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant: 20).isActive = true
|
||||||
|
inputField.lastBaselineAnchor.constraint(equalTo: button.lastBaselineAnchor).isActive = true
|
||||||
|
scrollView.topAnchor.constraint(equalTo: button.bottomAnchor).isActive = true
|
||||||
|
view.trailingAnchor.constraint(equalTo: button.trailingAnchor, constant: 3).isActive = true
|
||||||
|
inputField.topAnchor.constraint(equalTo: button.topAnchor).isActive = true
|
||||||
|
view.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
|
||||||
|
view.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
|
||||||
|
inputField.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
|
||||||
|
inputField.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,6 +16,10 @@
|
||||||
"Loading…" = "Loading…";
|
"Loading…" = "Loading…";
|
||||||
"Consolidate" = "Consolidate";
|
"Consolidate" = "Consolidate";
|
||||||
"Reload" = "Reload";
|
"Reload" = "Reload";
|
||||||
|
"Loading complete." = "Loading complete.";
|
||||||
|
"Char\tReading(s)\n" = "Char\tReading(s)\n";
|
||||||
|
"Reverse Lookup (Phonabets)" = "Reverse Lookup (Phonabets)";
|
||||||
|
"Maximum 15 results returnable." = "Maximum 15 results returnable.";
|
||||||
"Example:\nCandidate Reading-Reading #Comment" = "Example:\nCandidate Reading-Reading #Comment";
|
"Example:\nCandidate Reading-Reading #Comment" = "Example:\nCandidate Reading-Reading #Comment";
|
||||||
"Example:\nCandidate Reading-Reading Weight #Comment\nCandidate Reading-Reading #Comment" = "Example:\nCandidate Reading-Reading Weight #Comment\nCandidate Reading-Reading #Comment";
|
"Example:\nCandidate Reading-Reading Weight #Comment\nCandidate Reading-Reading #Comment" = "Example:\nCandidate Reading-Reading Weight #Comment\nCandidate Reading-Reading #Comment";
|
||||||
"Example:\nInitial RestPhrase\nInitial RestPhrase1 RestPhrase2 RestPhrase3..." = "Example:\nInitial RestPhrase\nInitial RestPhrase1 RestPhrase2 RestPhrase3...";
|
"Example:\nInitial RestPhrase\nInitial RestPhrase1 RestPhrase2 RestPhrase3..." = "Example:\nInitial RestPhrase\nInitial RestPhrase1 RestPhrase2 RestPhrase3...";
|
||||||
|
|
|
@ -16,6 +16,10 @@
|
||||||
"Loading…" = "Loading…";
|
"Loading…" = "Loading…";
|
||||||
"Consolidate" = "Consolidate";
|
"Consolidate" = "Consolidate";
|
||||||
"Reload" = "Reload";
|
"Reload" = "Reload";
|
||||||
|
"Loading complete." = "Loading complete.";
|
||||||
|
"Char\tReading(s)\n" = "Char\tReading(s)\n";
|
||||||
|
"Reverse Lookup (Phonabets)" = "Reverse Lookup (Phonabets)";
|
||||||
|
"Maximum 15 results returnable." = "Maximum 15 results returnable.";
|
||||||
"Example:\nCandidate Reading-Reading #Comment" = "Example:\nCandidate Reading-Reading #Comment";
|
"Example:\nCandidate Reading-Reading #Comment" = "Example:\nCandidate Reading-Reading #Comment";
|
||||||
"Example:\nCandidate Reading-Reading Weight #Comment\nCandidate Reading-Reading #Comment" = "Example:\nCandidate Reading-Reading Weight #Comment\nCandidate Reading-Reading #Comment";
|
"Example:\nCandidate Reading-Reading Weight #Comment\nCandidate Reading-Reading #Comment" = "Example:\nCandidate Reading-Reading Weight #Comment\nCandidate Reading-Reading #Comment";
|
||||||
"Example:\nInitial RestPhrase\nInitial RestPhrase1 RestPhrase2 RestPhrase3..." = "Example:\nInitial RestPhrase\nInitial RestPhrase1 RestPhrase2 RestPhrase3...";
|
"Example:\nInitial RestPhrase\nInitial RestPhrase1 RestPhrase2 RestPhrase3..." = "Example:\nInitial RestPhrase\nInitial RestPhrase1 RestPhrase2 RestPhrase3...";
|
||||||
|
|
|
@ -16,6 +16,10 @@
|
||||||
"Loading…" = "読み込む中…";
|
"Loading…" = "読み込む中…";
|
||||||
"Consolidate" = "整理";
|
"Consolidate" = "整理";
|
||||||
"Reload" = "再読込";
|
"Reload" = "再読込";
|
||||||
|
"Loading complete." = "読込完了。";
|
||||||
|
"Char\tReading(s)\n" = "漢字\t音読\n";
|
||||||
|
"Reverse Lookup (Phonabets)" = "注音音読逆引参照";
|
||||||
|
"Maximum 15 results returnable." = "参照結果は最初の15件のみ表示可能。";
|
||||||
"Example:\nCandidate Reading-Reading #Comment" = "【模範例】\n候補 音読-音読 #メモ";
|
"Example:\nCandidate Reading-Reading #Comment" = "【模範例】\n候補 音読-音読 #メモ";
|
||||||
"Example:\nCandidate Reading-Reading Weight #Comment\nCandidate Reading-Reading #Comment" = "【模範例】\n候補 音読-音読 優先度 #メモ\n候補 音読-音読 #メモ";
|
"Example:\nCandidate Reading-Reading Weight #Comment\nCandidate Reading-Reading #Comment" = "【模範例】\n候補 音読-音読 優先度 #メモ\n候補 音読-音読 #メモ";
|
||||||
"Example:\nInitial RestPhrase\nInitial RestPhrase1 RestPhrase2 RestPhrase3..." = "【模範例】\n頭文字 残候補\n頭文字 残候補1 残候補2 残候補3...";
|
"Example:\nInitial RestPhrase\nInitial RestPhrase1 RestPhrase2 RestPhrase3..." = "【模範例】\n頭文字 残候補\n頭文字 残候補1 残候補2 残候補3...";
|
||||||
|
|
|
@ -16,6 +16,10 @@
|
||||||
"Loading…" = "正在载入…";
|
"Loading…" = "正在载入…";
|
||||||
"Consolidate" = "整理";
|
"Consolidate" = "整理";
|
||||||
"Reload" = "重新载入";
|
"Reload" = "重新载入";
|
||||||
|
"Loading complete." = "载入完毕。";
|
||||||
|
"Char\tReading(s)\n" = "汉字\t读音\n";
|
||||||
|
"Reverse Lookup (Phonabets)" = "注音反查";
|
||||||
|
"Maximum 15 results returnable." = "仅能给出前 15 笔结果。";
|
||||||
"Example:\nCandidate Reading-Reading #Comment" = "【范例】\n候选字词 读音-读音 #注解";
|
"Example:\nCandidate Reading-Reading #Comment" = "【范例】\n候选字词 读音-读音 #注解";
|
||||||
"Example:\nCandidate Reading-Reading Weight #Comment\nCandidate Reading-Reading #Comment" = "【范例】\n候选字词 读音-读音 权重 #注解\n候选字词 读音-读音 #注解";
|
"Example:\nCandidate Reading-Reading Weight #Comment\nCandidate Reading-Reading #Comment" = "【范例】\n候选字词 读音-读音 权重 #注解\n候选字词 读音-读音 #注解";
|
||||||
"Example:\nInitial RestPhrase\nInitial RestPhrase1 RestPhrase2 RestPhrase3..." = "【范例】\n首字 候选\n首字 候选1 候选2 候选3...";
|
"Example:\nInitial RestPhrase\nInitial RestPhrase1 RestPhrase2 RestPhrase3..." = "【范例】\n首字 候选\n首字 候选1 候选2 候选3...";
|
||||||
|
|
|
@ -16,6 +16,10 @@
|
||||||
"Loading…" = "正在載入…";
|
"Loading…" = "正在載入…";
|
||||||
"Consolidate" = "整理";
|
"Consolidate" = "整理";
|
||||||
"Reload" = "重新載入";
|
"Reload" = "重新載入";
|
||||||
|
"Loading complete." = "載入完畢。";
|
||||||
|
"Char\tReading(s)\n" = "漢字\t讀音\n";
|
||||||
|
"Reverse Lookup (Phonabets)" = "注音反查";
|
||||||
|
"Maximum 15 results returnable." = "僅能給出前 15 筆結果。";
|
||||||
"Example:\nCandidate Reading-Reading #Comment" = "【範例】\n候選字詞 讀音-讀音 #註解";
|
"Example:\nCandidate Reading-Reading #Comment" = "【範例】\n候選字詞 讀音-讀音 #註解";
|
||||||
"Example:\nCandidate Reading-Reading Weight #Comment\nCandidate Reading-Reading #Comment" = "【範例】\n候選字詞 讀音-讀音 權重 #註解\n候選字詞 讀音-讀音 #註解";
|
"Example:\nCandidate Reading-Reading Weight #Comment\nCandidate Reading-Reading #Comment" = "【範例】\n候選字詞 讀音-讀音 權重 #註解\n候選字詞 讀音-讀音 #註解";
|
||||||
"Example:\nInitial RestPhrase\nInitial RestPhrase1 RestPhrase2 RestPhrase3..." = "【範例】\n首字 候選\n首字 候選1 候選2 候選3...";
|
"Example:\nInitial RestPhrase\nInitial RestPhrase1 RestPhrase2 RestPhrase3..." = "【範例】\n首字 候選\n首字 候選1 候選2 候選3...";
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
5B253E822945AF6700680C67 /* data-bpmf-reverse-lookup-CNS4.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5B253E7C2945AF6700680C67 /* data-bpmf-reverse-lookup-CNS4.plist */; };
|
5B253E822945AF6700680C67 /* data-bpmf-reverse-lookup-CNS4.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5B253E7C2945AF6700680C67 /* data-bpmf-reverse-lookup-CNS4.plist */; };
|
||||||
5B253E832945AF6700680C67 /* data-bpmf-reverse-lookup-CNS5.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5B253E7D2945AF6700680C67 /* data-bpmf-reverse-lookup-CNS5.plist */; };
|
5B253E832945AF6700680C67 /* data-bpmf-reverse-lookup-CNS5.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5B253E7D2945AF6700680C67 /* data-bpmf-reverse-lookup-CNS5.plist */; };
|
||||||
5B2E009428FD1E8100E78D6E /* VwrPrefPaneCassette.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B2E009328FD1E8100E78D6E /* VwrPrefPaneCassette.swift */; };
|
5B2E009428FD1E8100E78D6E /* VwrPrefPaneCassette.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B2E009328FD1E8100E78D6E /* VwrPrefPaneCassette.swift */; };
|
||||||
|
5B30BF282944867800BD87A9 /* CtlRevLookupWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B30BF272944867800BD87A9 /* CtlRevLookupWindow.swift */; };
|
||||||
5B3133BF280B229700A4A505 /* InputHandler_HandleStates.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B3133BE280B229700A4A505 /* InputHandler_HandleStates.swift */; };
|
5B3133BF280B229700A4A505 /* InputHandler_HandleStates.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B3133BE280B229700A4A505 /* InputHandler_HandleStates.swift */; };
|
||||||
5B40113928D7050D00A9D4CB /* Shared in Frameworks */ = {isa = PBXBuildFile; productRef = 5B40113828D7050D00A9D4CB /* Shared */; };
|
5B40113928D7050D00A9D4CB /* Shared in Frameworks */ = {isa = PBXBuildFile; productRef = 5B40113828D7050D00A9D4CB /* Shared */; };
|
||||||
5B40113C28D71C0100A9D4CB /* Uninstaller in Frameworks */ = {isa = PBXBuildFile; productRef = 5B40113B28D71C0100A9D4CB /* Uninstaller */; };
|
5B40113C28D71C0100A9D4CB /* Uninstaller in Frameworks */ = {isa = PBXBuildFile; productRef = 5B40113B28D71C0100A9D4CB /* Uninstaller */; };
|
||||||
|
@ -215,6 +216,7 @@
|
||||||
5B2DB17127AF8771006D874E /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; name = Makefile; path = Data/Makefile; sourceTree = "<group>"; };
|
5B2DB17127AF8771006D874E /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; name = Makefile; path = Data/Makefile; sourceTree = "<group>"; };
|
||||||
5B2E009328FD1E8100E78D6E /* VwrPrefPaneCassette.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VwrPrefPaneCassette.swift; sourceTree = "<group>"; };
|
5B2E009328FD1E8100E78D6E /* VwrPrefPaneCassette.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VwrPrefPaneCassette.swift; sourceTree = "<group>"; };
|
||||||
5B2F2BB3286216A500B8557B /* vChewingTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = vChewingTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
5B2F2BB3286216A500B8557B /* vChewingTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = vChewingTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
5B30BF272944867800BD87A9 /* CtlRevLookupWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CtlRevLookupWindow.swift; sourceTree = "<group>"; };
|
||||||
5B30F11227BA568800484E24 /* vChewingKeyLayout.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = vChewingKeyLayout.bundle; sourceTree = "<group>"; };
|
5B30F11227BA568800484E24 /* vChewingKeyLayout.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = vChewingKeyLayout.bundle; sourceTree = "<group>"; };
|
||||||
5B312684287800DE001AA720 /* FAQ.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = FAQ.md; sourceTree = "<group>"; };
|
5B312684287800DE001AA720 /* FAQ.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = FAQ.md; sourceTree = "<group>"; };
|
||||||
5B3133BE280B229700A4A505 /* InputHandler_HandleStates.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = InputHandler_HandleStates.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
5B3133BE280B229700A4A505 /* InputHandler_HandleStates.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = InputHandler_HandleStates.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
|
||||||
|
@ -470,6 +472,7 @@
|
||||||
5B0EF55E28CDBF8E00F8F7CE /* CtlClientListMgr.swift */,
|
5B0EF55E28CDBF8E00F8F7CE /* CtlClientListMgr.swift */,
|
||||||
D47F7DCD278BFB57002F9DD7 /* CtlPrefWindow.swift */,
|
D47F7DCD278BFB57002F9DD7 /* CtlPrefWindow.swift */,
|
||||||
5BCC631529407BBB00A2D84F /* CtlPrefWindow_PhraseEditor.swift */,
|
5BCC631529407BBB00A2D84F /* CtlPrefWindow_PhraseEditor.swift */,
|
||||||
|
5B30BF272944867800BD87A9 /* CtlRevLookupWindow.swift */,
|
||||||
);
|
);
|
||||||
path = WindowControllers;
|
path = WindowControllers;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -1090,6 +1093,7 @@
|
||||||
5B78EE0D28A562B4009456C1 /* VwrPrefPaneDevZone.swift in Sources */,
|
5B78EE0D28A562B4009456C1 /* VwrPrefPaneDevZone.swift in Sources */,
|
||||||
5B6C141228A9D4B30098ADF8 /* SessionCtl_HandleEvent.swift in Sources */,
|
5B6C141228A9D4B30098ADF8 /* SessionCtl_HandleEvent.swift in Sources */,
|
||||||
D47F7DCE278BFB57002F9DD7 /* CtlPrefWindow.swift in Sources */,
|
D47F7DCE278BFB57002F9DD7 /* CtlPrefWindow.swift in Sources */,
|
||||||
|
5B30BF282944867800BD87A9 /* CtlRevLookupWindow.swift in Sources */,
|
||||||
5BD0113D2818543900609769 /* InputHandler_Core.swift in Sources */,
|
5BD0113D2818543900609769 /* InputHandler_Core.swift in Sources */,
|
||||||
5BF56F9A28C39D1800DD6839 /* IMEStateData.swift in Sources */,
|
5BF56F9A28C39D1800DD6839 /* IMEStateData.swift in Sources */,
|
||||||
5B21176C287539BB000443A9 /* SessionCtl_HandleStates.swift in Sources */,
|
5B21176C287539BB000443A9 /* SessionCtl_HandleStates.swift in Sources */,
|
||||||
|
|
Loading…
Reference in New Issue