summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Cook <james@lindenlab.com>2010-02-12 16:12:12 -0800
committerJames Cook <james@lindenlab.com>2010-02-12 16:12:12 -0800
commitc16591c046fa76fc5d13387efa3bcaec3422e593 (patch)
tree709d1bd5e4c5587ee9b51a032535a6567565342e
parent3581d0001e2506389f41ce46f5007cc6f40f2d6a (diff)
Per-avatar customizable icons next to name links in text
Changed LLUrlEntryAgent callbacks to handle both link label and icon Eliminated legacy LLNameCache file loading Reviewed with Kelly
-rw-r--r--indra/llcommon/llavatarname.cpp7
-rw-r--r--indra/llcommon/llavatarname.h11
-rw-r--r--indra/llmessage/llavatarnamecache.cpp147
-rw-r--r--indra/llmessage/llcachename.cpp83
-rw-r--r--indra/llmessage/llcachename.h5
-rw-r--r--indra/llui/lltextbase.cpp47
-rw-r--r--indra/llui/lltextbase.h5
-rw-r--r--indra/llui/llurlentry.cpp61
-rw-r--r--indra/llui/llurlentry.h9
-rw-r--r--indra/llui/llurlregistry.cpp4
-rw-r--r--indra/llui/llurlregistry.h4
-rw-r--r--indra/newview/llappviewer.cpp12
-rw-r--r--indra/newview/llstartup.cpp36
-rw-r--r--indra/newview/llstartup.h4
-rw-r--r--indra/newview/skins/default/textures/icons/Person_Check.pngbin0 -> 3824 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Person_Star.pngbin0 -> 3762 bytes
-rw-r--r--indra/newview/skins/default/textures/textures.xml2
17 files changed, 231 insertions, 206 deletions
diff --git a/indra/llcommon/llavatarname.cpp b/indra/llcommon/llavatarname.cpp
index 0563374785..3b1ab4d267 100644
--- a/indra/llcommon/llavatarname.cpp
+++ b/indra/llcommon/llavatarname.cpp
@@ -35,6 +35,13 @@
#include "llavatarname.h"
+LLAvatarName::LLAvatarName()
+: mSLID(),
+ mDisplayName(),
+ mLastUpdate(0),
+ mBadge()
+{ }
+
bool LLAvatarName::operator<(const LLAvatarName& rhs) const
{
if (mSLID == rhs.mSLID)
diff --git a/indra/llcommon/llavatarname.h b/indra/llcommon/llavatarname.h
index 4264a8e655..7205eb4523 100644
--- a/indra/llcommon/llavatarname.h
+++ b/indra/llcommon/llavatarname.h
@@ -39,6 +39,8 @@
class LL_COMMON_API LLAvatarName
{
public:
+ LLAvatarName();
+
bool operator<(const LLAvatarName& rhs) const;
// "bobsmith123" or "james.linden", US-ASCII only
@@ -48,6 +50,15 @@ public:
// Contains data whether or not user has explicitly set
// a display name; may duplicate their SLID.
std::string mDisplayName;
+
+ // Names can change, so need to keep track of when name was
+ // last checked.
+ // Unix time-from-epoch seconds
+ U32 mLastUpdate;
+
+ // Can be a viewer UI image name ("Person_Check") or a server-side
+ // image UUID, or empty string.
+ std::string mBadge;
};
#endif
diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index 16bfa37b0e..610bc58057 100644
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -38,6 +38,11 @@
#include <cctype> // tolower()
+namespace LLAvatarNameCache
+{
+ std::map<LLUUID, LLAvatarName> sCache;
+}
+
static std::string slid_from_full_name(const std::string& full_name)
{
std::string id = full_name;
@@ -52,64 +57,67 @@ static std::string slid_from_full_name(const std::string& full_name)
return id;
}
-static std::map<LLUUID, std::string> sDisplayNames;
-
-// JAMESDEBUG HACK temporary IDEVO code
-static std::string get_display_name(const LLUUID& id)
-{
- if (sDisplayNames.empty())
- {
- LLUUID id;
- const unsigned char miyazaki_hayao_san[]
- = { 0xE5, 0xAE, 0xAE, 0xE5, 0xB4, 0x8E,
- 0xE9, 0xA7, 0xBF,
- 0xE3, 0x81, 0x95, 0xE3, 0x82, 0x93, '\0' };
- id.set("27888d5f-4ddb-4df3-ad36-a1483ce0b3d9"); // miyazaki23
- sDisplayNames[id] = (const char*)miyazaki_hayao_san;
-
- id.set("3e5bf676-3577-c9ee-9fac-10df430015a1"); // Jim Linden
- sDisplayNames[id] = "Jim Jenkins";
-
- const unsigned char jose_sanchez[] =
- { 'J','o','s',0xC3,0xA9,' ','S','a','n','c','h','e','z', '\0' };
- id.set("a2e76fcd-9360-4f6d-a924-938f923df11a"); // James Linden
- sDisplayNames[id] = (const char*)jose_sanchez;
-
- id.set("a23fff6c-80ae-4997-9253-48272fd01d3c"); // bobsmith123
- sDisplayNames[id] = (const char*)jose_sanchez;
-
- id.set("3f7ced39-5e38-4fdd-90f2-423560b1e6e2"); // Hamilton Linden
- sDisplayNames[id] = "Hamilton Hitchings";
-
- id.set("537da1e1-a89f-4f9b-9056-b1f0757ccdd0"); // Rome Linden
- sDisplayNames[id] = "Rome Portlock";
-
- id.set("244195d6-c9b7-4fd6-9229-c3a8b2e60e81"); // M Linden
- sDisplayNames[id] = "Mark Kingdon";
-
- id.set("49856302-98d4-4e32-b5e9-035e5b4e83a4"); // T Linden
- sDisplayNames[id] = "Tom Hale";
-
- id.set("e6ed7825-708f-4c6b-b6a7-f3fe921a9176"); // Callen Linden
- sDisplayNames[id] = "Christina Allen";
-
- id.set("a7f0ac18-205f-41d2-b5b4-f75f096ae511"); // Crimp Linden
- sDisplayNames[id] = "Chris Rimple";
- }
-
- std::map<LLUUID,std::string>::iterator it = sDisplayNames.find(id);
- if (it != sDisplayNames.end())
- {
- return it->second;
- }
- else
- {
- return std::string();
- }
-}
-
void LLAvatarNameCache::initClass()
{
+ // HACK - prepopulate the cache
+ LLAvatarName name;
+ LLUUID id;
+
+ name.mSLID = "miyazaki23";
+ const unsigned char miyazaki_hayao_san[]
+ = { 0xE5, 0xAE, 0xAE, 0xE5, 0xB4, 0x8E,
+ 0xE9, 0xA7, 0xBF,
+ 0xE3, 0x81, 0x95, 0xE3, 0x82, 0x93, '\0' };
+ name.mDisplayName = (const char*)miyazaki_hayao_san;
+ name.mBadge = "Person_Check";
+ sCache[LLUUID("27888d5f-4ddb-4df3-ad36-a1483ce0b3d9")] = name;
+
+ name.mSLID = "jim.linden";
+ name.mDisplayName = "Jim Jenkins";
+ name.mBadge = "Person_Star";
+ sCache[LLUUID("3e5bf676-3577-c9ee-9fac-10df430015a1")] = name;
+
+ name.mSLID = "james.linden";
+ const unsigned char jose_sanchez[] =
+ { 'J','o','s',0xC3,0xA9,' ','S','a','n','c','h','e','z', '\0' };
+ name.mDisplayName = (const char*)jose_sanchez;
+ name.mBadge = "35f217a3-f618-49cf-bbca-c86d486551a9"; // IMG_SHOT
+ sCache[LLUUID("a2e76fcd-9360-4f6d-a924-938f923df11a")] = name;
+
+ name.mSLID = "bobsmith123";
+ name.mDisplayName = (const char*)jose_sanchez;
+ name.mBadge = "";
+ sCache[LLUUID("a23fff6c-80ae-4997-9253-48272fd01d3c")] = name;
+
+ name.mSLID = "hamilton.linden";
+ name.mDisplayName = "Hamilton Hitchings";
+ name.mBadge = "Person_Star";
+ sCache[LLUUID("3f7ced39-5e38-4fdd-90f2-423560b1e6e2")] = name;
+
+ name.mSLID = "rome.linden";
+ name.mDisplayName = "Rome Portlock";
+ name.mBadge = "Person_Star";
+ sCache[LLUUID("537da1e1-a89f-4f9b-9056-b1f0757ccdd0")] = name;
+
+ name.mSLID = "m.linden";
+ name.mDisplayName = "Mark Kingdon";
+ name.mBadge = "Person_Star";
+ sCache[LLUUID("244195d6-c9b7-4fd6-9229-c3a8b2e60e81")] = name;
+
+ name.mSLID = "t.linden";
+ name.mDisplayName = "Tom Hale";
+ name.mBadge = "Person_Star";
+ sCache[LLUUID("49856302-98d4-4e32-b5e9-035e5b4e83a4")] = name;
+
+ name.mSLID = "callen.linden";
+ name.mDisplayName = "Christina Allen";
+ name.mBadge = "Person_Star";
+ sCache[LLUUID("e6ed7825-708f-4c6b-b6a7-f3fe921a9176")] = name;
+
+ name.mSLID = "crimp.linden";
+ name.mDisplayName = "Chris Rimple";
+ name.mBadge = "Person_Star";
+ sCache[LLUUID("a7f0ac18-205f-41d2-b5b4-f75f096ae511")] = name;
}
void LLAvatarNameCache::cleanupClass()
@@ -130,24 +138,23 @@ void LLAvatarNameCache::idle()
bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)
{
+ std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id);
+ if (it != sCache.end())
+ {
+ *av_name = it->second;
+ return true;
+ }
+
std::string full_name;
- bool found = gCacheName->getFullName(agent_id, full_name);
- if (found)
+ if (gCacheName->getFullName(agent_id, full_name))
{
av_name->mSLID = slid_from_full_name(full_name);
-
- std::string display_name = get_display_name(agent_id);
- if (!display_name.empty())
- {
- av_name->mDisplayName = display_name;
- }
- else
- {
- // ...no explicit display name, use legacy name
- av_name->mDisplayName = full_name;
- }
+ av_name->mDisplayName = full_name;
+ av_name->mBadge = "Generic_Person";
+ return true;
}
- return found;
+
+ return false;
}
void LLAvatarNameCache::get(const LLUUID& agent_id, name_cache_callback_t callback)
diff --git a/indra/llmessage/llcachename.cpp b/indra/llmessage/llcachename.cpp
index 4e3c3630ab..b94788bd0c 100644
--- a/indra/llmessage/llcachename.cpp
+++ b/indra/llmessage/llcachename.cpp
@@ -308,89 +308,10 @@ boost::signals2::connection LLCacheName::addObserver(const LLCacheNameCallback&
return impl.mSignal.connect(callback);
}
-void LLCacheName::importFile(LLFILE* fp)
-{
- S32 count = 0;
-
- const S32 BUFFER_SIZE = 1024;
- char buffer[BUFFER_SIZE]; /*Flawfinder: ignore*/
-
- // *NOTE: These buffer sizes are hardcoded into sscanf() below
- char id_string[MAX_STRING]; /*Flawfinder: ignore*/
- char firstname[MAX_STRING]; /*Flawfinder: ignore*/
- char lastname[MAX_STRING]; /*Flawfinder: ignore*/
- U32 create_time;
-
- // This is OK if the first line is actually a name. We just don't load it.
- char* valid = fgets(buffer, BUFFER_SIZE, fp);
- if (!valid) return;
-
- // *NOTE: This buffer size is hardcoded into sscanf() below
- char version_string[BUFFER_SIZE]; /*Flawfinder: ignore*/
- S32 version = 0;
- S32 match = sscanf( /* Flawfinder: ignore */
- buffer,
- "%1023s %d",
- version_string, &version);
- if ( match != 2
- || strcmp(version_string, "version")
- || version != CN_FILE_VERSION)
- {
- llwarns << "Ignoring old cache name file format" << llendl;
- return;
- }
-
- // We'll expire entries more than a week old
- U32 now = (U32)time(NULL);
- const U32 SECS_PER_DAY = 60 * 60 * 24;
- U32 delete_before_time = now - (7 * SECS_PER_DAY);
-
- while(!feof(fp))
- {
- valid = fgets(buffer, BUFFER_SIZE, fp);
- if (!valid) break;
-
- match = sscanf( /* Flawfinder: ignore */
- buffer,
- "%254s %u %254s %254s",
- id_string,
- &create_time,
- firstname,
- lastname);
- if (4 != match) continue;
-
- LLUUID id(id_string);
- if (id.isNull()) continue;
-
- // undo trivial XOR
- S32 i;
- for (i = 0; i < UUID_BYTES; i++)
- {
- id.mData[i] ^= 0x33;
- }
-
- // Don't load entries that are more than a week old
- if (create_time < delete_before_time) continue;
-
- LLCacheNameEntry* entry = new LLCacheNameEntry();
- entry->mIsGroup = false;
- entry->mCreateTime = create_time;
- entry->mFirstName = firstname;
- entry->mLastName = lastname;
- impl.mCache[id] = entry;
- std::string fullname = entry->mFirstName + " " + entry->mLastName;
- impl.mReverseCache[fullname] = id;
-
- count++;
- }
-
- llinfos << "LLCacheName loaded " << count << " names" << llendl;
-}
-
bool LLCacheName::importFile(std::istream& istr)
{
LLSD data;
- if(LLSDSerialize::fromXML(data, istr) < 1)
+ if(LLSDSerialize::fromXMLDocument(data, istr) < 1)
return false;
// We'll expire entries more than a week old
@@ -512,7 +433,7 @@ BOOL LLCacheName::Impl::getName(const LLUUID& id, std::string& first, std::strin
}
// static
-void LLCacheName::LocalizeCacheName(std::string key, std::string value)
+void LLCacheName::localizeCacheName(std::string key, std::string value)
{
if (key!="" && value!= "" )
sCacheName[key]=value;
diff --git a/indra/llmessage/llcachename.h b/indra/llmessage/llcachename.h
index 322ca4aa1a..8d8e172c08 100644
--- a/indra/llmessage/llcachename.h
+++ b/indra/llmessage/llcachename.h
@@ -70,9 +70,6 @@ public:
boost::signals2::connection addObserver(const LLCacheNameCallback& callback);
- // janky old format. Remove after a while. Phoenix. 2008-01-30
- void importFile(LLFILE* fp);
-
// storing cache on disk; for viewer, in name.cache
bool importFile(std::istream& istr);
void exportFile(std::ostream& ostr);
@@ -116,7 +113,7 @@ public:
void dumpStats(); // Dumps the sizes of the cache and associated queues.
static std::string getDefaultName();
- static void LocalizeCacheName(std::string key, std::string value);
+ static void localizeCacheName(std::string key, std::string value);
static std::map<std::string, std::string> sCacheName;
private:
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index ef422dbdc5..075f54ed30 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -1527,6 +1527,20 @@ std::string LLTextBase::getText() const
return getViewModel()->getValue().asString();
}
+// IDEVO - icons can be UI image names or UUID sent from
+// server with avatar display name
+static LLUIImagePtr image_from_icon_name(const std::string& icon_name)
+{
+ if (LLUUID::validate(icon_name))
+ {
+ return LLUI::getUIImageByID( LLUUID(icon_name) );
+ }
+ else
+ {
+ return LLUI::getUIImage(icon_name);
+ }
+}
+
void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params)
{
LLStyle::Params style_params(input_params);
@@ -1539,7 +1553,7 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c
LLUrlMatch match;
std::string text = new_text;
while ( LLUrlRegistry::instance().findUrl(text, match,
- boost::bind(&LLTextBase::replaceUrlLabel, this, _1, _2)) )
+ boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3)) )
{
start = match.getStart();
end = match.getEnd()+1;
@@ -1570,15 +1584,18 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c
// output an optional icon before the Url
if (! match.getIcon().empty())
{
- LLUIImagePtr image = LLUI::getUIImage(match.getIcon());
+ LLUIImagePtr image = image_from_icon_name( match.getIcon() );
if (image)
{
- LLStyle::Params icon;
- icon.image = image;
+ LLStyle::Params icon_params;
+ icon_params.image = image;
+ // must refer to our link so we can update the icon later
+ // after name/group data is looked up
+ icon_params.link_href = match.getUrl();
// Text will be replaced during rendering with the icon,
// but string cannot be empty or the segment won't be
// added (or drawn).
- appendAndHighlightText(" ", prepend_newline, part, icon);
+ appendAndHighlightText(" ", prepend_newline, part, icon_params);
prepend_newline = false;
}
}
@@ -1728,8 +1745,9 @@ void LLTextBase::appendAndHighlightText(const std::string &new_text, bool prepen
}
-void LLTextBase::replaceUrlLabel(const std::string &url,
- const std::string &label)
+void LLTextBase::replaceUrl(const std::string &url,
+ const std::string &label,
+ const std::string &icon)
{
// get the full (wide) text for the editor so we can change it
LLWString text = getWText();
@@ -1759,6 +1777,21 @@ void LLTextBase::replaceUrlLabel(const std::string &url,
modified = true;
}
+ // Icon might be updated when more avatar or group info
+ // becomes available
+ if (style->isImage() && style->getLinkHREF() == url)
+ {
+ LLUIImagePtr image = image_from_icon_name( icon );
+ if (image)
+ {
+ LLStyle::Params icon_params;
+ icon_params.image = image;
+ LLStyleConstSP new_style(new LLStyle(icon_params));
+ seg->setStyle(new_style);
+ modified = true;
+ }
+ }
+
// work out the character offset for the next segment
seg_start = seg->getEnd();
}
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 3dda6f4cc8..dc8bc0dca0 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -309,7 +309,10 @@ protected:
// misc
void updateRects();
void needsScroll() { mScrollNeeded = TRUE; }
- void replaceUrlLabel(const std::string &url, const std::string &label);
+
+ // Replace a URL with a new icon and label, for example, when
+ // avatar names are looked up.
+ void replaceUrl(const std::string &url, const std::string &label, const std::string& icon);
protected:
// text segmentation and flow
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index dae2c44f08..dbfac63a72 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -55,6 +55,12 @@ std::string LLUrlEntryBase::getUrl(const std::string &string) const
return escapeUrl(string);
}
+//virtual
+std::string LLUrlEntryBase::getIcon(const std::string &url) const
+{
+ return mIcon;
+}
+
std::string LLUrlEntryBase::getIDStringFromUrl(const std::string &url) const
{
// return the id from a SLURL in the format /app/{cmd}/{id}/about
@@ -133,7 +139,9 @@ void LLUrlEntryBase::addObserver(const std::string &id,
}
}
-void LLUrlEntryBase::callObservers(const std::string &id, const std::string &label)
+void LLUrlEntryBase::callObservers(const std::string &id,
+ const std::string &label,
+ const std::string &icon)
{
// notify all callbacks waiting on the given uuid
std::multimap<std::string, LLUrlEntryObserver>::iterator it;
@@ -141,7 +149,7 @@ void LLUrlEntryBase::callObservers(const std::string &id, const std::string &lab
{
// call the callback - give it the new label
LLUrlEntryObserver &observer = it->second;
- (*observer.signal)(it->second.url, label);
+ (*observer.signal)(it->second.url, label, icon);
// then remove the signal - we only need to call it once
delete observer.signal;
mObservers.erase(it++);
@@ -312,22 +320,18 @@ LLUrlEntryAgent::LLUrlEntryAgent()
mColor = LLUIColorTable::instance().getColor("AgentLinkColor");
}
-// IDEVO demo code
-std::string LLUrlEntryAgent::buildName(const LLUUID& id)
-{
- // JAMESDEBUG HACK: assume name is there
- LLAvatarName av_name;
- LLAvatarNameCache::get(id, &av_name);
- return av_name.mDisplayName + " (" + av_name.mSLID + ")";
-}
-
void LLUrlEntryAgent::onNameCache(const LLUUID& id,
const std::string& full_name,
bool is_group)
{
- std::string final = buildName(id);
+ // IDEVO demo code
+ LLAvatarName av_name;
+ LLAvatarNameCache::get(id, &av_name);
+ std::string label = av_name.mDisplayName + " (" + av_name.mSLID + ")";
+ // use custom icon if available
+ std::string icon = (!av_name.mBadge.empty() ? av_name.mBadge : mIcon);
// received the agent name from the server - tell our observers
- callObservers(id.asString(), final);
+ callObservers(id.asString(), label, icon);
}
std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
@@ -353,7 +357,10 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa
}
else if (gCacheName->getFullName(agent_id, full_name))
{
- return buildName(agent_id);
+ LLAvatarName av_name;
+ LLAvatarNameCache::get(agent_id, &av_name);
+ std::string label = av_name.mDisplayName + " (" + av_name.mSLID + ")";
+ return label;
}
else
{
@@ -366,6 +373,30 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa
}
+std::string LLUrlEntryAgent::getIcon(const std::string &url) const
+{
+ std::string agent_id_string = getIDStringFromUrl(url);
+ if (agent_id_string.empty())
+ {
+ return mIcon;
+ }
+
+ LLUUID agent_id(agent_id_string);
+ if (agent_id.isNull())
+ {
+ return mIcon;
+ }
+
+ LLAvatarName av_name;
+ LLAvatarNameCache::get(agent_id, &av_name);
+ if (av_name.mBadge.empty())
+ {
+ return mIcon;
+ }
+
+ return av_name.mBadge;
+}
+
//
// LLUrlEntryGroup Describes a Second Life group Url, e.g.,
// secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about
@@ -386,7 +417,7 @@ void LLUrlEntryGroup::onGroupNameReceived(const LLUUID& id,
bool is_group)
{
// received the group name from the server - tell our observers
- callObservers(id.asString(), name);
+ callObservers(id.asString(), name, mIcon);
}
std::string LLUrlEntryGroup::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h
index 2bc21eb989..1f0caeacf5 100644
--- a/indra/llui/llurlentry.h
+++ b/indra/llui/llurlentry.h
@@ -42,7 +42,8 @@
#include <map>
typedef boost::signals2::signal<void (const std::string& url,
- const std::string& label)> LLUrlLabelSignal;
+ const std::string& label,
+ const std::string& icon)> LLUrlLabelSignal;
typedef LLUrlLabelSignal::slot_type LLUrlLabelCallback;
///
@@ -77,7 +78,7 @@ public:
virtual std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) { return url; }
/// Return an icon that can be displayed next to Urls of this type
- std::string getIcon() const { return mIcon; }
+ virtual std::string getIcon(const std::string &url) const;
/// Return the color to render the displayed text
LLUIColor getColor() const { return mColor; }
@@ -101,7 +102,7 @@ protected:
std::string getLabelFromWikiLink(const std::string &url) const;
std::string getUrlFromWikiLink(const std::string &string) const;
void addObserver(const std::string &id, const std::string &url, const LLUrlLabelCallback &cb);
- void callObservers(const std::string &id, const std::string &label);
+ void callObservers(const std::string &id, const std::string &label, const std::string& icon);
typedef struct {
std::string url;
@@ -168,10 +169,10 @@ class LLUrlEntryAgent : public LLUrlEntryBase
public:
LLUrlEntryAgent();
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
+ /*virtual*/ std::string getIcon(const std::string &url) const;
private:
void onNameCache(const LLUUID& id, const std::string& full_name, bool is_group);
- std::string buildName(const LLUUID& id);
};
///
diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp
index 5db1f46b8d..1ee87a01de 100644
--- a/indra/llui/llurlregistry.cpp
+++ b/indra/llui/llurlregistry.cpp
@@ -37,7 +37,7 @@
#include <boost/regex.hpp>
// default dummy callback that ignores any label updates from the server
-void LLUrlRegistryNullCallback(const std::string &url, const std::string &label)
+void LLUrlRegistryNullCallback(const std::string &url, const std::string &label, const std::string& icon)
{
}
@@ -180,7 +180,7 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL
match_entry->getUrl(url),
match_entry->getLabel(url, cb),
match_entry->getTooltip(),
- match_entry->getIcon(),
+ match_entry->getIcon(url),
match_entry->getColor(),
match_entry->getMenuName(),
match_entry->getLocation(url),
diff --git a/indra/llui/llurlregistry.h b/indra/llui/llurlregistry.h
index 6d47c2c2a2..dffbd9d4bf 100644
--- a/indra/llui/llurlregistry.h
+++ b/indra/llui/llurlregistry.h
@@ -43,7 +43,9 @@
#include <vector>
/// This default callback for findUrl() simply ignores any label updates
-void LLUrlRegistryNullCallback(const std::string &url, const std::string &label);
+void LLUrlRegistryNullCallback(const std::string &url,
+ const std::string &label,
+ const std::string &icon);
///
/// LLUrlRegistry is a singleton that contains a set of Url types that
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 00a9e4d745..ba2e13da9d 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1298,8 +1298,7 @@ bool LLAppViewer::cleanup()
LLPolyMesh::freeAllMeshes();
- delete gCacheName;
- gCacheName = NULL;
+ LLStartUp::cleanupNameCache();
// Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be deleted.
@@ -3337,15 +3336,6 @@ void LLAppViewer::loadNameCache()
{
if(gCacheName->importFile(cache_file)) return;
}
-
- // Try to load from the legacy format. This should go away after a
- // while. Phoenix 2008-01-30
- LLFILE* name_cache_fp = LLFile::fopen(name_cache, "r"); // Flawfinder: ignore
- if (name_cache_fp)
- {
- gCacheName->importFile(name_cache_fp);
- fclose(name_cache_fp);
- }
}
void LLAppViewer::saveNameCache()
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index cfad29df89..97e47fb05e 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -52,6 +52,7 @@
#endif
#include "llares.h"
+#include "llavatarnamecache.h"
#include "lllandmark.h"
#include "llcachename.h"
#include "lldir.h"
@@ -1280,16 +1281,7 @@ bool idle_startup()
gXferManager->registerCallbacks(gMessageSystem);
- if ( gCacheName == NULL )
- {
- gCacheName = new LLCacheName(gMessageSystem);
- gCacheName->addObserver(&callback_cache_name);
- gCacheName->LocalizeCacheName("waiting", LLTrans::getString("AvatarNameWaiting"));
- gCacheName->LocalizeCacheName("nobody", LLTrans::getString("AvatarNameNobody"));
- gCacheName->LocalizeCacheName("none", LLTrans::getString("GroupNameNone"));
- // Load stored cache if possible
- LLAppViewer::instance()->loadNameCache();
- }
+ LLStartUp::initNameCache();
//gCacheName is required for nearby chat history loading
//so I just moved nearby history loading a few states further
@@ -2781,6 +2773,30 @@ void LLStartUp::fontInit()
LLFontGL::loadDefaultFonts();
}
+void LLStartUp::initNameCache()
+{
+ // Can be called multiple times
+ if ( gCacheName ) return;
+
+ gCacheName = new LLCacheName(gMessageSystem);
+ gCacheName->addObserver(&callback_cache_name);
+ gCacheName->localizeCacheName("waiting", LLTrans::getString("AvatarNameWaiting"));
+ gCacheName->localizeCacheName("nobody", LLTrans::getString("AvatarNameNobody"));
+ gCacheName->localizeCacheName("none", LLTrans::getString("GroupNameNone"));
+ // Load stored cache if possible
+ LLAppViewer::instance()->loadNameCache();
+
+ LLAvatarNameCache::initClass();
+}
+
+void LLStartUp::cleanupNameCache()
+{
+ LLAvatarNameCache::cleanupClass();
+
+ delete gCacheName;
+ gCacheName = NULL;
+}
+
bool LLStartUp::dispatchURL()
{
// ok, if we've gotten this far and have a startup URL
diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h
index 92fe9521d3..14a7c71544 100644
--- a/indra/newview/llstartup.h
+++ b/indra/newview/llstartup.h
@@ -95,6 +95,10 @@ public:
// Load default fonts not already loaded at start screen
static void fontInit();
+ static void initNameCache();
+
+ static void cleanupNameCache();
+
// outfit_folder_name can be a folder anywhere in your inventory,
// but the name must be a case-sensitive exact match.
// gender_name is either "male" or "female"
diff --git a/indra/newview/skins/default/textures/icons/Person_Check.png b/indra/newview/skins/default/textures/icons/Person_Check.png
new file mode 100644
index 0000000000..f8638540d4
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Person_Check.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Person_Star.png b/indra/newview/skins/default/textures/icons/Person_Star.png
new file mode 100644
index 0000000000..ad10580ac4
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Person_Star.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 18d1779702..753f62dc8d 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -410,6 +410,8 @@ with the same filename but different name
<texture name="Pause_Off" file_name="icons/Pause_Off.png" preload="false" />
<texture name="Pause_Over" file_name="icons/Pause_Over.png" preload="false" />
<texture name="Pause_Press" file_name="icons/Pause_Press.png" preload="false" />
+ <texture name="Person_Check" file_name="icons/Person_Check.png" preload="false" />
+ <texture name="Person_Star" file_name="icons/Person_Star.png" preload="false" />
<texture name="Play_Off" file_name="icons/Play_Off.png" preload="false" />
<texture name="Play_Over" file_name="icons/Play_Over.png" preload="false" />
<texture name="Play_Press" file_name="icons/Play_Press.png" preload="false" />