aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden
diff options
context:
space:
mode:
Diffstat (limited to 'linden')
-rw-r--r--linden/indra/llcommon/llstring.h30
-rw-r--r--linden/indra/llui/lltexteditor.cpp128
-rw-r--r--linden/indra/llui/lltexteditor.h21
-rw-r--r--linden/indra/newview/skins/default/xui/en-us/floater_chat_history.xml4
-rw-r--r--linden/indra/newview/skins/default/xui/en-us/floater_instant_message.xml1
-rw-r--r--linden/indra/newview/skins/default/xui/en-us/floater_instant_message_ad_hoc.xml147
-rw-r--r--linden/indra/newview/skins/default/xui/en-us/floater_instant_message_group.xml1
7 files changed, 176 insertions, 156 deletions
diff --git a/linden/indra/llcommon/llstring.h b/linden/indra/llcommon/llstring.h
index 7b08fd3..2d76eca 100644
--- a/linden/indra/llcommon/llstring.h
+++ b/linden/indra/llcommon/llstring.h
@@ -133,26 +133,32 @@ struct char_traits<U16>
133class LLStringOps 133class LLStringOps
134{ 134{
135public: 135public:
136 static char toUpper(char elem) { return toupper(elem); } 136 static char toUpper(char elem) { return toupper((unsigned char)elem); }
137 static llwchar toUpper(llwchar elem) { return towupper(elem); } 137 static llwchar toUpper(llwchar elem) { return towupper(elem); }
138 138
139 static char toLower(char elem) { return tolower(elem); } 139 static char toLower(char elem) { return tolower((unsigned char)elem); }
140 static llwchar toLower(llwchar elem) { return towlower(elem); } 140 static llwchar toLower(llwchar elem) { return towlower(elem); }
141 141
142 static BOOL isSpace(char elem) { return isspace(elem) != 0; } 142 static bool isSpace(char elem) { return isspace((unsigned char)elem) != 0; }
143 static BOOL isSpace(llwchar elem) { return iswspace(elem) != 0; } 143 static bool isSpace(llwchar elem) { return iswspace(elem) != 0; }
144 144
145 static BOOL isUpper(char elem) { return isupper(elem) != 0; } 145 static bool isUpper(char elem) { return isupper((unsigned char)elem) != 0; }
146 static BOOL isUpper(llwchar elem) { return iswupper(elem) != 0; } 146 static bool isUpper(llwchar elem) { return iswupper(elem) != 0; }
147 147
148 static BOOL isLower(char elem) { return islower(elem) != 0; } 148 static bool isLower(char elem) { return islower((unsigned char)elem) != 0; }
149 static BOOL isLower(llwchar elem) { return iswlower(elem) != 0; } 149 static bool isLower(llwchar elem) { return iswlower(elem) != 0; }
150
151 static bool isDigit(char a) { return isdigit((unsigned char)a) != 0; }
152 static bool isDigit(llwchar a) { return iswdigit(a) != 0; }
153
154 static bool isPunct(char a) { return ispunct((unsigned char)a) != 0; }
155 static bool isPunct(llwchar a) { return iswpunct(a) != 0; }
156
157 static bool isAlnum(char a) { return isalnum((unsigned char)a) != 0; }
158 static bool isAlnum(llwchar a) { return iswalnum(a) != 0; }
150 159
151 static S32 collate(const char* a, const char* b) { return strcoll(a, b); } 160 static S32 collate(const char* a, const char* b) { return strcoll(a, b); }
152 static S32 collate(const llwchar* a, const llwchar* b); 161 static S32 collate(const llwchar* a, const llwchar* b);
153
154 static BOOL isDigit(char a) { return isdigit(a) != 0; }
155 static BOOL isDigit(llwchar a) { return iswdigit(a) != 0; }
156}; 162};
157 163
158/** 164/**
@@ -194,7 +200,7 @@ public:
194 typedef std::map<LLFormatMapString, LLFormatMapString> format_map_t; 200 typedef std::map<LLFormatMapString, LLFormatMapString> format_map_t;
195 static S32 format(std::basic_string<T>& s, const format_map_t& fmt_map); 201 static S32 format(std::basic_string<T>& s, const format_map_t& fmt_map);
196 202
197 static BOOL isValidIndex(const std::basic_string<T>& string, size_type i) 203 static bool isValidIndex(const std::basic_string<T>& string, size_type i)
198 { 204 {
199 return !string.empty() && (0 <= i) && (i <= string.size()); 205 return !string.empty() && (0 <= i) && (i <= string.size());
200 } 206 }
diff --git a/linden/indra/llui/lltexteditor.cpp b/linden/indra/llui/lltexteditor.cpp
index 90199f1..72d8f17 100644
--- a/linden/indra/llui/lltexteditor.cpp
+++ b/linden/indra/llui/lltexteditor.cpp
@@ -260,7 +260,7 @@ LLTextEditor::LLTextEditor(
260 mIsSelecting( FALSE ), 260 mIsSelecting( FALSE ),
261 mSelectionStart( 0 ), 261 mSelectionStart( 0 ),
262 mSelectionEnd( 0 ), 262 mSelectionEnd( 0 ),
263 mScrolledToBottom( FALSE ), 263 mScrolledToBottom( TRUE ),
264 mOnScrollEndCallback( NULL ), 264 mOnScrollEndCallback( NULL ),
265 mOnScrollEndData( NULL ), 265 mOnScrollEndData( NULL ),
266 mCursorColor( LLUI::sColorsGroup->getColor( "TextCursorColor" ) ), 266 mCursorColor( LLUI::sColorsGroup->getColor( "TextCursorColor" ) ),
@@ -277,14 +277,16 @@ LLTextEditor::LLTextEditor(
277 mCommitOnFocusLost( FALSE ), 277 mCommitOnFocusLost( FALSE ),
278 mHideScrollbarForShortDocs( FALSE ), 278 mHideScrollbarForShortDocs( FALSE ),
279 mTakesNonScrollClicks( TRUE ), 279 mTakesNonScrollClicks( TRUE ),
280 mTrackBottom( TRUE ), 280 mTrackBottom( FALSE ),
281 mAllowEmbeddedItems( allow_embedded_items ), 281 mAllowEmbeddedItems( allow_embedded_items ),
282 mAcceptCallingCardNames(FALSE), 282 mAcceptCallingCardNames(FALSE),
283 mHandleEditKeysDirectly( FALSE ), 283 mHandleEditKeysDirectly( FALSE ),
284 mMouseDownX(0), 284 mMouseDownX(0),
285 mMouseDownY(0), 285 mMouseDownY(0),
286 mLastSelectionX(-1), 286 mLastSelectionX(-1),
287 mLastSelectionY(-1) 287 mLastSelectionY(-1),
288 mReflowNeeded(FALSE),
289 mScrollNeeded(FALSE)
288{ 290{
289 mSourceID.generate(); 291 mSourceID.generate();
290 292
@@ -468,6 +470,13 @@ void LLTextEditor::updateLineStartList(S32 startpos)
468 mScrollbar->setVisible(!short_doc); 470 mScrollbar->setVisible(!short_doc);
469 } 471 }
470 472
473 // if scrolled to bottom, stay at bottom
474 // unless user is editing text
475 // do this after updating page size
476 if (mScrolledToBottom && mTrackBottom && !hasFocus())
477 {
478 endOfDoc();
479 }
471} 480}
472 481
473//////////////////////////////////////////////////////////// 482////////////////////////////////////////////////////////////
@@ -511,8 +520,7 @@ void LLTextEditor::setText(const LLStringExplicit &utf8str)
511 setCursorPos(0); 520 setCursorPos(0);
512 deselect(); 521 deselect();
513 522
514 updateLineStartList(); 523 needsReflow();
515 updateScrollFromCursor();
516 524
517 resetDirty(); 525 resetDirty();
518} 526}
@@ -529,8 +537,7 @@ void LLTextEditor::setWText(const LLWString &wtext)
529 setCursorPos(0); 537 setCursorPos(0);
530 deselect(); 538 deselect();
531 539
532 updateLineStartList(); 540 needsReflow();
533 updateScrollFromCursor();
534 541
535 resetDirty(); 542 resetDirty();
536} 543}
@@ -568,8 +575,7 @@ void LLTextEditor::setWordWrap(BOOL b)
568 setCursorPos(0); 575 setCursorPos(0);
569 deselect(); 576 deselect();
570 577
571 updateLineStartList(); 578 needsReflow();
572 updateScrollFromCursor();
573} 579}
574 580
575 581
@@ -734,6 +740,7 @@ S32 LLTextEditor::getLineStart( S32 line ) const
734 { 740 {
735 return 0; 741 return 0;
736 } 742 }
743
737 line = llclamp(line, 0, num_lines-1); 744 line = llclamp(line, 0, num_lines-1);
738 S32 segidx = mLineStartList[line].mSegment; 745 S32 segidx = mLineStartList[line].mSegment;
739 S32 segoffset = mLineStartList[line].mOffset; 746 S32 segoffset = mLineStartList[line].mOffset;
@@ -781,14 +788,14 @@ void LLTextEditor::getSegmentAndOffset( S32 startpos, S32* segidxp, S32* offsetp
781 *offsetp = startpos - (*seg_iter)->getStart(); 788 *offsetp = startpos - (*seg_iter)->getStart();
782} 789}
783 790
784const LLTextSegment* LLTextEditor::getPreviousSegment() 791const LLTextSegment* LLTextEditor::getPreviousSegment() const
785{ 792{
786 // find segment index at character to left of cursor (or rightmost edge of selection) 793 // find segment index at character to left of cursor (or rightmost edge of selection)
787 S32 idx = llmax(0, getSegmentIdxAtOffset(mCursorPos) - 1); 794 S32 idx = llmax(0, getSegmentIdxAtOffset(mCursorPos) - 1);
788 return idx >= 0 ? mSegments[idx] : NULL; 795 return idx >= 0 ? mSegments[idx] : NULL;
789} 796}
790 797
791void LLTextEditor::getSelectedSegments(std::vector<const LLTextSegment*>& segments) 798void LLTextEditor::getSelectedSegments(std::vector<const LLTextSegment*>& segments) const
792{ 799{
793 S32 left = hasSelection() ? llmin(mSelectionStart, mSelectionEnd) : mCursorPos; 800 S32 left = hasSelection() ? llmin(mSelectionStart, mSelectionEnd) : mCursorPos;
794 S32 right = hasSelection() ? llmax(mSelectionStart, mSelectionEnd) : mCursorPos; 801 S32 right = hasSelection() ? llmax(mSelectionStart, mSelectionEnd) : mCursorPos;
@@ -875,13 +882,12 @@ void LLTextEditor::setCursor(S32 row, S32 column)
875 } 882 }
876 doc += column; 883 doc += column;
877 setCursorPos(doc - mWText.c_str()); 884 setCursorPos(doc - mWText.c_str());
878 updateScrollFromCursor();
879} 885}
880 886
881void LLTextEditor::setCursorPos(S32 offset) 887void LLTextEditor::setCursorPos(S32 offset)
882{ 888{
883 mCursorPos = llclamp(offset, 0, (S32)getLength()); 889 mCursorPos = llclamp(offset, 0, (S32)getLength());
884 updateScrollFromCursor(); 890 needsScroll();
885 // reset desired x cursor position 891 // reset desired x cursor position
886 mDesiredXPixel = -1; 892 mDesiredXPixel = -1;
887} 893}
@@ -925,7 +931,7 @@ BOOL LLTextEditor::selectionContainsLineBreaks()
925 if (hasSelection()) 931 if (hasSelection())
926 { 932 {
927 S32 left = llmin(mSelectionStart, mSelectionEnd); 933 S32 left = llmin(mSelectionStart, mSelectionEnd);
928 S32 right = left + abs(mSelectionStart - mSelectionEnd); 934 S32 right = left + llabs(mSelectionStart - mSelectionEnd);
929 935
930 const LLWString &wtext = mWText; 936 const LLWString &wtext = mWText;
931 for( S32 i = left; i < right; i++ ) 937 for( S32 i = left; i < right; i++ )
@@ -981,7 +987,7 @@ void LLTextEditor::indentSelectedLines( S32 spaces )
981 { 987 {
982 const LLWString &text = mWText; 988 const LLWString &text = mWText;
983 S32 left = llmin( mSelectionStart, mSelectionEnd ); 989 S32 left = llmin( mSelectionStart, mSelectionEnd );
984 S32 right = left + abs( mSelectionStart - mSelectionEnd ); 990 S32 right = left + llabs( mSelectionStart - mSelectionEnd );
985 BOOL cursor_on_right = (mSelectionEnd > mSelectionStart); 991 BOOL cursor_on_right = (mSelectionEnd > mSelectionStart);
986 S32 cur = left; 992 S32 cur = left;
987 993
@@ -1222,8 +1228,6 @@ BOOL LLTextEditor::handleHover(S32 x, S32 y, MASK mask)
1222 1228
1223 setCursorAtLocalPos( x, y, TRUE ); 1229 setCursorAtLocalPos( x, y, TRUE );
1224 mSelectionEnd = mCursorPos; 1230 mSelectionEnd = mCursorPos;
1225
1226 updateScrollFromCursor();
1227 } 1231 }
1228 1232
1229 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (active)" << llendl; 1233 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (active)" << llendl;
@@ -1812,7 +1816,7 @@ void LLTextEditor::deleteSelection(BOOL group_with_next_op )
1812 if( getEnabled() && hasSelection() ) 1816 if( getEnabled() && hasSelection() )
1813 { 1817 {
1814 S32 pos = llmin( mSelectionStart, mSelectionEnd ); 1818 S32 pos = llmin( mSelectionStart, mSelectionEnd );
1815 S32 length = abs( mSelectionStart - mSelectionEnd ); 1819 S32 length = llabs( mSelectionStart - mSelectionEnd );
1816 1820
1817 remove( pos, length, group_with_next_op ); 1821 remove( pos, length, group_with_next_op );
1818 1822
@@ -1835,12 +1839,11 @@ void LLTextEditor::cut()
1835 return; 1839 return;
1836 } 1840 }
1837 S32 left_pos = llmin( mSelectionStart, mSelectionEnd ); 1841 S32 left_pos = llmin( mSelectionStart, mSelectionEnd );
1838 S32 length = abs( mSelectionStart - mSelectionEnd ); 1842 S32 length = llabs( mSelectionStart - mSelectionEnd );
1839 gClipboard.copyFromSubstring( mWText, left_pos, length, mSourceID ); 1843 gClipboard.copyFromSubstring( mWText, left_pos, length, mSourceID );
1840 deleteSelection( FALSE ); 1844 deleteSelection( FALSE );
1841 1845
1842 updateLineStartList(); 1846 needsReflow();
1843 updateScrollFromCursor();
1844} 1847}
1845 1848
1846BOOL LLTextEditor::canCopy() const 1849BOOL LLTextEditor::canCopy() const
@@ -1856,7 +1859,7 @@ void LLTextEditor::copy()
1856 return; 1859 return;
1857 } 1860 }
1858 S32 left_pos = llmin( mSelectionStart, mSelectionEnd ); 1861 S32 left_pos = llmin( mSelectionStart, mSelectionEnd );
1859 S32 length = abs( mSelectionStart - mSelectionEnd ); 1862 S32 length = llabs( mSelectionStart - mSelectionEnd );
1860 gClipboard.copyFromSubstring(mWText, left_pos, length, mSourceID); 1863 gClipboard.copyFromSubstring(mWText, left_pos, length, mSourceID);
1861} 1864}
1862 1865
@@ -1910,8 +1913,7 @@ void LLTextEditor::paste()
1910 setCursorPos(mCursorPos + insert(mCursorPos, clean_string, FALSE)); 1913 setCursorPos(mCursorPos + insert(mCursorPos, clean_string, FALSE));
1911 deselect(); 1914 deselect();
1912 1915
1913 updateLineStartList(); 1916 needsReflow();
1914 updateScrollFromCursor();
1915} 1917}
1916 1918
1917 1919
@@ -2235,9 +2237,9 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask )
2235 2237
2236 if(text_may_have_changed) 2238 if(text_may_have_changed)
2237 { 2239 {
2238 updateLineStartList(); 2240 needsReflow();
2239 } 2241 }
2240 updateScrollFromCursor(); 2242 needsScroll();
2241 } 2243 }
2242 } 2244 }
2243 2245
@@ -2280,8 +2282,7 @@ BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char)
2280 // Most keystrokes will make the selection box go away, but not all will. 2282 // Most keystrokes will make the selection box go away, but not all will.
2281 deselect(); 2283 deselect();
2282 2284
2283 updateLineStartList(); 2285 needsReflow();
2284 updateScrollFromCursor();
2285 } 2286 }
2286 } 2287 }
2287 2288
@@ -2339,8 +2340,7 @@ void LLTextEditor::doDelete()
2339 } 2340 }
2340 } 2341 }
2341 2342
2342 updateLineStartList(); 2343 needsReflow();
2343 updateScrollFromCursor();
2344} 2344}
2345 2345
2346//---------------------------------------------------------------------------- 2346//----------------------------------------------------------------------------
@@ -2383,8 +2383,7 @@ void LLTextEditor::undo()
2383 2383
2384 setCursorPos(pos); 2384 setCursorPos(pos);
2385 2385
2386 updateLineStartList(); 2386 needsReflow();
2387 updateScrollFromCursor();
2388} 2387}
2389 2388
2390BOOL LLTextEditor::canRedo() const 2389BOOL LLTextEditor::canRedo() const
@@ -2426,8 +2425,7 @@ void LLTextEditor::redo()
2426 2425
2427 setCursorPos(pos); 2426 setCursorPos(pos);
2428 2427
2429 updateLineStartList(); 2428 needsReflow();
2430 updateScrollFromCursor();
2431} 2429}
2432 2430
2433void LLTextEditor::onFocusReceived() 2431void LLTextEditor::onFocusReceived()
@@ -3100,6 +3098,20 @@ void LLTextEditor::drawClippedSegment(const LLWString &text, S32 seg_start, S32
3100 3098
3101void LLTextEditor::draw() 3099void LLTextEditor::draw()
3102{ 3100{
3101 // do on-demand reflow
3102 if (mReflowNeeded)
3103 {
3104 updateLineStartList();
3105 mReflowNeeded = FALSE;
3106 }
3107
3108 // then update scroll position, as cursor may have moved
3109 if (mScrollNeeded)
3110 {
3111 updateScrollFromCursor();
3112 mScrollNeeded = FALSE;
3113 }
3114
3103 { 3115 {
3104 LLLocalClipRect clip(LLRect(0, getRect().getHeight(), getRect().getWidth() - (mScrollbar->getVisible() ? SCROLLBAR_SIZE : 0), 0)); 3116 LLLocalClipRect clip(LLRect(0, getRect().getHeight(), getRect().getWidth() - (mScrollbar->getVisible() ? SCROLLBAR_SIZE : 0), 0));
3105 3117
@@ -3118,10 +3130,10 @@ void LLTextEditor::draw()
3118 mBorder->setKeyboardFocusHighlight( gFocusMgr.getKeyboardFocus() == this);// && !mReadOnly); 3130 mBorder->setKeyboardFocusHighlight( gFocusMgr.getKeyboardFocus() == this);// && !mReadOnly);
3119 } 3131 }
3120 3132
3133 LLView::draw(); // Draw children (scrollbar and border)
3134
3121 // remember if we are supposed to be at the bottom of the buffer 3135 // remember if we are supposed to be at the bottom of the buffer
3122 mScrolledToBottom = isScrolledToBottom(); 3136 mScrolledToBottom = isScrolledToBottom();
3123
3124 LLView::draw(); // Draw children (scrollbar and border)
3125} 3137}
3126 3138
3127 3139
@@ -3311,7 +3323,7 @@ void LLTextEditor::setCursorAndScrollToEnd()
3311{ 3323{
3312 deselect(); 3324 deselect();
3313 endOfDoc(); 3325 endOfDoc();
3314 updateScrollFromCursor(); 3326 needsScroll();
3315} 3327}
3316 3328
3317void LLTextEditor::getLineAndColumnForPosition( S32 position, S32* line, S32* col, BOOL include_wordwrap ) 3329void LLTextEditor::getLineAndColumnForPosition( S32 position, S32* line, S32* col, BOOL include_wordwrap )
@@ -3374,7 +3386,9 @@ void LLTextEditor::endOfLine()
3374 3386
3375void LLTextEditor::endOfDoc() 3387void LLTextEditor::endOfDoc()
3376{ 3388{
3377 mScrollbar->setDocPos( mScrollbar->getDocPosMax() ); 3389 mScrollbar->setDocPos(mScrollbar->getDocPosMax());
3390 mScrolledToBottom = true;
3391
3378 S32 len = getLength(); 3392 S32 len = getLength();
3379 if( len ) 3393 if( len )
3380 { 3394 {
@@ -3438,7 +3452,7 @@ void LLTextEditor::reshape(S32 width, S32 height, BOOL called_from_parent)
3438 // up-to-date mTextRect 3452 // up-to-date mTextRect
3439 updateTextRect(); 3453 updateTextRect();
3440 3454
3441 updateLineStartList(); 3455 needsReflow();
3442 3456
3443 // propagate shape information to scrollbar 3457 // propagate shape information to scrollbar
3444 mScrollbar->setDocSize( getLineCount() ); 3458 mScrollbar->setDocSize( getLineCount() );
@@ -3446,14 +3460,6 @@ void LLTextEditor::reshape(S32 width, S32 height, BOOL called_from_parent)
3446 S32 line_height = llround( mGLFont->getLineHeight() ); 3460 S32 line_height = llround( mGLFont->getLineHeight() );
3447 S32 page_lines = mTextRect.getHeight() / line_height; 3461 S32 page_lines = mTextRect.getHeight() / line_height;
3448 mScrollbar->setPageSize( page_lines ); 3462 mScrollbar->setPageSize( page_lines );
3449
3450 // if scrolled to bottom, stay at bottom
3451 // unless user is editing text
3452 // do this after updating page size
3453 if (mScrolledToBottom && mTrackBottom && !hasFocus())
3454 {
3455 endOfDoc();
3456 }
3457} 3463}
3458 3464
3459void LLTextEditor::autoIndent() 3465void LLTextEditor::autoIndent()
@@ -3500,8 +3506,7 @@ void LLTextEditor::insertText(const std::string &new_text)
3500 3506
3501 setCursorPos(mCursorPos + insert( mCursorPos, utf8str_to_wstring(new_text), FALSE )); 3507 setCursorPos(mCursorPos + insert( mCursorPos, utf8str_to_wstring(new_text), FALSE ));
3502 3508
3503 updateLineStartList(); 3509 needsReflow();
3504 updateScrollFromCursor();
3505 3510
3506 setEnabled( enabled ); 3511 setEnabled( enabled );
3507} 3512}
@@ -3600,7 +3605,7 @@ void LLTextEditor::appendText(const std::string &new_text, bool allow_undo, bool
3600 mSegments.push_back(segment); 3605 mSegments.push_back(segment);
3601 } 3606 }
3602 3607
3603 updateLineStartList(old_length); 3608 needsReflow();
3604 3609
3605 // Set the cursor and scroll position 3610 // Set the cursor and scroll position
3606 // Maintain the scroll position unless the scroll was at the end of the doc (in which 3611 // Maintain the scroll position unless the scroll was at the end of the doc (in which
@@ -3639,14 +3644,6 @@ void LLTextEditor::appendText(const std::string &new_text, bool allow_undo, bool
3639 { 3644 {
3640 blockUndo(); 3645 blockUndo();
3641 } 3646 }
3642
3643 // if scrolled to bottom, stay at bottom
3644 // unless user is editing text
3645 // do this after updating page size
3646 if (mScrolledToBottom && mTrackBottom && !hasFocus())
3647 {
3648 endOfDoc();
3649 }
3650} 3647}
3651 3648
3652void LLTextEditor::removeTextFromEnd(S32 num_chars) 3649void LLTextEditor::removeTextFromEnd(S32 num_chars)
@@ -3661,7 +3658,10 @@ void LLTextEditor::removeTextFromEnd(S32 num_chars)
3661 mSelectionEnd = llclamp(mSelectionEnd, 0, len); 3658 mSelectionEnd = llclamp(mSelectionEnd, 0, len);
3662 3659
3663 pruneSegments(); 3660 pruneSegments();
3661
3662 // pruneSegments will invalidate mLineStartList.
3664 updateLineStartList(); 3663 updateLineStartList();
3664 needsScroll();
3665} 3665}
3666 3666
3667/////////////////////////////////////////////////////////////////// 3667///////////////////////////////////////////////////////////////////
@@ -3759,8 +3759,7 @@ BOOL LLTextEditor::tryToRevertToPristineState()
3759 } 3759 }
3760 } 3760 }
3761 3761
3762 updateLineStartList(); 3762 needsReflow();
3763 updateScrollFromCursor();
3764 } 3763 }
3765 3764
3766 return isPristine(); // TRUE => success 3765 return isPristine(); // TRUE => success
@@ -3808,6 +3807,7 @@ void LLTextEditor::updateSegments()
3808 { 3807 {
3809 findEmbeddedItemSegments(); 3808 findEmbeddedItemSegments();
3810 } 3809 }
3810
3811 // Make sure we have at least one segment 3811 // Make sure we have at least one segment
3812 if (mSegments.size() == 1 && mSegments[0]->getIsDefault()) 3812 if (mSegments.size() == 1 && mSegments[0]->getIsDefault())
3813 { 3813 {
@@ -3824,6 +3824,7 @@ void LLTextEditor::updateSegments()
3824} 3824}
3825 3825
3826// Only effective if text was removed from the end of the editor 3826// Only effective if text was removed from the end of the editor
3827// *NOTE: Using this will invalidate references to mSegments from mLineStartList.
3827void LLTextEditor::pruneSegments() 3828void LLTextEditor::pruneSegments()
3828{ 3829{
3829 S32 len = mWText.length(); 3830 S32 len = mWText.length();
@@ -4066,9 +4067,7 @@ BOOL LLTextEditor::importBuffer(const char* buffer, S32 length )
4066 setCursorPos(0); 4067 setCursorPos(0);
4067 deselect(); 4068 deselect();
4068 4069
4069 updateLineStartList(); 4070 needsReflow();
4070 updateScrollFromCursor();
4071
4072 return success; 4071 return success;
4073} 4072}
4074 4073
@@ -4496,9 +4495,8 @@ void LLTextEditor::updatePreedit(const LLWString &preedit_string,
4496 4495
4497 mPreeditStandouts = preedit_standouts; 4496 mPreeditStandouts = preedit_standouts;
4498 4497
4499 updateLineStartList(); 4498 needsReflow();
4500 setCursorPos(insert_preedit_at + caret_position); 4499 setCursorPos(insert_preedit_at + caret_position);
4501 // updateScrollFromCursor();
4502 4500
4503 // Update of the preedit should be caused by some key strokes. 4501 // Update of the preedit should be caused by some key strokes.
4504 mKeystrokeTimer.reset(); 4502 mKeystrokeTimer.reset();
diff --git a/linden/indra/llui/lltexteditor.h b/linden/indra/llui/lltexteditor.h
index 3cff91d..c76395c 100644
--- a/linden/indra/llui/lltexteditor.h
+++ b/linden/indra/llui/lltexteditor.h
@@ -110,6 +110,7 @@ public:
110 virtual BOOL canUndo() const; 110 virtual BOOL canUndo() const;
111 virtual void redo(); 111 virtual void redo();
112 virtual BOOL canRedo() const; 112 virtual BOOL canRedo() const;
113
113 virtual void cut(); 114 virtual void cut();
114 virtual BOOL canCut() const; 115 virtual BOOL canCut() const;
115 virtual void copy(); 116 virtual void copy();
@@ -245,9 +246,11 @@ public:
245 llwchar getWChar(S32 pos) const { return mWText[pos]; } 246 llwchar getWChar(S32 pos) const { return mWText[pos]; }
246 LLWString getWSubString(S32 pos, S32 len) const { return mWText.substr(pos, len); } 247 LLWString getWSubString(S32 pos, S32 len) const { return mWText.substr(pos, len); }
247 248
248 const LLTextSegment* getCurrentSegment() { return getSegmentAtOffset(mCursorPos); } 249 const LLTextSegment* getCurrentSegment() const { return getSegmentAtOffset(mCursorPos); }
249 const LLTextSegment* getPreviousSegment(); 250 const LLTextSegment* getPreviousSegment() const;
250 void getSelectedSegments(std::vector<const LLTextSegment*>& segments); 251 void getSelectedSegments(std::vector<const LLTextSegment*>& segments) const;
252
253 static bool isPartOfWord(llwchar c) { return (c == '_') || LLStringOps::isAlnum((char)c); }
251 254
252protected: 255protected:
253 // 256 //
@@ -266,8 +269,6 @@ protected:
266 void assignEmbedded(const std::string &s); 269 void assignEmbedded(const std::string &s);
267 BOOL truncate(); // Returns true if truncation occurs 270 BOOL truncate(); // Returns true if truncation occurs
268 271
269 static BOOL isPartOfWord(llwchar c) { return (c == '_') || isalnum(c); }
270
271 void removeCharOrTab(); 272 void removeCharOrTab();
272 void setCursorAtLocalPos(S32 x, S32 y, BOOL round); 273 void setCursorAtLocalPos(S32 x, S32 y, BOOL round);
273 S32 getCursorPosFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const; 274 S32 getCursorPosFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const;
@@ -433,6 +434,14 @@ private:
433 void drawText(); 434 void drawText();
434 void drawClippedSegment(const LLWString &wtext, S32 seg_start, S32 seg_end, F32 x, F32 y, S32 selection_left, S32 selection_right, const LLStyleSP& color, F32* right_x); 435 void drawClippedSegment(const LLWString &wtext, S32 seg_start, S32 seg_end, F32 x, F32 y, S32 selection_left, S32 selection_right, const LLStyleSP& color, F32* right_x);
435 436
437 void needsReflow()
438 {
439 mReflowNeeded = TRUE;
440 // cursor might have moved, need to scroll
441 mScrollNeeded = TRUE;
442 }
443 void needsScroll() { mScrollNeeded = TRUE; }
444
436 // 445 //
437 // Data 446 // Data
438 // 447 //
@@ -489,6 +498,8 @@ private:
489 }; 498 };
490 typedef std::vector<line_info> line_list_t; 499 typedef std::vector<line_info> line_list_t;
491 line_list_t mLineStartList; 500 line_list_t mLineStartList;
501 BOOL mReflowNeeded;
502 BOOL mScrollNeeded;
492 503
493 LLFrameTimer mKeystrokeTimer; 504 LLFrameTimer mKeystrokeTimer;
494 505
diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_chat_history.xml b/linden/indra/newview/skins/default/xui/en-us/floater_chat_history.xml
index 6bd4424..a12cb2b 100644
--- a/linden/indra/newview/skins/default/xui/en-us/floater_chat_history.xml
+++ b/linden/indra/newview/skins/default/xui/en-us/floater_chat_history.xml
@@ -46,13 +46,15 @@
46 bottom="28" embedded_items="false" enabled="false" 46 bottom="28" embedded_items="false" enabled="false"
47 follows="left|top|right|bottom" font="SansSerif" height="74" left="5" 47 follows="left|top|right|bottom" font="SansSerif" height="74" left="5"
48 max_length="2147483647" mouse_opaque="true" name="Chat History Editor" 48 max_length="2147483647" mouse_opaque="true" name="Chat History Editor"
49 track_bottom="true"
49 text_color="ChatHistoryTextColor" 50 text_color="ChatHistoryTextColor"
50 text_readonly_color="ChatHistoryTextColor" width="299" word_wrap="true" /> 51 text_readonly_color="ChatHistoryTextColor" width="299" word_wrap="true" />
51 <text_editor type="string" length="1" bg_readonly_color="ChatHistoryBgColor" bg_writeable_color="ChatHistoryBgColor" 52 <text_editor type="string" length="1" bg_readonly_color="ChatHistoryBgColor" bg_writeable_color="ChatHistoryBgColor"
52 bottom="28" embedded_items="false" enabled="false" 53 bottom="28" embedded_items="false" enabled="false"
53 follows="left|top|right|bottom" font="SansSerif" height="74" left="5" 54 follows="left|top|right|bottom" font="SansSerif" height="74" left="5"
54 max_length="2147483647" mouse_opaque="true" 55 max_length="2147483647" mouse_opaque="true"
55 name="Chat History Editor with mute" text_color="ChatHistoryTextColor" 56 name="Chat History Editor with mute" text_color="ChatHistoryTextColor"
57 track_bottom="true"
56 text_readonly_color="ChatHistoryTextColor" width="300" word_wrap="true" /> 58 text_readonly_color="ChatHistoryTextColor" width="300" word_wrap="true" />
57 <panel bottom="5" follows="left|right|bottom" left="5" name="chat_panel" right="-5" 59 <panel bottom="5" follows="left|right|bottom" left="5" name="chat_panel" right="-5"
58 tab_group="1" top="25"> 60 tab_group="1" top="25">
diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_instant_message.xml b/linden/indra/newview/skins/default/xui/en-us/floater_instant_message.xml
index eb8e672..3b1c927 100644
--- a/linden/indra/newview/skins/default/xui/en-us/floater_instant_message.xml
+++ b/linden/indra/newview/skins/default/xui/en-us/floater_instant_message.xml
@@ -64,6 +64,7 @@
64 follows="left|top|right|bottom" font="SansSerif" height="221" left="5" 64 follows="left|top|right|bottom" font="SansSerif" height="221" left="5"
65 max_length="2147483647" mouse_opaque="true" name="im_history" 65 max_length="2147483647" mouse_opaque="true" name="im_history"
66 text_color="ChatHistoryTextColor" 66 text_color="ChatHistoryTextColor"
67 track_bottom="true"
67 text_readonly_color="ChatHistoryTextColor" width="487" word_wrap="true" /> 68 text_readonly_color="ChatHistoryTextColor" width="487" word_wrap="true" />
68 <line_editor bevel_style="in" border_style="line" border_thickness="1" bottom="7" 69 <line_editor bevel_style="in" border_style="line" border_thickness="1" bottom="7"
69 follows="left|right|bottom" font="SansSerif" height="20" 70 follows="left|right|bottom" font="SansSerif" height="20"
diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_instant_message_ad_hoc.xml b/linden/indra/newview/skins/default/xui/en-us/floater_instant_message_ad_hoc.xml
index eea285c..ddf344d 100644
--- a/linden/indra/newview/skins/default/xui/en-us/floater_instant_message_ad_hoc.xml
+++ b/linden/indra/newview/skins/default/xui/en-us/floater_instant_message_ad_hoc.xml
@@ -1,73 +1,74 @@
1<?xml version="1.0" encoding="utf-8" standalone="yes" ?> 1<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
2<floater border="true" bottom="-298" can_close="true" can_drag_on_left="false" 2<floater border="true" bottom="-298" can_close="true" can_drag_on_left="false"
3 can_minimize="false" can_resize="true" default_tab_group="1" enabled="true" 3 can_minimize="false" can_resize="true" default_tab_group="1" enabled="true"
4 follows="left|top|right|bottom" height="297" label="(unknown)" left="1" 4 follows="left|top|right|bottom" height="297" label="(unknown)" left="1"
5 min_height="225" min_width="265" mouse_opaque="true" name="im_floater" 5 min_height="225" min_width="265" mouse_opaque="true" name="im_floater"
6 rect_control="" title="(unknown)" width="501"> 6 rect_control="" title="(unknown)" width="501">
7 <string name="ringing"> 7 <string name="ringing">
8 Joining Voice Chat... 8 Joining Voice Chat...
9 </string> 9 </string>
10 <string name="connected"> 10 <string name="connected">
11 Connected, click End Call to hang up 11 Connected, click End Call to hang up
12 </string> 12 </string>
13 <string name="hang_up"> 13 <string name="hang_up">
14 Left Voice Chat 14 Left Voice Chat
15 </string> 15 </string>
16 <string name="voice_icon"> 16 <string name="voice_icon">
17 icn_voice-groupfocus.tga 17 icn_voice-groupfocus.tga
18 </string> 18 </string>
19 <string name="title_string"> 19 <string name="title_string">
20 Instant Message with [NAME] 20 Instant Message with [NAME]
21 </string> 21 </string>
22 <string name="typing_start_string"> 22 <string name="typing_start_string">
23 [NAME] is typing... 23 [NAME] is typing...
24 </string> 24 </string>
25 <string name="session_start_string"> 25 <string name="session_start_string">
26 Starting session with [NAME] please wait. 26 Starting session with [NAME] please wait.
27 </string> 27 </string>
28 <string name="default_text_label"> 28 <string name="default_text_label">
29 Click here to instant message. 29 Click here to instant message.
30 </string> 30 </string>
31 <layout_stack border="false" bottom="0" follows="left|top|right|bottom" height="277" left="2" 31 <layout_stack border="false" bottom="0" follows="left|top|right|bottom" height="277" left="2"
32 orientation="horizontal" tab_group="1" width="495" name="panels"> 32 orientation="horizontal" tab_group="1" width="495" name="panels">
33 <layout_panel border="false" bottom="0" default_tab_group="1" follows="left|top|bottom|right" 33 <layout_panel border="false" bottom="0" default_tab_group="1" follows="left|top|bottom|right"
34 height="295" left="0" min_width="115" name="im_contents_panel" width="495"> 34 height="295" left="0" min_width="115" name="im_contents_panel" width="495">
35 <button bottom="-20" enabled="false" follows="left|top" halign="center" height="20" 35 <button bottom="-20" enabled="false" follows="left|top" halign="center" height="20"
36 image_overlay="icn_voice-call-start.tga" image_overlay_alignment="left" 36 image_overlay="icn_voice-call-start.tga" image_overlay_alignment="left"
37 label="Call" left="5" name="start_call_btn" width="80" /> 37 label="Call" left="5" name="start_call_btn" width="80" />
38 <button bottom_delta="0" follows="left|top" halign="center" height="20" 38 <button bottom_delta="0" follows="left|top" halign="center" height="20"
39 image_overlay="icn_voice-call-end.tga" image_overlay_alignment="left" 39 image_overlay="icn_voice-call-end.tga" image_overlay_alignment="left"
40 label="End Call" left_delta="0" name="end_call_btn" visible="false" 40 label="End Call" left_delta="0" name="end_call_btn" visible="false"
41 width="80" /> 41 width="80" />
42 <button bottom_delta="0" follows="right|top" height="20" label="&lt; &lt;" 42 <button bottom_delta="0" follows="right|top" height="20" label="&lt; &lt;"
43 label_selected="&gt; &gt;" left="463" name="toggle_active_speakers_btn" 43 label_selected="&gt; &gt;" left="463" name="toggle_active_speakers_btn"
44 right="496" 44 right="496"
45 tool_tip="Click here to toggle a list of active participants in this IM session." 45 tool_tip="Click here to toggle a list of active participants in this IM session."
46 visible="true" width="80" /> 46 visible="true" width="80" />
47 <text_editor type="string" length="1" bg_readonly_color="ChatHistoryBgColor" bg_writeable_color="ChatHistoryBgColor" 47 <text_editor type="string" length="1" bg_readonly_color="ChatHistoryBgColor" bg_writeable_color="ChatHistoryBgColor"
48 bottom="-265" embedded_items="false" enabled="false" 48 bottom="-265" embedded_items="false" enabled="false"
49 follows="left|top|right|bottom" font="SansSerif" height="239" left="5" 49 follows="left|top|right|bottom" font="SansSerif" height="239" left="5"
50 max_length="2147483647" mouse_opaque="true" name="im_history" 50 max_length="2147483647" mouse_opaque="true" name="im_history"
51 text_color="ChatHistoryTextColor" 51 track_bottom="true"
52 text_readonly_color="ChatHistoryTextColor" width="490" word_wrap="true" /> 52 text_color="ChatHistoryTextColor"
53 <line_editor bevel_style="in" border_style="line" border_thickness="1" bottom="7" 53 text_readonly_color="ChatHistoryTextColor" width="490" word_wrap="true" />
54 enabled="true" follows="left|right|bottom" font="SansSerif" 54 <line_editor bevel_style="in" border_style="line" border_thickness="1" bottom="7"
55 handle_edit_keys_directly="false" height="20" 55 enabled="true" follows="left|right|bottom" font="SansSerif"
56 label="Click here to instant message" left="5" max_length="1022" 56 handle_edit_keys_directly="false" height="20"
57 mouse_opaque="true" name="chat_editor" select_all_on_focus_received="false" 57 label="Click here to instant message" left="5" max_length="1022"
58 select_on_focus="false" tab_group="1" width="426" /> 58 mouse_opaque="true" name="chat_editor" select_all_on_focus_received="false"
59 <button bottom_delta="0" enabled="true" follows="right|bottom" font="SansSerif" 59 select_on_focus="false" tab_group="1" width="426" />
60 halign="center" height="20" label="Send" left="436" mouse_opaque="true" 60 <button bottom_delta="0" enabled="true" follows="right|bottom" font="SansSerif"
61 name="send_btn" scale_image="true" width="60" /> 61 halign="center" height="20" label="Send" left="436" mouse_opaque="true"
62 </layout_panel> 62 name="send_btn" scale_image="true" width="60" />
63 <layout_panel auto_resize="false" bottom="0" can_resize="true" 63 </layout_panel>
64 filename="panel_speaker_controls.xml" height="120" left="0" min_width="140" 64 <layout_panel auto_resize="false" bottom="0" can_resize="true"
65 name="active_speakers_panel" top_delta="0" visible="false" width="140" /> 65 filename="panel_speaker_controls.xml" height="120" left="0" min_width="140"
66 </layout_stack> 66 name="active_speakers_panel" top_delta="0" visible="false" width="140" />
67 <string name="live_help_dialog"> 67 </layout_stack>
68 *** Welcome to Help Request *** 68 <string name="live_help_dialog">
69Please first check our SL Help Pages by pressing F1, or by accessing the Knowledge Base http://secondlife.com/knowledgebase/ 69 *** Welcome to Help Request ***
70If your answer is not there, please enter your question to begin, then allow a few moments for available helpers to respond. 70Please first check our SL Help Pages by pressing F1, or by accessing the Knowledge Base http://secondlife.com/knowledgebase/
71-=-=- Response times will vary, especially during peak times -=-=- 71If your answer is not there, please enter your question to begin, then allow a few moments for available helpers to respond.
72 </string> 72-=-=- Response times will vary, especially during peak times -=-=-
73</floater> 73 </string>
74</floater>
diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_instant_message_group.xml b/linden/indra/newview/skins/default/xui/en-us/floater_instant_message_group.xml
index 3a6e4ec..f59017e 100644
--- a/linden/indra/newview/skins/default/xui/en-us/floater_instant_message_group.xml
+++ b/linden/indra/newview/skins/default/xui/en-us/floater_instant_message_group.xml
@@ -64,6 +64,7 @@
64 follows="left|top|right|bottom" font="SansSerif" left="4" 64 follows="left|top|right|bottom" font="SansSerif" left="4"
65 max_length="2147483647" mouse_opaque="true" name="im_history" 65 max_length="2147483647" mouse_opaque="true" name="im_history"
66 text_color="ChatHistoryTextColor" 66 text_color="ChatHistoryTextColor"
67 track_bottom="true"
67 text_readonly_color="ChatHistoryTextColor" top="104" width="170" 68 text_readonly_color="ChatHistoryTextColor" top="104" width="170"
68 word_wrap="true" /> 69 word_wrap="true" />
69 <line_editor bevel_style="in" border_style="line" border_thickness="1" bottom="7" 70 <line_editor bevel_style="in" border_style="line" border_thickness="1" bottom="7"