[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);
|
||||
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();
|
||||
|
||||
protected:
|
||||
|
@ -64,6 +68,7 @@ namespace Formosa {
|
|||
static const size_t MaximumBuildSpanLength = 6;
|
||||
|
||||
size_t m_cursorIndex;
|
||||
size_t m_markerCursorIndex;
|
||||
vector<string> m_readings;
|
||||
|
||||
Grid m_grid;
|
||||
|
@ -74,12 +79,14 @@ namespace Formosa {
|
|||
inline BlockReadingBuilder::BlockReadingBuilder(LanguageModel *inLM)
|
||||
: m_LM(inLM)
|
||||
, m_cursorIndex(0)
|
||||
, m_markerCursorIndex(-1)
|
||||
{
|
||||
}
|
||||
|
||||
inline void BlockReadingBuilder::clear()
|
||||
{
|
||||
m_cursorIndex = 0;
|
||||
m_markerCursorIndex = -1;
|
||||
m_readings.clear();
|
||||
m_grid.clear();
|
||||
}
|
||||
|
@ -99,6 +106,15 @@ namespace Formosa {
|
|||
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)
|
||||
{
|
||||
|
@ -108,6 +124,14 @@ namespace Formosa {
|
|||
build();
|
||||
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()
|
||||
{
|
||||
|
|
|
@ -114,6 +114,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/McBopomofo-visualization.dot
|
|||
// shared language model object that stores our phrase-term probability database
|
||||
FastLM gLanguageModel;
|
||||
FastLM gLanguageModelPlainBopomofo;
|
||||
FastLM gUserPhraseLanguageModel;
|
||||
|
||||
static const int kUserOverrideModelCapacity = 500;
|
||||
static const double kObservedOverrideHalflife = 5400.0; // 1.5 hr.
|
||||
|
@ -451,6 +452,22 @@ static double FindHighestScore(const vector<NodeAnchor>& nodes, double epsilon)
|
|||
NSMarkedClauseSegmentAttributeName: @0};
|
||||
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,
|
||||
// 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)];
|
||||
|
@ -559,6 +576,41 @@ static double FindHighestScore(const vector<NodeAnchor>& nodes, double epsilon)
|
|||
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
|
||||
{
|
||||
NSRect textFrame = NSZeroRect;
|
||||
|
@ -771,11 +823,30 @@ static double FindHighestScore(const vector<NodeAnchor>& nodes, double epsilon)
|
|||
return NO;
|
||||
}
|
||||
|
||||
if (_builder->cursorIndex() > 0) {
|
||||
_builder->setCursorIndex(_builder->cursorIndex() - 1);
|
||||
}
|
||||
else {
|
||||
[self beep];
|
||||
if (flags & NSShiftKeyMask) {
|
||||
if (_builder->markerCursorIndex() == -1) {
|
||||
if (_builder->cursorIndex() > 0) {
|
||||
_builder->setMarkerCursorIndex(_builder->cursorIndex() - 1);
|
||||
} 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;
|
||||
}
|
||||
|
||||
if (_builder->cursorIndex() < _builder->length()) {
|
||||
_builder->setCursorIndex(_builder->cursorIndex() + 1);
|
||||
}
|
||||
else {
|
||||
[self beep];
|
||||
if (flags & NSShiftKeyMask) {
|
||||
if (_builder->markerCursorIndex() == -1) {
|
||||
if (_builder->cursorIndex() < _builder->length()) {
|
||||
_builder->setMarkerCursorIndex(_builder->cursorIndex() + 1);
|
||||
} 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
|
||||
|
||||
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)
|
||||
{
|
||||
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()
|
||||
{
|
||||
|
|
|
@ -224,7 +224,7 @@
|
|||
<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"/>
|
||||
<font key="font" size="13" name=".PingFangTC-Regular"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<binding destination="32" name="value" keyPath="values.EscToCleanInputBufferKey" id="DyT-0S-5XE"/>
|
||||
|
|
Loading…
Reference in New Issue