summaryrefslogtreecommitdiff
path: root/indra/llui/lltexteditor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llui/lltexteditor.cpp')
-rw-r--r--indra/llui/lltexteditor.cpp207
1 files changed, 96 insertions, 111 deletions
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index cbbb164cb2..cfe729be06 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -60,6 +60,7 @@
#include "llurlregistry.h"
#include "lltooltip.h"
#include "llmenugl.h"
+#include "llchatmentionhelper.h"
#include <queue>
#include "llcombobox.h"
@@ -167,50 +168,6 @@ 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
{
@@ -253,8 +210,15 @@ public:
}
virtual bool execute( LLTextBase* editor, S32* delta )
{
- mWString = editor->getWText().substr(getPosition(), mLen);
- *delta = remove(editor, getPosition(), mLen );
+ try
+ {
+ mWString = editor->getWText().substr(getPosition(), mLen);
+ *delta = remove(editor, getPosition(), mLen);
+ }
+ catch (std::out_of_range&)
+ {
+ return false;
+ }
return (*delta != 0);
}
virtual S32 undo( LLTextBase* editor )
@@ -307,6 +271,7 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) :
mPrevalidator(p.prevalidator()),
mShowContextMenu(p.show_context_menu),
mShowEmojiHelper(p.show_emoji_helper),
+ mShowChatMentionPicker(false),
mEnableTooltipPaste(p.enable_tooltip_paste),
mPassDelete(false),
mKeepSelectionOnReturn(false)
@@ -751,6 +716,30 @@ void LLTextEditor::handleEmojiCommit(llwchar emoji)
}
}
+void LLTextEditor::handleMentionCommit(std::string name_url)
+{
+ S32 mention_start_pos;
+ if (LLChatMentionHelper::instance().isCursorInNameMention(getWText(), mCursorPos, &mention_start_pos))
+ {
+ remove(mention_start_pos, mCursorPos - mention_start_pos, true);
+ insert(mention_start_pos, utf8str_to_wstring(name_url), false, LLTextSegmentPtr());
+
+ std::string new_text(wstring_to_utf8str(getConvertedText()));
+ clear();
+ appendTextImpl(new_text, LLStyle::Params(), true);
+
+ segment_set_t::const_iterator it = getSegIterContaining(mention_start_pos);
+ if (it != mSegments.end())
+ {
+ setCursorPos((*it)->getEnd() + 1);
+ }
+ else
+ {
+ setCursorPos(mention_start_pos);
+ }
+ }
+}
+
bool LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)
{
bool handled = false;
@@ -1140,6 +1129,7 @@ void LLTextEditor::removeCharOrTab()
}
tryToShowEmojiHelper();
+ tryToShowMentionHelper();
}
else
{
@@ -1165,6 +1155,7 @@ void LLTextEditor::removeChar()
setCursorPos(mCursorPos - 1);
removeChar(mCursorPos);
tryToShowEmojiHelper();
+ tryToShowMentionHelper();
}
else
{
@@ -1208,18 +1199,6 @@ 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())
@@ -1238,6 +1217,7 @@ void LLTextEditor::addChar(llwchar wc)
setCursorPos(mCursorPos + addChar( mCursorPos, wc ));
tryToShowEmojiHelper();
+ tryToShowMentionHelper();
if (!mReadOnly && mAutoreplaceCallback != NULL)
{
@@ -1257,38 +1237,6 @@ 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)
@@ -1299,6 +1247,14 @@ void LLTextEditor::showEmojiHelper()
LLEmojiHelper::instance().showHelper(this, cursorRect.mLeft, cursorRect.mTop, LLStringUtil::null, cb);
}
+void LLTextEditor::hideEmojiHelper()
+{
+ if (mShowEmojiHelper)
+ {
+ LLEmojiHelper::instance().hideHelper(this);
+ }
+}
+
void LLTextEditor::tryToShowEmojiHelper()
{
if (mReadOnly || !mShowEmojiHelper)
@@ -1320,6 +1276,31 @@ void LLTextEditor::tryToShowEmojiHelper()
}
}
+void LLTextEditor::tryToShowMentionHelper()
+{
+ if (mReadOnly || !mShowChatMentionPicker)
+ return;
+
+ S32 mention_start_pos;
+ LLWString text(getWText());
+ if (LLChatMentionHelper::instance().isCursorInNameMention(text, mCursorPos, &mention_start_pos))
+ {
+ const LLRect cursor_rect(getLocalRectFromDocIndex(mention_start_pos));
+ std::string name_part(wstring_to_utf8str(text.substr(mention_start_pos, mCursorPos - mention_start_pos)));
+ name_part.erase(0, 1);
+ auto cb = [this](std::string name_url)
+ {
+ handleMentionCommit(name_url);
+ };
+ LLChatMentionHelper::instance().showHelper(this, cursor_rect.mLeft, cursor_rect.mTop, name_part, cb);
+ }
+ else
+ {
+ LLChatMentionHelper::instance().hideHelper();
+ }
+}
+
+
void LLTextEditor::addLineBreakChar(bool group_together)
{
if( !getEnabled() )
@@ -1946,7 +1927,7 @@ bool LLTextEditor::handleKeyHere(KEY key, MASK mask )
// not handled and let the parent take care of field movement.
if (KEY_TAB == key && mTabsToNextField)
{
- return false;
+ return mShowChatMentionPicker && LLChatMentionHelper::instance().handleKey(this, key, mask);
}
if (mReadOnly && mScroller)
@@ -1957,9 +1938,13 @@ bool LLTextEditor::handleKeyHere(KEY key, MASK mask )
}
else
{
- if (!mReadOnly && mShowEmojiHelper && LLEmojiHelper::instance().handleKey(this, key, mask))
+ if (!mReadOnly)
{
- return true;
+ if ((mShowEmojiHelper && LLEmojiHelper::instance().handleKey(this, key, mask)) ||
+ (mShowChatMentionPicker && LLChatMentionHelper::instance().handleKey(this, key, mask)))
+ {
+ return true;
+ }
}
if (mEnableTooltipPaste &&
@@ -2060,24 +2045,6 @@ 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
@@ -3174,3 +3141,21 @@ S32 LLTextEditor::spacesPerTab()
{
return SPACES_PER_TAB;
}
+
+LLWString LLTextEditor::getConvertedText() const
+{
+ LLWString text = getWText();
+ S32 diff = 0;
+ for (auto segment : mSegments)
+ {
+ if (segment && segment->getStyle() && segment->getStyle()->getDrawHighlightBg())
+ {
+ S32 seg_length = segment->getEnd() - segment->getStart();
+ std::string slurl = segment->getStyle()->getLinkHREF();
+
+ text.replace(segment->getStart() + diff, seg_length, utf8str_to_wstring(slurl));
+ diff += (S32)slurl.size() - seg_length;
+ }
+ }
+ return text;
+}