Merge pull request #227 from zonble/master
Adds a new setting: Chinese conversion style
This commit is contained in:
commit
01378b8091
|
@ -51,6 +51,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NonModalAlertWindowControlle
|
|||
private var updateNextStepURL: URL?
|
||||
|
||||
func applicationDidFinishLaunching(_ notification: Notification) {
|
||||
LanguageModelManager.setupDataModelValueConverter()
|
||||
LanguageModelManager.loadDataModels()
|
||||
LanguageModelManager.loadUserPhrases()
|
||||
LanguageModelManager.loadUserPhraseReplacement()
|
||||
|
|
|
@ -19,14 +19,14 @@
|
|||
<window title="Bopomofo Preferences" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" animationBehavior="default" id="1" userLabel="Window - Preferences">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="401" y="295" width="475" height="438"/>
|
||||
<rect key="contentRect" x="401" y="295" width="475" height="484"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1055"/>
|
||||
<view key="contentView" id="2">
|
||||
<rect key="frame" x="0.0" y="0.0" width="475" height="438"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="475" height="484"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="11">
|
||||
<rect key="frame" x="38" y="400" width="183" height="17"/>
|
||||
<rect key="frame" x="38" y="446" width="183" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Bopomofo Keyboard Layout:" id="12">
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -35,7 +35,7 @@
|
|||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="124">
|
||||
<rect key="frame" x="225" y="363" width="156" height="26"/>
|
||||
<rect key="frame" x="225" y="409" width="156" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="127">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
|
@ -47,7 +47,7 @@
|
|||
</connections>
|
||||
</popUpButton>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="125">
|
||||
<rect key="frame" x="16" y="369" width="205" height="17"/>
|
||||
<rect key="frame" x="16" y="415" width="205" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Alphanumeric Keyboard Layout:" id="126">
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -56,7 +56,7 @@
|
|||
</textFieldCell>
|
||||
</textField>
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="109">
|
||||
<rect key="frame" x="226" y="309" width="217" height="18"/>
|
||||
<rect key="frame" x="226" y="355" width="217" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Space key chooses candidate" bezelStyle="regularSquare" imagePosition="left" alignment="left" state="on" inset="2" id="110">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
|
@ -67,7 +67,7 @@
|
|||
</connections>
|
||||
</button>
|
||||
<comboBox verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="uHU-aL-du7">
|
||||
<rect key="frame" x="228" y="336" width="209" height="25"/>
|
||||
<rect key="frame" x="228" y="382" width="209" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<comboBoxCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" completes="NO" numberOfVisibleItems="5" id="jQC-12-UuK">
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -84,7 +84,7 @@
|
|||
</connections>
|
||||
</comboBox>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ETa-09-qWI">
|
||||
<rect key="frame" x="38" y="342" width="183" height="16"/>
|
||||
<rect key="frame" x="38" y="388" width="183" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Selection Keys:" id="FnD-oH-El5">
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -93,7 +93,7 @@
|
|||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3">
|
||||
<rect key="frame" x="225" y="394" width="132" height="26"/>
|
||||
<rect key="frame" x="225" y="440" width="132" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Standard" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="6" id="4">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
|
@ -114,7 +114,7 @@
|
|||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="bE0-Lq-Pj7">
|
||||
<rect key="frame" x="226" y="287" width="229" height="18"/>
|
||||
<rect key="frame" x="226" y="333" width="229" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="ESC key clears entire input buffer" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="f2j-xD-4xK">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
|
@ -125,7 +125,7 @@
|
|||
</connections>
|
||||
</button>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="13">
|
||||
<rect key="frame" x="63" y="252" width="155" height="17"/>
|
||||
<rect key="frame" x="63" y="298" width="155" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Show Candidate Phrase:" id="14">
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -134,7 +134,7 @@
|
|||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="23">
|
||||
<rect key="frame" x="80" y="206" width="138" height="17"/>
|
||||
<rect key="frame" x="80" y="252" width="138" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Candidate List Style:" id="24">
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -143,7 +143,7 @@
|
|||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="28">
|
||||
<rect key="frame" x="84" y="159" width="134" height="17"/>
|
||||
<rect key="frame" x="84" y="205" width="134" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Candidate Text Size:" id="29">
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -152,7 +152,7 @@
|
|||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="MBE-hh-AxG">
|
||||
<rect key="frame" x="45" y="103" width="173" height="17"/>
|
||||
<rect key="frame" x="48" y="41" width="173" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Chinese Conversion Engine:" id="hwF-gg-TYW">
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -161,7 +161,7 @@
|
|||
</textFieldCell>
|
||||
</textField>
|
||||
<matrix verticalHuggingPriority="750" fixedFrame="YES" tag="1" allowsEmptySelection="NO" translatesAutoresizingMaskIntoConstraints="NO" id="15">
|
||||
<rect key="frame" x="227" y="231" width="213" height="38"/>
|
||||
<rect key="frame" x="227" y="277" width="213" height="38"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
<size key="cellSize" width="206" height="18"/>
|
||||
|
@ -187,7 +187,7 @@
|
|||
</connections>
|
||||
</matrix>
|
||||
<matrix verticalHuggingPriority="750" fixedFrame="YES" tag="1" allowsEmptySelection="NO" translatesAutoresizingMaskIntoConstraints="NO" id="rAU-Xz-M2R">
|
||||
<rect key="frame" x="227" y="82" width="213" height="38"/>
|
||||
<rect key="frame" x="227" y="20" width="213" height="38"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
<size key="cellSize" width="206" height="18"/>
|
||||
|
@ -212,8 +212,43 @@
|
|||
<binding destination="32" name="selectedTag" keyPath="values.ChineseConversionEngine" id="qf2-qK-OJ0"/>
|
||||
</connections>
|
||||
</matrix>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2Lk-JF-I6D">
|
||||
<rect key="frame" x="45" y="87" width="173" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Chinese Conversion Style:" id="DMf-hh-Tut">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<matrix verticalHuggingPriority="750" fixedFrame="YES" tag="1" allowsEmptySelection="NO" translatesAutoresizingMaskIntoConstraints="NO" id="11Y-7Q-irj">
|
||||
<rect key="frame" x="228" y="66" width="213" height="38"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
<size key="cellSize" width="206" height="18"/>
|
||||
<size key="intercellSpacing" width="4" height="2"/>
|
||||
<buttonCell key="prototype" type="radio" title="Radio" imagePosition="left" alignment="left" inset="2" id="H7Y-M5-po3">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<cells>
|
||||
<column>
|
||||
<buttonCell type="radio" title="Convert ouput" imagePosition="left" alignment="left" state="on" inset="2" id="GhA-hR-a8V">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<buttonCell type="radio" title="Convert models" imagePosition="left" alignment="left" tag="1" inset="2" id="k2S-cq-v0o">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</column>
|
||||
</cells>
|
||||
<connections>
|
||||
<binding destination="32" name="selectedTag" keyPath="values.ChineseConversionStyle" id="dTK-DC-XfO"/>
|
||||
</connections>
|
||||
</matrix>
|
||||
<matrix verticalHuggingPriority="750" fixedFrame="YES" allowsEmptySelection="NO" translatesAutoresizingMaskIntoConstraints="NO" id="19">
|
||||
<rect key="frame" x="227" y="185" width="207" height="38"/>
|
||||
<rect key="frame" x="227" y="231" width="207" height="38"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
<size key="cellSize" width="88" height="18"/>
|
||||
|
@ -239,7 +274,7 @@
|
|||
</connections>
|
||||
</matrix>
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="90">
|
||||
<rect key="frame" x="224" y="151" width="86" height="26"/>
|
||||
<rect key="frame" x="224" y="197" width="86" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" title="18" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" tag="18" imageScaling="proportionallyDown" inset="2" selectedItem="96" id="91">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
|
@ -261,12 +296,8 @@
|
|||
<binding destination="32" name="selectedTag" keyPath="values.CandidateListTextSize" id="107"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="BtG-38-RSK">
|
||||
<rect key="frame" x="12" y="132" width="443" height="5"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
</box>
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Fc2-qh-r1H">
|
||||
<rect key="frame" x="226" y="19" width="218" height="18"/>
|
||||
<rect key="frame" x="226" y="127" width="218" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Check for updates automatically" bezelStyle="regularSquare" imagePosition="left" alignment="left" state="on" inset="2" id="Z9t-P0-BLF">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
|
@ -276,9 +307,13 @@
|
|||
<binding destination="32" name="value" keyPath="values.CheckUpdateAutomatically" id="6WP-5h-sHG"/>
|
||||
</connections>
|
||||
</button>
|
||||
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="BtG-38-RSK">
|
||||
<rect key="frame" x="12" y="117" width="443" height="5"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
</box>
|
||||
</subviews>
|
||||
</view>
|
||||
<point key="canvasLocation" x="148.5" y="233"/>
|
||||
<point key="canvasLocation" x="148.5" y="256"/>
|
||||
</window>
|
||||
<userDefaultsController representsSharedInstance="YES" id="32"/>
|
||||
</objects>
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include "McBopomofoLM.h"
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <unordered_set>
|
||||
|
||||
using namespace McBopomofo;
|
||||
|
||||
|
@ -61,7 +60,8 @@ void McBopomofoLM::loadUserPhrases(const char* userPhrasesDataPath,
|
|||
}
|
||||
}
|
||||
|
||||
void McBopomofoLM::loadPhraseReplacementMap(const char* phraseReplacementPath) {
|
||||
void McBopomofoLM::loadPhraseReplacementMap(const char* phraseReplacementPath)
|
||||
{
|
||||
if (phraseReplacementPath) {
|
||||
m_phraseReplacement.close();
|
||||
m_phraseReplacement.open(phraseReplacementPath);
|
||||
|
@ -75,75 +75,37 @@ const vector<Bigram> McBopomofoLM::bigramsForKeys(const string& preceedingKey, c
|
|||
|
||||
const vector<Unigram> McBopomofoLM::unigramsForKey(const string& key)
|
||||
{
|
||||
vector<Unigram> unigrams;
|
||||
vector<Unigram> allUnigrams;
|
||||
vector<Unigram> userUnigrams;
|
||||
|
||||
// Use unordered_set so that you don't have to do O(n*m)
|
||||
unordered_set<string> excludedValues;
|
||||
unordered_set<string> userValues;
|
||||
unordered_set<string> insertedValues;
|
||||
|
||||
if (m_excludedPhrases.hasUnigramsForKey(key)) {
|
||||
vector<Unigram> excludedUnigrams = m_excludedPhrases.unigramsForKey(key);
|
||||
transform(excludedUnigrams.begin(), excludedUnigrams.end(),
|
||||
inserter(excludedValues, excludedValues.end()),
|
||||
[](const Unigram &u) { return u.keyValue.value; });
|
||||
[](const Unigram& u) { return u.keyValue.value; });
|
||||
}
|
||||
|
||||
if (m_userPhrases.hasUnigramsForKey(key)) {
|
||||
vector<Unigram> rawUserUnigrams = m_userPhrases.unigramsForKey(key);
|
||||
vector<Unigram> filterredUserUnigrams = m_userPhrases.unigramsForKey(key);
|
||||
|
||||
for (auto&& unigram : rawUserUnigrams) {
|
||||
if (excludedValues.find(unigram.keyValue.value) == excludedValues.end()) {
|
||||
filterredUserUnigrams.push_back(unigram);
|
||||
}
|
||||
}
|
||||
|
||||
transform(filterredUserUnigrams.begin(), filterredUserUnigrams.end(),
|
||||
inserter(userValues, userValues.end()),
|
||||
[](const Unigram &u) { return u.keyValue.value; });
|
||||
|
||||
if (m_phraseReplacementEnabled) {
|
||||
for (auto&& unigram : filterredUserUnigrams) {
|
||||
string value = unigram.keyValue.value;
|
||||
string replacement = m_phraseReplacement.valueForKey(value);
|
||||
if (replacement != "") {
|
||||
unigram.keyValue.value = replacement;
|
||||
}
|
||||
unigrams.push_back(unigram);
|
||||
}
|
||||
} else {
|
||||
unigrams = filterredUserUnigrams;
|
||||
}
|
||||
userUnigrams = filterAndTransformUnigrams(rawUserUnigrams, excludedValues, insertedValues);
|
||||
}
|
||||
|
||||
if (m_languageModel.hasUnigramsForKey(key)) {
|
||||
vector<Unigram> globalUnigrams = m_languageModel.unigramsForKey(key);
|
||||
|
||||
for (auto&& unigram : globalUnigrams) {
|
||||
string value = unigram.keyValue.value;
|
||||
if (excludedValues.find(value) == excludedValues.end() &&
|
||||
userValues.find(value) == userValues.end()) {
|
||||
if (m_phraseReplacementEnabled) {
|
||||
string replacement = m_phraseReplacement.valueForKey(value);
|
||||
if (replacement != "") {
|
||||
unigram.keyValue.value = replacement;
|
||||
}
|
||||
}
|
||||
unigrams.push_back(unigram);
|
||||
}
|
||||
}
|
||||
vector<Unigram> rawGlobalUnigrams = m_languageModel.unigramsForKey(key);
|
||||
allUnigrams = filterAndTransformUnigrams(rawGlobalUnigrams, excludedValues, insertedValues);
|
||||
}
|
||||
|
||||
unigrams.insert(unigrams.begin(), userUnigrams.begin(), userUnigrams.end());
|
||||
return unigrams;
|
||||
allUnigrams.insert(allUnigrams.begin(), userUnigrams.begin(), userUnigrams.end());
|
||||
return allUnigrams;
|
||||
}
|
||||
|
||||
bool McBopomofoLM::hasUnigramsForKey(const string& key)
|
||||
{
|
||||
if (!m_excludedPhrases.hasUnigramsForKey(key)) {
|
||||
return m_userPhrases.hasUnigramsForKey(key) ||
|
||||
m_languageModel.hasUnigramsForKey(key);
|
||||
return m_userPhrases.hasUnigramsForKey(key) || m_languageModel.hasUnigramsForKey(key);
|
||||
}
|
||||
|
||||
return unigramsForKey(key).size() > 0;
|
||||
|
@ -159,3 +121,52 @@ bool McBopomofoLM::phraseReplacementEnabled()
|
|||
return m_phraseReplacementEnabled;
|
||||
}
|
||||
|
||||
void McBopomofoLM::setExternalConverterEnabled(bool enabled)
|
||||
{
|
||||
m_externalConverterEnabled = enabled;
|
||||
}
|
||||
|
||||
bool McBopomofoLM::externalConverterEnabled()
|
||||
{
|
||||
return m_externalConverterEnabled;
|
||||
}
|
||||
|
||||
void McBopomofoLM::setExternalConverter(std::function<string(string)> externalConverter)
|
||||
{
|
||||
m_externalConverter = externalConverter;
|
||||
}
|
||||
|
||||
const vector<Unigram> McBopomofoLM::filterAndTransformUnigrams(const vector<Unigram> unigrams, const unordered_set<string>& excludedValues, unordered_set<string>& insertedValues)
|
||||
{
|
||||
vector<Unigram> results;
|
||||
|
||||
for (auto&& unigram : unigrams) {
|
||||
// excludedValues filters out the unigrams with the original value.
|
||||
// insertedValues filters out the ones with the converted value
|
||||
string originalValue = unigram.keyValue.value;
|
||||
if (excludedValues.find(originalValue) != excludedValues.end()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
string value = originalValue;
|
||||
if (m_phraseReplacementEnabled) {
|
||||
string replacement = m_phraseReplacement.valueForKey(value);
|
||||
if (replacement != "") {
|
||||
value = replacement;
|
||||
}
|
||||
}
|
||||
if (m_externalConverterEnabled && m_externalConverter) {
|
||||
string replacement = m_externalConverter(value);
|
||||
value = replacement;
|
||||
}
|
||||
if (insertedValues.find(value) == insertedValues.end()) {
|
||||
Unigram g;
|
||||
g.keyValue.value = value;
|
||||
g.keyValue.key = unigram.keyValue.key;
|
||||
g.score = unigram.score;
|
||||
results.push_back(g);
|
||||
insertedValues.insert(value);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
|
|
@ -28,34 +28,91 @@
|
|||
#include "UserPhrasesLM.h"
|
||||
#include "ParselessLM.h"
|
||||
#include "PhraseReplacementMap.h"
|
||||
#include <unordered_set>
|
||||
|
||||
namespace McBopomofo {
|
||||
|
||||
using namespace Formosa::Gramambular;
|
||||
|
||||
/// McBopomofoLM is a facade for managing a set of models including
|
||||
/// the input method language model, user phrases and excluded phrases.
|
||||
///
|
||||
/// It is the primary model class that the input controller and grammer builder
|
||||
/// of McBopomofo talk to. When the grammer builder starts to build a sentense
|
||||
/// from a series of BPMF readings, it passes the readings to the model to see
|
||||
/// if there are valid unigrams, and use returned unigrams to produce the final
|
||||
/// results.
|
||||
///
|
||||
/// McBopomofoLM combine and transform the unigrams from the primary language
|
||||
/// model and user phrases. The process is
|
||||
///
|
||||
/// 1) Get the original unigrams.
|
||||
/// 2) Drop the unigrams whose value is contained in the exclusion map.
|
||||
/// 3) Replace the values of the unigrams using the phrase replacement map.
|
||||
/// 4) Replace the values of the unigrams using an external converter lambda.
|
||||
/// 5) Drop the duplicated phrases.
|
||||
///
|
||||
/// The controller can ask the model to load the primary input method language
|
||||
/// model while launching and to load the user phrases anytime if the custom
|
||||
/// files are modified. It does not keep the reference of the data pathes but
|
||||
/// you have to pass the paths when you ask it to do loading.
|
||||
class McBopomofoLM : public LanguageModel {
|
||||
public:
|
||||
McBopomofoLM();
|
||||
~McBopomofoLM();
|
||||
|
||||
void loadLanguageModel(const char* languageModelDataPath);
|
||||
void loadUserPhrases(const char* userPhrasesDataPath,
|
||||
const char* excludedPhrasesDataPath);
|
||||
/// Asks to load the primary language model a the given path.
|
||||
/// @param languageModelPath Thw path of the language model.
|
||||
void loadLanguageModel(const char* languageModelPath);
|
||||
/// Asks to load the user phrases and excluded phrases at the given path.
|
||||
/// @param userPhrasesPath The path of user phrases.
|
||||
/// @param excludedPhrasesPath The path of excluded phrases.
|
||||
void loadUserPhrases(const char* userPhrasesPath, const char* excludedPhrasesPath);
|
||||
/// Asks to load th phrase replacement table at the given path.
|
||||
/// @param phraseReplacementPath The path of the phrase replacement table.
|
||||
void loadPhraseReplacementMap(const char* phraseReplacementPath);
|
||||
|
||||
/// Not implemented since we do not have data to provide bigram function.
|
||||
const vector<Bigram> bigramsForKeys(const string& preceedingKey, const string& key);
|
||||
/// Returns a list of available unigram for the given key.
|
||||
/// @param key A string represents the BPMF reading or a symbol key. For
|
||||
/// example, it you pass "ㄇㄚ", it returns "嗎", "媽", and so on.
|
||||
const vector<Unigram> unigramsForKey(const string& key);
|
||||
/// If the model has unigrams for the given key.
|
||||
/// @param key The key.
|
||||
bool hasUnigramsForKey(const string& key);
|
||||
|
||||
/// Enables or disables phrase replacement.
|
||||
void setPhraseReplacementEnabled(bool enabled);
|
||||
/// If phrease replacement is enabled or not.
|
||||
bool phraseReplacementEnabled();
|
||||
|
||||
/// Enables or disables the external converter.
|
||||
void setExternalConverterEnabled(bool enabled);
|
||||
/// If the external converted is enabled or not.
|
||||
bool externalConverterEnabled();
|
||||
/// Sets a lambda to let the values of unigrams could be converted by it.
|
||||
void setExternalConverter(std::function<string(string)> externalConverter);
|
||||
|
||||
protected:
|
||||
/// Filters and converts the input unigrams and return a new list of unigrams.
|
||||
///
|
||||
/// @param unigrams The unigrams to be processed.
|
||||
/// @param excludedValues The values to excluded unigrams.
|
||||
/// @param insertedValues The values for unigrams already in the results.
|
||||
/// It helps to prevent duplicated unigrams. Please note that the method
|
||||
/// has a side effect that it inserts values to `insertedValues`.
|
||||
const vector<Unigram> filterAndTransformUnigrams(const vector<Unigram> unigrams,
|
||||
const std::unordered_set<string>& excludedValues,
|
||||
std::unordered_set<string>& insertedValues);
|
||||
|
||||
ParselessLM m_languageModel;
|
||||
UserPhrasesLM m_userPhrases;
|
||||
UserPhrasesLM m_excludedPhrases;
|
||||
PhraseReplacementMap m_phraseReplacement;
|
||||
bool m_phraseReplacementEnabled;
|
||||
bool m_externalConverterEnabled;
|
||||
std::function<string(string)> m_externalConverter;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -243,6 +243,8 @@ static double FindHighestScore(const vector<NodeAnchor>& nodes, double epsilon)
|
|||
Preferences.keyboardLayout = KeyboardLayoutStandard;
|
||||
}
|
||||
|
||||
_languageModel->setExternalConverterEnabled(Preferences.chineseConversionStyle == 1);
|
||||
|
||||
[(AppDelegate *)[NSApp delegate] checkForUpdate];
|
||||
}
|
||||
|
||||
|
@ -275,12 +277,14 @@ static double FindHighestScore(const vector<NodeAnchor>& nodes, double epsilon)
|
|||
if ([value isKindOfClass:[NSString class]] && [value isEqual:kPlainBopomofoModeIdentifier]) {
|
||||
newInputMode = kPlainBopomofoModeIdentifier;
|
||||
newLanguageModel = [LanguageModelManager languageModelPlainBopomofo];
|
||||
newLanguageModel->setPhraseReplacementEnabled(false);
|
||||
}
|
||||
else {
|
||||
newInputMode = kBopomofoModeIdentifier;
|
||||
newLanguageModel = [LanguageModelManager languageModelMcBopomofo];
|
||||
newLanguageModel->setPhraseReplacementEnabled(Preferences.phraseReplacementEnabled);
|
||||
}
|
||||
newLanguageModel->setExternalConverterEnabled(Preferences.chineseConversionStyle == 1);
|
||||
|
||||
// Only apply the changes if the value is changed
|
||||
if (![_inputMode isEqualToString:newInputMode]) {
|
||||
|
@ -312,8 +316,16 @@ static double FindHighestScore(const vector<NodeAnchor>& nodes, double epsilon)
|
|||
|
||||
#pragma mark - IMKServerInput protocol methods
|
||||
|
||||
- (NSString *)_convertToSimplifiedChinese:(NSString *)text
|
||||
- (NSString *)_convertToSimplifiedChineseIfRequired:(NSString *)text
|
||||
{
|
||||
if (!Preferences.chineseConversionEnabled) {
|
||||
return text;
|
||||
}
|
||||
|
||||
if (Preferences.chineseConversionStyle == 1) {
|
||||
return text;
|
||||
}
|
||||
|
||||
if (Preferences.chineneConversionEngine == 1) {
|
||||
return [VXHanConvert convertToSimplifiedFrom:text];
|
||||
}
|
||||
|
@ -333,11 +345,7 @@ static double FindHighestScore(const vector<NodeAnchor>& nodes, double epsilon)
|
|||
}
|
||||
|
||||
// Chinese conversion.
|
||||
NSString *buffer = _composingBuffer;
|
||||
|
||||
if (Preferences.chineseConversionEnabled) {
|
||||
buffer = [self _convertToSimplifiedChinese:_composingBuffer];
|
||||
}
|
||||
NSString *buffer = [self _convertToSimplifiedChineseIfRequired:_composingBuffer];
|
||||
|
||||
// commit the text, clear the state
|
||||
[client insertText:buffer replacementRange:NSMakeRange(NSNotFound, NSNotFound)];
|
||||
|
@ -483,10 +491,7 @@ NS_INLINE size_t max(size_t a, size_t b) { return a > b ? a : b; }
|
|||
NodeAnchor &anchor = _walkedNodes[0];
|
||||
NSString *popedText = [NSString stringWithUTF8String:anchor.node->currentKeyValue().value.c_str()];
|
||||
// Chinese conversion.
|
||||
BOOL chineseConversionEnabled = Preferences.chineseConversionEnabled;
|
||||
if (chineseConversionEnabled) {
|
||||
popedText = [self _convertToSimplifiedChinese:popedText];
|
||||
}
|
||||
popedText = [self _convertToSimplifiedChineseIfRequired:popedText];
|
||||
[client insertText:popedText replacementRange:NSMakeRange(NSNotFound, NSNotFound)];
|
||||
_builder->removeHeadReadings(anchor.spanningLength);
|
||||
}
|
||||
|
@ -1504,7 +1509,7 @@ NS_INLINE size_t max(size_t a, size_t b) { return a > b ? a : b; }
|
|||
{
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-result"
|
||||
[Preferences tooglePhraseReplacementEnabled];
|
||||
[Preferences toogleHalfWidthPunctuationEnabled];
|
||||
#pragma GCC diagnostic pop
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
+ (void)loadDataModels;
|
||||
+ (void)loadUserPhrases;
|
||||
+ (void)loadUserPhraseReplacement;
|
||||
+ (void)setupDataModelValueConverter;
|
||||
+ (BOOL)checkIfUserLanguageModelFilesExist;
|
||||
+ (BOOL)writeUserPhrase:(NSString *)userPhrase;
|
||||
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
#import <set>
|
||||
#import "OVStringHelper.h"
|
||||
#import "OVUTF8Helper.h"
|
||||
#import "McBopomofo-Swift.h"
|
||||
|
||||
@import VXHanConvert;
|
||||
@import OpenCCBridge;
|
||||
|
||||
using namespace std;
|
||||
using namespace Formosa::Gramambular;
|
||||
|
@ -43,6 +47,31 @@ static void LTLoadLanguageModelFile(NSString *filenameWithoutExtension, McBopomo
|
|||
gLanguageModelMcBopomofo.loadPhraseReplacementMap([[self phraseReplacementDataPathMcBopomofo] UTF8String]);
|
||||
}
|
||||
|
||||
+ (void)setupDataModelValueConverter
|
||||
{
|
||||
auto converter = [] (string input) {
|
||||
if (!Preferences.chineseConversionEnabled) {
|
||||
return input;
|
||||
}
|
||||
|
||||
if (Preferences.chineseConversionStyle == 0) {
|
||||
return input;
|
||||
}
|
||||
|
||||
NSString *text = [NSString stringWithUTF8String:input.c_str()];
|
||||
if (Preferences.chineneConversionEngine == 1) {
|
||||
text = [VXHanConvert convertToSimplifiedFrom:text];
|
||||
}
|
||||
else {
|
||||
text = [OpenCCBridge convertToSimplified:text];
|
||||
}
|
||||
return string(text.UTF8String);
|
||||
};
|
||||
|
||||
gLanguageModelMcBopomofo.setExternalConverter(converter);
|
||||
gLanguageModelPlainBopomofo.setExternalConverter(converter);
|
||||
}
|
||||
|
||||
+ (BOOL)checkIfUserDataFolderExists
|
||||
{
|
||||
NSString *folderPath = [self dataFolderPath];
|
||||
|
|
|
@ -8,4 +8,5 @@
|
|||
+ (void)loadDataModels;
|
||||
+ (void)loadUserPhrases;
|
||||
+ (void)loadUserPhraseReplacement;
|
||||
+ (void)setupDataModelValueConverter;
|
||||
@end
|
||||
|
|
|
@ -50,8 +50,9 @@ private let kEscToCleanInputBufferKey = "EscToCleanInputBuffer"
|
|||
private let kCandidateTextFontName = "CandidateTextFontName"
|
||||
private let kCandidateKeyLabelFontName = "CandidateKeyLabelFontName"
|
||||
private let kCandidateKeys = "CandidateKeys"
|
||||
private let kChineseConversionEngineKey = "ChineseConversionEngine"
|
||||
private let kPhraseReplacementEnabledKey = "PhraseReplacementEnabled"
|
||||
private let kChineseConversionEngineKey = "ChineseConversionEngine"
|
||||
private let kChineseConversionStyle = "ChineseConversionStyle"
|
||||
|
||||
private let kDefaultCandidateListTextSize: CGFloat = 16
|
||||
private let kMinKeyLabelSize: CGFloat = 10
|
||||
|
@ -217,6 +218,20 @@ struct ComposingKeys {
|
|||
}
|
||||
}
|
||||
|
||||
@objc enum ChineseConversionStyle: Int {
|
||||
case output
|
||||
case model
|
||||
|
||||
var name: String {
|
||||
switch (self) {
|
||||
case .output:
|
||||
return "output"
|
||||
case .model:
|
||||
return "model"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
class Preferences: NSObject {
|
||||
|
@ -285,13 +300,6 @@ class Preferences: NSObject {
|
|||
kDefaultKeys
|
||||
}
|
||||
|
||||
@UserDefault(key: kChineseConversionEngineKey, defaultValue: 0)
|
||||
@objc static var chineneConversionEngine: Int
|
||||
|
||||
@objc static var chineneConversionEngineName: String? {
|
||||
return ChineseConversionEngine(rawValue: chineneConversionEngine)?.name
|
||||
}
|
||||
|
||||
@UserDefault(key: kPhraseReplacementEnabledKey, defaultValue: false)
|
||||
@objc static var phraseReplacementEnabled: Bool
|
||||
|
||||
|
@ -300,4 +308,26 @@ class Preferences: NSObject {
|
|||
return phraseReplacementEnabled;
|
||||
}
|
||||
|
||||
/// The conversion engine.
|
||||
///
|
||||
/// - 0: OpenCC
|
||||
/// - 1: VXHanConvert
|
||||
@UserDefault(key: kChineseConversionEngineKey, defaultValue: 0)
|
||||
@objc static var chineneConversionEngine: Int
|
||||
|
||||
@objc static var chineneConversionEngineName: String? {
|
||||
return ChineseConversionEngine(rawValue: chineneConversionEngine)?.name
|
||||
}
|
||||
|
||||
/// The conversion style.
|
||||
///
|
||||
/// - 0: convert the output
|
||||
/// - 1: convert the phrase models.
|
||||
@UserDefault(key: kChineseConversionStyle, defaultValue: 0)
|
||||
@objc static var chineseConversionStyle: Int
|
||||
|
||||
@objc static var chineseConversionStyleName: String? {
|
||||
return ChineseConversionStyle(rawValue: chineseConversionStyle)?.name
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,14 +19,14 @@
|
|||
<window title="注音偏好設定" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" animationBehavior="default" id="1" userLabel="Window - Preferences">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="489" y="334" width="446" height="456"/>
|
||||
<rect key="contentRect" x="489" y="334" width="446" height="479"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1055"/>
|
||||
<view key="contentView" id="2">
|
||||
<rect key="frame" x="0.0" y="0.0" width="446" height="456"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="446" height="479"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3">
|
||||
<rect key="frame" x="181" y="411" width="125" height="26"/>
|
||||
<rect key="frame" x="181" y="434" width="125" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="4">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
|
@ -49,7 +49,7 @@
|
|||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="11">
|
||||
<rect key="frame" x="83" y="417" width="95" height="17"/>
|
||||
<rect key="frame" x="83" y="440" width="95" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="注音鍵盤配置:" id="12">
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -58,7 +58,7 @@
|
|||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="112">
|
||||
<rect key="frame" x="181" y="374" width="149" height="26"/>
|
||||
<rect key="frame" x="181" y="397" width="149" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="115">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
|
@ -70,7 +70,7 @@
|
|||
</connections>
|
||||
</popUpButton>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="13">
|
||||
<rect key="frame" x="18" y="254" width="160" height="17"/>
|
||||
<rect key="frame" x="18" y="277" width="160" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="選字時,候選詞起算點在:" id="14">
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -79,7 +79,7 @@
|
|||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="23">
|
||||
<rect key="frame" x="40" y="208" width="138" height="17"/>
|
||||
<rect key="frame" x="40" y="231" width="138" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="候選詞呈現方式:" id="24">
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -88,7 +88,7 @@
|
|||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="28">
|
||||
<rect key="frame" x="70" y="161" width="108" height="17"/>
|
||||
<rect key="frame" x="70" y="184" width="108" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="選字窗文字大小:" id="29">
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -97,7 +97,7 @@
|
|||
</textFieldCell>
|
||||
</textField>
|
||||
<matrix verticalHuggingPriority="750" fixedFrame="YES" tag="1" allowsEmptySelection="NO" translatesAutoresizingMaskIntoConstraints="NO" id="15">
|
||||
<rect key="frame" x="184" y="233" width="184" height="38"/>
|
||||
<rect key="frame" x="184" y="256" width="184" height="38"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
<size key="cellSize" width="184" height="18"/>
|
||||
|
@ -123,7 +123,7 @@
|
|||
</connections>
|
||||
</matrix>
|
||||
<matrix verticalHuggingPriority="750" fixedFrame="YES" allowsEmptySelection="NO" translatesAutoresizingMaskIntoConstraints="NO" id="19">
|
||||
<rect key="frame" x="184" y="187" width="207" height="38"/>
|
||||
<rect key="frame" x="184" y="210" width="207" height="38"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
<size key="cellSize" width="207" height="18"/>
|
||||
|
@ -149,7 +149,7 @@
|
|||
</connections>
|
||||
</matrix>
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="90">
|
||||
<rect key="frame" x="181" y="153" width="86" height="26"/>
|
||||
<rect key="frame" x="181" y="176" width="86" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" title="18" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" tag="18" imageScaling="proportionallyDown" inset="2" selectedItem="96" id="91">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
|
@ -172,7 +172,7 @@
|
|||
</connections>
|
||||
</popUpButton>
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="109">
|
||||
<rect key="frame" x="182" y="313" width="231" height="18"/>
|
||||
<rect key="frame" x="182" y="336" width="231" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="使用空白鍵選字" bezelStyle="regularSquare" imagePosition="left" alignment="left" state="on" inset="2" id="110">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
|
@ -183,7 +183,7 @@
|
|||
</connections>
|
||||
</button>
|
||||
<comboBox verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="bQw-gl-dUP">
|
||||
<rect key="frame" x="184" y="340" width="206" height="25"/>
|
||||
<rect key="frame" x="184" y="363" width="206" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<comboBoxCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" completes="NO" numberOfVisibleItems="5" id="mNx-Jy-SJB">
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -200,7 +200,7 @@
|
|||
</connections>
|
||||
</comboBox>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8KJ-n8-0Wd">
|
||||
<rect key="frame" x="70" y="344" width="108" height="17"/>
|
||||
<rect key="frame" x="70" y="367" width="108" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="選字鍵:" id="eBT-Tv-vED">
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -209,7 +209,7 @@
|
|||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" id="OrA-WH-e5x">
|
||||
<rect key="frame" x="182" y="290" width="231" height="20"/>
|
||||
<rect key="frame" x="182" y="313" width="231" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="按下 ESC 會清除整個輸入緩衝區" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="7gv-k3-Mbt">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
|
@ -220,7 +220,7 @@
|
|||
</connections>
|
||||
</button>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="113">
|
||||
<rect key="frame" x="70" y="380" width="108" height="17"/>
|
||||
<rect key="frame" x="70" y="403" width="108" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="英數字鍵盤配置:" id="114">
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -229,16 +229,16 @@
|
|||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="p0T-C5-tAj">
|
||||
<rect key="frame" x="18" y="106" width="160" height="17"/>
|
||||
<rect key="frame" x="18" y="41" width="160" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="中文简繁转换引擎:" id="jd1-sb-9rA">
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="中文簡繁轉換引擎:" id="jd1-sb-9rA">
|
||||
<font key="font" size="13" name=".PingFangTC-Regular"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<matrix verticalHuggingPriority="750" fixedFrame="YES" tag="1" allowsEmptySelection="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gYl-c0-mKc">
|
||||
<rect key="frame" x="184" y="85" width="213" height="38"/>
|
||||
<rect key="frame" x="184" y="20" width="213" height="38"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
<size key="cellSize" width="206" height="18"/>
|
||||
|
@ -263,12 +263,43 @@
|
|||
<binding destination="32" name="selectedTag" keyPath="values.ChineseConversionEngine" id="RYU-BR-yvD"/>
|
||||
</connections>
|
||||
</matrix>
|
||||
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="5B4-1Z-6Mz">
|
||||
<rect key="frame" x="20" y="136" width="406" height="5"/>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="84v-v7-84f">
|
||||
<rect key="frame" x="18" y="87" width="160" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
</box>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="中文簡繁轉換模式:" id="8fJ-OC-sPK">
|
||||
<font key="font" size="13" name=".PingFangTC-Regular"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<matrix verticalHuggingPriority="750" fixedFrame="YES" tag="1" allowsEmptySelection="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ml5-hh-vEa">
|
||||
<rect key="frame" x="184" y="66" width="213" height="38"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
<size key="cellSize" width="206" height="18"/>
|
||||
<size key="intercellSpacing" width="4" height="2"/>
|
||||
<buttonCell key="prototype" type="radio" title="Radio" imagePosition="left" alignment="left" inset="2" id="kFb-B9-1bM">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<cells>
|
||||
<column>
|
||||
<buttonCell type="radio" title="轉換輸出結果" imagePosition="left" alignment="left" state="on" inset="2" id="xoK-fI-RZZ">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<buttonCell type="radio" title="轉換詞庫" imagePosition="left" alignment="left" tag="1" inset="2" id="hHx-SU-C1Q">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</column>
|
||||
</cells>
|
||||
<connections>
|
||||
<binding destination="32" name="selectedTag" keyPath="values.ChineseConversionStyle" id="lEn-wb-L3k"/>
|
||||
</connections>
|
||||
</matrix>
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ooW-fi-BVN">
|
||||
<rect key="frame" x="182" y="19" width="148" height="18"/>
|
||||
<rect key="frame" x="182" y="125" width="148" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="定期檢查是否有新版" bezelStyle="regularSquare" imagePosition="left" alignment="left" state="on" inset="2" id="rcF-Ys-CM3">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
|
@ -278,9 +309,13 @@
|
|||
<binding destination="32" name="value" keyPath="values.CheckUpdateAutomatically" id="drP-1F-7NA"/>
|
||||
</connections>
|
||||
</button>
|
||||
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="5B4-1Z-6Mz">
|
||||
<rect key="frame" x="28" y="115" width="406" height="5"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
</box>
|
||||
</subviews>
|
||||
</view>
|
||||
<point key="canvasLocation" x="189" y="242"/>
|
||||
<point key="canvasLocation" x="189" y="253.5"/>
|
||||
</window>
|
||||
<userDefaultsController representsSharedInstance="YES" id="32"/>
|
||||
</objects>
|
||||
|
|
Loading…
Reference in New Issue