From da8f2ffb16d6df1ccb9f34ddf6f26d799d2ea127 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Thu, 28 Mar 2013 04:52:24 +0200
Subject: CHUI-855 FIXED Text entry bar auto expand does not resize

---
 indra/llui/llchatentry.cpp       | 32 ++++++++++++++++++++++++++------
 indra/llui/llchatentry.h         |  7 +++++--
 indra/llui/llscrollbar.cpp       |  5 +++++
 indra/llui/llscrollbar.h         |  3 +++
 indra/llui/llscrollcontainer.cpp | 32 ++++++++++++++++++++++++--------
 indra/llui/llscrollcontainer.h   |  4 ++++
 indra/llui/lltextbase.cpp        |  4 ++++
 indra/llui/lltextbase.h          |  6 +++++-
 8 files changed, 76 insertions(+), 17 deletions(-)

(limited to 'indra/llui')

diff --git a/indra/llui/llchatentry.cpp b/indra/llui/llchatentry.cpp
index 9e48dcde7e..6a1b48a08a 100644
--- a/indra/llui/llchatentry.cpp
+++ b/indra/llui/llchatentry.cpp
@@ -25,6 +25,7 @@
  */
 
 #include "linden_common.h"
+#include "llscrollcontainer.h"
 
 #include "llchatentry.h"
 
@@ -42,7 +43,9 @@ LLChatEntry::LLChatEntry(const Params& p)
  	mHasHistory(p.has_history),
  	mIsExpandable(p.is_expandable),
  	mExpandLinesCount(p.expand_lines_count),
- 	mPrevLinesCount(0)
+ 	mPrevLinesCount(0),
+	mSingleLineMode(false),
+	mPrevExpandedLineCount(S32_MAX)
 {
 	// Initialize current history line iterator
 	mCurrentHistoryLine = mLineHistory.begin();
@@ -82,20 +85,23 @@ boost::signals2::connection LLChatEntry::setTextExpandedCallback(const commit_si
 
 void LLChatEntry::expandText()
 {
+	S32 line_count = mSingleLineMode ? 1 : mExpandLinesCount;
+
 	int visible_lines_count = llabs(getVisibleLines(true).first - getVisibleLines(true).second);
-	bool can_expand = getLineCount() <= mExpandLinesCount;
+	bool can_changed = getLineCount() <= line_count || line_count < mPrevExpandedLineCount ;
+	mPrevExpandedLineCount = line_count;
 
 	// true if pasted text has more lines than expand height limit and expand limit is not reached yet
-	bool text_pasted = (getLineCount() > mExpandLinesCount) && (visible_lines_count < mExpandLinesCount);
+	bool text_pasted = (getLineCount() > line_count) && (visible_lines_count < line_count);
 
-	if (mIsExpandable && (can_expand || text_pasted) && getLineCount() != mPrevLinesCount)
+	if (mIsExpandable && (can_changed || text_pasted || mSingleLineMode) && getLineCount() != mPrevLinesCount)
 	{
 		int lines_height = 0;
 		if (text_pasted)
 		{
 			// text is pasted and now mLineInfoList.size() > mExpandLineCounts and mLineInfoList is not empty,
-			// so lines_height is the sum of the last 'mExpandLinesCount' lines height
-			lines_height = (mLineInfoList.end() - mExpandLinesCount)->mRect.mTop - mLineInfoList.back().mRect.mBottom;
+			// so lines_height is the sum of the last 'expanded_line_count' lines height
+			lines_height = (mLineInfoList.end() - line_count)->mRect.mTop - mLineInfoList.back().mRect.mBottom;
 		}
 		else
 		{
@@ -114,6 +120,8 @@ void LLChatEntry::expandText()
 		{
 			(*mTextExpandedSignal)(this, LLSD() );
 		}
+
+		needsReflow();
 	}
 }
 
@@ -235,3 +243,15 @@ BOOL LLChatEntry::handleSpecialKey(const KEY key, const MASK mask)
 
 	return handled;
 }
+
+void LLChatEntry::enableSingleLineMode(bool single_line_mode)
+{
+	if (mScroller)
+	{
+		mScroller->setSize(single_line_mode ? 0 : -1);
+	}
+
+	mSingleLineMode = single_line_mode;
+	mPrevLinesCount = -1;
+	setWordWrap(!single_line_mode);
+}
diff --git a/indra/llui/llchatentry.h b/indra/llui/llchatentry.h
index 49181c8d78..49c8d21450 100644
--- a/indra/llui/llchatentry.h
+++ b/indra/llui/llchatentry.h
@@ -65,6 +65,7 @@ public:
     /*virtual*/ void	onFocusReceived();
     /*virtual*/ void	onFocusLost();
 
+	void enableSingleLineMode(bool single_line_mode);
 	boost::signals2::connection setTextExpandedCallback(const commit_signal_t::slot_type& cb);
 
 private:
@@ -95,9 +96,11 @@ private:
 	line_history_t						mLineHistory;			// line history storage
 	bool								mHasHistory;			// flag for enabled/disabled line history
 	bool								mIsExpandable;
+	bool								mSingleLineMode;
 
-	int									mExpandLinesCount;
-	int									mPrevLinesCount;
+	S32									mExpandLinesCount;
+	S32									mPrevLinesCount;
+	S32									mPrevExpandedLineCount;
 };
 
 #endif /* LLCHATENTRY_H_ */
diff --git a/indra/llui/llscrollbar.cpp b/indra/llui/llscrollbar.cpp
index 5d3bf7a670..13887cbe73 100644
--- a/indra/llui/llscrollbar.cpp
+++ b/indra/llui/llscrollbar.cpp
@@ -642,3 +642,8 @@ void LLScrollbar::onLineDownBtnPressed( const LLSD& data )
 {
 	changeLine( mStepSize, TRUE );
 }
+
+void LLScrollbar::setThickness(S32 thickness)
+{
+	mThickness = thickness < 0 ? LLUI::sSettingGroups["config"]->getS32("UIScrollbarSize") : thickness;
+}
diff --git a/indra/llui/llscrollbar.h b/indra/llui/llscrollbar.h
index ff74f753b9..21fd2d631e 100644
--- a/indra/llui/llscrollbar.h
+++ b/indra/llui/llscrollbar.h
@@ -124,6 +124,9 @@ public:
 
 	void				onLineUpBtnPressed(const LLSD& data);
 	void				onLineDownBtnPressed(const LLSD& data);
+		
+	S32					getThickness() const { return mThickness; }
+	void				setThickness(S32 thickness);
 
 private:
 	void				updateThumbRect();
diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp
index 2fd187a526..cbcce0ece5 100644
--- a/indra/llui/llscrollcontainer.cpp
+++ b/indra/llui/llscrollcontainer.cpp
@@ -73,7 +73,8 @@ LLScrollContainer::Params::Params()
 	hide_scrollbar("hide_scrollbar"),
 	min_auto_scroll_rate("min_auto_scroll_rate", 100),
 	max_auto_scroll_rate("max_auto_scroll_rate", 1000),
-	reserve_scroll_corner("reserve_scroll_corner", false)
+	reserve_scroll_corner("reserve_scroll_corner", false),
+	size("size", -1)
 {}
 
 
@@ -88,9 +89,12 @@ LLScrollContainer::LLScrollContainer(const LLScrollContainer::Params& p)
 	mReserveScrollCorner(p.reserve_scroll_corner),
 	mMinAutoScrollRate(p.min_auto_scroll_rate),
 	mMaxAutoScrollRate(p.max_auto_scroll_rate),
-	mScrolledView(NULL)
+	mScrolledView(NULL),
+	mSize(p.size)
 {
-	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+	static LLUICachedControl<S32> scrollbar_size_control ("UIScrollbarSize", 0);
+	S32 scrollbar_size = (mSize == -1 ? scrollbar_size_control : mSize);
+
 	LLRect border_rect( 0, getRect().getHeight(), getRect().getWidth(), 0 );
 	LLViewBorder::Params params;
 	params.name("scroll border");
@@ -276,7 +280,6 @@ BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask,
 												  EAcceptance* accept,
 												  std::string& tooltip_msg)
 {
-	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
 	// Scroll folder view if needed.  Never accepts a drag or drop.
 	*accept = ACCEPT_NO;
 	BOOL handled = autoScroll(x, y);
@@ -292,7 +295,8 @@ BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask,
 
 bool LLScrollContainer::autoScroll(S32 x, S32 y)
 {
-	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+	static LLUICachedControl<S32> scrollbar_size_control ("UIScrollbarSize", 0);
+	S32 scrollbar_size = (mSize == -1 ? scrollbar_size_control : mSize);
 
 	bool scrolling = false;
 	if( mScrollbar[HORIZONTAL]->getVisible() || mScrollbar[VERTICAL]->getVisible() )
@@ -365,7 +369,9 @@ bool LLScrollContainer::autoScroll(S32 x, S32 y)
 void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const
 {
 	const LLRect& doc_rect = getScrolledViewRect();
-	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+	static LLUICachedControl<S32> scrollbar_size_control ("UIScrollbarSize", 0);
+	S32 scrollbar_size = (mSize == -1 ? scrollbar_size_control : mSize);
+
 	S32 doc_width = doc_rect.getWidth();
 	S32 doc_height = doc_rect.getHeight();
 
@@ -406,7 +412,9 @@ void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height
 
 void LLScrollContainer::draw()
 {
-	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+	static LLUICachedControl<S32> scrollbar_size_control ("UIScrollbarSize", 0);
+	S32 scrollbar_size = (mSize == -1 ? scrollbar_size_control : mSize);
+
 	if (mAutoScrolling)
 	{
 		// add acceleration to autoscroll
@@ -515,7 +523,9 @@ void LLScrollContainer::updateScroll()
 	{
 		return;
 	}
-	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+	static LLUICachedControl<S32> scrollbar_size_control ("UIScrollbarSize", 0);
+	S32 scrollbar_size = (mSize == -1 ? scrollbar_size_control : mSize);
+
 	LLRect doc_rect = mScrolledView->getRect();
 	S32 doc_width = doc_rect.getWidth();
 	S32 doc_height = doc_rect.getHeight();
@@ -716,3 +726,9 @@ S32 LLScrollContainer::getBorderWidth() const
 	return 0;
 }
 
+void LLScrollContainer::setSize(S32 size)
+{
+	mSize = size;
+	mScrollbar[VERTICAL]->setThickness(size);
+	mScrollbar[HORIZONTAL]->setThickness(size);
+}
diff --git a/indra/llui/llscrollcontainer.h b/indra/llui/llscrollcontainer.h
index d87c95b3d7..4eb43539b8 100644
--- a/indra/llui/llscrollcontainer.h
+++ b/indra/llui/llscrollcontainer.h
@@ -68,6 +68,7 @@ public:
 							max_auto_scroll_rate;
 		Optional<LLUIColor>	bg_color;
 		Optional<LLScrollbar::callback_t> scroll_callback;
+		Optional<S32>		size;
 		
 		Params();
 	};
@@ -116,6 +117,9 @@ public:
 	
 	bool autoScroll(S32 x, S32 y);
 
+	S32 getSize() const { return mSize; }
+	void setSize(S32 thickness);
+
 protected:
 	LLView*		mScrolledView;
 
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 270d5294f9..a815cfc176 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -3490,3 +3490,7 @@ F32	LLImageTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 select
 	return 0.0;
 }
 
+void LLTextBase::setWordWrap(bool wrap)
+{
+	mWordWrap = wrap;
+}
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index ad566a36d3..20a73387b5 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -41,6 +41,7 @@
 
 #include <boost/signals2.hpp>
 
+class LLScrollContainer;
 class LLContextMenu;
 class LLUrlMatch;
 
@@ -434,6 +435,9 @@ public:
 	virtual void			appendWidget(const LLInlineViewSegment::Params& params, const std::string& text, bool allow_undo);
 	boost::signals2::connection setURLClickedCallback(const commit_signal_t::slot_type& cb);
 
+	void					setWordWrap(bool wrap);
+	LLScrollContainer*		getScrollContainer() const { return mScroller; }
+
 protected:
 	// helper structs
 	struct compare_bottom;
@@ -634,7 +638,7 @@ protected:
 	// support widgets
 	LLContextMenu*				mPopupMenu;
 	LLView*						mDocumentView;
-	class LLScrollContainer*	mScroller;
+	LLScrollContainer*			mScroller;
 
 	// transient state
 	S32							mReflowIndex;		// index at which to start reflow.  S32_MAX indicates no reflow needed.
-- 
cgit v1.2.3


From e76a4eb7c51ab662d5f463737361cfdb1e82bf67 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 28 Mar 2013 17:31:45 -0700
Subject: CHUI-905 (Viewer crashes while using Insert keyboard key in chat):
 Problem was because when insert was used at the end of a string of text, this
 would attempt to delete something past the bounds of the string...as a side
 effect the size of the segment was increasing even though the string length
 never changed. The segment size would be greater than the string size and
 would eventually cause an invalid read outside the bounds of the string.

---
 indra/llui/lltexteditor.cpp | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

(limited to 'indra/llui')

diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index d5e08fa29b..b8bdea48b5 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -956,12 +956,18 @@ S32 LLTextEditor::insert(S32 pos, const LLWString &wstr, bool group_with_next_op
 S32 LLTextEditor::remove(S32 pos, S32 length, bool group_with_next_op)
 {
 	S32 end_pos = getEditableIndex(pos + length, true);
+	BOOL removedChar = FALSE;
 
 	segment_vec_t segments_to_remove;
 	// store text segments
 	getSegmentsInRange(segments_to_remove, pos, pos + length, false);
+	
+	if(pos <= end_pos)
+	{
+		removedChar = execute( new TextCmdRemove( pos, group_with_next_op, end_pos - pos, segments_to_remove ) );
+	}
 
-	return execute( new TextCmdRemove( pos, group_with_next_op, end_pos - pos, segments_to_remove ) );
+	return removedChar;
 }
 
 S32 LLTextEditor::overwriteChar(S32 pos, llwchar wc)
-- 
cgit v1.2.3


From 7c7ccf27d1638577290ebefcc16dded9390f5f21 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 29 Mar 2013 17:22:53 -0700
Subject: CHUI-807 : Add more defensive coding. Also trace in log the sessions
 created so we'll have a better idea of what people do with conversations if
 we see that crash again.

---
 indra/llui/lltabcontainer.cpp | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

(limited to 'indra/llui')

diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index 6f895ed939..fd98155704 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -1215,9 +1215,11 @@ void LLTabContainer::removeTabPanel(LLPanel* child)
 				removeChild( tuple->mButton );
 			}
  			delete tuple->mButton;
+            tuple->mButton = NULL;
 
  			removeChild( tuple->mTabPanel );
 // 			delete tuple->mTabPanel;
+            tuple->mTabPanel = NULL;
 			
 			mTabList.erase( iter );
 			delete tuple;
@@ -1279,9 +1281,11 @@ void LLTabContainer::deleteAllTabs()
 
 		removeChild( tuple->mButton );
 		delete tuple->mButton;
+        tuple->mButton = NULL;
 
  		removeChild( tuple->mTabPanel );
 // 		delete tuple->mTabPanel;
+        tuple->mTabPanel = NULL;
 	}
 
 	// Actually delete the tuples themselves
@@ -1484,9 +1488,8 @@ BOOL LLTabContainer::setTab(S32 which)
 		{
 			LLTabTuple* tuple = *iter;
 			BOOL is_selected = ( tuple == selected_tuple );
-            
             // Although the selected tab must be complete, we may have hollow LLTabTuple tucked in the list
-            if (tuple->mButton)
+            if (tuple && tuple->mButton)
             {
                 tuple->mButton->setUseEllipses(mUseTabEllipses);
                 tuple->mButton->setHAlign(mFontHalign);
@@ -1494,7 +1497,7 @@ BOOL LLTabContainer::setTab(S32 which)
                 // RN: this limits tab-stops to active button only, which would require arrow keys to switch tabs
                 tuple->mButton->setTabStop( is_selected );
             }
-            if (tuple->mTabPanel)
+            if (tuple && tuple->mTabPanel)
             {
                 tuple->mTabPanel->setVisible( is_selected );
                 //tuple->mTabPanel->setFocus(is_selected); // not clear that we want to do this here.
@@ -1525,7 +1528,7 @@ BOOL LLTabContainer::setTab(S32 which)
 					else
 					{
 						S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + tabcntr_arrow_btn_size  + tabcntr_arrow_btn_size + 1);
-						S32 running_tab_width = tuple->mButton->getRect().getWidth();
+						S32 running_tab_width = (tuple && tuple->mButton ? tuple->mButton->getRect().getWidth() : 0);
 						S32 j = i - 1;
 						S32 min_scroll_pos = i;
 						if (running_tab_width < available_width_with_arrows)
@@ -1533,7 +1536,7 @@ BOOL LLTabContainer::setTab(S32 which)
 							while (j >= 0)
 							{
 								LLTabTuple* other_tuple = getTab(j);
-								running_tab_width += other_tuple->mButton->getRect().getWidth();
+								running_tab_width += (other_tuple && other_tuple->mButton ? other_tuple->mButton->getRect().getWidth() : 0);
 								if (running_tab_width > available_width_with_arrows)
 								{
 									break;
-- 
cgit v1.2.3