diff options
author | Mark Palange <palange@lindenlab.com> | 2008-11-21 01:18:39 +0000 |
---|---|---|
committer | Mark Palange <palange@lindenlab.com> | 2008-11-21 01:18:39 +0000 |
commit | ac68eb16a2dac453fe85b7218297f561b8fc96ca (patch) | |
tree | a1e26d95326b610c6d2a740ee80071bfb866d8e9 /indra/llui/lltexteditor.cpp | |
parent | 77c108b2c4879fbbb168f91fed7763a0b557ecab (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.cpp | 140 |
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(); |