diff options
author | Erik Kundiman <erik@megapahit.org> | 2024-01-29 17:42:38 +0800 |
---|---|---|
committer | Erik Kundiman <erik@megapahit.org> | 2024-01-30 12:06:48 +0800 |
commit | aaa8cb5a37a720ff67792d0a31fec793b03b3742 (patch) | |
tree | 734ce89b2f133f1fd55cd04e5e79eb5c1ed06d50 /indra/llui/lltexteditor.cpp | |
parent | 4c97df0ab1b450d5680975e18e894b6676a589ee (diff) |
First attempt to fix unicode input
It should work well enough with most, but on Japanese (I assume all CJK),
for now the composition part is still left printed out along with the result
(as opposed to just replaced by the result). It's to be fixed next.
Diffstat (limited to 'indra/llui/lltexteditor.cpp')
-rw-r--r-- | indra/llui/lltexteditor.cpp | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 3d2a426913..299af0dec8 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -166,6 +166,50 @@ private: }; /////////////////////////////////////////////////////////////////// +class LLTextEditor::TextCmdAddString : public LLTextBase::TextCmd +{ +public: + TextCmdAddString(S32 pos, BOOL group_with_next, char *str, + LLTextSegmentPtr segment) : + TextCmd(pos, group_with_next, segment), + mWString(utf8str_to_wstring(str)), + mBlockExtensions(FALSE) + { + } + virtual void blockExtensions() + { + mBlockExtensions = TRUE; + } + virtual BOOL canExtend(S32 pos) const + { + if (!mSegments.empty()) return FALSE; + + return !mBlockExtensions + && (pos == getPosition() + (S32)mWString.length()); + } + virtual BOOL execute(LLTextBase* editor, S32* delta) + { + *delta = insert(editor, getPosition(), mWString); + LLWStringUtil::truncate(mWString, *delta); + return (*delta != 0); + } + virtual S32 undo(LLTextBase* editor) + { + remove(editor, getPosition(), mWString.length()); + return getPosition(); + } + virtual S32 redo(LLTextBase* editor) + { + insert(editor, getPosition(), mWString); + return getPosition() + mWString.length(); + } + +private: + LLWString mWString; + BOOL mBlockExtensions; +}; + +/////////////////////////////////////////////////////////////////// class LLTextEditor::TextCmdOverwriteChar : public LLTextBase::TextCmd { @@ -1111,6 +1155,18 @@ S32 LLTextEditor::addChar(S32 pos, llwchar wc) } } +S32 LLTextEditor::addString(S32 pos, char *str) +{ + if ((wstring_utf8_length(getWText()) + strlen(str)) + > mMaxTextByteLength) { + make_ui_sound("UISndBadKeystroke"); + return 0; + } + + return execute(new TextCmdAddString(pos, FALSE, str, + LLTextSegmentPtr())); +} + void LLTextEditor::addChar(llwchar wc) { if( !getEnabled() ) @@ -1146,6 +1202,34 @@ void LLTextEditor::addChar(llwchar wc) } } +void LLTextEditor::addString(char *str) +{ + if (!getEnabled()) + return; + if (hasSelection()) + deleteSelection(TRUE); + else if (LL_KIM_OVERWRITE == gKeyboard->getInsertMode()) + removeChar(mCursorPos); + + setCursorPos(mCursorPos + addString(mCursorPos, str)); + + if (!mReadOnly && mAutoreplaceCallback != NULL) { + S32 replacement_start; + S32 replacement_length; + LLWString replacement_string; + S32 new_cursor_pos = mCursorPos; + mAutoreplaceCallback(replacement_start, replacement_length, + replacement_string, new_cursor_pos, getWText()); + + if (replacement_length > 0 || !replacement_string.empty()) { + remove(replacement_start, replacement_length, true); + insert(replacement_start, replacement_string, false, + LLTextSegmentPtr()); + setCursorPos(new_cursor_pos); + } + } +} + void LLTextEditor::addLineBreakChar(BOOL group_together) { if( !getEnabled() ) @@ -1864,6 +1948,24 @@ BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char) return handled; } +BOOL LLTextEditor::handleUnicodeStringHere(char *uni_str) +{ + auto handled = FALSE; + + if (!mReadOnly) { + addString(uni_str); + getWindow()->hideCursorUntilMouseMove(); + handled = TRUE; + } + + if (handled) { + resetCursorBlink(); + deselect(); + onKeyStroke(); + } + + return handled; +} // virtual BOOL LLTextEditor::canDoDelete() const |