From 83fb99a9ac2f07334233e7307cc18a4d340c8527 Mon Sep 17 00:00:00 2001
From: richard <none@none>
Date: Wed, 4 Nov 2009 18:28:45 -0800
Subject: [PATCH] ext-2038 - script editor, cursor becomes stuck in some rows
 ext-2037 0 Script editor, garbage characters inserted in text

---
 indra/llui/lltextbase.cpp             | 28 +++++++++++++++++++++------
 indra/llui/lltextbase.h               |  6 +++---
 indra/newview/llexpandabletextbox.cpp |  3 ++-
 indra/newview/llparticipantlist.cpp   |  3 +++
 indra/newview/llviewertexteditor.cpp  |  4 ++--
 5 files changed, 32 insertions(+), 12 deletions(-)

diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index e5aac0d5e7..97ba691341 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -1108,7 +1108,7 @@ void LLTextBase::reflow(S32 start_index)
 														S32_MAX);
 
 			S32 segment_width, segment_height;
-			segment->getDimensions(seg_offset, character_count, segment_width, segment_height);
+			bool force_newline = 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;
@@ -1153,6 +1153,18 @@ void LLTextBase::reflow(S32 start_index)
 			else
 			{
 				// subtract pixels used and increment segment
+				if (force_newline)
+				{
+					mLineInfoList.push_back(line_info(
+												line_start_index, 
+												last_segment_char_on_line, 
+												line_rect, 
+												line_count));
+					line_start_index = segment->getStart() + seg_offset;
+					cur_top -= llround((F32)line_height * mLineSpacingMult) + mLineSpacingPixels;
+					line_height = 0;
+					remaining_pixels = text_width;
+				}
 				++seg_iter;
 				seg_offset = 0;
 			}
@@ -2124,7 +2136,7 @@ LLRect LLTextBase::getVisibleDocumentRect() const
 LLTextSegment::~LLTextSegment()
 {}
 
-void LLTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const { width = 0; height = 0; }
+bool LLTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const { width = 0; height = 0; return false;}
 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) {}
@@ -2352,12 +2364,13 @@ void LLNormalTextSegment::setToolTip(const std::string& tooltip)
 	mTooltip = tooltip;
 }
 
-void LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const
+bool LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const
 {
 	LLWString text = mEditor.getWText();
 
 	height = mFontHeight;
 	width = mStyle->getFont()->getWidth(text.c_str(), mStart + first_char, num_chars);
+	return num_chars >= 1 && text[mStart + num_chars - 1] == '\n';
 }
 
 S32	LLNormalTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const
@@ -2404,8 +2417,9 @@ S32	LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin
 	// but not both
 	S32 last_char_in_run = mStart + segment_offset + num_chars;
 	// check length first to avoid indexing off end of string
-	if (last_char_in_run >= mEditor.getLength() 
-		|| text[last_char_in_run] == '\n')
+	if (last_char_in_run < mEnd 
+		&& (last_char_in_run >= mEditor.getLength() 
+			|| text[last_char_in_run] == '\n'))
 	{
 		num_chars++;
 	}
@@ -2444,7 +2458,7 @@ LLInlineViewSegment::~LLInlineViewSegment()
 	mView->die();
 }
 
-void	LLInlineViewSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const
+bool LLInlineViewSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const
 {
 	if (first_char == 0 && num_chars == 0) 
 	{
@@ -2458,6 +2472,8 @@ void	LLInlineViewSegment::getDimensions(S32 first_char, S32 num_chars, S32& widt
 		width = mLeftPad + mRightPad + mView->getRect().getWidth();
 		height = mBottomPad + mTopPad + mView->getRect().getHeight();
 	}
+
+	return false;
 }
 
 S32	LLInlineViewSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 4cca522a23..8cae8fde22 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -370,7 +370,7 @@ public:
 	LLTextSegment(S32 start, S32 end) : mStart(start), mEnd(end){};
 	virtual ~LLTextSegment();
 
-	virtual void				getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;
+	virtual bool				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);
@@ -421,7 +421,7 @@ 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*/ void				getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;
+	/*virtual*/ bool				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);
@@ -474,7 +474,7 @@ public:
 
 	LLInlineViewSegment(const Params& p, S32 start, S32 end);
 	~LLInlineViewSegment();
-	/*virtual*/ void		getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;
+	/*virtual*/ bool		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);
diff --git a/indra/newview/llexpandabletextbox.cpp b/indra/newview/llexpandabletextbox.cpp
index 7bc48185e6..424d635321 100644
--- a/indra/newview/llexpandabletextbox.cpp
+++ b/indra/newview/llexpandabletextbox.cpp
@@ -48,11 +48,12 @@ public:
 		mExpanderLabel(more_text)
 	{}
 
-	/*virtual*/ void	getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const 
+	/*virtual*/ bool	getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const 
 	{
 		// more label always spans width of text box
 		width = mEditor.getTextRect().getWidth() - mEditor.getHPad(); 
 		height = llceil(mStyle->getFont()->getLineHeight());
+		return true;
 	}
 	/*virtual*/ S32		getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const 
 	{ 
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 9450bee315..c373cef6f3 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -42,6 +42,9 @@
 #include "llspeakers.h"
 
 //LLParticipantList retrieves add, clear and remove events and updates view accordingly 
+#if LL_MSVC
+#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
+#endif
 LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* avatar_list):
 	mSpeakerMgr(data_source),
 	mAvatarList(avatar_list),
diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp
index 90dff465c9..75555efe7a 100644
--- a/indra/newview/llviewertexteditor.cpp
+++ b/indra/newview/llviewertexteditor.cpp
@@ -171,7 +171,7 @@ public:
 		mToolTip = inv_item->getName() + '\n' + inv_item->getDescription();
 	}
 
-	/*virtual*/ void getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const
+	/*virtual*/ bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const
 	{
 		if (num_chars == 0)
 		{
@@ -183,7 +183,7 @@ public:
 			width = EMBEDDED_ITEM_LABEL_PADDING + mImage->getWidth() + mStyle->getFont()->getWidth(mLabel.c_str());
 			height = llmax(mImage->getHeight(), llceil(mStyle->getFont()->getLineHeight()));
 		}
-
+		return false;
 	}
 
 	/*virtual*/ S32				getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const 
-- 
GitLab