diff options
author | Mark Palange (Mani) <palange@lindenlab.com> | 2010-02-02 18:31:51 -0800 |
---|---|---|
committer | Mark Palange (Mani) <palange@lindenlab.com> | 2010-02-02 18:31:51 -0800 |
commit | 86923afd27d76734cf1274fa788928230c232a4d (patch) | |
tree | 7eafa493f052a1af6edc6b132bc22c365272ede5 | |
parent | e518fa8df91ebe8dabf949cc6074b35f60ca083f (diff) | |
parent | 5491dd6e983f8fccbd687c7c45ef43125dfc0f6c (diff) |
Merge
-rw-r--r-- | indra/llui/lltextbase.cpp | 28 | ||||
-rw-r--r-- | indra/llui/lltextbase.h | 6 | ||||
-rw-r--r-- | indra/llui/lltexteditor.cpp | 69 | ||||
-rw-r--r-- | indra/llui/lltexteditor.h | 1 | ||||
-rw-r--r-- | indra/newview/llinventorymodel.cpp | 6 |
5 files changed, 27 insertions, 83 deletions
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index b977e50bc1..75ca6d8895 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -185,7 +185,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p) mWriteableBgColor(p.bg_writeable_color), mReadOnlyBgColor(p.bg_readonly_color), mFocusBgColor(p.bg_focus_color), - mReflowNeeded(FALSE), + mReflowIndex(S32_MAX), mCursorPos( 0 ), mScrollNeeded(FALSE), mDesiredXPixel(-1), @@ -660,7 +660,7 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s } onValueChange(pos, pos + insert_len); - needsReflow(); + needsReflow(pos); return insert_len; } @@ -720,7 +720,7 @@ S32 LLTextBase::removeStringNoUndo(S32 pos, S32 length) createDefaultSegment(); onValueChange(pos, pos); - needsReflow(); + needsReflow(pos); return -length; // This will be wrong if someone calls removeStringNoUndo with an excessive length } @@ -736,7 +736,7 @@ S32 LLTextBase::overwriteCharNoUndo(S32 pos, llwchar wc) getViewModel()->setDisplay(text); onValueChange(pos, pos + 1); - needsReflow(); + needsReflow(pos); return 1; } @@ -762,15 +762,18 @@ void LLTextBase::insertSegment(LLTextSegmentPtr segment_to_insert) } segment_set_t::iterator cur_seg_iter = getSegIterContaining(segment_to_insert->getStart()); + S32 reflow_start_index = 0; if (cur_seg_iter == mSegments.end()) { mSegments.insert(segment_to_insert); segment_to_insert->linkToDocument(this); + reflow_start_index = segment_to_insert->getStart(); } else { LLTextSegmentPtr cur_segmentp = *cur_seg_iter; + reflow_start_index = cur_segmentp->getStart(); if (cur_segmentp->getStart() < segment_to_insert->getStart()) { S32 old_segment_end = cur_segmentp->getEnd(); @@ -829,7 +832,7 @@ void LLTextBase::insertSegment(LLTextSegmentPtr segment_to_insert) } // layout potentially changed - needsReflow(); + needsReflow(reflow_start_index); } BOOL LLTextBase::handleMouseDown(S32 x, S32 y, MASK mask) @@ -1084,15 +1087,16 @@ S32 LLTextBase::getLeftOffset(S32 width) static LLFastTimer::DeclareTimer FTM_TEXT_REFLOW ("Text Reflow"); -void LLTextBase::reflow(S32 start_index) +void LLTextBase::reflow() { LLFastTimer ft(FTM_TEXT_REFLOW); updateSegments(); - while(mReflowNeeded) + while(mReflowIndex < S32_MAX) { - mReflowNeeded = false; + S32 start_index = mReflowIndex; + mReflowIndex = S32_MAX; // shrink document to minimum size (visible portion of text widget) // to force inlined widgets with follows set to shrink @@ -1619,6 +1623,12 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c } } +void LLTextBase::needsReflow(S32 index) +{ + lldebugs << "reflow on object " << (void*)this << " index = " << mReflowIndex << ", new index = " << index << llendl; + mReflowIndex = llmin(mReflowIndex, index); +} + void LLTextBase::appendAndHighlightText(const std::string &new_text, bool prepend_newline, S32 highlight_part, const LLStyle::Params& style_params) { if (new_text.empty()) return; @@ -2260,7 +2270,7 @@ LLNormalTextSegment::LLNormalTextSegment( LLStyleConstSP style, S32 start, S32 e LLUIImagePtr image = mStyle->getImage(); if (image.notNull()) { - mImageLoadedConnection = image->addLoadedCallback(boost::bind(&LLTextBase::needsReflow, &mEditor)); + mImageLoadedConnection = image->addLoadedCallback(boost::bind(&LLTextBase::needsReflow, &mEditor, start)); } } diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index ed2f239476..3dda6f4cc8 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -150,7 +150,7 @@ public: void appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params = LLStyle::Params()); // force reflow of text - void needsReflow() { mReflowNeeded = TRUE; } + void needsReflow(S32 index = 0); S32 getLength() const { return getWText().length(); } S32 getLineCount() const { return mLineInfoList.size(); } @@ -292,7 +292,7 @@ protected: S32 getFirstVisibleLine() const; std::pair<S32, S32> getVisibleLines(bool fully_visible = false); S32 getLeftOffset(S32 width); - void reflow(S32 start_index = 0); + void reflow(); // cursor void updateCursorXPos(); @@ -362,7 +362,7 @@ protected: class LLScrollContainer* mScroller; // transient state - bool mReflowNeeded; // need to reflow text because of change to text contents or display region + S32 mReflowIndex; // index at which to start reflow. S32_MAX indicates no reflow needed. bool mScrollNeeded; // need to change scroll region because of change to cursor position S32 mScrollIndex; // index of first character to keep visible in scroll region diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index e76fee9f17..7a19b7427c 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -1285,8 +1285,6 @@ void LLTextEditor::cut() gClipboard.copyFromSubstring( getWText(), left_pos, length, mSourceID ); deleteSelection( FALSE ); - needsReflow(); - onKeyStroke(); } @@ -1391,8 +1389,6 @@ void LLTextEditor::pasteHelper(bool is_primary) setCursorPos(mCursorPos + insert(mCursorPos, clean_string, FALSE, LLTextSegmentPtr())); deselect(); - needsReflow(); - onKeyStroke(); } @@ -1787,8 +1783,6 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask ) if(text_may_have_changed) { - needsReflow(); - onKeyStroke(); } needsScroll(); @@ -1831,8 +1825,6 @@ BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char) // Most keystrokes will make the selection box go away, but not all will. deselect(); - needsReflow(); - onKeyStroke(); } @@ -1891,8 +1883,6 @@ void LLTextEditor::doDelete() } onKeyStroke(); - - needsReflow(); } //---------------------------------------------------------------------------- @@ -1935,8 +1925,6 @@ void LLTextEditor::undo() setCursorPos(pos); - needsReflow(); - onKeyStroke(); } @@ -1979,8 +1967,6 @@ void LLTextEditor::redo() setCursorPos(pos); - needsReflow(); - onKeyStroke(); } @@ -2339,8 +2325,6 @@ void LLTextEditor::insertText(const std::string &new_text) setCursorPos(mCursorPos + insert( mCursorPos, utf8str_to_wstring(new_text), FALSE, LLTextSegmentPtr() )); - needsReflow(); - setEnabled( enabled ); } @@ -2363,8 +2347,6 @@ void LLTextEditor::appendWidget(const LLInlineViewSegment::Params& params, const LLTextSegmentPtr segment = new LLInlineViewSegment(params, old_length, old_length + widget_wide_text.size()); insert(getLength(), widget_wide_text, FALSE, segment); - needsReflow(); - // Set the cursor and scroll position if( selection_start != selection_end ) { @@ -2389,52 +2371,6 @@ void LLTextEditor::appendWidget(const LLInlineViewSegment::Params& params, const } } - -void LLTextEditor::replaceUrlLabel(const std::string &url, - const std::string &label) -{ - // get the full (wide) text for the editor so we can change it - LLWString text = getWText(); - LLWString wlabel = utf8str_to_wstring(label); - bool modified = false; - S32 seg_start = 0; - - // iterate through each segment looking for ones styled as links - segment_set_t::iterator it; - for (it = mSegments.begin(); it != mSegments.end(); ++it) - { - LLTextSegment *seg = *it; - LLStyleConstSP style = seg->getStyle(); - - // update segment start/end length in case we replaced text earlier - S32 seg_length = seg->getEnd() - seg->getStart(); - seg->setStart(seg_start); - seg->setEnd(seg_start + seg_length); - - // if we find a link with our Url, then replace the label - if (style->isLink() && style->getLinkHREF() == url) - { - S32 start = seg->getStart(); - S32 end = seg->getEnd(); - text = text.substr(0, start) + wlabel + text.substr(end, text.size() - end + 1); - seg->setEnd(start + wlabel.size()); - modified = true; - } - - // work out the character offset for the next segment - seg_start = seg->getEnd(); - } - - // update the editor with the new (wide) text string - if (modified) - { - getViewModel()->setDisplay(text); - deselect(); - setCursorPos(mCursorPos); - needsReflow(); - } -} - void LLTextEditor::removeTextFromEnd(S32 num_chars) { if (num_chars <= 0) return; @@ -2446,7 +2382,6 @@ void LLTextEditor::removeTextFromEnd(S32 num_chars) mSelectionStart = llclamp(mSelectionStart, 0, len); mSelectionEnd = llclamp(mSelectionEnd, 0, len); - needsReflow(); needsScroll(); } @@ -2505,8 +2440,6 @@ BOOL LLTextEditor::tryToRevertToPristineState() i--; } } - - needsReflow(); } return isPristine(); // TRUE => success @@ -2681,7 +2614,6 @@ BOOL LLTextEditor::importBuffer(const char* buffer, S32 length ) startOfDoc(); deselect(); - needsReflow(); return success; } @@ -2785,7 +2717,6 @@ void LLTextEditor::updatePreedit(const LLWString &preedit_string, mPreeditStandouts = preedit_standouts; - needsReflow(); setCursorPos(insert_preedit_at + caret_position); // Update of the preedit should be caused by some key strokes. diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index 043dda8fa6..a136f9ccce 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -149,7 +149,6 @@ public: void selectNext(const std::string& search_text_in, BOOL case_insensitive, BOOL wrap = TRUE); BOOL replaceText(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive, BOOL wrap = TRUE); void replaceTextAll(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive); - void replaceUrlLabel(const std::string &url, const std::string &label); // Undo/redo stack void blockUndo(); diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index bdf1ebddac..05e366523a 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -317,7 +317,10 @@ BOOL LLInventoryModel::isObjectDescendentOf(const LLUUID& obj_id, const LLViewerInventoryCategory *LLInventoryModel::getFirstNondefaultParent(const LLUUID& obj_id) const { const LLInventoryObject* obj = getObject(obj_id); - const LLUUID& parent_id = obj->getParentUUID(); + + // Search up the parent chain until we get to root or an acceptable folder. + // This assumes there are no cycles in the tree else we'll get a hang. + LLUUID parent_id = obj->getParentUUID(); while (!parent_id.isNull()) { const LLViewerInventoryCategory *cat = getCategory(parent_id); @@ -329,6 +332,7 @@ const LLViewerInventoryCategory *LLInventoryModel::getFirstNondefaultParent(cons { return cat; } + parent_id = cat->getParentUUID(); } return NULL; } |