From 337716d946cf4ece8ba59cce82bd51b3c2148f75 Mon Sep 17 00:00:00 2001 From: richard Date: Fri, 22 Jan 2010 16:51:13 -0800 Subject: LLPointer cleanup and fix for EXT-4413 reviewed by Rick --- indra/llui/lltextbase.h | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'indra/llui/lltextbase.h') diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 038b9eaa62..5526667166 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -184,7 +184,6 @@ public: bool scrolledToEnd(); const LLFontGL* getDefaultFont() const { return mDefaultFont; } - LLStyle::Params getDefaultStyle(); public: // Fired when a URL link is clicked @@ -281,7 +280,8 @@ protected: void createDefaultSegment(); virtual void updateSegments(); void insertSegment(LLTextSegmentPtr segment_to_insert); - + LLStyle::Params getDefaultStyleParams(); + // manage lines S32 getLineStart( S32 line ) const; S32 getLineEnd( S32 line ) const; @@ -388,9 +388,9 @@ public: virtual void linkToDocument(class LLTextBase* editor); virtual const LLColor4& getColor() const; - virtual void setColor(const LLColor4 &color); - virtual const LLStyleSP getStyle() const; - virtual void setStyle(const LLStyleSP &style); + //virtual void setColor(const LLColor4 &color); + virtual LLStyleConstSP getStyle() const; + virtual void setStyle(LLStyleConstSP &style); virtual void setToken( LLKeywordToken* token ); virtual LLKeywordToken* getToken() const; virtual void setToolTip(const std::string& tooltip); @@ -426,7 +426,7 @@ protected: class LLNormalTextSegment : public LLTextSegment { public: - LLNormalTextSegment( const LLStyleSP& style, S32 start, S32 end, LLTextBase& editor ); + LLNormalTextSegment( LLStyleConstSP& style, S32 start, S32 end, LLTextBase& editor ); LLNormalTextSegment( const LLColor4& color, S32 start, S32 end, LLTextBase& editor, BOOL is_visible = TRUE); ~LLNormalTextSegment(); @@ -436,9 +436,8 @@ public: /*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect); /*virtual*/ bool canEdit() const { return true; } /*virtual*/ const LLColor4& getColor() const { return mStyle->getColor(); } - /*virtual*/ void setColor(const LLColor4 &color) { mStyle->setColor(color); } - /*virtual*/ const LLStyleSP getStyle() const { return mStyle; } - /*virtual*/ void setStyle(const LLStyleSP &style) { mStyle = style; } + /*virtual*/ LLStyleConstSP getStyle() const { return mStyle; } + /*virtual*/ void setStyle(LLStyleConstSP &style) { mStyle = style; } /*virtual*/ void setToken( LLKeywordToken* token ) { mToken = token; } /*virtual*/ LLKeywordToken* getToken() const { return mToken; } /*virtual*/ BOOL getToolTip( std::string& msg ) const; @@ -456,7 +455,7 @@ protected: protected: class LLTextBase& mEditor; - LLStyleSP mStyle; + LLStyleConstSP mStyle; S32 mFontHeight; LLKeywordToken* mToken; std::string mTooltip; -- cgit v1.3 From 66e7c2ce7715873bc29437878c5bce1ca0bee27b Mon Sep 17 00:00:00 2001 From: angela Date: Tue, 26 Jan 2010 06:48:42 +0800 Subject: fix mac build failure -- richard --- indra/llui/lltextbase.cpp | 4 ++-- indra/llui/lltextbase.h | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'indra/llui/lltextbase.h') diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 885a830c9f..ddbe81a6d4 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -2203,7 +2203,7 @@ void LLTextSegment::linkToDocument(LLTextBase*) {} const LLColor4& LLTextSegment::getColor() const { return LLColor4::white; } //void LLTextSegment::setColor(const LLColor4 &color) {} LLStyleConstSP LLTextSegment::getStyle() const {static LLStyleConstSP sp(new LLStyle()); return sp; } -void LLTextSegment::setStyle(LLStyleConstSP &style) {} +void LLTextSegment::setStyle(LLStyleConstSP style) {} void LLTextSegment::setToken( LLKeywordToken* token ) {} LLKeywordToken* LLTextSegment::getToken() const { return NULL; } void LLTextSegment::setToolTip( const std::string &msg ) {} @@ -2228,7 +2228,7 @@ BOOL LLTextSegment::hasMouseCapture() { return FALSE; } // LLNormalTextSegment // -LLNormalTextSegment::LLNormalTextSegment( LLStyleConstSP& style, S32 start, S32 end, LLTextBase& editor ) +LLNormalTextSegment::LLNormalTextSegment( LLStyleConstSP style, S32 start, S32 end, LLTextBase& editor ) : LLTextSegment(start, end), mStyle( style ), mToken(NULL), diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 5526667166..9fff910173 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -390,7 +390,7 @@ public: virtual const LLColor4& getColor() const; //virtual void setColor(const LLColor4 &color); virtual LLStyleConstSP getStyle() const; - virtual void setStyle(LLStyleConstSP &style); + virtual void setStyle(LLStyleConstSP style); virtual void setToken( LLKeywordToken* token ); virtual LLKeywordToken* getToken() const; virtual void setToolTip(const std::string& tooltip); @@ -426,7 +426,7 @@ protected: class LLNormalTextSegment : public LLTextSegment { public: - LLNormalTextSegment( LLStyleConstSP& style, S32 start, S32 end, LLTextBase& editor ); + LLNormalTextSegment( LLStyleConstSP style, S32 start, S32 end, LLTextBase& editor ); LLNormalTextSegment( const LLColor4& color, S32 start, S32 end, LLTextBase& editor, BOOL is_visible = TRUE); ~LLNormalTextSegment(); @@ -437,7 +437,7 @@ public: /*virtual*/ bool canEdit() const { return true; } /*virtual*/ const LLColor4& getColor() const { return mStyle->getColor(); } /*virtual*/ LLStyleConstSP getStyle() const { return mStyle; } - /*virtual*/ void setStyle(LLStyleConstSP &style) { mStyle = style; } + /*virtual*/ void setStyle(LLStyleConstSP style) { mStyle = style; } /*virtual*/ void setToken( LLKeywordToken* token ) { mToken = token; } /*virtual*/ LLKeywordToken* getToken() const { return mToken; } /*virtual*/ BOOL getToolTip( std::string& msg ) const; -- cgit v1.3 From 4ad357ec70e15afdfe78816990cb23c7ba17619c Mon Sep 17 00:00:00 2001 From: Monroe Linden Date: Mon, 1 Feb 2010 17:51:30 -0800 Subject: Fixes for EXT-4689 (Long-word chat spam cripples fps and/or disconnects client) Removed some unnecessary string copies in LLTextBase and LLNormalTextSegment by changing getWText() to return const LLWString& (instead of LLWString), and storing the result in a const LLWString& instead of an LLWString in places where the string doesn't need to be modified. Made LLTextViewModel::getDisplay() also return const LLWString& instead of LLWString. Removed a couple of unused local string variables in LLTextBase (the compiler flagged these after converting the local copies to const LLWString&). --- indra/llui/lltextbase.cpp | 13 +++++-------- indra/llui/lltextbase.h | 2 +- indra/llui/llviewmodel.h | 3 ++- 3 files changed, 8 insertions(+), 10 deletions(-) (limited to 'indra/llui/lltextbase.h') diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index a12b7793f7..259522a932 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -312,7 +312,6 @@ void LLTextBase::drawSelectionBackground() // Draw selection even if we don't have keyboard focus for search/replace if( hasSelection() && !mLineInfoList.empty()) { - LLWString text = getWText(); std::vector selection_rects; S32 selection_left = llmin( mSelectionStart, mSelectionEnd ); @@ -411,7 +410,7 @@ void LLTextBase::drawCursor() && gFocusMgr.getAppHasFocus() && !mReadOnly) { - LLWString wtext = getWText(); + const LLWString &wtext = getWText(); const llwchar* text = wtext.c_str(); LLRect cursor_rect = getLocalRectFromDocIndex(mCursorPos); @@ -497,7 +496,6 @@ void LLTextBase::drawCursor() void LLTextBase::drawText() { - LLWString text = getWText(); const S32 text_len = getLength(); if( text_len <= 0 ) { @@ -1116,7 +1114,6 @@ void LLTextBase::reflow(S32 start_index) S32 line_start_index = 0; const S32 text_available_width = mVisibleTextRect.getWidth() - mHPad; // reserve room for margin S32 remaining_pixels = text_available_width; - LLWString text(getWText()); S32 line_count = 0; // find and erase line info structs starting at start_index and going to end of document @@ -1759,7 +1756,7 @@ void LLTextBase::setWText(const LLWString& text) setText(wstring_to_utf8str(text)); } -LLWString LLTextBase::getWText() const +const LLWString& LLTextBase::getWText() const { return getViewModel()->getDisplay(); } @@ -2454,7 +2451,7 @@ bool LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& widt if (num_chars > 0) { height = mFontHeight; - LLWString text = mEditor.getWText(); + const LLWString &text = mEditor.getWText(); // if last character is a newline, then return true, forcing line break llwchar last_char = text[mStart + first_char + num_chars - 1]; if (last_char == '\n') @@ -2481,7 +2478,7 @@ bool LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& widt S32 LLNormalTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const { - LLWString text = mEditor.getWText(); + const LLWString &text = mEditor.getWText(); return mStyle->getFont()->charFromPixelOffset(text.c_str(), mStart + start_offset, (F32)segment_local_x_coord, F32_MAX, @@ -2491,7 +2488,7 @@ S32 LLNormalTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset, S32 LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const { - LLWString text = mEditor.getWText(); + const LLWString &text = mEditor.getWText(); LLUIImagePtr image = mStyle->getImage(); if( image.notNull()) diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 48d5478088..b5c7fab67a 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -145,7 +145,7 @@ public: // wide-char versions void setWText(const LLWString& text); - LLWString getWText() const; + const LLWString& getWText() const; void appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params = LLStyle::Params()); // force reflow of text diff --git a/indra/llui/llviewmodel.h b/indra/llui/llviewmodel.h index c8a9b52cca..992365d44d 100644 --- a/indra/llui/llviewmodel.h +++ b/indra/llui/llviewmodel.h @@ -107,7 +107,8 @@ public: // New functions /// Get the stored value in string form - LLWString getDisplay() const { return mDisplay; } + const LLWString& getDisplay() const { return mDisplay; } + /** * Set the display string directly (see LLTextEditor). What the user is * editing is actually the LLWString value rather than the underlying -- cgit v1.3 From 38315a063d83bf4dbf90569dbe37a344d91349a7 Mon Sep 17 00:00:00 2001 From: Dmitry Zaporozhan Date: Tue, 2 Feb 2010 14:25:31 +0200 Subject: Fixed normal bug EXT-4740 - Object inspector hides however context menu present --HG-- branch : product-engine --- indra/llui/lltextbase.cpp | 10 ++++++++++ indra/llui/lltextbase.h | 1 + indra/newview/llinspect.cpp | 24 ++++++++++++++++++++++++ indra/newview/llinspect.h | 3 +++ indra/newview/llinspectavatar.cpp | 13 ++++++++++--- indra/newview/llinspectobject.cpp | 11 +++++++++-- 6 files changed, 57 insertions(+), 5 deletions(-) (limited to 'indra/llui/lltextbase.h') diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 259522a932..b977e50bc1 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1023,6 +1023,16 @@ void LLTextBase::setReadOnlyColor(const LLColor4 &c) mReadOnlyFgColor = c; } +//virtual +void LLTextBase::handleVisibilityChange( BOOL new_visibility ) +{ + if(!new_visibility && mPopupMenu) + { + mPopupMenu->hide(); + } + LLUICtrl::handleVisibilityChange(new_visibility); +} + //virtual void LLTextBase::setValue(const LLSD& value ) { diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index b5c7fab67a..ed2f239476 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -122,6 +122,7 @@ public: /*virtual*/ BOOL acceptsTextInput() const { return !mReadOnly; } /*virtual*/ void setColor( const LLColor4& c ); virtual void setReadOnlyColor(const LLColor4 &c); + virtual void handleVisibilityChange( BOOL new_visibility ); /*virtual*/ void setValue(const LLSD& value ); /*virtual*/ LLTextViewModel* getViewModel() const; diff --git a/indra/newview/llinspect.cpp b/indra/newview/llinspect.cpp index c7b8db9635..c7b651f37c 100644 --- a/indra/newview/llinspect.cpp +++ b/indra/newview/llinspect.cpp @@ -34,6 +34,7 @@ #include "llcontrol.h" // LLCachedControl #include "llui.h" // LLUI::sSettingsGroups +#include "llviewermenu.h" LLInspect::LLInspect(const LLSD& key) : LLFloater(key), @@ -108,3 +109,26 @@ void LLInspect::onMouseLeave(S32 x, S32 y, MASK mask) { mOpenTimer.unpause(); } + +bool LLInspect::childHasVisiblePopupMenu() +{ + // Child text-box may spawn a pop-up menu, if mouse is over the menu, Inspector + // will hide(which is not expected). + // This is an attempt to find out if child control has spawned a menu. + + LLView* child_menu = gMenuHolder->getVisibleMenu(); + if(child_menu) + { + LLRect floater_rc = calcScreenRect(); + LLRect menu_screen_rc = child_menu->calcScreenRect(); + S32 mx, my; + LLUI::getMousePositionScreen(&mx, &my); + + // This works wrong if we spawn a menu near Inspector and menu overlaps Inspector. + if(floater_rc.overlaps(menu_screen_rc) && menu_screen_rc.pointInRect(mx, my)) + { + return true; + } + } + return false; +} diff --git a/indra/newview/llinspect.h b/indra/newview/llinspect.h index a1cb9cd71c..f8c86618d2 100644 --- a/indra/newview/llinspect.h +++ b/indra/newview/llinspect.h @@ -56,6 +56,9 @@ public: /*virtual*/ void onFocusLost(); protected: + + virtual bool childHasVisiblePopupMenu(); + LLFrameTimer mCloseTimer; LLFrameTimer mOpenTimer; }; diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp index 3a41aebf28..b2cdc0738f 100644 --- a/indra/newview/llinspectavatar.cpp +++ b/indra/newview/llinspectavatar.cpp @@ -393,11 +393,18 @@ void LLInspectAvatar::onMouseLeave(S32 x, S32 y, MASK mask) { LLMenuGL* gear_menu = getChild("gear_btn")->getMenu(); LLMenuGL* gear_menu_self = getChild("gear_self_btn")->getMenu(); - if ( !(gear_menu && gear_menu->getVisible()) && - !(gear_menu_self && gear_menu_self->getVisible())) + if ( gear_menu && gear_menu->getVisible() && + gear_menu_self && gear_menu_self->getVisible() ) { - mOpenTimer.unpause(); + return; + } + + if(childHasVisiblePopupMenu()) + { + return; } + + mOpenTimer.unpause(); } void LLInspectAvatar::updateModeratorPanel() diff --git a/indra/newview/llinspectobject.cpp b/indra/newview/llinspectobject.cpp index dd313c528d..1a5795a2ae 100644 --- a/indra/newview/llinspectobject.cpp +++ b/indra/newview/llinspectobject.cpp @@ -575,10 +575,17 @@ void LLInspectObject::updateSecureBrowsing() void LLInspectObject::onMouseLeave(S32 x, S32 y, MASK mask) { LLMenuGL* gear_menu = getChild("gear_btn")->getMenu(); - if ( !(gear_menu && gear_menu->getVisible())) + if ( gear_menu && gear_menu->getVisible() ) { - mOpenTimer.unpause(); + return; + } + + if(childHasVisiblePopupMenu()) + { + return; } + + mOpenTimer.unpause(); } void LLInspectObject::onClickBuy() -- cgit v1.3 From 5491dd6e983f8fccbd687c7c45ef43125dfc0f6c Mon Sep 17 00:00:00 2001 From: Monroe Linden Date: Tue, 2 Feb 2010 18:24:11 -0800 Subject: Further fixes for EXT-4689 (Long-word chat spam cripples fps and/or disconnects client). This should fix the inefficiencies in the append path that made viewer FPS drop severely when addinglarge amounts of text to the nearby chat floater. Resizing the floater with a huge amount of text in it is still pretty bad, but fixing that will require some bigger architectural changes. Changed LLTextBase::needsReflow() to take an offset at which to start reflow processing. Changed most needsReflow() calls in LLTextBase to supply a proper index. Changed LLTextBase::reflow() to use the reflow index maintained by needsReflow(). Removed all needsReflow() calls from LLTextEditor (the only way for it to manipulate the text is through functions in LLTextBase that already manage reflowing internally). Removed LLTextEditor::replaceUrlLabel(), since it was identical to the inherited version LLTextBase::replaceUrlLabel(). Reviewed by Richard. --- indra/llui/lltextbase.cpp | 28 ++++++++++++------ indra/llui/lltextbase.h | 6 ++-- indra/llui/lltexteditor.cpp | 69 --------------------------------------------- indra/llui/lltexteditor.h | 1 - 4 files changed, 22 insertions(+), 82 deletions(-) (limited to 'indra/llui/lltextbase.h') 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 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(); -- cgit v1.3 From ef9b7c5b36c7521c4519e682aa312c4c25c31c2f Mon Sep 17 00:00:00 2001 From: Monroe Linden Date: Thu, 18 Feb 2010 15:45:31 -0800 Subject: Fix for EXT-5120 "Mouse-up in the scrollbar to the right of a link in nearby chat window opens the link". Added an optional bool parameter "hit_past_end_of_line" to LLTextBase:: getDocIndexFromLocalCoord() and getSegmentAtLocalPos(). Default is true, which gives the old behavior. If false, clicks past the end-of-line won't map to the last segment on the line. Made LLNormalTextSegment::handleHover(), handleRightMouseDown(), handleMouseDown(), and handleMouseUp() call getSegmentAtLocalPos() in this new mode before processing URL actions, and only do the processing if it returns the same segment. Reviewed by Richard. --- indra/llui/lltextbase.cpp | 40 ++++++++++++++++++++++++++++------------ indra/llui/lltextbase.h | 8 ++++++-- 2 files changed, 34 insertions(+), 14 deletions(-) (limited to 'indra/llui/lltextbase.h') diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index b84e6f45fb..851fb966ec 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1445,10 +1445,10 @@ LLTextBase::segment_set_t::const_iterator LLTextBase::getSegIterContaining(S32 i } // Finds the text segment (if any) at the give local screen position -LLTextSegmentPtr LLTextBase::getSegmentAtLocalPos( S32 x, S32 y ) +LLTextSegmentPtr LLTextBase::getSegmentAtLocalPos( S32 x, S32 y, bool hit_past_end_of_line) { // Find the cursor position at the requested local screen position - S32 offset = getDocIndexFromLocalCoord( x, y, FALSE ); + S32 offset = getDocIndexFromLocalCoord( x, y, FALSE, hit_past_end_of_line); segment_set_t::iterator seg_iter = getSegIterContaining(offset); if (seg_iter != mSegments.end()) { @@ -1788,7 +1788,7 @@ const LLWString& LLTextBase::getWText() const // will be put to its right. If round is false, the cursor will always be put to the // character's left. -S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const +S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, bool hit_past_end_of_line) const { // Figure out which line we're nearest to. LLRect visible_region = getVisibleDocumentRect(); @@ -1817,7 +1817,7 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round S32 text_width, text_height; segmentp->getDimensions(line_seg_offset, segment_line_length, text_width, text_height); if (local_x < start_x + text_width // cursor to left of right edge of text - || segmentp->getEnd() >= line_iter->mDocIndexEnd - 1) // or this segment wraps to next line + || (hit_past_end_of_line && (segmentp->getEnd() >= line_iter->mDocIndexEnd - 1))) // or this segment wraps to next line { // Figure out which character we're nearest to. S32 offset; @@ -2402,8 +2402,12 @@ BOOL LLNormalTextSegment::handleHover(S32 x, S32 y, MASK mask) { if (getStyle() && getStyle()->isLink()) { - LLUI::getWindow()->setCursor(UI_CURSOR_HAND); - return TRUE; + // Only process the click if it's actually in this segment, not to the right of the end-of-line. + if(mEditor.getSegmentAtLocalPos(x, y, false) == this) + { + LLUI::getWindow()->setCursor(UI_CURSOR_HAND); + return TRUE; + } } return FALSE; } @@ -2412,8 +2416,12 @@ BOOL LLNormalTextSegment::handleRightMouseDown(S32 x, S32 y, MASK mask) { if (getStyle() && getStyle()->isLink()) { - mEditor.createUrlContextMenu(x, y, getStyle()->getLinkHREF()); - return TRUE; + // Only process the click if it's actually in this segment, not to the right of the end-of-line. + if(mEditor.getSegmentAtLocalPos(x, y, false) == this) + { + mEditor.createUrlContextMenu(x, y, getStyle()->getLinkHREF()); + return TRUE; + } } return FALSE; } @@ -2422,8 +2430,12 @@ BOOL LLNormalTextSegment::handleMouseDown(S32 x, S32 y, MASK mask) { if (getStyle() && getStyle()->isLink()) { - // eat mouse down event on hyperlinks, so we get the mouse up - return TRUE; + // Only process the click if it's actually in this segment, not to the right of the end-of-line. + if(mEditor.getSegmentAtLocalPos(x, y, false) == this) + { + // eat mouse down event on hyperlinks, so we get the mouse up + return TRUE; + } } return FALSE; @@ -2433,8 +2445,12 @@ BOOL LLNormalTextSegment::handleMouseUp(S32 x, S32 y, MASK mask) { if (getStyle() && getStyle()->isLink()) { - LLUrlAction::clickAction(getStyle()->getLinkHREF()); - return TRUE; + // Only process the click if it's actually in this segment, not to the right of the end-of-line. + if(mEditor.getSegmentAtLocalPos(x, y, false) == this) + { + LLUrlAction::clickAction(getStyle()->getLinkHREF()); + return TRUE; + } } return FALSE; diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 3dda6f4cc8..5b24c63557 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -48,6 +48,7 @@ class LLContextMenu; class LLTextSegment; +class LLNormalTextSegment; typedef LLPointer LLTextSegmentPtr; @@ -61,6 +62,9 @@ class LLTextBase protected LLEditMenuHandler { public: + friend class LLTextSegment; + friend class LLNormalTextSegment; + struct LineSpacingParams : public LLInitParam::Choice { Alternative multiple; @@ -165,7 +169,7 @@ public: S32 getVPad() { return mVPad; } S32 getHPad() { return mHPad; } - S32 getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const; + S32 getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, bool hit_past_end_of_line = true) const; LLRect getLocalRectFromDocIndex(S32 pos) const; LLRect getDocRectFromDocIndex(S32 pos) const; @@ -275,7 +279,7 @@ protected: // manage segments void getSegmentAndOffset( S32 startpos, segment_set_t::const_iterator* seg_iter, S32* offsetp ) const; void getSegmentAndOffset( S32 startpos, segment_set_t::iterator* seg_iter, S32* offsetp ); - LLTextSegmentPtr getSegmentAtLocalPos( S32 x, S32 y ); + LLTextSegmentPtr getSegmentAtLocalPos( S32 x, S32 y, bool hit_past_end_of_line = true); segment_set_t::iterator getSegIterContaining(S32 index); segment_set_t::const_iterator getSegIterContaining(S32 index) const; void clearSegments(); -- cgit v1.3