diff options
Diffstat (limited to 'indra/llui')
-rw-r--r-- | indra/llui/CMakeLists.txt | 2 | ||||
-rw-r--r-- | indra/llui/llfocusmgr.cpp | 6 | ||||
-rw-r--r-- | indra/llui/llfocusmgr.h | 1 | ||||
-rw-r--r-- | indra/llui/lllineeditor.cpp | 49 | ||||
-rw-r--r-- | indra/llui/lllineeditor.h | 2 | ||||
-rw-r--r-- | indra/llui/lltexteditor.cpp | 106 | ||||
-rw-r--r-- | indra/llui/lltexteditor.h | 4 | ||||
-rw-r--r-- | indra/llui/llui.cpp | 5 | ||||
-rw-r--r-- | indra/llui/llview.cpp | 19 | ||||
-rw-r--r-- | indra/llui/llview.h | 2 |
10 files changed, 196 insertions, 0 deletions
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index a0314cb5f2..5991a5b35e 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -270,6 +270,8 @@ target_link_libraries(llui llcommon ) +include(LibraryInstall) + # Add tests if(LL_TESTS) include(LLAddBuildTest) diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp index 0d7c98294f..4f3d2328aa 100644 --- a/indra/llui/llfocusmgr.cpp +++ b/indra/llui/llfocusmgr.cpp @@ -59,6 +59,12 @@ bool LLFocusableElement::handleUnicodeChar(llwchar uni_char, bool called_from_pa } // virtual +bool LLFocusableElement::handleUnicodeString(char *uni_str, bool editing, bool called_from_parent) +{ + return FALSE; +} + +// virtual bool LLFocusableElement::wantsKeyUpKeyDown() const { return false; diff --git a/indra/llui/llfocusmgr.h b/indra/llui/llfocusmgr.h index 1fa0ac137e..1ca6f50354 100644 --- a/indra/llui/llfocusmgr.h +++ b/indra/llui/llfocusmgr.h @@ -59,6 +59,7 @@ public: virtual bool handleKey(KEY key, MASK mask, bool called_from_parent); virtual bool handleKeyUp(KEY key, MASK mask, bool called_from_parent); virtual bool handleUnicodeChar(llwchar uni_char, bool called_from_parent); + virtual bool handleUnicodeString(char *uni_str, bool editing, bool called_from_parent); /** * If true this LLFocusableElement wants to receive KEYUP and KEYDOWN messages diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 66b274c33f..1f2aed48cc 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -1050,6 +1050,25 @@ void LLLineEditor::addChar(const llwchar uni_char) getWindow()->hideCursorUntilMouseMove(); } +void LLLineEditor::addString(char *s, bool editing) +{ + if (hasSelection()) + deleteSelection(); + else if (LL_KIM_OVERWRITE == gKeyboard->getInsertMode()) { + if (!prevalidateInput(mText.getWString() + .substr(getCursor(), 1))) + return; + mText.erase(getCursor(), 1); + } else if (editing) { + mText.clear(); + setCursor(0); + } + mText.insert(getCursor(), utf8str_to_wstring(s)); + if (editing) setCursor(strlen(s)); + else setCursor(getCursor() + 1); + getWindow()->hideCursorUntilMouseMove(); +} + // Extends the selection box to the new cursor position void LLLineEditor::extendSelection( S32 new_cursor_pos ) { @@ -1720,6 +1739,36 @@ bool LLLineEditor::handleUnicodeCharHere(llwchar uni_char) return handled; } +bool LLLineEditor::handleUnicodeStringHere(char *uni_str, bool editing) +{ + auto handled = FALSE; + + if ((gFocusMgr.getKeyboardFocus() == this) + && getVisible() && !mReadOnly) { + handled = TRUE; + LLLineEditorRollback rollback(this); + + addString(uni_str, editing); + + mKeystrokeTimer.reset(); + deselect(); + auto need_to_rollback = mPrevalidator + && !mPrevalidator.validate(mText.getWString()); + + if (need_to_rollback) { + rollback.doRollback(this); + LLUI::getInstance()->reportBadKeystroke(); + mPrevalidator.showLastErrorUsingTimeout(); + } + + if (!need_to_rollback && handled) { + onKeystroke(); + mSpellCheckTimer.setTimerExpirySec(SPELLCHECK_DELAY); + } + } + + return handled; +} bool LLLineEditor::canDoDelete() const { diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index 12fe800acb..47ff321b54 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -134,6 +134,7 @@ public: /*virtual*/ bool handleRightMouseDown(S32 x, S32 y, MASK mask) override; /*virtual*/ bool handleKeyHere(KEY key, MASK mask) override; /*virtual*/ bool handleUnicodeCharHere(llwchar uni_char) override; + /*virtual*/ bool handleUnicodeStringHere(char *uni_str, bool editing) override; /*virtual*/ void onMouseCaptureLost() override; // LLEditMenuHandler overrides @@ -301,6 +302,7 @@ public: void removeChar(); void addChar(const llwchar c); + void addString(char *s, bool editing); void setCursorAtLocalPos(S32 local_mouse_x); S32 findPixelNearestPos(S32 cursor_offset = 0) const; S32 calcCursorPos(S32 mouse_x); diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 3537c764b9..cbbb164cb2 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -167,6 +167,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 { @@ -1164,6 +1208,18 @@ S32 LLTextEditor::addChar(S32 pos, llwchar wc) return execute(new TextCmdAddChar(pos, false, wc, LLTextSegmentPtr())); } +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()) @@ -1201,6 +1257,38 @@ void LLTextEditor::addChar(llwchar wc) } } +void LLTextEditor::addString(char *str, bool editing) +{ + if (!getEnabled()) + return; + if (hasSelection()) + deleteSelection(TRUE); + else if (LL_KIM_OVERWRITE == gKeyboard->getInsertMode()) + removeChar(mCursorPos); + else if (editing) { + clear(); + setCursorPos(0); + } + + 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::showEmojiHelper() { if (mReadOnly || !mShowEmojiHelper) @@ -1972,6 +2060,24 @@ bool LLTextEditor::handleUnicodeCharHere(llwchar uni_char) return handled; } +bool LLTextEditor::handleUnicodeStringHere(char *uni_str, bool editing) +{ + auto handled = FALSE; + + if (!mReadOnly) { + addString(uni_str, editing); + getWindow()->hideCursorUntilMouseMove(); + handled = TRUE; + } + + if (handled) { + resetCursorBlink(); + deselect(); + onKeyStroke(); + } + + return handled; +} // virtual bool LLTextEditor::canDoDelete() const diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index e9e7070414..b46b3b595b 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -105,6 +105,7 @@ public: virtual bool handleKeyHere(KEY key, MASK mask ); virtual bool handleUnicodeCharHere(llwchar uni_char); + virtual bool handleUnicodeStringHere(char *uni_str, bool editing); virtual void onMouseCaptureLost(); @@ -249,6 +250,8 @@ protected: // Undoable operations void addChar(llwchar c); // at mCursorPos S32 addChar(S32 pos, llwchar wc); + void addString(char *s, bool editing); + S32 addString(S32 pos, char *str); void addLineBreakChar(bool group_together = false); S32 overwriteChar(S32 pos, llwchar wc); void removeChar(); @@ -312,6 +315,7 @@ private: // Concrete TextCmd sub-classes used by the LLTextEditor base class class TextCmdInsert; class TextCmdAddChar; + class TextCmdAddString; class TextCmdOverwriteChar; class TextCmdRemove; diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index e36dae3955..e7dea79eaa 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -231,6 +231,11 @@ void LLUI::getMousePositionScreen(S32 *x, S32 *y) LLCoordGL cursor_pos_gl(cursor_pos_window.convert()); *x = ll_round((F32)cursor_pos_gl.mX / getScaleFactor().mV[VX]); *y = ll_round((F32)cursor_pos_gl.mY / getScaleFactor().mV[VY]); +#if defined(LL_SDL) + *x = *x * LLView::getWindow()->getSystemUISize(); + *y = *y * LLView::getWindow()->getSystemUISize(); +#endif + } void LLUI::setMousePositionLocal(const LLView* viewp, S32 x, S32 y) diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 7d6c937b85..f2a1e16aad 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -1080,12 +1080,31 @@ bool LLView::handleUnicodeChar(llwchar uni_char, bool called_from_parent) return handled; } +bool LLView::handleUnicodeString(char *uni_str, bool editing, bool called_from_parent) +{ + auto handled = FALSE; + + if (getVisible() && getEnabled() && !handled) { + handled = handleUnicodeStringHere(uni_str, editing); + if (handled && LLView::sDebugKeys) + LL_INFOS() << "Unicode key handled by " << getName() << LL_ENDL; + } + + if (!handled && !called_from_parent && mParentView) + handled = mParentView->handleUnicodeString(uni_str, editing, FALSE); + + return handled; +} bool LLView::handleUnicodeCharHere(llwchar uni_char ) { return false; } +bool LLView::handleUnicodeStringHere(char *uni_str, bool editing) +{ + return FALSE; +} bool LLView::handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop, EDragAndDropType cargo_type, void* cargo_data, diff --git a/indra/llui/llview.h b/indra/llui/llview.h index 710ec3d05e..876bfafaa3 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -385,6 +385,7 @@ public: /* virtual */ bool handleKey(KEY key, MASK mask, bool called_from_parent); /* virtual */ bool handleKeyUp(KEY key, MASK mask, bool called_from_parent); /* virtual */ bool handleUnicodeChar(llwchar uni_char, bool called_from_parent); + /* virtual */ bool handleUnicodeString(char *uni_str, bool editing, bool called_from_parent); virtual bool handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop, EDragAndDropType cargo_type, @@ -518,6 +519,7 @@ public: virtual bool handleKeyHere(KEY key, MASK mask); virtual bool handleKeyUpHere(KEY key, MASK mask); virtual bool handleUnicodeCharHere(llwchar uni_char); + virtual bool handleUnicodeStringHere(char *uni_str, bool editing); virtual void handleReshape(const LLRect& rect, bool by_user); virtual void dirtyRect(); |