diff options
Diffstat (limited to 'indra/llui/lltexteditor.cpp')
-rw-r--r-- | indra/llui/lltexteditor.cpp | 207 |
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; +} |