summaryrefslogtreecommitdiff
path: root/indra/llui/lltexteditor.cpp
diff options
context:
space:
mode:
authorMark Palange <palange@lindenlab.com>2008-11-21 01:18:39 +0000
committerMark Palange <palange@lindenlab.com>2008-11-21 01:18:39 +0000
commitac68eb16a2dac453fe85b7218297f561b8fc96ca (patch)
treea1e26d95326b610c6d2a740ee80071bfb866d8e9 /indra/llui/lltexteditor.cpp
parent77c108b2c4879fbbb168f91fed7763a0b557ecab (diff)
Merging the changes in viewer_1-22-0 (1.22 RC0) back into trunk, revs. 101837 to 103519
Diffstat (limited to 'indra/llui/lltexteditor.cpp')
-rw-r--r--indra/llui/lltexteditor.cpp140
1 files changed, 67 insertions, 73 deletions
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index f935432e57..197f8d98cf 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -260,7 +260,7 @@ LLTextEditor::LLTextEditor(
mIsSelecting( FALSE ),
mSelectionStart( 0 ),
mSelectionEnd( 0 ),
- mScrolledToBottom( FALSE ),
+ mScrolledToBottom( TRUE ),
mOnScrollEndCallback( NULL ),
mOnScrollEndData( NULL ),
mCursorColor( LLUI::sColorsGroup->getColor( "TextCursorColor" ) ),
@@ -277,14 +277,16 @@ LLTextEditor::LLTextEditor(
mCommitOnFocusLost( FALSE ),
mHideScrollbarForShortDocs( FALSE ),
mTakesNonScrollClicks( TRUE ),
- mTrackBottom( TRUE ),
+ mTrackBottom( FALSE ),
mAllowEmbeddedItems( allow_embedded_items ),
mAcceptCallingCardNames(FALSE),
mHandleEditKeysDirectly( FALSE ),
mMouseDownX(0),
mMouseDownY(0),
mLastSelectionX(-1),
- mLastSelectionY(-1)
+ mLastSelectionY(-1),
+ mReflowNeeded(FALSE),
+ mScrollNeeded(FALSE)
{
mSourceID.generate();
@@ -468,6 +470,13 @@ void LLTextEditor::updateLineStartList(S32 startpos)
mScrollbar->setVisible(!short_doc);
}
+ // if scrolled to bottom, stay at bottom
+ // unless user is editing text
+ // do this after updating page size
+ if (mScrolledToBottom && mTrackBottom && !hasFocus())
+ {
+ endOfDoc();
+ }
}
////////////////////////////////////////////////////////////
@@ -511,8 +520,7 @@ void LLTextEditor::setText(const LLStringExplicit &utf8str)
setCursorPos(0);
deselect();
- updateLineStartList();
- updateScrollFromCursor();
+ needsReflow();
resetDirty();
}
@@ -529,8 +537,7 @@ void LLTextEditor::setWText(const LLWString &wtext)
setCursorPos(0);
deselect();
- updateLineStartList();
- updateScrollFromCursor();
+ needsReflow();
resetDirty();
}
@@ -568,8 +575,7 @@ void LLTextEditor::setWordWrap(BOOL b)
setCursorPos(0);
deselect();
- updateLineStartList();
- updateScrollFromCursor();
+ needsReflow();
}
@@ -734,6 +740,7 @@ S32 LLTextEditor::getLineStart( S32 line ) const
{
return 0;
}
+
line = llclamp(line, 0, num_lines-1);
S32 segidx = mLineStartList[line].mSegment;
S32 segoffset = mLineStartList[line].mOffset;
@@ -781,14 +788,14 @@ void LLTextEditor::getSegmentAndOffset( S32 startpos, S32* segidxp, S32* offsetp
*offsetp = startpos - (*seg_iter)->getStart();
}
-const LLTextSegment* LLTextEditor::getPreviousSegment()
+const LLTextSegment* LLTextEditor::getPreviousSegment() const
{
// find segment index at character to left of cursor (or rightmost edge of selection)
S32 idx = llmax(0, getSegmentIdxAtOffset(mCursorPos) - 1);
return idx >= 0 ? mSegments[idx] : NULL;
}
-void LLTextEditor::getSelectedSegments(std::vector<const LLTextSegment*>& segments)
+void LLTextEditor::getSelectedSegments(std::vector<const LLTextSegment*>& segments) const
{
S32 left = hasSelection() ? llmin(mSelectionStart, mSelectionEnd) : mCursorPos;
S32 right = hasSelection() ? llmax(mSelectionStart, mSelectionEnd) : mCursorPos;
@@ -875,13 +882,12 @@ void LLTextEditor::setCursor(S32 row, S32 column)
}
doc += column;
setCursorPos(doc - mWText.c_str());
- updateScrollFromCursor();
}
void LLTextEditor::setCursorPos(S32 offset)
{
mCursorPos = llclamp(offset, 0, (S32)getLength());
- updateScrollFromCursor();
+ needsScroll();
// reset desired x cursor position
mDesiredXPixel = -1;
}
@@ -1222,8 +1228,6 @@ BOOL LLTextEditor::handleHover(S32 x, S32 y, MASK mask)
setCursorAtLocalPos( x, y, TRUE );
mSelectionEnd = mCursorPos;
-
- updateScrollFromCursor();
}
lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (active)" << llendl;
@@ -1317,8 +1321,6 @@ BOOL LLTextEditor::handleMouseUp(S32 x, S32 y, MASK mask)
setCursorAtLocalPos( x, y, TRUE );
endSelection();
-
- updateScrollFromCursor();
}
if( !hasSelection() )
@@ -1839,8 +1841,7 @@ void LLTextEditor::cut()
gClipboard.copyFromSubstring( mWText, left_pos, length, mSourceID );
deleteSelection( FALSE );
- updateLineStartList();
- updateScrollFromCursor();
+ needsReflow();
}
BOOL LLTextEditor::canCopy() const
@@ -1910,8 +1911,7 @@ void LLTextEditor::paste()
setCursorPos(mCursorPos + insert(mCursorPos, clean_string, FALSE));
deselect();
- updateLineStartList();
- updateScrollFromCursor();
+ needsReflow();
}
@@ -2235,9 +2235,9 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask )
if(text_may_have_changed)
{
- updateLineStartList();
+ needsReflow();
}
- updateScrollFromCursor();
+ needsScroll();
}
}
@@ -2280,8 +2280,7 @@ BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char)
// Most keystrokes will make the selection box go away, but not all will.
deselect();
- updateLineStartList();
- updateScrollFromCursor();
+ needsReflow();
}
}
@@ -2339,8 +2338,7 @@ void LLTextEditor::doDelete()
}
}
- updateLineStartList();
- updateScrollFromCursor();
+ needsReflow();
}
//----------------------------------------------------------------------------
@@ -2383,8 +2381,7 @@ void LLTextEditor::undo()
setCursorPos(pos);
- updateLineStartList();
- updateScrollFromCursor();
+ needsReflow();
}
BOOL LLTextEditor::canRedo() const
@@ -2426,8 +2423,7 @@ void LLTextEditor::redo()
setCursorPos(pos);
- updateLineStartList();
- updateScrollFromCursor();
+ needsReflow();
}
void LLTextEditor::onFocusReceived()
@@ -3100,6 +3096,20 @@ void LLTextEditor::drawClippedSegment(const LLWString &text, S32 seg_start, S32
void LLTextEditor::draw()
{
+ // do on-demand reflow
+ if (mReflowNeeded)
+ {
+ updateLineStartList();
+ mReflowNeeded = FALSE;
+ }
+
+ // then update scroll position, as cursor may have moved
+ if (mScrollNeeded)
+ {
+ updateScrollFromCursor();
+ mScrollNeeded = FALSE;
+ }
+
{
LLLocalClipRect clip(LLRect(0, getRect().getHeight(), getRect().getWidth() - (mScrollbar->getVisible() ? SCROLLBAR_SIZE : 0), 0));
@@ -3118,10 +3128,10 @@ void LLTextEditor::draw()
mBorder->setKeyboardFocusHighlight( gFocusMgr.getKeyboardFocus() == this);// && !mReadOnly);
}
+ LLView::draw(); // Draw children (scrollbar and border)
+
// remember if we are supposed to be at the bottom of the buffer
mScrolledToBottom = isScrolledToBottom();
-
- LLView::draw(); // Draw children (scrollbar and border)
}
@@ -3311,7 +3321,7 @@ void LLTextEditor::setCursorAndScrollToEnd()
{
deselect();
endOfDoc();
- updateScrollFromCursor();
+ needsScroll();
}
void LLTextEditor::getLineAndColumnForPosition( S32 position, S32* line, S32* col, BOOL include_wordwrap )
@@ -3438,7 +3448,7 @@ void LLTextEditor::reshape(S32 width, S32 height, BOOL called_from_parent)
// up-to-date mTextRect
updateTextRect();
- updateLineStartList();
+ needsReflow();
// propagate shape information to scrollbar
mScrollbar->setDocSize( getLineCount() );
@@ -3446,14 +3456,6 @@ void LLTextEditor::reshape(S32 width, S32 height, BOOL called_from_parent)
S32 line_height = llround( mGLFont->getLineHeight() );
S32 page_lines = mTextRect.getHeight() / line_height;
mScrollbar->setPageSize( page_lines );
-
- // if scrolled to bottom, stay at bottom
- // unless user is editing text
- // do this after updating page size
- if (mScrolledToBottom && mTrackBottom && !hasFocus())
- {
- endOfDoc();
- }
}
void LLTextEditor::autoIndent()
@@ -3500,8 +3502,7 @@ void LLTextEditor::insertText(const std::string &new_text)
setCursorPos(mCursorPos + insert( mCursorPos, utf8str_to_wstring(new_text), FALSE ));
- updateLineStartList();
- updateScrollFromCursor();
+ needsReflow();
setEnabled( enabled );
}
@@ -3600,7 +3601,7 @@ void LLTextEditor::appendText(const std::string &new_text, bool allow_undo, bool
mSegments.push_back(segment);
}
- updateLineStartList(old_length);
+ needsReflow();
// Set the cursor and scroll position
// Maintain the scroll position unless the scroll was at the end of the doc (in which
@@ -3639,14 +3640,6 @@ void LLTextEditor::appendText(const std::string &new_text, bool allow_undo, bool
{
blockUndo();
}
-
- // if scrolled to bottom, stay at bottom
- // unless user is editing text
- // do this after updating page size
- if (mScrolledToBottom && mTrackBottom && !hasFocus())
- {
- endOfDoc();
- }
}
void LLTextEditor::removeTextFromEnd(S32 num_chars)
@@ -3661,7 +3654,10 @@ void LLTextEditor::removeTextFromEnd(S32 num_chars)
mSelectionEnd = llclamp(mSelectionEnd, 0, len);
pruneSegments();
+
+ // pruneSegments will invalidate mLineStartList.
updateLineStartList();
+ needsScroll();
}
///////////////////////////////////////////////////////////////////
@@ -3759,8 +3755,7 @@ BOOL LLTextEditor::tryToRevertToPristineState()
}
}
- updateLineStartList();
- updateScrollFromCursor();
+ needsReflow();
}
return isPristine(); // TRUE => success
@@ -3808,6 +3803,7 @@ void LLTextEditor::updateSegments()
{
findEmbeddedItemSegments();
}
+
// Make sure we have at least one segment
if (mSegments.size() == 1 && mSegments[0]->getIsDefault())
{
@@ -3824,6 +3820,7 @@ void LLTextEditor::updateSegments()
}
// Only effective if text was removed from the end of the editor
+// *NOTE: Using this will invalidate references to mSegments from mLineStartList.
void LLTextEditor::pruneSegments()
{
S32 len = mWText.length();
@@ -4066,9 +4063,7 @@ BOOL LLTextEditor::importBuffer(const char* buffer, S32 length )
setCursorPos(0);
deselect();
- updateLineStartList();
- updateScrollFromCursor();
-
+ needsReflow();
return success;
}
@@ -4260,35 +4255,35 @@ S32 LLTextEditor::findHTMLToken(const std::string &line, S32 pos, BOOL reverse)
std::string openers=" \t\n('\"[{<>";
std::string closers=" \t\n)'\"]}><;";
- S32 m2 = 0;
- S32 retval = 0;
+ S32 index = 0;
if (reverse)
{
-
- for (retval=pos; retval >= 0; retval--)
+ for (index=pos; index >= 0; index--)
{
- m2 = openers.find(line.substr(retval,1));
+ char c = line[index];
+ S32 m2 = openers.find(c);
if (m2 >= 0)
{
- break;
+ return index+1;
}
}
- return retval+1;
}
else
{
- for (retval=pos; retval<(S32)line.length(); retval++)
+ for (index=pos; index<(S32)line.length(); index++)
{
- m2 = closers.find(line.substr(retval,1));
+ char c = line[index];
+ S32 m2 = closers.find(c);
if (m2 >= 0)
{
- break;
+ return index;
}
}
- return retval;
- }
+ }
+
+ return index;
}
BOOL LLTextEditor::findHTML(const std::string &line, S32 *begin, S32 *end) const
@@ -4476,9 +4471,8 @@ void LLTextEditor::updatePreedit(const LLWString &preedit_string,
mPreeditStandouts = preedit_standouts;
- updateLineStartList();
+ needsReflow();
setCursorPos(insert_preedit_at + caret_position);
- // updateScrollFromCursor();
// Update of the preedit should be caused by some key strokes.
mKeystrokeTimer.reset();