Skip to content
48 changes: 48 additions & 0 deletions McBopomofoTests/KeyHandlerBopomofoTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2706,3 +2706,51 @@ extension KeyHandlerBopomofoTests {
}
}
}

extension KeyHandlerBopomofoTests {

func checkChangingReadingUsingToneKey(input: String, expected: String) {
let associatedPhrasesEnabled = Preferences.associatedPhrasesEnabled
let allowChangingPriorTone = Preferences.allowChangingPriorTone
Preferences.associatedPhrasesEnabled = false
Preferences.allowChangingPriorTone = true

defer {
Preferences.associatedPhrasesEnabled = associatedPhrasesEnabled
Preferences.allowChangingPriorTone = allowChangingPriorTone
}

var state: InputState = InputState.Empty()
let keys = Array(input).map {
String($0)
}
for key in keys {
let input = KeyHandlerInput(
inputText: key, keyCode: 0, charCode: charCode(key), flags: [],
isVerticalMode: false)
handler.handle(input: input, state: state) { newState in
state = newState
} errorCallback: {
}
}
XCTAssertTrue(state is InputState.Inputting, "\(state)")
if let state = state as? InputState.Inputting {
XCTAssertEqual(state.composingBuffer, expected)
}
}

// Input 小麥 then change to tone 3
func testChangingReadingUsingToneKey1() {
checkChangingReadingUsingToneKey(input: "vul3a943", expected: "小買")
}

// Input 小麥 then change to tone 4
func testChangingReadingUsingToneKey2() {
checkChangingReadingUsingToneKey(input: "vul3a946", expected: "小埋")
}

// Input 小麥 then change to tone 5
func testChangingReadingUsingToneKey3() {
checkChangingReadingUsingToneKey(input: "vul3a947", expected: "小麥˙")
}
}
1 change: 1 addition & 0 deletions Source/Engine/Mandarin/Mandarin.h
Original file line number Diff line number Diff line change
Expand Up @@ -482,3 +482,4 @@ class BopomofoReadingBuffer {
} // namespace Formosa

#endif // SRC_ENGINE_MANDARIN_MANDARIN_H_

36 changes: 34 additions & 2 deletions Source/KeyHandler.mm
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,8 @@ - (BOOL)handleInput:(KeyHandlerInput *)input state:(InputState *)inState stateCa
// MARK: Handle BPMF Keys

// see if it's valid BPMF reading
if (!skipBpmfHandling && _bpmfReadingBuffer->isValidKey((char)charCode)) {
bool isValidKey = _bpmfReadingBuffer->isValidKey((char)charCode);
if (!skipBpmfHandling && isValidKey) {
_bpmfReadingBuffer->combineKey((char)charCode);
keyConsumedByReading = YES;

Expand All @@ -463,7 +464,38 @@ - (BOOL)handleInput:(KeyHandlerInput *)input state:(InputState *)inState stateCa
}
}

BOOL composeReading = _bpmfReadingBuffer->isValidKey((char)charCode) && _bpmfReadingBuffer->hasToneMarker() && !_bpmfReadingBuffer->hasToneMarkerOnly();
// Issue 753
//
// This allows users to use tone key to change an existing reading before
// the current cursor.
if (_bpmfReadingBuffer->hasToneMarkerOnly() &&
_grid->readings().size() > 0 &&
_grid->cursor() > 0 &&
Preferences.allowChangingPriorTone) {
size_t cursor = _grid->cursor() - 1;
const std::string& reading = _grid->readings()[cursor];
if (!reading.empty() && reading[0] != '_') {
Formosa::Mandarin::BopomofoReadingBuffer tmpBuffer(_bpmfReadingBuffer->keyboardLayout());
Formosa::Mandarin::BopomofoSyllable syllable = Formosa::Mandarin::BopomofoSyllable::FromComposedString(reading);
std::string keys = _bpmfReadingBuffer->keyboardLayout()->keySequenceFromSyllable(syllable);
for (char k:keys) {
tmpBuffer.combineKey(k);
}
tmpBuffer.combineKey((char)charCode);
std::string newReading = tmpBuffer.syllable().composedString();
if (_languageModel->hasUnigrams(newReading)) {
_bpmfReadingBuffer->clear();
_grid->deleteReadingBeforeCursor();
_grid->insertReading(newReading);
[self _walk];
InputStateInputting *inputting = (InputStateInputting *)[self buildInputtingState];
stateCallback(inputting);
return YES;
}
}
}

BOOL composeReading = isValidKey && _bpmfReadingBuffer->hasToneMarker() && !_bpmfReadingBuffer->hasToneMarkerOnly();

// see if we have composition if Enter/Space is hit and buffer is not empty
// this is bit-OR'ed so that the tone marker key is also taken into account
Expand Down
6 changes: 6 additions & 0 deletions Source/Preferences.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ private let kBig5InputEnabledKey = "Big5InputEnabled"
let kBeepUponInputErrorKey = "BeepUponInputError"

private let kEnableUserPhrasesInPlainBopomofo = "EnableUserPhrasesInPlainBopomofo"
private let kAllowChangingPriorTone = "AllowChangingPriorTone"

// MARK: Property wrappers

Expand Down Expand Up @@ -570,6 +571,11 @@ extension Preferences {
@objc static var enableUserPhrasesInPlainBopomofo: Bool
}

extension Preferences {
@UserDefault(key: kAllowChangingPriorTone, defaultValue: false)
@objc static var allowChangingPriorTone: Bool
}

extension Preferences {
static func createReport() -> String {
var lines: [String] = []
Expand Down