summaryrefslogtreecommitdiff
path: root/indra/llui
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llui')
-rw-r--r--indra/llui/CMakeLists.txt2
-rw-r--r--indra/llui/llfocusmgr.cpp6
-rw-r--r--indra/llui/llfocusmgr.h1
-rw-r--r--indra/llui/lllineeditor.cpp49
-rw-r--r--indra/llui/lllineeditor.h2
-rw-r--r--indra/llui/lltexteditor.cpp106
-rw-r--r--indra/llui/lltexteditor.h4
-rw-r--r--indra/llui/llview.cpp19
-rw-r--r--indra/llui/llview.h2
9 files changed, 191 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 7b0a6cbdae..3bc56a8360 100644
--- a/indra/llui/llfocusmgr.cpp
+++ b/indra/llui/llfocusmgr.cpp
@@ -58,6 +58,12 @@ BOOL LLFocusableElement::handleUnicodeChar(llwchar uni_char, BOOL called_from_pa
return FALSE;
}
+// virtual
+BOOL LLFocusableElement::handleUnicodeString(char *uni_str, bool editing, BOOL called_from_parent)
+{
+ return FALSE;
+}
+
// virtual
bool LLFocusableElement::wantsKeyUpKeyDown() const
{
diff --git a/indra/llui/llfocusmgr.h b/indra/llui/llfocusmgr.h
index 0e3d7d8e59..e916c9a737 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 453fa29e7c..9f55738401 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -1011,6 +1011,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 )
{
@@ -1652,6 +1671,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 = FALSE;
+ need_to_rollback |= (mPrevalidateFunc
+ && !mPrevalidateFunc(mText.getWString()));
+
+ if (need_to_rollback) {
+ rollback.doRollback(this);
+ LLUI::getInstance()->reportBadKeystroke();
+ }
+
+ 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 5794b3c35a..ef0e74015a 100644
--- a/indra/llui/lllineeditor.h
+++ b/indra/llui/lllineeditor.h
@@ -132,6 +132,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
@@ -299,6 +300,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 a247e8700a..3277512bc5 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
{
@@ -1157,6 +1201,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() )
@@ -1193,6 +1249,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)
@@ -1958,6 +2046,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 521405ec25..76d2b159a4 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();
@@ -310,6 +313,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/llview.cpp b/indra/llui/llview.cpp
index 139eb17efa..e9c16d058e 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -1044,12 +1044,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 6e16d41cba..5c4a8ab01a 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -383,6 +383,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,
@@ -516,6 +517,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();