From fd846da06cbd1a62023de8e9c3ec61d40e8cd226 Mon Sep 17 00:00:00 2001
From: Richard Nelson <richard@lindenlab.com>
Date: Thu, 8 Oct 2009 01:48:50 +0000
Subject: [PATCH] only add LLScrollContainers to text widgets when requested,
 saving on LLTextBox construction time combined clip and scroll attributes of
 text editors and text boxes...if you want to clip text, you need to introduce
 a scrollbar moved clear to LLTextEditor so that text boxes won't empty out
 when calling LLPanel::clearCtrls() EXT-1354 - added optional wrapping to
 LLTooltips...inspector tooltips don't wrap, everything else does added
 LLFastTimer::reset call on application init to prime timers for pre-login
 timing fixed tooltips positioning incorrectly due to mis-sized tooltipview
 eliminated hide_scrollbar param for text editors

reviewed by Leyla
---
 indra/llui/llsearcheditor.cpp                 |   6 +-
 indra/llui/lltextbase.cpp                     | 192 ++++++++++--------
 indra/llui/lltextbase.h                       |  18 +-
 indra/llui/lltexteditor.cpp                   |   7 +
 indra/llui/lltexteditor.h                     |   1 +
 indra/llui/lltooltip.cpp                      |   2 +
 indra/llui/lltooltip.h                        |   1 +
 indra/newview/llappviewer.cpp                 |   3 +-
 indra/newview/llchatmsgbox.cpp                |   2 +-
 indra/newview/lltoolpie.cpp                   |   6 +-
 indra/newview/llviewerwindow.cpp              |   1 +
 .../default/xui/en/floater_incoming_call.xml  |   1 -
 .../default/xui/en/floater_settings_debug.xml |   1 -
 .../default/xui/en/floater_test_widgets.xml   |   1 +
 .../default/xui/en/panel_audio_device.xml     |   1 -
 .../skins/default/xui/en/panel_avatar_tag.xml |   1 -
 .../skins/default/xui/en/panel_edit_pick.xml  |   1 -
 .../default/xui/en/panel_group_general.xml    |   1 -
 .../default/xui/en/panel_group_notices.xml    |   2 -
 .../default/xui/en/panel_group_roles.xml      |   2 -
 .../skins/default/xui/en/panel_notes.xml      |   1 -
 .../xui/en/panel_teleport_history_item.xml    |   2 +-
 .../xui/en/widgets/expandable_text.xml        |   4 +-
 .../xui/en/widgets/simple_text_editor.xml     |   6 +-
 .../skins/default/xui/en/widgets/text.xml     |   7 +-
 .../skins/default/xui/en/widgets/textbase.xml |   6 +-
 26 files changed, 151 insertions(+), 125 deletions(-)

diff --git a/indra/llui/llsearcheditor.cpp b/indra/llui/llsearcheditor.cpp
index b87f645f3fc..fad2b7bc990 100644
--- a/indra/llui/llsearcheditor.cpp
+++ b/indra/llui/llsearcheditor.cpp
@@ -37,9 +37,9 @@
 #include "llsearcheditor.h"
 
 LLSearchEditor::LLSearchEditor(const LLSearchEditor::Params& p)
-:	LLUICtrl(p)
-	, mSearchButton(NULL)
-	, mClearButton(NULL)
+:	LLUICtrl(p),
+	mSearchButton(NULL),
+	mClearButton(NULL)
 {
 	S32 srch_btn_top = p.search_button.top_pad + p.search_button.rect.height;
 	S32 srch_btn_right = p.search_button.rect.width + p.search_button.left_pad;
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 3dacf979c72..123e59ae6a0 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -122,17 +122,6 @@ struct LLTextBase::line_end_compare
 
 };
 
-//////////////////////////////////////////////////////////////////////////
-//
-// LLTextBase::DocumentPanel
-//
-
-
-LLTextBase::DocumentPanel::DocumentPanel(const Params& p)
-: LLPanel(p)
-{}
-
-
 //////////////////////////////////////////////////////////////////////////
 //
 // LLTextBase
@@ -157,8 +146,7 @@ LLTextBase::Params::Params()
 	bg_readonly_color("bg_readonly_color"),
 	bg_writeable_color("bg_writeable_color"),
 	bg_focus_color("bg_focus_color"),
-	hide_scrollbar("hide_scrollbar"),
-	clip_to_rect("clip_to_rect", true),
+	allow_scroll("allow_scroll", true),
 	track_end("track_end", false),
 	read_only("read_only", false),
 	v_pad("v_pad", 0),
@@ -205,35 +193,44 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
 	mSelectionStart( 0 ),
 	mSelectionEnd( 0 ),
 	mIsSelecting( FALSE ),
-	mClip(p.clip_to_rect),
 	mWordWrap(p.wrap),
 	mUseEllipses( p.use_ellipses ),
 	mParseHTML(p.allow_html),
 	mParseHighlights(p.parse_highlights),
-	mHideScrollbar(p.hide_scrollbar)
-{
-	LLScrollContainer::Params scroll_params;
-	scroll_params.name = "text scroller";
-	scroll_params.rect = getLocalRect();
-	scroll_params.follows.flags = FOLLOWS_ALL;
-	scroll_params.is_opaque = false;
-	scroll_params.mouse_opaque = false;
-	scroll_params.min_auto_scroll_rate = 200;
-	scroll_params.max_auto_scroll_rate = 800;
-	scroll_params.hide_scrollbar = p.hide_scrollbar;
-	scroll_params.border_visible = p.border_visible;
-	mScroller = LLUICtrlFactory::create<LLScrollContainer>(scroll_params);
-	addChild(mScroller);
-
-	LLPanel::Params panel_params;
-	panel_params.name = "text_contents";
-	panel_params.rect =  LLRect(0, 500, 500, 0);
-	panel_params.background_visible = p.bg_visible;
-	panel_params.background_opaque = true;
-	panel_params.mouse_opaque = false;
-
-	mDocumentPanel = LLUICtrlFactory::create<DocumentPanel>(panel_params);
-	mScroller->addChild(mDocumentPanel);
+	mBGVisible(p.bg_visible),
+	mScroller(NULL)
+{
+	if(p.allow_scroll)
+	{
+		LLScrollContainer::Params scroll_params;
+		scroll_params.name = "text scroller";
+		scroll_params.rect = getLocalRect();
+		scroll_params.follows.flags = FOLLOWS_ALL;
+		scroll_params.is_opaque = false;
+		scroll_params.mouse_opaque = false;
+		scroll_params.min_auto_scroll_rate = 200;
+		scroll_params.max_auto_scroll_rate = 800;
+		// all text widgets only show scrollbar on demand
+		scroll_params.hide_scrollbar = true;
+		scroll_params.border_visible = p.border_visible;
+		mScroller = LLUICtrlFactory::create<LLScrollContainer>(scroll_params);
+		addChild(mScroller);
+	}
+
+	LLView::Params view_params;
+	view_params.name = "text_contents";
+	view_params.rect =  LLRect(0, 500, 500, 0);
+	view_params.mouse_opaque = false;
+
+	mDocumentView = LLUICtrlFactory::create<LLView>(view_params);
+	if (mScroller)
+	{
+		mScroller->addChild(mDocumentView);
+	}
+	else
+	{
+		addChild(mDocumentView);
+	}
 
 	createDefaultSegment();
 
@@ -314,7 +311,7 @@ void LLTextBase::drawSelectionBackground()
 		LLRect selection_rect = mTextRect;
 
 		// Skip through the lines we aren't drawing.
-		LLRect content_display_rect = mScroller->getVisibleContentRect();
+		LLRect content_display_rect = getVisibleDocumentRect();
 
 		// binary search for line that starts before top of visible buffer
 		line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mTop, compare_bottom());
@@ -496,8 +493,7 @@ void LLTextBase::drawText()
 		selection_right = llmax( mSelectionStart, mSelectionEnd );
 	}
 
-	LLRect scrolled_view_rect = mScroller->getVisibleContentRect();
-	LLRect content_rect = mScroller->getContentWindowRect();
+	LLRect scrolled_view_rect = getVisibleDocumentRect();
 	std::pair<S32, S32> line_range = getVisibleLines();
 	S32 first_line = line_range.first;
 	S32 last_line = line_range.second;
@@ -540,7 +536,7 @@ void LLTextBase::drawText()
 
 		LLRect text_rect(line.mRect.mLeft + mTextRect.mLeft - scrolled_view_rect.mLeft,
 						line.mRect.mTop - scrolled_view_rect.mBottom + mTextRect.mBottom,
-						mDocumentPanel->getRect().getWidth() - scrolled_view_rect.mLeft,
+						mDocumentView->getRect().getWidth() - scrolled_view_rect.mLeft,
 						line.mRect.mBottom - scrolled_view_rect.mBottom + mTextRect.mBottom);
 
 		// draw a single line of text
@@ -645,6 +641,7 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s
 	}
 
 	onValueChange(pos, pos + insert_len);
+	needsReflow();
 
 	return insert_len;
 }
@@ -704,6 +701,7 @@ S32 LLTextBase::removeStringNoUndo(S32 pos, S32 length)
 	createDefaultSegment();
 
 	onValueChange(pos, pos);
+	needsReflow();
 
 	return -length;	// This will be wrong if someone calls removeStringNoUndo with an excessive length
 }
@@ -719,6 +717,7 @@ S32 LLTextBase::overwriteCharNoUndo(S32 pos, llwchar wc)
     getViewModel()->setDisplay(text);
 
 	onValueChange(pos, pos + 1);
+	needsReflow();
 
 	return 1;
 }
@@ -949,29 +948,31 @@ void LLTextBase::draw()
 	// then update scroll position, as cursor may have moved
 	updateScrollFromCursor();
 
-	LLColor4 bg_color = mReadOnly 
-						? mReadOnlyBgColor.get()
-						: hasFocus() 
-							? mFocusBgColor.get() 
-							: mWriteableBgColor.get();
+	if (mBGVisible)
+	{
+		// clip background rect against extents, if we support scrolling
+		LLLocalClipRect clip(getLocalRect(), mScroller != NULL);
 
-	mDocumentPanel->setBackgroundColor(bg_color);
+		LLColor4 bg_color = mReadOnly 
+							? mReadOnlyBgColor.get()
+							: hasFocus() 
+								? mFocusBgColor.get() 
+								: mWriteableBgColor.get();
+		gl_rect_2d(mDocumentView->getRect(), bg_color, TRUE);
+	}
 
+	// draw document view
 	LLUICtrl::draw();
+
 	{
-		LLLocalClipRect clip(mTextRect, mClip);
+		// only clip if we support scrolling (mScroller != NULL)
+		LLLocalClipRect clip(mTextRect, mScroller != NULL);
 		drawSelectionBackground();
 		drawText();
 		drawCursor();
 	}
 }
 
-//virtual
-void LLTextBase::clear()
-{
-	getViewModel()->setDisplay(LLWStringUtil::null);
-	clearSegments();
-}
 
 //virtual
 void LLTextBase::setColor( const LLColor4& c )
@@ -1000,14 +1001,14 @@ void LLTextBase::updateScrollFromCursor()
 	// Update scroll position even in read-only mode (when there's no cursor displayed)
 	// because startOfDoc()/endOfDoc() modify cursor position. See EXT-736.
 
-	if (!mScrollNeeded)
+	if (!mScrollNeeded || !mScroller)
 	{
 		return;
 	}
 	mScrollNeeded = FALSE; 
 
 	// scroll so that the cursor is at the top of the page
-	LLRect scroller_doc_window = mScroller->getVisibleContentRect();
+	LLRect scroller_doc_window = getVisibleDocumentRect();
 	LLRect cursor_rect_doc = getLocalRectFromDocIndex(mCursorPos);
 	cursor_rect_doc.translate(scroller_doc_window.mLeft, scroller_doc_window.mBottom);
 	mScroller->scrollToShowRect(cursor_rect_doc, LLRect(0, scroller_doc_window.getHeight() - 5, scroller_doc_window.getWidth(), 5));
@@ -1042,7 +1043,7 @@ void LLTextBase::reflow(S32 start_index)
 	{
 		mReflowNeeded = FALSE;
 
-		bool scrolled_to_bottom = mScroller->isAtBottom();
+		bool scrolled_to_bottom = mScroller ? mScroller->isAtBottom() : false;
 
 		LLRect old_cursor_rect = getLocalRectFromDocIndex(mCursorPos);
 		bool follow_selection = mTextRect.overlaps(old_cursor_rect); // cursor is visible
@@ -1183,17 +1184,29 @@ void LLTextBase::reflow(S32 start_index)
 			mContentsRect.stretch(1);
 		}
 
-		// change mDocumentPanel document size to accomodate reflowed text
+		// change mDocumentView size to accomodate reflowed text
 		LLRect document_rect;
-		document_rect.setOriginAndSize(1, 1, 
-									mScroller->getContentWindowRect().getWidth(), 
-									llmax(mScroller->getContentWindowRect().getHeight(), mContentsRect.getHeight()));
-		mDocumentPanel->setShape(document_rect);
+		if (mScroller)
+		{
+			// document is size of scroller or size of text contents, whichever is larger
+			document_rect.setOriginAndSize(0, 0, 
+										mScroller->getContentWindowRect().getWidth(), 
+										llmax(mScroller->getContentWindowRect().getHeight(), mContentsRect.getHeight()));
+		}
+		else
+		{
+			// document size is just extents of reflowed text, reset to origin 0,0
+			document_rect.set(0, 
+							getLocalRect().getHeight(), 
+							getLocalRect().getWidth(), 
+							llmin(0, getLocalRect().getHeight() - mContentsRect.getHeight()));
+		}
+		mDocumentView->setShape(document_rect);
 
 		// after making document big enough to hold all the text, move the text to fit in the document
 		if (!mLineInfoList.empty())
 		{
-			S32 delta_pos = mDocumentPanel->getRect().getHeight() - mLineInfoList.begin()->mRect.mTop - mVPad;
+			S32 delta_pos = mDocumentView->getRect().getHeight() - mLineInfoList.begin()->mRect.mTop - mVPad;
 			// move line segments to fit new document rect
 			for (line_list_t::iterator it = mLineInfoList.begin(); it != mLineInfoList.end(); ++it)
 			{
@@ -1215,9 +1228,9 @@ void LLTextBase::reflow(S32 start_index)
 		}
 
 		// apply scroll constraints after reflowing text
-		if (!hasMouseCapture())
+		if (!hasMouseCapture() && mScroller)
 		{
-			LLRect visible_content_rect = mScroller->getVisibleContentRect();
+			LLRect visible_content_rect = getVisibleDocumentRect();
 			if (scrolled_to_bottom && mTrackEnd)
 			{
 				// keep bottom of text buffer visible
@@ -1329,7 +1342,7 @@ S32 LLTextBase::getLineOffsetFromDocIndex( S32 startpos, bool include_wordwrap)
 
 S32	LLTextBase::getFirstVisibleLine() const
 {
-	LLRect visible_region = mScroller->getVisibleContentRect();
+	LLRect visible_region = getVisibleDocumentRect();
 
 	// binary search for line that starts before top of visible buffer
 	line_list_t::const_iterator iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), visible_region.mTop, compare_bottom());
@@ -1339,7 +1352,7 @@ S32	LLTextBase::getFirstVisibleLine() const
 
 std::pair<S32, S32>	LLTextBase::getVisibleLines(bool fully_visible) 
 {
-	LLRect visible_region = mScroller->getVisibleContentRect();
+	LLRect visible_region = getVisibleDocumentRect();
 	line_list_t::const_iterator first_iter;
 	line_list_t::const_iterator last_iter;
 
@@ -1370,12 +1383,12 @@ LLTextViewModel* LLTextBase::getViewModel() const
 
 void LLTextBase::addDocumentChild(LLView* view) 
 { 
-	mDocumentPanel->addChild(view); 
+	mDocumentView->addChild(view); 
 }
 
 void LLTextBase::removeDocumentChild(LLView* view) 
 { 
-	mDocumentPanel->removeChild(view); 
+	mDocumentView->removeChild(view); 
 }
 
 
@@ -1481,11 +1494,10 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
 void LLTextBase::setText(const LLStringExplicit &utf8str)
 {
 	// clear out the existing text and segments
-	clear();
-
-	truncate();
+	getViewModel()->setDisplay(LLWStringUtil::null);
 
-	createDefaultSegment();
+	clearSegments();
+//	createDefaultSegment();
 
 	startOfDoc();
 	deselect();
@@ -1496,10 +1508,9 @@ void LLTextBase::setText(const LLStringExplicit &utf8str)
 
 	appendText(text, false);
 
-	needsReflow();
-
 	//resetDirty();
 	onValueChange(0, getLength());
+	needsReflow();
 }
 
 //virtual
@@ -1767,7 +1778,7 @@ LLWString LLTextBase::getWText() const
 S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const
 {
 	// Figure out which line we're nearest to.
-	LLRect visible_region = mScroller->getVisibleContentRect();
+	LLRect visible_region = getVisibleDocumentRect();
 
 	// binary search for line that starts before local_y
 	line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), local_y - mTextRect.mBottom + visible_region.mBottom, compare_bottom());
@@ -1838,7 +1849,7 @@ LLRect LLTextBase::getLocalRectFromDocIndex(S32 pos) const
 	// find line that contains cursor
 	line_list_t::const_iterator line_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), pos, line_end_compare());
 
-	LLRect scrolled_view_rect = mScroller->getVisibleContentRect();
+	LLRect scrolled_view_rect = getVisibleDocumentRect();
 	local_rect.mLeft = mTextRect.mLeft - scrolled_view_rect.mLeft + line_iter->mRect.mLeft; 
 	local_rect.mBottom = mTextRect.mBottom + (line_iter->mRect.mBottom - scrolled_view_rect.mBottom);
 	local_rect.mTop = mTextRect.mBottom + (line_iter->mRect.mTop - scrolled_view_rect.mBottom);
@@ -1917,7 +1928,7 @@ void LLTextBase::endOfDoc()
 void LLTextBase::changePage( S32 delta )
 {
 	const S32 PIXEL_OVERLAP_ON_PAGE_CHANGE = 10;
-	if (delta == 0) return;
+	if (delta == 0 || !mScroller) return;
 
 	LLRect cursor_rect = getLocalRectFromDocIndex(mCursorPos);
 
@@ -1970,7 +1981,7 @@ void LLTextBase::changeLine( S32 delta )
 		new_line = line + 1;
 	}
 
-	LLRect visible_region = mScroller->getVisibleContentRect();
+	LLRect visible_region = getVisibleDocumentRect();
 
 	S32 new_cursor_pos = getDocIndexFromLocalCoord(mDesiredXPixel, mLineInfoList[new_line].mRect.mBottom + mTextRect.mBottom - visible_region.mBottom, TRUE);
 	setCursorPos(new_cursor_pos, true);
@@ -2047,7 +2058,7 @@ S32 LLTextBase::getEditableIndex(S32 index, bool increasing_direction)
 void LLTextBase::updateTextRect()
 {
 	LLRect old_text_rect = mTextRect;
-	mTextRect = mScroller->getContentWindowRect();
+	mTextRect = mScroller ? mScroller->getContentWindowRect() : getLocalRect();
 	//FIXME: replace border with image?
 	if (mBorderVisible)
 	{
@@ -2081,6 +2092,22 @@ void LLTextBase::endSelection()
 	}
 }
 
+// get portion of document that is visible in text editor
+LLRect LLTextBase::getVisibleDocumentRect() const
+{
+	if (mScroller)
+	{
+		return mScroller->getVisibleContentRect();
+	}
+	else
+	{
+		// entire document rect when not scrolling
+		LLRect doc_rect = mDocumentView->getLocalRect();
+		doc_rect.translate(-mDocumentView->getRect().mLeft, -mDocumentView->getRect().mBottom);
+		return doc_rect;
+	}
+}
+
 //
 // LLTextSegment
 //
@@ -2150,6 +2177,7 @@ F32 LLNormalTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selec
 	{
 		if ( mStyle->isImage() && (start >= 0) && (end <= mEnd - mStart))
 		{
+			LLColor4 color = LLColor4::white % mEditor.getDrawContext().mAlpha;
 			LLUIImagePtr image = mStyle->getImage();
 			S32 style_image_height = image->getHeight();
 			S32 style_image_width = image->getWidth();
@@ -2398,7 +2426,7 @@ S32	LLInlineViewSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin
 void LLInlineViewSegment::updateLayout(const LLTextBase& editor)
 {
 	LLRect start_rect = editor.getLocalRectFromDocIndex(mStart);
-	LLRect doc_rect = editor.getDocumentPanel()->getRect();
+	LLRect doc_rect = editor.getDocumentView()->getRect();
 	mView->setOrigin(doc_rect.mLeft + start_rect.mLeft, doc_rect.mBottom + start_rect.mBottom);
 }
 
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index f20134fd6d1..903396c78ab 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -80,8 +80,7 @@ class LLTextBase
 								border_visible,
 								track_end,
 								read_only,
-								hide_scrollbar,
-								clip_to_rect,
+								allow_scroll,
 								wrap,
 								use_ellipses,
 								allow_html,
@@ -118,7 +117,6 @@ class LLTextBase
 
 	// LLUICtrl interface
 	/*virtual*/ BOOL		acceptsTextInput() const { return !mReadOnly; }
-	/*virtual*/ void		clear();
 	/*virtual*/ void		setColor( const LLColor4& c );
 	/*virtual*/ void		setValue(const LLSD& value );
 	/*virtual*/ LLTextViewModel* getViewModel() const;
@@ -149,16 +147,13 @@ class LLTextBase
 	S32						getLength() const { return getWText().length(); }
 	S32						getLineCount() const { return mLineInfoList.size(); }
 
-	class DocumentPanel : public LLPanel
-	{
-	public:
-		DocumentPanel(const Params&);
-	};
 	void					addDocumentChild(LLView* view);
 	void					removeDocumentChild(LLView* view);
-	const DocumentPanel*	getDocumentPanel() const { return mDocumentPanel; }
+	const LLView*			getDocumentView() const { return mDocumentView; }
 	LLRect					getTextRect() { return mTextRect; }
 	LLRect					getContentsRect();
+	LLRect					getVisibleDocumentRect() const;
+
 
 	S32						getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const;
 	LLRect					getLocalRectFromDocIndex(S32 pos) const;
@@ -344,13 +339,12 @@ class LLTextBase
 	bool						mUseEllipses;
 	bool						mTrackEnd;			// if true, keeps scroll position at end of document during resize
 	bool						mReadOnly;
-	bool						mClip;
-	bool						mHideScrollbar;
+	bool						mBGVisible;			// render background?
 	S32							mMaxTextByteLength;	// Maximum length mText is allowed to be in bytes
 
 	// support widgets
 	LLContextMenu*				mPopupMenu;
-	DocumentPanel*				mDocumentPanel;
+	LLView*						mDocumentView;
 	class LLScrollContainer*	mScroller;
 
 	// transient state
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 997c5b8fa8e..74373e7803f 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -2916,3 +2916,10 @@ void LLTextEditor::onKeyStroke()
 {
 	mKeystrokeSignal(this);
 }
+
+//virtual
+void LLTextEditor::clear()
+{
+	getViewModel()->setDisplay(LLWStringUtil::null);
+	clearSegments();
+}
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 0e5707a3a63..e232efbfb34 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -116,6 +116,7 @@ class LLTextEditor :
 	virtual void	setEnabled(BOOL enabled);
 
 	// uictrl overrides
+	virtual void	clear();
 	virtual void	setFocus( BOOL b );
 	virtual BOOL	isDirty() const;
 
diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp
index c55273cacfe..f30e56b907a 100644
--- a/indra/llui/lltooltip.cpp
+++ b/indra/llui/lltooltip.cpp
@@ -147,6 +147,7 @@ static LLDefaultChildRegistry::Register<LLToolTip> r("tool_tip");
 LLToolTip::Params::Params()
 :	max_width("max_width", 200),
 	padding("padding", 4),
+	wrap("wrap", true),
 	pos("pos"),
 	message("message"),
 	delay_time("delay_time", LLUI::sSettingGroups["config"]->getF32( "ToolTipDelay" )),
@@ -181,6 +182,7 @@ LLToolTip::LLToolTip(const LLToolTip::Params& p)
 	params.bg_visible = false;
 	params.font = p.font;
 	params.use_ellipses = true;
+	params.wrap = p.wrap;
 	mTextBox = LLUICtrlFactory::create<LLTextBox> (params);
 	addChild(mTextBox);
 
diff --git a/indra/llui/lltooltip.h b/indra/llui/lltooltip.h
index 6715da16115..63e7249a12b 100644
--- a/indra/llui/lltooltip.h
+++ b/indra/llui/lltooltip.h
@@ -83,6 +83,7 @@ class LLToolTip : public LLPanel
 		Optional<LLUIImage*>		image;
 		Optional<S32>				max_width;
 		Optional<S32>				padding;
+		Optional<bool>				wrap;
 
 		Params();
 	};
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 41cbc21fe9b..d47b994322b 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -594,7 +594,8 @@ bool LLAppViewer::init()
 	// into the log files during normal startup until AFTER
 	// we run the "program crashed last time" error handler below.
 	//
-	
+	LLFastTimer::reset();
+
 	// Need to do this initialization before we do anything else, since anything
 	// that touches files should really go through the lldir API
 	gDirUtilp->initAppDirs("SecondLife");
diff --git a/indra/newview/llchatmsgbox.cpp b/indra/newview/llchatmsgbox.cpp
index 6eaafc90598..12626e3b43b 100644
--- a/indra/newview/llchatmsgbox.cpp
+++ b/indra/newview/llchatmsgbox.cpp
@@ -59,7 +59,7 @@ class ChatSeparator : public LLTextSegment
 
 	/*virtual*/ S32 getWidth(S32 first_char, S32 num_chars) const
 	{
-		return mEditor->getDocumentPanel()->getRect().getWidth();
+		return mEditor->getDocumentView()->getRect().getWidth();
 	}
 
 	/*virtual*/ F32	draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect)
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index beb16c267eb..b015f668e4a 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -703,7 +703,8 @@ BOOL LLToolPie::handleToolTip(S32 local_x, S32 local_y, MASK mask)
 					.image(LLUI::getUIImage("Info"))
 					.click_callback(boost::bind(showAvatarInspector, hover_object->getID()))
 					.visible_time_near(6.f)
-					.visible_time_far(3.f));
+					.visible_time_far(3.f)
+					.wrap(false));
 			}
 		}
 		else
@@ -746,7 +747,8 @@ BOOL LLToolPie::handleToolTip(S32 local_x, S32 local_y, MASK mask)
 						.image(LLUI::getUIImage("Info"))
 						.click_callback(boost::bind(showObjectInspector, hover_object->getID()))
 						.visible_time_near(6.f)
-						.visible_time_far(3.f));
+						.visible_time_far(3.f)
+						.wrap(false));
 				}
 			}
 		}
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 24d00cba169..22141011a2b 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1465,6 +1465,7 @@ void LLViewerWindow::initBase()
 	LLToolTipView::Params hvp;
 	hvp.name("tooltip view");
 	hvp.rect(full_window);
+	hvp.follows.flags(FOLLOWS_ALL);
 	gToolTipView = LLUICtrlFactory::create<LLToolTipView>(hvp);
 	getRootView()->addChild(gToolTipView);
 
diff --git a/indra/newview/skins/default/xui/en/floater_incoming_call.xml b/indra/newview/skins/default/xui/en/floater_incoming_call.xml
index bdce8fa4fcb..95e4247a058 100644
--- a/indra/newview/skins/default/xui/en/floater_incoming_call.xml
+++ b/indra/newview/skins/default/xui/en/floater_incoming_call.xml
@@ -34,7 +34,6 @@
      font="SansSerif"
      height="64"
      border_visible="false"
-     hide_scrollbar="true"
      layout="topleft"
      left="77"
      max_length="2147483647"
diff --git a/indra/newview/skins/default/xui/en/floater_settings_debug.xml b/indra/newview/skins/default/xui/en/floater_settings_debug.xml
index e2f4a73ec84..b7779687ec3 100644
--- a/indra/newview/skins/default/xui/en/floater_settings_debug.xml
+++ b/indra/newview/skins/default/xui/en/floater_settings_debug.xml
@@ -23,7 +23,6 @@
     <text_editor
      enabled="false"
      height="60"
-     hide_scrollbar="true"
      layout="topleft"
      left_delta="0"
      name="comment_text"
diff --git a/indra/newview/skins/default/xui/en/floater_test_widgets.xml b/indra/newview/skins/default/xui/en/floater_test_widgets.xml
index 8ed2047a279..cc0fc34dd59 100644
--- a/indra/newview/skins/default/xui/en/floater_test_widgets.xml
+++ b/indra/newview/skins/default/xui/en/floater_test_widgets.xml
@@ -277,6 +277,7 @@
    follows="top|left" 
    label="Spinner"
    layout="topleft"
+   label_width="45" 
    name="test_spinner" 
    tool_tip="spinner"/>
   <text
diff --git a/indra/newview/skins/default/xui/en/panel_audio_device.xml b/indra/newview/skins/default/xui/en/panel_audio_device.xml
index 4329982209f..546f46205f6 100644
--- a/indra/newview/skins/default/xui/en/panel_audio_device.xml
+++ b/indra/newview/skins/default/xui/en/panel_audio_device.xml
@@ -81,7 +81,6 @@
      enabled="false"
      height="60"
      border_visible="false"
-     hide_scrollbar="true"
      layout="topleft"
      left_delta="10"
      max_length="65535"
diff --git a/indra/newview/skins/default/xui/en/panel_avatar_tag.xml b/indra/newview/skins/default/xui/en/panel_avatar_tag.xml
index 34b4736979f..e4f6e7bd44e 100644
--- a/indra/newview/skins/default/xui/en/panel_avatar_tag.xml
+++ b/indra/newview/skins/default/xui/en/panel_avatar_tag.xml
@@ -61,7 +61,6 @@
      font="SansSerifSmall" 
      read_only="true"
      bg_readonly_color="0 0 0 0"
-     hide_scrollbar="true"
      word_wrap="true"
      mouse_opaque="true" 
      name="msg_text" >
diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
index 5dd03656c66..b9a01d80f93 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
@@ -120,7 +120,6 @@
          follows="left|top|right"
          height="100"
          width="220"
-         hide_scrollbar="true"
          layout="topleft"
          left="10"
          top_pad="2"
diff --git a/indra/newview/skins/default/xui/en/panel_group_general.xml b/indra/newview/skins/default/xui/en/panel_group_general.xml
index 03e2d35b9ff..e49914d5e69 100644
--- a/indra/newview/skins/default/xui/en/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_general.xml
@@ -45,7 +45,6 @@ Hover your mouse over the options for more help.
      follows="left|top"
      left="5"
      height="75"
-     hide_scrollbar="true"
      layout="topleft"
      max_length="511"
      name="charter"
diff --git a/indra/newview/skins/default/xui/en/panel_group_notices.xml b/indra/newview/skins/default/xui/en/panel_group_notices.xml
index ffc2f279bcb..82a3c98dd92 100644
--- a/indra/newview/skins/default/xui/en/panel_group_notices.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_notices.xml
@@ -187,7 +187,6 @@ the General tab.
         </text>
         <text_editor
          height="75"
-         hide_scrollbar="true"
          layout="topleft"
          left_pad="3"
          max_length="511"
@@ -344,7 +343,6 @@ the General tab.
         <text_editor
          enabled="false"
          height="150"
-         hide_scrollbar="true"
          layout="topleft"
          left="10"
          max_length="511"
diff --git a/indra/newview/skins/default/xui/en/panel_group_roles.xml b/indra/newview/skins/default/xui/en/panel_group_roles.xml
index 7b8bd8b3373..64359511578 100644
--- a/indra/newview/skins/default/xui/en/panel_group_roles.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml
@@ -625,7 +625,6 @@ things in this group. There&apos;s a broad variety of Abilities.
          type="string"
          halign="left"
          height="48"
-         hide_scrollbar="true"
          layout="topleft"
          left="135"
          max_length="254"
@@ -723,7 +722,6 @@ things in this group. There&apos;s a broad variety of Abilities.
          enabled="false"
          halign="left"
          height="48"
-         hide_scrollbar="true"
          layout="topleft"
          left_delta="0"
          max_length="512"
diff --git a/indra/newview/skins/default/xui/en/panel_notes.xml b/indra/newview/skins/default/xui/en/panel_notes.xml
index 2056ec14d52..4274a37497a 100644
--- a/indra/newview/skins/default/xui/en/panel_notes.xml
+++ b/indra/newview/skins/default/xui/en/panel_notes.xml
@@ -58,7 +58,6 @@
                 <text_editor
                  follows="left|top"
                  height="200"
-                 hide_scrollbar="true"
                  layout="topleft"
                  left="10"
                  max_length="1000"
diff --git a/indra/newview/skins/default/xui/en/panel_teleport_history_item.xml b/indra/newview/skins/default/xui/en/panel_teleport_history_item.xml
index d640d3ad884..63c2d4538e5 100644
--- a/indra/newview/skins/default/xui/en/panel_teleport_history_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_teleport_history_item.xml
@@ -42,7 +42,7 @@
      height="20"
      layout="topleft"
      left_pad="5"
-     use_ellipsis="true"
+     use_ellipses="true"
      name="region"
      text_color="white"
      top="4"
diff --git a/indra/newview/skins/default/xui/en/widgets/expandable_text.xml b/indra/newview/skins/default/xui/en/widgets/expandable_text.xml
index 6381dce1d6b..120deaaef53 100644
--- a/indra/newview/skins/default/xui/en/widgets/expandable_text.xml
+++ b/indra/newview/skins/default/xui/en/widgets/expandable_text.xml
@@ -8,8 +8,8 @@
   use_ellipses="true"
   word_wrap="true"
   tab_stop="true"
-  v_pad="2"
-  h_pad="3" >
+  v_pad="3"
+  h_pad="4" >
  </textbox>
  <scroll
   name="scroll"
diff --git a/indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml b/indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml
index 8ace7b96bc2..bb46ec09541 100644
--- a/indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml
+++ b/indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml
@@ -5,7 +5,7 @@
   font="SansSerifSmall"
   max_length="255" 
   embedded_items="false" 
-  hide_scrollbar="false"
+  allow_scroll="true"
   border_visible="false"
   word_wrap="false" 
   ignore_tab="true"
@@ -15,8 +15,8 @@
   default_color="TextDefaultColor"
   text_color="TextFgColor"
   text_readonly_color="TextFgReadOnlyColor"
-  h_pad="5" 
-  v_pad="3"
+  h_pad="6" 
+  v_pad="4"
   bg_visible="true"
   bg_readonly_color="TextBgReadOnlyColor"
   bg_writeable_color="TextBgWriteableColor"
diff --git a/indra/newview/skins/default/xui/en/widgets/text.xml b/indra/newview/skins/default/xui/en/widgets/text.xml
index 5914c21b2be..22bda459239 100644
--- a/indra/newview/skins/default/xui/en/widgets/text.xml
+++ b/indra/newview/skins/default/xui/en/widgets/text.xml
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <text allow_html="true"
-      clip_to_rect="false"
       mouse_opaque="false" 
       name="text_box" 
       font="SansSerifSmall"
@@ -8,8 +7,8 @@
       tab_stop="false" 
       halign="left" 
       hover_color="LabelSelectedColor" 
-      h_pad="-1" 
-      hide_scrollbar="true"
+      h_pad="0" 
+      allow_scroll="false"
       text_readonly_color="LabelDisabledColor"
       bg_writeable_color="FloaterDefaultBackgroundColor" 
       border_color="DefaultHighlightLight"
@@ -18,5 +17,5 @@
       border_visible="false" 
       hover="false" 
       text_color="LabelTextColor"
-      v_pad="-1"
+      v_pad="0"
       max_length="4096"/>
diff --git a/indra/newview/skins/default/xui/en/widgets/textbase.xml b/indra/newview/skins/default/xui/en/widgets/textbase.xml
index c352abca3bb..e5dc0226335 100644
--- a/indra/newview/skins/default/xui/en/widgets/textbase.xml
+++ b/indra/newview/skins/default/xui/en/widgets/textbase.xml
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<textbase clip_to_rect="true"
-          h_pad="4"
-          v_pad="4"/>
+<textbase allow_scroll="true"
+          h_pad="5"
+          v_pad="5"/>
-- 
GitLab