summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMnikolenko Productengine <mnikolenko@productengine.com>2025-04-10 17:57:16 +0300
committerMnikolenko Productengine <mnikolenko@productengine.com>2025-04-18 19:59:09 +0300
commit90c7684112714fd5ca2c8d73d8ca9bef3fc1e5d6 (patch)
tree6f85fb1bb4085388f3839d9135eee354632336b5
parent3d5f1541dd9980196ba0c8a3c3396c8ed3384d1e (diff)
#3758 add support for highlighted segments
-rw-r--r--indra/llui/llstyle.cpp8
-rw-r--r--indra/llui/llstyle.h13
-rw-r--r--indra/llui/lltextbase.cpp138
-rw-r--r--indra/llui/lltextbase.h8
-rw-r--r--indra/llui/llurlentry.cpp56
-rw-r--r--indra/llui/llurlentry.h31
-rw-r--r--indra/llui/llurlmatch.cpp10
-rw-r--r--indra/llui/llurlmatch.h17
-rw-r--r--indra/llui/llurlregistry.cpp11
-rw-r--r--indra/newview/llappviewer.cpp2
-rw-r--r--indra/newview/llpanelprofile.cpp2
-rw-r--r--indra/newview/llstartup.cpp2
-rw-r--r--indra/newview/skins/default/colors.xml6
13 files changed, 247 insertions, 57 deletions
diff --git a/indra/llui/llstyle.cpp b/indra/llui/llstyle.cpp
index 4714665e8b..7a0e620d61 100644
--- a/indra/llui/llstyle.cpp
+++ b/indra/llui/llstyle.cpp
@@ -38,11 +38,13 @@ LLStyle::Params::Params()
color("color", LLColor4::black),
readonly_color("readonly_color", LLColor4::black),
selected_color("selected_color", LLColor4::black),
+ highlight_bg_color("highlight_bg_color", LLColor4::green),
alpha("alpha", 1.f),
font("font", LLStyle::getDefaultFont()),
image("image"),
link_href("href"),
- is_link("is_link")
+ is_link("is_link"),
+ draw_highlight_bg("draw_highlight_bg", false)
{}
@@ -51,12 +53,14 @@ LLStyle::LLStyle(const LLStyle::Params& p)
mColor(p.color),
mReadOnlyColor(p.readonly_color),
mSelectedColor(p.selected_color),
+ mHighlightBgColor(p.highlight_bg_color),
mFont(p.font()),
mLink(p.link_href),
mIsLink(p.is_link.isProvided() ? p.is_link : !p.link_href().empty()),
mDropShadow(p.drop_shadow),
mImagep(p.image()),
- mAlpha(p.alpha)
+ mAlpha(p.alpha),
+ mDrawHighlightBg(p.draw_highlight_bg)
{}
void LLStyle::setFont(const LLFontGL* font)
diff --git a/indra/llui/llstyle.h b/indra/llui/llstyle.h
index 0c78fe5a9f..2c86eb6db7 100644
--- a/indra/llui/llstyle.h
+++ b/indra/llui/llstyle.h
@@ -43,12 +43,14 @@ public:
Optional<LLFontGL::ShadowType> drop_shadow;
Optional<LLUIColor> color,
readonly_color,
- selected_color;
+ selected_color,
+ highlight_bg_color;
Optional<F32> alpha;
Optional<const LLFontGL*> font;
Optional<LLUIImage*> image;
Optional<std::string> link_href;
Optional<bool> is_link;
+ Optional<bool> draw_highlight_bg;
Params();
};
LLStyle(const Params& p = Params());
@@ -84,6 +86,9 @@ public:
bool isImage() const { return mImagep.notNull(); }
+ bool getDrawHighlightBg() const { return mDrawHighlightBg; }
+ const LLUIColor& getHighlightBgColor() const { return mHighlightBgColor; }
+
bool operator==(const LLStyle &rhs) const
{
return
@@ -91,11 +96,13 @@ public:
&& mColor == rhs.mColor
&& mReadOnlyColor == rhs.mReadOnlyColor
&& mSelectedColor == rhs.mSelectedColor
+ && mHighlightBgColor == rhs.mHighlightBgColor
&& mFont == rhs.mFont
&& mLink == rhs.mLink
&& mImagep == rhs.mImagep
&& mDropShadow == rhs.mDropShadow
- && mAlpha == rhs.mAlpha;
+ && mAlpha == rhs.mAlpha
+ && mDrawHighlightBg == rhs.mDrawHighlightBg;
}
bool operator!=(const LLStyle& rhs) const { return !(*this == rhs); }
@@ -112,11 +119,13 @@ private:
LLUIColor mColor;
LLUIColor mReadOnlyColor;
LLUIColor mSelectedColor;
+ LLUIColor mHighlightBgColor;
const LLFontGL* mFont;
LLPointer<LLUIImage> mImagep;
F32 mAlpha;
bool mVisible;
bool mIsLink;
+ bool mDrawHighlightBg;
};
typedef LLPointer<LLStyle> LLStyleSP;
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 41e7094163..cb682a3625 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -460,6 +460,62 @@ std::vector<LLRect> LLTextBase::getSelectionRects()
return selection_rects;
}
+std::vector<std::pair<LLRect, LLUIColor>> LLTextBase::getHighlightedBgRects()
+{
+ std::vector<std::pair<LLRect, LLUIColor>> highlight_rects;
+
+ LLRect content_display_rect = getVisibleDocumentRect();
+
+ // binary search for line that starts before top of visible buffer
+ line_list_t::const_iterator line_iter =
+ std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mTop, compare_bottom());
+ line_list_t::const_iterator end_iter =
+ std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mBottom, compare_top());
+
+ for (; line_iter != end_iter; ++line_iter)
+ {
+ segment_set_t::iterator segment_iter;
+ S32 segment_offset;
+ getSegmentAndOffset(line_iter->mDocIndexStart, &segment_iter, &segment_offset);
+
+ // Use F32 otherwise a string of multiple segments
+ // will accumulate a large error
+ F32 left_precise = (F32)line_iter->mRect.mLeft;
+ F32 right_precise = (F32)line_iter->mRect.mLeft;
+
+ for (; segment_iter != mSegments.end(); ++segment_iter)
+ {
+ LLTextSegmentPtr segmentp = *segment_iter;
+
+ S32 segment_line_start = segmentp->getStart() + segment_offset;
+ S32 segment_line_end = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd);
+
+ if (segment_line_start > segment_line_end)
+ break;
+
+ F32 segment_width = 0;
+ S32 segment_height = 0;
+
+ S32 num_chars = segment_line_end - segment_line_start;
+ segmentp->getDimensionsF32(segment_offset, num_chars, segment_width, segment_height);
+ right_precise += segment_width;
+
+ if (segmentp->getStyle()->getDrawHighlightBg())
+ {
+ LLRect selection_rect;
+ selection_rect.mLeft = (S32)left_precise;
+ selection_rect.mRight = (S32)right_precise;
+ selection_rect.mBottom = line_iter->mRect.mBottom;
+ selection_rect.mTop = line_iter->mRect.mTop;
+
+ highlight_rects.push_back(std::pair(selection_rect, segmentp->getStyle()->getHighlightBgColor()));
+ }
+ left_precise += segment_width;
+ }
+ }
+ return highlight_rects;
+}
+
// Draws the black box behind the selected text
void LLTextBase::drawSelectionBackground()
{
@@ -529,6 +585,71 @@ void LLTextBase::drawSelectionBackground()
}
}
+void LLTextBase::drawHighlightedBackground()
+{
+ if (!mLineInfoList.empty())
+ {
+ std::vector<std::pair<LLRect, LLUIColor>> highlight_rects = getHighlightedBgRects();
+
+ if (highlight_rects.empty())
+ return;
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ LLRect content_display_rect = getVisibleDocumentRect();
+
+ for (std::vector<std::pair<LLRect, LLUIColor>>::iterator rect_it = highlight_rects.begin();
+ rect_it != highlight_rects.end(); ++rect_it)
+ {
+ LLRect selection_rect = rect_it->first;
+ const LLColor4& color = rect_it->second;
+ if (mScroller)
+ {
+ // If scroller is On content_display_rect has correct rect and safe to use as is
+ // Note: we might need to account for border
+ selection_rect.translate(mVisibleTextRect.mLeft - content_display_rect.mLeft, mVisibleTextRect.mBottom - content_display_rect.mBottom);
+ }
+ else
+ {
+ // If scroller is Off content_display_rect will have rect from document, adjusted to text width, heigh and position
+ // and we have to acount for offset depending on position
+ S32 v_delta = 0;
+ S32 h_delta = 0;
+ switch (mVAlign)
+ {
+ case LLFontGL::TOP:
+ v_delta = mVisibleTextRect.mTop - content_display_rect.mTop - mVPad;
+ break;
+ case LLFontGL::VCENTER:
+ v_delta = (llmax(mVisibleTextRect.getHeight() - content_display_rect.mTop, -content_display_rect.mBottom) + (mVisibleTextRect.mBottom - content_display_rect.mBottom)) / 2;
+ break;
+ case LLFontGL::BOTTOM:
+ v_delta = mVisibleTextRect.mBottom - content_display_rect.mBottom;
+ break;
+ default:
+ break;
+ }
+ switch (mHAlign)
+ {
+ case LLFontGL::LEFT:
+ h_delta = mVisibleTextRect.mLeft - content_display_rect.mLeft + mHPad;
+ break;
+ case LLFontGL::HCENTER:
+ h_delta = (llmax(mVisibleTextRect.getWidth() - content_display_rect.mLeft, -content_display_rect.mRight) + (mVisibleTextRect.mRight - content_display_rect.mRight)) / 2;
+ break;
+ case LLFontGL::RIGHT:
+ h_delta = mVisibleTextRect.mRight - content_display_rect.mRight;
+ break;
+ default:
+ break;
+ }
+ selection_rect.translate(h_delta, v_delta);
+ }
+ gl_rect_2d(selection_rect, color);
+ }
+ }
+}
+
void LLTextBase::drawCursor()
{
F32 alpha = getDrawContext().mAlpha;
@@ -1399,6 +1520,7 @@ void LLTextBase::draw()
drawChild(mDocumentView);
}
+ drawHighlightedBackground();
drawSelectionBackground();
drawText();
drawCursor();
@@ -2245,7 +2367,7 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
}
// output the styled Url
- appendAndHighlightTextImpl(match.getLabel(), part, link_params, match.underlineOnHoverOnly());
+ appendAndHighlightTextImpl(match.getLabel(), part, link_params, match.getUnderline());
bool tooltip_required = !match.getTooltip().empty();
// set the tooltip for the Url label
@@ -2260,7 +2382,7 @@ 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());
+ appendAndHighlightTextImpl(label, part, link_params, match.getUnderline());
// set the tooltip for the query part of url
if (tooltip_required)
@@ -2428,7 +2550,7 @@ 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, S32 highlight_part, const LLStyle::Params& style_params, e_underline underline_link)
{
// Save old state
S32 selection_start = mSelectionStart;
@@ -2458,7 +2580,7 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig
S32 cur_length = getLength();
LLStyleConstSP sp(new LLStyle(highlight_params));
LLTextSegmentPtr segmentp;
- if (underline_on_hover_only || mSkipLinkUnderline)
+ if ((underline_link == e_underline::UNDERLINE_ON_HOVER) || mSkipLinkUnderline)
{
highlight_params.font.style("NORMAL");
LLStyleConstSP normal_sp(new LLStyle(highlight_params));
@@ -2482,7 +2604,7 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig
S32 segment_start = old_length;
S32 segment_end = old_length + static_cast<S32>(wide_text.size());
LLStyleConstSP sp(new LLStyle(style_params));
- if (underline_on_hover_only || mSkipLinkUnderline)
+ if ((underline_link == e_underline::UNDERLINE_ON_HOVER) || mSkipLinkUnderline)
{
LLStyle::Params normal_style_params(style_params);
normal_style_params.font.style("NORMAL");
@@ -2516,7 +2638,7 @@ 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, S32 highlight_part, const LLStyle::Params& style_params, e_underline underline_link)
{
if (new_text.empty())
{
@@ -2531,7 +2653,7 @@ void LLTextBase::appendAndHighlightText(const std::string &new_text, S32 highlig
if (pos != start)
{
std::string str = std::string(new_text,start,pos-start);
- appendAndHighlightTextImpl(str, highlight_part, style_params, underline_on_hover_only);
+ appendAndHighlightTextImpl(str, highlight_part, style_params, underline_link);
}
appendLineBreakSegment(style_params);
start = pos+1;
@@ -2539,7 +2661,7 @@ void LLTextBase::appendAndHighlightText(const std::string &new_text, S32 highlig
}
std::string str = std::string(new_text, start, new_text.length() - start);
- appendAndHighlightTextImpl(str, highlight_part, style_params, underline_on_hover_only);
+ appendAndHighlightTextImpl(str, highlight_part, style_params, underline_link);
}
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 76d4e160af..fa8d22c819 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 "llurlmatch.h"
#include <string>
#include <vector>
@@ -607,6 +608,7 @@ protected:
bool operator()(const LLTextSegmentPtr& a, const LLTextSegmentPtr& b) const;
};
typedef std::multiset<LLTextSegmentPtr, compare_segment_end> segment_set_t;
+ typedef LLUrlMatch::EUnderlineLink e_underline;
// member functions
LLTextBase(const Params &p);
@@ -620,12 +622,13 @@ protected:
virtual void drawSelectionBackground(); // draws the black box behind the selected text
void drawCursor();
void drawText();
+ void drawHighlightedBackground();
// modify contents
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, S32 highlight_part, const LLStyle::Params& stylep, e_underline underline_link = e_underline::UNDERLINE_ALWAYS);
// manage segments
@@ -674,7 +677,7 @@ protected:
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 appendAndHighlightTextImpl(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params, e_underline underline_link = e_underline::UNDERLINE_ALWAYS);
S32 normalizeUri(std::string& uri);
protected:
@@ -685,6 +688,7 @@ protected:
}
std::vector<LLRect> getSelectionRects();
+ std::vector<std::pair<LLRect, LLUIColor>> getHighlightedBgRects();
protected:
// text segmentation and flow
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index 77f132e9d8..ce5ff0ff75 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -29,7 +29,6 @@
#include "llurlentry.h"
#include "lluictrl.h"
#include "lluri.h"
-#include "llurlmatch.h"
#include "llurlregistry.h"
#include "lluriparser.h"
@@ -48,7 +47,7 @@
// Utility functions
std::string localize_slapp_label(const std::string& url, const std::string& full_name);
-
+LLUUID LLUrlEntryBase::sAgentID(LLUUID::null);
LLUrlEntryBase::LLUrlEntryBase()
{
}
@@ -68,7 +67,7 @@ std::string LLUrlEntryBase::getIcon(const std::string &url)
return mIcon;
}
-LLStyle::Params LLUrlEntryBase::getStyle() const
+LLStyle::Params LLUrlEntryBase::getStyle(const std::string &url) const
{
LLStyle::Params style_params;
style_params.color = LLUIColorTable::instance().getColor("HTMLLinkColor");
@@ -667,10 +666,24 @@ std::string LLUrlEntryAgent::getTooltip(const std::string &string) const
return LLTrans::getString("TooltipAgentUrl");
}
-bool LLUrlEntryAgent::underlineOnHoverOnly(const std::string &string) const
+LLUrlMatch::EUnderlineLink LLUrlEntryAgent::getUnderline(const std::string& string) const
{
std::string url = getUrl(string);
- return LLStringUtil::endsWith(url, "/about") || LLStringUtil::endsWith(url, "/inspect");
+ if (LLStringUtil::endsWith(url, "/about") || LLStringUtil::endsWith(url, "/inspect"))
+ {
+ return LLUrlMatch::EUnderlineLink::UNDERLINE_ON_HOVER;
+ }
+ else if (LLStringUtil::endsWith(url, "/mention"))
+ {
+ return LLUrlMatch::EUnderlineLink::UNDERLINE_NEVER;
+ }
+ return LLUrlMatch::EUnderlineLink::UNDERLINE_ALWAYS;
+}
+
+bool LLUrlEntryAgent::getSkipProfileIcon(const std::string& string) const
+{
+ std::string url = getUrl(string);
+ return (LLStringUtil::endsWith(url, "/mention")) ? true : false;
}
std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
@@ -712,11 +725,19 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa
}
}
-LLStyle::Params LLUrlEntryAgent::getStyle() const
+LLStyle::Params LLUrlEntryAgent::getStyle(const std::string &url) const
{
- LLStyle::Params style_params = LLUrlEntryBase::getStyle();
+ LLStyle::Params style_params = LLUrlEntryBase::getStyle(url);
style_params.color = LLUIColorTable::instance().getColor("HTMLLinkColor");
style_params.readonly_color = LLUIColorTable::instance().getColor("HTMLLinkColor");
+ if (LLStringUtil::endsWith(url, "/mention"))
+ {
+ style_params.font.style = "NORMAL";
+ style_params.draw_highlight_bg = true;
+
+ LLUUID agent_id(getIDStringFromUrl(url));
+ style_params.highlight_bg_color = LLUIColorTable::instance().getColor((agent_id == sAgentID) ? "ChatSelfMentionHighlight" : "ChatMentionHighlight");
+ }
return style_params;
}
@@ -751,6 +772,10 @@ std::string localize_slapp_label(const std::string& url, const std::string& full
{
return LLTrans::getString("SLappAgentRemoveFriend") + " " + full_name;
}
+ if (LLStringUtil::endsWith(url, "/mention"))
+ {
+ return "@" + full_name;
+ }
return full_name;
}
@@ -823,7 +848,7 @@ std::string LLUrlEntryAgentName::getLabel(const std::string &url, const LLUrlLab
}
}
-LLStyle::Params LLUrlEntryAgentName::getStyle() const
+LLStyle::Params LLUrlEntryAgentName::getStyle(const std::string &url) const
{
// don't override default colors
return LLStyle::Params().is_link(false);
@@ -959,9 +984,9 @@ std::string LLUrlEntryGroup::getLabel(const std::string &url, const LLUrlLabelCa
}
}
-LLStyle::Params LLUrlEntryGroup::getStyle() const
+LLStyle::Params LLUrlEntryGroup::getStyle(const std::string &url) const
{
- LLStyle::Params style_params = LLUrlEntryBase::getStyle();
+ LLStyle::Params style_params = LLUrlEntryBase::getStyle(url);
style_params.color = LLUIColorTable::instance().getColor("HTMLLinkColor");
style_params.readonly_color = LLUIColorTable::instance().getColor("HTMLLinkColor");
return style_params;
@@ -1037,7 +1062,6 @@ std::string LLUrlEntryChat::getLabel(const std::string &url, const LLUrlLabelCal
}
// LLUrlEntryParcel statics.
-LLUUID LLUrlEntryParcel::sAgentID(LLUUID::null);
LLUUID LLUrlEntryParcel::sSessionID(LLUUID::null);
LLHost LLUrlEntryParcel::sRegionHost;
bool LLUrlEntryParcel::sDisconnected(false);
@@ -1371,17 +1395,17 @@ std::string LLUrlEntrySLLabel::getTooltip(const std::string &string) const
return LLUrlEntryBase::getTooltip(string);
}
-bool LLUrlEntrySLLabel::underlineOnHoverOnly(const std::string &string) const
+LLUrlMatch::EUnderlineLink LLUrlEntrySLLabel::getUnderline(const std::string& string) const
{
std::string url = getUrl(string);
- LLUrlMatch match;
+ LLUrlMatch match;
if (LLUrlRegistry::instance().findUrl(url, match))
{
- return match.underlineOnHoverOnly();
+ return match.getUnderline();
}
// unrecognized URL? should not happen
- return LLUrlEntryBase::underlineOnHoverOnly(string);
+ return LLUrlEntryBase::getUnderline(string);
}
//
@@ -1445,7 +1469,7 @@ std::string LLUrlEntryNoLink::getLabel(const std::string &url, const LLUrlLabelC
return getUrl(url);
}
-LLStyle::Params LLUrlEntryNoLink::getStyle() const
+LLStyle::Params LLUrlEntryNoLink::getStyle(const std::string &url) const
{
// Don't render as URL (i.e. no context menu or hand cursor).
return LLStyle::Params().is_link(false);
diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h
index fffee88496..af5b8f5d83 100644
--- a/indra/llui/llurlentry.h
+++ b/indra/llui/llurlentry.h
@@ -34,6 +34,7 @@
#include "llavatarname.h"
#include "llhost.h" // for resolving parcel name by parcel id
+#include "llurlmatch.h"
#include <boost/signals2.hpp>
#include <boost/regex.hpp>
@@ -85,7 +86,7 @@ public:
virtual std::string getIcon(const std::string &url);
/// Return the style to render the displayed text
- virtual LLStyle::Params getStyle() const;
+ virtual LLStyle::Params getStyle(const std::string &url) const;
/// Given a matched Url, return a tooltip string for the hyperlink
virtual std::string getTooltip(const std::string &string) const { return mTooltip; }
@@ -96,11 +97,12 @@ public:
/// Return the name of a SL location described by this Url, if any
virtual std::string getLocation(const std::string &url) const { return ""; }
- /// Should this link text be underlined only when mouse is hovered over it?
- virtual bool underlineOnHoverOnly(const std::string &string) const { return false; }
+ virtual LLUrlMatch::EUnderlineLink getUnderline(const std::string& string) const { return LLUrlMatch::EUnderlineLink::UNDERLINE_ALWAYS; }
virtual bool isTrusted() const { return false; }
+ virtual bool getSkipProfileIcon(const std::string& string) const { return false; }
+
virtual LLUUID getID(const std::string &string) const { return LLUUID::null; }
bool isLinkDisabled() const;
@@ -109,6 +111,8 @@ public:
virtual bool isSLURLvalid(const std::string &url) const { return true; };
+ static void setAgentID(const LLUUID& id) { sAgentID = id; }
+
protected:
std::string getIDStringFromUrl(const std::string &url) const;
std::string escapeUrl(const std::string &url) const;
@@ -130,6 +134,8 @@ protected:
std::string mMenuName;
std::string mTooltip;
std::multimap<std::string, LLUrlEntryObserver> mObservers;
+
+ static LLUUID sAgentID;
};
///
@@ -224,9 +230,12 @@ public:
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
/*virtual*/ std::string getIcon(const std::string &url);
/*virtual*/ std::string getTooltip(const std::string &string) const;
- /*virtual*/ LLStyle::Params getStyle() const;
+ /*virtual*/ LLStyle::Params getStyle(const std::string &url) const;
/*virtual*/ LLUUID getID(const std::string &string) const;
- /*virtual*/ bool underlineOnHoverOnly(const std::string &string) const;
+
+ LLUrlMatch::EUnderlineLink getUnderline(const std::string& string) const;
+ bool getSkipProfileIcon(const std::string& string) const;
+
protected:
/*virtual*/ void callObservers(const std::string &id, const std::string &label, const std::string& icon);
private:
@@ -257,7 +266,7 @@ public:
mAvatarNameCacheConnections.clear();
}
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
- /*virtual*/ LLStyle::Params getStyle() const;
+ /*virtual*/ LLStyle::Params getStyle(const std::string &url) const;
protected:
// override this to pull out relevant name fields
virtual std::string getName(const LLAvatarName& avatar_name) = 0;
@@ -339,7 +348,7 @@ class LLUrlEntryGroup : public LLUrlEntryBase
public:
LLUrlEntryGroup();
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
- /*virtual*/ LLStyle::Params getStyle() const;
+ /*virtual*/ LLStyle::Params getStyle(const std::string &url) const;
/*virtual*/ LLUUID getID(const std::string &string) const;
private:
void onGroupNameReceived(const LLUUID& id, const std::string& name, bool is_group);
@@ -411,17 +420,15 @@ public:
// Processes parcel label and triggers notifying observers.
static void processParcelInfo(const LLParcelData& parcel_data);
- // Next 4 setters are used to update agent and viewer connection information
+ // Next setters are used to update agent and viewer connection information
// upon events like user login, viewer disconnect and user changing region host.
// These setters are made public to be accessible from newview and should not be
// used in other cases.
- static void setAgentID(const LLUUID& id) { sAgentID = id; }
static void setSessionID(const LLUUID& id) { sSessionID = id; }
static void setRegionHost(const LLHost& host) { sRegionHost = host; }
static void setDisconnected(bool disconnected) { sDisconnected = disconnected; }
private:
- static LLUUID sAgentID;
static LLUUID sSessionID;
static LLHost sRegionHost;
static bool sDisconnected;
@@ -486,7 +493,7 @@ public:
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
/*virtual*/ std::string getUrl(const std::string &string) const;
/*virtual*/ std::string getTooltip(const std::string &string) const;
- /*virtual*/ bool underlineOnHoverOnly(const std::string &string) const;
+ LLUrlMatch::EUnderlineLink getUnderline(const std::string& string) const;
};
///
@@ -510,7 +517,7 @@ public:
LLUrlEntryNoLink();
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
/*virtual*/ std::string getUrl(const std::string &string) const;
- /*virtual*/ LLStyle::Params getStyle() const;
+ /*virtual*/ LLStyle::Params getStyle(const std::string &url) const;
};
///
diff --git a/indra/llui/llurlmatch.cpp b/indra/llui/llurlmatch.cpp
index bfa3b167b1..3e61abe118 100644
--- a/indra/llui/llurlmatch.cpp
+++ b/indra/llui/llurlmatch.cpp
@@ -37,8 +37,9 @@ LLUrlMatch::LLUrlMatch() :
mIcon(""),
mMenuName(""),
mLocation(""),
- mUnderlineOnHoverOnly(false),
- mTrusted(false)
+ mUnderline(UNDERLINE_ALWAYS),
+ mTrusted(false),
+ mSkipProfileIcon(false)
{
}
@@ -46,7 +47,7 @@ void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url, const std
const std::string& query, const std::string &tooltip,
const std::string &icon, const LLStyle::Params& style,
const std::string &menu, const std::string &location,
- const LLUUID& id, bool underline_on_hover_only, bool trusted)
+ const LLUUID& id, EUnderlineLink underline, bool trusted, bool skip_icon)
{
mStart = start;
mEnd = end;
@@ -60,6 +61,7 @@ void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url, const std
mMenuName = menu;
mLocation = location;
mID = id;
- mUnderlineOnHoverOnly = underline_on_hover_only;
+ mUnderline = underline;
mTrusted = trusted;
+ mSkipProfileIcon = skip_icon;
}
diff --git a/indra/llui/llurlmatch.h b/indra/llui/llurlmatch.h
index ba822fbda6..b05b3f2c82 100644
--- a/indra/llui/llurlmatch.h
+++ b/indra/llui/llurlmatch.h
@@ -47,6 +47,13 @@ class LLUrlMatch
public:
LLUrlMatch();
+ enum EUnderlineLink
+ {
+ UNDERLINE_ALWAYS = 0,
+ UNDERLINE_ON_HOVER,
+ UNDERLINE_NEVER
+ };
+
/// return true if this object does not contain a valid Url match yet
bool empty() const { return mUrl.empty(); }
@@ -80,18 +87,19 @@ public:
/// return the SL location that this Url describes, or "" if none.
std::string getLocation() const { return mLocation; }
- /// Should this link text be underlined only when mouse is hovered over it?
- bool underlineOnHoverOnly() const { return mUnderlineOnHoverOnly; }
+ EUnderlineLink getUnderline() const { return mUnderline; }
/// Return true if Url is trusted.
bool isTrusted() const { return mTrusted; }
+ bool getSkipProfileIcon() const { return mSkipProfileIcon; }
+
/// Change the contents of this match object (used by LLUrlRegistry)
void setValues(U32 start, U32 end, const std::string &url, const std::string &label,
const std::string& query, const std::string &tooltip, const std::string &icon,
const LLStyle::Params& style, const std::string &menu,
const std::string &location, const LLUUID& id,
- bool underline_on_hover_only = false, bool trusted = false);
+ EUnderlineLink underline = UNDERLINE_ALWAYS, bool trusted = false, bool skip_icon = false);
const LLUUID& getID() const { return mID; }
private:
@@ -106,8 +114,9 @@ private:
std::string mLocation;
LLUUID mID;
LLStyle::Params mStyle;
- bool mUnderlineOnHoverOnly;
+ EUnderlineLink mUnderline;
bool mTrusted;
+ bool mSkipProfileIcon;
};
#endif
diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp
index cec1ddfc57..6e6e3be9b4 100644
--- a/indra/llui/llurlregistry.cpp
+++ b/indra/llui/llurlregistry.cpp
@@ -233,12 +233,13 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL
match_entry->getQuery(url),
match_entry->getTooltip(url),
match_entry->getIcon(url),
- match_entry->getStyle(),
+ match_entry->getStyle(url),
match_entry->getMenuName(),
match_entry->getLocation(url),
match_entry->getID(url),
- match_entry->underlineOnHoverOnly(url),
- match_entry->isTrusted());
+ match_entry->getUnderline(url),
+ match_entry->isTrusted(),
+ match_entry->getSkipProfileIcon(url));
return true;
}
@@ -274,7 +275,9 @@ bool LLUrlRegistry::findUrl(const LLWString &text, LLUrlMatch &match, const LLUr
match.getMenuName(),
match.getLocation(),
match.getID(),
- match.underlineOnHoverOnly());
+ match.getUnderline(),
+ false,
+ match.getSkipProfileIcon());
return true;
}
return false;
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index edc70030b4..7e7aa521d3 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -475,7 +475,7 @@ static void deferred_ui_audio_callback(const LLUUID& uuid)
bool create_text_segment_icon_from_url_match(LLUrlMatch* match,LLTextBase* base)
{
- if(!match || !base || base->getPlainText())
+ if (!match || match->getSkipProfileIcon() || !base || base->getPlainText())
return false;
LLUUID match_id = match->getID();
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index 08605f7cf4..c81746a48a 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -328,7 +328,7 @@ public:
}
const std::string verb = params[1].asString();
- if (verb == "about")
+ if (verb == "about" || verb == "mention")
{
LLAvatarActions::showProfile(avatar_id);
return true;
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 3973036cc6..4f60f98b49 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -3566,7 +3566,7 @@ bool process_login_success_response()
// Agent id needed for parcel info request in LLUrlEntryParcel
// to resolve parcel name.
- LLUrlEntryParcel::setAgentID(gAgentID);
+ LLUrlEntryBase::setAgentID(gAgentID);
text = response["session_id"].asString();
if(!text.empty()) gAgentSessionID.set(text);
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index f0af4acf20..cb190d3d34 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -1000,4 +1000,10 @@
<color
name="OutfitSnapshotMacMask2"
value="0.1 0.1 0.1 1"/>
+ <color
+ name="ChatMentionHighlight"
+ value="0.82 0.91 0.98 0.15" />
+ <color
+ name="ChatSelfMentionHighlight"
+ value="0.85 0.75 0.40 0.5" />
</colors>