[WIP] Starts to work on the user phrases.
This commit is contained in:
parent
39cdc7d73d
commit
358462dff1
|
@ -52,7 +52,11 @@ namespace Formosa {
|
||||||
|
|
||||||
void setJoinSeparator(const string& separator);
|
void setJoinSeparator(const string& separator);
|
||||||
const string joinSeparator() const;
|
const string joinSeparator() const;
|
||||||
|
|
||||||
|
size_t markerCursorIndex() const;
|
||||||
|
void setMarkerCursorIndex(size_t inNewIndex);
|
||||||
|
vector<string> readingsAtRange(size_t begin, size_t end) const;
|
||||||
|
|
||||||
Grid& grid();
|
Grid& grid();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -64,6 +68,7 @@ namespace Formosa {
|
||||||
static const size_t MaximumBuildSpanLength = 6;
|
static const size_t MaximumBuildSpanLength = 6;
|
||||||
|
|
||||||
size_t m_cursorIndex;
|
size_t m_cursorIndex;
|
||||||
|
size_t m_markerCursorIndex;
|
||||||
vector<string> m_readings;
|
vector<string> m_readings;
|
||||||
|
|
||||||
Grid m_grid;
|
Grid m_grid;
|
||||||
|
@ -74,12 +79,14 @@ namespace Formosa {
|
||||||
inline BlockReadingBuilder::BlockReadingBuilder(LanguageModel *inLM)
|
inline BlockReadingBuilder::BlockReadingBuilder(LanguageModel *inLM)
|
||||||
: m_LM(inLM)
|
: m_LM(inLM)
|
||||||
, m_cursorIndex(0)
|
, m_cursorIndex(0)
|
||||||
|
, m_markerCursorIndex(-1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void BlockReadingBuilder::clear()
|
inline void BlockReadingBuilder::clear()
|
||||||
{
|
{
|
||||||
m_cursorIndex = 0;
|
m_cursorIndex = 0;
|
||||||
|
m_markerCursorIndex = -1;
|
||||||
m_readings.clear();
|
m_readings.clear();
|
||||||
m_grid.clear();
|
m_grid.clear();
|
||||||
}
|
}
|
||||||
|
@ -99,6 +106,15 @@ namespace Formosa {
|
||||||
m_cursorIndex = inNewIndex > m_readings.size() ? m_readings.size() : inNewIndex;
|
m_cursorIndex = inNewIndex > m_readings.size() ? m_readings.size() : inNewIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline size_t BlockReadingBuilder::markerCursorIndex() const
|
||||||
|
{
|
||||||
|
return m_markerCursorIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void BlockReadingBuilder::setMarkerCursorIndex(size_t inNewIndex)
|
||||||
|
{
|
||||||
|
m_markerCursorIndex = inNewIndex > m_readings.size() ? m_readings.size() : inNewIndex;
|
||||||
|
}
|
||||||
|
|
||||||
inline void BlockReadingBuilder::insertReadingAtCursor(const string& inReading)
|
inline void BlockReadingBuilder::insertReadingAtCursor(const string& inReading)
|
||||||
{
|
{
|
||||||
|
@ -108,6 +124,14 @@ namespace Formosa {
|
||||||
build();
|
build();
|
||||||
m_cursorIndex++;
|
m_cursorIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline vector<string> BlockReadingBuilder::readingsAtRange(size_t begin, size_t end) const {
|
||||||
|
vector<string> v;
|
||||||
|
for (size_t i = begin; i < end; i++) {
|
||||||
|
v.push_back(m_readings[i]);
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
inline bool BlockReadingBuilder::deleteReadingBeforeCursor()
|
inline bool BlockReadingBuilder::deleteReadingBeforeCursor()
|
||||||
{
|
{
|
||||||
|
|
|
@ -114,6 +114,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/McBopomofo-visualization.dot
|
||||||
// shared language model object that stores our phrase-term probability database
|
// shared language model object that stores our phrase-term probability database
|
||||||
FastLM gLanguageModel;
|
FastLM gLanguageModel;
|
||||||
FastLM gLanguageModelPlainBopomofo;
|
FastLM gLanguageModelPlainBopomofo;
|
||||||
|
FastLM gUserPhraseLanguageModel;
|
||||||
|
|
||||||
static const int kUserOverrideModelCapacity = 500;
|
static const int kUserOverrideModelCapacity = 500;
|
||||||
static const double kObservedOverrideHalflife = 5400.0; // 1.5 hr.
|
static const double kObservedOverrideHalflife = 5400.0; // 1.5 hr.
|
||||||
|
@ -451,6 +452,22 @@ static double FindHighestScore(const vector<NodeAnchor>& nodes, double epsilon)
|
||||||
NSMarkedClauseSegmentAttributeName: @0};
|
NSMarkedClauseSegmentAttributeName: @0};
|
||||||
NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:composedText attributes:attrDict];
|
NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:composedText attributes:attrDict];
|
||||||
|
|
||||||
|
if (_bpmfReadingBuffer->isEmpty() && _builder->markerCursorIndex() != -1) {
|
||||||
|
NSInteger begin = 0;
|
||||||
|
NSInteger end = 0;
|
||||||
|
if (_builder->markerCursorIndex() > _builder->cursorIndex()) {
|
||||||
|
begin = _builder->cursorIndex();
|
||||||
|
end = _builder->markerCursorIndex();
|
||||||
|
} else {
|
||||||
|
end = _builder->cursorIndex();
|
||||||
|
begin = _builder->markerCursorIndex();
|
||||||
|
}
|
||||||
|
NSRange range = NSMakeRange(begin, end - begin);
|
||||||
|
NSDictionary *highlightAttrDict = @{NSUnderlineStyleAttributeName: @(NSUnderlineStyleDouble),
|
||||||
|
NSMarkedClauseSegmentAttributeName: @0};
|
||||||
|
[attrString addAttributes:highlightAttrDict range:range];
|
||||||
|
}
|
||||||
|
|
||||||
// the selection range is where the cursor is, with the length being 0 and replacement range NSNotFound,
|
// the selection range is where the cursor is, with the length being 0 and replacement range NSNotFound,
|
||||||
// i.e. the client app needs to take care of where to put ths composing buffer
|
// i.e. the client app needs to take care of where to put ths composing buffer
|
||||||
[client setMarkedText:attrString selectionRange:NSMakeRange(cursorIndex, 0) replacementRange:NSMakeRange(NSNotFound, NSNotFound)];
|
[client setMarkedText:attrString selectionRange:NSMakeRange(cursorIndex, 0) replacementRange:NSMakeRange(NSNotFound, NSNotFound)];
|
||||||
|
@ -559,6 +576,41 @@ static double FindHighestScore(const vector<NodeAnchor>& nodes, double epsilon)
|
||||||
return layout;
|
return layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSString *)_currentHighlighText
|
||||||
|
{
|
||||||
|
if (_builder->markerCursorIndex() == -1) {
|
||||||
|
return @"";
|
||||||
|
}
|
||||||
|
if (!_bpmfReadingBuffer->isEmpty()) {
|
||||||
|
return @"";
|
||||||
|
}
|
||||||
|
|
||||||
|
NSInteger begin = 0;
|
||||||
|
NSInteger end = 0;
|
||||||
|
if (_builder->markerCursorIndex() > _builder->cursorIndex()) {
|
||||||
|
begin = _builder->cursorIndex();
|
||||||
|
end = _builder->markerCursorIndex();
|
||||||
|
} else {
|
||||||
|
end = _builder->cursorIndex();
|
||||||
|
begin = _builder->markerCursorIndex();
|
||||||
|
}
|
||||||
|
NSRange range = NSMakeRange(begin, end - begin);
|
||||||
|
NSString *reading = [_composingBuffer substringWithRange:range];
|
||||||
|
NSMutableString *string = [[NSMutableString alloc] init];
|
||||||
|
[string appendString:reading];
|
||||||
|
[string appendString:@" "];
|
||||||
|
NSMutableArray *readingsArray = [[NSMutableArray alloc] init];
|
||||||
|
vector<std::string> v = _builder->readingsAtRange(begin,end);
|
||||||
|
for(vector<std::string>::iterator it_i=v.begin(); it_i!=v.end(); ++it_i) {
|
||||||
|
[readingsArray addObject:[NSString stringWithUTF8String:it_i->c_str()]];
|
||||||
|
}
|
||||||
|
NSString *joined = [readingsArray componentsJoinedByString:@"-"];
|
||||||
|
[string appendString:joined];
|
||||||
|
[string appendString:@" "];
|
||||||
|
[string appendString:@"-1.0"];
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
- (BOOL)handleInputText:(NSString*)inputText key:(NSInteger)keyCode modifiers:(NSUInteger)flags client:(id)client
|
- (BOOL)handleInputText:(NSString*)inputText key:(NSInteger)keyCode modifiers:(NSUInteger)flags client:(id)client
|
||||||
{
|
{
|
||||||
NSRect textFrame = NSZeroRect;
|
NSRect textFrame = NSZeroRect;
|
||||||
|
@ -771,11 +823,30 @@ static double FindHighestScore(const vector<NodeAnchor>& nodes, double epsilon)
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_builder->cursorIndex() > 0) {
|
if (flags & NSShiftKeyMask) {
|
||||||
_builder->setCursorIndex(_builder->cursorIndex() - 1);
|
if (_builder->markerCursorIndex() == -1) {
|
||||||
}
|
if (_builder->cursorIndex() > 0) {
|
||||||
else {
|
_builder->setMarkerCursorIndex(_builder->cursorIndex() - 1);
|
||||||
[self beep];
|
} else {
|
||||||
|
[self beep];
|
||||||
|
}
|
||||||
|
NSString *tmp = [self _currentHighlighText];
|
||||||
|
NSLog(@"%@", tmp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (_builder->markerCursorIndex() > 0) {
|
||||||
|
_builder->setMarkerCursorIndex(_builder->markerCursorIndex() - 1);
|
||||||
|
} else {
|
||||||
|
[self beep];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (_builder->cursorIndex() > 0) {
|
||||||
|
_builder->setCursorIndex(_builder->cursorIndex() - 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
[self beep];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -793,11 +864,32 @@ static double FindHighestScore(const vector<NodeAnchor>& nodes, double epsilon)
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_builder->cursorIndex() < _builder->length()) {
|
if (flags & NSShiftKeyMask) {
|
||||||
_builder->setCursorIndex(_builder->cursorIndex() + 1);
|
if (_builder->markerCursorIndex() == -1) {
|
||||||
}
|
if (_builder->cursorIndex() < _builder->length()) {
|
||||||
else {
|
_builder->setMarkerCursorIndex(_builder->cursorIndex() + 1);
|
||||||
[self beep];
|
} else {
|
||||||
|
[self beep];
|
||||||
|
}
|
||||||
|
NSString *tmp = [self _currentHighlighText];
|
||||||
|
NSLog(@"%@", tmp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (_builder->markerCursorIndex() < _builder->length()) {
|
||||||
|
_builder->setMarkerCursorIndex(_builder->markerCursorIndex() + 1);
|
||||||
|
} else {
|
||||||
|
[self beep];
|
||||||
|
}
|
||||||
|
NSString *tmp = [self _currentHighlighText];
|
||||||
|
NSLog(@"%@", tmp);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (_builder->cursorIndex() < _builder->length()) {
|
||||||
|
_builder->setCursorIndex(_builder->cursorIndex() + 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
[self beep];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1419,6 +1511,13 @@ static double FindHighestScore(const vector<NodeAnchor>& nodes, double epsilon)
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
static NSString *userDataFolderPath() {
|
||||||
|
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDirectory, YES);
|
||||||
|
NSString *appSupportPath = [paths objectAtIndex:0];
|
||||||
|
NSString *userDictPath = [appSupportPath stringByAppendingPathComponent:@"McBopomofo"];
|
||||||
|
return userDictPath;
|
||||||
|
}
|
||||||
|
|
||||||
static void LTLoadLanguageModelFile(NSString *filenameWithoutExtension, FastLM &lm)
|
static void LTLoadLanguageModelFile(NSString *filenameWithoutExtension, FastLM &lm)
|
||||||
{
|
{
|
||||||
NSString *dataPath = [[NSBundle bundleForClass:[McBopomofoInputMethodController class]] pathForResource:filenameWithoutExtension ofType:@"txt"];
|
NSString *dataPath = [[NSBundle bundleForClass:[McBopomofoInputMethodController class]] pathForResource:filenameWithoutExtension ofType:@"txt"];
|
||||||
|
@ -1428,6 +1527,15 @@ static void LTLoadLanguageModelFile(NSString *filenameWithoutExtension, FastLM &
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void LTLoadUserLanguageModelFile(NSString *filenameWithoutExtension, FastLM &lm)
|
||||||
|
{
|
||||||
|
NSString *filename = [filenameWithoutExtension stringByAppendingPathExtension:@"txt"];
|
||||||
|
NSString *dataPath = [userDataFolderPath() stringByAppendingPathComponent:filename];
|
||||||
|
bool result = lm.open([dataPath UTF8String]);
|
||||||
|
if (!result) {
|
||||||
|
NSLog(@"Failed opening language model: %@", dataPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LTLoadLanguageModel()
|
void LTLoadLanguageModel()
|
||||||
{
|
{
|
||||||
|
|
|
@ -224,7 +224,7 @@
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<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">
|
<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"/>
|
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||||
<font key="font" size="13" name=".PingFangTC-Regular"/>
|
<font key="font" metaFont="system"/>
|
||||||
</buttonCell>
|
</buttonCell>
|
||||||
<connections>
|
<connections>
|
||||||
<binding destination="32" name="value" keyPath="values.EscToCleanInputBufferKey" id="DyT-0S-5XE"/>
|
<binding destination="32" name="value" keyPath="values.EscToCleanInputBufferKey" id="DyT-0S-5XE"/>
|
||||||
|
|
Loading…
Reference in New Issue