From ce5a5f84d5b5aee95b0b130d0fbdb8fbaa688ba7 Mon Sep 17 00:00:00 2001
From: Richard Nelson <richard@lindenlab.com>
Date: Tue, 20 Oct 2009 00:41:41 +0000
Subject: [PATCH] ext-1670 - fix the chat history use of widgets

reviewed by leyla
---
 indra/llui/lltextbase.cpp             | 125 +++++++++++++++-----------
 indra/llui/lltextbase.h               |  14 ++-
 indra/llui/lltexteditor.cpp           |  14 +--
 indra/llui/lltexteditor.h             |   2 +-
 indra/newview/llchathistory.cpp       |   2 +-
 indra/newview/llexpandabletextbox.cpp |  17 ++--
 indra/newview/llexpandabletextbox.h   |   2 +-
 indra/newview/llviewertexteditor.cpp  |  12 ++-
 8 files changed, 100 insertions(+), 88 deletions(-)

diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 4cf8d76827..1d36a16ea7 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -340,11 +340,14 @@ void LLTextBase::drawSelectionBackground()
 					S32 segment_line_start = segmentp->getStart() + segment_offset;
 					S32 segment_line_end = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd);
 
+					S32 segment_width, segment_height;
+
 					// if selection after beginning of segment
 					if(selection_left >= segment_line_start)
 					{
 						S32 num_chars = llmin(selection_left, segment_line_end) - segment_line_start;
-						selection_rect.mLeft += segmentp->getWidth(segment_offset, num_chars);
+						segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height);
+						selection_rect.mLeft += segment_width;
 					}
 
 					// if selection spans end of current segment...
@@ -352,13 +355,16 @@ void LLTextBase::drawSelectionBackground()
 					{
 						// extend selection slightly beyond end of line
 						// to indicate selection of newline character (use "n" character to determine width)
-						selection_rect.mRight += segmentp->getWidth(segment_offset, segment_line_end - segment_line_start);
+						S32 num_chars = segment_line_end - segment_line_start;
+						segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height);
+						selection_rect.mRight += segment_width;
 					}
 					// else if selection ends on current segment...
 					else
 					{
 						S32 num_chars = selection_right - segment_line_start;
-						selection_rect.mRight += segmentp->getWidth(segment_offset, num_chars);
+						segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height);
+						selection_rect.mRight += segment_width;
 
 						break;
 					}
@@ -424,7 +430,9 @@ void LLTextBase::drawCursor()
 
 			if (LL_KIM_OVERWRITE == gKeyboard->getInsertMode() && !hasSelection())
 			{
-				S32 width = llmax(CURSOR_THICKNESS, segmentp->getWidth(mCursorPos - segmentp->getStart(), 1));
+				S32 segment_width, segment_height;
+				segmentp->getDimensions(mCursorPos - segmentp->getStart(), 1, segment_width, segment_height);
+				S32 width = llmax(CURSOR_THICKNESS, segment_width);
 				cursor_rect.mRight = cursor_rect.mLeft + width;
 			}
 			else
@@ -1087,24 +1095,18 @@ void LLTextBase::reflow(S32 start_index)
 			LLTextSegmentPtr segment = *seg_iter;
 
 			// track maximum height of any segment on this line
-			line_height = llmax(line_height, segment->getMaxHeight());
 			S32 cur_index = segment->getStart() + seg_offset;
-			// find run of text from this segment that we can display on one line
-			S32 end_index = cur_index;
-			while(end_index < segment->getEnd() && text[end_index] != '\n')
-			{
-				++end_index;
-			}
 
 			// ask segment how many character fit in remaining space
-			S32 max_characters = end_index - cur_index;
 			S32 character_count = segment->getNumChars(getWordWrap() ? llmax(0, remaining_pixels) : S32_MAX,
 														seg_offset, 
 														cur_index - line_start_index, 
-														max_characters);
-			
+														S32_MAX);
 
-			S32 segment_width = segment->getWidth(seg_offset, character_count);
+			S32 segment_width, segment_height;
+			segment->getDimensions(seg_offset, character_count, segment_width, segment_height);
+			// grow line height as necessary based on reported height of this segment
+			line_height = llmax(line_height, segment_height);
 			remaining_pixels -= segment_width;
 
 			seg_offset += character_count;
@@ -1120,16 +1122,6 @@ void LLTextBase::reflow(S32 start_index)
 			// if we didn't finish the current segment...
 			if (last_segment_char_on_line < segment->getEnd())
 			{
-				// set up index for next line
-				// ...skip newline, we don't want to draw
-				S32 next_line_count = line_count;
-				if (text[last_segment_char_on_line] == '\n')
-				{
-					seg_offset++;
-					last_segment_char_on_line++;
-					next_line_count++;
-				}
-
 				// add line info and keep going
 				mLineInfoList.push_back(line_info(
 											line_start_index, 
@@ -1141,7 +1133,6 @@ void LLTextBase::reflow(S32 start_index)
 				cur_top -= llround((F32)line_height * mLineSpacingMult) + mLineSpacingPixels;
 				remaining_pixels = text_width;
 				line_height = 0;
-				line_count = next_line_count;
 			}
 			// ...just consumed last segment..
 			else if (++segment_set_t::iterator(seg_iter) == mSegments.end())
@@ -1801,7 +1792,8 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round
 
 		S32 segment_line_start = segmentp->getStart() + line_seg_offset;
 		S32 segment_line_length = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd - 1) - segment_line_start;
-		S32 text_width = segmentp->getWidth(line_seg_offset, segment_line_length);
+		S32 text_width, text_height;
+		segmentp->getDimensions(line_seg_offset, segment_line_length, text_width, text_height);
 		if (local_x < start_x + text_width						// cursor to left of right edge of text
 			|| segmentp->getEnd() >= line_iter->mDocIndexEnd - 1)	// or this segment wraps to next line
 		{
@@ -1809,7 +1801,8 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round
 			S32 offset;
 			if (!segmentp->canEdit())
 			{
-				S32 segment_width = segmentp->getWidth(0, segmentp->getEnd() - segmentp->getStart());
+				S32 segment_width, segment_height;
+				segmentp->getDimensions(0, segmentp->getEnd() - segmentp->getStart(), segment_width, segment_height);
 				if (round && local_x - start_x > segment_width / 2)
 				{
 					offset = segment_line_length;
@@ -1868,14 +1861,18 @@ LLRect LLTextBase::getLocalRectFromDocIndex(S32 pos) const
 		if (line_seg_iter == cursor_seg_iter)
 		{
 			// cursor advanced to right based on difference in offset of cursor to start of line
-			local_rect.mLeft += segmentp->getWidth(line_seg_offset, cursor_seg_offset - line_seg_offset);
+			S32 segment_width, segment_height;
+			segmentp->getDimensions(line_seg_offset, cursor_seg_offset - line_seg_offset, segment_width, segment_height);
+			local_rect.mLeft += segment_width;
 
 			break;
 		}
 		else
 		{
 			// add remainder of current text segment to cursor position
-			local_rect.mLeft += segmentp->getWidth(line_seg_offset, (segmentp->getEnd() - segmentp->getStart()) - line_seg_offset);
+			S32 segment_width, segment_height;
+			segmentp->getDimensions(line_seg_offset, (segmentp->getEnd() - segmentp->getStart()) - line_seg_offset, segment_width, segment_height);
+			local_rect.mLeft += segment_width;
 			// offset will be 0 for all segments after the first
 			line_seg_offset = 0;
 			// go to next text segment on this line
@@ -2115,12 +2112,11 @@ LLRect LLTextBase::getVisibleDocumentRect() const
 LLTextSegment::~LLTextSegment()
 {}
 
-S32	LLTextSegment::getWidth(S32 first_char, S32 num_chars) const { return 0; }
+void LLTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const { width = 0; height = 0; }
 S32	LLTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const { return 0; }
 S32	LLTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const { return 0; }
 void LLTextSegment::updateLayout(const LLTextBase& editor) {}
 F32	LLTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect) { return draw_rect.mLeft; }
-S32	LLTextSegment::getMaxHeight() const { return 0; }
 bool LLTextSegment::canEdit() const { return false; }
 void LLTextSegment::unlinkFromDocument(LLTextBase*) {}
 void LLTextSegment::linkToDocument(LLTextBase*) {}
@@ -2158,7 +2154,7 @@ LLNormalTextSegment::LLNormalTextSegment( const LLStyleSP& style, S32 start, S32
 	mToken(NULL),
 	mEditor(editor)
 {
-	mMaxHeight = llceil(mStyle->getFont()->getLineHeight());
+	mFontHeight = llceil(mStyle->getFont()->getLineHeight());
 }
 
 LLNormalTextSegment::LLNormalTextSegment( const LLColor4& color, S32 start, S32 end, LLTextBase& editor, BOOL is_visible) 
@@ -2168,7 +2164,7 @@ LLNormalTextSegment::LLNormalTextSegment( const LLColor4& color, S32 start, S32
 {
 	mStyle = new LLStyle(LLStyle::Params().visible(is_visible).color(color));
 
-	mMaxHeight = llceil(mStyle->getFont()->getLineHeight());
+	mFontHeight = llceil(mStyle->getFont()->getLineHeight());
 }
 
 F32 LLNormalTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect)
@@ -2266,11 +2262,6 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele
 	return right_x;
 }
 
-S32	LLNormalTextSegment::getMaxHeight() const	
-{ 
-	return mMaxHeight; 
-}
-
 BOOL LLNormalTextSegment::handleHover(S32 x, S32 y, MASK mask)
 {
 	if (getStyle() && getStyle()->isLink())
@@ -2344,10 +2335,21 @@ void LLNormalTextSegment::setToolTip(const std::string& tooltip)
 	mTooltip = tooltip;
 }
 
-S32	LLNormalTextSegment::getWidth(S32 first_char, S32 num_chars) const
+void LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const
 {
 	LLWString text = mEditor.getWText();
-	return mStyle->getFont()->getWidth(text.c_str(), mStart + first_char, num_chars);
+
+	// look for any printable character, then return the font height
+	height = 0;
+	for (S32 index = mStart + first_char; index < mStart + first_char + num_chars; ++index)
+	{
+		if (text[index] != '\n')
+		{
+			height = mFontHeight;
+			break;
+		}
+	}
+	width = mStyle->getFont()->getWidth(text.c_str(), mStart + first_char, num_chars);
 }
 
 S32	LLNormalTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const
@@ -2363,6 +2365,17 @@ S32	LLNormalTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset,
 S32	LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const
 {
 	LLWString text = mEditor.getWText();
+
+	// search for newline and if found, truncate there
+	S32 last_char = mStart + segment_offset;
+	for (; last_char != mEnd; ++last_char)
+	{
+		if (text[last_char] == '\n') break;
+	}
+
+	// set max characters to length of segment, or to first newline
+	max_chars = llmin(max_chars, last_char - (mStart + segment_offset));
+
 	S32 num_chars = mStyle->getFont()->maxDrawableChars(text.c_str() + segment_offset + mStart, 
 												(F32)num_pixels,
 												max_chars, 
@@ -2380,6 +2393,10 @@ S32	LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin
 		// include terminating NULL
 		num_chars++;
 	}
+	else if (text[mStart + segment_offset + num_chars] == '\n')
+	{
+		num_chars++;
+	}
 	return num_chars;
 }
 
@@ -2399,9 +2416,10 @@ void LLNormalTextSegment::dump() const
 // LLInlineViewSegment
 //
 
-LLInlineViewSegment::LLInlineViewSegment(LLView* view, S32 start, S32 end)
+LLInlineViewSegment::LLInlineViewSegment(LLView* view, S32 start, S32 end, bool force_new_line)
 :	LLTextSegment(start, end),
-	mView(view)
+	mView(view),
+	mForceNewLine(force_new_line)
 {
 } 
 
@@ -2410,21 +2428,29 @@ LLInlineViewSegment::~LLInlineViewSegment()
 	mView->die();
 }
 
-S32	LLInlineViewSegment::getWidth(S32 first_char, S32 num_chars) const
+void	LLInlineViewSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const
 {
 	if (first_char == 0 && num_chars == 0) 
 	{
-		return 0;
+		// we didn't fit on a line, the widget will fall on the next line
+		// so dimensions here are 0
+		width = 0;
+		height = 0;
 	}
 	else
 	{
-		return mView->getRect().getWidth();
+		width = mView->getRect().getWidth();
+		height = mView->getRect().getHeight();
 	}
 }
 
 S32	LLInlineViewSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const
 {
-	if (line_offset != 0 && num_pixels < mView->getRect().getWidth()) 
+	// if putting a widget anywhere but at the beginning of a line
+	// and the widget doesn't fit or mForceNewLine is true
+	// then return 0 chars for that line, and all characters for the next
+	if (line_offset != 0 
+		&& (mForceNewLine || num_pixels < mView->getRect().getWidth())) 
 	{
 		return 0;
 	}
@@ -2446,11 +2472,6 @@ F32	LLInlineViewSegment::draw(S32 start, S32 end, S32 selection_start, S32 selec
 	return (F32)(draw_rect.mLeft + mView->getRect().getWidth());
 }
 
-S32	LLInlineViewSegment::getMaxHeight() const
-{
-	return mView->getRect().getHeight();
-}
-
 void LLInlineViewSegment::unlinkFromDocument(LLTextBase* editor)
 {
 	editor->removeDocumentChild(mView);
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index ca9b1cc123..c05a31baec 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -366,12 +366,11 @@ public:
 	LLTextSegment(S32 start, S32 end) : mStart(start), mEnd(end){};
 	virtual ~LLTextSegment();
 
-	virtual S32					getWidth(S32 first_char, S32 num_chars) const;
+	virtual void				getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;
 	virtual S32					getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const;
 	virtual S32					getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const;
 	virtual void				updateLayout(const class LLTextBase& editor);
 	virtual F32					draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect);
-	virtual S32					getMaxHeight() const;
 	virtual bool				canEdit() const;
 	virtual void				unlinkFromDocument(class LLTextBase* editor);
 	virtual void				linkToDocument(class LLTextBase* editor);
@@ -418,11 +417,10 @@ public:
 	LLNormalTextSegment( const LLStyleSP& style, S32 start, S32 end, LLTextBase& editor );
 	LLNormalTextSegment( const LLColor4& color, S32 start, S32 end, LLTextBase& editor, BOOL is_visible = TRUE);
 
-	/*virtual*/ S32					getWidth(S32 first_char, S32 num_chars) const;
+	/*virtual*/ void				getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;
 	/*virtual*/ S32					getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const;
 	/*virtual*/ S32					getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const;
 	/*virtual*/ F32					draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect);
-	/*virtual*/ S32					getMaxHeight() const;
 	/*virtual*/ bool				canEdit() const { return true; }
 	/*virtual*/ const LLColor4&		getColor() const					{ return mStyle->getColor(); }
 	/*virtual*/ void 				setColor(const LLColor4 &color)		{ mStyle->setColor(color); }
@@ -446,7 +444,7 @@ protected:
 protected:
 	class LLTextBase&	mEditor;
 	LLStyleSP			mStyle;
-	S32					mMaxHeight;
+	S32					mFontHeight;
 	LLKeywordToken* 	mToken;
 	std::string     	mTooltip;
 };
@@ -460,19 +458,19 @@ public:
 class LLInlineViewSegment : public LLTextSegment
 {
 public:
-	LLInlineViewSegment(LLView* widget, S32 start, S32 end);
+	LLInlineViewSegment(LLView* widget, S32 start, S32 end, bool force_new_line);
 	~LLInlineViewSegment();
-	/*virtual*/ S32			getWidth(S32 first_char, S32 num_chars) const;
+	/*virtual*/ void		getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;
 	/*virtual*/ S32			getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const;
 	/*virtual*/ void		updateLayout(const class LLTextBase& editor);
 	/*virtual*/ F32			draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect);
-	/*virtuaL*/ S32			getMaxHeight() const;
 	/*virtual*/ bool		canEdit() const { return false; }
 	/*virtual*/ void		unlinkFromDocument(class LLTextBase* editor);
 	/*virtual*/ void		linkToDocument(class LLTextBase* editor);
 
 private:
 	LLView* mView;
+	bool	mForceNewLine;
 };
 
 
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 7c925b8899..953c5b292f 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -2276,7 +2276,7 @@ void LLTextEditor::insertText(const std::string &new_text)
 	setEnabled( enabled );
 }
 
-void LLTextEditor::appendWidget(LLView* widget, const std::string &widget_text, bool allow_undo, bool prepend_newline)
+void LLTextEditor::appendWidget(LLView* widget, const std::string &widget_text, bool allow_undo, bool force_new_line)
 {
 	// Save old state
 	S32 selection_start = mSelectionStart;
@@ -2293,17 +2293,9 @@ void LLTextEditor::appendWidget(LLView* widget, const std::string &widget_text,
 	LLWString widget_wide_text;
 
 	// Add carriage return if not first line
-	if (getLength() != 0
-		&& prepend_newline)
-	{
-		widget_wide_text = utf8str_to_wstring(std::string("\n") + widget_text);
-	}
-	else
-	{
-		widget_wide_text = utf8str_to_wstring(widget_text);
-	}
+	widget_wide_text = utf8str_to_wstring(widget_text);
 
-	LLTextSegmentPtr segment = new LLInlineViewSegment(widget, old_length, old_length + widget_text.size());
+	LLTextSegmentPtr segment = new LLInlineViewSegment(widget, old_length, old_length + widget_text.size(), force_new_line);
 	insert(getLength(), widget_wide_text, FALSE, segment);
 
 	needsReflow();
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index e232efbfb3..82f3956855 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -165,7 +165,7 @@ public:
 	// inserts text at cursor
 	void			insertText(const std::string &text);
 
-	void			appendWidget(LLView* widget, const std::string &widget_text, bool allow_undo, bool prepend_newline);
+	void			appendWidget(LLView* widget, const std::string &widget_text, bool allow_undo, bool force_newline);
 	// Non-undoable
 	void			setText(const LLStringExplicit &utf8str);
 
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 80f3867a80..cc21b636f1 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -109,7 +109,7 @@ void LLChatHistory::appendWidgetMessage(const LLUUID& avatar_id, std::string& fr
 		view_text = from + MESSAGE_USERNAME_DATE_SEPARATOR + time;
 	}
 	//Prepare the rect for the view
-	LLRect target_rect = mScroller->getContentWindowRect();
+	LLRect target_rect = getDocumentView()->getRect();
 	target_rect.mLeft += mLeftWidgetPad;
 	target_rect.mRight -= mRightWidgetPad;
 	view->reshape(target_rect.getWidth(), view->getRect().getHeight());
diff --git a/indra/newview/llexpandabletextbox.cpp b/indra/newview/llexpandabletextbox.cpp
index e2d6bcee8f..48b5fc11b7 100644
--- a/indra/newview/llexpandabletextbox.cpp
+++ b/indra/newview/llexpandabletextbox.cpp
@@ -48,10 +48,11 @@ public:
 		mExpanderLabel(more_text)
 	{}
 
-	/*virtual*/ S32		getWidth(S32 first_char, S32 num_chars) const 
+	/*virtual*/ void	getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const 
 	{
 		// more label always spans width of text box
-		return mEditor.getTextRect().getWidth(); 
+		width = mEditor.getTextRect().getWidth(); 
+		height = llceil(mStyle->getFont()->getLineHeight());
 	}
 	/*virtual*/ S32		getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const 
 	{ 
@@ -85,8 +86,9 @@ public:
 									mEditor.getUseEllipses());
 		return right_x;
 	}
-	/*virtual*/ S32		getMaxHeight() const { return llceil(mStyle->getFont()->getLineHeight()); }
 	/*virtual*/ bool	canEdit() const { return false; }
+	// eat handleMouseDown event so we get the mouseup event
+	/*virtual*/ BOOL	handleMouseDown(S32 x, S32 y, MASK mask) { return TRUE; }
 	/*virtual*/ BOOL	handleMouseUp(S32 x, S32 y, MASK mask) { mEditor.onCommit(); return TRUE; }
 	/*virtual*/ BOOL	handleHover(S32 x, S32 y, MASK mask) 
 	{
@@ -126,9 +128,12 @@ void LLExpandableTextBox::LLTextBoxEx::reshape(S32 width, S32 height, BOOL calle
 	}
 }
 
-void LLExpandableTextBox::LLTextBoxEx::setValue(const LLSD& value)
+void LLExpandableTextBox::LLTextBoxEx::setText(const LLStringExplicit& text)
 {
-	LLTextBox::setValue(value);
+	// LLTextBox::setText will obliterate the expander segment, so make sure
+	// we generate it again by clearing mExpanderVisible
+	mExpanderVisible = false;
+	LLTextBox::setText(text);
 
 	// text contents have changed, segments are cleared out
 	// so hide the expander and determine if we need it
@@ -395,7 +400,6 @@ void LLExpandableTextBox::onTopLost()
 void LLExpandableTextBox::setValue(const LLSD& value)
 {
 	collapseTextBox();
-
 	mText = value.asString();
 	mTextBox->setValue(value);
 }
@@ -403,7 +407,6 @@ void LLExpandableTextBox::setValue(const LLSD& value)
 void LLExpandableTextBox::setText(const std::string& str)
 {
 	collapseTextBox();
-
 	mText = str;
 	mTextBox->setText(str);
 }
diff --git a/indra/newview/llexpandabletextbox.h b/indra/newview/llexpandabletextbox.h
index d6401e224f..d45527aabb 100644
--- a/indra/newview/llexpandabletextbox.h
+++ b/indra/newview/llexpandabletextbox.h
@@ -60,7 +60,7 @@ protected:
 
 		// adds or removes "More" link as needed
 		/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
-		/*virtual*/ void setValue(const LLSD& value);
+		/*virtual*/ void setText(const LLStringExplicit& text);
 
 		/**
 		 * Returns difference between text box height and text height.
diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp
index 0ce1ecc6ee..65994dfb30 100644
--- a/indra/newview/llviewertexteditor.cpp
+++ b/indra/newview/llviewertexteditor.cpp
@@ -130,15 +130,17 @@ public:
 		mToolTip = inv_item->getName() + '\n' + inv_item->getDescription();
 	}
 
-	/*virtual*/ S32				getWidth(S32 first_char, S32 num_chars) const
+	/*virtual*/ void getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const
 	{
 		if (num_chars == 0)
 		{
-			return 0;
+			width = 0;
+			height = 0;
 		}
 		else
 		{
-			return EMBEDDED_ITEM_LABEL_PADDING + mImage->getWidth() + mStyle->getFont()->getWidth(mLabel.c_str());
+			width = EMBEDDED_ITEM_LABEL_PADDING + mImage->getWidth() + mStyle->getFont()->getWidth(mLabel.c_str());
+			height = llmax(mImage->getHeight(), llceil(mStyle->getFont()->getLineHeight()));
 		}
 
 	}
@@ -169,10 +171,6 @@ public:
 		return right_x;
 	}
 	
-	/*virtual*/ S32				getMaxHeight() const
-	{
-		return llmax(mImage->getHeight(), llceil(mStyle->getFont()->getLineHeight()));
-	}
 	/*virtual*/ bool			canEdit() const { return false; }
 
 
-- 
GitLab