diff options
-rw-r--r-- | indra/llui/llstyle.cpp | 25 | ||||
-rw-r--r-- | indra/llui/llstyle.h | 11 | ||||
-rw-r--r-- | indra/llui/lltextbase.cpp | 222 | ||||
-rw-r--r-- | indra/llui/lltextbase.h | 33 | ||||
-rw-r--r-- | indra/newview/llexpandabletextbox.cpp | 18 |
5 files changed, 179 insertions, 130 deletions
diff --git a/indra/llui/llstyle.cpp b/indra/llui/llstyle.cpp index df4b0ef6a0..f1d57a2273 100644 --- a/indra/llui/llstyle.cpp +++ b/indra/llui/llstyle.cpp @@ -43,8 +43,8 @@ LLStyle::Params::Params() image("image"), link_href("href"), is_link("is_link") -{} - +{ +} LLStyle::LLStyle(const LLStyle::Params& p) : mVisible(p.visible), @@ -57,14 +57,31 @@ LLStyle::LLStyle(const LLStyle::Params& p) mDropShadow(p.drop_shadow), mImagep(p.image()), mAlpha(p.alpha) -{} +{ +} + +LLStyle* LLStyle::makeCopy() const +{ + LLStyle* copy = new LLStyle(); + copy->mDropShadow = mDropShadow; + copy->mFontName = mFontName; + copy->mLink = mLink; + copy->mColor = mColor; + copy->mReadOnlyColor = mReadOnlyColor; + copy->mSelectedColor = mSelectedColor; + copy->mFont = mFont; + copy->mImagep = mImagep; + copy->mAlpha = mAlpha; + copy->mVisible = mVisible; + copy->mIsLink = mIsLink; + return copy; +} void LLStyle::setFont(const LLFontGL* font) { mFont = font; } - const LLFontGL* LLStyle::getFont() const { return mFont; diff --git a/indra/llui/llstyle.h b/indra/llui/llstyle.h index e506895de5..d3a50f99a5 100644 --- a/indra/llui/llstyle.h +++ b/indra/llui/llstyle.h @@ -33,6 +33,10 @@ #include "lluiimage.h" class LLFontGL; +class LLStyle; + +typedef LLPointer<LLStyle> LLStyleSP; +typedef LLPointer<const LLStyle> LLStyleConstSP; class LLStyle : public LLRefCount { @@ -52,6 +56,9 @@ public: Params(); }; LLStyle(const Params& p = Params()); + LLStyleSP clone() const { return makeCopy(); } + LLStyleConstSP cloneConst() const { return makeCopy(); } + public: const LLUIColor& getColor() const { return mColor; } void setColor(const LLUIColor &color) { mColor = color; } @@ -104,6 +111,7 @@ public: protected: ~LLStyle() = default; + LLStyle* makeCopy() const; private: std::string mFontName; @@ -118,7 +126,4 @@ private: bool mIsLink; }; -typedef LLPointer<LLStyle> LLStyleSP; -typedef LLPointer<const LLStyle> LLStyleConstSP; - #endif // LL_LLSTYLE_H diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 1bfb137e0f..2a8b71055d 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -886,7 +886,7 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s } // shift remaining segments to right - for(;seg_iter != mSegments.end(); ++seg_iter) + for (;seg_iter != mSegments.end(); ++seg_iter) { LLTextSegmentPtr segmentp = *seg_iter; segmentp->setStart(segmentp->getStart() + insert_len); @@ -913,22 +913,29 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s // Insert special segments where necessary (insertSegment takes care of splitting normal text segments around them for us) if (mUseEmoji) { - LLStyleSP emoji_style; LLEmojiDictionary* ed = LLEmojiDictionary::instanceExists() ? LLEmojiDictionary::getInstance() : NULL; - for (S32 text_kitty = 0, text_len = static_cast<S32>(wstr.size()); text_kitty < text_len; text_kitty++) + for (std::size_t i = 0; i < wstr.size(); ++i) { - llwchar code = wstr[text_kitty]; + llwchar code = wstr[i]; bool isEmoji = ed ? ed->isEmoji(code) : LLStringOps::isEmoji(code); if (isEmoji) { - if (!emoji_style) + S32 new_seg_start = pos + (S32)i; + segment_set_t::iterator cur_seg_iter = getSegIterContaining(new_seg_start); + LLStyleSP new_style; + if (cur_seg_iter != mSegments.end()) // Should be 100% { - emoji_style = new LLStyle(getStyleParams()); - emoji_style->setFont(LLFontGL::getFontEmojiLarge()); + // Use font EmojiLarge but preserve the target font style + new_style = (*cur_seg_iter)->getStyle()->clone(); + U8 font_style = new_style->getFont()->getFontDesc().getStyle(); + new_style->setFont(LLFontGL::getFont(LLFontDescriptor("Emoji", "Large", font_style))); } - - S32 new_seg_start = pos + text_kitty; - insertSegment(new LLEmojiTextSegment(emoji_style, new_seg_start, new_seg_start + 1, *this)); + else // Very unlikely + { + new_style = new LLStyle(getStyleParams()); + new_style->setFont(LLFontGL::getFontEmojiLarge()); + } + insertSegment(new LLEmojiTextSegment(new_style, new_seg_start, new_seg_start + 1, *this)); } } } @@ -1059,14 +1066,18 @@ void LLTextBase::insertSegment(LLTextSegmentPtr segment_to_insert) S32 old_segment_end = cur_segmentp->getEnd(); // split old at start point for new segment cur_segmentp->setEnd(segment_to_insert->getStart()); - // advance to next segment - // insert remainder of old segment - LLStyleConstSP sp = cur_segmentp->getStyle(); - LLTextSegmentPtr remainder_segment = new LLNormalTextSegment( sp, segment_to_insert->getStart(), old_segment_end, *this); - mSegments.insert(cur_seg_iter, remainder_segment); - remainder_segment->linkToDocument(this); // insert new segment before remainder of old segment mSegments.insert(cur_seg_iter, segment_to_insert); + // advance to next segment + // insert remainder of old segment + if (segment_to_insert->getEnd() < old_segment_end) + { + LLTextSegmentPtr remainder_segment = cur_segmentp->clone(*this); + remainder_segment->setStart(segment_to_insert->getEnd()); + remainder_segment->setEnd(old_segment_end); + mSegments.insert(cur_seg_iter, remainder_segment); + remainder_segment->linkToDocument(this); + } segment_to_insert->linkToDocument(this); // at this point, there will be two overlapping segments owning the text @@ -1080,7 +1091,7 @@ void LLTextBase::insertSegment(LLTextSegmentPtr segment_to_insert) // now delete/truncate remaining segments as necessary // cur_seg_iter points to segment before incoming segment - while(cur_seg_iter != mSegments.end()) + while (cur_seg_iter != mSegments.end()) { cur_segmentp = *cur_seg_iter; if (cur_segmentp == segment_to_insert) @@ -1966,7 +1977,7 @@ void LLTextBase::updateSegments() createDefaultSegment(); } -void LLTextBase::getSegmentAndOffset( S32 startpos, segment_set_t::const_iterator* seg_iter, S32* offsetp ) const +void LLTextBase::getSegmentAndOffset(S32 startpos, segment_set_t::const_iterator* seg_iter, S32* offsetp) const { *seg_iter = getSegIterContaining(startpos); if (*seg_iter == mSegments.end()) @@ -1979,7 +1990,7 @@ void LLTextBase::getSegmentAndOffset( S32 startpos, segment_set_t::const_iterato } } -void LLTextBase::getSegmentAndOffset( S32 startpos, segment_set_t::iterator* seg_iter, S32* offsetp ) +void LLTextBase::getSegmentAndOffset(S32 startpos, segment_set_t::iterator* seg_iter, S32* offsetp) { *seg_iter = getSegIterContaining(startpos); if (*seg_iter == mSegments.end()) @@ -1997,7 +2008,8 @@ LLTextBase::segment_set_t::iterator LLTextBase::getEditableSegIterContaining(S32 segment_set_t::iterator it = getSegIterContaining(index); segment_set_t::iterator orig_it = it; - if (it == mSegments.end()) return it; + if (it == mSegments.end()) + return it; if (!(*it)->canEdit() && index == (*it)->getStart() @@ -2009,6 +2021,7 @@ LLTextBase::segment_set_t::iterator LLTextBase::getEditableSegIterContaining(S32 return it; } } + return orig_it; } @@ -2016,7 +2029,8 @@ LLTextBase::segment_set_t::const_iterator LLTextBase::getEditableSegIterContaini { segment_set_t::const_iterator it = getSegIterContaining(index); segment_set_t::const_iterator orig_it = it; - if (it == mSegments.end()) return it; + if (it == mSegments.end()) + return it; if (!(*it)->canEdit() && index == (*it)->getStart() @@ -2028,6 +2042,7 @@ LLTextBase::segment_set_t::const_iterator LLTextBase::getEditableSegIterContaini return it; } } + return orig_it; } @@ -2036,7 +2051,10 @@ LLTextBase::segment_set_t::iterator LLTextBase::getSegIterContaining(S32 index) static LLPointer<LLIndexSegment> index_segment = new LLIndexSegment(); // when there are no segments, we return the end iterator, which must be checked by caller - if (mSegments.size() <= 1) { return mSegments.begin(); } + if (mSegments.size() <= 1) + { + return mSegments.begin(); + } index_segment->setStart(index); index_segment->setEnd(index); @@ -2049,7 +2067,10 @@ LLTextBase::segment_set_t::const_iterator LLTextBase::getSegIterContaining(S32 i static LLPointer<LLIndexSegment> index_segment = new LLIndexSegment(); // when there are no segments, we return the end iterator, which must be checked by caller - if (mSegments.size() <= 1) { return mSegments.begin(); } + if (mSegments.size() <= 1) + { + return mSegments.begin(); + } index_segment->setStart(index); index_segment->setEnd(index); @@ -2058,7 +2079,7 @@ 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, bool hit_past_end_of_line) +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, hit_past_end_of_line); @@ -2067,10 +2088,8 @@ LLTextSegmentPtr LLTextBase::getSegmentAtLocalPos( S32 x, S32 y, bool hit_past_e { return *seg_iter; } - else - { - return LLTextSegmentPtr(); - } + + return LLTextSegmentPtr(); } void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url) @@ -2078,7 +2097,7 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url) // work out the XUI menu file to use for this url LLUrlMatch match; std::string url = in_url; - if (! LLUrlRegistry::instance().findUrl(url, match)) + if (!LLUrlRegistry::instance().findUrl(url, match)) { return; } @@ -2192,10 +2211,8 @@ static LLUIImagePtr image_from_icon_name(const std::string& icon_name) { return LLUI::getUIImageByID( LLUUID(icon_name) ); } - else - { - return LLUI::getUIImage(icon_name); - } + + return LLUI::getUIImage(icon_name); } @@ -2205,17 +2222,17 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para LLStyle::Params style_params(getStyleParams()); style_params.overwriteFrom(input_params); - S32 part = (S32)LLTextParser::WHOLE; + LLTextParser::EHighlightPosition part = LLTextParser::WHOLE; if (mParseHTML && !style_params.is_link) // Don't search for URLs inside a link segment (STORM-358). { - S32 start=0,end=0; + U32 next = 0; LLUrlMatch match; std::string text = new_text; while (LLUrlRegistry::instance().findUrl(text, match, boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3), isContentTrusted() || mAlwaysShowIcons)) { - start = match.getStart(); - end = match.getEnd()+1; + U32 start = match.getStart(); + next = match.getEnd() + 1; LLStyle::Params link_params(style_params); link_params.overwriteFrom(match.getStyle()); @@ -2223,16 +2240,16 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para // output the text before the Url if (start > 0) { - if (part == (S32)LLTextParser::WHOLE || - part == (S32)LLTextParser::START) + if (part == LLTextParser::WHOLE || + part == LLTextParser::START) { - part = (S32)LLTextParser::START; + part = LLTextParser::START; } else { - part = (S32)LLTextParser::MIDDLE; + part = LLTextParser::MIDDLE; } - std::string subtext=text.substr(0,start); + std::string subtext = text.substr(0, start); appendAndHighlightText(subtext, part, style_params); } @@ -2244,14 +2261,8 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para } // output the styled Url - appendAndHighlightTextImpl(match.getLabel(), part, link_params, match.underlineOnHoverOnly()); - bool tooltip_required = !match.getTooltip().empty(); - - // set the tooltip for the Url label - if (tooltip_required) - { - setLastSegmentToolTip(match.getTooltip()); - } + appendAndHighlightTextImpl(match.getLabel(), part, link_params, match.underlineOnHoverOnly(), match.getTooltip()); + bool tooltip_required = !match.getTooltip().empty(); // show query part of url with gray color only for LLUrlEntryHTTP url entries std::string label = match.getQuery(); @@ -2259,31 +2270,27 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para { link_params.color = LLColor4::grey; link_params.readonly_color = LLColor4::grey; - appendAndHighlightTextImpl(label, part, link_params, match.underlineOnHoverOnly()); - - // set the tooltip for the query part of url - if (tooltip_required) - { - setLastSegmentToolTip(match.getTooltip()); - } + appendAndHighlightTextImpl(label, part, link_params, match.underlineOnHoverOnly(), match.getTooltip()); } - // move on to the rest of the text after the Url - if (end < (S32)text.length()) - { - text = text.substr(end,text.length() - end); - end=0; - part=(S32)LLTextParser::END; - } - else - { + if (next >= text.length()) break; - } + + // move on to the rest of the text after the Url + text = text.substr(next, text.length() - next); + next = 0; + part = LLTextParser::END; } - if (part != (S32)LLTextParser::WHOLE) - part=(S32)LLTextParser::END; - if (end < (S32)text.length()) + + if (part != LLTextParser::WHOLE) + { + part = LLTextParser::END; + } + + if (next < text.length()) + { appendAndHighlightText(text, part, style_params); + } } else { @@ -2307,7 +2314,7 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c if (new_text.empty()) return; - if(prepend_newline) + if (prepend_newline) appendLineBreakSegment(input_params); appendTextImpl(new_text,input_params); } @@ -2365,6 +2372,7 @@ S32 LLTextBase::removeFirstLine() removeStringNoUndo(0, length); return length; } + return 0; } @@ -2407,10 +2415,11 @@ void LLTextBase::appendLineBreakSegment(const LLStyle::Params& style_params) void LLTextBase::appendImageSegment(const LLStyle::Params& style_params) { - if(getPlainText()) + if (getPlainText()) { return; } + segment_vec_t segments; LLStyleConstSP sp(new LLStyle(style_params)); segments.push_back(new LLImageTextSegment(sp, getLength(),*this)); @@ -2427,7 +2436,8 @@ void LLTextBase::appendWidget(const LLInlineViewSegment::Params& params, const s insertStringNoUndo(getLength(), widget_wide_text, &segments); } -void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params, bool underline_on_hover_only) +void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, LLTextParser::EHighlightPosition highlight_part, + const LLStyle::Params& style_params, bool underline_on_hover_only, std::string tooltip) { // Save old state S32 selection_start = mSelectionStart; @@ -2445,7 +2455,7 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig { LLStyle::Params highlight_params(style_params); - auto pieces = LLTextParser::instance().parsePartialLineHighlights(new_text, highlight_params.color, (LLTextParser::EHighlightPosition)highlight_part); + auto pieces = LLTextParser::instance().parsePartialLineHighlights(new_text, highlight_params.color, highlight_part); for (S32 i = 0; i < pieces.size(); i++) { const auto& piece_pair = pieces[i]; @@ -2467,8 +2477,13 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig { segmentp = new LLNormalTextSegment(sp, cur_length, cur_length + static_cast<S32>(wide_text.size()), *this); } - segment_vec_t segments; - segments.push_back(segmentp); + + if (!tooltip.empty()) + { + segmentp->setToolTip(tooltip); + } + + segment_vec_t segments = { segmentp }; insertStringNoUndo(cur_length, wide_text, &segments); } } @@ -2477,22 +2492,28 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig LLWString wide_text; wide_text = utf8str_to_wstring(new_text); - segment_vec_t segments; S32 segment_start = old_length; S32 segment_end = old_length + static_cast<S32>(wide_text.size()); LLStyleConstSP sp(new LLStyle(style_params)); + LLTextSegmentPtr segmentp; if (underline_on_hover_only || mSkipLinkUnderline) { LLStyle::Params normal_style_params(style_params); normal_style_params.font.style("NORMAL"); LLStyleConstSP normal_sp(new LLStyle(normal_style_params)); - segments.push_back(new LLOnHoverChangeableTextSegment(sp, normal_sp, segment_start, segment_end, *this)); + segmentp = new LLOnHoverChangeableTextSegment(sp, normal_sp, segment_start, segment_end, *this); } else { - segments.push_back(new LLNormalTextSegment(sp, segment_start, segment_end, *this)); + segmentp = new LLNormalTextSegment(sp, segment_start, segment_end, *this); } + if (!tooltip.empty()) + { + segmentp->setToolTip(tooltip); + } + + segment_vec_t segments = { segmentp }; insertStringNoUndo(getLength(), wide_text, &segments); } @@ -2515,7 +2536,9 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig } } -void LLTextBase::appendAndHighlightText(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params, bool underline_on_hover_only) +void LLTextBase::appendAndHighlightText(const std::string &new_text, + LLTextParser::EHighlightPosition highlight_part, + const LLStyle::Params& style_params, bool underline_on_hover_only) { if (new_text.empty()) { @@ -2527,13 +2550,15 @@ void LLTextBase::appendAndHighlightText(const std::string &new_text, S32 highlig while (pos != std::string::npos) { - if (pos != start) + if (pos > start) { - std::string str = std::string(new_text,start,pos-start); + std::string str = std::string(new_text, start, pos - start); appendAndHighlightTextImpl(str, highlight_part, style_params, underline_on_hover_only); } appendLineBreakSegment(style_params); - start = pos+1; + start = pos + 1; + if (start >= new_text.length()) + return; pos = new_text.find("\n", start); } @@ -3259,26 +3284,9 @@ boost::signals2::connection LLTextBase::setIsObjectBlockedCallback(const is_bloc // LLTextSegment::~LLTextSegment() -{} - -// static -LLStyleSP LLTextSegment::cloneStyle(LLTextBase& target, const LLStyle* source) { - // Take most params from target - LLStyle::Params params = target.getStyleParams(); - LLStyle* style = new LLStyle(params); - - // Take some params from source - style->setLinkHREF(source->getLinkHREF()); - if (source->isImage()) - { - style->setImage(source->getImage()->getName()); - } - - return style; } - bool LLTextSegment::getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const { width = 0; height = 0; return false; } bool LLTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const { @@ -3614,19 +3622,27 @@ void LLNormalTextSegment::setToolTip(const std::string& tooltip) // we cannot replace a keyword tooltip that's loaded from a file if (mToken) { - LL_WARNS() << "LLTextSegment::setToolTip: cannot replace keyword tooltip." << LL_ENDL; + LL_WARNS() << "Cannot replace keyword tooltip." << LL_ENDL; return; } mTooltip = tooltip; } +LLStyleConstSP LLNormalTextSegment::cloneStyle(LLTextBase& target, const LLStyle* source) const +{ + return (&target == &mEditor) ? mStyle : mStyle->cloneConst(); +} + // virtual LLTextSegmentPtr LLNormalTextSegment::clone(LLTextBase& target) const { LLStyleConstSP sp(cloneStyle(target, mStyle)); - return new LLNormalTextSegment(sp, mStart, mEnd, target); + LLNormalTextSegment* copy = new LLNormalTextSegment(sp, mStart, mEnd, target); + copy->mTooltip = mTooltip; + return copy; } +// virtual bool LLNormalTextSegment::getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const { height = 0; @@ -3994,7 +4010,7 @@ LLImageTextSegment::~LLImageTextSegment() // virtual LLTextSegmentPtr LLImageTextSegment::clone(LLTextBase& target) const { - LLStyleConstSP sp(cloneStyle(target, mStyle)); + LLStyleConstSP sp((&target == &mEditor) ? mStyle : mStyle->cloneConst()); return new LLImageTextSegment(sp, mStart, target); } diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 76d4e160af..b3fde84f5f 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -35,6 +35,7 @@ #include "llstyle.h" #include "llkeywords.h" #include "llpanel.h" +#include "lltextparser.h" #include <string> #include <vector> @@ -64,7 +65,6 @@ public: {} virtual ~LLTextSegment(); virtual LLTextSegmentPtr clone(LLTextBase& terget) const { return new LLTextSegment(mStart, mEnd); } - static LLStyleSP cloneStyle(LLTextBase& target, const LLStyle* source); bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const; @@ -132,6 +132,7 @@ public: LLNormalTextSegment( LLStyleConstSP style, S32 start, S32 end, LLTextBase& editor ); LLNormalTextSegment( const LLUIColor& color, S32 start, S32 end, LLTextBase& editor, bool is_visible = true); virtual ~LLNormalTextSegment(); + LLStyleConstSP cloneStyle(LLTextBase& target, const LLStyle* source) const; /*virtual*/ LLTextSegmentPtr clone(LLTextBase& target) const; /*virtual*/ bool getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const; @@ -267,7 +268,7 @@ class LLLineBreakTextSegment : public LLTextSegment { public: - LLLineBreakTextSegment(LLStyleConstSP style,S32 pos); + LLLineBreakTextSegment(LLStyleConstSP style, S32 pos); LLLineBreakTextSegment(S32 pos); ~LLLineBreakTextSegment(); /*virtual*/ LLTextSegmentPtr clone(LLTextBase& target) const; @@ -282,19 +283,19 @@ private: class LLImageTextSegment : public LLTextSegment { public: - LLImageTextSegment(LLStyleConstSP style,S32 pos,class LLTextBase& editor); + LLImageTextSegment(LLStyleConstSP style, S32 pos,class LLTextBase& editor); ~LLImageTextSegment(); /*virtual*/ LLTextSegmentPtr clone(LLTextBase& target) const; - /*virtual*/ bool getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const; - S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 char_offset, S32 max_chars, S32 line_ind) const; - F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect); + /*virtual*/ bool getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const; + /*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 char_offset, S32 max_chars, S32 line_ind) const; + /*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect); /*virtual*/ bool handleToolTip(S32 x, S32 y, MASK mask); /*virtual*/ void setToolTip(const std::string& tooltip); private: - class LLTextBase& mEditor; + LLTextBase& mEditor; LLStyleConstSP mStyle; protected: @@ -622,16 +623,19 @@ protected: void drawText(); // modify contents - S32 insertStringNoUndo(S32 pos, const LLWString &wstr, segment_vec_t* segments = NULL); // returns num of chars actually inserted + S32 insertStringNoUndo(S32 pos, const LLWString &wstr, + segment_vec_t* segments = NULL); // returns num of chars actually inserted S32 removeStringNoUndo(S32 pos, S32 length); S32 overwriteCharNoUndo(S32 pos, llwchar wc); - void appendAndHighlightText(const std::string &new_text, S32 highlight_part, const LLStyle::Params& stylep, bool underline_on_hover_only = false); + void appendAndHighlightText(const std::string &new_text, + LLTextParser::EHighlightPosition highlight_part, + const LLStyle::Params& stylep, bool underline_on_hover_only = false); // 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, bool hit_past_end_of_line = true); + 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, bool hit_past_end_of_line = true); segment_set_t::iterator getEditableSegIterContaining(S32 index); segment_set_t::const_iterator getEditableSegIterContaining(S32 index) const; segment_set_t::iterator getSegIterContaining(S32 index); @@ -673,8 +677,9 @@ protected: // avatar names are looked up. void replaceUrl(const std::string &url, const std::string &label, const std::string& icon); - void appendTextImpl(const std::string &new_text, const LLStyle::Params& input_params = LLStyle::Params()); - void appendAndHighlightTextImpl(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params, bool underline_on_hover_only = false); + void appendTextImpl(const std::string &new_text, const LLStyle::Params& input_params = LLStyle::Params()); + void appendAndHighlightTextImpl(const std::string &new_text, LLTextParser::EHighlightPosition highlight_part, + const LLStyle::Params& style_params, bool underline_on_hover_only, std::string tooltip = LLStringUtil::null); S32 normalizeUri(std::string& uri); protected: diff --git a/indra/newview/llexpandabletextbox.cpp b/indra/newview/llexpandabletextbox.cpp index 5c46eb9d80..093f978e74 100644 --- a/indra/newview/llexpandabletextbox.cpp +++ b/indra/newview/llexpandabletextbox.cpp @@ -42,17 +42,18 @@ public: mEditor(editor), mStyle(style), mExpanderLabel(utf8str_to_wstring(more_text)) - {} + { + } /*virtual*/ LLTextSegmentPtr clone(LLTextBase& target) const { - LLStyleSP sp(cloneStyle(target, mStyle)); + LLStyleSP sp((&target == &mEditor) ? mStyle : mStyle->clone()); LLExpanderSegment* copy = new LLExpanderSegment(sp, mStart, mEnd, LLStringUtil::null, target); copy->mExpanderLabel = mExpanderLabel; return copy; } - /*virtual*/ bool getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const + /*virtual*/ bool getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const { // more label always spans width of text box if (num_chars == 0) @@ -67,11 +68,13 @@ public: } return true; } - /*virtual*/ S32 getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const + + /*virtual*/ S32 getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const { return start_offset; } - /*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const + + /*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const { // require full line to ourselves if (line_offset == 0) @@ -85,7 +88,8 @@ public: return 0; } } - /*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect) + + /*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect) { F32 right_x; mStyle->getFont()->render(mExpanderLabel, start, @@ -99,6 +103,7 @@ public: mEditor.getUseEllipses(), mEditor.getUseColor()); return right_x; } + /*virtual*/ bool canEdit() const { return false; } // eat handleMouseDown event so we get the mouseup event /*virtual*/ bool handleMouseDown(S32 x, S32 y, MASK mask) { return true; } @@ -108,6 +113,7 @@ public: LLUI::getInstance()->getWindow()->setCursor(UI_CURSOR_HAND); return true; } + private: LLTextBase& mEditor; LLStyleSP mStyle; |