diff options
| author | Richard Nelson <none@none> | 2010-05-24 16:37:52 -0700 | 
|---|---|---|
| committer | Richard Nelson <none@none> | 2010-05-24 16:37:52 -0700 | 
| commit | 2920d4c46f99c8c5bc8942a08a87fa204c57464b (patch) | |
| tree | 515837435a28924b028815fc79f7f4f2ec18871e /indra/newview | |
| parent | a146a0f27b3ea2fadaa9e7286645a0944996309d (diff) | |
| parent | d674d11f895b8f3d578cded931cdc1c430379c95 (diff) | |
merge
Diffstat (limited to 'indra/newview')
144 files changed, 4049 insertions, 1901 deletions
| diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 7094d68292..37b5eb24b7 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -240,6 +240,7 @@ set(viewer_SOURCE_FILES      llhudeffecttrail.cpp      llhudicon.cpp      llhudmanager.cpp +    llhudnametag.cpp      llhudobject.cpp      llhudrender.cpp      llhudtext.cpp @@ -470,6 +471,7 @@ set(viewer_SOURCE_FILES      llviewercontrol.cpp      llviewercontrollistener.cpp      llviewerdisplay.cpp +    llviewerdisplayname.cpp      llviewerfloaterreg.cpp      llviewerfoldertype.cpp      llviewergenericmessage.cpp @@ -758,6 +760,7 @@ set(viewer_HEADER_FILES      llhudeffecttrail.h      llhudicon.h      llhudmanager.h +    llhudnametag.h      llhudobject.h      llhudrender.h      llhudtext.h @@ -987,6 +990,7 @@ set(viewer_HEADER_FILES      llviewercontrol.h      llviewercontrollistener.h      llviewerdisplay.h +    llviewerdisplayname.h      llviewerfloaterreg.h      llviewerfoldertype.h      llviewergenericmessage.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 1d27d00451..f79693586a 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -24,7 +24,7 @@        <key>Value</key>        <integer>0</integer>      </map> -    <key>AgentPause</key> +     <key>AgentPause</key>      <map>        <key>Comment</key>        <string>Ask the simulator to stop updating the agent while enabled</string> @@ -7348,7 +7348,7 @@        <key>Value</key>        <integer>0</integer>      </map> -    <key>RenderShowGroupTitleAll</key> +    <key>NameTagShowGroupTitles</key>      <map>        <key>Comment</key>        <string>Show group titles in name labels</string> @@ -7357,6 +7357,39 @@        <key>Type</key>        <string>Boolean</string>        <key>Value</key> +      <integer>0</integer> +    </map> +    <key>NameTagShowDisplayNames</key> +    <map> +      <key>Comment</key> +      <string>Show display names in name labels</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>1</integer> +    </map> +    <key>NameTagShowFriends</key> +    <map> +      <key>Comment</key> +      <string>Highlight the name tags of your friends</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map> +    <key>NameTagShowUsernames</key> +    <map> +      <key>Comment</key> +      <string>Show usernames in avatar name tags</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key>        <integer>1</integer>      </map>      <key>RenderInitError</key> @@ -10274,6 +10307,17 @@        <key>Value</key>        <integer>0</integer>      </map> +  <key>UseDisplayNames</key> +  <map> +    <key>Comment</key> +    <string>Use new, changeable, unicode names</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>1</integer> +  </map>      <key>UseEnergy</key>      <map>        <key>Comment</key> diff --git a/indra/newview/llagentui.cpp b/indra/newview/llagentui.cpp index 15d9f36b74..b5f9810e24 100644 --- a/indra/newview/llagentui.cpp +++ b/indra/newview/llagentui.cpp @@ -46,29 +46,6 @@  #include "llslurl.h"  //static -void LLAgentUI::buildName(std::string& name) -{ -	name.clear(); -	if (isAgentAvatarValid()) -	{ -		LLNameValue *first_nv = gAgentAvatarp->getNVPair("FirstName"); -		LLNameValue *last_nv = gAgentAvatarp->getNVPair("LastName"); -		if (first_nv && last_nv) -		{ -			name = first_nv->printData() + " " + last_nv->printData(); -		} -		else -		{ -			llwarns << "Agent is missing FirstName and/or LastName nv pair." << llendl; -		} -	} -	else -	{ -		name = gSavedSettings.getString("FirstName") + " " + gSavedSettings.getString("LastName"); -	} -} - -//static  void LLAgentUI::buildFullname(std::string& name)  {  	if (isAgentAvatarValid()) diff --git a/indra/newview/llagentui.h b/indra/newview/llagentui.h index 577b752fbe..2c3c65fb8a 100644 --- a/indra/newview/llagentui.h +++ b/indra/newview/llagentui.h @@ -47,7 +47,6 @@ public:  		LOCATION_FORMAT_FULL,			// Parcel, Region (x, y, z) - Maturity  	}; -	static void buildName(std::string& name);  	static void buildFullname(std::string &name);  	static void buildSLURL(LLSLURL& slurl, const bool escaped = true); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index f7f7cb599e..0958612749 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -87,6 +87,7 @@  #include "llsecondlifeurls.h"  // Linden library includes +#include "llavatarnamecache.h"  #include "llimagej2c.h"  #include "llmemory.h"  #include "llprimitive.h" @@ -159,7 +160,6 @@  // Included so that constants/settings might be initialized  // in save_settings_to_globals()  #include "llbutton.h" -#include "llcombobox.h"  #include "llstatusbar.h"  #include "llsurface.h"  #include "llvosky.h" @@ -404,9 +404,6 @@ static void settings_to_globals()  	MENU_BAR_HEIGHT		= gSavedSettings.getS32("MenuBarHeight");  	MENU_BAR_WIDTH		= gSavedSettings.getS32("MenuBarWidth"); -	LLCOMBOBOX_HEIGHT	= BTN_HEIGHT - 2; -	LLCOMBOBOX_WIDTH	= 128; -  	LLSurface::setTextureSize(gSavedSettings.getU32("RegionTextureSize"));  	LLImageGL::sGlobalUseAnisotropic	= gSavedSettings.getBOOL("RenderAnisotropic"); @@ -1291,8 +1288,7 @@ bool LLAppViewer::cleanup()  	LLPolyMesh::freeAllMeshes(); -	delete gCacheName; -	gCacheName = NULL; +	LLStartUp::cleanupNameCache();  	// Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be deleted. @@ -3332,6 +3328,15 @@ void LLAppViewer::saveFinalSnapshot()  void LLAppViewer::loadNameCache()  { +	// display names cache +	std::string filename = +		gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "avatar_name_cache.xml"); +	llifstream name_cache_stream(filename); +	if(name_cache_stream.is_open()) +	{ +		LLAvatarNameCache::importFile(name_cache_stream); +	} +  	if (!gCacheName) return;  	std::string name_cache; @@ -3341,19 +3346,19 @@ 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()  { +	// display names cache +	std::string filename = +		gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "avatar_name_cache.xml"); +	llofstream name_cache_stream(filename); +	if(name_cache_stream.is_open()) +	{ +		LLAvatarNameCache::exportFile(name_cache_stream); +	} +  	if (!gCacheName) return;  	std::string name_cache; @@ -3549,9 +3554,10 @@ void LLAppViewer::idle()  	    // NOTE: Starting at this point, we may still have pointers to "dead" objects  	    // floating throughout the various object lists.  	    // +		idleNameCache();  		idleNetwork(); -	    	         +  		// Check for away from keyboard, kick idle agents.  		idle_afk_check(); @@ -3886,6 +3892,60 @@ void LLAppViewer::sendLogoutRequest()  	}  } +void LLAppViewer::idleNameCache() +{ +	// Neither old nor new name cache can function before agent has a region +	LLViewerRegion* region = gAgent.getRegion(); +	if (!region) return; + +	// deal with any queued name requests and replies. +	gCacheName->processPending(); + +	// Can't run the new cache until we have the list of capabilities +	// for the agent region, and can therefore decide whether to use +	// display names or fall back to the old name system. +	if (!region->capabilitiesReceived()) return; + +	// Agent may have moved to a different region, so need to update cap URL +	// for name lookups.  Can't do this in the cap grant code, as caps are +	// granted to neighbor regions before the main agent gets there.  Can't +	// do it in the move-into-region code because cap not guaranteed to be +	// granted yet, for example on teleport. +	bool had_capability = LLAvatarNameCache::hasNameLookupURL(); +	std::string name_lookup_url; +	name_lookup_url.reserve(128); // avoid a memory allocation below +	name_lookup_url = region->getCapability("GetDisplayNames"); +	bool have_capability = !name_lookup_url.empty(); +	if (have_capability) +	{ +		// we have support for display names, use it +	    U32 url_size = name_lookup_url.size(); +	    // capabilities require URLs with slashes before query params: +	    // https://<host>:<port>/cap/<uuid>/?ids=<blah> +	    // but the caps are granted like: +	    // https://<host>:<port>/cap/<uuid> +	    if (url_size > 0 && name_lookup_url[url_size-1] != '/') +	    { +		    name_lookup_url += '/'; +	    } +		LLAvatarNameCache::setNameLookupURL(name_lookup_url); +	} +	else +	{ +		// Display names not available on this region +		LLAvatarNameCache::setNameLookupURL( std::string() ); +	} + +	// Error recovery - did we change state? +	if (had_capability != have_capability) +	{ +		// name tags are persistant on screen, so make sure they refresh +		LLVOAvatar::invalidateNameTags(); +	} + +	LLAvatarNameCache::idle(); +} +  //  // Handle messages, and all message related stuff  // @@ -3911,8 +3971,6 @@ void LLAppViewer::idleNetwork()  	{  		LLFastTimer t(FTM_IDLE_NETWORK); // decode -		// deal with any queued name requests and replies. -		gCacheName->processPending();  		LLTimer check_message_timer;  		//  Read all available packets from network   		const S64 frame_count = gFrameCount;  // U32->S64 diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 5acd6e11c4..6e6a382e46 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -211,6 +211,8 @@ private:      void idle();       void idleShutdown(); +	// update avatar SLID and display name caches +	void idleNameCache();      void idleNetwork();      void sendLogoutRequest(); diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 875ed72a12..6cef0b5119 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -37,11 +37,11 @@  #include "boost/lambda/lambda.hpp"	// for lambda::constant +#include "llavatarnamecache.h"	// IDEVO  #include "llsd.h"  #include "lldarray.h"  #include "llnotifications.h"  #include "llnotificationsutil.h" -  #include "roles_constants.h"    // for GP_MEMBER_INVITE  #include "llagent.h" @@ -69,6 +69,7 @@  #include "llimfloater.h"  #include "lltrans.h"  #include "llcallingcard.h" +#include "llslurl.h"			// IDEVO  // static  void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::string& name) @@ -80,7 +81,7 @@ void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::strin  	}  	LLSD args; -	args["NAME"] = name; +	args["NAME"] = LLSLURL("agent", id, "inspect").getSLURLString();  	LLSD payload;  	payload["id"] = id;  	payload["name"] = name; @@ -135,11 +136,10 @@ void LLAvatarActions::removeFriendsDialog(const uuid_vec_t& ids)  	if(ids.size() == 1)  	{  		LLUUID agent_id = ids[0]; -		std::string first, last; -		if(gCacheName->getName(agent_id, first, last)) +		std::string full_name; +		if(gCacheName->getFullName(agent_id, full_name))  		{ -			args["FIRST_NAME"] = first; -			args["LAST_NAME"] = last;	 +			args["NAME"] = full_name;  		}  		msgType = "RemoveFromFriends"; @@ -189,20 +189,11 @@ void LLAvatarActions::offerTeleport(const uuid_vec_t& ids)  	handle_lure(ids);  } -// static -void LLAvatarActions::startIM(const LLUUID& id) +static void on_avatar_name_cache_start_im(const LLUUID& agent_id, +										  const LLAvatarName& av_name)  { -	if (id.isNull()) -		return; - -	std::string name; -	if (!gCacheName->getFullName(id, name)) -	{ -		gCacheName->get(id, FALSE, boost::bind(&LLAvatarActions::startIM, id)); -		return; -	} - -	LLUUID session_id = gIMMgr->addSession(name, IM_NOTHING_SPECIAL, id); +	std::string name = av_name.getCompleteName(); +	LLUUID session_id = gIMMgr->addSession(name, IM_NOTHING_SPECIAL, agent_id);  	if (session_id != LLUUID::null)  	{  		LLIMFloater::show(session_id); @@ -211,6 +202,16 @@ void LLAvatarActions::startIM(const LLUUID& id)  }  // static +void LLAvatarActions::startIM(const LLUUID& id) +{ +	if (id.isNull()) +		return; + +	LLAvatarNameCache::get(id, +		boost::bind(&on_avatar_name_cache_start_im, _1, _2)); +} + +// static  void LLAvatarActions::endIM(const LLUUID& id)  {  	if (id.isNull()) @@ -223,6 +224,18 @@ void LLAvatarActions::endIM(const LLUUID& id)  	}  } +static void on_avatar_name_cache_start_call(const LLUUID& agent_id, +											const LLAvatarName& av_name) +{ +	std::string name = av_name.getCompleteName(); +	LLUUID session_id = gIMMgr->addSession(name, IM_NOTHING_SPECIAL, agent_id, true); +	if (session_id != LLUUID::null) +	{ +		gIMMgr->startCall(session_id); +	} +	make_ui_sound("UISndStartIM"); +} +  // static  void LLAvatarActions::startCall(const LLUUID& id)  { @@ -230,15 +243,8 @@ void LLAvatarActions::startCall(const LLUUID& id)  	{  		return;  	} - -	std::string name; -	gCacheName->getFullName(id, name); -	LLUUID session_id = gIMMgr->addSession(name, IM_NOTHING_SPECIAL, id, true); -	if (session_id != LLUUID::null) -	{ -		gIMMgr->startCall(session_id); -	} -	make_ui_sound("UISndStartIM"); +	LLAvatarNameCache::get(id, +		boost::bind(&on_avatar_name_cache_start_call, _1, _2));  }  // static @@ -768,9 +774,9 @@ bool LLAvatarActions::isBlocked(const LLUUID& id)  // static  bool LLAvatarActions::canBlock(const LLUUID& id)  { -	std::string firstname, lastname; -	gCacheName->getName(id, firstname, lastname); -	bool is_linden = !LLStringUtil::compareStrings(lastname, "Linden"); +	std::string full_name; +	gCacheName->getFullName(id, full_name); +	bool is_linden = (full_name.find("Linden") != std::string::npos);  	bool is_self = id == gAgentID;  	return !is_self && !is_linden;  } diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp index 87b8d807c4..11cc456695 100644 --- a/indra/newview/llavatariconctrl.cpp +++ b/indra/newview/llavatariconctrl.cpp @@ -244,7 +244,8 @@ void LLAvatarIconCtrl::setValue(const LLSD& value)  		LLIconCtrl::setValue(value);  	} -	gCacheName->get(mAvatarId, FALSE, boost::bind(&LLAvatarIconCtrl::nameUpdatedCallback, this, _1, _2, _3, _4)); +	gCacheName->get(mAvatarId, false, +		boost::bind(&LLAvatarIconCtrl::nameUpdatedCallback, this, _1, _2, _3));  }  bool LLAvatarIconCtrl::updateFromCache() @@ -289,22 +290,20 @@ void LLAvatarIconCtrl::processProperties(void* data, EAvatarProcessorType type)  void LLAvatarIconCtrl::nameUpdatedCallback(  	const LLUUID& id, -	const std::string& first, -	const std::string& last, -	BOOL is_group) +	const std::string& name, +	bool is_group)  {  	if (id == mAvatarId)  	{ -		mFirstName = first; -		mLastName = last; +		mFullName = name;  		if (mDrawTooltip)  		{ -			setToolTip(mFirstName + " " + mLastName); +			setToolTip(name);  		}  		else  		{ -			setToolTip(std::string("")); +			setToolTip(std::string());  		}  	}  } diff --git a/indra/newview/llavatariconctrl.h b/indra/newview/llavatariconctrl.h index 38616b7852..a5452ee1d3 100644 --- a/indra/newview/llavatariconctrl.h +++ b/indra/newview/llavatariconctrl.h @@ -92,20 +92,17 @@ public:  	void nameUpdatedCallback(  		const LLUUID& id, -		const std::string& first, -		const std::string& last, -		BOOL is_group); +		const std::string& name, +		bool is_group);  	const LLUUID&		getAvatarId() const	{ return mAvatarId; } -	const std::string&	getFirstName() const { return mFirstName; } -	const std::string&	getLastName() const { return mLastName; } +	const std::string&	getFullName() const { return mFullName; }  	void setDrawTooltip(bool value) { mDrawTooltip = value;}  protected:  	LLUUID				mAvatarId; -	std::string			mFirstName; -	std::string			mLastName; +	std::string			mFullName;  	bool				mDrawTooltip;  	std::string			mDefaultIconName; diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index 24290ac089..0c4a51d7fe 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -44,6 +44,7 @@  // newview  #include "llagentdata.h" // for comparator  #include "llavatariconctrl.h" +#include "llavatarnamecache.h"  #include "llcallingcard.h" // for LLAvatarTracker  #include "llcachename.h"  #include "llrecentpeople.h" @@ -241,12 +242,15 @@ void LLAvatarList::refresh()  	// Handle added items.  	unsigned nadded = 0; +	const std::string waiting_str = LLTrans::getString("AvatarNameWaiting"); +  	for (uuid_vec_t::const_iterator it=added.begin(); it != added.end(); it++)  	{ -		std::string name;  		const LLUUID& buddy_id = *it; -		have_names &= (bool)gCacheName->getFullName(buddy_id, name); -		if (!have_filter || findInsensitive(name, mNameFilter)) +		LLAvatarName av_name; +		have_names &= LLAvatarNameCache::get(buddy_id, &av_name); + +		if (!have_filter || findInsensitive(av_name.mDisplayName, mNameFilter))  		{  			if (nadded >= ADD_LIMIT)  			{ @@ -255,7 +259,9 @@ void LLAvatarList::refresh()  			}  			else  			{ -				addNewItem(buddy_id, name, LLAvatarTracker::instance().isBuddyOnline(buddy_id)); +				addNewItem(buddy_id,  +					       av_name.mDisplayName.empty() ? waiting_str : av_name.mDisplayName,  +						   LLAvatarTracker::instance().isBuddyOnline(buddy_id));  				modified = true;  				nadded++;  			} diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp index 5a8ad73c83..4e018c5784 100644 --- a/indra/newview/llavatarlistitem.cpp +++ b/indra/newview/llavatarlistitem.cpp @@ -41,6 +41,7 @@  #include "lltextutil.h"  #include "llagent.h" +#include "llavatarnamecache.h"  #include "llavatariconctrl.h"  #include "lloutputmonitorctrl.h" @@ -170,6 +171,7 @@ void LLAvatarListItem::setOnline(bool online)  void LLAvatarListItem::setName(const std::string& name)  {  	setNameInternal(name, mHighlihtSubstring); +	mAvatarName->setToolTip(name);  }  void LLAvatarListItem::setHighlight(const std::string& highlight) @@ -230,7 +232,8 @@ void LLAvatarListItem::setAvatarId(const LLUUID& id, const LLUUID& session_id, b  		mAvatarIcon->setValue(id);  		// Set avatar name. -		gCacheName->get(id, FALSE, boost::bind(&LLAvatarListItem::onNameCache, this, _2, _3)); +		LLAvatarNameCache::get(id, +			boost::bind(&LLAvatarListItem::onAvatarNameCache, this, _2));  	}  } @@ -333,13 +336,12 @@ const std::string LLAvatarListItem::getAvatarName() const  void LLAvatarListItem::setNameInternal(const std::string& name, const std::string& highlight)  {  	LLTextUtil::textboxSetHighlightedVal(mAvatarName, mAvatarNameStyle, name, highlight); -	mAvatarName->setToolTip(name);  } -void LLAvatarListItem::onNameCache(const std::string& first_name, const std::string& last_name) +void LLAvatarListItem::onAvatarNameCache(const LLAvatarName& av_name)  { -	std::string name = first_name + " " + last_name; -	setName(name); +	setName(av_name.mDisplayName); +	mAvatarName->setToolTip(av_name.mUsername);  	//requesting the list to resort  	notifyParent(LLSD().with("sort", LLSD())); diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h index c6fac7a9f1..a385cffdc2 100644 --- a/indra/newview/llavatarlistitem.h +++ b/indra/newview/llavatarlistitem.h @@ -42,6 +42,7 @@  #include "llcallingcard.h" // for LLFriendObserver  class LLAvatarIconCtrl; +class LLAvatarName;  class LLAvatarListItem : public LLPanel, public LLFriendObserver  { @@ -152,7 +153,7 @@ private:  	} EAvatarListItemChildIndex;  	void setNameInternal(const std::string& name, const std::string& highlight); -	void onNameCache(const std::string& first_name, const std::string& last_name); +	void onAvatarNameCache(const LLAvatarName& av_name);  	std::string formatSeconds(U32 secs); diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp index dd99c6564c..44fb4e9e72 100644 --- a/indra/newview/llcallfloater.cpp +++ b/indra/newview/llcallfloater.cpp @@ -33,13 +33,14 @@  #include "llviewerprecompiledheaders.h" +#include "llcallfloater.h" +  #include "llnotificationsutil.h"  #include "lltrans.h" -#include "llcallfloater.h" -  #include "llagent.h"  #include "llagentdata.h" // for gAgentID +#include "llavatarnamecache.h"  #include "llavatariconctrl.h"  #include "llavatarlist.h"  #include "llbottomtray.h" @@ -422,9 +423,10 @@ void LLCallFloater::initAgentData()  	{  		mAgentPanel->childSetValue("user_icon", gAgentID); -		std::string name; -		gCacheName->getFullName(gAgentID, name); -		mAgentPanel->childSetValue("user_text", name); +		// Just use display name, because it's you +		LLAvatarName av_name; +		LLAvatarNameCache::get( gAgentID, &av_name ); +		mAgentPanel->childSetValue("user_text", av_name.mDisplayName);  		mSpeakingIndicator = mAgentPanel->getChild<LLOutputMonitorCtrl>("speaking_indicator");  		mSpeakingIndicator->setSpeakerId(gAgentID); @@ -445,7 +447,10 @@ void LLCallFloater::setModeratorMutedVoice(bool moderator_muted)  void LLCallFloater::updateAgentModeratorState()  {  	std::string name; -	gCacheName->getFullName(gAgentID, name); +	// Just use display name, because it's you +	LLAvatarName av_name; +	LLAvatarNameCache::get(gAgentID, &av_name); +	name = av_name.mDisplayName;  	if(gAgent.isInGroup(mSpeakerManager->getSessionID()))  	{ diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp index 1a6c11fa73..645ff1f3e9 100644 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp @@ -43,6 +43,7 @@  //#include <iterator>  #include "indra_constants.h" +#include "llavatarnamecache.h"  #include "llcachename.h"  #include "llstl.h"  #include "lltimer.h" @@ -96,8 +97,10 @@ const F32 OFFLINE_SECONDS = FIND_FREQUENCY + 8.0f;  // static  LLAvatarTracker LLAvatarTracker::sInstance; - - +static void on_avatar_name_cache_notify(const LLUUID& agent_id, +										const LLAvatarName& av_name, +										bool online, +										LLSD payload);  ///----------------------------------------------------------------------------  /// Class LLAvatarTracker @@ -250,7 +253,7 @@ S32 LLAvatarTracker::addBuddyList(const LLAvatarTracker::buddy_map_t& buds)  	using namespace std;  	U32 new_buddy_count = 0; -	std::string first,last; +	std::string full_name;  	LLUUID agent_id;  	for(buddy_map_t::const_iterator itr = buds.begin(); itr != buds.end(); ++itr)  	{ @@ -260,7 +263,8 @@ S32 LLAvatarTracker::addBuddyList(const LLAvatarTracker::buddy_map_t& buds)  		{  			++new_buddy_count;  			mBuddyInfo[agent_id] = (*itr).second; -			gCacheName->getName(agent_id, first, last); +			// IDEVO JAMESDEBUG is this necessary?  name is unused? +			gCacheName->getFullName(agent_id, full_name);  			addChangedMask(LLFriendObserver::ADD, agent_id);  			lldebugs << "Added buddy " << agent_id  					<< ", " << (mBuddyInfo[agent_id]->isOnline() ? "Online" : "Offline") @@ -680,8 +684,6 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online)  		{  			tracking_id = mTrackingData->mAvatarID;  		} -		BOOL notify = FALSE; -		LLSD args;  		LLSD payload;  		for(S32 i = 0; i < count; ++i)  		{ @@ -691,17 +693,6 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online)  			if(info)  			{  				setBuddyOnline(agent_id,online); -				if(chat_notify) -				{ -					std::string first, last; -					if(gCacheName->getName(agent_id, first, last)) -					{ -						notify = TRUE; -						args["FIRST"] = first; -						args["LAST"] = last; -					} - -				}  			}  			else  			{ @@ -717,29 +708,12 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online)  			// *TODO: get actual inventory id  			gInventory.addChangedMask(LLInventoryObserver::CALLING_CARD, LLUUID::null);  		} -		if(notify) +		if(chat_notify)  		{ -			// Popup a notify box with online status of this agent -			LLNotificationPtr notification; - -			if (online) -			{ -				notification = -					LLNotificationsUtil::add("FriendOnline", -											 args, -											 payload.with("respond_on_mousedown", TRUE), -											 boost::bind(&LLAvatarActions::startIM, agent_id)); -			} -			else -			{ -				notification = -					LLNotificationsUtil::add("FriendOffline", args, payload); -			} - -			// If there's an open IM session with this agent, send a notification there too. -			LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, agent_id); -			std::string notify_msg = notification->getMessage(); -			LLIMModel::instance().proccessOnlineOfflineNotification(session_id, notify_msg); +			// Look up the name of this agent for the notification +			LLAvatarNameCache::get(agent_id, +				boost::bind(&on_avatar_name_cache_notify, +					_1, _2, online, payload));  		}  		mModifyMask |= LLFriendObserver::ONLINE; @@ -748,6 +722,37 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online)  	}  } +static void on_avatar_name_cache_notify(const LLUUID& agent_id, +										const LLAvatarName& av_name, +										bool online, +										LLSD payload) +{ +	// Popup a notify box with online status of this agent +	// Use display name only because this user is your friend +	LLSD args; +	args["NAME"] = av_name.mDisplayName; + +	LLNotificationPtr notification; +	if (online) +	{ +		notification = +			LLNotificationsUtil::add("FriendOnline", +									 args, +									 payload.with("respond_on_mousedown", TRUE), +									 boost::bind(&LLAvatarActions::startIM, agent_id)); +	} +	else +	{ +		notification = +			LLNotificationsUtil::add("FriendOffline", args, payload); +	} + +	// If there's an open IM session with this agent, send a notification there too. +	LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, agent_id); +	std::string notify_msg = notification->getMessage(); +	LLIMModel::instance().proccessOnlineOfflineNotification(session_id, notify_msg); +} +  void LLAvatarTracker::formFriendship(const LLUUID& id)  {  	if(id.notNull()) @@ -868,10 +873,8 @@ bool LLCollectProxyBuddies::operator()(const LLUUID& buddy_id, LLRelationship* b  bool LLCollectMappableBuddies::operator()(const LLUUID& buddy_id, LLRelationship* buddy)  { -	gCacheName->getName(buddy_id, mFirst, mLast); -	std::ostringstream fullname; -	fullname << mFirst << " " << mLast; -	buddy_map_t::value_type value(fullname.str(), buddy_id); +	gCacheName->getFullName(buddy_id, mFullName); +	buddy_map_t::value_type value(mFullName, buddy_id);  	if(buddy->isOnline() && buddy->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION))  	{  		mMappable.insert(value); @@ -881,10 +884,8 @@ bool LLCollectMappableBuddies::operator()(const LLUUID& buddy_id, LLRelationship  bool LLCollectOnlineBuddies::operator()(const LLUUID& buddy_id, LLRelationship* buddy)  { -	gCacheName->getName(buddy_id, mFirst, mLast); -	std::ostringstream fullname; -	fullname << mFirst << " " << mLast; -	buddy_map_t::value_type value(fullname.str(), buddy_id); +	gCacheName->getFullName(buddy_id, mFullName); +	buddy_map_t::value_type value(mFullName, buddy_id);  	if(buddy->isOnline())  	{  		mOnline.insert(value); @@ -894,10 +895,8 @@ bool LLCollectOnlineBuddies::operator()(const LLUUID& buddy_id, LLRelationship*  bool LLCollectAllBuddies::operator()(const LLUUID& buddy_id, LLRelationship* buddy)  { -	gCacheName->getName(buddy_id, mFirst, mLast); -	std::ostringstream fullname; -	fullname << mFirst << " " << mLast; -	buddy_map_t::value_type value(fullname.str(), buddy_id); +	gCacheName->getFullName(buddy_id, mFullName); +	buddy_map_t::value_type value(mFullName, buddy_id);  	if(buddy->isOnline())  	{  		mOnline.insert(value); @@ -908,5 +907,3 @@ bool LLCollectAllBuddies::operator()(const LLUUID& buddy_id, LLRelationship* bud  	}  	return true;  } - - diff --git a/indra/newview/llcallingcard.h b/indra/newview/llcallingcard.h index 47b0dcb903..5bd1f05687 100644 --- a/indra/newview/llcallingcard.h +++ b/indra/newview/llcallingcard.h @@ -241,8 +241,7 @@ public:  	virtual bool operator()(const LLUUID& buddy_id, LLRelationship* buddy);  	typedef std::map<std::string, LLUUID, LLDictionaryLess> buddy_map_t;  	buddy_map_t mMappable; -	std::string mFirst; -	std::string mLast; +	std::string mFullName;  };  // collect dictionary sorted map of name -> agent_id for every online buddy @@ -254,8 +253,7 @@ public:  	virtual bool operator()(const LLUUID& buddy_id, LLRelationship* buddy);  	typedef std::map<std::string, LLUUID, LLDictionaryLess> buddy_map_t;  	buddy_map_t mOnline; -	std::string mFirst; -	std::string mLast; +	std::string mFullName;  };  // collect dictionary sorted map of name -> agent_id for every buddy, @@ -269,8 +267,7 @@ public:  	typedef std::map<std::string, LLUUID, LLDictionaryLess> buddy_map_t;  	buddy_map_t mOnline;  	buddy_map_t mOffline; -	std::string mFirst; -	std::string mLast; +	std::string mFullName;  };  #endif // LL_LLCALLINGCARD_H diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index bd14732b4a..d3686ab99c 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -32,10 +32,12 @@  #include "llviewerprecompiledheaders.h" +#include "llchathistory.h" + +#include "llavatarnamecache.h"  #include "llinstantmessage.h"  #include "llimview.h" -#include "llchathistory.h"  #include "llcommandhandler.h"  #include "llpanel.h"  #include "lluictrlfactory.h" @@ -104,6 +106,18 @@ LLObjectIMHandler gObjectIMHandler;  class LLChatHistoryHeader: public LLPanel  {  public: +	LLChatHistoryHeader() +	:	LLPanel(), +		mPopupMenuHandleAvatar(), +		mPopupMenuHandleObject(), +		mAvatarID(), +		mSourceType(CHAT_SOURCE_UNKNOWN), +		mFrom(), +		mSessionID(), +		mMinUserNameWidth(0), +		mUserNameFont(NULL) +	{} +  	static LLChatHistoryHeader* createInstance(const std::string& file_name)  	{  		LLChatHistoryHeader* pInstance = new LLChatHistoryHeader; @@ -240,7 +254,6 @@ public:  		mAvatarID = chat.mFromID;  		mSessionID = chat.mSessionID;  		mSourceType = chat.mSourceType; -		gCacheName->get(mAvatarID, FALSE, boost::bind(&LLChatHistoryHeader::nameUpdatedCallback, this, _1, _2, _3, _4));  		//*TODO overly defensive thing, source type should be maintained out there  		if((chat.mFromID.isNull() && chat.mFromName.empty()) || chat.mFromName == SYSTEM_FROM) @@ -248,21 +261,28 @@ public:  			mSourceType = CHAT_SOURCE_SYSTEM;  		} -		LLTextBox* userName = getChild<LLTextBox>("user_name"); - -		userName->setReadOnlyColor(style_params.readonly_color()); -		userName->setColor(style_params.color()); +		mUserNameFont = style_params.font(); +		LLTextBox* user_name = getChild<LLTextBox>("user_name"); +		user_name->setReadOnlyColor(style_params.readonly_color()); +		user_name->setColor(style_params.color()); -		userName->setValue(chat.mFromName); -		mFrom = chat.mFromName; -		if (chat.mFromName.empty() || CHAT_SOURCE_SYSTEM == mSourceType) +		if (chat.mFromName.empty() +			|| mSourceType == CHAT_SOURCE_SYSTEM +			|| mAvatarID.isNull())  		{  			mFrom = LLTrans::getString("SECOND_LIFE"); -			userName->setValue(mFrom); +			user_name->setValue(mFrom); +			updateMinUserNameWidth(); +		} +		else +		{ +			// ...from a normal user, lookup the name and fill in later, +			// but start with blank so sample data from XUI XML doesn't +			// flash on the screen +			user_name->setValue( LLSD() ); +			LLAvatarNameCache::get(mAvatarID, +				boost::bind(&LLChatHistoryHeader::onAvatarNameCache, this, _1, _2));  		} - - -		mMinUserNameWidth = style_params.font()->getWidth(userName->getWText().c_str()) + PADDING;  		setTimeField(chat); @@ -317,12 +337,28 @@ public:  		LLPanel::draw();  	} -	void nameUpdatedCallback(const LLUUID& id,const std::string& first,const std::string& last,BOOL is_group) +	void updateMinUserNameWidth()  	{ -		if (id != mAvatarID) -			return; -		mFrom = first + " " + last; +		if (mUserNameFont) +		{ +			LLTextBox* user_name = getChild<LLTextBox>("user_name"); +			const LLWString& text = user_name->getWText(); +			mMinUserNameWidth = mUserNameFont->getWidth(text.c_str()) + PADDING; +		}  	} + +	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) +	{ +		mFrom = av_name.mDisplayName; + +		LLTextBox* user_name = getChild<LLTextBox>("user_name"); +		user_name->setValue( LLSD(av_name.mDisplayName ) ); +		user_name->setToolTip( av_name.mUsername ); +		setToolTip( av_name.mUsername ); +		// name might have changed, update width +		updateMinUserNameWidth(); +	} +  protected:  	static const S32 PADDING = 20; @@ -439,6 +475,7 @@ protected:  	LLUUID				mSessionID;  	S32					mMinUserNameWidth; +	const LLFontGL*		mUserNameFont;  };  LLUICtrl* LLChatHistoryHeader::sInfoCtrl = NULL; diff --git a/indra/newview/lldateutil.cpp b/indra/newview/lldateutil.cpp index 3e71ecdfba..ae955b6cad 100644 --- a/indra/newview/lldateutil.cpp +++ b/indra/newview/lldateutil.cpp @@ -172,3 +172,23 @@ std::string LLDateUtil::ageFromDate(const std::string& date_string)  {  	return ageFromDate(date_string, LLDate::now());  } + +//std::string LLDateUtil::ageFromDateISO(const std::string& date_string, +//									   const LLDate& now) +//{ +//	S32 born_month, born_day, born_year; +//	S32 matched = sscanf(date_string.c_str(), "%d-%d-%d", +//			&born_year, &born_month, &born_day); +//	if (matched != 3) return "???"; +//	date.fromYMDHMS(year, month, day); +//	F64 secs_since_epoch = date.secondsSinceEpoch(); +//	// Correct for the fact that specified date is in Pacific time, == UTC - 8 +//	secs_since_epoch += 8.0 * 60.0 * 60.0; +//	date.secondsSinceEpoch(secs_since_epoch); +//	return ageFromDate(born_year, born_month, born_day, now); +//} +// +//std::string LLDateUtil::ageFromDateISO(const std::string& date_string) +//{ +//	return ageFromDateISO(date_string, LLDate::now()); +//} diff --git a/indra/newview/lldateutil.h b/indra/newview/lldateutil.h index a0df21022e..8d41eea511 100644 --- a/indra/newview/lldateutil.h +++ b/indra/newview/lldateutil.h @@ -67,6 +67,14 @@ namespace LLDateUtil  	// Calls the above with LLDate::now()  	std::string ageFromDate(const std::string& date_string); + +	// As above, for YYYY-MM-DD dates +	//std::string ageFromDateISO(const std::string& date_string, const LLDate& now); + +	// Calls the above with LLDate::now() +	//std::string ageFromDateISO(const std::string& date_string); + +	//std::string ageFromDate(S32 born_year, S32 born_month, S32 born_day, const LLDate& now);  }  #endif diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index 651dabff9e..b8b09b89f1 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -53,6 +53,7 @@ class LLCamera;  class LLDrawPool;  class LLDrawable;  class LLFace; +class LLFacePool;  class LLSpatialGroup;  class LLSpatialBridge;  class LLSpatialPartition; diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index b40c19c2c6..16a8f244ee 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -36,15 +36,21 @@  // Viewer includes  #include "llagent.h"  #include "llcallingcard.h" +#include "lldate.h"				// split() +#include "lldateutil.h"			// ageFromDate()  #include "llfocusmgr.h"  #include "llfloaterreg.h"  #include "llimview.h"			// for gIMMgr  #include "lltooldraganddrop.h"	// for LLToolDragAndDrop  #include "llviewercontrol.h" +#include "llviewerregion.h"		// getCapability()  #include "llworld.h"  // Linden libraries +#include "llavatarnamecache.h"	// IDEVO  #include "llbutton.h" +#include "llcachename.h" +#include "llhttpclient.h"		// IDEVO  #include "lllineeditor.h"  #include "llscrolllistctrl.h"  #include "llscrolllistitem.h" @@ -53,6 +59,8 @@  #include "lluictrlfactory.h"  #include "message.h" +//#include "llsdserialize.h" +  LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(select_callback_t callback,  												   BOOL allow_multiple,  												   BOOL closeOnSelect) @@ -352,23 +360,75 @@ BOOL LLFloaterAvatarPicker::visibleItemsSelected() const  	return FALSE;  } +class LLAvatarPickerResponder : public LLHTTPClient::Responder +{ +public: +	LLUUID mQueryID; + +	LLAvatarPickerResponder(const LLUUID& id) : mQueryID(id) { } + +	/*virtual*/ void completed(U32 status, const std::string& reason, const LLSD& content) +	{ +		//std::ostringstream ss; +		//LLSDSerialize::toPrettyXML(content, ss); +		//llinfos << ss.str() << llendl; + +		if (isGoodStatus(status)) +		{ +			LLFloaterAvatarPicker* floater = +				LLFloaterReg::findTypedInstance<LLFloaterAvatarPicker>("avatar_picker"); +			if (floater) +			{ +				floater->processResponse(mQueryID, content); +			} +		} +		else +		{ +			llinfos << "avatar picker failed " << status +				<< " reason " << reason << llendl; +		} +	} +}; +  void LLFloaterAvatarPicker::find()  {  	std::string text = childGetValue("Edit").asString();  	mQueryID.generate(); -	LLMessageSystem* msg = gMessageSystem; +	std::string url; +	url.reserve(128); // avoid a memory allocation or two -	msg->newMessage("AvatarPickerRequest"); -	msg->nextBlock("AgentData"); -	msg->addUUID("AgentID", gAgent.getID()); -	msg->addUUID("SessionID", gAgent.getSessionID()); -	msg->addUUID("QueryID", mQueryID);	// not used right now -	msg->nextBlock("Data"); -	msg->addString("Name", text); - -	gAgent.sendReliableMessage(); +	LLViewerRegion* region = gAgent.getRegion(); +	url = region->getCapability("AvatarPickerSearch"); +	// Prefer use of capabilities to search on both SLID and display name +	// but allow display name search to be manually turned off for test +	if (!url.empty() +		&& LLAvatarNameCache::useDisplayNames()) +	{ +		// capability urls don't end in '/', but we need one to parse +		// query parameters correctly +		if (url.size() > 0 && url[url.size()-1] != '/') +		{ +			url += "/"; +		} +		url += "?names="; +		url += LLURI::escape(text); +		llinfos << "avatar picker " << url << llendl; +		LLHTTPClient::get(url, new LLAvatarPickerResponder(mQueryID)); +	} +	else +	{ +		LLMessageSystem* msg = gMessageSystem; +		msg->newMessage("AvatarPickerRequest"); +		msg->nextBlock("AgentData"); +		msg->addUUID("AgentID", gAgent.getID()); +		msg->addUUID("SessionID", gAgent.getSessionID()); +		msg->addUUID("QueryID", mQueryID);	// not used right now +		msg->nextBlock("Data"); +		msg->addString("Name", text); +		gAgent.sendReliableMessage(); +	}  	getChild<LLScrollListCtrl>("SearchResults")->deleteAllItems();  	getChild<LLScrollListCtrl>("SearchResults")->setCommentText(getString("searching")); @@ -496,12 +556,13 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void*  		}  		else  		{ -			avatar_name = first_name + " " + last_name; +			avatar_name = LLCacheName::buildFullName(first_name, last_name);  			search_results->setEnabled(TRUE);  			found_one = TRUE;  		}  		LLSD element;  		element["id"] = avatar_id; // value +		element["columns"][0]["column"] = "name";  		element["columns"][0]["value"] = avatar_name;  		search_results->addElement(element);  	} @@ -515,10 +576,63 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void*  	}  } +void LLFloaterAvatarPicker::processResponse(const LLUUID& query_id, const LLSD& content) +{ +	// Check for out-of-date query +	if (query_id != mQueryID) return; + +	LLScrollListCtrl* search_results = getChild<LLScrollListCtrl>("SearchResults"); + +	LLSD agents = content["agents"]; +	if (agents.size() == 0) +	{ +		LLStringUtil::format_map_t map; +		map["[TEXT]"] = childGetText("Edit"); +		LLSD item; +		item["id"] = LLUUID::null; +		item["columns"][0]["column"] = "name"; +		item["columns"][0]["value"] = getString("not_found", map); +		search_results->addElement(item); +		search_results->setEnabled(FALSE); +		childDisable("ok_btn"); +		return; +	} + +	// clear "Searching" label on first results +	search_results->deleteAllItems(); + +	LLSD item; +	LLSD::array_const_iterator it = agents.beginArray(); +	for ( ; it != agents.endArray(); ++it) +	{ +		const LLSD& row = *it; +		item["id"] = row["agent_id"]; +		LLSD& columns = item["columns"]; +		columns[0]["column"] = "name"; +		columns[0]["value"] = row["display_name"]; +		columns[1]["column"] = "slid"; +		columns[1]["value"] = row["sl_id"]; +		LLDate account_created = row["account_created"].asDate(); +		S32 year, month, day; +		account_created.split(&year, &month, &day); +		std::string age = +			LLDateUtil::ageFromDate(account_created, LLDate::now()); +		columns[2]["column"] = "age"; +		columns[2]["value"] = age; +		search_results->addElement(item); +	} + +	childEnable("ok_btn"); +	search_results->setEnabled(true); +	search_results->selectFirstItem(); +	onList(); +	search_results->setFocus(TRUE); +} +  //static  void LLFloaterAvatarPicker::editKeystroke(LLLineEditor* caller, void* user_data)  { -	childSetEnabled("Find", caller->getText().size() >= 3); +	childSetEnabled("Find", caller->getText().size() > 0);  }  // virtual diff --git a/indra/newview/llfloateravatarpicker.h b/indra/newview/llfloateravatarpicker.h index e69b814f9f..e355b38457 100644 --- a/indra/newview/llfloateravatarpicker.h +++ b/indra/newview/llfloateravatarpicker.h @@ -60,6 +60,7 @@ public:  	void setOkBtnEnableCb(validate_callback_t cb);  	static void processAvatarPickerReply(class LLMessageSystem* msg, void**); +	void processResponse(const LLUUID& query_id, const LLSD& content);  	BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,  						   BOOL drop, EDragAndDropType cargo_type, diff --git a/indra/newview/llfloaterbump.cpp b/indra/newview/llfloaterbump.cpp index e925796526..9ccae43a92 100644 --- a/indra/newview/llfloaterbump.cpp +++ b/indra/newview/llfloaterbump.cpp @@ -89,7 +89,7 @@ void LLFloaterBump::onOpen(const LLSD& key)  void LLFloaterBump::add(LLScrollListCtrl* list, LLMeanCollisionData* mcd)  { -	if (mcd->mFirstName.empty() || list->getItemCount() >= 20) +	if (mcd->mFullName.empty() || list->getItemCount() >= 20)  	{  		return;  	} @@ -127,8 +127,7 @@ void LLFloaterBump::add(LLScrollListCtrl* list, LLMeanCollisionData* mcd)  	// All above action strings are in XML file  	LLUIString text = getString(action);  	text.setArg("[TIME]", timeStr); -	text.setArg("[FIRST]", mcd->mFirstName); -	text.setArg("[LAST]", mcd->mLastName); +	text.setArg("[NAME]", mcd->mFullName);  	LLSD row;  	row["id"] = mcd->mPerp; diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp index 7ca7ace0fc..419253d938 100644 --- a/indra/newview/llfloaterbuyland.cpp +++ b/indra/newview/llfloaterbuyland.cpp @@ -186,9 +186,8 @@ public:  	void updateNames();  	// Name cache callback  	void updateGroupName(const LLUUID& id, -						 const std::string& first_name, -						 const std::string& last_name, -						 BOOL is_group); +						 const std::string& name, +						 bool is_group);  	void refreshUI(); @@ -824,9 +823,9 @@ void LLFloaterBuyLandUI::updateNames()  	}  	else if (parcelp->getIsGroupOwned())  	{ -		gCacheName->get(parcelp->getGroupID(), TRUE, +		gCacheName->get(parcelp->getGroupID(), true,  			boost::bind(&LLFloaterBuyLandUI::updateGroupName, this, -				_1, _2, _3, _4)); +				_1, _2, _3));  	}  	else  	{ @@ -836,16 +835,15 @@ void LLFloaterBuyLandUI::updateNames()  }  void LLFloaterBuyLandUI::updateGroupName(const LLUUID& id, -						 const std::string& first_name, -						 const std::string& last_name, -						 BOOL is_group) +						 const std::string& name, +						 bool is_group)  {  	LLParcel* parcelp = mParcel->getParcel();  	if (parcelp  		&& parcelp->getGroupID() == id)  	{  		// request is current -		mParcelSellerName = first_name; +		mParcelSellerName = name;  	}  } diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index abdb55ec17..81dea58607 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -37,7 +37,7 @@  #include "llfloaterland.h" -#include "llcachename.h" +#include "llavatarnamecache.h"  #include "llfocusmgr.h"  #include "llnotificationsutil.h"  #include "llparcel.h" @@ -586,6 +586,8 @@ void LLPanelLandGeneral::refresh()  										parcel, GP_LAND_SET_SALE_INFO);  		BOOL can_be_sold = owner_sellable || estate_manager_sellable; +		can_be_sold = true; +  		const LLUUID &owner_id = parcel->getOwnerID();  		BOOL is_public = parcel->isPublic(); @@ -828,9 +830,9 @@ void LLPanelLandGeneral::refreshNames()  		const LLUUID& auth_buyer_id = parcel->getAuthorizedBuyerID();  		if(auth_buyer_id.notNull())  		{ -		  std::string name; -		  name = LLSLURL("agent", auth_buyer_id, "inspect").getSLURLString(); -		  mSaleInfoForSale2->setTextArg("[BUYER]", name); +			std::string name; +			name = LLSLURL("agent", auth_buyer_id, "inspect").getSLURLString(); +			mSaleInfoForSale2->setTextArg("[BUYER]", name);  		}  		else  		{ @@ -1390,10 +1392,7 @@ bool LLPanelLandObjects::callbackReturnOwnerObjects(const LLSD& notification, co  			}  			else  			{ -				std::string first, last; -				gCacheName->getName(owner_id, first, last); -				args["FIRST"] = first; -				args["LAST"] = last; +				args["NAME"] = LLSLURL("agent", owner_id, "inspect").getSLURLString();  				LLNotificationsUtil::add("OtherObjectsReturned", args);  			}  			send_return_objects_message(parcel->getLocalID(), RT_OWNER); @@ -1611,9 +1610,9 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo  		}  		// Placeholder for name. -		std::string name; -		gCacheName->getFullName(owner_id, name);		 -		item_params.columns.add().value(name).font(FONT).column("name"); +		LLAvatarName av_name; +		LLAvatarNameCache::get(owner_id, &av_name); +		item_params.columns.add().value(av_name.getCompleteName()).font(FONT).column("name");  		object_count_str = llformat("%d", object_count);  		item_params.columns.add().value(object_count_str).font(FONT).column("count"); @@ -1722,9 +1721,7 @@ void LLPanelLandObjects::onClickReturnOwnerObjects(void* userdata)  	}  	else  	{ -		std::string name; -		gCacheName->getFullName(owner_id, name); -		args["NAME"] = name; +		args["NAME"] = LLSLURL("agent", owner_id, "inspect").getSLURLString();  		LLNotificationsUtil::add("ReturnObjectsOwnedByUser", args, LLSD(), boost::bind(&LLPanelLandObjects::callbackReturnOwnerObjects, panelp, _1, _2));  	}  } @@ -1783,10 +1780,7 @@ void LLPanelLandObjects::onClickReturnOtherObjects(void* userdata)  		}  		else  		{ -			std::string name; -			gCacheName->getFullName(owner_id, name); -			args["NAME"] = name; - +			args["NAME"] = LLSLURL("agent", owner_id, "inspect").getSLURLString();  			LLNotificationsUtil::add("ReturnObjectsNotOwnedByUser", args, LLSD(), boost::bind(&LLPanelLandObjects::callbackReturnOtherObjects, panelp, _1, _2));  		}  	} @@ -2509,7 +2503,7 @@ void LLPanelLandAccess::refresh()  			if (maturity_pos != std::string::npos)  			{  				maturity_string.replace(maturity_pos, MATURITY.length(), std::string("")); -			} +		}  			maturity_checkbox->setLabel(maturity_string);  		} diff --git a/indra/newview/llfloaterpay.cpp b/indra/newview/llfloaterpay.cpp index 51364594e4..7b596e9ba3 100644 --- a/indra/newview/llfloaterpay.cpp +++ b/indra/newview/llfloaterpay.cpp @@ -47,6 +47,7 @@  #include "lllineeditor.h"  #include "llmutelist.h"  #include "llfloaterreporter.h" +#include "llslurl.h"  #include "llviewerobject.h"  #include "llviewerobjectlist.h"  #include "llviewerregion.h" @@ -102,10 +103,6 @@ private:  	static void onGive(void* data);  	void give(S32 amount);  	static void processPayPriceReply(LLMessageSystem* msg, void **userdata); -	void onCacheOwnerName(const LLUUID& owner_id, -						  const std::string& firstname, -						  const std::string& lastname, -						  BOOL is_group);  	void finishPayUI(const LLUUID& target_id, BOOL is_group);  protected: @@ -427,33 +424,28 @@ void LLFloaterPay::payDirectly(money_callback callback,  void LLFloaterPay::finishPayUI(const LLUUID& target_id, BOOL is_group)  { -	gCacheName->get(target_id, is_group, boost::bind(&LLFloaterPay::onCacheOwnerName, this, _1, _2, _3, _4)); - -	// Make sure the amount field has focus - -	childSetFocus("amount", TRUE); -	 -	LLLineEditor* amount = getChild<LLLineEditor>("amount"); -	amount->selectAll(); -	mTargetIsGroup = is_group; -} - -void LLFloaterPay::onCacheOwnerName(const LLUUID& owner_id, -									const std::string& firstname, -									const std::string& lastname, -									BOOL is_group) -{ +	// IDEVO +	//gCacheName->get(target_id, is_group, boost::bind(&LLFloaterPay::onCacheOwnerName, this, _1, _2, _3, _4)); +	std::string slurl;  	if (is_group)  	{  		setTitle(getString("payee_group")); +		slurl = LLSLURL("group", target_id, "inspect").getSLURLString();  	}  	else  	{  		setTitle(getString("payee_resident")); +		slurl = LLSLURL("agent", target_id, "inspect").getSLURLString();  	} +	childSetText("payee_name", slurl); -	childSetTextArg("payee_name", "[FIRST]", firstname); -	childSetTextArg("payee_name", "[LAST]", lastname); +	// Make sure the amount field has focus + +	childSetFocus("amount", TRUE); +	 +	LLLineEditor* amount = getChild<LLLineEditor>("amount"); +	amount->selectAll(); +	mTargetIsGroup = is_group;  }  // static diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 0eeef0039c..920d09bd7f 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -81,6 +81,7 @@  #include "llvosky.h"  // linden library includes +#include "llavatarnamecache.h"  #include "llerror.h"  #include "llfontgl.h"  #include "llrect.h" @@ -184,6 +185,8 @@ void LLVoiceSetKeyDialog::onCancel(void* user_data)  // if creating/destroying these is too slow, we'll need to create  // a static member and update all our static callbacks +void handleNameTagOptionChanged(const LLSD& newvalue);	 +void handleDisplayNamesOptionChanged(const LLSD& newvalue);	  bool callback_clear_browser_cache(const LLSD& notification, const LLSD& response);  //bool callback_skip_dialogs(const LLSD& notification, const LLSD& response, LLFloaterPreference* floater); @@ -219,6 +222,18 @@ bool callback_clear_browser_cache(const LLSD& notification, const LLSD& response  	return false;  } +void handleNameTagOptionChanged(const LLSD& newvalue) +{ +	LLVOAvatar::invalidateNameTags(); +} + +void handleDisplayNamesOptionChanged(const LLSD& newvalue) +{ +	LLAvatarNameCache::setUseDisplayNames(newvalue.asBoolean()); +	LLVOAvatar::invalidateNameTags(); +} + +  /*bool callback_skip_dialogs(const LLSD& notification, const LLSD& response, LLFloaterPreference* floater)  {  	S32 option = LLNotificationsUtil::getSelectedOption(notification, response); @@ -311,6 +326,10 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)  	mCommitCallbackRegistrar.add("Pref.MaturitySettings",		boost::bind(&LLFloaterPreference::onChangeMaturity, this));  	sSkin = gSavedSettings.getString("SkinCurrent"); +	 +	gSavedSettings.getControl("NameTagShowUsernames")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged,  _2));	 +	gSavedSettings.getControl("NameTagShowFriends")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged,  _2));	 +	gSavedSettings.getControl("UseDisplayNames")->getCommitSignal()->connect(boost::bind(&handleDisplayNamesOptionChanged,  _2));  }  BOOL LLFloaterPreference::postBuild() diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 8c219cb3fd..fa146342ad 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -1971,8 +1971,15 @@ void LLPanelEstateInfo::updateControls(LLViewerRegion* region)  	childSetEnabled("remove_allowed_avatar_btn",	god || owner || manager);  	childSetEnabled("add_allowed_group_btn",		god || owner || manager);  	childSetEnabled("remove_allowed_group_btn",		god || owner || manager); -	childSetEnabled("add_banned_avatar_btn",		god || owner || manager); -	childSetEnabled("remove_banned_avatar_btn",		god || owner || manager); + +	// Can't ban people from mainland, orientation islands, etc. because this +	// creates much network traffic and server load. +	// Disable their accounts in CSR tool instead. +	bool linden_estate = (getEstateID() <= ESTATE_LAST_LINDEN); +	bool enable_ban = (god || owner || manager) && !linden_estate; +	childSetEnabled("add_banned_avatar_btn",		enable_ban); +	childSetEnabled("remove_banned_avatar_btn",		enable_ban); +  	childSetEnabled("message_estate_btn",			god || owner || manager);  	childSetEnabled("kick_user_from_estate_btn",	god || owner || manager); diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index f7c8855bf6..bdaf036d0e 100644 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -39,6 +39,7 @@  // linden library includes  #include "llassetstorage.h" +#include "llcachename.h"  #include "llfontgl.h"  #include "llimagej2c.h"  #include "llinventory.h" @@ -274,9 +275,8 @@ void LLFloaterReporter::getObjectInfo(const LLUUID& object_id)  				LLNameValue* lastname =  objectp->getNVPair("LastName");  				if (firstname && lastname)  				{ -					object_owner.append(firstname->getString()); -					object_owner.append(1, ' '); -					object_owner.append(lastname->getString()); +					object_owner = LLCacheName::buildFullName( +						firstname->getString(), lastname->getString());  				}  				else  				{ diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp index 4792d761d8..bd31181e5a 100644 --- a/indra/newview/llfloaterscriptlimits.cpp +++ b/indra/newview/llfloaterscriptlimits.cpp @@ -295,7 +295,7 @@ void fetchScriptLimitsRegionSummaryResponder::result(const LLSD& content_ref)  		LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels");  		if(tab)  		{ -			LLPanelScriptLimitsRegionMemory* panel_memory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); +		LLPanelScriptLimitsRegionMemory* panel_memory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel");  			if(panel_memory)  			{  				panel_memory->childSetValue("loading_text", LLSD(std::string(""))); @@ -306,9 +306,9 @@ void fetchScriptLimitsRegionSummaryResponder::result(const LLSD& content_ref)  					btn->setEnabled(true);  				} -				panel_memory->setRegionSummary(content); -			} -		} +		panel_memory->setRegionSummary(content); +	} +}  	}  } @@ -599,11 +599,8 @@ void LLPanelScriptLimitsRegionMemory::setErrorStatus(U32 status, const std::stri  // callback from the name cache with an owner name to add to the list  void LLPanelScriptLimitsRegionMemory::onNameCache(  						 const LLUUID& id, -						 const std::string& first_name, -						 const std::string& last_name) +						 const std::string& name)  { -	std::string name = first_name + " " + last_name; -  	LLScrollListCtrl *list = getChild<LLScrollListCtrl>("scripts_list");	  	if(!list)  	{ @@ -675,6 +672,9 @@ void LLPanelScriptLimitsRegionMemory::setRegionDetails(LLSD content)  			std::string name_buf = content["parcels"][i]["objects"][j]["name"].asString();  			LLUUID task_id = content["parcels"][i]["objects"][j]["id"].asUUID();  			LLUUID owner_id = content["parcels"][i]["objects"][j]["owner_id"].asUUID(); +			// This field may not be sent by all server versions, but it's OK if +			// it uses the LLSD default of false +			bool is_group_owned = content["parcels"][i]["objects"][j]["is_group_owned"].asBoolean();  			F32 location_x = 0.0f;  			F32 location_y = 0.0f; @@ -700,15 +700,23 @@ void LLPanelScriptLimitsRegionMemory::setRegionDetails(LLSD content)  			// ...and if not use the slightly more painful method of disovery:  			else  			{ -				BOOL name_is_cached = gCacheName->getFullName(owner_id, owner_buf); +				BOOL name_is_cached; +				if (is_group_owned) +				{ +					name_is_cached = gCacheName->getGroupName(owner_id, owner_buf); +				} +				else +				{ +					name_is_cached = gCacheName->getFullName(owner_id, owner_buf); +				}  				if(!name_is_cached)  				{  					if(std::find(names_requested.begin(), names_requested.end(), owner_id) == names_requested.end())  					{  						names_requested.push_back(owner_id); -						gCacheName->get(owner_id, TRUE, +						gCacheName->get(owner_id, is_group_owned,  						boost::bind(&LLPanelScriptLimitsRegionMemory::onNameCache, -							this, _1, _2, _3)); +							    this, _1, _2));  					}  				}  			} @@ -1310,7 +1318,7 @@ void LLPanelScriptLimitsAttachment::setAttachmentSummary(LLSD content)  // static  void LLPanelScriptLimitsAttachment::onClickRefresh(void* userdata) -{	 +{  	LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");  	if(instance)  	{ diff --git a/indra/newview/llfloaterscriptlimits.h b/indra/newview/llfloaterscriptlimits.h index 3c32b9f701..ba6f930bee 100644 --- a/indra/newview/llfloaterscriptlimits.h +++ b/indra/newview/llfloaterscriptlimits.h @@ -170,10 +170,8 @@ public:  	void returnObjects();  private: -  	void onNameCache(const LLUUID& id, -			 const std::string& first_name, -			 const std::string& last_name); +						 const std::string& name);  	LLSD mContent;  	LLUUID mParcelId; diff --git a/indra/newview/llfloatersellland.cpp b/indra/newview/llfloatersellland.cpp index 9dddbd998a..e214b58a9a 100644 --- a/indra/newview/llfloatersellland.cpp +++ b/indra/newview/llfloatersellland.cpp @@ -33,6 +33,7 @@  #include "llfloatersellland.h" +#include "llavatarnamecache.h"  #include "llfloateravatarpicker.h"  #include "llfloaterreg.h"  #include "llfloaterland.h" @@ -47,6 +48,8 @@  #include "lluictrlfactory.h"  #include "llviewerwindow.h" +class LLAvatarName; +  // defined in llfloaterland.cpp  void send_parcel_select_objects(S32 parcel_local_id, U32 return_type,  								uuid_list_t* return_ids = NULL); @@ -97,6 +100,8 @@ private:  	void callbackAvatarPick(const std::vector<std::string>& names, const uuid_vec_t& ids); +	void onBuyerNameCache(const LLAvatarName& av_name); +  public:  	virtual BOOL postBuild(); @@ -230,12 +235,17 @@ void LLFloaterSellLandUI::updateParcelInfo()  	if(mSellToBuyer)  	{ -		std::string name; -		gCacheName->getFullName(mAuthorizedBuyer, name); -		childSetText("sell_to_agent", name); +		LLAvatarNameCache::get(mAuthorizedBuyer,  +			boost::bind(&LLFloaterSellLandUI::onBuyerNameCache, this, _2));  	}  } +void LLFloaterSellLandUI::onBuyerNameCache(const LLAvatarName& av_name) +{ +	childSetText("sell_to_agent", av_name.getCompleteName()); +	childSetToolTip("sell_to_agent", av_name.mUsername); +} +  void LLFloaterSellLandUI::setBadge(const char* id, Badge badge)  {  	static std::string badgeOK("badge_ok.j2c"); diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp index 84ea353dab..04eb5f5d86 100644 --- a/indra/newview/llfloatertopobjects.cpp +++ b/indra/newview/llfloatertopobjects.cpp @@ -196,8 +196,9 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)  		LLSD element;  		element["id"] = task_id; -		element["object_name"] = name_buf; -		element["owner_name"] = owner_buf; +		// These cause parse warnings. JC +		//element["object_name"] = name_buf; +		//element["owner_name"] = owner_buf;  		element["columns"][0]["column"] = "score";  		element["columns"][0]["value"] = llformat("%0.3f", score);  		element["columns"][0]["font"] = "SANSSERIF"; @@ -206,7 +207,7 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)  		element["columns"][1]["value"] = name_buf;  		element["columns"][1]["font"] = "SANSSERIF";  		element["columns"][2]["column"] = "owner"; -		element["columns"][2]["value"] = owner_buf; +		element["columns"][2]["value"] = LLCacheName::cleanFullName(owner_buf);  		element["columns"][2]["font"] = "SANSSERIF";  		element["columns"][3]["column"] = "location";  		element["columns"][3]["value"] = llformat("<%0.1f,%0.1f,%0.1f>", location_x, location_y, location_z); diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index 2aba0b5c09..eec08301a8 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -54,6 +54,7 @@  #include "lltoolmgr.h"  #include "llselectmgr.h"  #include "llhudmanager.h" +#include "llhudtext.h"  #include "llrendersphere.h"  #include "llviewerobjectlist.h"  #include "lltoolselectrect.h" @@ -894,7 +895,7 @@ void LLViewerObjectList::renderObjectBeacons()  			color = debug_beacon.mTextColor;  			color.mV[3] *= 1.f; -			hud_textp->setString(utf8str_to_wstring(debug_beacon.mString)); +			hud_textp->setString(debug_beacon.mString);  			hud_textp->setColor(color);  			hud_textp->setPositionAgent(debug_beacon.mPositionAgent);  			debug_beacon.mHUDObject = hud_textp; diff --git a/indra/newview/llhudicon.h b/indra/newview/llhudicon.h index 770e3bbcd0..91b3a64250 100644 --- a/indra/newview/llhudicon.h +++ b/indra/newview/llhudicon.h @@ -50,6 +50,7 @@  // Renders a 2D icon billboard floating at the location specified.  class LLDrawable;  class LLViewerObject; +class LLViewerTexture;  class LLHUDIcon : public LLHUDObject  { diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp new file mode 100644 index 0000000000..2cb333a717 --- /dev/null +++ b/indra/newview/llhudnametag.cpp @@ -0,0 +1,1072 @@ +/**  + * @file llhudnametag.cpp + * @brief Name tags for avatars + * @author James Cook + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + *  + * Copyright (c) 2002-2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llhudnametag.h" + +#include "llrender.h" + +#include "llagent.h" +#include "llviewercontrol.h" +#include "llcriticaldamp.h" +#include "lldrawable.h" +#include "llfontgl.h" +#include "llglheaders.h" +#include "llhudrender.h" +#include "llui.h" +#include "llviewercamera.h" +#include "llviewertexturelist.h" +#include "llviewerobject.h" +#include "llvovolume.h" +#include "llviewerwindow.h" +#include "llstatusbar.h" +#include "llmenugl.h" +#include "pipeline.h" +#include <boost/tokenizer.hpp> + + +const F32 SPRING_STRENGTH = 0.7f; +const F32 RESTORATION_SPRING_TIME_CONSTANT = 0.1f; +const F32 HORIZONTAL_PADDING = 16.f; +const F32 VERTICAL_PADDING = 12.f; +const F32 LINE_PADDING = 3.f;			// aka "leading" +const F32 BUFFER_SIZE = 2.f; +const F32 MIN_EDGE_OVERLAP = 3.f; +const F32 HUD_TEXT_MAX_WIDTH = 190.f; +const F32 HUD_TEXT_MAX_WIDTH_NO_BUBBLE = 1000.f; +const F32 RESIZE_TIME = 0.f; +const S32 NUM_OVERLAP_ITERATIONS = 10; +const F32 NEIGHBOR_FORCE_FRACTION = 1.f; +const F32 POSITION_DAMPING_TC = 0.2f; +const F32 MAX_STABLE_CAMERA_VELOCITY = 0.1f; +const F32 LOD_0_SCREEN_COVERAGE = 0.15f; +const F32 LOD_1_SCREEN_COVERAGE = 0.30f; +const F32 LOD_2_SCREEN_COVERAGE = 0.40f; + +std::set<LLPointer<LLHUDNameTag> > LLHUDNameTag::sTextObjects; +std::vector<LLPointer<LLHUDNameTag> > LLHUDNameTag::sVisibleTextObjects; +BOOL LLHUDNameTag::sDisplayText = TRUE ; + +bool llhudnametag_further_away::operator()(const LLPointer<LLHUDNameTag>& lhs, const LLPointer<LLHUDNameTag>& rhs) const +{ +	return lhs->getDistance() > rhs->getDistance(); +} + + +LLHUDNameTag::LLHUDNameTag(const U8 type) +:	LLHUDObject(type), +	mDoFade(TRUE), +	mFadeDistance(8.f), +	mFadeRange(4.f), +	mLastDistance(0.f), +	mZCompare(TRUE), +	mVisibleOffScreen(FALSE), +	mOffscreen(FALSE), +	mColor(1.f, 1.f, 1.f, 1.f), +//	mScale(), +	mWidth(0.f), +	mHeight(0.f), +	mFontp(LLFontGL::getFontSansSerifSmall()), +	mBoldFontp(LLFontGL::getFontSansSerifBold()), +	mSoftScreenRect(), +	mPositionAgent(), +	mPositionOffset(), +	mMass(10.f), +	mMaxLines(10), +	mOffsetY(0), +	mRadius(0.1f), +	mTextSegments(), +	mLabelSegments(), +	mTextAlignment(ALIGN_TEXT_CENTER), +	mVertAlignment(ALIGN_VERT_CENTER), +	mLOD(0), +	mHidden(FALSE) +{ +	LLPointer<LLHUDNameTag> ptr(this); +	sTextObjects.insert(ptr); +} + +LLHUDNameTag::~LLHUDNameTag() +{ +} + + +BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3& intersection, BOOL debug_render) +{ +	if (!mVisible || mHidden) +	{ +		return FALSE; +	} + +	// don't pick text that isn't bound to a viewerobject +	if (!mSourceObject || mSourceObject->mDrawable.isNull()) +	{ +		return FALSE; +	} +	 +	F32 alpha_factor = 1.f; +	LLColor4 text_color = mColor; +	if (mDoFade) +	{ +		if (mLastDistance > mFadeDistance) +		{ +			alpha_factor = llmax(0.f, 1.f - (mLastDistance - mFadeDistance)/mFadeRange); +			text_color.mV[3] = text_color.mV[3]*alpha_factor; +		} +	} +	if (text_color.mV[3] < 0.01f) +	{ +		return FALSE; +	} + +	mOffsetY = lltrunc(mHeight * ((mVertAlignment == ALIGN_VERT_CENTER) ? 0.5f : 1.f)); + +	// scale screen size of borders down +	//RN: for now, text on hud objects is never occluded + +	LLVector3 x_pixel_vec; +	LLVector3 y_pixel_vec; +	 +	LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec); + +	LLVector3 width_vec = mWidth * x_pixel_vec; +	LLVector3 height_vec = mHeight * y_pixel_vec; +	 +	LLCoordGL screen_pos; +	LLViewerCamera::getInstance()->projectPosAgentToScreen(mPositionAgent, screen_pos, FALSE); + +	LLVector2 screen_offset; +	screen_offset = updateScreenPos(mPositionOffset); +	 +	LLVector3 render_position = mPositionAgent   +			+ (x_pixel_vec * screen_offset.mV[VX]) +			+ (y_pixel_vec * screen_offset.mV[VY]); + + +	//if (mUseBubble) +	{ +		LLVector3 bg_pos = render_position +			+ (F32)mOffsetY * y_pixel_vec +			- (width_vec / 2.f) +			- (height_vec); +		//LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]); + +		LLVector3 v[] =  +		{ +			bg_pos, +			bg_pos + width_vec, +			bg_pos + width_vec + height_vec, +			bg_pos + height_vec, +		}; + +		if (debug_render) +		{ +			gGL.begin(LLRender::LINE_STRIP); +			gGL.vertex3fv(v[0].mV); +			gGL.vertex3fv(v[1].mV); +			gGL.vertex3fv(v[2].mV); +			gGL.vertex3fv(v[3].mV); +			gGL.vertex3fv(v[0].mV); +			gGL.vertex3fv(v[2].mV); +			gGL.end(); +		} + +		LLVector3 dir = end-start; +		F32 t = 0.f; + +		if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, NULL, NULL, &t, FALSE) || +			LLTriangleRayIntersect(v[2], v[3], v[0], start, dir, NULL, NULL, &t, FALSE) ) +		{ +			if (t <= 1.f) +			{ +				intersection = start + dir*t; +				return TRUE; +			} +		} +	} + +	return FALSE; +} + +void LLHUDNameTag::render() +{ +	if (sDisplayText) +	{ +		LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); +		renderText(FALSE); +	} +} + +void LLHUDNameTag::renderForSelect() +{ +	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); +	renderText(TRUE); +} + +void LLHUDNameTag::renderText(BOOL for_select) +{ +	if (!mVisible || mHidden) +	{ +		return; +	} + +	// don't pick text that isn't bound to a viewerobject +	if (for_select &&  +		(!mSourceObject || mSourceObject->mDrawable.isNull())) +	{ +		return; +	} +	 +	if (for_select) +	{ +		gGL.getTexUnit(0)->disable(); +	} +	else +	{ +		gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); +	} + +	LLGLState gls_blend(GL_BLEND, for_select ? FALSE : TRUE); +	LLGLState gls_alpha(GL_ALPHA_TEST, for_select ? FALSE : TRUE); +	 +	LLColor4 shadow_color(0.f, 0.f, 0.f, 1.f); +	F32 alpha_factor = 1.f; +	LLColor4 text_color = mColor; +	if (mDoFade) +	{ +		if (mLastDistance > mFadeDistance) +		{ +			alpha_factor = llmax(0.f, 1.f - (mLastDistance - mFadeDistance)/mFadeRange); +			text_color.mV[3] = text_color.mV[3]*alpha_factor; +		} +	} +	if (text_color.mV[3] < 0.01f) +	{ +		return; +	} +	shadow_color.mV[3] = text_color.mV[3]; + +	mOffsetY = lltrunc(mHeight * ((mVertAlignment == ALIGN_VERT_CENTER) ? 0.5f : 1.f)); + +	// *TODO: cache this image +	LLUIImagePtr imagep = LLUI::getUIImage("Rounded_Rect"); + +	// *TODO: make this a per-text setting +	LLColor4 bg_color = LLUIColorTable::instance().getColor("NameTagBackground"); +	bg_color.setAlpha(gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor); + +	// JAMESDEBUG - maybe a no-op +	//const S32 border_height = 16; +	//const S32 border_width = 16; +	const S32 border_height = 8; +	const S32 border_width = 8; + +	// *TODO move this into helper function +	F32 border_scale = 1.f; + +	if (border_height * 2 > mHeight) +	{ +		border_scale = (F32)mHeight / ((F32)border_height * 2.f); +	} +	if (border_width * 2 > mWidth) +	{ +		border_scale = llmin(border_scale, (F32)mWidth / ((F32)border_width * 2.f)); +	} + +	// scale screen size of borders down +	//RN: for now, text on hud objects is never occluded + +	LLVector3 x_pixel_vec; +	LLVector3 y_pixel_vec; +	 +	LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec); + +	LLVector2 border_scale_vec((F32)border_width / (F32)imagep->getTextureWidth(), (F32)border_height / (F32)imagep->getTextureHeight()); +	LLVector3 width_vec = mWidth * x_pixel_vec; +	LLVector3 height_vec = mHeight * y_pixel_vec; +	LLVector3 scaled_border_width = (F32)llfloor(border_scale * (F32)border_width) * x_pixel_vec; +	LLVector3 scaled_border_height = (F32)llfloor(border_scale * (F32)border_height) * y_pixel_vec; + +	mRadius = (width_vec + height_vec).magVec() * 0.5f; + +	LLCoordGL screen_pos; +	LLViewerCamera::getInstance()->projectPosAgentToScreen(mPositionAgent, screen_pos, FALSE); + +	LLVector2 screen_offset; +//	if (!mUseBubble) +//	{ +//		screen_offset = mPositionOffset; +//	} +//	else +//	{ +		screen_offset = updateScreenPos(mPositionOffset); +//	} + +	LLVector3 render_position = mPositionAgent   +			+ (x_pixel_vec * screen_offset.mV[VX]) +			+ (y_pixel_vec * screen_offset.mV[VY]); + +//	if (mUseBubble) +	{ +		LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); +		LLUI::pushMatrix(); +		{ +			LLVector3 bg_pos = render_position +				+ (F32)mOffsetY * y_pixel_vec +				- (width_vec / 2.f) +				- (height_vec); +			LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]); + +			if (for_select) +			{ +				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +				S32 name = mSourceObject->mGLName; +				LLColor4U coloru((U8)(name >> 16), (U8)(name >> 8), (U8)name); +				gGL.color4ubv(coloru.mV); +				gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec); +				LLUI::popMatrix(); +				return; +			} +			else +			{ +				gGL.getTexUnit(0)->bind(imagep->getImage()); +				 +				gGL.color4fv(bg_color.mV); +				gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec); +		 +				if ( mLabelSegments.size()) +				{ +					LLUI::pushMatrix(); +					{ +						gGL.color4f(text_color.mV[VX], text_color.mV[VY], text_color.mV[VZ], gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor); +						LLVector3 label_height = (mFontp->getLineHeight() * mLabelSegments.size() + (VERTICAL_PADDING / 3.f)) * y_pixel_vec; +						LLVector3 label_offset = height_vec - label_height; +						LLUI::translate(label_offset.mV[VX], label_offset.mV[VY], label_offset.mV[VZ]); +						gl_segmented_rect_3d_tex_top(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, label_height); +					} +					LLUI::popMatrix(); +				} +			} + +			BOOL outside_width = llabs(mPositionOffset.mV[VX]) > mWidth * 0.5f; +			BOOL outside_height = llabs(mPositionOffset.mV[VY] + (mVertAlignment == ALIGN_VERT_TOP ? mHeight * 0.5f : 0.f)) > mHeight * (mVertAlignment == ALIGN_VERT_TOP ? mHeight * 0.75f : 0.5f); + +			// draw line segments pointing to parent object +			if (!mOffscreen && (outside_width || outside_height)) +			{ +				LLUI::pushMatrix(); +				{ +					gGL.color4fv(bg_color.mV); +					LLVector3 target_pos = -1.f * (mPositionOffset.mV[VX] * x_pixel_vec + mPositionOffset.mV[VY] * y_pixel_vec); +					target_pos += (width_vec / 2.f); +					target_pos += mVertAlignment == ALIGN_VERT_CENTER ? (height_vec * 0.5f) : LLVector3::zero; +					target_pos -= 3.f * x_pixel_vec; +					target_pos -= 6.f * y_pixel_vec; +					LLUI::translate(target_pos.mV[VX], target_pos.mV[VY], target_pos.mV[VZ]); +					gl_segmented_rect_3d_tex(border_scale_vec, 3.f * x_pixel_vec, 3.f * y_pixel_vec, 6.f * x_pixel_vec, 6.f * y_pixel_vec);	 +				} +				LLUI::popMatrix(); + +				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +				LLGLDepthTest gls_depth(mZCompare ? GL_TRUE : GL_FALSE, GL_FALSE); +				 +				LLVector3 box_center_offset; +				box_center_offset = (width_vec * 0.5f) + (height_vec * 0.5f); +				LLUI::translate(box_center_offset.mV[VX], box_center_offset.mV[VY], box_center_offset.mV[VZ]); +				gGL.color4fv(bg_color.mV); +				LLUI::setLineWidth(2.0); +				gGL.begin(LLRender::LINES); +				{ +					if (outside_width) +					{ +						LLVector3 vert; +						// draw line in x then y +						if (mPositionOffset.mV[VX] < 0.f) +						{ +							// start at right edge +							vert = width_vec * 0.5f; +							gGL.vertex3fv(vert.mV); +						} +						else +						{ +							// start at left edge +							vert = width_vec * -0.5f; +							gGL.vertex3fv(vert.mV); +						} +						vert = -mPositionOffset.mV[VX] * x_pixel_vec; +						gGL.vertex3fv(vert.mV); +						gGL.vertex3fv(vert.mV); +						vert -= mPositionOffset.mV[VY] * y_pixel_vec; +						vert -= ((mVertAlignment == ALIGN_VERT_TOP) ? (height_vec * 0.5f) : LLVector3::zero); +						gGL.vertex3fv(vert.mV); +					} +					else +					{ +						LLVector3 vert; +						// draw line in y then x +						if (mPositionOffset.mV[VY] < 0.f) +						{ +							// start at top edge +							vert = (height_vec * 0.5f) - (mPositionOffset.mV[VX] * x_pixel_vec); +							gGL.vertex3fv(vert.mV); +						} +						else +						{ +							// start at bottom edge +							vert = (height_vec * -0.5f)  - (mPositionOffset.mV[VX] * x_pixel_vec); +							gGL.vertex3fv(vert.mV); +						} +						vert = -mPositionOffset.mV[VY] * y_pixel_vec - mPositionOffset.mV[VX] * x_pixel_vec; +						vert -= ((mVertAlignment == ALIGN_VERT_TOP) ? (height_vec * 0.5f) : LLVector3::zero); +						gGL.vertex3fv(vert.mV); +					} +				} +				gGL.end(); +				LLUI::setLineWidth(1.0); + +			} +		} +		LLUI::popMatrix(); +	} + +	F32 y_offset = (F32)mOffsetY; +		 +	// Render label +	{ +		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); + +		for(std::vector<LLHUDTextSegment>::iterator segment_iter = mLabelSegments.begin(); +			segment_iter != mLabelSegments.end(); ++segment_iter ) +		{ +			// Label segments use default font +			const LLFontGL* fontp = (segment_iter->mStyle == LLFontGL::BOLD) ? mBoldFontp : mFontp; +			y_offset -= fontp->getLineHeight(); + +			F32 x_offset; +			if (mTextAlignment == ALIGN_TEXT_CENTER) +			{ +				x_offset = -0.5f*segment_iter->getWidth(fontp); +			} +			else // ALIGN_LEFT +			{ +				x_offset = -0.5f * mWidth + (HORIZONTAL_PADDING / 2.f); +			} + +			LLColor4 label_color(0.f, 0.f, 0.f, 1.f); +			label_color.mV[VALPHA] = alpha_factor; +			hud_render_text(segment_iter->getText(), render_position, *fontp, segment_iter->mStyle, LLFontGL::NO_SHADOW, x_offset, y_offset, label_color, FALSE); +		} +	} + +	// Render text +	{ +		// -1 mMaxLines means unlimited lines. +		S32 start_segment; +		S32 max_lines = getMaxLines(); + +		if (max_lines < 0)  +		{ +			start_segment = 0; +		} +		else  +		{ +			start_segment = llmax((S32)0, (S32)mTextSegments.size() - max_lines); +		} + +		for (std::vector<LLHUDTextSegment>::iterator segment_iter = mTextSegments.begin() + start_segment; +			 segment_iter != mTextSegments.end(); ++segment_iter ) +		{ +			const LLFontGL* fontp = segment_iter->mFont; +			y_offset -= fontp->getLineHeight(); +			y_offset -= LINE_PADDING; + +			U8 style = segment_iter->mStyle; +			LLFontGL::ShadowType shadow = LLFontGL::DROP_SHADOW; +	 +			F32 x_offset; +			if (mTextAlignment== ALIGN_TEXT_CENTER) +			{ +				x_offset = -0.5f*segment_iter->getWidth(fontp); +			} +			else // ALIGN_LEFT +			{ +				x_offset = -0.5f * mWidth + (HORIZONTAL_PADDING / 2.f); + +				// JAMESDEBUG HACK +				x_offset += 1; +			} + +			text_color = segment_iter->mColor; +			text_color.mV[VALPHA] *= alpha_factor; + +			hud_render_text(segment_iter->getText(), render_position, *fontp, style, shadow, x_offset, y_offset, text_color, FALSE); +		} +	} +	/// Reset the default color to white.  The renderer expects this to be the default.  +	gGL.color4f(1.0f, 1.0f, 1.0f, 1.0f); +	if (for_select) +	{ +		gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); +	} +} + +void LLHUDNameTag::setString(const std::string &text_utf8) +{ +	mTextSegments.clear(); +	addLine(text_utf8, mColor); +} + +void LLHUDNameTag::clearString() +{ +	mTextSegments.clear(); +} + + +void LLHUDNameTag::addLine(const std::string &text_utf8, +						const LLColor4& color, +						const LLFontGL::StyleFlags style, +						const LLFontGL* font) +{ +	LLWString wline = utf8str_to_wstring(text_utf8); +	if (!wline.empty()) +	{ +		// use default font for segment if custom font not specified +		if (!font) +		{ +			font = mFontp; +		} +		typedef boost::tokenizer<boost::char_separator<llwchar>, LLWString::const_iterator, LLWString > tokenizer; +		LLWString seps(utf8str_to_wstring("\r\n")); +		boost::char_separator<llwchar> sep(seps.c_str()); + +		tokenizer tokens(wline, sep); +		tokenizer::iterator iter = tokens.begin(); + +		while (iter != tokens.end()) +		{ +			U32 line_length = 0; +			do	 +			{ +				F32 max_pixels = HUD_TEXT_MAX_WIDTH; +				S32 segment_length = font->maxDrawableChars(iter->substr(line_length).c_str(), max_pixels, wline.length(), LLFontGL::WORD_BOUNDARY_IF_POSSIBLE); +				LLHUDTextSegment segment(iter->substr(line_length, segment_length), style, color, font); +				mTextSegments.push_back(segment); +				line_length += segment_length; +			} +			while (line_length != iter->size()); +			++iter; +		} +	} +} + +void LLHUDNameTag::setLabel(const std::string &label_utf8) +{ +	mLabelSegments.clear(); +	addLabel(label_utf8); +} + +void LLHUDNameTag::addLabel(const std::string& label_utf8) +{ +	LLWString wstr = utf8string_to_wstring(label_utf8); +	if (!wstr.empty()) +	{ +		LLWString seps(utf8str_to_wstring("\r\n")); +		LLWString empty; + +		typedef boost::tokenizer<boost::char_separator<llwchar>, LLWString::const_iterator, LLWString > tokenizer; +		boost::char_separator<llwchar> sep(seps.c_str(), empty.c_str(), boost::keep_empty_tokens); + +		tokenizer tokens(wstr, sep); +		tokenizer::iterator iter = tokens.begin(); + +		while (iter != tokens.end()) +		{ +			U32 line_length = 0; +			do	 +			{ +				S32 segment_length = mFontp->maxDrawableChars(iter->substr(line_length).c_str(),  +					HUD_TEXT_MAX_WIDTH, wstr.length(), LLFontGL::WORD_BOUNDARY_IF_POSSIBLE); +				LLHUDTextSegment segment(iter->substr(line_length, segment_length), LLFontGL::NORMAL, mColor, mFontp); +				mLabelSegments.push_back(segment); +				line_length += segment_length; +			} +			while (line_length != iter->size()); +			++iter; +		} +	} +} + +void LLHUDNameTag::setZCompare(const BOOL zcompare) +{ +	mZCompare = zcompare; +} + +void LLHUDNameTag::setFont(const LLFontGL* font) +{ +	mFontp = font; +} + + +void LLHUDNameTag::setColor(const LLColor4 &color) +{ +	mColor = color; +	for (std::vector<LLHUDTextSegment>::iterator segment_iter = mTextSegments.begin(); +		 segment_iter != mTextSegments.end(); ++segment_iter ) +	{ +		segment_iter->mColor = color; +	} +} + +void LLHUDNameTag::setAlpha(F32 alpha) +{ +	mColor.mV[VALPHA] = alpha; +	for (std::vector<LLHUDTextSegment>::iterator segment_iter = mTextSegments.begin(); +		 segment_iter != mTextSegments.end(); ++segment_iter ) +	{ +		segment_iter->mColor.mV[VALPHA] = alpha; +	} +} + + +void LLHUDNameTag::setDoFade(const BOOL do_fade) +{ +	mDoFade = do_fade; +} + +void LLHUDNameTag::updateVisibility() +{ +	if (mSourceObject) +	{ +		mSourceObject->updateText(); +	} +	 +	mPositionAgent = gAgent.getPosAgentFromGlobal(mPositionGlobal); + +	if (!mSourceObject) +	{ +		//llwarns << "LLHUDNameTag::updateScreenPos -- mSourceObject is NULL!" << llendl; +		mVisible = TRUE; +		sVisibleTextObjects.push_back(LLPointer<LLHUDNameTag> (this)); +		return; +	} + +	// Not visible if parent object is dead +	if (mSourceObject->isDead()) +	{ +		mVisible = FALSE; +		return; +	} + +	// push text towards camera by radius of object, but not past camera +	LLVector3 vec_from_camera = mPositionAgent - LLViewerCamera::getInstance()->getOrigin(); +	LLVector3 dir_from_camera = vec_from_camera; +	dir_from_camera.normVec(); + +	if (dir_from_camera * LLViewerCamera::getInstance()->getAtAxis() <= 0.f) +	{ //text is behind camera, don't render +		mVisible = FALSE; +		return; +	} +		 +	if (vec_from_camera * LLViewerCamera::getInstance()->getAtAxis() <= LLViewerCamera::getInstance()->getNear() + 0.1f + mSourceObject->getVObjRadius()) +	{ +		mPositionAgent = LLViewerCamera::getInstance()->getOrigin() + vec_from_camera * ((LLViewerCamera::getInstance()->getNear() + 0.1f) / (vec_from_camera * LLViewerCamera::getInstance()->getAtAxis())); +	} +	else +	{ +		mPositionAgent -= dir_from_camera * mSourceObject->getVObjRadius(); +	} + +	mLastDistance = (mPositionAgent - LLViewerCamera::getInstance()->getOrigin()).magVec(); + +	if (mLOD >= 3 || !mTextSegments.size() || (mDoFade && (mLastDistance > mFadeDistance + mFadeRange))) +	{ +		mVisible = FALSE; +		return; +	} + +	LLVector3 x_pixel_vec; +	LLVector3 y_pixel_vec; + +	LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec); + +	LLVector3 render_position = mPositionAgent + 			 +			(x_pixel_vec * mPositionOffset.mV[VX]) + +			(y_pixel_vec * mPositionOffset.mV[VY]); + +	mOffscreen = FALSE; +	if (!LLViewerCamera::getInstance()->sphereInFrustum(render_position, mRadius)) +	{ +		if (!mVisibleOffScreen) +		{ +			mVisible = FALSE; +			return; +		} +		else +		{ +			mOffscreen = TRUE; +		} +	} + +	mVisible = TRUE; +	sVisibleTextObjects.push_back(LLPointer<LLHUDNameTag> (this)); +} + +LLVector2 LLHUDNameTag::updateScreenPos(LLVector2 &offset) +{ +	LLCoordGL screen_pos; +	LLVector2 screen_pos_vec; +	LLVector3 x_pixel_vec; +	LLVector3 y_pixel_vec; +	LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec); +	LLVector3 world_pos = mPositionAgent + (offset.mV[VX] * x_pixel_vec) + (offset.mV[VY] * y_pixel_vec); +	if (!LLViewerCamera::getInstance()->projectPosAgentToScreen(world_pos, screen_pos, FALSE) && mVisibleOffScreen) +	{ +		// bubble off-screen, so find a spot for it along screen edge +		LLViewerCamera::getInstance()->projectPosAgentToScreenEdge(world_pos, screen_pos); +	} + +	screen_pos_vec.setVec((F32)screen_pos.mX, (F32)screen_pos.mY); + +	LLRect world_rect = gViewerWindow->getWorldViewRectScaled(); +	S32 bottom = world_rect.mBottom + STATUS_BAR_HEIGHT; + +	LLVector2 screen_center; +	screen_center.mV[VX] = llclamp((F32)screen_pos_vec.mV[VX], (F32)world_rect.mLeft + mWidth * 0.5f, (F32)world_rect.mRight - mWidth * 0.5f); + +	if(mVertAlignment == ALIGN_VERT_TOP) +	{ +		screen_center.mV[VY] = llclamp((F32)screen_pos_vec.mV[VY],  +			(F32)bottom,  +			(F32)world_rect.mTop - mHeight - (F32)MENU_BAR_HEIGHT); +		mSoftScreenRect.setLeftTopAndSize(screen_center.mV[VX] - (mWidth + BUFFER_SIZE) * 0.5f,  +			screen_center.mV[VY] + (mHeight + BUFFER_SIZE), mWidth + BUFFER_SIZE, mHeight + BUFFER_SIZE); +	} +	else +	{ +		screen_center.mV[VY] = llclamp((F32)screen_pos_vec.mV[VY],  +			(F32)bottom + mHeight * 0.5f,  +			(F32)world_rect.mTop - mHeight * 0.5f - (F32)MENU_BAR_HEIGHT); +		mSoftScreenRect.setCenterAndSize(screen_center.mV[VX], screen_center.mV[VY], mWidth + BUFFER_SIZE, mHeight + BUFFER_SIZE); +	} + +	return offset + (screen_center - LLVector2((F32)screen_pos.mX, (F32)screen_pos.mY)); +} + +void LLHUDNameTag::updateSize() +{ +	F32 height = 0.f; +	F32 width = 0.f; + +	S32 max_lines = getMaxLines(); +	//S32 lines = (max_lines < 0) ? (S32)mTextSegments.size() : llmin((S32)mTextSegments.size(), max_lines); +	//F32 height = (F32)mFontp->getLineHeight() * (lines + mLabelSegments.size()); + +	S32 start_segment; +	if (max_lines < 0) start_segment = 0; +	else start_segment = llmax((S32)0, (S32)mTextSegments.size() - max_lines); + +	std::vector<LLHUDTextSegment>::iterator iter = mTextSegments.begin() + start_segment; +	while (iter != mTextSegments.end()) +	{ +		const LLFontGL* fontp = iter->mFont; +		height += fontp->getLineHeight(); +		height += LINE_PADDING; +		width = llmax(width, llmin(iter->getWidth(fontp), HUD_TEXT_MAX_WIDTH)); +		++iter; +	} + +	// Don't want line spacing under the last line +	if (height > 0.f) +	{ +		height -= LINE_PADDING; +	} + +	iter = mLabelSegments.begin(); +	while (iter != mLabelSegments.end()) +	{ +		height += mFontp->getLineHeight(); +		width = llmax(width, llmin(iter->getWidth(mFontp), HUD_TEXT_MAX_WIDTH)); +		++iter; +	} +	 +	if (width == 0.f) +	{ +		return; +	} + +	width += HORIZONTAL_PADDING; +	height += VERTICAL_PADDING; + +	// *TODO: Could do a timer-based resize here +	//mWidth = llmax(width, lerp(mWidth, (F32)width, u)); +	//mHeight = llmax(height, lerp(mHeight, (F32)height, u)); +	mWidth = width; +	mHeight = height; +} + +void LLHUDNameTag::updateAll() +{ +	// iterate over all text objects, calculate their restoration forces, +	// and add them to the visible set if they are on screen and close enough +	sVisibleTextObjects.clear(); +	 +	TextObjectIterator text_it; +	for (text_it = sTextObjects.begin(); text_it != sTextObjects.end(); ++text_it) +	{ +		LLHUDNameTag* textp = (*text_it); +		textp->mTargetPositionOffset.clearVec(); +		textp->updateSize(); +		textp->updateVisibility(); +	} +	 +	// sort back to front for rendering purposes +	std::sort(sVisibleTextObjects.begin(), sVisibleTextObjects.end(), llhudnametag_further_away()); + +	// iterate from front to back, and set LOD based on current screen coverage +	F32 screen_area = (F32)(gViewerWindow->getWindowWidthScaled() * gViewerWindow->getWindowHeightScaled()); +	F32 current_screen_area = 0.f; +	std::vector<LLPointer<LLHUDNameTag> >::reverse_iterator r_it; +	for (r_it = sVisibleTextObjects.rbegin(); r_it != sVisibleTextObjects.rend(); ++r_it) +	{ +		LLHUDNameTag* textp = (*r_it); +//		if (textp->mUseBubble) +//		{ +			if (current_screen_area / screen_area > LOD_2_SCREEN_COVERAGE) +			{ +				textp->setLOD(3); +			} +			else if (current_screen_area / screen_area > LOD_1_SCREEN_COVERAGE) +			{ +				textp->setLOD(2); +			} +			else if (current_screen_area / screen_area > LOD_0_SCREEN_COVERAGE) +			{ +				textp->setLOD(1); +			} +			else +			{ +				textp->setLOD(0); +			} +			textp->updateSize(); +			// find on-screen position and initialize collision rectangle +			textp->mTargetPositionOffset = textp->updateScreenPos(LLVector2::zero); +			current_screen_area += (F32)(textp->mSoftScreenRect.getWidth() * textp->mSoftScreenRect.getHeight()); +//		} +	} + +	LLStat* camera_vel_stat = LLViewerCamera::getInstance()->getVelocityStat(); +	F32 camera_vel = camera_vel_stat->getCurrent(); +	if (camera_vel > MAX_STABLE_CAMERA_VELOCITY) +	{ +		return; +	} + +	VisibleTextObjectIterator src_it; + +	for (S32 i = 0; i < NUM_OVERLAP_ITERATIONS; i++) +	{ +		for (src_it = sVisibleTextObjects.begin(); src_it != sVisibleTextObjects.end(); ++src_it) +		{ +			LLHUDNameTag* src_textp = (*src_it); + +//			if (!src_textp->mUseBubble) +//			{ +//				continue; +//			} +			VisibleTextObjectIterator dst_it = src_it; +			++dst_it; +			for (; dst_it != sVisibleTextObjects.end(); ++dst_it) +			{ +				LLHUDNameTag* dst_textp = (*dst_it); + +//				if (!dst_textp->mUseBubble) +//				{ +//					continue; +//				} +				if (src_textp->mSoftScreenRect.overlaps(dst_textp->mSoftScreenRect)) +				{ +					LLRectf intersect_rect = src_textp->mSoftScreenRect; +					intersect_rect.intersectWith(dst_textp->mSoftScreenRect); +					intersect_rect.stretch(-BUFFER_SIZE * 0.5f); +					 +					F32 src_center_x = src_textp->mSoftScreenRect.getCenterX(); +					F32 src_center_y = src_textp->mSoftScreenRect.getCenterY(); +					F32 dst_center_x = dst_textp->mSoftScreenRect.getCenterX(); +					F32 dst_center_y = dst_textp->mSoftScreenRect.getCenterY(); +					F32 intersect_center_x = intersect_rect.getCenterX(); +					F32 intersect_center_y = intersect_rect.getCenterY(); +					LLVector2 force = lerp(LLVector2(dst_center_x - intersect_center_x, dst_center_y - intersect_center_y),  +										LLVector2(intersect_center_x - src_center_x, intersect_center_y - src_center_y), +										0.5f); +					force.setVec(dst_center_x - src_center_x, dst_center_y - src_center_y); +					force.normVec(); + +					LLVector2 src_force = -1.f * force; +					LLVector2 dst_force = force; + +					LLVector2 force_strength; +					F32 src_mult = dst_textp->mMass / (dst_textp->mMass + src_textp->mMass);  +					F32 dst_mult = 1.f - src_mult; +					F32 src_aspect_ratio = src_textp->mSoftScreenRect.getWidth() / src_textp->mSoftScreenRect.getHeight(); +					F32 dst_aspect_ratio = dst_textp->mSoftScreenRect.getWidth() / dst_textp->mSoftScreenRect.getHeight(); +					src_force.mV[VY] *= src_aspect_ratio; +					src_force.normVec(); +					dst_force.mV[VY] *= dst_aspect_ratio; +					dst_force.normVec(); + +					src_force.mV[VX] *= llmin(intersect_rect.getWidth() * src_mult, intersect_rect.getHeight() * SPRING_STRENGTH); +					src_force.mV[VY] *= llmin(intersect_rect.getHeight() * src_mult, intersect_rect.getWidth() * SPRING_STRENGTH); +					dst_force.mV[VX] *=  llmin(intersect_rect.getWidth() * dst_mult, intersect_rect.getHeight() * SPRING_STRENGTH); +					dst_force.mV[VY] *=  llmin(intersect_rect.getHeight() * dst_mult, intersect_rect.getWidth() * SPRING_STRENGTH); +					 +					src_textp->mTargetPositionOffset += src_force; +					dst_textp->mTargetPositionOffset += dst_force; +					src_textp->mTargetPositionOffset = src_textp->updateScreenPos(src_textp->mTargetPositionOffset); +					dst_textp->mTargetPositionOffset = dst_textp->updateScreenPos(dst_textp->mTargetPositionOffset); +				} +			} +		} +	} + +	VisibleTextObjectIterator this_object_it; +	for (this_object_it = sVisibleTextObjects.begin(); this_object_it != sVisibleTextObjects.end(); ++this_object_it) +	{ +//		if (!(*this_object_it)->mUseBubble) +//		{ +//			continue; +//		} +		(*this_object_it)->mPositionOffset = lerp((*this_object_it)->mPositionOffset, (*this_object_it)->mTargetPositionOffset, LLCriticalDamp::getInterpolant(POSITION_DAMPING_TC)); +	} +} + +void LLHUDNameTag::setLOD(S32 lod) +{ +	mLOD = lod; +	//RN: uncomment this to visualize LOD levels +	//std::string label = llformat("%d", lod); +	//setLabel(label); +} + +S32 LLHUDNameTag::getMaxLines() +{ +	switch(mLOD) +	{ +	case 0: +		return mMaxLines; +	case 1: +		return mMaxLines > 0 ? mMaxLines / 2 : 5; +	case 2: +		return mMaxLines > 0 ? mMaxLines / 3 : 2; +	default: +		// label only +		return 0; +	} +} + +void LLHUDNameTag::markDead() +{ +	sTextObjects.erase(LLPointer<LLHUDNameTag>(this)); +	LLHUDObject::markDead(); +} + +void LLHUDNameTag::shiftAll(const LLVector3& offset) +{ +	TextObjectIterator text_it; +	for (text_it = sTextObjects.begin(); text_it != sTextObjects.end(); ++text_it) +	{ +		LLHUDNameTag *textp = text_it->get(); +		textp->shift(offset); +	} +} + +void LLHUDNameTag::shift(const LLVector3& offset) +{ +	mPositionAgent += offset; +} + +//static  +void LLHUDNameTag::addPickable(std::set<LLViewerObject*> &pick_list) +{ +	//this might put an object on the pick list a second time, overriding it's mGLName, which is ok +	// *FIX: we should probably cull against pick frustum +	VisibleTextObjectIterator text_it; +	for (text_it = sVisibleTextObjects.begin(); text_it != sVisibleTextObjects.end(); ++text_it) +	{ +//		if (!(*text_it)->mUseBubble) +//		{ +//			continue; +//		} +		pick_list.insert((*text_it)->mSourceObject); +	} +} + +//static +// called when UI scale changes, to flush font width caches +void LLHUDNameTag::reshape() +{ +	TextObjectIterator text_it; +	for (text_it = sTextObjects.begin(); text_it != sTextObjects.end(); ++text_it) +	{ +		LLHUDNameTag* textp = (*text_it); +		std::vector<LLHUDTextSegment>::iterator segment_iter;  +		for (segment_iter = textp->mTextSegments.begin(); +			 segment_iter != textp->mTextSegments.end(); ++segment_iter ) +		{ +			segment_iter->clearFontWidthMap(); +		} +		for(segment_iter = textp->mLabelSegments.begin(); +			segment_iter != textp->mLabelSegments.end(); ++segment_iter ) +		{ +			segment_iter->clearFontWidthMap(); +		}		 +	} +} + +//============================================================================ + +F32 LLHUDNameTag::LLHUDTextSegment::getWidth(const LLFontGL* font) +{ +	std::map<const LLFontGL*, F32>::iterator iter = mFontWidthMap.find(font); +	if (iter != mFontWidthMap.end()) +	{ +		return iter->second; +	} +	else +	{ +		F32 width = font->getWidthF32(mText.c_str()); +		mFontWidthMap[font] = width; +		return width; +	} +} diff --git a/indra/newview/llhudnametag.h b/indra/newview/llhudnametag.h new file mode 100644 index 0000000000..9a92307009 --- /dev/null +++ b/indra/newview/llhudnametag.h @@ -0,0 +1,191 @@ +/**  + * @file llhudnametag.h + * @brief Name tags for avatars + * @author James Cook + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + *  + * Copyright (c) 2002-2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LLHUDNAMETAG_H +#define LLHUDNAMETAG_H + +#include "llpointer.h" + +#include "llhudobject.h" +#include "v4color.h" +//#include "v4coloru.h" +#include "v2math.h" +#include "llrect.h" +//#include "llframetimer.h" +#include "llfontgl.h" +#include <set> +#include <vector> + +class LLDrawable; +class LLHUDNameTag; + +struct llhudnametag_further_away +{ +	bool operator()(const LLPointer<LLHUDNameTag>& lhs, const LLPointer<LLHUDNameTag>& rhs) const; +}; + +class LLHUDNameTag : public LLHUDObject +{ +protected: +	class LLHUDTextSegment +	{ +	public: +		LLHUDTextSegment(const LLWString& text, const LLFontGL::StyleFlags style, const LLColor4& color, const LLFontGL* font) +		:	mColor(color), +			mStyle(style), +			mText(text), +			mFont(font) +		{} +		F32 getWidth(const LLFontGL* font); +		const LLWString& getText() const { return mText; } +		void clearFontWidthMap() { mFontWidthMap.clear(); } +		 +		LLColor4				mColor; +		LLFontGL::StyleFlags	mStyle; +		const LLFontGL*			mFont; +	private: +		LLWString				mText; +		std::map<const LLFontGL*, F32> mFontWidthMap; +	}; + +public: +	typedef enum e_text_alignment +	{ +		ALIGN_TEXT_LEFT, +		ALIGN_TEXT_CENTER +	} ETextAlignment; + +	typedef enum e_vert_alignment +	{ +		ALIGN_VERT_TOP, +		ALIGN_VERT_CENTER +	} EVertAlignment; + +public: +	// Set entire string, eliminating existing lines +	void setString(const std::string& text_utf8); + +	void clearString(); + +	// Add text a line at a time, allowing custom formatting +	void addLine(const std::string &text_utf8, const LLColor4& color, const LLFontGL::StyleFlags style = LLFontGL::NORMAL, const LLFontGL* font = NULL); + +	// For bubble chat, set the part above the chat text +	void setLabel(const std::string& label_utf8); +	void addLabel(const std::string& label_utf8); + +	// Sets the default font for lines with no font specified +	void setFont(const LLFontGL* font); +	void setColor(const LLColor4 &color); +	void setAlpha(F32 alpha); +	void setZCompare(const BOOL zcompare); +	void setDoFade(const BOOL do_fade); +	void setVisibleOffScreen(BOOL visible) { mVisibleOffScreen = visible; } +	 +	// mMaxLines of -1 means unlimited lines. +	void setMaxLines(S32 max_lines) { mMaxLines = max_lines; } +	void setFadeDistance(F32 fade_distance, F32 fade_range) { mFadeDistance = fade_distance; mFadeRange = fade_range; } +	void updateVisibility(); +	LLVector2 updateScreenPos(LLVector2 &offset_target); +	void updateSize(); +//	void setMass(F32 mass) { mMass = llmax(0.1f, mass); } +	void setTextAlignment(ETextAlignment alignment) { mTextAlignment = alignment; } +	void setVertAlignment(EVertAlignment alignment) { mVertAlignment = alignment; } +	/*virtual*/ void markDead(); +	friend class LLHUDObject; +	/*virtual*/ F32 getDistance() const { return mLastDistance; } +	//void setUseBubble(BOOL use_bubble) { mUseBubble = use_bubble; } +	S32  getLOD() { return mLOD; } +	BOOL getVisible() { return mVisible; } +	BOOL getHidden() const { return mHidden; } +	void setHidden( BOOL hide ) { mHidden = hide; } +	void shift(const LLVector3& offset); + +	BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3& intersection, BOOL debug_render = FALSE); + +	static void shiftAll(const LLVector3& offset); +	static void addPickable(std::set<LLViewerObject*> &pick_list); +	static void reshape(); +	static void setDisplayText(BOOL flag) { sDisplayText = flag ; } + +protected: +	LLHUDNameTag(const U8 type); + +	/*virtual*/ void render(); +	/*virtual*/ void renderForSelect(); +	void renderText(BOOL for_select); +	static void updateAll(); +	void setLOD(S32 lod); +	S32 getMaxLines(); + +private: +	~LLHUDNameTag(); +	BOOL			mDoFade; +	F32				mFadeRange; +	F32				mFadeDistance; +	F32				mLastDistance; +	BOOL			mZCompare; +	BOOL			mVisibleOffScreen; +	BOOL			mOffscreen; +	LLColor4		mColor; +//	LLVector3		mScale; +	F32				mWidth; +	F32				mHeight; +//	LLColor4U		mPickColor; +	const LLFontGL*	mFontp; +	const LLFontGL*	mBoldFontp; +	LLRectf			mSoftScreenRect; +	LLVector3		mPositionAgent; +	LLVector2		mPositionOffset; +	LLVector2		mTargetPositionOffset; +	F32				mMass; +	S32				mMaxLines; +	S32				mOffsetY; +	F32				mRadius; +	std::vector<LLHUDTextSegment> mTextSegments; +	std::vector<LLHUDTextSegment> mLabelSegments; +//	LLFrameTimer	mResizeTimer; +	ETextAlignment	mTextAlignment; +	EVertAlignment	mVertAlignment; +	S32				mLOD; +	BOOL			mHidden; + +	static BOOL    sDisplayText ; +	static std::set<LLPointer<LLHUDNameTag> > sTextObjects; +	static std::vector<LLPointer<LLHUDNameTag> > sVisibleTextObjects; +//	static std::vector<LLPointer<LLHUDNameTag> > sVisibleHUDTextObjects; +	typedef std::set<LLPointer<LLHUDNameTag> >::iterator TextObjectIterator; +	typedef std::vector<LLPointer<LLHUDNameTag> >::iterator VisibleTextObjectIterator; +}; + +#endif diff --git a/indra/newview/llhudobject.cpp b/indra/newview/llhudobject.cpp index 2b73ed1dcd..d66ac6c5b2 100644 --- a/indra/newview/llhudobject.cpp +++ b/indra/newview/llhudobject.cpp @@ -30,9 +30,6 @@   * $/LicenseInfo$   */ -// llhudobject.cpp -// Copyright 2002, Linden Research, Inc. -  #include "llviewerprecompiledheaders.h"  #include "llhudobject.h" @@ -44,7 +41,7 @@  #include "llhudeffecttrail.h"  #include "llhudeffectlookat.h"  #include "llhudeffectpointat.h" - +#include "llhudnametag.h"  #include "llvoicevisualizer.h"  #include "llagent.h" @@ -72,7 +69,6 @@ LLHUDObject::LLHUDObject(const U8 type) :  	mVisible = TRUE;  	mType = type;  	mDead = FALSE; -	mOnHUDAttachment = FALSE;  }  LLHUDObject::~LLHUDObject() @@ -151,6 +147,9 @@ LLHUDObject *LLHUDObject::addHUDObject(const U8 type)  	case LL_HUD_ICON:  		hud_objectp = new LLHUDIcon(type);  		break; +	case LL_HUD_NAME_TAG: +		hud_objectp = new LLHUDNameTag(type); +		break;  	default:  		llwarns << "Unknown type of hud object:" << (U32) type << llendl;  	} @@ -263,6 +262,7 @@ void LLHUDObject::updateAll()  	LLFastTimer ftm(FTM_HUD_UPDATE);  	LLHUDText::updateAll();  	LLHUDIcon::updateAll(); +	LLHUDNameTag::updateAll();  	sortObjects();  } @@ -311,6 +311,14 @@ void LLHUDObject::renderAllForSelect()  }  // static +void LLHUDObject::reshapeAll() +{ +	// only hud objects that use fonts care about window size/scale changes +	LLHUDText::reshape(); +	LLHUDNameTag::reshape(); +} + +// static  void LLHUDObject::sortObjects()  {  	sHUDObjects.sort(hud_object_further_away());	 diff --git a/indra/newview/llhudobject.h b/indra/newview/llhudobject.h index d304ac41af..a370b31a20 100644 --- a/indra/newview/llhudobject.h +++ b/indra/newview/llhudobject.h @@ -42,7 +42,7 @@  #include "v4color.h"  #include "v3math.h"  #include "v3dmath.h" -#include "lldrawpool.h" +#include "lldrawpool.h"		// TODO: eliminate, unused below  #include <list>  class LLViewerCamera; @@ -76,6 +76,9 @@ public:  	static void renderAll();  	static void renderAllForSelect(); +	// Some objects may need to update when window shape changes +	static void reshapeAll(); +  	static void cleanupHUDObjects();  	enum @@ -96,7 +99,8 @@ public:  		LL_HUD_EFFECT_EDIT,  		LL_HUD_EFFECT_LOOKAT,  		LL_HUD_EFFECT_POINTAT, -		LL_HUD_EFFECT_VOICE_VISUALIZER	// Ventrella +		LL_HUD_EFFECT_VOICE_VISUALIZER,	// Ventrella +		LL_HUD_NAME_TAG  	};  protected:  	static void sortObjects(); @@ -112,7 +116,6 @@ protected:  	BOOL			mDead;  	BOOL			mVisible;  	LLVector3d		mPositionGlobal; -	BOOL			mOnHUDAttachment;  	LLPointer<LLViewerObject> mSourceObject;  	LLPointer<LLViewerObject> mTargetObject; diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp index 8d1d27444b..31522f6efb 100644 --- a/indra/newview/llhudtext.cpp +++ b/indra/newview/llhudtext.cpp @@ -1,7 +1,6 @@ -  /**    * @file llhudtext.cpp - * @brief LLHUDText class implementation + * @brief Floating text above objects, set via script with llSetText()   *   * $LicenseInfo:firstyear=2002&license=viewergpl$   *  @@ -62,16 +61,16 @@ const F32 HORIZONTAL_PADDING = 15.f;  const F32 VERTICAL_PADDING = 12.f;  const F32 BUFFER_SIZE = 2.f;  const F32 MIN_EDGE_OVERLAP = 3.f; -F32 HUD_TEXT_MAX_WIDTH = 190.f; +const F32 HUD_TEXT_MAX_WIDTH = 190.f;  const F32 HUD_TEXT_MAX_WIDTH_NO_BUBBLE = 1000.f;  const F32 RESIZE_TIME = 0.f;  const S32 NUM_OVERLAP_ITERATIONS = 10;  const F32 NEIGHBOR_FORCE_FRACTION = 1.f;  const F32 POSITION_DAMPING_TC = 0.2f;  const F32 MAX_STABLE_CAMERA_VELOCITY = 0.1f; -const F32 LOD_0_SCREEN_COVERAGE = 0.15f; -const F32 LOD_1_SCREEN_COVERAGE = 0.30f; -const F32 LOD_2_SCREEN_COVERAGE = 0.40f; +//const F32 LOD_0_SCREEN_COVERAGE = 0.15f; +//const F32 LOD_1_SCREEN_COVERAGE = 0.30f; +//const F32 LOD_2_SCREEN_COVERAGE = 0.40f;  std::set<LLPointer<LLHUDText> > LLHUDText::sTextObjects;  std::vector<LLPointer<LLHUDText> > LLHUDText::sVisibleTextObjects; @@ -80,15 +79,14 @@ BOOL LLHUDText::sDisplayText = TRUE ;  bool lltextobject_further_away::operator()(const LLPointer<LLHUDText>& lhs, const LLPointer<LLHUDText>& rhs) const  { -	return (lhs->getDistance() > rhs->getDistance()) ? true : false; +	return lhs->getDistance() > rhs->getDistance();  }  LLHUDText::LLHUDText(const U8 type) :  			LLHUDObject(type), -			mUseBubble(FALSE), -			mUsePixelSize(TRUE), -			mVisibleOffScreen(FALSE), +			mOnHUDAttachment(FALSE), +//			mVisibleOffScreen(FALSE),  			mWidth(0.f),  			mHeight(0.f),  			mFontp(LLFontGL::getFontSansSerifSmall()), @@ -98,7 +96,7 @@ LLHUDText::LLHUDText(const U8 type) :  			mOffsetY(0),  			mTextAlignment(ALIGN_TEXT_CENTER),  			mVertAlignment(ALIGN_VERT_CENTER), -			mLOD(0), +//			mLOD(0),  			mHidden(FALSE)  {  	mColor = LLColor4(1.f, 1.f, 1.f, 1.f); @@ -106,7 +104,6 @@ LLHUDText::LLHUDText(const U8 type) :  	mFadeDistance = 8.f;  	mFadeRange = 4.f;  	mZCompare = TRUE; -	mDropShadow = TRUE;  	mOffscreen = FALSE;  	mRadius = 0.1f;  	LLPointer<LLHUDText> ptr(this); @@ -117,112 +114,6 @@ LLHUDText::~LLHUDText()  {  } - -BOOL LLHUDText::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3& intersection, BOOL debug_render) -{ -	if (!mVisible || mHidden) -	{ -		return FALSE; -	} - -	// don't pick text that isn't bound to a viewerobject or isn't in a bubble -	if (!mSourceObject || mSourceObject->mDrawable.isNull() || !mUseBubble) -	{ -		return FALSE; -	} -	 -	F32 alpha_factor = 1.f; -	LLColor4 text_color = mColor; -	if (mDoFade) -	{ -		if (mLastDistance > mFadeDistance) -		{ -			alpha_factor = llmax(0.f, 1.f - (mLastDistance - mFadeDistance)/mFadeRange); -			text_color.mV[3] = text_color.mV[3]*alpha_factor; -		} -	} -	if (text_color.mV[3] < 0.01f) -	{ -		return FALSE; -	} - -	mOffsetY = lltrunc(mHeight * ((mVertAlignment == ALIGN_VERT_CENTER) ? 0.5f : 1.f)); - -	// scale screen size of borders down -	//RN: for now, text on hud objects is never occluded - -	LLVector3 x_pixel_vec; -	LLVector3 y_pixel_vec; -	 -	if (mOnHUDAttachment) -	{ -		x_pixel_vec = LLVector3::y_axis / (F32)gViewerWindow->getWindowWidthScaled(); -		y_pixel_vec = LLVector3::z_axis / (F32)gViewerWindow->getWindowHeightScaled(); -	} -	else -	{ -		LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec); -	} - -	LLVector3 width_vec = mWidth * x_pixel_vec; -	LLVector3 height_vec = mHeight * y_pixel_vec; -	 -	LLCoordGL screen_pos; -	LLViewerCamera::getInstance()->projectPosAgentToScreen(mPositionAgent, screen_pos, FALSE); - -	LLVector2 screen_offset; -	screen_offset = updateScreenPos(mPositionOffset); -	 -	LLVector3 render_position = mPositionAgent   -			+ (x_pixel_vec * screen_offset.mV[VX]) -			+ (y_pixel_vec * screen_offset.mV[VY]); - - -	if (mUseBubble) -	{ -		LLVector3 bg_pos = render_position -			+ (F32)mOffsetY * y_pixel_vec -			- (width_vec / 2.f) -			- (height_vec); -		//LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]); - -		LLVector3 v[] =  -		{ -			bg_pos, -			bg_pos + width_vec, -			bg_pos + width_vec + height_vec, -			bg_pos + height_vec, -		}; - -		if (debug_render) -		{ -			gGL.begin(LLRender::LINE_STRIP); -			gGL.vertex3fv(v[0].mV); -			gGL.vertex3fv(v[1].mV); -			gGL.vertex3fv(v[2].mV); -			gGL.vertex3fv(v[3].mV); -			gGL.vertex3fv(v[0].mV); -			gGL.vertex3fv(v[2].mV); -			gGL.end(); -		} - -		LLVector3 dir = end-start; -		F32 t = 0.f; - -		if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, NULL, NULL, &t, FALSE) || -			LLTriangleRayIntersect(v[2], v[3], v[0], start, dir, NULL, NULL, &t, FALSE) ) -		{ -			if (t <= 1.f) -			{ -				intersection = start + dir*t; -				return TRUE; -			} -		} -	} - -	return FALSE; -} -  void LLHUDText::render()  {  	if (!mOnHUDAttachment && sDisplayText) @@ -248,21 +139,13 @@ void LLHUDText::renderText(BOOL for_select)  		return;  	} -	// don't pick text that isn't bound to a viewerobject or isn't in a bubble -	if (for_select &&  -		(!mSourceObject || mSourceObject->mDrawable.isNull() || !mUseBubble)) +	// don't pick text +	if (for_select)  	{  		return;  	} -	if (for_select) -	{ -		gGL.getTexUnit(0)->disable(); -	} -	else -	{ -		gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); -	} +	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);  	LLGLState gls_blend(GL_BLEND, for_select ? FALSE : TRUE);  	LLGLState gls_alpha(GL_ALPHA_TEST, for_select ? FALSE : TRUE); @@ -290,7 +173,7 @@ void LLHUDText::renderText(BOOL for_select)  	LLUIImagePtr imagep = LLUI::getUIImage("Rounded_Square");  	// *TODO: make this a per-text setting -	LLColor4 bg_color = LLUIColorTable::instance().getColor("BackgroundChatColor"); +	LLColor4 bg_color = LLUIColorTable::instance().getColor("ObjectBubbleColor");  	bg_color.setAlpha(gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor);  	const S32 border_height = 16; @@ -336,178 +219,17 @@ void LLHUDText::renderText(BOOL for_select)  	LLViewerCamera::getInstance()->projectPosAgentToScreen(mPositionAgent, screen_pos, FALSE);  	LLVector2 screen_offset; -	if (!mUseBubble) -	{ -		screen_offset = mPositionOffset; -	} -	else -	{ -		screen_offset = updateScreenPos(mPositionOffset); -	} +	screen_offset = mPositionOffset;  	LLVector3 render_position = mPositionAgent    			+ (x_pixel_vec * screen_offset.mV[VX])  			+ (y_pixel_vec * screen_offset.mV[VY]); -	//if (mOnHUD) -	//{ -	//	render_position.mV[VY] -= fmodf(render_position.mV[VY], 1.f / (F32)gViewerWindow->getWindowWidthScaled()); -	//	render_position.mV[VZ] -= fmodf(render_position.mV[VZ], 1.f / (F32)gViewerWindow->getWindowHeightScaled()); -	//} -	//else -	//{ -	//	render_position = LLViewerCamera::getInstance()->roundToPixel(render_position); -	//} - -	if (mUseBubble) -	{ -		LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); -		LLUI::pushMatrix(); -		{ -			LLVector3 bg_pos = render_position -				+ (F32)mOffsetY * y_pixel_vec -				- (width_vec / 2.f) -				- (height_vec); -			LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]); - -			if (for_select) -			{ -				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); -				S32 name = mSourceObject->mGLName; -				LLColor4U coloru((U8)(name >> 16), (U8)(name >> 8), (U8)name); -				gGL.color4ubv(coloru.mV); -				gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec); -				LLUI::popMatrix(); -				return; -			} -			else -			{ -				gGL.getTexUnit(0)->bind(imagep->getImage()); -				 -				gGL.color4fv(bg_color.mV); -				gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec); -		 -				if ( mLabelSegments.size()) -				{ -					LLUI::pushMatrix(); -					{ -						gGL.color4f(text_color.mV[VX], text_color.mV[VY], text_color.mV[VZ], gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor); -						LLVector3 label_height = (mFontp->getLineHeight() * mLabelSegments.size() + (VERTICAL_PADDING / 3.f)) * y_pixel_vec; -						LLVector3 label_offset = height_vec - label_height; -						LLUI::translate(label_offset.mV[VX], label_offset.mV[VY], label_offset.mV[VZ]); -						gl_segmented_rect_3d_tex_top(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, label_height); -					} -					LLUI::popMatrix(); -				} -			} - -			BOOL outside_width = llabs(mPositionOffset.mV[VX]) > mWidth * 0.5f; -			BOOL outside_height = llabs(mPositionOffset.mV[VY] + (mVertAlignment == ALIGN_VERT_TOP ? mHeight * 0.5f : 0.f)) > mHeight * (mVertAlignment == ALIGN_VERT_TOP ? mHeight * 0.75f : 0.5f); - -			// draw line segments pointing to parent object -			if (!mOffscreen && (outside_width || outside_height)) -			{ -				LLUI::pushMatrix(); -				{ -					gGL.color4fv(bg_color.mV); -					LLVector3 target_pos = -1.f * (mPositionOffset.mV[VX] * x_pixel_vec + mPositionOffset.mV[VY] * y_pixel_vec); -					target_pos += (width_vec / 2.f); -					target_pos += mVertAlignment == ALIGN_VERT_CENTER ? (height_vec * 0.5f) : LLVector3::zero; -					target_pos -= 3.f * x_pixel_vec; -					target_pos -= 6.f * y_pixel_vec; -					LLUI::translate(target_pos.mV[VX], target_pos.mV[VY], target_pos.mV[VZ]); -					gl_segmented_rect_3d_tex(border_scale_vec, 3.f * x_pixel_vec, 3.f * y_pixel_vec, 6.f * x_pixel_vec, 6.f * y_pixel_vec);	 -				} -				LLUI::popMatrix(); - -				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); -				LLGLDepthTest gls_depth(mZCompare ? GL_TRUE : GL_FALSE, GL_FALSE); -				 -				LLVector3 box_center_offset; -				box_center_offset = (width_vec * 0.5f) + (height_vec * 0.5f); -				LLUI::translate(box_center_offset.mV[VX], box_center_offset.mV[VY], box_center_offset.mV[VZ]); -				gGL.color4fv(bg_color.mV); -				LLUI::setLineWidth(2.0); -				gGL.begin(LLRender::LINES); -				{ -					if (outside_width) -					{ -						LLVector3 vert; -						// draw line in x then y -						if (mPositionOffset.mV[VX] < 0.f) -						{ -							// start at right edge -							vert = width_vec * 0.5f; -							gGL.vertex3fv(vert.mV); -						} -						else -						{ -							// start at left edge -							vert = width_vec * -0.5f; -							gGL.vertex3fv(vert.mV); -						} -						vert = -mPositionOffset.mV[VX] * x_pixel_vec; -						gGL.vertex3fv(vert.mV); -						gGL.vertex3fv(vert.mV); -						vert -= mPositionOffset.mV[VY] * y_pixel_vec; -						vert -= ((mVertAlignment == ALIGN_VERT_TOP) ? (height_vec * 0.5f) : LLVector3::zero); -						gGL.vertex3fv(vert.mV); -					} -					else -					{ -						LLVector3 vert; -						// draw line in y then x -						if (mPositionOffset.mV[VY] < 0.f) -						{ -							// start at top edge -							vert = (height_vec * 0.5f) - (mPositionOffset.mV[VX] * x_pixel_vec); -							gGL.vertex3fv(vert.mV); -						} -						else -						{ -							// start at bottom edge -							vert = (height_vec * -0.5f)  - (mPositionOffset.mV[VX] * x_pixel_vec); -							gGL.vertex3fv(vert.mV); -						} -						vert = -mPositionOffset.mV[VY] * y_pixel_vec - mPositionOffset.mV[VX] * x_pixel_vec; -						vert -= ((mVertAlignment == ALIGN_VERT_TOP) ? (height_vec * 0.5f) : LLVector3::zero); -						gGL.vertex3fv(vert.mV); -					} -				} -				gGL.end(); -				LLUI::setLineWidth(1.0); - -			} -		} -		LLUI::popMatrix(); -	} -  	F32 y_offset = (F32)mOffsetY;  	// Render label  	{  		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); - -		for(std::vector<LLHUDTextSegment>::iterator segment_iter = mLabelSegments.begin(); -			segment_iter != mLabelSegments.end(); ++segment_iter ) -		{ -			const LLFontGL* fontp = (segment_iter->mStyle == LLFontGL::BOLD) ? mBoldFontp : mFontp; -			y_offset -= fontp->getLineHeight(); - -			F32 x_offset; -			if (mTextAlignment == ALIGN_TEXT_CENTER) -			{ -				x_offset = -0.5f*segment_iter->getWidth(fontp); -			} -			else // ALIGN_LEFT -			{ -				x_offset = -0.5f * mWidth + (HORIZONTAL_PADDING / 2.f); -			} - -			LLColor4 label_color(0.f, 0.f, 0.f, 1.f); -			label_color.mV[VALPHA] = alpha_factor; -			hud_render_text(segment_iter->getText(), render_position, *fontp, segment_iter->mStyle, LLFontGL::NO_SHADOW, x_offset, y_offset, label_color, mOnHUDAttachment); -		}  	}  	// Render text @@ -528,15 +250,11 @@ void LLHUDText::renderText(BOOL for_select)  		for (std::vector<LLHUDTextSegment>::iterator segment_iter = mTextSegments.begin() + start_segment;  			 segment_iter != mTextSegments.end(); ++segment_iter )  		{ -			const LLFontGL* fontp = (segment_iter->mStyle == LLFontGL::BOLD) ? mBoldFontp : mFontp; +			const LLFontGL* fontp = segment_iter->mFont;  			y_offset -= fontp->getLineHeight();  			U8 style = segment_iter->mStyle; -			LLFontGL::ShadowType shadow = LLFontGL::NO_SHADOW; -			if (mDropShadow) -			{ -				shadow = LLFontGL::DROP_SHADOW; -			} +			LLFontGL::ShadowType shadow = LLFontGL::DROP_SHADOW;  			F32 x_offset;  			if (mTextAlignment== ALIGN_TEXT_CENTER) @@ -556,21 +274,12 @@ void LLHUDText::renderText(BOOL for_select)  	}  	/// Reset the default color to white.  The renderer expects this to be the default.   	gGL.color4f(1.0f, 1.0f, 1.0f, 1.0f); -	if (for_select) -	{ -		gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); -	} -} - -void LLHUDText::setStringUTF8(const std::string &wtext) -{ -	setString(utf8str_to_wstring(wtext));  } -void LLHUDText::setString(const LLWString &wtext) +void LLHUDText::setString(const std::string &text_utf8)  {  	mTextSegments.clear(); -	addLine(wtext, mColor); +	addLine(text_utf8, mColor);  }  void LLHUDText::clearString() @@ -579,21 +288,19 @@ void LLHUDText::clearString()  } -void LLHUDText::addLine(const std::string &str, const LLColor4& color, const LLFontGL::StyleFlags style) +void LLHUDText::addLine(const std::string &text_utf8, +						const LLColor4& color, +						const LLFontGL::StyleFlags style, +						const LLFontGL* font)  { -	addLine(utf8str_to_wstring(str), color, style); -} - - -void LLHUDText::addLine(const LLWString &wstr, const LLColor4& color, const LLFontGL::StyleFlags style) -{ -	if (gNoRender) -	{ -		return; -	} -	if (!wstr.empty()) +	LLWString wline = utf8str_to_wstring(text_utf8); +	if (!wline.empty())  	{ -		LLWString wline(wstr); +		// use default font for segment if custom font not specified +		if (!font) +		{ +			font = mFontp; +		}  		typedef boost::tokenizer<boost::char_separator<llwchar>, LLWString::const_iterator, LLWString > tokenizer;  		LLWString seps(utf8str_to_wstring("\r\n"));  		boost::char_separator<llwchar> sep(seps.c_str()); @@ -606,8 +313,10 @@ void LLHUDText::addLine(const LLWString &wstr, const LLColor4& color, const LLFo  			U32 line_length = 0;  			do	  			{ -				S32 segment_length = mFontp->maxDrawableChars(iter->substr(line_length).c_str(), mUseBubble ? HUD_TEXT_MAX_WIDTH : HUD_TEXT_MAX_WIDTH_NO_BUBBLE, wline.length(), LLFontGL::WORD_BOUNDARY_IF_POSSIBLE); -				mTextSegments.push_back(LLHUDTextSegment(iter->substr(line_length, segment_length), style, color)); +				F32 max_pixels = HUD_TEXT_MAX_WIDTH_NO_BUBBLE; +				S32 segment_length = font->maxDrawableChars(iter->substr(line_length).c_str(), max_pixels, wline.length(), LLFontGL::WORD_BOUNDARY_IF_POSSIBLE); +				LLHUDTextSegment segment(iter->substr(line_length, segment_length), style, color, font); +				mTextSegments.push_back(segment);  				line_length += segment_length;  			}  			while (line_length != iter->size()); @@ -616,47 +325,6 @@ void LLHUDText::addLine(const LLWString &wstr, const LLColor4& color, const LLFo  	}  } -void LLHUDText::setLabel(const std::string &label) -{ -	setLabel(utf8str_to_wstring(label)); -} - -void LLHUDText::setLabel(const LLWString &wlabel) -{ -	mLabelSegments.clear(); - -	if (!wlabel.empty()) -	{ -		LLWString wstr(wlabel); -		LLWString seps(utf8str_to_wstring("\r\n")); -		LLWString empty; - -		typedef boost::tokenizer<boost::char_separator<llwchar>, LLWString::const_iterator, LLWString > tokenizer; -		boost::char_separator<llwchar> sep(seps.c_str(), empty.c_str(), boost::keep_empty_tokens); - -		tokenizer tokens(wstr, sep); -		tokenizer::iterator iter = tokens.begin(); - -		while (iter != tokens.end()) -		{ -			U32 line_length = 0; -			do	 -			{ -				S32 segment_length = mFontp->maxDrawableChars(iter->substr(line_length).c_str(), mUseBubble ? HUD_TEXT_MAX_WIDTH : HUD_TEXT_MAX_WIDTH_NO_BUBBLE, wstr.length(), LLFontGL::WORD_BOUNDARY_IF_POSSIBLE); -				mLabelSegments.push_back(LLHUDTextSegment(iter->substr(line_length, segment_length), LLFontGL::NORMAL, mColor)); -				line_length += segment_length; -			} -			while (line_length != iter->size()); -			++iter; -		} -	} -} - -void LLHUDText::setDropShadow(const BOOL do_shadow) -{ -	mDropShadow = do_shadow; -} -  void LLHUDText::setZCompare(const BOOL zcompare)  {  	mZCompare = zcompare; @@ -678,12 +346,17 @@ void LLHUDText::setColor(const LLColor4 &color)  	}  } - -void LLHUDText::setUsePixelSize(const BOOL use_pixel_size) +void LLHUDText::setAlpha(F32 alpha)  { -	mUsePixelSize = use_pixel_size; +	mColor.mV[VALPHA] = alpha; +	for (std::vector<LLHUDTextSegment>::iterator segment_iter = mTextSegments.begin(); +		 segment_iter != mTextSegments.end(); ++segment_iter ) +	{ +		segment_iter->mColor.mV[VALPHA] = alpha; +	}  } +  void LLHUDText::setDoFade(const BOOL do_fade)  {  	mDoFade = do_fade; @@ -751,7 +424,7 @@ void LLHUDText::updateVisibility()  	mLastDistance = (mPositionAgent - LLViewerCamera::getInstance()->getOrigin()).magVec(); -	if (mLOD >= 3 || !mTextSegments.size() || (mDoFade && (mLastDistance > mFadeDistance + mFadeRange))) +	if (!mTextSegments.size() || (mDoFade && (mLastDistance > mFadeDistance + mFadeRange)))  	{  		mVisible = FALSE;  		return; @@ -769,15 +442,15 @@ void LLHUDText::updateVisibility()  	mOffscreen = FALSE;  	if (!LLViewerCamera::getInstance()->sphereInFrustum(render_position, mRadius))  	{ -		if (!mVisibleOffScreen) -		{ +//		if (!mVisibleOffScreen) +//		{  			mVisible = FALSE;  			return; -		} -		else -		{ -			mOffscreen = TRUE; -		} +//		} +//		else +//		{ +//			mOffscreen = TRUE; +//		}  	}  	mVisible = TRUE; @@ -792,11 +465,11 @@ LLVector2 LLHUDText::updateScreenPos(LLVector2 &offset)  	LLVector3 y_pixel_vec;  	LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec);  	LLVector3 world_pos = mPositionAgent + (offset.mV[VX] * x_pixel_vec) + (offset.mV[VY] * y_pixel_vec); -	if (!LLViewerCamera::getInstance()->projectPosAgentToScreen(world_pos, screen_pos, FALSE) && mVisibleOffScreen) -	{ -		// bubble off-screen, so find a spot for it along screen edge -		LLViewerCamera::getInstance()->projectPosAgentToScreenEdge(world_pos, screen_pos); -	} +//	if (!LLViewerCamera::getInstance()->projectPosAgentToScreen(world_pos, screen_pos, FALSE) && mVisibleOffScreen) +//	{ +//		// bubble off-screen, so find a spot for it along screen edge +//		LLViewerCamera::getInstance()->projectPosAgentToScreenEdge(world_pos, screen_pos); +//	}  	screen_pos_vec.setVec((F32)screen_pos.mX, (F32)screen_pos.mY); @@ -827,12 +500,12 @@ LLVector2 LLHUDText::updateScreenPos(LLVector2 &offset)  void LLHUDText::updateSize()  { +	F32 height = 0.f;  	F32 width = 0.f;  	S32 max_lines = getMaxLines(); -	S32 lines = (max_lines < 0) ? (S32)mTextSegments.size() : llmin((S32)mTextSegments.size(), max_lines); - -	F32 height = (F32)mFontp->getLineHeight() * (lines + mLabelSegments.size()); +	//S32 lines = (max_lines < 0) ? (S32)mTextSegments.size() : llmin((S32)mTextSegments.size(), max_lines); +	//F32 height = (F32)mFontp->getLineHeight() * (lines + mLabelSegments.size());  	S32 start_segment;  	if (max_lines < 0) start_segment = 0; @@ -841,17 +514,12 @@ void LLHUDText::updateSize()  	std::vector<LLHUDTextSegment>::iterator iter = mTextSegments.begin() + start_segment;  	while (iter != mTextSegments.end())  	{ -		width = llmax(width, llmin(iter->getWidth(mFontp), HUD_TEXT_MAX_WIDTH)); +		const LLFontGL* fontp = iter->mFont; +		height += fontp->getLineHeight(); +		width = llmax(width, llmin(iter->getWidth(fontp), HUD_TEXT_MAX_WIDTH));  		++iter;  	} -	iter = mLabelSegments.begin(); -	while (iter != mLabelSegments.end()) -	{ -		width = llmax(width, llmin(iter->getWidth(mFontp), HUD_TEXT_MAX_WIDTH)); -		++iter; -	} -	  	if (width == 0.f)  	{  		return; @@ -860,18 +528,8 @@ void LLHUDText::updateSize()  	width += HORIZONTAL_PADDING;  	height += VERTICAL_PADDING; -	if (!mResizeTimer.getStarted() && (width != mWidth || height != mHeight)) -	{ -		mResizeTimer.start(); -	} - -	// *NOTE: removed logic which did a divide by zero. -	F32 u = 1.f;//llclamp(mResizeTimer.getElapsedTimeF32() / RESIZE_TIME, 0.f, 1.f); -	if (u == 1.f) -	{ -		mResizeTimer.stop(); -	} - +	// *TODO: Could do some sort of timer-based resize logic here +	F32 u = 1.f;  	mWidth = llmax(width, lerp(mWidth, (F32)width, u));  	mHeight = llmax(height, lerp(mHeight, (F32)height, u));  } @@ -895,146 +553,31 @@ void LLHUDText::updateAll()  	// sort back to front for rendering purposes  	std::sort(sVisibleTextObjects.begin(), sVisibleTextObjects.end(), lltextobject_further_away());  	std::sort(sVisibleHUDTextObjects.begin(), sVisibleHUDTextObjects.end(), lltextobject_further_away()); - -	// iterate from front to back, and set LOD based on current screen coverage -	F32 screen_area = (F32)(gViewerWindow->getWindowWidthScaled() * gViewerWindow->getWindowHeightScaled()); -	F32 current_screen_area = 0.f; -	std::vector<LLPointer<LLHUDText> >::reverse_iterator r_it; -	for (r_it = sVisibleTextObjects.rbegin(); r_it != sVisibleTextObjects.rend(); ++r_it) -	{ -		LLHUDText* textp = (*r_it); -		if (textp->mUseBubble) -		{ -			if (current_screen_area / screen_area > LOD_2_SCREEN_COVERAGE) -			{ -				textp->setLOD(3); -			} -			else if (current_screen_area / screen_area > LOD_1_SCREEN_COVERAGE) -			{ -				textp->setLOD(2); -			} -			else if (current_screen_area / screen_area > LOD_0_SCREEN_COVERAGE) -			{ -				textp->setLOD(1); -			} -			else -			{ -				textp->setLOD(0); -			} -			textp->updateSize(); -			// find on-screen position and initialize collision rectangle -			textp->mTargetPositionOffset = textp->updateScreenPos(LLVector2::zero); -			current_screen_area += (F32)(textp->mSoftScreenRect.getWidth() * textp->mSoftScreenRect.getHeight()); -		} -	} - -	LLStat* camera_vel_stat = LLViewerCamera::getInstance()->getVelocityStat(); -	F32 camera_vel = camera_vel_stat->getCurrent(); -	if (camera_vel > MAX_STABLE_CAMERA_VELOCITY) -	{ -		return; -	} - -	VisibleTextObjectIterator src_it; - -	for (S32 i = 0; i < NUM_OVERLAP_ITERATIONS; i++) -	{ -		for (src_it = sVisibleTextObjects.begin(); src_it != sVisibleTextObjects.end(); ++src_it) -		{ -			LLHUDText* src_textp = (*src_it); - -			if (!src_textp->mUseBubble) -			{ -				continue; -			} -			VisibleTextObjectIterator dst_it = src_it; -			++dst_it; -			for (; dst_it != sVisibleTextObjects.end(); ++dst_it) -			{ -				LLHUDText* dst_textp = (*dst_it); - -				if (!dst_textp->mUseBubble) -				{ -					continue; -				} -				if (src_textp->mSoftScreenRect.overlaps(dst_textp->mSoftScreenRect)) -				{ -					LLRectf intersect_rect = src_textp->mSoftScreenRect; -					intersect_rect.intersectWith(dst_textp->mSoftScreenRect); -					intersect_rect.stretch(-BUFFER_SIZE * 0.5f); -					 -					F32 src_center_x = src_textp->mSoftScreenRect.getCenterX(); -					F32 src_center_y = src_textp->mSoftScreenRect.getCenterY(); -					F32 dst_center_x = dst_textp->mSoftScreenRect.getCenterX(); -					F32 dst_center_y = dst_textp->mSoftScreenRect.getCenterY(); -					F32 intersect_center_x = intersect_rect.getCenterX(); -					F32 intersect_center_y = intersect_rect.getCenterY(); -					LLVector2 force = lerp(LLVector2(dst_center_x - intersect_center_x, dst_center_y - intersect_center_y),  -										LLVector2(intersect_center_x - src_center_x, intersect_center_y - src_center_y), -										0.5f); -					force.setVec(dst_center_x - src_center_x, dst_center_y - src_center_y); -					force.normVec(); - -					LLVector2 src_force = -1.f * force; -					LLVector2 dst_force = force; - -					LLVector2 force_strength; -					F32 src_mult = dst_textp->mMass / (dst_textp->mMass + src_textp->mMass);  -					F32 dst_mult = 1.f - src_mult; -					F32 src_aspect_ratio = src_textp->mSoftScreenRect.getWidth() / src_textp->mSoftScreenRect.getHeight(); -					F32 dst_aspect_ratio = dst_textp->mSoftScreenRect.getWidth() / dst_textp->mSoftScreenRect.getHeight(); -					src_force.mV[VY] *= src_aspect_ratio; -					src_force.normVec(); -					dst_force.mV[VY] *= dst_aspect_ratio; -					dst_force.normVec(); - -					src_force.mV[VX] *= llmin(intersect_rect.getWidth() * src_mult, intersect_rect.getHeight() * SPRING_STRENGTH); -					src_force.mV[VY] *= llmin(intersect_rect.getHeight() * src_mult, intersect_rect.getWidth() * SPRING_STRENGTH); -					dst_force.mV[VX] *=  llmin(intersect_rect.getWidth() * dst_mult, intersect_rect.getHeight() * SPRING_STRENGTH); -					dst_force.mV[VY] *=  llmin(intersect_rect.getHeight() * dst_mult, intersect_rect.getWidth() * SPRING_STRENGTH); -					 -					src_textp->mTargetPositionOffset += src_force; -					dst_textp->mTargetPositionOffset += dst_force; -					src_textp->mTargetPositionOffset = src_textp->updateScreenPos(src_textp->mTargetPositionOffset); -					dst_textp->mTargetPositionOffset = dst_textp->updateScreenPos(dst_textp->mTargetPositionOffset); -				} -			} -		} -	} - -	VisibleTextObjectIterator this_object_it; -	for (this_object_it = sVisibleTextObjects.begin(); this_object_it != sVisibleTextObjects.end(); ++this_object_it) -	{ -		if (!(*this_object_it)->mUseBubble) -		{ -			continue; -		} -		(*this_object_it)->mPositionOffset = lerp((*this_object_it)->mPositionOffset, (*this_object_it)->mTargetPositionOffset, LLCriticalDamp::getInterpolant(POSITION_DAMPING_TC)); -	}  } -void LLHUDText::setLOD(S32 lod) -{ -	mLOD = lod; -	//RN: uncomment this to visualize LOD levels -	//std::string label = llformat("%d", lod); -	//setLabel(label); -} +//void LLHUDText::setLOD(S32 lod) +//{ +//	mLOD = lod; +//	//RN: uncomment this to visualize LOD levels +//	//std::string label = llformat("%d", lod); +//	//setLabel(label); +//}  S32 LLHUDText::getMaxLines()  { -	switch(mLOD) -	{ -	case 0: -		return mMaxLines; -	case 1: -		return mMaxLines > 0 ? mMaxLines / 2 : 5; -	case 2: -		return mMaxLines > 0 ? mMaxLines / 3 : 2; -	default: -		// label only -		return 0; -	} +	return mMaxLines; +	//switch(mLOD) +	//{ +	//case 0: +	//	return mMaxLines; +	//case 1: +	//	return mMaxLines > 0 ? mMaxLines / 2 : 5; +	//case 2: +	//	return mMaxLines > 0 ? mMaxLines / 3 : 2; +	//default: +	//	// label only +	//	return 0; +	//}  }  void LLHUDText::markDead() @@ -1085,22 +628,6 @@ void LLHUDText::shift(const LLVector3& offset)  	mPositionAgent += offset;  } -//static  -void LLHUDText::addPickable(std::set<LLViewerObject*> &pick_list) -{ -	//this might put an object on the pick list a second time, overriding it's mGLName, which is ok -	// *FIX: we should probably cull against pick frustum -	VisibleTextObjectIterator text_it; -	for (text_it = sVisibleTextObjects.begin(); text_it != sVisibleTextObjects.end(); ++text_it) -	{ -		if (!(*text_it)->mUseBubble) -		{ -			continue; -		} -		pick_list.insert((*text_it)->mSourceObject); -	} -} -  //static  // called when UI scale changes, to flush font width caches  void LLHUDText::reshape() @@ -1115,11 +642,6 @@ void LLHUDText::reshape()  		{  			segment_iter->clearFontWidthMap();  		} -		for(segment_iter = textp->mLabelSegments.begin(); -			segment_iter != textp->mLabelSegments.end(); ++segment_iter ) -		{ -			segment_iter->clearFontWidthMap(); -		}		  	}  } diff --git a/indra/newview/llhudtext.h b/indra/newview/llhudtext.h index dc14a8c764..27b8f07cca 100644 --- a/indra/newview/llhudtext.h +++ b/indra/newview/llhudtext.h @@ -34,18 +34,15 @@  #define LL_LLHUDTEXT_H  #include "llpointer.h" -#include "lldarrayptr.h"  #include "llhudobject.h"  #include "v4color.h"  #include "v4coloru.h"  #include "v2math.h"  #include "llrect.h" -#include "llframetimer.h"  #include "llfontgl.h"  #include <set>  #include <vector> -#include "lldarray.h"  // Renders a 2D text billboard floating at the location specified.  class LLDrawable; @@ -62,14 +59,19 @@ protected:  	class LLHUDTextSegment  	{  	public: -		LLHUDTextSegment(const LLWString& text, const LLFontGL::StyleFlags style, const LLColor4& color) -			: mColor(color), mStyle(style), mText(text) {} +		LLHUDTextSegment(const LLWString& text, const LLFontGL::StyleFlags style, const LLColor4& color, const LLFontGL* font) +		:	mColor(color), +			mStyle(style), +			mText(text), +			mFont(font) +		{}  		F32 getWidth(const LLFontGL* font); -		const LLWString& getText() const { return mText; }; +		const LLWString& getText() const { return mText; }  		void clearFontWidthMap() { mFontWidthMap.clear(); }  		LLColor4				mColor;  		LLFontGL::StyleFlags	mStyle; +		const LLFontGL*			mFont;  	private:  		LLWString				mText;  		std::map<const LLFontGL*, F32> mFontWidthMap; @@ -89,20 +91,21 @@ public:  	} EVertAlignment;  public: -	void setStringUTF8(const std::string &utf8string); -	void setString(const LLWString &wstring); +	// Set entire string, eliminating existing lines +	void setString(const std::string& text_utf8); +  	void clearString(); -	void addLine(const std::string &text, const LLColor4& color, const LLFontGL::StyleFlags style = LLFontGL::NORMAL); -	void addLine(const LLWString &wtext, const LLColor4& color, const LLFontGL::StyleFlags style = LLFontGL::NORMAL); -	void setLabel(const std::string &label); -	void setLabel(const LLWString &label); -	void setDropShadow(const BOOL do_shadow); + +	// Add text a line at a time, allowing custom formatting +	void addLine(const std::string &text_utf8, const LLColor4& color, const LLFontGL::StyleFlags style = LLFontGL::NORMAL, const LLFontGL* font = NULL); + +	// Sets the default font for lines with no font specified  	void setFont(const LLFontGL* font);  	void setColor(const LLColor4 &color); -	void setUsePixelSize(const BOOL use_pixel_size); +	void setAlpha(F32 alpha);  	void setZCompare(const BOOL zcompare);  	void setDoFade(const BOOL do_fade); -	void setVisibleOffScreen(BOOL visible) { mVisibleOffScreen = visible; } +//	void setVisibleOffScreen(BOOL visible) { mVisibleOffScreen = visible; }  	// mMaxLines of -1 means unlimited lines.  	void setMaxLines(S32 max_lines) { mMaxLines = max_lines; } @@ -116,21 +119,17 @@ public:  	/*virtual*/ void markDead();  	friend class LLHUDObject;  	/*virtual*/ F32 getDistance() const { return mLastDistance; } -	void setUseBubble(BOOL use_bubble) { mUseBubble = use_bubble; } -	S32  getLOD() { return mLOD; }  	BOOL getVisible() { return mVisible; }  	BOOL getHidden() const { return mHidden; }  	void setHidden( BOOL hide ) { mHidden = hide; }  	void setOnHUDAttachment(BOOL on_hud) { mOnHUDAttachment = on_hud; }  	void shift(const LLVector3& offset); -	BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3& intersection, BOOL debug_render = FALSE); -  	static void shiftAll(const LLVector3& offset);  	static void renderAllHUD(); -	static void addPickable(std::set<LLViewerObject*> &pick_list);  	static void reshape();  	static void setDisplayText(BOOL flag) { sDisplayText = flag ; } +  protected:  	LLHUDText(const U8 type); @@ -138,21 +137,17 @@ protected:  	/*virtual*/ void renderForSelect();  	void renderText(BOOL for_select);  	static void updateAll(); -	void setLOD(S32 lod);  	S32 getMaxLines();  private:  	~LLHUDText(); -	BOOL			mOnHUD; -	BOOL			mUseBubble; -	BOOL			mDropShadow; +	BOOL			mOnHUDAttachment;  	BOOL			mDoFade;  	F32				mFadeRange;  	F32				mFadeDistance;  	F32				mLastDistance; -	BOOL			mUsePixelSize;  	BOOL			mZCompare; -	BOOL			mVisibleOffScreen; +//	BOOL			mVisibleOffScreen;  	BOOL			mOffscreen;  	LLColor4		mColor;  	LLVector3		mScale; @@ -170,11 +165,8 @@ private:  	S32				mOffsetY;  	F32				mRadius;  	std::vector<LLHUDTextSegment> mTextSegments; -	std::vector<LLHUDTextSegment> mLabelSegments; -	LLFrameTimer	mResizeTimer;  	ETextAlignment	mTextAlignment;  	EVertAlignment	mVertAlignment; -	S32				mLOD;  	BOOL			mHidden;  	static BOOL    sDisplayText ; diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp index 3aa9d75bc0..1c1d9343aa 100644 --- a/indra/newview/llimfloater.cpp +++ b/indra/newview/llimfloater.cpp @@ -38,6 +38,7 @@  #include "llagent.h"  #include "llappviewer.h" +#include "llavatarnamecache.h"  #include "llbutton.h"  #include "llbottomtray.h"  #include "llchannelmanager.h" @@ -275,12 +276,6 @@ BOOL LLIMFloater::postBuild()  	mInputEditor->setReplaceNewlinesWithSpaces( FALSE );  	mInputEditor->setPassDelete( TRUE ); -	std::string session_name(LLIMModel::instance().getName(mSessionID)); - -	mInputEditor->setLabel(LLTrans::getString("IM_to_label") + " " + session_name); - -	setTitle(session_name); -  	childSetCommitCallback("chat_editor", onSendMsg, this);  	mChatHistory = getChild<LLChatHistory>("chat_history"); @@ -298,6 +293,19 @@ BOOL LLIMFloater::postBuild()  		mInputEditor->setLabel(LLTrans::getString("IM_unavailable_text_label"));  	} +	if ( im_session && im_session->isP2PSessionType()) +	{ +		// look up display name for window title +		LLAvatarNameCache::get(im_session->mOtherParticipantID, +							   boost::bind(&LLIMFloater::onAvatarNameCache, +										   this, _1, _2)); +	} +	else +	{ +		std::string session_name(LLIMModel::instance().getName(mSessionID)); +		updateSessionName(session_name, session_name); +	} +	  	//*TODO if session is not initialized yet, add some sort of a warning message like "starting session...blablabla"  	//see LLFloaterIMPanel for how it is done (IB) @@ -311,6 +319,22 @@ BOOL LLIMFloater::postBuild()  	}  } +void LLIMFloater::updateSessionName(const std::string& ui_title, +									const std::string& ui_label) +{ +	mInputEditor->setLabel(LLTrans::getString("IM_to_label") + " " + ui_label); +	setTitle(ui_title);	 +} + +void LLIMFloater::onAvatarNameCache(const LLUUID& agent_id, +									const LLAvatarName& av_name) +{ +	// Use display name only for labels, as the extended name will be in the +	// floater title +	std::string ui_title = av_name.getCompleteName(); +	updateSessionName(ui_title, av_name.mDisplayName); +} +  // virtual  void LLIMFloater::draw()  { diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h index fef178e3a2..addb218651 100644 --- a/indra/newview/llimfloater.h +++ b/indra/newview/llimfloater.h @@ -38,6 +38,7 @@  #include "lltooldraganddrop.h"  #include "lltransientdockablefloater.h" +class LLAvatarName;  class LLLineEditor;  class LLPanelChatControlPanel;  class LLChatHistory; @@ -130,6 +131,12 @@ private:  	/* virtual */ void onFocusLost();  	/* virtual */ void onFocusReceived(); +	// Update the window title, input field help text, etc. +	void updateSessionName(const std::string& ui_title, const std::string& ui_label); +	 +	// For display name lookups for IM window titles +	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); +	  	BOOL dropCallingCard(LLInventoryItem* item, BOOL drop);  	BOOL dropCategory(LLInventoryCategory* category, BOOL drop); diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 039df69454..e915d3ad70 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -34,6 +34,7 @@  #include "llimview.h" +#include "llavatarnamecache.h"	// IDEVO  #include "llfloaterreg.h"  #include "llfontgl.h"  #include "llgl.h" @@ -631,7 +632,7 @@ bool LLIMModel::clearSession(const LLUUID& session_id)  void LLIMModel::getMessagesSilently(const LLUUID& session_id, std::list<LLSD>& messages, int start_index)  {  	LLIMSession* session = findIMSession(session_id); -	if (!session) +	if (!session)   	{  		llwarns << "session " << session_id << "does not exist " << llendl;  		return; @@ -639,7 +640,7 @@ void LLIMModel::getMessagesSilently(const LLUUID& session_id, std::list<LLSD>& m  	int i = session->mMsgs.size() - start_index; -	for (std::list<LLSD>::iterator iter = session->mMsgs.begin(); +	for (std::list<LLSD>::iterator iter = session->mMsgs.begin();   		iter != session->mMsgs.end() && i > 0;  		iter++)  	{ @@ -1745,8 +1746,19 @@ void LLOutgoingCallDialog::show(const LLSD& key)  	setTitle(callee_name);  	LLSD callee_id = mPayload["other_user_id"]; -	childSetTextArg("calling", "[CALLEE_NAME]", callee_name); -	childSetTextArg("connecting", "[CALLEE_NAME]", callee_name); +	// Beautification:  Since SLID is in the title bar, and you probably +	// recognize this person's voice, just show display name +	std::string final_callee_name = callee_name; +	if (mPayload["session_type"].asInteger() == LLIMModel::LLIMSession::P2P_SESSION) +	{ +		LLAvatarName av_name; +		if (LLAvatarNameCache::get(callee_id, &av_name)) +		{ +			final_callee_name = av_name.mDisplayName; +		} +	} +	childSetTextArg("calling", "[CALLEE_NAME]", final_callee_name); +	childSetTextArg("connecting", "[CALLEE_NAME]", final_callee_name);  	// for outgoing group calls callee_id == group id == session id  	setIcon(callee_id, callee_id); @@ -1903,16 +1915,21 @@ BOOL LLIncomingCallDialog::postBuild()  	if (caller_name == "anonymous")  	{  		caller_name = getString("anonymous"); +		setCallerName(caller_name, caller_name, call_type);  	}  	else if (!is_avatar)  	{  		caller_name = LLTextUtil::formatPhoneNumber(caller_name); +		setCallerName(caller_name, caller_name, call_type); +	} +	else +	{ +		// Get the full name information +		LLAvatarNameCache::get(caller_id, +			boost::bind(&LLIncomingCallDialog::onAvatarNameCache, +				this, _1, _2, call_type));  	} -	setTitle(caller_name + " " + call_type); - -	LLUICtrl* caller_name_widget = getChild<LLUICtrl>("caller name"); -	caller_name_widget->setValue(caller_name + " " + call_type);  	setIcon(session_id, caller_id);  	childSetAction("Accept", onAccept, this); @@ -1936,6 +1953,24 @@ BOOL LLIncomingCallDialog::postBuild()  	return TRUE;  } +void LLIncomingCallDialog::setCallerName(const std::string& ui_title, +										 const std::string& ui_label, +										 const std::string& call_type) +{ +	setTitle(ui_title); + +	// call_type may be a string like " is calling." +	LLUICtrl* caller_name_widget = getChild<LLUICtrl>("caller name"); +	caller_name_widget->setValue(ui_label + " " + call_type); +} + +void LLIncomingCallDialog::onAvatarNameCache(const LLUUID& agent_id, +											 const LLAvatarName& av_name, +											 const std::string& call_type) +{ +	std::string title = av_name.getCompleteName(); +	setCallerName(title, av_name.mDisplayName, call_type); +}  void LLIncomingCallDialog::onOpen(const LLSD& key)  { @@ -2034,8 +2069,11 @@ void LLIncomingCallDialog::processCallResponse(S32 response)  					}  					else  					{ -						if (gCacheName->getFullName(caller_id, correct_session_name)) +						// *NOTE: really should be using callbacks here +						LLAvatarName av_name; +						if (LLAvatarNameCache::get(caller_id, &av_name))  						{ +							correct_session_name = av_name.mDisplayName + " (" + av_name.mUsername + ")";  							correct_session_name.append(ADHOC_NAME_SUFFIX);   						}  					} @@ -2544,7 +2582,8 @@ void LLIMMgr::inviteToSession(  	{  		if (caller_name.empty())  		{ -			gCacheName->get(caller_id, FALSE, boost::bind(&LLIMMgr::onInviteNameLookup, payload, _1, _2, _3, _4)); +			gCacheName->get(caller_id, false, +				boost::bind(&LLIMMgr::onInviteNameLookup, payload, _1, _2, _3));  		}  		else  		{ @@ -2554,9 +2593,9 @@ void LLIMMgr::inviteToSession(  	}  } -void LLIMMgr::onInviteNameLookup(LLSD payload, const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group) +void LLIMMgr::onInviteNameLookup(LLSD payload, const LLUUID& id, const std::string& name, bool is_group)  { -	payload["caller_name"] = first + " " + last; +	payload["caller_name"] = name;  	payload["session_name"] = payload["caller_name"].asString();  	std::string notify_box_type = payload["notify_box_type"].asString(); @@ -2777,13 +2816,12 @@ void LLIMMgr::noteOfflineUsers(  		for(S32 i = 0; i < count; ++i)  		{  			info = at.getBuddyInfo(ids.get(i)); -			std::string first, last; +			std::string full_name;  			if(info && !info->isOnline() -			   && gCacheName->getName(ids.get(i), first, last)) +			   && gCacheName->getFullName(ids.get(i), full_name))  			{  				LLUIString offline = LLTrans::getString("offline_message"); -				offline.setArg("[FIRST]", first); -				offline.setArg("[LAST]", last); +				offline.setArg("[NAME]", full_name);  				im_model.proccessOnlineOfflineNotification(session_id, offline);  			}  		} diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index ffa8a16797..c132ac328f 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -41,7 +41,7 @@  #include "llvoicechannel.h" - +class LLAvatarName;  class LLFriendObserver;  class LLCallDialogManager;	  class LLIMSpeakerMgr; @@ -458,7 +458,7 @@ private:  	void processIMTypingCore(const LLIMInfo* im_info, BOOL typing); -	static void onInviteNameLookup(LLSD payload, const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group); +	static void onInviteNameLookup(LLSD payload, const LLUUID& id, const std::string& name, bool is_group);  	void notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);  	void notifyObserverSessionRemoved(const LLUUID& session_id); @@ -540,6 +540,13 @@ public:  	static void onStartIM(void* user_data);  private: +	void setCallerName(const std::string& ui_title, +		const std::string& ui_label, +		const std::string& call_type); +	void onAvatarNameCache(const LLUUID& agent_id, +		const LLAvatarName& av_name, +		const std::string& call_type); +  	/*virtual*/ void onLifetimeExpired();  	void processCallResponse(S32 response);  }; diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp index d9fdc876db..c4144c9844 100644 --- a/indra/newview/llinspectavatar.cpp +++ b/indra/newview/llinspectavatar.cpp @@ -37,6 +37,7 @@  #include "llagent.h"  #include "llagentdata.h"  #include "llavataractions.h" +#include "llavatarnamecache.h"  #include "llavatarpropertiesprocessor.h"  #include "llcallingcard.h"  #include "lldateutil.h" @@ -143,17 +144,13 @@ private:  	// Is used to determine if "Add friend" option should be enabled in gear menu  	bool isNotFriend(); -	// Callback for gCacheName to look up avatar name -	void nameUpdatedCallback( -							 const LLUUID& id, -							 const std::string& first, -							 const std::string& last, -							 BOOL is_group); +	void onAvatarNameCache(const LLUUID& agent_id, +						   const LLAvatarName& av_name);  private:  	LLUUID				mAvatarID;  	// Need avatar name information to spawn friend add request -	std::string			mAvatarName; +	std::string			mLegacyName;  	// an in-flight request for avatar properties from LLAvatarPropertiesProcessor  	// is represented by this object  	LLFetchAvatarData*	mPropertiesRequest; @@ -208,7 +205,7 @@ public:  LLInspectAvatar::LLInspectAvatar(const LLSD& sd)  :	LLInspect( LLSD() ),	// single_instance, doesn't really need key  	mAvatarID(),			// set in onOpen()  *Note: we used to show partner's name but we dont anymore --angela 3rd Dec*  -	mAvatarName(), +	mLegacyName(),  	mPropertiesRequest(NULL)  {  	mCommitCallbackRegistrar.add("InspectAvatar.ViewProfile",	boost::bind(&LLInspectAvatar::onClickViewProfile, this));	 @@ -336,6 +333,7 @@ void LLInspectAvatar::requestUpdate()  	// Clear out old data so it doesn't flash between old and new  	getChild<LLUICtrl>("user_name")->setValue(""); +	getChild<LLUICtrl>("user_slid")->setValue("");  	getChild<LLUICtrl>("user_subtitle")->setValue("");  	getChild<LLUICtrl>("user_details")->setValue(""); @@ -373,9 +371,9 @@ void LLInspectAvatar::requestUpdate()  	childSetValue("avatar_icon", LLSD(mAvatarID) ); -	gCacheName->get(mAvatarID, FALSE, -		boost::bind(&LLInspectAvatar::nameUpdatedCallback, -			this, _1, _2, _3, _4)); +	LLAvatarNameCache::get(mAvatarID, +			boost::bind(&LLInspectAvatar::onAvatarNameCache, +				this, _1, _2));  }  void LLInspectAvatar::processAvatarData(LLAvatarData* data) @@ -562,7 +560,7 @@ void LLInspectAvatar::updateVolumeSlider()  		LLUICtrl* mute_btn = getChild<LLUICtrl>("mute_btn"); -		bool is_linden = LLStringUtil::endsWith(mAvatarName, " Linden"); +		bool is_linden = LLStringUtil::endsWith(mLegacyName, " Linden");  		mute_btn->setEnabled( !is_linden);  		mute_btn->setValue( is_muted ); @@ -593,7 +591,7 @@ void LLInspectAvatar::onClickMuteVolume()  	LLMuteList* mute_list = LLMuteList::getInstance();  	bool is_muted = mute_list->isMuted(mAvatarID, LLMute::flagVoiceChat); -	LLMute mute(mAvatarID, mAvatarName, LLMute::AGENT); +	LLMute mute(mAvatarID, mLegacyName, LLMute::AGENT);  	if (!is_muted)  	{  		mute_list->add(mute, LLMute::flagVoiceChat); @@ -612,22 +610,21 @@ void LLInspectAvatar::onVolumeChange(const LLSD& data)  	LLVoiceClient::getInstance()->setUserVolume(mAvatarID, volume);  } -void LLInspectAvatar::nameUpdatedCallback( -	const LLUUID& id, -	const std::string& first, -	const std::string& last, -	BOOL is_group) +void LLInspectAvatar::onAvatarNameCache( +		const LLUUID& agent_id, +		const LLAvatarName& av_name)  { -	if (id == mAvatarID) +	if (agent_id == mAvatarID)  	{ -		mAvatarName = first + " " + last; -		childSetValue("user_name", LLSD(mAvatarName) ); +		getChild<LLUICtrl>("user_name")->setValue(av_name.mDisplayName); +		getChild<LLUICtrl>("user_slid")->setValue(av_name.mUsername); +		mLegacyName = av_name.getLegacyName();  	}  }  void LLInspectAvatar::onClickAddFriend()  { -	LLAvatarActions::requestFriendshipDialog(mAvatarID, mAvatarName); +	LLAvatarActions::requestFriendshipDialog(mAvatarID, mLegacyName);  	closeFloater();  } @@ -695,7 +692,7 @@ void LLInspectAvatar::onClickShare()  void LLInspectAvatar::onToggleMute()  { -	LLMute mute(mAvatarID, mAvatarName, LLMute::AGENT); +	LLMute mute(mAvatarID, mLegacyName, LLMute::AGENT);  	if (LLMuteList::getInstance()->isMuted(mute.mID, mute.mName))  	{ @@ -712,7 +709,7 @@ void LLInspectAvatar::onToggleMute()  void LLInspectAvatar::onClickReport()  { -	LLFloaterReporter::showFromAvatar(mAvatarID, mAvatarName); +	LLFloaterReporter::showFromAvatar(mAvatarID, mLegacyName);  	closeFloater();  } @@ -736,17 +733,17 @@ void LLInspectAvatar::onClickZoomIn()  void LLInspectAvatar::onClickFindOnMap()  { -	gFloaterWorldMap->trackAvatar(mAvatarID, mAvatarName); +	gFloaterWorldMap->trackAvatar(mAvatarID, mLegacyName);  	LLFloaterReg::showInstance("world_map");  }  bool LLInspectAvatar::enableMute()  { -		bool is_linden = LLStringUtil::endsWith(mAvatarName, " Linden"); +		bool is_linden = LLStringUtil::endsWith(mLegacyName, " Linden");  		bool is_self = mAvatarID == gAgent.getID(); -		if (!is_linden && !is_self && !LLMuteList::getInstance()->isMuted(mAvatarID, mAvatarName)) +		if (!is_linden && !is_self && !LLMuteList::getInstance()->isMuted(mAvatarID, mLegacyName))  		{  			return true;  		} @@ -758,10 +755,10 @@ bool LLInspectAvatar::enableMute()  bool LLInspectAvatar::enableUnmute()  { -		bool is_linden = LLStringUtil::endsWith(mAvatarName, " Linden"); +		bool is_linden = LLStringUtil::endsWith(mLegacyName, " Linden");  		bool is_self = mAvatarID == gAgent.getID(); -		if (!is_linden && !is_self && LLMuteList::getInstance()->isMuted(mAvatarID, mAvatarName)) +		if (!is_linden && !is_self && LLMuteList::getInstance()->isMuted(mAvatarID, mLegacyName))  		{  			return true;  		} diff --git a/indra/newview/llinspectgroup.cpp b/indra/newview/llinspectgroup.cpp index 7fd7b69021..364da3f64c 100644 --- a/indra/newview/llinspectgroup.cpp +++ b/indra/newview/llinspectgroup.cpp @@ -84,9 +84,8 @@ public:  	// Callback for gCacheName to look up group name  	// Faster than waiting for group properties to return  	void nameUpdatedCallback(const LLUUID& id, -							 const std::string& first, -							 const std::string& last, -							 BOOL is_group); +							 const std::string& name, +							 bool is_group);  	// Button/menu callbacks  	void onClickViewProfile(); @@ -225,21 +224,19 @@ void LLInspectGroup::requestUpdate()  	mPropertiesRequest = new LLFetchGroupData(mGroupID, this);  	// Name lookup will be faster out of cache, use that -	gCacheName->get(mGroupID, TRUE, +	gCacheName->get(mGroupID, true,  		boost::bind(&LLInspectGroup::nameUpdatedCallback, -			this, _1, _2, _3, _4)); +			this, _1, _2, _3));  }  void LLInspectGroup::nameUpdatedCallback(  	const LLUUID& id, -	const std::string& first, -	const std::string& last, -	BOOL is_group) +	const std::string& name, +	bool is_group)  {  	if (id == mGroupID)  	{ -		// group names are returned as a first name -		childSetValue("group_name", LLSD(first) ); +		childSetValue("group_name", LLSD(name) );  	}  	// Otherwise possibly a request for an older inspector, ignore it diff --git a/indra/newview/llinspectremoteobject.cpp b/indra/newview/llinspectremoteobject.cpp index 97ff771658..08446760f8 100644 --- a/indra/newview/llinspectremoteobject.cpp +++ b/indra/newview/llinspectremoteobject.cpp @@ -66,7 +66,7 @@ public:  private:  	void update(); -	static void nameCallback(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* data); +	void onNameCache(const LLUUID& id, const std::string& name, bool is_group);  private:  	LLUUID		 mObjectID; @@ -121,7 +121,8 @@ void LLInspectRemoteObject::onOpen(const LLSD& data)  	mOwner = "";  	if (gCacheName)  	{ -		gCacheName->get(mOwnerID, mGroupOwned, nameCallback, this); +		gCacheName->get(mOwnerID, mGroupOwned, +			boost::bind(&LLInspectRemoteObject::onNameCache, this, _1, _2, _3));  	}  	// update the inspector with the current object state @@ -152,16 +153,10 @@ void LLInspectRemoteObject::onClickClose()  	closeFloater();  } -//static  -void LLInspectRemoteObject::nameCallback(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* data) +void LLInspectRemoteObject::onNameCache(const LLUUID& id, const std::string& name, bool is_group)  { -	LLInspectRemoteObject *self = (LLInspectRemoteObject*)data; -	self->mOwner = first; -	if (!last.empty()) -	{ -		self->mOwner += " " + last; -	} -	self->update(); +	mOwner = name; +	update();  }  void LLInspectRemoteObject::update() diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 2d27c89074..181a9fa7eb 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -35,6 +35,7 @@  // external projects  #include "lltransfersourceasset.h" +#include "llavatarnamecache.h"	// IDEVO  #include "llagent.h"  #include "llagentcamera.h" @@ -3613,6 +3614,13 @@ void LLCallingCardBridge::performAction(LLInventoryModel* model, std::string act  		{  			std::string callingcard_name;  			gCacheName->getFullName(item->getCreatorUUID(), callingcard_name); +			// IDEVO +			LLAvatarName av_name; +			if (LLAvatarNameCache::useDisplayNames() +				&& LLAvatarNameCache::get(item->getCreatorUUID(), &av_name)) +			{ +				callingcard_name = av_name.mDisplayName + " (" + av_name.mUsername + ")"; +			}  			LLUUID session_id = gIMMgr->addSession(callingcard_name, IM_NOTHING_SPECIAL, item->getCreatorUUID());  			if (session_id != LLUUID::null)  			{ diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index c373512ace..098ee22280 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -716,7 +716,8 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item)  			new_item->setCreator(id);  			std::string avatar_name;  			// Fetch the currect name -			gCacheName->get(id, FALSE, boost::bind(&LLViewerInventoryItem::onCallingCardNameLookup, new_item.get(), _1, _2, _3)); +			gCacheName->get(id, false, +				boost::bind(&LLViewerInventoryItem::onCallingCardNameLookup, new_item.get(), _1, _2, _3));  		}  	}  	else if (new_item->getType() == LLAssetType::AT_GESTURE) diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index 71604291e1..11ee95ed6d 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -142,6 +142,7 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia  	requested_options.append("initial-outfit");  	requested_options.append("gestures"); +	requested_options.append("display_names");  	requested_options.append("event_categories");  	requested_options.append("event_notifications");  	requested_options.append("classified_categories"); diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp index 7cb192e026..7126914260 100644 --- a/indra/newview/llmutelist.cpp +++ b/indra/newview/llmutelist.cpp @@ -118,9 +118,8 @@ LLMute::LLMute(const LLUUID& id, const std::string& name, EType type, U32 flags)  		LLNameValue* lastname = mute_object->getNVPair("LastName");  		if (firstname && lastname)  		{ -			mName.assign( firstname->getString() ); -			mName.append(" "); -			mName.append( lastname->getString() ); +			mName = LLCacheName::buildFullName( +				firstname->getString(), lastname->getString());  		}  		mType = mute_object->isAvatar() ? AGENT : OBJECT;  	} @@ -416,7 +415,7 @@ void LLMuteList::updateRemove(const LLMute& mute)  	gAgent.sendReliableMessage();  } -void notify_automute_callback(const LLUUID& agent_id, const std::string& first_name, const std::string& last_name, BOOL is_group, LLMuteList::EAutoReason reason) +void notify_automute_callback(const LLUUID& agent_id, const std::string& full_name, bool is_group, LLMuteList::EAutoReason reason)  {  	std::string notif_name;  	switch (reason) @@ -434,8 +433,7 @@ void notify_automute_callback(const LLUUID& agent_id, const std::string& first_n  	}  	LLSD args; -	args["FIRST"] = first_name; -	args["LAST"] = last_name; +	args["NAME"] = full_name;  	LLNotificationPtr notif_ptr = LLNotifications::instance().add(notif_name, args, LLSD());  	if (notif_ptr) @@ -450,7 +448,7 @@ void notify_automute_callback(const LLUUID& agent_id, const std::string& first_n  } -BOOL LLMuteList::autoRemove(const LLUUID& agent_id, const EAutoReason reason, const std::string& first_name, const std::string& last_name) +BOOL LLMuteList::autoRemove(const LLUUID& agent_id, const EAutoReason reason)  {  	BOOL removed = FALSE; @@ -460,24 +458,17 @@ BOOL LLMuteList::autoRemove(const LLUUID& agent_id, const EAutoReason reason, co  		removed = TRUE;  		remove(automute); -		if (first_name.empty() && last_name.empty()) -		{ -			std::string cache_first, cache_last; -			if (gCacheName->getName(agent_id, cache_first, cache_last)) +		std::string full_name; +		if (gCacheName->getFullName(agent_id, full_name))  			{  				// name in cache, call callback directly -				notify_automute_callback(agent_id, cache_first, cache_last, FALSE, reason); +			notify_automute_callback(agent_id, full_name, false, reason);  			}  			else  			{  				// not in cache, lookup name from cache -				gCacheName->get(agent_id, FALSE, boost::bind(¬ify_automute_callback, _1, _2, _3, _4, reason)); -			} -		} -		else -		{ -			// call callback directly -			notify_automute_callback(agent_id, first_name, last_name, FALSE, reason); +			gCacheName->get(agent_id, false, +				boost::bind(¬ify_automute_callback, _1, _2, _3, reason));  		}  	} diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h index 79b556bdbb..ad4fd2345d 100644 --- a/indra/newview/llmutelist.h +++ b/indra/newview/llmutelist.h @@ -69,7 +69,7 @@ public:  public:  	LLUUID		mID;	// agent or object id -	std::string	mName;	// agent or object name +	std::string	mName;	// agent or object name, does not store last name "Resident"  	EType		mType;	// needed for UI display of existing mutes  	U32			mFlags;	// flags pertaining to this mute entry  }; @@ -102,7 +102,7 @@ public:  	// Remove both normal and legacy mutes, for any or all properties.  	BOOL remove(const LLMute& mute, U32 flags = 0); -	BOOL autoRemove(const LLUUID& agent_id, const EAutoReason reason, const std::string& first_name = LLStringUtil::null, const std::string& last_name = LLStringUtil::null); +	BOOL autoRemove(const LLUUID& agent_id, const EAutoReason reason);  	// Name is required to test against legacy text-only mutes.  	BOOL isMuted(const LLUUID& id, const std::string& name = LLStringUtil::null, U32 flags = 0) const; diff --git a/indra/newview/llnamebox.cpp b/indra/newview/llnamebox.cpp index cd810b9793..da3e95e947 100644 --- a/indra/newview/llnamebox.cpp +++ b/indra/newview/llnamebox.cpp @@ -87,26 +87,15 @@ void LLNameBox::setNameID(const LLUUID& name_id, BOOL is_group)  		setText(mInitialValue);  } -void LLNameBox::refresh(const LLUUID& id, const std::string& firstname, -						const std::string& lastname, BOOL is_group) +void LLNameBox::refresh(const LLUUID& id, const std::string& full_name, bool is_group)  {  	if (id == mNameID)  	{ -		std::string name; -		if (!is_group) -		{ -			name = firstname + " " + lastname; -		} -		else -		{ -			name = firstname; -		} -		setName(name, is_group); +		setName(full_name, is_group);  	}  } -void LLNameBox::refreshAll(const LLUUID& id, const std::string& firstname, -						   const std::string& lastname, BOOL is_group) +void LLNameBox::refreshAll(const LLUUID& id, const std::string& full_name, bool is_group)  {  	std::set<LLNameBox*>::iterator it;  	for (it = LLNameBox::sInstances.begin(); @@ -114,7 +103,7 @@ void LLNameBox::refreshAll(const LLUUID& id, const std::string& firstname,  		 ++it)  	{  		LLNameBox* box = *it; -		box->refresh(id, firstname, lastname, is_group); +		box->refresh(id, full_name, is_group);  	}  } diff --git a/indra/newview/llnamebox.h b/indra/newview/llnamebox.h index 48b54faec8..2fe8990653 100644 --- a/indra/newview/llnamebox.h +++ b/indra/newview/llnamebox.h @@ -59,10 +59,9 @@ public:  	void setNameID(const LLUUID& name_id, BOOL is_group); -	void refresh(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group); +	void refresh(const LLUUID& id, const std::string& full_name, bool is_group); -	static void refreshAll(const LLUUID& id, const std::string& firstname, -						   const std::string& lastname, BOOL is_group); +	static void refreshAll(const LLUUID& id, const std::string& full_name, bool is_group);  protected:  	LLNameBox (const Params&); diff --git a/indra/newview/llnameeditor.cpp b/indra/newview/llnameeditor.cpp index 65601da7da..0c704a1f56 100644 --- a/indra/newview/llnameeditor.cpp +++ b/indra/newview/llnameeditor.cpp @@ -81,26 +81,15 @@ void LLNameEditor::setNameID(const LLUUID& name_id, BOOL is_group)  	setText(name);  } -void LLNameEditor::refresh(const LLUUID& id, const std::string& firstname, -						   const std::string& lastname, BOOL is_group) +void LLNameEditor::refresh(const LLUUID& id, const std::string& full_name, bool is_group)  {  	if (id == mNameID)  	{ -		std::string name; -		if (!is_group) -		{ -			name = firstname + " " + lastname; -		} -		else -		{ -			name = firstname; -		} -		setText(name); +		setText(full_name);  	}  } -void LLNameEditor::refreshAll(const LLUUID& id, const std::string& firstname, -							  const std::string& lastname, BOOL is_group) +void LLNameEditor::refreshAll(const LLUUID& id, const std::string& full_name, bool is_group)  {  	std::set<LLNameEditor*>::iterator it;  	for (it = LLNameEditor::sInstances.begin(); @@ -108,7 +97,7 @@ void LLNameEditor::refreshAll(const LLUUID& id, const std::string& firstname,  		 ++it)  	{  		LLNameEditor* box = *it; -		box->refresh(id, firstname, lastname, is_group); +		box->refresh(id, full_name, is_group);  	}  } diff --git a/indra/newview/llnameeditor.h b/indra/newview/llnameeditor.h index 99e03a1166..a75c492aca 100644 --- a/indra/newview/llnameeditor.h +++ b/indra/newview/llnameeditor.h @@ -65,10 +65,9 @@ public:  	void setNameID(const LLUUID& name_id, BOOL is_group); -	void refresh(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group); +	void refresh(const LLUUID& id, const std::string& full_name, bool is_group); -	static void refreshAll(const LLUUID& id, const std::string& firstname, -						   const std::string& lastname, BOOL is_group); +	static void refreshAll(const LLUUID& id, const std::string& full_name, bool is_group);  	// Take/return agent UUIDs diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp index d605d4430e..a2450fcdd2 100644 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -36,6 +36,7 @@  #include <boost/tokenizer.hpp> +#include "llavatarnamecache.h"  #include "llcachename.h"  #include "llfloaterreg.h"  #include "llinventory.h" @@ -58,7 +59,8 @@ void LLNameListCtrl::NameTypeNames::declareValues()  LLNameListCtrl::Params::Params()  :	name_column(""), -	allow_calling_card_drop("allow_calling_card_drop", false) +	allow_calling_card_drop("allow_calling_card_drop", false), +	short_names("short_names", false)  {  	name = "name_list";  } @@ -67,7 +69,8 @@ LLNameListCtrl::LLNameListCtrl(const LLNameListCtrl::Params& p)  :	LLScrollListCtrl(p),  	mNameColumnIndex(p.name_column.column_index),  	mNameColumn(p.name_column.column_name), -	mAllowCallingCardDrop(p.allow_calling_card_drop) +	mAllowCallingCardDrop(p.allow_calling_card_drop), +	mShortNames(p.short_names)  {}  // public @@ -297,10 +300,20 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow(  		break;  	case INDIVIDUAL:  		{ -			std::string name; -			if (gCacheName->getFullName(id, name)) +			LLAvatarName av_name; +			if (LLAvatarNameCache::get(id, &av_name))  			{ -				fullname = name; +				if (mShortNames) +					fullname = av_name.mDisplayName; +				else +					fullname = av_name.getCompleteName(); +			} +			else +			{ +				// ...schedule a callback +				LLAvatarNameCache::get(id, +					boost::bind(&LLNameListCtrl::onAvatarNameCache, +						this, _1, _2));  			}  			break;  		} @@ -355,34 +368,25 @@ void LLNameListCtrl::removeNameItem(const LLUUID& agent_id)  	}  } -// public -void LLNameListCtrl::refresh(const LLUUID& id, const std::string& first,  -							 const std::string& last, BOOL is_group) +void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id, +									   const LLAvatarName& av_name)  { -	//llinfos << "LLNameListCtrl::refresh " << id << " '" << first << " " -	//	<< last << "'" << llendl; - -	std::string fullname; -	if (!is_group) -	{ -		fullname = first + " " + last; -	} +	std::string name; +	if (mShortNames) +		name = av_name.mDisplayName;  	else -	{ -		fullname = first; -	} +		name = av_name.getCompleteName(); -	// TODO: scan items for that ID, fix if necessary  	item_list::iterator iter;  	for (iter = getItemList().begin(); iter != getItemList().end(); iter++)  	{  		LLScrollListItem* item = *iter; -		if (item->getUUID() == id) +		if (item->getUUID() == agent_id)  		{  			LLScrollListCell* cell = item->getColumn(mNameColumnIndex);  			if (cell)  			{ -				cell->setValue(fullname); +				cell->setValue(name);  			}  		}  	} @@ -391,19 +395,6 @@ void LLNameListCtrl::refresh(const LLUUID& id, const std::string& first,  } -// static -void LLNameListCtrl::refreshAll(const LLUUID& id, const std::string& first, -								const std::string& last, BOOL is_group) -{ -	LLInstanceTrackerScopedGuard guard; -	LLInstanceTracker<LLNameListCtrl>::instance_iter it; -	for (it = guard.beginInstances(); it != guard.endInstances(); ++it) -	{ -		LLNameListCtrl& ctrl = *it; -		ctrl.refresh(id, first, last, is_group); -	} -} -  void LLNameListCtrl::updateColumns()  {  	LLScrollListCtrl::updateColumns(); diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h index 1c26ee5db4..54237f4305 100644 --- a/indra/newview/llnamelistctrl.h +++ b/indra/newview/llnamelistctrl.h @@ -37,6 +37,7 @@  #include "llscrolllistctrl.h" +class LLAvatarName;  class LLNameListCtrl  :	public LLScrollListCtrl, protected LLInstanceTracker<LLNameListCtrl> @@ -80,6 +81,7 @@ public:  	{  		Optional<NameColumn>	name_column;  		Optional<bool>	allow_calling_card_drop; +		Optional<bool>			short_names;  		Params();  	}; @@ -105,11 +107,6 @@ public:  	void removeNameItem(const LLUUID& agent_id); -	void refresh(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group); - -	static void refreshAll(const LLUUID& id, const std::string& firstname, -						   const std::string& lastname, BOOL is_group); -  	// LLView interface  	/*virtual*/ BOOL	handleDragAndDrop(S32 x, S32 y, MASK mask,  									  BOOL drop, EDragAndDropType cargo_type, void *cargo_data, @@ -124,11 +121,13 @@ public:  	/*virtual*/ void	mouseOverHighlightNthItem( S32 index );  private:  	void showInspector(const LLUUID& avatar_id, bool is_group); +	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);  private:  	S32    			mNameColumnIndex;  	std::string		mNameColumn;  	BOOL			mAllowCallingCardDrop; +	bool			mShortNames;  // display name only, no SLID  };  /** diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index a8dee8a24a..67b238ad58 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -37,6 +37,7 @@  // Library includes (should move below)  #include "indra_constants.h" +#include "llavatarnamecache.h"  #include "llmath.h"  #include "llfloaterreg.h"  #include "llfocusmgr.h" @@ -555,11 +556,14 @@ BOOL LLNetMap::handleToolTip( S32 x, S32 y, MASK mask )  	// mToolTipMsg = "[AGENT][REGION](Double-click to open Map)" +	bool have_agent = false;  	LLStringUtil::format_map_t args; -	std::string fullname; -	if(mClosestAgentToCursor.notNull() && gCacheName->getFullName(mClosestAgentToCursor, fullname)) +	LLAvatarName av_name; +	if(mClosestAgentToCursor.notNull() +	   && LLAvatarNameCache::get(mClosestAgentToCursor, &av_name))  	{ -		args["[AGENT]"] = fullname + "\n"; +		args["[AGENT]"] = av_name.getCompleteName() + "\n"; +		have_agent = true;  	}  	else  	{ @@ -567,7 +571,7 @@ BOOL LLNetMap::handleToolTip( S32 x, S32 y, MASK mask )  	}  	LLViewerRegion*	region = LLWorld::getInstance()->getRegionFromPosGlobal( viewPosToGlobal( x, y ) ); -	if( region ) +	if( region && !have_agent)  	{  		args["[REGION]"] = region->getName() + "\n";  	} diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp index 95b946f307..2ca2df152b 100644 --- a/indra/newview/llnotificationhandlerutil.cpp +++ b/indra/newview/llnotificationhandlerutil.cpp @@ -113,8 +113,11 @@ void LLSysHandler::removeExclusiveNotifications(const LLNotificationPtr& notif)  }  const static std::string GRANTED_MODIFY_RIGHTS("GrantedModifyRights"), -		REVOKED_MODIFY_RIGHTS("RevokedModifyRights"), OBJECT_GIVE_ITEM( -				"ObjectGiveItem"), PAYMENT_RECIVED("PaymentRecived"), +		REVOKED_MODIFY_RIGHTS("RevokedModifyRights"), +		OBJECT_GIVE_ITEM("ObjectGiveItem"), +		OBJECT_GIVE_ITEM_UNKNOWN_USER("ObjectGiveItemUnknownUser"), +						PAYMENT_RECEIVED("PaymentReceived"), +						PAYMENT_SENT("PaymentSent"),  						ADD_FRIEND_WITH_MESSAGE("AddFriendWithMessage"),  						USER_GIVE_ITEM("UserGiveItem"),  						INVENTORY_ACCEPTED("InventoryAccepted"), @@ -136,7 +139,8 @@ bool LLHandlerUtil::canLogToIM(const LLNotificationPtr& notification)  {  	return GRANTED_MODIFY_RIGHTS == notification->getName()  			|| REVOKED_MODIFY_RIGHTS == notification->getName() -			|| PAYMENT_RECIVED == notification->getName() +			|| PAYMENT_RECEIVED == notification->getName() +			|| PAYMENT_SENT == notification->getName()  			|| OFFER_FRIENDSHIP == notification->getName()  			|| FRIENDSHIP_OFFERED == notification->getName()  			|| FRIENDSHIP_ACCEPTED == notification->getName() diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index 0b31ffc9a0..e60189d301 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -224,12 +224,11 @@ void LLPanelAvatarNotes::rightsConfirmationCallback(const LLSD& notification,  void LLPanelAvatarNotes::confirmModifyRights(bool grant, S32 rights)  { -	std::string first, last; +	std::string full_name;  	LLSD args; -	if (gCacheName->getName(getAvatarId(), first, last)) +	if (gCacheName->getFullName(getAvatarId(), full_name))  	{ -		args["FIRST_NAME"] = first; -		args["LAST_NAME"] = last; +		args["NAME"] = full_name;  	}  	if (grant) diff --git a/indra/newview/llpanelavatartag.cpp b/indra/newview/llpanelavatartag.cpp index 7563cc7f61..173fb851ce 100644 --- a/indra/newview/llpanelavatartag.cpp +++ b/indra/newview/llpanelavatartag.cpp @@ -86,7 +86,7 @@ void LLPanelAvatarTag::setAvatarId(const LLUUID& avatar_id)  	{  		mIcon->setValue(avatar_id);  	} -	setName(std::string(mIcon->getFirstName()+ " "+ mIcon->getLastName())); +	setName(std::string(mIcon->getFullName()));  }  boost::signals2::connection LLPanelAvatarTag::setLeftButtonClickCallback( diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp index 11d3768a3d..38922e1b99 100644 --- a/indra/newview/llpanelgroupinvite.cpp +++ b/indra/newview/llpanelgroupinvite.cpp @@ -404,16 +404,18 @@ void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids)  	std::vector<std::string> names;  	for (S32 i = 0; i < (S32)agent_ids.size(); i++)  	{ +		std::string fullname;  		LLUUID agent_id = agent_ids[i];  		LLViewerObject* dest = gObjectList.findObject(agent_id); -		std::string fullname;  		if(dest && dest->isAvatar())  		{  			LLNameValue* nvfirst = dest->getNVPair("FirstName");  			LLNameValue* nvlast = dest->getNVPair("LastName");  			if(nvfirst && nvlast)  			{ -				fullname = std::string(nvfirst->getString()) + " " + std::string(nvlast->getString()); +				fullname = LLCacheName::buildFullName( +					nvfirst->getString(), nvlast->getString()); +  			}  			if (!fullname.empty())  			{ @@ -436,8 +438,7 @@ void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids)  				{  					// actually it should happen, just in case  					gCacheName->get(LLUUID(agent_id), false, boost::bind( -							&LLPanelGroupInvite::addUserCallback, this, _1, _2, -							_3)); +							&LLPanelGroupInvite::addUserCallback, this, _1, _2));  					// for this special case!  					//when there is no cached name we should remove resident from agent_ids list to avoid breaking of sequence  					// removed id will be added in callback @@ -453,16 +454,16 @@ void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids)  	mImplementation->addUsers(names, agent_ids);  } -void LLPanelGroupInvite::addUserCallback(const LLUUID& id, const std::string& first_name, const std::string& last_name) +void LLPanelGroupInvite::addUserCallback(const LLUUID& id, const std::string& full_name)  {  	std::vector<std::string> names;  	uuid_vec_t agent_ids; -	std::string full_name = first_name + " " + last_name;  	agent_ids.push_back(id); -	names.push_back(first_name + " " + last_name); +	names.push_back(full_name);  	mImplementation->addUsers(names, agent_ids);  } +  void LLPanelGroupInvite::draw()  {  	LLPanel::draw(); diff --git a/indra/newview/llpanelgroupinvite.h b/indra/newview/llpanelgroupinvite.h index 2ed443ed46..520107c33a 100644 --- a/indra/newview/llpanelgroupinvite.h +++ b/indra/newview/llpanelgroupinvite.h @@ -46,7 +46,7 @@ public:  	/**  	 * this callback is being used to add a user whose fullname isn't been loaded before invoking of addUsers().  	 */   -	void addUserCallback(const LLUUID& id, const std::string& first_name, const std::string& last_name); +	void addUserCallback(const LLUUID& id, const std::string& full_name);  	void clear();  	void update(); diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp index 42ff514f09..2a955004e9 100644 --- a/indra/newview/llpanelgroupnotices.cpp +++ b/indra/newview/llpanelgroupnotices.cpp @@ -36,6 +36,7 @@  #include "llview.h" +#include "llcachename.h"  #include "llinventory.h"  #include "llviewerinventory.h"  #include "llinventorydefines.h" @@ -547,6 +548,9 @@ void LLPanelGroupNotices::processNotices(LLMessageSystem* msg)  		msg->getU8("Data","AssetType",asset_type,i);  		msg->getU32("Data","Timestamp",timestamp,i); +		// IDEVO clean up legacy "Resident" names +		name = LLCacheName::cleanFullName(name); +  		LLSD row;  		row["id"] = id; diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp index 709bb83fe4..89eef8b8d3 100644 --- a/indra/newview/llpanelimcontrolpanel.cpp +++ b/indra/newview/llpanelimcontrolpanel.cpp @@ -185,7 +185,7 @@ void LLPanelIMControlPanel::onViewProfileButtonClicked()  void LLPanelIMControlPanel::onAddFriendButtonClicked()  {  	LLAvatarIconCtrl* avatar_icon = getChild<LLAvatarIconCtrl>("avatar_icon"); -	std::string full_name = avatar_icon->getFirstName() + " " + avatar_icon->getLastName(); +	std::string full_name = avatar_icon->getFullName();  	LLAvatarActions::requestFriendshipDialog(mAvatarID, full_name);  } @@ -227,6 +227,15 @@ void LLPanelIMControlPanel::setSessionId(const LLUUID& session_id)  		childSetEnabled("share_btn", FALSE);  		childSetEnabled("teleport_btn", FALSE);  		childSetEnabled("pay_btn", FALSE); + +        getChild<LLTextBox>("avatar_name")->setValue(im_session->mName); +        getChild<LLTextBox>("avatar_name")->setToolTip(im_session->mName); +	} +	else +	{ +		// If the participant is an avatar, fetch the currect name +		gCacheName->get(mAvatarID, false, +			boost::bind(&LLPanelIMControlPanel::onNameCache, this, _1, _2, _3));  	}  } @@ -242,6 +251,16 @@ void LLPanelIMControlPanel::changed(U32 mask)  	}  } +void LLPanelIMControlPanel::onNameCache(const LLUUID& id, const std::string& full_name, bool is_group) +{ +	if ( id == mAvatarID ) +	{ +		std::string avatar_name = full_name; +		getChild<LLTextBox>("avatar_name")->setValue(avatar_name); +		getChild<LLTextBox>("avatar_name")->setToolTip(avatar_name); +	} +} +  LLPanelGroupControlPanel::LLPanelGroupControlPanel(const LLUUID& session_id):  mParticipantList(NULL)  { diff --git a/indra/newview/llpanelimcontrolpanel.h b/indra/newview/llpanelimcontrolpanel.h index ce8fc58e56..45f4b95903 100644 --- a/indra/newview/llpanelimcontrolpanel.h +++ b/indra/newview/llpanelimcontrolpanel.h @@ -89,6 +89,9 @@ public:  	// LLFriendObserver trigger  	virtual void changed(U32 mask); +protected: +	void onNameCache(const LLUUID& id, const std::string& full_name, bool is_group); +  private:  	void onViewProfileButtonClicked();  	void onAddFriendButtonClicked(); diff --git a/indra/newview/llpanellandmarkinfo.cpp b/indra/newview/llpanellandmarkinfo.cpp index 4ffd43cb0f..4c2ff471e8 100644 --- a/indra/newview/llpanellandmarkinfo.cpp +++ b/indra/newview/llpanellandmarkinfo.cpp @@ -45,6 +45,7 @@  #include "llagent.h"  #include "llagentui.h"  #include "lllandmarkactions.h" +#include "llslurl.h"  #include "llviewerinventory.h"  #include "llviewerparcelmgr.h"  #include "llviewerregion.h" @@ -231,13 +232,15 @@ void LLPanelLandmarkInfo::displayItemInfo(const LLInventoryItem* pItem)  	//////////////////  	if (pItem->getCreatorUUID().notNull())  	{ -		std::string name; +		// IDEVO  		LLUUID creator_id = pItem->getCreatorUUID(); -		if (!gCacheName->getFullName(creator_id, name)) -		{ -			gCacheName->get(creator_id, FALSE, -							boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, mCreator, _2, _3)); -		} +		std::string name = +			LLSLURL("agent", creator_id, "inspect").getSLURLString(); +		//if (!gCacheName->getFullName(creator_id, name)) +		//{ +		//	gCacheName->get(creator_id, FALSE, +		//					boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, mCreator, _2, _3)); +		//}  		mCreator->setText(name);  	}  	else @@ -254,20 +257,24 @@ void LLPanelLandmarkInfo::displayItemInfo(const LLInventoryItem* pItem)  		if (perm.isGroupOwned())  		{  			LLUUID group_id = perm.getGroup(); -			if (!gCacheName->getGroupName(group_id, name)) -			{ -				gCacheName->get(group_id, TRUE, -								boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, mOwner, _2, _3)); -			} +			// IDEVO +			//if (!gCacheName->getGroupName(group_id, name)) +			//{ +			//	gCacheName->get(group_id, TRUE, +			//					boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, mOwner, _2, _3)); +			//} +			name = LLSLURL("group", group_id, "inspect").getSLURLString();  		}  		else  		{  			LLUUID owner_id = perm.getOwner(); -			if (!gCacheName->getFullName(owner_id, name)) -			{ -				gCacheName->get(owner_id, FALSE, -								boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, mOwner, _2, _3)); -			} +			// IDEVO +			//if (!gCacheName->getFullName(owner_id, name)) +			//{ +			//	gCacheName->get(owner_id, FALSE, +			//					boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, mOwner, _2, _3)); +			//} +			name = LLSLURL("agent", owner_id, "inspect").getSLURLString();  		}  		mOwner->setText(name);  	} diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 0009f7203a..5fbe198f6f 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -211,7 +211,6 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,  	}  #if !USE_VIEWER_AUTH -	childSetPrevalidate("username_edit", LLTextValidate::validateASCIIPrintableNoPipe);  	getChild<LLLineEditor>("password_edit")->setKeystrokeCallback(onPassKey, this);  	// change z sort of clickable text to be behind buttons @@ -514,8 +513,16 @@ void LLPanelLogin::setFields(LLPointer<LLCredential> credential,  	LLSD identifier = credential->getIdentifier();  	if((std::string)identifier["type"] == "agent")   	{ -		sInstance->childSetText("username_edit", (std::string)identifier["first_name"] + " " +  -								(std::string)identifier["last_name"]);	 +		std::string firstname = identifier["first_name"].asString(); +		std::string lastname = identifier["last_name"].asString(); +	    std::string login_id = firstname; +	    if (!lastname.empty() && lastname != "Resident") +	    { +		    // support traditional First Last name SLURLs +		    login_id += " "; +		    login_id += lastname; +	    } +		sInstance->childSetText("username_edit", login_id);	  	}  	else if((std::string)identifier["type"] == "account")  	{ @@ -579,7 +586,8 @@ void LLPanelLogin::getFields(LLPointer<LLCredential>& credential,  	LL_INFOS2("Credentials", "Authentication") << "retrieving username:" << username << LL_ENDL;  	// determine if the username is a first/last form or not.  	size_t separator_index = username.find_first_of(' '); -	if (separator_index == username.npos) +	if (separator_index == username.npos +		&& !LLGridManager::getInstance()->isSystemGrid())  	{  		LL_INFOS2("Credentials", "Authentication") << "account: " << username << LL_ENDL;  		// single username, so this is a 'clear' identifier @@ -596,9 +604,23 @@ void LLPanelLogin::getFields(LLPointer<LLCredential>& credential,  	}  	else  	{ +		// Be lenient in terms of what separators we allow for two-word names +		// and allow legacy users to login with firstname.lastname +		separator_index = username.find_first_of(" ._");  		std::string first = username.substr(0, separator_index); -		std::string last = username.substr(separator_index, username.npos); -		LLStringUtil::trim(last); +		std::string last; +		if (separator_index != username.npos) +		{ +			last = username.substr(separator_index+1, username.npos); +			LLStringUtil::trim(last); +		} +		else +		{ +			// ...on Linden grids, single username users as considered to have +			// last name "Resident" +			// *TODO: Make login.cgi support "account_name" like above +			last = "Resident"; +		}  		if (last.find_first_of(' ') == last.npos)  		{ diff --git a/indra/newview/llpanelme.cpp b/indra/newview/llpanelme.cpp index 3f620869e0..c1d02fae39 100644 --- a/indra/newview/llpanelme.cpp +++ b/indra/newview/llpanelme.cpp @@ -32,17 +32,25 @@  #include "llviewerprecompiledheaders.h" +#include "llpanelme.h" + +// Viewer includes  #include "llpanelprofile.h"  #include "llavatarconstants.h" -#include "llpanelme.h"  #include "llagent.h"  #include "llagentcamera.h"  #include "llagentwearables.h" -#include "lliconctrl.h"  #include "llsidetray.h" +#include "llviewercontrol.h" +#include "llviewerdisplayname.h" + +// Linden libraries +#include "llavatarnamecache.h"		// IDEVO +#include "lliconctrl.h" +#include "llnotifications.h" +#include "llnotificationsutil.h"	// IDEVO  #include "lltabcontainer.h"  #include "lltexturectrl.h" -#include "llviewercontrol.h"  #define PICKER_SECOND_LIFE "2nd_life_pic"  #define PICKER_FIRST_LIFE "real_world_pic" @@ -180,6 +188,13 @@ void LLPanelMyProfileEdit::onOpen(const LLSD& key)  	// Disable editing until data is loaded, or edited fields will be overwritten when data  	// is loaded.  	enableEditing(false); + +	// Only allow changing name if this region/grid supports it +	bool use_display_names = LLAvatarNameCache::useDisplayNames(); +	LLUICtrl* set_name = getChild<LLUICtrl>("set_name"); +	set_name->setVisible(use_display_names); +	set_name->setEnabled(use_display_names); +  	LLPanelMyProfile::onOpen(getAvatarId());  } @@ -213,13 +228,21 @@ void LLPanelMyProfileEdit::processProfileProperties(const LLAvatarData* avatar_d  	childSetValue("show_in_search_checkbox", (BOOL)(avatar_data->flags & AVATAR_ALLOW_PUBLISH)); -	std::string first, last; -	BOOL found = gCacheName->getName(avatar_data->avatar_id, first, last); -	if (found) -	{ -		childSetTextArg("name_text", "[FIRST]", first); -		childSetTextArg("name_text", "[LAST]", last); -	} +	// IDEVO - These fields do not seem to exist any more. +	//std::string full_name; +	//BOOL found = gCacheName->getFullName(avatar_data->avatar_id, full_name); +	//if (found) +	//{ +	//	childSetTextArg("name_text", "[NAME]", full_name); +	//} +	LLAvatarNameCache::get(avatar_data->avatar_id, +		boost::bind(&LLPanelMyProfileEdit::onNameCache, this, _1, _2)); +} + +void LLPanelMyProfileEdit::onNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) +{ +	getChild<LLUICtrl>("user_name")->setValue( av_name.mDisplayName ); +	getChild<LLUICtrl>("user_slid")->setValue( av_name.mUsername );  }  BOOL LLPanelMyProfileEdit::postBuild() @@ -229,6 +252,9 @@ BOOL LLPanelMyProfileEdit::postBuild()  	childSetTextArg("partner_edit_link", "[URL]", getString("partner_edit_link_url"));  	childSetTextArg("my_account_link", "[URL]", getString("my_account_link_url")); +	getChild<LLUICtrl>("set_name")->setCommitCallback( +		boost::bind(&LLPanelMyProfileEdit::onClickSetName, this)); +  	return LLPanelAvatarProfile::postBuild();  }  /** @@ -256,8 +282,10 @@ void LLPanelMyProfileEdit::resetData()  {  	LLPanelMyProfile::resetData(); -	childSetTextArg("name_text", "[FIRST]", LLStringUtil::null); -	childSetTextArg("name_text", "[LAST]", LLStringUtil::null); +	//childSetTextArg("name_text", "[FIRST]", LLStringUtil::null); +	//childSetTextArg("name_text", "[LAST]", LLStringUtil::null); +	getChild<LLUICtrl>("user_name")->setValue( LLSD() ); +	getChild<LLUICtrl>("user_slid")->setValue( LLSD() );  }  void LLPanelMyProfileEdit::onTexturePickerMouseEnter(LLUICtrl* ctrl) @@ -269,6 +297,106 @@ void LLPanelMyProfileEdit::onTexturePickerMouseLeave(LLUICtrl* ctrl)  	mTextureEditIconMap[ctrl->getName()]->setVisible(FALSE);  } +void LLPanelMyProfileEdit::onCacheSetName(bool success, +										  const std::string& reason, +										  const LLSD& content) +{ +	if (success) +	{ +		// Inform the user that the change took place, but will take a while +		// to percolate. +		LLSD args; +		// *TODO: get estimated percolation time from service +		S32 timeout_hours = 72; +		args["HOURS"] = llformat("%d", timeout_hours); +		LLNotificationsUtil::add("SetDisplayNameSuccess", args); + +		// Re-fetch my name, as it may have been sanitized by the service +		LLAvatarNameCache::get(getAvatarId(), +			boost::bind(&LLPanelMyProfileEdit::onNameCache, this, _1, _2)); +		return; +	} + +	// Request failed, notify the user +	std::string error_tag = content["error_tag"].asString(); +	llinfos << "set name failure error_tag " << error_tag << llendl; + +	// We might have a localized string for this message +	if (!error_tag.empty() +		&& LLNotifications::getInstance()->templateExists(error_tag)) +	{ +		LLNotificationsUtil::add(error_tag); +		return; +	} + +	// The server error might have a localized message for us +	std::string lang_code = LLUI::getLanguage(); +	LLSD error_desc = content["error_description"]; +	if (error_desc.has( lang_code )) +	{ +		LLSD args; +		args["MESSAGE"] = error_desc[lang_code].asString(); +		LLNotificationsUtil::add("GenericAlert", args); +		return; +	} + +	// No specific error, throw a generic one +	LLNotificationsUtil::add("SetDisplayNameFailedGeneric"); +} + +void LLPanelMyProfileEdit::onDialogSetName(const LLSD& notification, const LLSD& response) +{ +	S32 option = LLNotificationsUtil::getSelectedOption(notification, response); +	if (option == 0) +	{ +		LLUUID agent_id = notification["payload"]["agent_id"]; +		if (agent_id.isNull()) return; + +		std::string display_name_utf8 = response["display_name"].asString(); + +		const U32 DISPLAY_NAME_MAX_LENGTH = 31; // characters, not bytes +		LLWString display_name_wstr = utf8string_to_wstring(display_name_utf8); +		if (display_name_wstr.size() > DISPLAY_NAME_MAX_LENGTH) +		{ +			LLSD args; +			args["LENGTH"] = llformat("%d", DISPLAY_NAME_MAX_LENGTH); +			LLNotificationsUtil::add("SetDisplayNameFailedLength", args); +			return; +		} + +		LLViewerDisplayName::set(display_name_utf8, +			boost::bind(&LLPanelMyProfileEdit::onCacheSetName, this, +				_1, _2, _3)); +	} +} + +void LLPanelMyProfileEdit::onClickSetName() +{ +	// IDEVO +	LLUUID agent_id = getAvatarId(); +	std::string display_name; +	LLAvatarName av_name; +	if (LLAvatarNameCache::useDisplayNames() +		&& LLAvatarNameCache::get(agent_id, &av_name)) +	{ +		display_name = av_name.mDisplayName; +	} +	else +	{ +		gCacheName->getFullName(agent_id, display_name); +	} + +	if (!display_name.empty()) +	{ +		LLSD args; +		args["DISPLAY_NAME"] = display_name; +		LLSD payload; +		payload["agent_id"] = agent_id; +		LLNotificationsUtil::add("SetDisplayName", args, payload,  +			boost::bind(&LLPanelMyProfileEdit::onDialogSetName, this, _1, _2)); +	} +} +  void LLPanelMyProfileEdit::enableEditing(bool enable)  {  	childSetEnabled("2nd_life_pic", enable); diff --git a/indra/newview/llpanelme.h b/indra/newview/llpanelme.h index f2b38de3d6..f3caf026dc 100644 --- a/indra/newview/llpanelme.h +++ b/indra/newview/llpanelme.h @@ -34,8 +34,9 @@  #define LL_LLPANELMEPROFILE_H  #include "llpanel.h" -#include "llpanelavatar.h" +#include "llpanelprofile.h" +class LLAvatarName;  class LLPanelMyProfileEdit;  class LLPanelProfile;  class LLIconCtrl; @@ -89,11 +90,15 @@ protected:  	/*virtual*/void resetData();  	void processProfileProperties(const LLAvatarData* avatar_data); +	void onNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);  private:  	void initTexturePickerMouseEvents();  	void onTexturePickerMouseEnter(LLUICtrl* ctrl);  	void onTexturePickerMouseLeave(LLUICtrl* ctrl); +	void onClickSetName(); +	void onDialogSetName(const LLSD& notification, const LLSD& response); +	void onCacheSetName(bool success, const std::string& reason, const LLSD& content);  	/**  	 * Enabled/disables controls to prevent overwriting edited data upon receiving diff --git a/indra/newview/llpanelmediasettingspermissions.cpp b/indra/newview/llpanelmediasettingspermissions.cpp index e5caaaaffc..227dbb3da7 100644 --- a/indra/newview/llpanelmediasettingspermissions.cpp +++ b/indra/newview/llpanelmediasettingspermissions.cpp @@ -115,7 +115,7 @@ void LLPanelMediaSettingsPermissions::draw()  		if(mPermsGroupName)  		{  			mPermsGroupName->setNameID(LLUUID::null, TRUE); -			mPermsGroupName->refresh(LLUUID::null, LLStringUtil::null, LLStringUtil::null, true); +			mPermsGroupName->refresh(LLUUID::null, std::string(), true);  			mPermsGroupName->setEnabled(false);  		};  	}; @@ -194,7 +194,7 @@ void LLPanelMediaSettingsPermissions::initValues( void* userdata, const LLSD& me              data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() );          };      }; -	 +  	// *NOTE: If any of a particular flavor is tentative, we have to disable   	// them all because of an architectural issue: namely that we represent   	// these as a bit field, and we can't selectively apply only one bit to all selected @@ -238,21 +238,21 @@ void LLPanelMediaSettingsPermissions::getValues( LLSD &fill_me_in, bool include_  {  	// moved over from the 'General settings' tab  	if (include_tentative || !mControls->getTentative()) fill_me_in[LLMediaEntry::CONTROLS_KEY] = (LLSD::Integer)mControls->getCurrentIndex(); -	 -	// *NOTE: For some reason, gcc does not like these symbol references in the  -	// expressions below (inside the static_casts).	 I have NO idea why :(. -	// For some reason, assigning them to const temp vars here fixes the link -	// error.  Bizarre. -	const U8 none = LLMediaEntry::PERM_NONE; -	const U8 owner = LLMediaEntry::PERM_OWNER; -	const U8 group = LLMediaEntry::PERM_GROUP; -	const U8 anyone = LLMediaEntry::PERM_ANYONE;  -	const LLSD::Integer control = static_cast<LLSD::Integer>( + +    // *NOTE: For some reason, gcc does not like these symbol references in the  +    // expressions below (inside the static_casts).  I have NO idea why :(. +    // For some reason, assigning them to const temp vars here fixes the link +    // error.  Bizarre. +    const U8 none = LLMediaEntry::PERM_NONE; +    const U8 owner = LLMediaEntry::PERM_OWNER; +    const U8 group = LLMediaEntry::PERM_GROUP; +    const U8 anyone = LLMediaEntry::PERM_ANYONE; +    const LLSD::Integer control = static_cast<LLSD::Integer>(  		(mPermsOwnerControl->getValue() ? owner : none ) |  		(mPermsGroupControl->getValue() ? group: none  ) |  		(mPermsWorldControl->getValue() ? anyone : none )); -	const LLSD::Integer interact = static_cast<LLSD::Integer>( -		(mPermsOwnerInteract->getValue() ? owner: none	) | +    const LLSD::Integer interact = static_cast<LLSD::Integer>( +		(mPermsOwnerInteract->getValue() ? owner: none  ) |  		(mPermsGroupInteract->getValue() ? group : none ) |  		(mPermsWorldInteract->getValue() ? anyone : none )); @@ -266,15 +266,15 @@ void LLPanelMediaSettingsPermissions::getValues( LLSD &fill_me_in, bool include_  		!mPermsGroupControl->getTentative() ||   		!mPermsWorldControl->getTentative())  	{ -		fill_me_in[LLMediaEntry::PERMS_CONTROL_KEY] = control; +    fill_me_in[LLMediaEntry::PERMS_CONTROL_KEY] = control;  	}  	if (include_tentative ||   		!mPermsOwnerInteract->getTentative() ||   		!mPermsGroupInteract->getTentative() ||   		!mPermsWorldInteract->getTentative())  	{ -		fill_me_in[LLMediaEntry::PERMS_INTERACT_KEY] = interact; -	} +    fill_me_in[LLMediaEntry::PERMS_INTERACT_KEY] = interact; +}  } diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp index 71d16a08b4..6bac4ae196 100644 --- a/indra/newview/llpanelpermissions.cpp +++ b/indra/newview/llpanelpermissions.cpp @@ -385,7 +385,7 @@ void LLPanelPermissions::refresh()  		if (mLabelGroupName)  		{  			mLabelGroupName->setNameID(LLUUID::null, TRUE); -			mLabelGroupName->refresh(LLUUID::null,LLStringUtil::null, LLStringUtil::null, TRUE); +			mLabelGroupName->refresh(LLUUID::null, std::string(), true);  			mLabelGroupName->setEnabled(FALSE);  		}  	} diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp index bde8d02885..291da5fdd2 100644 --- a/indra/newview/llpanelpicks.cpp +++ b/indra/newview/llpanelpicks.cpp @@ -235,9 +235,9 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)  		LLAvatarPicks* avatar_picks = static_cast<LLAvatarPicks*>(data);  		if(avatar_picks && getAvatarId() == avatar_picks->target_id)  		{ -			std::string name, second_name; -			gCacheName->getName(getAvatarId(),name,second_name); -			childSetTextArg("pick_title", "[NAME]",name); +			std::string full_name; +			gCacheName->getFullName(getAvatarId(), full_name); +			childSetTextArg("pick_title", "[NAME]", full_name);  			// Save selection, to be able to edit same item after saving changes. See EXT-3023.  			LLUUID selected_id = mPicksList->getSelectedValue()[PICK_ID]; diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp index f6133d4446..4c3d6e2758 100644 --- a/indra/newview/llpanelplaceinfo.cpp +++ b/indra/newview/llpanelplaceinfo.cpp @@ -281,9 +281,7 @@ void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global, LLPanelPickEdit*  }  // static -void LLPanelPlaceInfo::nameUpdatedCallback(LLTextBox* text, -										   const std::string& first, -										   const std::string& last) +void LLPanelPlaceInfo::onNameCache(LLTextBox* text, const std::string& full_name)  { -	text->setText(first + " " + last); +	text->setText(full_name);  } diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h index deedbd2b0f..0d7a09b5de 100644 --- a/indra/newview/llpanelplaceinfo.h +++ b/indra/newview/llpanelplaceinfo.h @@ -102,9 +102,7 @@ public:  	void createPick(const LLVector3d& pos_global, LLPanelPickEdit* pick_panel);  protected: -	static void nameUpdatedCallback(LLTextBox* text, -									const std::string& first, -									const std::string& last); +	static void onNameCache(LLTextBox* text, const std::string& full_name);  	/**  	 * mParcelID is valid only for remote places, in other cases it's null. See resetLocation()  diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp index c8abcc83c4..4a5be96a5e 100644 --- a/indra/newview/llpanelplaceprofile.cpp +++ b/indra/newview/llpanelplaceprofile.cpp @@ -50,7 +50,8 @@  #include "llagentui.h"  #include "llappviewer.h"  #include "llcallbacklist.h" -#include "llbuycurrencyhtml.h" +#include "llfloaterbuycurrency.h" +#include "llslurl.h"  #include "llstatusbar.h"  #include "llviewercontrol.h"  #include "llviewerparcelmgr.h" @@ -427,11 +428,11 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,  			if(!parcel->getGroupID().isNull())  			{  				// FIXME: Using parcel group as region group. -				gCacheName->get(parcel->getGroupID(), TRUE, -								boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, mRegionGroupText, _2, _3)); +				gCacheName->get(parcel->getGroupID(), true, +								boost::bind(&LLPanelPlaceInfo::onNameCache, mRegionGroupText, _2)); -				gCacheName->get(parcel->getGroupID(), TRUE, -								boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, mParcelOwner, _2, _3)); +				gCacheName->get(parcel->getGroupID(), true, +								boost::bind(&LLPanelPlaceInfo::onNameCache, mParcelOwner, _2));  			}  			else  			{ @@ -443,10 +444,14 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,  		else  		{  			// Figure out the owner's name -			gCacheName->get(parcel->getOwnerID(), FALSE, -							boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, mParcelOwner, _2, _3)); -			gCacheName->get(region->getOwner(), FALSE, -							boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, mRegionOwnerText, _2, _3)); +			// IDEVO +			//gCacheName->get(parcel->getOwnerID(), FALSE, +			//				boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, mParcelOwner, _2, _3)); +			std::string parcel_owner = +				LLSLURL("agent", parcel->getOwnerID(), "inspect").getSLURLString(); +			mParcelOwner->setText(parcel_owner); +			gCacheName->get(region->getOwner(), false, +							boost::bind(&LLPanelPlaceInfo::onNameCache, mRegionOwnerText, _2));  		}  		if(LLParcel::OS_LEASE_PENDING == parcel->getOwnershipStatus()) @@ -468,8 +473,8 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,  		const LLUUID& auth_buyer_id = parcel->getAuthorizedBuyerID();  		if(auth_buyer_id.notNull())  		{ -			gCacheName->get(auth_buyer_id, TRUE, -							boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, mSaleToText, _2, _3)); +			gCacheName->get(auth_buyer_id, true, +							boost::bind(&LLPanelPlaceInfo::onNameCache, mSaleToText, _2));  			// Show sales info to a specific person or a group he belongs to.  			if (auth_buyer_id != gAgent.getID() && !gAgent.isInGroup(auth_buyer_id)) diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h index f1aa3f10f8..be5b440050 100644 --- a/indra/newview/llpanelprofile.h +++ b/indra/newview/llpanelprofile.h @@ -33,7 +33,6 @@  #ifndef LL_LLPANELPROFILE_H  #define LL_LLPANELPROFILE_H -#include "llviewerprecompiledheaders.h"  #include "llpanel.h"  #include "llpanelavatar.h" diff --git a/indra/newview/llpanelprofileview.cpp b/indra/newview/llpanelprofileview.cpp index 044036ea50..d22d8d2718 100644 --- a/indra/newview/llpanelprofileview.cpp +++ b/indra/newview/llpanelprofileview.cpp @@ -32,11 +32,12 @@  #include "llviewerprecompiledheaders.h" +#include "llpanelprofileview.h" +  #include "llavatarconstants.h" +#include "llavatarnamecache.h"	// IDEVO  #include "lluserrelations.h" -#include "llpanelprofileview.h" -  #include "llavatarpropertiesprocessor.h"  #include "llcallingcard.h"  #include "llpanelavatar.h" @@ -104,11 +105,15 @@ void LLPanelProfileView::onOpen(const LLSD& key)  	if(id.notNull() && getAvatarId() != id)  	{  		setAvatarId(id); + +		// clear name fields, which might have old data +		getChild<LLUICtrl>("user_name")->setValue( LLSD() ); +		getChild<LLUICtrl>("user_slid")->setValue( LLSD() );  	}  	// Update the avatar name. -	gCacheName->get(getAvatarId(), FALSE, -		boost::bind(&LLPanelProfileView::onAvatarNameCached, this, _1, _2, _3, _4)); +	LLAvatarNameCache::get(getAvatarId(), +		boost::bind(&LLPanelProfileView::onAvatarNameCache, this, _1, _2));  	updateOnlineStatus(); @@ -198,10 +203,11 @@ void LLPanelProfileView::processOnlineStatus(bool online)  	mStatusText->setValue(status);  } -void LLPanelProfileView::onAvatarNameCached(const LLUUID& id, const std::string& first_name, const std::string& last_name, BOOL is_group) +void LLPanelProfileView::onAvatarNameCache(const LLUUID& agent_id, +										   const LLAvatarName& av_name)  { -	llassert(getAvatarId() == id); -	getChild<LLUICtrl>("user_name", FALSE)->setValue(first_name + " " + last_name); +	getChild<LLUICtrl>("user_name")->setValue( av_name.mDisplayName ); +	getChild<LLUICtrl>("user_slid")->setValue( av_name.mUsername );  }  // EOF diff --git a/indra/newview/llpanelprofileview.h b/indra/newview/llpanelprofileview.h index 9b87e146a8..dedb617c27 100644 --- a/indra/newview/llpanelprofileview.h +++ b/indra/newview/llpanelprofileview.h @@ -39,6 +39,7 @@  #include "llagent.h"  #include "lltooldraganddrop.h" +class LLAvatarName;  class LLPanelProfile;  class LLPanelProfileTab;  class LLTextBox; @@ -99,11 +100,11 @@ protected:  private:  	// LLCacheName will call this function when avatar name is loaded from server.  	// This is required to display names that have not been cached yet. -	void onAvatarNameCached( -		const LLUUID& id,  -		const std::string& first_name, -		const std::string& last_name, -		BOOL is_group); +//	void onNameCache( +//		const LLUUID& id,  +//		const std::string& full_name, +//		bool is_group); +	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);  	LLTextBox* mStatusText;  	AvatarStatusObserver* mAvatarStatusObserver; diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp index 6ebe55e362..2a0360460c 100644 --- a/indra/newview/llsidepaneltaskinfo.cpp +++ b/indra/newview/llsidepaneltaskinfo.cpp @@ -350,7 +350,7 @@ void LLSidepanelTaskInfo::refresh()  		if (mLabelGroupName)  		{  			mLabelGroupName->setNameID(LLUUID::null, TRUE); -			mLabelGroupName->refresh(LLUUID::null,LLStringUtil::null, LLStringUtil::null, TRUE); +			mLabelGroupName->refresh(LLUUID::null, std::string(), true);  			mLabelGroupName->setEnabled(FALSE);  		}  	} diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp index c8bb4aa983..b09ade15b8 100644 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -74,12 +74,13 @@ LLSpeaker::LLSpeaker(const LLUUID& id, const std::string& name, const ESpeakerTy  void LLSpeaker::lookupName()  { -	gCacheName->get(mID, FALSE, boost::bind(&LLSpeaker::onAvatarNameLookup, this, _1, _2, _3, _4)); +	gCacheName->get(mID, false, +		boost::bind(&LLSpeaker::onNameCache, this, _1, _2, _3));  } -void LLSpeaker::onAvatarNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group) +void LLSpeaker::onNameCache(const LLUUID& id, const std::string& full_name, bool is_group)  { -	mDisplayName = first + " " + last; +	mDisplayName = full_name;  }  bool LLSpeaker::isInVoiceChannel() diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h index 2bb160b7ce..402c2d95b9 100644 --- a/indra/newview/llspeakers.h +++ b/indra/newview/llspeakers.h @@ -66,7 +66,7 @@ public:  	~LLSpeaker() {};  	void lookupName(); -	void onAvatarNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group); +	void onNameCache(const LLUUID& id, const std::string& full_name, bool is_group);  	bool isInVoiceChannel(); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 0a464b3b6c..eb265e60b0 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" @@ -269,11 +270,10 @@ void apply_udp_blacklist(const std::string& csv);  bool process_login_success_response();  void transition_back_to_login_panel(const std::string& emsg); -void callback_cache_name(const LLUUID& id, const std::string& firstname, const std::string& lastname, BOOL is_group) +void callback_cache_name(const LLUUID& id, const std::string& full_name, bool is_group)  { -	LLNameListCtrl::refreshAll(id, firstname, lastname, is_group); -	LLNameBox::refreshAll(id, firstname, lastname, is_group); -	LLNameEditor::refreshAll(id, firstname, lastname, is_group); +	LLNameBox::refreshAll(id, full_name, is_group); +	LLNameEditor::refreshAll(id, full_name, is_group);  	// TODO: Actually be intelligent about the refresh.  	// For now, just brute force refresh the dialogs. @@ -1281,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 @@ -1628,7 +1619,6 @@ bool idle_startup()  			LLClassifiedInfo::loadCategories(classified_categories);  		} -  		// This method MUST be called before gInventory.findCategoryUUIDForType because of   		// gInventory.mIsAgentInvUsable is set to true in the gInventory.buildParentChildMap.  		gInventory.buildParentChildMap(); @@ -2639,6 +2629,33 @@ 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(); + +	// Start cache in not-running state until we figure out if we have +	// capabilities for display name lookup +	LLAvatarNameCache::initClass(false); +	LLAvatarNameCache::setUseDisplayNames(gSavedSettings.getBOOL("UseDisplayNames")); +} + +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 16cc74504f..0de42830aa 100644 --- a/indra/newview/llstartup.h +++ b/indra/newview/llstartup.h @@ -96,6 +96,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/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index ae244cd8a1..ebef28fd64 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -40,6 +40,7 @@  #include "llagent.h"  #include "llagentcamera.h" +#include "llavatarnamecache.h"  #include "llviewercontrol.h"  #include "llfocusmgr.h"  //#include "llfirstuse.h" @@ -859,23 +860,39 @@ BOOL LLToolPie::handleTooltipObject( LLViewerObject* hover_object, std::string l  			|| !existing_inspector->getVisible()  			|| existing_inspector->getKey()["avatar_id"].asUUID() != hover_object->getID())  		{ -			std::string avatar_name; +			// IDEVO JAMESDEBUG try to get display name + SLID +			std::string final_name; +			std::string full_name; +			if (!gCacheName->getFullName(hover_object->getID(), full_name)) +			{  			LLNameValue* firstname = hover_object->getNVPair("FirstName");  			LLNameValue* lastname =  hover_object->getNVPair("LastName");  			if (firstname && lastname)  			{ -				avatar_name = llformat("%s %s", firstname->getString(), lastname->getString()); +					full_name = LLCacheName::buildFullName( +						firstname->getString(), lastname->getString()); +				} +				else +				{ +					full_name = LLTrans::getString("TooltipPerson"); +				} +			} +			LLAvatarName av_name; +			if (LLAvatarNameCache::useDisplayNames() +				&& LLAvatarNameCache::get(hover_object->getID(), &av_name)) +			{ +				final_name = av_name.mDisplayName + " (" + av_name.mUsername + ")";  			}  			else  			{ -				avatar_name = LLTrans::getString("TooltipPerson"); +				final_name = full_name;  			}  			// *HACK: We may select this object, so pretend it was clicked  			mPick = mHoverPick;  			LLInspector::Params p;  			p.fillFrom(LLUICtrlFactory::instance().getDefaultParams<LLInspector>()); -			p.message(avatar_name); +			p.message(final_name);  			p.image.name("Inspector_I");  			p.click_callback(boost::bind(showAvatarInspector, hover_object->getID()));  			p.visible_time_near(6.f); diff --git a/indra/newview/lltracker.cpp b/indra/newview/lltracker.cpp index cc074287c4..c81a062ade 100644 --- a/indra/newview/lltracker.cpp +++ b/indra/newview/lltracker.cpp @@ -570,16 +570,16 @@ void LLTracker::renderBeacon(LLVector3d pos_global,  	std::string text;  	text = llformat( "%.0f m", to_vec.magVec()); -	LLWString wstr; -	wstr += utf8str_to_wstring(label); -	wstr += '\n'; -	wstr += utf8str_to_wstring(text); +	std::string str; +	str += label; +	str += '\n'; +	str += text;  	hud_textp->setFont(LLFontGL::getFontSansSerif());  	hud_textp->setZCompare(FALSE);  	hud_textp->setColor(LLColor4(1.f, 1.f, 1.f, llmax(0.2f, llmin(1.f,(dist-FADE_DIST)/FADE_DIST)))); -	hud_textp->setString(wstr); +	hud_textp->setString(str);  	hud_textp->setVertAlignment(LLHUDText::ALIGN_VERT_CENTER);  	hud_textp->setPositionAgent(pos_agent);  } diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 3482ac508e..3e30911847 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -323,7 +323,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  	LLImageGL::updateStats(gFrameTimeSeconds);  	LLVOAvatar::sRenderName = gSavedSettings.getS32("AvatarNameTagMode"); -	LLVOAvatar::sRenderGroupTitles = (gSavedSettings.getBOOL("RenderShowGroupTitleAll") && gSavedSettings.getS32("AvatarNameTagMode")); +	LLVOAvatar::sRenderGroupTitles = (gSavedSettings.getBOOL("NameTagShowGroupTitles") && gSavedSettings.getS32("AvatarNameTagMode"));  	gPipeline.mBackfaceCull = TRUE;  	gFrameCount++; diff --git a/indra/newview/llviewerdisplayname.cpp b/indra/newview/llviewerdisplayname.cpp new file mode 100644 index 0000000000..a783cb03d8 --- /dev/null +++ b/indra/newview/llviewerdisplayname.cpp @@ -0,0 +1,201 @@ +/**  + * @file llviewerdisplayname.cpp + * @brief Wrapper for display name functionality + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + *  + * Copyright (c) 2010, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#include "llviewerprecompiledheaders.h" + +#include "llviewerdisplayname.h" + +// viewer includes +#include "llagent.h" +#include "llviewerregion.h" +#include "llvoavatar.h" + +// library includes +#include "llavatarnamecache.h" +#include "llhttpclient.h" +#include "llhttpnode.h" +#include "llnotificationsutil.h" +#include "llui.h"					// getLanguage() + +namespace LLViewerDisplayName +{ +	// Fired when viewer receives server response to display name change +	set_name_signal_t sSetDisplayNameSignal; +} + +class LLSetDisplayNameResponder : public LLHTTPClient::Responder +{ +public: +	// only care about errors +	/*virtual*/ void error(U32 status, const std::string& reason) +	{ +		LLViewerDisplayName::sSetDisplayNameSignal(false, "", LLSD()); +		LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots(); +	} +}; + +void LLViewerDisplayName::set(const std::string& display_name, const set_name_slot_t& slot) +{ +	// TODO: simple validation here + +	LLViewerRegion* region = gAgent.getRegion(); +	llassert(region); +	std::string cap_url = region->getCapability("SetDisplayName"); +	if (cap_url.empty()) +	{ +		// this server does not support display names, report error +		slot(false, "unsupported", LLSD()); +		return; +	} + +	// People API can return localized error messages.  Indicate our +	// language preference via header. +	LLSD headers; +	headers["Accept-Language"] = LLUI::getLanguage(); + +	// People API requires both the old and new value to change a variable. +	// Our display name will be in cache before the viewer's UI is available +	// to request a change, so we can use direct lookup without callback. +	LLAvatarName av_name; +	if (!LLAvatarNameCache::get( gAgent.getID(), &av_name)) +	{ +		slot(false, "name unavailable", LLSD()); +		return; +	} + +	// People API expects array of [ "old value", "new value" ] +	LLSD change_array = LLSD::emptyArray(); +	change_array.append(av_name.mDisplayName); +	change_array.append(display_name); +	 +	llinfos << "Set name POST to " << cap_url << llendl; + +	// Record our caller for when the server sends back a reply +	sSetDisplayNameSignal.connect(slot); +	 +	// POST the requested change.  The sim will not send a response back to +	// this request directly, rather it will send a separate message after it +	// communicates with the back-end. +	LLSD body; +	body["display_name"] = change_array; +	LLHTTPClient::post(cap_url, body, new LLSetDisplayNameResponder, headers); +} + +class LLSetDisplayNameReply : public LLHTTPNode +{ +	LOG_CLASS(LLSetDisplayNameReply); +public: +	/*virtual*/ void post( +		LLHTTPNode::ResponsePtr response, +		const LLSD& context, +		const LLSD& input) const +	{ +		LLSD body = input["body"]; + +		S32 status = body["status"].asInteger(); +		bool success = (status == 200); +		std::string reason = body["reason"].asString(); +		LLSD content = body["content"]; + +		llinfos << "status " << status << " reason " << reason << llendl; + +		// If viewer's concept of display name is out-of-date, the set request +		// will fail with 409 Conflict.  If that happens, fetch up-to-date +		// name information. +		if (status == 409) +		{ +			LLUUID agent_id = gAgent.getID(); +			// Flush stale data +			LLAvatarNameCache::erase( agent_id ); +			// Queue request for new data +			LLAvatarName ignored; +			LLAvatarNameCache::get( agent_id, &ignored ); +			// Kill name tag, as it is wrong +			LLVOAvatar::invalidateNameTag( agent_id ); +		} + +		// inform caller of result +		LLViewerDisplayName::sSetDisplayNameSignal(success, reason, content); +		LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots(); +	} +}; + + +class LLDisplayNameUpdate : public LLHTTPNode +{ +	/*virtual*/ void post( +		LLHTTPNode::ResponsePtr response, +		const LLSD& context, +		const LLSD& input) const +	{ +		LLSD body = input["body"]; +		LLUUID agent_id = body["agent_id"]; +		std::string old_display_name = body["old_display_name"]; +		// By convention this record is called "agent" in the People API +		LLSD name_data = body["agent"]; + +		// Inject the new name data into cache +		LLAvatarName av_name; +		av_name.fromLLSD( name_data ); + +		// Name expiration time may be provided in headers, or we may use a +		// default value +		// JAMESDEBUG TODO: get actual headers out of ResponsePtr +		//LLSD headers = response->mHeaders; +		LLSD headers; +		av_name.mExpires =  +			LLAvatarNameCache::nameExpirationFromHeaders(headers); + +		LLAvatarNameCache::insert(agent_id, av_name); + +		// force name tag to update +		LLVOAvatar::invalidateNameTag(agent_id); + +		// Don't show a notification for my name, because we'll show a nicer +		// dialog +		if (agent_id != gAgent.getID()) +		{ +			LLSD args; +			args["OLD_NAME"] = old_display_name; +			args["SLID"] = av_name.mUsername; +			args["NEW_NAME"] = av_name.mDisplayName; +			LLNotificationsUtil::add("DisplayNameUpdate", args); +		} +	} +}; + +LLHTTPRegistration<LLSetDisplayNameReply> +    gHTTPRegistrationMessageSetDisplayNameReply( +		"/message/SetDisplayNameReply"); + +LLHTTPRegistration<LLDisplayNameUpdate> +    gHTTPRegistrationMessageDisplayNameUpdate( +		"/message/DisplayNameUpdate"); diff --git a/indra/newview/llviewerdisplayname.h b/indra/newview/llviewerdisplayname.h new file mode 100644 index 0000000000..c77388531b --- /dev/null +++ b/indra/newview/llviewerdisplayname.h @@ -0,0 +1,53 @@ +/**  + * @file llviewerdisplayname.h + * @brief Wrapper for display name functionality + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + *  + * Copyright (c) 2010, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#ifndef LLVIEWERDISPLAYNAME_H +#define LLVIEWERDISPLAYNAME_H + +#include <boost/signals2.hpp> + +class LLSD; +class LLUUID; + +namespace LLViewerDisplayName +{ +	typedef boost::signals2::signal< +		void (bool success, const std::string& reason, const LLSD& content)> +			set_name_signal_t; +	typedef set_name_signal_t::slot_type set_name_slot_t; + +	// Sends an update to the server to change a display name +	// and call back when done.  May not succeed due to service +	// unavailable or name not available. +	void set(const std::string& display_name, const set_name_slot_t& slot); +} + +#endif // LLVIEWERDISPLAYNAME_H diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index f0532d5a31..94dc2911f5 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -1705,9 +1705,9 @@ PermissionMask LLViewerInventoryItem::getPermissionMask() const  //---------- -void LLViewerInventoryItem::onCallingCardNameLookup(const LLUUID& id, const std::string& first_name, const std::string& last_name) +void LLViewerInventoryItem::onCallingCardNameLookup(const LLUUID& id, const std::string& name, bool is_group)  { -	rename(first_name + " " + last_name); +	rename(name);  	gInventory.addChangedMask(LLInventoryObserver::LABEL, getUUID());  	gInventory.notifyObservers();  } diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index 8ab7c9710d..3c841d93c6 100644 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -162,7 +162,7 @@ public:  	PermissionMask getPermissionMask() const;  	// callback -	void onCallingCardNameLookup(const LLUUID& id, const std::string& first_name, const std::string& last_name); +	void onCallingCardNameLookup(const LLUUID& id, const std::string& name, bool is_group);  	// If this is a broken link, try to fix it and any other identical link.  	BOOL regenerateLink(); diff --git a/indra/newview/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp index 2b4b78d82d..b230203561 100644 --- a/indra/newview/llviewerjointattachment.cpp +++ b/indra/newview/llviewerjointattachment.cpp @@ -39,6 +39,7 @@  #include "llviewercontrol.h"  #include "lldrawable.h"  #include "llgl.h" +#include "llhudtext.h"  #include "llrender.h"  #include "llvoavatar.h"  #include "llvolume.h" diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 10ceab2656..bcd3a79a8a 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -34,6 +34,7 @@  #include "llviewermenu.h"   // linden library includes +#include "llavatarnamecache.h"	// IDEVO  #include "llfloaterreg.h"  #include "llcombobox.h"  #include "llinventorypanel.h" @@ -107,7 +108,6 @@  #include "llfloatercamera.h"  #include "lluilistener.h"  #include "llappearancemgr.h" -#include "lltrans.h"  using namespace LLVOAvatarDefines; @@ -2781,9 +2781,8 @@ class LLObjectMute : public view_listener_t  			LLNameValue *lastname = avatar->getNVPair("LastName");  			if (firstname && lastname)  			{ -				name = firstname->getString(); -				name += " "; -				name += lastname->getString(); +				name = LLCacheName::buildFullName( +					firstname->getString(), lastname->getString());  			}  			type = LLMute::AGENT; @@ -3129,58 +3128,6 @@ bool enable_freeze_eject(const LLSD& avatar_id)  	return new_value;  } -class LLAvatarGiveCard : public view_listener_t -{ -	bool handleEvent(const LLSD& userdata) -	{ -		llinfos << "handle_give_card()" << llendl; -		LLViewerObject* dest = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); -		if(dest && dest->isAvatar()) -		{ -			bool found_name = false; -			LLSD args; -			LLSD old_args; -			LLNameValue* nvfirst = dest->getNVPair("FirstName"); -			LLNameValue* nvlast = dest->getNVPair("LastName"); -			if(nvfirst && nvlast) -			{ -				args["FIRST"] = nvfirst->getString(); -				args["LAST"] = nvlast->getString(); -				old_args["FIRST"] = nvfirst->getString(); -				old_args["LAST"] = nvlast->getString(); -				found_name = true; -			} -			LLViewerRegion* region = dest->getRegion(); -			LLHost dest_host; -			if(region) -			{ -				dest_host = region->getHost(); -			} -			if(found_name && dest_host.isOk()) -			{ -				LLMessageSystem* msg = gMessageSystem; -				msg->newMessage("OfferCallingCard"); -				msg->nextBlockFast(_PREHASH_AgentData); -				msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); -				msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); -				msg->nextBlockFast(_PREHASH_AgentBlock); -				msg->addUUIDFast(_PREHASH_DestID, dest->getID()); -				LLUUID transaction_id; -				transaction_id.generate(); -				msg->addUUIDFast(_PREHASH_TransactionID, transaction_id); -				msg->sendReliable(dest_host); -				LLNotificationsUtil::add("OfferedCard", args); -			} -			else -			{ -				LLNotificationsUtil::add("CantOfferCallingCard", old_args); -			} -		} -		return true; -	} -}; - -  void login_done(S32 which, void *user)  { @@ -3600,21 +3547,17 @@ void request_friendship(const LLUUID& dest_id)  	LLViewerObject* dest = gObjectList.findObject(dest_id);  	if(dest && dest->isAvatar())  	{ -		std::string fullname; -		LLSD args; +		std::string full_name;  		LLNameValue* nvfirst = dest->getNVPair("FirstName");  		LLNameValue* nvlast = dest->getNVPair("LastName");  		if(nvfirst && nvlast)  		{ -			args["FIRST"] = nvfirst->getString(); -			args["LAST"] = nvlast->getString(); -			fullname = nvfirst->getString(); -			fullname += " "; -			fullname += nvlast->getString(); +			full_name = LLCacheName::buildFullName( +				nvfirst->getString(), nvlast->getString());  		} -		if (!fullname.empty()) +		if (!full_name.empty())  		{ -			LLAvatarActions::requestFriendshipDialog(dest_id, fullname); +			LLAvatarActions::requestFriendshipDialog(dest_id, full_name);  		}  		else  		{ @@ -7825,6 +7768,7 @@ void initialize_menus()  	view_listener_t::addMenu(new LLAdvancedToggleConsole(), "Advanced.ToggleConsole");  	view_listener_t::addMenu(new LLAdvancedCheckConsole(), "Advanced.CheckConsole");  	view_listener_t::addMenu(new LLAdvancedDumpInfoToConsole(), "Advanced.DumpInfoToConsole"); +	  	// Advanced > HUD Info  	view_listener_t::addMenu(new LLAdvancedToggleHUDInfo(), "Advanced.ToggleHUDInfo");  	view_listener_t::addMenu(new LLAdvancedCheckHUDInfo(), "Advanced.CheckHUDInfo"); @@ -8003,7 +7947,6 @@ void initialize_menus()  	view_listener_t::addMenu(new LLAvatarDebug(), "Avatar.Debug");  	view_listener_t::addMenu(new LLAvatarVisibleDebug(), "Avatar.VisibleDebug");  	view_listener_t::addMenu(new LLAvatarInviteToGroup(), "Avatar.InviteToGroup"); -	view_listener_t::addMenu(new LLAvatarGiveCard(), "Avatar.GiveCard");  	commit.add("Avatar.Eject", boost::bind(&handle_avatar_eject, LLSD()));  	view_listener_t::addMenu(new LLAvatarSendIM(), "Avatar.SendIM");  	view_listener_t::addMenu(new LLAvatarCall(), "Avatar.Call"); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 5836aff4e7..bb64494d87 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -34,9 +34,11 @@  #include "llviewermessage.h"  #include "boost/lexical_cast.hpp" +// Linden libraries  #include "llanimationstates.h"  #include "llaudioengine.h"   #include "llavataractions.h" +#include "llavatarnamecache.h"		// IDEVO HACK  #include "lscript_byteformat.h"  #include "lleconomy.h"  #include "lleventtimer.h" @@ -84,6 +86,7 @@  #include "llspeakers.h"  #include "lltrans.h"  #include "llviewerfoldertype.h" +#include "llvoavatar.h"				// IDEVO HACK  #include "lluri.h"  #include "llviewergenericmessage.h"  #include "llviewermenu.h" @@ -136,6 +139,7 @@ extern BOOL gDebugClicks;  // function prototypes  bool check_offer_throttle(const std::string& from_name, bool check_only); +static void process_money_balance_reply_extended(LLMessageSystem* msg);  //inventory offer throttle globals  LLFrameTimer gThrottleTimer; @@ -1197,27 +1201,24 @@ bool highlight_offered_item(const LLUUID& item_id)  }  void inventory_offer_mute_callback(const LLUUID& blocked_id, -								   const std::string& first_name, -								   const std::string& last_name, -								   BOOL is_group, LLOfferInfo* offer = NULL) +								   const std::string& full_name, +								   bool is_group, +								   LLOfferInfo* offer = NULL)  { -	std::string from_name; +	std::string from_name = full_name;  	LLMute::EType type;  	if (is_group)  	{  		type = LLMute::GROUP; -		from_name = first_name;  	}  	else if(offer && offer->mFromObject)  	{  		//we have to block object by name because blocked_id is an id of owner  		type = LLMute::BY_NAME; -		from_name = offer->mFromName;  	}  	else  	{  		type = LLMute::AGENT; -		from_name = first_name + " " + last_name;  	}  	// id should be null for BY_NAME mute, see  LLMuteList::add for details   @@ -1390,7 +1391,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&  	// * we can't build two messages at once.  	if (2 == button) // Block  	{ -		gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,_4,this)); +		gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,this));  	}  	std::string from_string; // Used in the pop-up. @@ -1524,7 +1525,7 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const  	// * we can't build two messages at once.  	if (2 == button)  	{ -		gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,_4,this)); +		gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,this));  	}  	LLMessageSystem* msg = gMessageSystem; @@ -1572,12 +1573,12 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const  		}  		else  		{ -			std::string first_name, last_name; -			if (gCacheName->getName(mFromID, first_name, last_name)) +			std::string full_name; +			if (gCacheName->getFullName(mFromID, full_name))  			{  				from_string = LLTrans::getString("InvOfferAnObjectNamed") + " "+ LLTrans::getString("'") + mFromName  -				+ LLTrans::getString("'")+" " + LLTrans::getString("InvOfferOwnedBy") + first_name + " " + last_name; -				chatHistory_string = mFromName + " " + LLTrans::getString("InvOfferOwnedBy") + " " + first_name + " " + last_name; +					+ LLTrans::getString("'")+" " + LLTrans::getString("InvOfferOwnedBy") + full_name; +				chatHistory_string = mFromName + " " + LLTrans::getString("InvOfferOwnedBy") + " " + full_name;  			}  			else  			{ @@ -1781,7 +1782,14 @@ void inventory_offer_handler(LLOfferInfo* info)  	payload["give_inventory_notification"] = FALSE;  	args["OBJECTFROMNAME"] = info->mFromName;  	args["NAME"] = info->mFromName; -	args["NAME_SLURL"] = LLSLURL("agent", info->mFromID, "about").getSLURLString(); +	if (info->mFromGroup) +	{ +		args["NAME_SLURL"] = LLSLURL("group", info->mFromID, "about").getSLURLString(); +	} +	else +	{ +		args["NAME_SLURL"] = LLSLURL("agent", info->mFromID, "about").getSLURLString(); +	}  	std::string verb = "select?name=" + LLURI::escape(msg);  	args["ITEM_SLURL"] = LLSLURL("inventory", info->mObjectID, verb.c_str()).getSLURLString(); @@ -1964,6 +1972,75 @@ static bool parse_lure_bucket(const std::string& bucket,  	return true;  } +// Strip out "Resident" for display, but only if the message came from a user +// (rather than a script) +static std::string clean_name_from_im(const std::string& name, EInstantMessage type) +{ +	switch(type) +	{ +	case IM_NOTHING_SPECIAL: +	case IM_MESSAGEBOX: +	case IM_GROUP_INVITATION: +	case IM_INVENTORY_OFFERED: +	case IM_INVENTORY_ACCEPTED: +	case IM_INVENTORY_DECLINED: +	case IM_GROUP_VOTE: +	case IM_GROUP_MESSAGE_DEPRECATED: +	//IM_TASK_INVENTORY_OFFERED +	//IM_TASK_INVENTORY_ACCEPTED +	//IM_TASK_INVENTORY_DECLINED +	case IM_NEW_USER_DEFAULT: +	case IM_SESSION_INVITE: +	case IM_SESSION_P2P_INVITE: +	case IM_SESSION_GROUP_START: +	case IM_SESSION_CONFERENCE_START: +	case IM_SESSION_SEND: +	case IM_SESSION_LEAVE: +	//IM_FROM_TASK +	case IM_BUSY_AUTO_RESPONSE: +	case IM_CONSOLE_AND_CHAT_HISTORY: +	case IM_LURE_USER: +	case IM_LURE_ACCEPTED: +	case IM_LURE_DECLINED: +	case IM_GODLIKE_LURE_USER: +	case IM_YET_TO_BE_USED: +	case IM_GROUP_ELECTION_DEPRECATED: +	//IM_GOTO_URL +	//IM_FROM_TASK_AS_ALERT +	case IM_GROUP_NOTICE: +	case IM_GROUP_NOTICE_INVENTORY_ACCEPTED: +	case IM_GROUP_NOTICE_INVENTORY_DECLINED: +	case IM_GROUP_INVITATION_ACCEPT: +	case IM_GROUP_INVITATION_DECLINE: +	case IM_GROUP_NOTICE_REQUESTED: +	case IM_FRIENDSHIP_OFFERED: +	case IM_FRIENDSHIP_ACCEPTED: +	case IM_FRIENDSHIP_DECLINED_DEPRECATED: +	//IM_TYPING_START +	//IM_TYPING_STOP +		return LLCacheName::cleanFullName(name); +	default: +		return name; +	} +} + +static std::string clean_name_from_task_im(const std::string& msg) +{ +	boost::smatch match; +	static const boost::regex returned_exp( +		"(.*been returned to your inventory lost and found folder by )(.+)( (from|near).*)"); +	if (boost::regex_match(msg, match, returned_exp)) +	{ +		// match objects are 1-based for groups +		std::string final = match[1].str(); +		std::string name = match[2].str(); +		final += LLCacheName::cleanFullName(name); +		final += match[3].str(); +		return final; +	} +	return msg; +} +  void process_improved_im(LLMessageSystem *msg, void **user_data)  {  	if (gNoRender) @@ -2011,6 +2088,8 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)  	{          name = LLTrans::getString("Unnamed");  	} +	// IDEVO convert new-style "Resident" names for display +	name = clean_name_from_im(name, dialog);  	BOOL is_busy = gAgent.getBusy();  	BOOL is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat); @@ -2317,6 +2396,15 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)  				invite_bucket = (struct invite_bucket_t*) &binary_bucket[0];  				S32 membership_fee = ntohl(invite_bucket->membership_fee); +				// IDEVO Clean up legacy name "Resident" in message constructed in +				// lldatagroups.cpp +				U32 pos = message.find(" has invited you to join a group.\n"); +				if (pos != std::string::npos) +				{ +					// use cleaned-up name from above +					message = name + message.substr(pos); +				} +  				LLSD payload;  				payload["transaction_id"] = session_id;  				payload["group_id"] = from_id; @@ -2504,6 +2592,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)  				chat.mSourceType = CHAT_SOURCE_SYSTEM;  			} +			// IDEVO Some messages have embedded resident names +			message = clean_name_from_task_im(message); +  			LLSD query_string;  			query_string["owner"] = from_id;  			query_string["slurl"] = location; @@ -2816,9 +2907,8 @@ void process_offer_callingcard(LLMessageSystem* msg, void**)  		LLNameValue* nvlast  = source->getNVPair("LastName");  		if (nvfirst && nvlast)  		{ -			args["FIRST"] = nvfirst->getString(); -			args["LAST"] = nvlast->getString(); -			source_name = std::string(nvfirst->getString()) + " " + nvlast->getString(); +			source_name = LLCacheName::buildFullName( +				nvfirst->getString(), nvlast->getString());  		}  	} @@ -2851,7 +2941,6 @@ void process_decline_callingcard(LLMessageSystem* msg, void**)  	LLNotificationsUtil::add("CallingCardDeclined");  } -  void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)  {  	LLChat	chat; @@ -2867,7 +2956,6 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)  	LLViewerObject*	chatter;  	msg->getString("ChatData", "FromName", from_name); -	chat.mFromName = from_name;  	msg->getUUID("ChatData", "SourceID", from_id);  	chat.mFromID = from_id; @@ -2886,6 +2974,27 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)  	chat.mTime = LLFrameTimer::getElapsedSeconds(); +	// IDEVO Correct for new-style "Resident" names +	if (chat.mSourceType == CHAT_SOURCE_AGENT) +	{ +		// JAMESDEBUG - I don't know if it's OK to change this here, if  +		// anything downstream does lookups by name, for instance +		LLAvatarName av_name; +		if (LLAvatarNameCache::useDisplayNames() +			&& LLAvatarNameCache::get(from_id, &av_name)) +		{ +			chat.mFromName = av_name.mDisplayName; +		} +		else +		{ +			chat.mFromName = LLCacheName::cleanFullName(from_name); +		} +	} +	else +	{ +		chat.mFromName = from_name; +	} +  	BOOL is_busy = gAgent.getBusy();  	BOOL is_muted = FALSE; @@ -4742,168 +4851,239 @@ void process_time_dilation(LLMessageSystem *msg, void **user_data)  */ -  void process_money_balance_reply( LLMessageSystem* msg, void** )  {  	S32 balance = 0;  	S32 credit = 0;  	S32 committed = 0;  	std::string desc; +	LLUUID tid; +	msg->getUUID("MoneyData", "TransactionID", tid);  	msg->getS32("MoneyData", "MoneyBalance", balance);  	msg->getS32("MoneyData", "SquareMetersCredit", credit);  	msg->getS32("MoneyData", "SquareMetersCommitted", committed);  	msg->getStringFast(_PREHASH_MoneyData, _PREHASH_Description, desc);  	LL_INFOS("Messaging") << "L$, credit, committed: " << balance << " " << credit << " "  			<< committed << LL_ENDL; - +      	if (gStatusBar)  	{ -	//	S32 old_balance = gStatusBar->getBalance(); - -		// This is an update, not the first transmission of balance -	/*	if (old_balance != 0) -		{ -			// this is actually an update -			if (balance > old_balance) -			{ -				LLFirstUse::useBalanceIncrease(balance - old_balance); -			} -			else if (balance < old_balance) -			{ -				LLFirstUse::useBalanceDecrease(balance - old_balance); -			} -		} -	 */  		gStatusBar->setBalance(balance);  		gStatusBar->setLandCredit(credit);  		gStatusBar->setLandCommitted(committed);  	} -	LLUUID tid; -	msg->getUUID("MoneyData", "TransactionID", tid); +	if (desc.empty() +		|| !gSavedSettings.getBOOL("NotifyMoneyChange")) +	{ +		// ...nothing to display +		return; +	} + +	// Suppress duplicate messages about the same transaction  	static std::deque<LLUUID> recent; -	if(!desc.empty() && gSavedSettings.getBOOL("NotifyMoneyChange") -	   && (std::find(recent.rbegin(), recent.rend(), tid) == recent.rend())) +	if (std::find(recent.rbegin(), recent.rend(), tid) != recent.rend())  	{ -		// Make the user confirm the transaction, since they might -		// have missed something during an event. -		// *TODO: Translate -		LLSD args; -		 +		return; +	} -		// this is a marker to retrieve avatar name from server message: -		// "<avatar name> paid you L$" -		const std::string marker = "paid you L$"; +	// Once the 'recent' container gets large enough, chop some +	// off the beginning. +	const U32 MAX_LOOKBACK = 30; +	const S32 POP_FRONT_SIZE = 12; +	if(recent.size() > MAX_LOOKBACK) +	{ +		LL_DEBUGS("Messaging") << "Removing oldest transaction records" << LL_ENDL; +		recent.erase(recent.begin(), recent.begin() + POP_FRONT_SIZE); +	} +	//LL_DEBUGS("Messaging") << "Pushing back transaction " << tid << LL_ENDL; +	recent.push_back(tid); +	if (msg->has("TransactionInfo")) +	{ +		// ...message has extended info for localization +		process_money_balance_reply_extended(msg); +	} +	else +	{ +		// Only old dev grids will not supply the TransactionInfo block, +		// so we can just use the hard-coded English string. +		LLSD args;  		args["MESSAGE"] = desc; +		LLNotificationsUtil::add("SystemMessage", args); +	} +} -		// extract avatar name from system message -		S32 marker_pos = desc.find(marker, 0); +static std::string reason_from_transaction_type(S32 transaction_type, +												const std::string& item_desc) +{ +	// *NOTE: The keys for the reason strings are unusual because +	// an earlier version of the code used English language strings +	// extracted from hard-coded server English descriptions. +	// Keeping them so we don't have to re-localize them. +	switch (transaction_type) +	{ +		case TRANS_OBJECT_SALE: +		{ +			LLStringUtil::format_map_t arg; +			arg["ITEM"] = item_desc; +			return LLTrans::getString("for item", arg); +		} +		case TRANS_LAND_SALE: +			return LLTrans::getString("for a parcel of land"); +			 +		case TRANS_LAND_PASS_SALE: +			return LLTrans::getString("for a land access pass"); +			 +		case TRANS_GROUP_LAND_DEED: +			return LLTrans::getString("for deeding land"); +			 +		case TRANS_GROUP_CREATE: +			return LLTrans::getString("to create a group"); +			 +		case TRANS_GROUP_JOIN: +			return LLTrans::getString("to join a group"); +			 +		case TRANS_UPLOAD_CHARGE: +			return LLTrans::getString("to upload"); +			 +		default: +			llwarns << "Unknown transaction type "  +				<< transaction_type << llendl; +			return std::string(); +	} +} -		std::string base_name = desc.substr(0, marker_pos); -		 -		std::string name = base_name; -		LLStringUtil::trim(name); +static void money_balance_group_notify(const LLUUID& group_id, +									   const std::string& name, +									   bool is_group, +									   std::string notification, +									   LLSD args, +									   LLSD payload) +{ +	// Message uses name SLURLs, don't actually have to substitute in +	// the name.  We're just making sure it's available. +	// Notification is either PaymentReceived or PaymentSent +	LLNotificationsUtil::add(notification, args, payload); +} -		// if name extracted and name cache contains avatar id send loggable notification -		LLUUID from_id; -		if(name.size() > 0 && gCacheName->getUUID(name, from_id)) -		{ -			//description always comes not localized. lets fix this +static void money_balance_avatar_notify(const LLUUID& agent_id, +										const LLAvatarName& av_name, +									   	std::string notification, +									   	LLSD args, +									   	LLSD payload) +{ +	// Message uses name SLURLs, don't actually have to substitute in +	// the name.  We're just making sure it's available. +	// Notification is either PaymentReceived or PaymentSent +	LLNotificationsUtil::add(notification, args, payload); +} -			//ammount paid -			std::string ammount = desc.substr(marker_pos + marker.length(),desc.length() - marker.length() - marker_pos); +static void process_money_balance_reply_extended(LLMessageSystem* msg) +{ +    // Added in server 1.40 and viewer 2.1, support for localization +    // and agent ids for name lookup. +    S32 transaction_type = 0; +    LLUUID source_id; +	BOOL is_source_group = FALSE; +    LLUUID dest_id; +	BOOL is_dest_group = FALSE; +    S32 amount = 0; +    std::string item_description; + +    msg->getS32("TransactionInfo", "TransactionType", transaction_type); +    msg->getUUID("TransactionInfo", "SourceID", source_id); +	msg->getBOOL("TransactionInfo", "IsSourceGroup", is_source_group); +    msg->getUUID("TransactionInfo", "DestID", dest_id); +	msg->getBOOL("TransactionInfo", "IsDestGroup", is_dest_group); +    msg->getS32("TransactionInfo", "Amount", amount); +    msg->getString("TransactionInfo", "ItemDescription", item_description); +    LL_INFOS("Money") << "MoneyBalanceReply source " << source_id  +		<< " dest " << dest_id +		<< " type " << transaction_type +		<< " item " << item_description << LL_ENDL; + +	const char* source_type = (is_source_group ? "group" : "agent"); +	std::string source_slurl = +		LLSLURL( source_type, source_id, "inspect").getSLURLString(); -			//reform description -			LLStringUtil::format_map_t str_args; -			str_args["NAME"] = base_name; -			str_args["AMOUNT"] = ammount; -			std::string new_description = LLTrans::getString("paid_you_ldollars", str_args); +	const char* dest_type = (is_dest_group ? "group" : "agent"); +	std::string dest_slurl = +		LLSLURL( dest_type, dest_id, "inspect").getSLURLString(); - -			args["MESSAGE"] = new_description; -			args["NAME"] = name; -			LLSD payload; -			payload["from_id"] = from_id; -			LLNotificationsUtil::add("PaymentRecived", args, payload); +	std::string reason = +		reason_from_transaction_type(transaction_type, item_description); +	 +	LLStringUtil::format_map_t args; +	args["REASON"] = reason; // could be empty +	args["AMOUNT"] = llformat("%d", amount); +	 +	// Need to delay until name looked up, so need to know whether or not +	// is group +	bool is_name_group = false; +	LLUUID name_id; +	std::string message; +	std::string notification; +	LLSD final_args; +	LLSD payload; +	 +	bool you_paid_someone = (source_id == gAgentID); +	if (you_paid_someone) +	{ +		args["NAME"] = dest_slurl; +		is_name_group = is_dest_group; +		name_id = dest_id; +		if (!reason.empty()) +		{ +			message = LLTrans::getString("you_paid_ldollars", args);  		} -		//AD *HACK: Parsing incoming string to localize messages that come from server! EXT-5986 -		// It's only a temporarily and ineffective measure. It doesn't affect performance much -		// because we get here only for specific type of messages, but anyway it is not right to do it! -		// *TODO: Server-side changes should be made and this code removed.  		else  		{ -			if(desc.find("You paid")==0) -			{ -				// Regular expression for message parsing- change it in case of server-side changes. -				// Each set of parenthesis will later be used to find arguments of message we generate -				// in the end of this if- (.*) gives us name of money receiver, (\\d+)-amount of money we pay -				// and ([^$]*)- reason of payment -				boost::regex expr("You paid (?:.{0}|(.*) )L\\$(\\d+)\\s?([^$]*)\\."); -				boost::match_results <std::string::const_iterator> matches; -				if(boost::regex_match(desc, matches, expr)) -				{ -					// Name of full localizable notification string -					// there are four types of this string- with name of receiver and reason of payment, -					// without name and without reason (both may also be absent simultaneously). -					// example of string without name - You paid L$100 to create a group. -					// example of string without reason - You paid Smdby Linden L$100. -					// example of string with reason and name - You paid Smbdy Linden L$100 for a land access pass. -					// example of string with no info - You paid L$50. -					std::string line = "you_paid_ldollars_no_name"; - -					// arguments of string which will be in notification -					LLStringUtil::format_map_t str_args; - -					// extracting amount of money paid (without L$ symbols). It is always present. -					str_args["[AMOUNT]"] = std::string(matches[2]); - -					// extracting name of person/group you are paying (it may be absent) -					std::string name = std::string(matches[1]); -					if(!name.empty()) -					{ -						str_args["[NAME]"] = name; -						line = "you_paid_ldollars"; -					} - -					// extracting reason of payment (it may be absent) -					std::string reason = std::string(matches[3]); -					if (reason.empty()) -					{ -						line = name.empty() ? "you_paid_ldollars_no_info" : "you_paid_ldollars_no_reason"; -					} -					else -					{ -						std::string localized_reason; -						// if we haven't found localized string for reason of payment leave it as it was -						str_args["[REASON]"] =  LLTrans::findString(localized_reason, reason) ? localized_reason : reason; -					} - -					// forming final message string by retrieving localized version from xml -					// and applying previously found arguments -					line = LLTrans::getString(line, str_args); -					args["MESSAGE"] = line; -				} -			} - -			LLNotificationsUtil::add("SystemMessage", args); +			message = LLTrans::getString("you_paid_ldollars_no_reason", args);  		} - -		// Once the 'recent' container gets large enough, chop some -		// off the beginning. -		const U32 MAX_LOOKBACK = 30; -		const S32 POP_FRONT_SIZE = 12; -		if(recent.size() > MAX_LOOKBACK) +		final_args["MESSAGE"] = message; +		notification = "PaymentSent"; +	} +	else { +		// ...someone paid you +		args["NAME"] = source_slurl; +		is_name_group = is_source_group; +		name_id = source_id; +		if (!reason.empty())  		{ -			LL_DEBUGS("Messaging") << "Removing oldest transaction records" << LL_ENDL; -			recent.erase(recent.begin(), recent.begin() + POP_FRONT_SIZE); +			message = LLTrans::getString("paid_you_ldollars", args);  		} -		//LL_DEBUGS("Messaging") << "Pushing back transaction " << tid << LL_ENDL; -		recent.push_back(tid); +		else { +			message = LLTrans::getString("paid_you_ldollars_no_reason", args); +		} +		final_args["MESSAGE"] = message; + +		// make notification loggable +		payload["from_id"] = source_id; +		notification = "PaymentReceived"; +	} + +	// Despite using SLURLs, wait until the name is available before +	// showing the notification, otherwise the UI layout is strange and +	// the user sees a "Loading..." message +	if (is_name_group) +	{ +		gCacheName->get(name_id, true, +						boost::bind(&money_balance_group_notify, +									_1, _2, _3, +									notification, final_args, payload)); +	} +	else { +		LLAvatarNameCache::get(name_id, +							   boost::bind(&money_balance_avatar_notify, +										   _1, _2, +										   notification, final_args, payload));										     	}  } + +  bool handle_special_notification_callback(const LLSD& notification, const LLSD& response)  {  	S32 option = LLNotificationsUtil::getSelectedOption(notification, response); @@ -5145,7 +5325,7 @@ void handle_show_mean_events(void *)  	//LLFloaterBump::showInstance();  } -void mean_name_callback(const LLUUID &id, const std::string& first, const std::string& last, BOOL always_false) +void mean_name_callback(const LLUUID &id, const std::string& full_name, bool is_group)  {  	if (gNoRender)  	{ @@ -5167,8 +5347,7 @@ void mean_name_callback(const LLUUID &id, const std::string& first, const std::s  		LLMeanCollisionData *mcd = *iter;  		if (mcd->mPerp == id)  		{ -			mcd->mFirstName = first; -			mcd->mLastName = last; +			mcd->mFullName = full_name;  		}  	}  } @@ -5222,8 +5401,7 @@ void process_mean_collision_alert_message(LLMessageSystem *msgsystem, void **use  		{  			LLMeanCollisionData *mcd = new LLMeanCollisionData(gAgentID, perp, time, type, mag);  			gMeanCollisionList.push_front(mcd); -			const BOOL is_group = FALSE; -			gCacheName->get(perp, is_group, &mean_name_callback); +			gCacheName->get(perp, false, boost::bind(&mean_name_callback, _1, _2, _3));  		}  	}  } @@ -5445,7 +5623,7 @@ void process_script_question(LLMessageSystem *msg, void **user_data)  	// so we'll reuse the same namespace for both throttle types.  	std::string throttle_name = owner_name;  	std::string self_name; -	LLAgentUI::buildName( self_name ); +	LLAgentUI::buildFullname( self_name );  	if( owner_name == self_name )  	{  		throttle_name = taskid.getString(); @@ -5481,7 +5659,7 @@ void process_script_question(LLMessageSystem *msg, void **user_data)  		S32 count = 0;  		LLSD args;  		args["OBJECTNAME"] = object_name; -		args["NAME"] = owner_name; +		args["NAME"] = LLCacheName::cleanFullName(owner_name);  		// check the received permission flags against each permission  		for (S32 i = 0; i < SCRIPT_PERMISSION_EOF; i++) @@ -6096,8 +6274,7 @@ void process_script_dialog(LLMessageSystem* msg, void**)  	LLNotificationPtr notification;  	if (!first_name.empty())  	{ -		args["FIRST"] = first_name; -		args["LAST"] = last_name; +		args["NAME"] = LLCacheName::buildFullName(first_name, last_name);  		notification = LLNotifications::instance().add(  			LLNotification::Params("ScriptDialog").substitutions(args).payload(payload).form_elements(form.asLLSD()));  	} @@ -6130,7 +6307,7 @@ static LLNotificationFunctorRegistration callback_load_url_reg("LoadWebPage", ca  // We've got the name of the person who owns the object hurling the url.  // Display confirmation dialog. -void callback_load_url_name(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group) +void callback_load_url_name(const LLUUID& id, const std::string& full_name, bool is_group)  {  	std::vector<LLSD>::iterator it;  	for (it = gLoadUrlList.begin(); it != gLoadUrlList.end(); ) @@ -6143,11 +6320,11 @@ void callback_load_url_name(const LLUUID& id, const std::string& first, const st  			std::string owner_name;  			if (is_group)  			{ -				owner_name = first + LLTrans::getString("Group"); +				owner_name = full_name + LLTrans::getString("Group");  			}  			else  			{ -				owner_name = first + " " + last; +				owner_name = full_name;  			}  			// For legacy name-only mutes. @@ -6207,7 +6384,8 @@ void process_load_url(LLMessageSystem* msg, void**)  	// Add to list of pending name lookups  	gLoadUrlList.push_back(payload); -	gCacheName->get(owner_id, owner_is_group, &callback_load_url_name); +	gCacheName->get(owner_id, owner_is_group, +		boost::bind(&callback_load_url_name, _1, _2, _3));  } diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index ee89680fea..17aac1945b 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -69,6 +69,7 @@  #include "llface.h"  #include "llfloaterproperties.h"  #include "llfollowcam.h" +#include "llhudtext.h"  #include "llselectmgr.h"  #include "llrendersphere.h"  #include "lltooldraganddrop.h" @@ -1080,7 +1081,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  					// alpha was flipped so that it zero encoded better  					coloru.mV[3] = 255 - coloru.mV[3];  					mText->setColor(LLColor4(coloru)); -					mText->setStringUTF8(temp_string); +					mText->setString(temp_string);  					if (mDrawable.notNull())  					{ @@ -1472,7 +1473,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  					dp->unpackBinaryDataFixed(coloru.mV, 4, "Color");  					coloru.mV[3] = 255 - coloru.mV[3];  					mText->setColor(LLColor4(coloru)); -					mText->setStringUTF8(temp_string); +					mText->setString(temp_string);  					setChanged(TEXTURE);  				} @@ -4132,7 +4133,7 @@ void LLViewerObject::setDebugText(const std::string &utf8text)  		mText->setOnHUDAttachment(isHUDAttachment());  	}  	mText->setColor(LLColor4::white); -	mText->setStringUTF8(utf8text); +	mText->setString(utf8text);  	mText->setZCompare(FALSE);  	mText->setDoFade(FALSE);  	updateText(); diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index be83fb7ef8..346f33727f 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -37,7 +37,6 @@  #include "llassetstorage.h"  #include "lldarrayptr.h" -#include "llhudtext.h"  #include "llhudicon.h"  #include "llinventory.h"  #include "llrefcount.h" @@ -60,6 +59,7 @@ class LLColor4;  class LLFrameTimer;  class LLDrawable;  class LLHost; +class LLHUDText;  class LLWorld;  class LLNameValue;  class LLNetMap; diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 752aeaaab0..f682a05532 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -53,7 +53,7 @@  #include "lltooltip.h"  #include "llworld.h"  #include "llstring.h" -#include "llhudtext.h" +#include "llhudnametag.h"  #include "lldrawable.h"  #include "xform.h"  #include "llsky.h" @@ -1201,7 +1201,7 @@ void LLViewerObjectList::generatePickList(LLCamera &camera)  			}  		} -		LLHUDText::addPickable(mSelectPickList); +		LLHUDNameTag::addPickable(mSelectPickList);  		for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();  			iter != LLCharacter::sInstances.end(); ++iter) diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index a591cc1e14..c5d4ed1088 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -2075,10 +2075,9 @@ void LLViewerParcelMgr::deedLandToGroup()  	args["GROUP_NAME"] = group_name;  	if(mCurrentParcel->getContributeWithDeed())  	{ -		std::string first_name, last_name; -		gCacheName->getName(mCurrentParcel->getOwnerID(), first_name, last_name); -		args["FIRST_NAME"] = first_name; -		args["LAST_NAME"] = last_name; +		std::string full_name; +		gCacheName->getFullName(mCurrentParcel->getOwnerID(), full_name); +		args["NAME"] = full_name;  		LLNotificationsUtil::add("DeedLandToGroupWithContribution",args, LLSD(), deedAlertCB);  	}  	else diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index c48668df9a..0ef38b2d7c 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -34,7 +34,9 @@  #include "llviewerregion.h" +// linden libraries  #include "indra_constants.h" +#include "llavatarnamecache.h"		// name lookup cap url  #include "llfloaterreg.h"  #include "llmath.h"  #include "llhttpclient.h" @@ -174,7 +176,9 @@ public:  				mRegion->showReleaseNotes();  			}  		} -		 + +		mRegion->setCapabilitiesReceived(true); +  		if (STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())  		{  			LLStartUp::setStartupState( STATE_SEED_CAP_GRANTED ); @@ -231,7 +235,8 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,      // LLCapabilityListener binds all the globals it expects to need at      // construction time.      mCapabilityListener(host.getString(), gMessageSystem, *this, -                        gAgent.getID(), gAgent.getSessionID()) +                        gAgent.getID(), gAgent.getSessionID()), +	mCapabilitiesReceived(false)  {  	mWidth = region_width_meters;  	mOriginGlobal = from_region_handle(handle);  @@ -1485,6 +1490,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url)  	LLSD capabilityNames = LLSD::emptyArray();  	capabilityNames.append("AttachmentResources"); +	capabilityNames.append("AvatarPickerSearch");  	capabilityNames.append("ChatSessionRequest");  	capabilityNames.append("CopyInventoryFromNotecard");  	capabilityNames.append("DispatchRegionInfo"); @@ -1495,6 +1501,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url)  	capabilityNames.append("ObjectMediaNavigate");  	capabilityNames.append("FetchLib");  	capabilityNames.append("FetchLibDescendents"); +	capabilityNames.append("GetDisplayNames");  	capabilityNames.append("GetTexture");  	capabilityNames.append("GroupProposalBallot");  	capabilityNames.append("HomeLocation"); @@ -1516,6 +1523,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url)  	capabilityNames.append("SendUserReport");  	capabilityNames.append("SendUserReportWithScreenshot");  	capabilityNames.append("ServerReleaseNotes"); +	capabilityNames.append("SetDisplayName");  	capabilityNames.append("StartGroupProposal");  	capabilityNames.append("TextureStats");  	capabilityNames.append("UntrustedSimulatorMessage"); @@ -1573,6 +1581,16 @@ std::string LLViewerRegion::getCapability(const std::string& name) const  	return iter->second;  } +bool LLViewerRegion::capabilitiesReceived() const +{ +	return mCapabilitiesReceived; +} + +void LLViewerRegion::setCapabilitiesReceived(bool received) +{ +	mCapabilitiesReceived = received; +} +  void LLViewerRegion::logActiveCapabilities() const  {  	int count = 0; diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index 5c4d5a61fd..400180a01c 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -235,6 +235,11 @@ public:  	void setCapability(const std::string& name, const std::string& url);  	// implements LLCapabilityProvider      virtual std::string getCapability(const std::string& name) const; + +	// has region received its final (not seed) capability list? +	bool capabilitiesReceived() const; +	void setCapabilitiesReceived(bool received); +  	static bool isSpecialCapabilityName(const std::string &name);  	void logActiveCapabilities() const; @@ -415,6 +420,7 @@ private:  private:  	bool	mAlive;					// can become false if circuit disconnects +	bool	mCapabilitiesReceived;  	//spatial partitions for objects in this region  	std::vector<LLSpatialPartition*> mObjectPartition; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index e0463e3c4a..25bed6c0be 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -121,6 +121,7 @@  #include "llglheaders.h"  #include "lltooltip.h"  #include "llhudmanager.h" +#include "llhudobject.h"  #include "llhudview.h"  #include "llimagebmp.h"  #include "llimagej2c.h" @@ -1204,12 +1205,8 @@ BOOL LLViewerWindow::handlePaint(LLWindow *window,  S32 x,  S32 y, S32 width,  S  		//SetBKColor(hdc, RGB(255, 255, 255));  		FillRect(hdc, &wnd_rect, CreateSolidBrush(RGB(255, 255, 255))); -		std::string name_str; -		LLAgentUI::buildName(name_str); -  		std::string temp_str; -		temp_str = llformat( "%s FPS %3.1f Phy FPS %2.1f Time Dil %1.3f",		/* Flawfinder: ignore */ -				name_str.c_str(), +		temp_str = llformat( "FPS %3.1f Phy FPS %2.1f Time Dil %1.3f",		/* Flawfinder: ignore */  				LLViewerStats::getInstance()->mFPSStat.getMeanPerSec(),  				LLViewerStats::getInstance()->mSimPhysicsFPS.getPrev(0),  				LLViewerStats::getInstance()->mSimTimeDilation.getPrev(0)); @@ -1888,7 +1885,7 @@ void LLViewerWindow::reshape(S32 width, S32 height)  		// clear font width caches  		if (display_scale_changed)  		{ -			LLHUDText::reshape(); +			LLHUDObject::reshapeAll();  		}  		sendShapeToSim(); @@ -4085,7 +4082,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei  		send_agent_pause();  		//rescale fonts  		initFonts(scale_factor); -		LLHUDText::reshape(); +		LLHUDObject::reshapeAll();  	}  	S32 output_buffer_offset_y = 0; @@ -4214,7 +4211,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei  	if (high_res)  	{  		initFonts(1.f); -		LLHUDText::reshape(); +		LLHUDObject::reshapeAll();  	}  	// Pre-pad image to number of pixels such that the line length is a multiple of 4 bytes (for BMP encoding) diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 4371396629..edafd268c1 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -44,6 +44,7 @@  #include <ctype.h>  #include "llaudioengine.h" +#include "llcachename.h"  #include "noise.h"  #include "sound_ids.h" @@ -51,8 +52,10 @@  #include "llagentcamera.h"  #include "llagentwearables.h"  #include "llanimationstates.h" +#include "llavatarnamecache.h"  #include "llavatarpropertiesprocessor.h"  #include "llviewercontrol.h" +#include "llcallingcard.h"		// IDEVO for LLAvatarTracker  #include "lldrawpoolavatar.h"  #include "lldriverparam.h"  #include "lleditingmotion.h" @@ -61,6 +64,8 @@  #include "llheadrotmotion.h"  #include "llhudeffecttrail.h"  #include "llhudmanager.h" +#include "llhudnametag.h" +#include "llhudtext.h"				// for mText/mDebugText  #include "llkeyframefallmotion.h"  #include "llkeyframestandmotion.h"  #include "llkeyframewalkmotion.h" @@ -652,12 +657,14 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,  	mAppearanceAnimating(FALSE),  	mNameString(),  	mTitle(), -	mNameAway(FALSE), -	mNameBusy(FALSE), -	mNameMute(FALSE), +	mNameAway(false), +	mNameBusy(false), +	mNameMute(false), +	mNameAppearance(false), +	mNameFriend(false), +	mNameAlpha(0.f),  	mRenderGroupTitles(sRenderGroupTitles), -	mNameAppearance(FALSE), -	mNameCloud(FALSE), +	mNameCloud(false),  	mFirstTEMessageReceived( FALSE ),  	mFirstAppearanceMessageReceived( FALSE ),  	mCulled( FALSE ), @@ -2715,227 +2722,256 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)  								 && gSavedSettings.getS32("AvatarNameTagMode") ));  	} -	if ( render_name ) +	if ( !render_name )  	{ -		BOOL new_name = FALSE; -		if (visible_chat != mVisibleChat) +		if (mNameText)  		{ -			mVisibleChat = visible_chat; -			new_name = TRUE; +			// ...clean up old name tag +			mNameText->markDead(); +			mNameText = NULL; +			sNumVisibleChatBubbles--;  		} -		 -		if (sRenderGroupTitles != mRenderGroupTitles) +		return; +	} + +	BOOL new_name = FALSE; +	if (visible_chat != mVisibleChat) +	{ +		mVisibleChat = visible_chat; +		new_name = TRUE; +	} +	 +	if (sRenderGroupTitles != mRenderGroupTitles) +	{ +		mRenderGroupTitles = sRenderGroupTitles; +		new_name = TRUE; +	} + +	// First Calculate Alpha +	// If alpha > 0, create mNameText if necessary, otherwise delete it +	F32 alpha = 0.f; +	if (mAppAngle > 5.f) +	{ +		const F32 START_FADE_TIME = NAME_SHOW_TIME - FADE_DURATION; +		if (!visible_chat && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME) +		{ +			alpha = 1.f - (time_visible - START_FADE_TIME) / FADE_DURATION; +		} +		else +		{ +			// ...not fading, full alpha +			alpha = 1.f; +		} +	} +	else if (mAppAngle > 2.f) +	{ +		// far away is faded out also +		alpha = (mAppAngle-2.f)/3.f; +	} + +	if (alpha <= 0.f) +	{ +		if (mNameText)  		{ -			mRenderGroupTitles = sRenderGroupTitles; -			new_name = TRUE; +			mNameText->markDead(); +			mNameText = NULL; +			sNumVisibleChatBubbles--;  		} +		return; +	} + +	if (!mNameText) +	{ +		mNameText = static_cast<LLHUDNameTag*>( LLHUDObject::addHUDObject( +			LLHUDObject::LL_HUD_NAME_TAG) ); +		//mNameText->setMass(10.f); +		mNameText->setSourceObject(this); +		mNameText->setVertAlignment(LLHUDNameTag::ALIGN_VERT_TOP); +		mNameText->setVisibleOffScreen(TRUE); +		mNameText->setMaxLines(11); +		mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); +		sNumVisibleChatBubbles++; +		new_name = TRUE; +	} +				 +	LLVector3 name_position = idleUpdateNameTagPosition(root_pos_last); +	mNameText->setPositionAgent(name_position); +				 +	idleUpdateNameTagText(new_name); +			 +	idleUpdateNameTagAlpha(new_name, alpha); +} + +void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) +{ +	LLNameValue *title = getNVPair("Title"); +	LLNameValue* firstname = getNVPair("FirstName"); +	LLNameValue* lastname = getNVPair("LastName"); -		// First Calculate Alpha -		// If alpha > 0, create mNameText if necessary, otherwise delete it +	// Avatars must have a first and last name +	if (!firstname || !lastname) return; + +	bool is_away = mSignaledAnimations.find(ANIM_AGENT_AWAY)  != mSignaledAnimations.end(); +	bool is_busy = mSignaledAnimations.find(ANIM_AGENT_BUSY) != mSignaledAnimations.end(); +	bool is_appearance = mSignaledAnimations.find(ANIM_AGENT_CUSTOMIZE) != mSignaledAnimations.end(); +	bool is_muted; +	if (isSelf()) +	{ +		is_muted = false; +	} +	else +	{ +		is_muted = LLMuteList::getInstance()->isMuted(getID()); +	} +	bool is_friend = LLAvatarTracker::instance().isBuddy(getID()); +	bool is_cloud = getIsCloud(); +	 +	if (gSavedSettings.getBOOL("DebugAvatarRezTime")) +	{ +		if (is_appearance != mNameAppearance)  		{ -			F32 alpha = 0.f; -			if (mAppAngle > 5.f) +			if (is_appearance)  			{ -				const F32 START_FADE_TIME = NAME_SHOW_TIME - FADE_DURATION; -				if (!visible_chat && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME) -				{ -					alpha = 1.f - (time_visible - START_FADE_TIME) / FADE_DURATION; -				} -				else -				{ -					// ...not fading, full alpha -					alpha = 1.f; -				} +				LLSD args; +				args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); +				args["NAME"] = getFullname(); +				LLNotificationsUtil::add("AvatarRezEnteredAppearanceNotification",args); +				llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' entered appearance mode." << llendl;  			} -			else if (mAppAngle > 2.f) +			else  			{ -				// far away is faded out also -				alpha = (mAppAngle-2.f)/3.f; +				LLSD args; +				args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); +				args["NAME"] = getFullname(); +				LLNotificationsUtil::add("AvatarRezLeftAppearanceNotification",args); +				llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' left appearance mode." << llendl;  			} +		} +	} -			if (alpha > 0.f) -			{ -				if (!mNameText) -				{ -					mNameText = (LLHUDText *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_TEXT); -					mNameText->setMass(10.f); -					mNameText->setSourceObject(this); -					mNameText->setVertAlignment(LLHUDText::ALIGN_VERT_TOP); -					mNameText->setVisibleOffScreen(TRUE); -					mNameText->setMaxLines(11); -					mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); -					mNameText->setUseBubble(TRUE); -					sNumVisibleChatBubbles++; -					new_name = TRUE; -				} -				 -				LLColor4 avatar_name_color = LLUIColorTable::instance().getColor( "AvatarNameColor" ); -				avatar_name_color.setAlpha(alpha); -				mNameText->setColor(avatar_name_color); -				 -				LLQuaternion root_rot = mRoot.getWorldRotation(); -				mNameText->setUsePixelSize(TRUE); -				LLVector3 pixel_right_vec; -				LLVector3 pixel_up_vec; -				LLViewerCamera::getInstance()->getPixelVectors(root_pos_last, pixel_up_vec, pixel_right_vec); -				LLVector3 camera_to_av = root_pos_last - LLViewerCamera::getInstance()->getOrigin(); -				camera_to_av.normalize(); -				LLVector3 local_camera_at = camera_to_av * ~root_rot; -				LLVector3 local_camera_up = camera_to_av % LLViewerCamera::getInstance()->getLeftAxis(); -				local_camera_up.normalize(); -				local_camera_up = local_camera_up * ~root_rot; -			 -				local_camera_up.scaleVec(mBodySize * 0.5f); -				local_camera_at.scaleVec(mBodySize * 0.5f); +	// Rebuild name tag if state change detected +	if (mNameString.empty() +		|| new_name +		|| (!title && !mTitle.empty()) +		|| (title && mTitle != title->getString()) +		|| is_away != mNameAway  +		|| is_busy != mNameBusy  +		|| is_muted != mNameMute +		|| is_appearance != mNameAppearance +		|| is_friend != mNameFriend +		|| is_cloud != mNameCloud) +	{ +		LLColor4 name_tag_color = getNameTagColor(is_friend); + +		clearNameTag(); -				LLVector3 name_position = mRoot.getWorldPosition() +  -					(local_camera_up * root_rot) - -					(projected_vec(local_camera_at * root_rot, camera_to_av)); -				name_position += pixel_up_vec * 15.f; -				mNameText->setPositionAgent(name_position); +		if (is_away || is_muted || is_busy || is_appearance) +		{ +			std::string line; +			if (is_away) +			{ +				line += LLTrans::getString("AvatarAway"); +				line += ", ";  			} -			else if (mNameText) +			if (is_busy)  			{ -				mNameText->markDead(); -				mNameText = NULL; -				sNumVisibleChatBubbles--; +				line += LLTrans::getString("AvatarBusy"); +				line += ", ";  			} +			if (is_muted) +			{ +				line += LLTrans::getString("AvatarMuted"); +				line += ", "; +			} +			if (is_appearance) +			{ +				line += LLTrans::getString("AvatarEditingAppearance"); +				line += ", "; +			} +			if (is_cloud) +			{ +				line += LLTrans::getString("LoadingData"); +				line += ", "; +			} +			// trim last ", " +			line.resize( line.length() - 2 ); +			LLColor4 status_color = +				LLUIColorTable::getInstance()->getColor("NameTagStatus"); +			addNameTagLine(line, status_color, LLFontGL::NORMAL, +				LLFontGL::getFontSansSerifSmall());  		} -		 -		LLNameValue *title = getNVPair("Title"); -		LLNameValue* firstname = getNVPair("FirstName"); -		LLNameValue* lastname = getNVPair("LastName"); -		if (mNameText.notNull() && firstname && lastname) +		if (sRenderGroupTitles +			&& title && title->getString() && title->getString()[0] != '\0')  		{ -			const BOOL is_away = mSignaledAnimations.find(ANIM_AGENT_AWAY)  != mSignaledAnimations.end(); -			const BOOL is_busy = mSignaledAnimations.find(ANIM_AGENT_BUSY) != mSignaledAnimations.end(); -			const BOOL is_appearance = mSignaledAnimations.find(ANIM_AGENT_CUSTOMIZE) != mSignaledAnimations.end(); -			const BOOL is_muted = isSelf() ? FALSE : LLMuteList::getInstance()->isMuted(getID()); -			const BOOL is_cloud = getIsCloud(); +			LLColor4 group_color = +				LLUIColorTable::getInstance()->getColor("NameTagGroup"); +			std::string title_str = title->getString(); +			LLStringFn::replace_ascii_controlchars(title_str,LL_UNKNOWN_CHAR); +			addNameTagLine(title_str, group_color, LLFontGL::NORMAL, +				LLFontGL::getFontSansSerifSmall()); +		} + +		static LLUICachedControl<bool> show_display_names("NameTagShowDisplayNames"); +		static LLUICachedControl<bool> show_usernames("NameTagShowUsernames"); -			if (gSavedSettings.getBOOL("DebugAvatarRezTime")) +		if (LLAvatarNameCache::useDisplayNames()) +		{ +			LLAvatarName av_name; +			if (!LLAvatarNameCache::get(getID(), &av_name))  			{ -				if (is_appearance != mNameAppearance) -				{ -					if (is_appearance) -					{ -						LLSD args; -						args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); -						args["NAME"] = getFullname(); -						LLNotificationsUtil::add("AvatarRezEnteredAppearanceNotification",args); -						llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' entered appearance mode." << llendl; -					} -					else -					{ -						LLSD args; -						args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); -						args["NAME"] = getFullname(); -						LLNotificationsUtil::add("AvatarRezLeftAppearanceNotification",args); -						llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' left appearance mode." << llendl; -					} -				} +				// ...call this function back when the name arrives +				// and force a rebuild +				LLAvatarNameCache::get(getID(), +					boost::bind(&LLVOAvatar::clearNameTag, this));  			} -			if (mNameString.empty() || -				new_name || -				(!title && !mTitle.empty()) || -				(title && mTitle != title->getString()) || -				(is_away != mNameAway || is_busy != mNameBusy || is_muted != mNameMute) -				|| is_appearance != mNameAppearance  -				|| is_cloud != mNameCloud -				) +			// Might be blank if name not available yet, that's OK +			if (show_display_names)  			{ -				std::string line; -				if (!sRenderGroupTitles) -				{ -					// If all group titles are turned off, stack first name -					// on a line above last name -					line += firstname->getString(); -					line += "\n"; -				} -				else if (title && title->getString() && title->getString()[0] != '\0') -				{ -					line += title->getString(); -					LLStringFn::replace_ascii_controlchars(line,LL_UNKNOWN_CHAR); -					line += "\n"; -					line += firstname->getString(); -				} -				else -				{ -					line += firstname->getString(); -				} +				addNameTagLine(av_name.mDisplayName, name_tag_color, LLFontGL::NORMAL, +					LLFontGL::getFontSansSerif()); +			} +			// Suppress SLID display if display name matches exactly (ugh) +			if (show_usernames && !av_name.mIsDisplayNameDefault) +			{ +				// *HACK: Desaturate the color +				LLColor4 username_color = name_tag_color * 0.83f; +				addNameTagLine(av_name.mUsername, username_color, LLFontGL::NORMAL, +					LLFontGL::getFontSansSerifSmall()); +			} +		} +		else +		{ +			const LLFontGL* font = LLFontGL::getFontSansSerif(); +			std::string full_name = +				LLCacheName::buildFullName( firstname->getString(), lastname->getString() ); +			addNameTagLine(full_name, name_tag_color, LLFontGL::NORMAL, font); +		} -				line += " "; -				line += lastname->getString(); -				BOOL need_comma = FALSE; +		mNameAway = is_away; +		mNameBusy = is_busy; +		mNameMute = is_muted; +		mNameAppearance = is_appearance; +		mNameFriend = is_friend; +		mNameCloud = is_cloud; +		mTitle = title ? title->getString() : ""; +		LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR); +		new_name = TRUE; +	} -				if (is_away || is_muted || is_busy) -				{ -					line += " ("; -					if (is_away) -					{ -						line += LLTrans::getString("AvatarAway"); -						need_comma = TRUE; -					} -					if (is_busy) -					{ -						if (need_comma) -						{ -							line += ", "; -						} -						line += LLTrans::getString("AvatarBusy"); -						need_comma = TRUE; -					} -					if (is_muted) -					{ -						if (need_comma) -						{ -							line += ", "; -						} -						line += LLTrans::getString("AvatarMuted"); -						need_comma = TRUE; -					} -					line += ")"; -				} -				if (is_cloud) -				{ -					line += "\n"; -					line += "(" + LLTrans::getString("LoadingData") + ")"; -				} -				else if (is_appearance) -				{ -					line += "\n"; -					line += LLTrans::getString("AvatarEditingAppearance"); -				} -				mNameAway = is_away; -				mNameBusy = is_busy; -				mNameMute = is_muted; -				mNameAppearance = is_appearance; -				mNameCloud = is_cloud; -				mTitle = title ? title->getString() : ""; -				LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR); -				mNameString = utf8str_to_wstring(line); -				new_name = TRUE; -			} - -			if (visible_chat) -			{ -				mNameText->setDropShadow(TRUE); -				mNameText->setFont(LLFontGL::getFontSansSerif()); -				mNameText->setTextAlignment(LLHUDText::ALIGN_TEXT_LEFT); -				mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f); -				if (new_name) -				{ -					mNameText->setLabel(mNameString); -				} +	if (mVisibleChat) +	{ +		mNameText->setFont(LLFontGL::getFontSansSerif()); +		mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_LEFT); +		mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f); -				char line[MAX_STRING];		/* Flawfinder: ignore */ -				line[0] = '\0'; -				std::deque<LLChat>::iterator chat_iter = mChats.begin(); -				mNameText->clearString(); +			char line[MAX_STRING];		/* Flawfinder: ignore */ +			line[0] = '\0'; +			std::deque<LLChat>::iterator chat_iter = mChats.begin(); +			mNameText->clearString(); -				LLColor4 new_chat = LLUIColorTable::instance().getColor( "AvatarNameColor" ); +		LLColor4 new_chat = LLUIColorTable::instance().getColor( "NameTagChat" );  				LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f);  				LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f);  				if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES)  @@ -2962,17 +2998,17 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)  					if (chat_fade_amt < 1.f)  					{  						F32 u = clamp_rescale(chat_fade_amt, 0.9f, 1.f, 0.f, 1.f); -						mNameText->addLine(utf8str_to_wstring(chat_iter->mText), lerp(new_chat, normal_chat, u), style); +						mNameText->addLine(chat_iter->mText, lerp(new_chat, normal_chat, u), style);  					}  					else if (chat_fade_amt < 2.f)  					{  						F32 u = clamp_rescale(chat_fade_amt, 1.9f, 2.f, 0.f, 1.f); -						mNameText->addLine(utf8str_to_wstring(chat_iter->mText), lerp(normal_chat, old_chat, u), style); +						mNameText->addLine(chat_iter->mText, lerp(normal_chat, old_chat, u), style);  					}  					else if (chat_fade_amt < 3.f)  					{  						// *NOTE: only remove lines down to minimum number -						mNameText->addLine(utf8str_to_wstring(chat_iter->mText), old_chat, style); +						mNameText->addLine(chat_iter->mText, old_chat, style);  					}  				}  				mNameText->setVisibleOffScreen(TRUE); @@ -2997,24 +3033,129 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)  			}  			else  			{ -				mNameText->setFont(LLFontGL::getFontSansSerif()); -				mNameText->setTextAlignment(LLHUDText::ALIGN_TEXT_CENTER); -				mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); -				mNameText->setVisibleOffScreen(FALSE); -				if (new_name) -				{ -					mNameText->setLabel(""); -					mNameText->setString(mNameString); +		// ...not using chat bubbles, just names +		mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_CENTER); +		mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); +		mNameText->setVisibleOffScreen(FALSE); +	} +} + +void LLVOAvatar::addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font) +{ +	llassert(mNameText); +	if (mVisibleChat) +	{ +		mNameText->addLabel(line); +	} +	else +	{ +		mNameText->addLine(line, color, (LLFontGL::StyleFlags)style, font); +	} +	mNameString += line; +	mNameString += '\n'; +} + +void LLVOAvatar::clearNameTag() +{ +	mNameString.clear(); +	if (mNameText) +	{ +		mNameText->setLabel(""); +		mNameText->setString( "" ); +	} +} + +//static +void LLVOAvatar::invalidateNameTag(const LLUUID& agent_id) +{ +	LLViewerObject* obj = gObjectList.findObject(agent_id); +	if (!obj) return; + +	LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(obj); +	if (!avatar) return; + +	avatar->clearNameTag(); +} + +//static +void LLVOAvatar::invalidateNameTags() +{ +	std::vector<LLCharacter*>::iterator it = LLCharacter::sInstances.begin(); +	for ( ; it != LLCharacter::sInstances.end(); ++it) +	{ +		LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*it); +		if (!avatar) continue; +		if (avatar->isDead()) continue; + +		avatar->clearNameTag(); +	} +} + +// Compute name tag position during idle update +LLVector3 LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last) +{ +	LLQuaternion root_rot = mRoot.getWorldRotation(); +	LLVector3 pixel_right_vec; +	LLVector3 pixel_up_vec; +	LLViewerCamera::getInstance()->getPixelVectors(root_pos_last, pixel_up_vec, pixel_right_vec); +	LLVector3 camera_to_av = root_pos_last - LLViewerCamera::getInstance()->getOrigin(); +	camera_to_av.normalize(); +	LLVector3 local_camera_at = camera_to_av * ~root_rot; +	LLVector3 local_camera_up = camera_to_av % LLViewerCamera::getInstance()->getLeftAxis(); +	local_camera_up.normalize(); +	local_camera_up = local_camera_up * ~root_rot; + +	local_camera_up.scaleVec(mBodySize * 0.5f); +	local_camera_at.scaleVec(mBodySize * 0.5f); + +	LLVector3 name_position = mRoot.getWorldPosition() +  +		(local_camera_up * root_rot) - +		(projected_vec(local_camera_at * root_rot, camera_to_av)); +	name_position += pixel_up_vec * 15.f; +	return name_position;  				} -			} + +void LLVOAvatar::idleUpdateNameTagAlpha(BOOL new_name, F32 alpha) +{ +	llassert(mNameText); + +	if (new_name +		|| alpha != mNameAlpha) +	{ +		mNameText->setAlpha(alpha); +		mNameAlpha = alpha; +	} +} + +LLColor4 LLVOAvatar::getNameTagColor(bool is_friend) +{ +	static LLUICachedControl<bool> show_friends("NameTagShowFriends"); +	const char* color_name; +	if (show_friends && is_friend) +	{ +		color_name = "NameTagFriend"; +	} +	else if (LLAvatarNameCache::useDisplayNames()) +	{ +		// ...color based on whether username "matches" a computed display +		// name +		LLAvatarName av_name; +		if (LLAvatarNameCache::get(getID(), &av_name) +			&& av_name.mIsDisplayNameDefault) +		{ +			color_name = "NameTagMatch"; +		} +		else +		{ +			color_name = "NameTagMismatch";  		}  	} -	else if (mNameText) +	else  	{ -		mNameText->markDead(); -		mNameText = NULL; -		sNumVisibleChatBubbles--; +		// ...not using display names +		color_name = "NameTagLegacy";  	} +	return LLUIColorTable::getInstance()->getColor( color_name );  }  //-------------------------------------------------------------------- @@ -7628,9 +7769,7 @@ std::string LLVOAvatar::getFullname() const  	LLNameValue* last  = getNVPair("LastName");   	if (first && last)  	{ -		name += first->getString(); -		name += " "; -		name += last->getString(); +		name = LLCacheName::buildFullName( first->getString(), last->getString() );  	}  	return name; diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 86a7cdae02..c99902a540 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -65,7 +65,7 @@ extern const LLUUID ANIM_AGENT_WALK_ADJUST;  class LLTexLayerSet;  class LLVoiceVisualizer; -class LLHUDText; +class LLHUDNameTag;  class LLHUDEffectSpiral;  class LLTexGlobalColor;  class LLVOAvatarBoneInfo; @@ -211,6 +211,15 @@ public:  	void 			idleUpdateLoadingEffect();  	void 			idleUpdateWindEffect();  	void 			idleUpdateNameTag(const LLVector3& root_pos_last); +	void			idleUpdateNameTagText(BOOL new_name); +	LLVector3		idleUpdateNameTagPosition(const LLVector3& root_pos_last); +	void			idleUpdateNameTagAlpha(BOOL new_name, F32 alpha); +	LLColor4		getNameTagColor(bool is_friend); +	void			clearNameTag(); +	static void		invalidateNameTag(const LLUUID& agent_id); +	// force all name tags to rebuild, useful when display names turned on/off +	static void		invalidateNameTags(); +	void			addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font);  	void 			idleUpdateRenderCost();  	void 			idleUpdateTractorBeam();  	void 			idleUpdateBelowWater(); @@ -824,13 +833,15 @@ protected:  	static void		getAnimLabels(LLDynamicArray<std::string>* labels);  	static void		getAnimNames(LLDynamicArray<std::string>* names);	  private: -	LLWString 		mNameString; +	std::string		mNameString;		// UTF-8 title + name + status  	std::string  	mTitle; -	BOOL	  		mNameAway; -	BOOL	  		mNameBusy; -	BOOL	  		mNameMute; -	BOOL      		mNameAppearance; -	BOOL      		mNameCloud; +	bool	  		mNameAway; +	bool	  		mNameBusy; +	bool	  		mNameMute; +	bool      		mNameAppearance; +	bool			mNameFriend; +	bool			mNameCloud; +	F32				mNameAlpha;  	BOOL      		mRenderGroupTitles;  	//-------------------------------------------------------------------- @@ -838,7 +849,7 @@ private:  	//--------------------------------------------------------------------  public:  	LLFrameTimer	mChatTimer; -	LLPointer<LLHUDText> mNameText; +	LLPointer<LLHUDNameTag> mNameText;  private:  	LLFrameTimer	mTimeVisible;  	std::deque<LLChat> mChats; diff --git a/indra/newview/llvoicechannel.h b/indra/newview/llvoicechannel.h index 573fab1f4f..1784ceaa12 100644 --- a/indra/newview/llvoicechannel.h +++ b/indra/newview/llvoicechannel.h @@ -82,6 +82,9 @@ public:  	virtual void getChannelInfo();  	virtual BOOL isActive();  	virtual BOOL callStarted(); + +	// Session name is a UI label used for feedback about which person, +	// group, or phone number you are talking to  	const std::string& getSessionName() const { return mSessionName; }  	boost::signals2::connection setStateChangedCallback(const state_changed_signal_t::slot_type& callback) diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index bcb1a70efb..409e507c16 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -37,6 +37,8 @@  #include "llsdutil.h" +// Linden library includes +#include "llavatarnamecache.h"  #include "llvoavatarself.h"  #include "llbufferstream.h"  #include "llfile.h" @@ -52,6 +54,8 @@  #include "llviewercontrol.h"  #include "llkeyboard.h"  #include "llappviewer.h"	// for gDisconnected, gDisableVoice + +// Viewer includes  #include "llmutelist.h"  // to check for muted avatars  #include "llagent.h"  #include "llcachename.h" @@ -6176,16 +6180,18 @@ void LLVivoxVoiceClient::notifyFriendObservers()  void LLVivoxVoiceClient::lookupName(const LLUUID &id)  { -	BOOL is_group = FALSE; -	gCacheName->get(id, is_group, &LLVivoxVoiceClient::onAvatarNameLookup); +	LLAvatarNameCache::get(id, +		boost::bind(&LLVivoxVoiceClient::onAvatarNameCache, +			this, _1, _2));  } -//static -void LLVivoxVoiceClient::onAvatarNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group) +void LLVivoxVoiceClient::onAvatarNameCache(const LLUUID& agent_id, +										   const LLAvatarName& av_name)  { -		std::string name = llformat("%s %s", first.c_str(), last.c_str()); -		LLVivoxVoiceClient::getInstance()->avatarNameResolved(id, name); -	 +	// For Vivox, we use the legacy name because I'm uncertain whether or +	// not their service can tolerate switching to Username or Display Name +	std::string legacy_name = av_name.getLegacyName(); +	avatarNameResolved(agent_id, legacy_name);	  }  void LLVivoxVoiceClient::avatarNameResolved(const LLUUID &id, const std::string &name) diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index 59fec8b954..341f22bd73 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -51,7 +51,7 @@ class LLVivoxProtocolParser;  #endif  #include "llvoiceclient.h" - +class LLAvatarName;  class LLVivoxVoiceAccountProvisionResponder;  class LLVivoxVoiceClientMuteListObserver;  class LLVivoxVoiceClientFriendsObserver;	 @@ -619,7 +619,7 @@ protected:  	void leaveAudioSession();  	void lookupName(const LLUUID &id); -	static void onAvatarNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group); +	void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name);  	void avatarNameResolved(const LLUUID &id, const std::string &name);  private: diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index cc65b34a61..ccd0f61fc1 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -70,6 +70,8 @@  #include "llfloaterreg.h"  #include "llgldbg.h"  #include "llhudmanager.h" +#include "llhudnametag.h" +#include "llhudtext.h"  #include "lllightconstants.h"  #include "llresmgr.h"  #include "llselectmgr.h" @@ -2086,6 +2088,7 @@ void LLPipeline::shiftObjects(const LLVector3 &offset)  	}  	LLHUDText::shiftAll(offset); +	LLHUDNameTag::shiftAll(offset);  	display_update_camera();  } @@ -5279,7 +5282,8 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,  		++iter)  	{  		LLVOAvatar* av = (LLVOAvatar*) *iter; -		if (av->mNameText.notNull() && av->mNameText->lineSegmentIntersect(start, local_end, position)) +		if (av->mNameText.notNull() +			&& av->mNameText->lineSegmentIntersect(start, local_end, position))  		{  			drawable = av->mDrawable;  			local_end = position; diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index e8a893e31b..592bda63d2 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -115,9 +115,6 @@       name="AlertTextColor"       value="0.58 0.66 0.84 1" />      <color -     name="AvatarNameColor" -     reference="White" /> -    <color       name="AvatarListItemIconDefaultColor"       reference="White" />      <color @@ -528,6 +525,38 @@      <color       name="MultiSliderTriangleColor"       reference="Unused?" /> +  <!-- +    <color +      name="NameTagBackground" +      value="0.85 0.85 0.85 0.80" /> +      --> +    <color +      name="NameTagBackground" +      value="0 0 0 1" /> +    <color +     name="NameTagChat" +     reference="White" /> +    <color +     name="NameTagFriend" +     value="0.447 0.784 0.663 1" /> +    <color +     name="NameTagGroup" +     value="1 1 1 1" /> +    <color +     name="NameTagLegacy" +     reference="White" /> +    <color +     name="NameTagMatch" +     reference="White" /> +    <color +     name="NameTagMismatch" +     reference="White" /> +    <color +     name="NameTagSLID" +     value="1 1 1 1" /> +    <color +     name="NameTagStatus" +     value="1 1 1 1" />      <color       name="NetMapBackgroundColor"       value="0 0 0 1" /> @@ -562,6 +591,9 @@       name="NotifyTextColor"       reference="White" />      <color +     name="ObjectBubbleColor" +     reference="DkGray_66" /> +    <color       name="ObjectChatColor"       reference="EmphasisColor" />      <color diff --git a/indra/newview/skins/default/textures/Rounded_Rect.png b/indra/newview/skins/default/textures/Rounded_Rect.pngBinary files differ new file mode 100644 index 0000000000..c270c28039 --- /dev/null +++ b/indra/newview/skins/default/textures/Rounded_Rect.png diff --git a/indra/newview/skins/default/textures/icons/Person_Check.png b/indra/newview/skins/default/textures/icons/Person_Check.pngBinary files differ new file mode 100644 index 0000000000..f8638540d4 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Person_Check.png diff --git a/indra/newview/skins/default/textures/icons/Person_Star.png b/indra/newview/skins/default/textures/icons/Person_Star.pngBinary files differ new file mode 100644 index 0000000000..ad10580ac4 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Person_Star.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 0788a0ca9e..4638c32886 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -376,6 +376,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" /> @@ -405,6 +407,7 @@ with the same filename but different name    <texture name="Resize_Corner" file_name="windows/Resize_Corner.png" preload="true" /> +  <texture name="Rounded_Rect"	file_name="Rounded_Rect.png" preload="true" scale.left="6" scale.top="24" scale.right="58" scale.bottom="6" />    <texture name="Rounded_Square"	file_name="rounded_square.j2c" preload="true" scale.left="16" scale.top="16" scale.right="112" scale.bottom="16" />    <texture name="Row_Selection" file_name="navbar/Row_Selection.png" preload="false" /> diff --git a/indra/newview/skins/default/xui/da/floater_windlight_options.xml b/indra/newview/skins/default/xui/da/floater_windlight_options.xml index 65f3f67a70..56f94b24e9 100644 --- a/indra/newview/skins/default/xui/da/floater_windlight_options.xml +++ b/indra/newview/skins/default/xui/da/floater_windlight_options.xml @@ -1,18 +1,18 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<?xml version="1.0" encoding="utf-8" standalone="yes" ?>  <floater name="WindLight floater" title="AVANCERET OPSÆTNING FOR HIMMEL">  	<text name="KeyFramePresetsText">  		Faste indstillinger:  	</text> -	<button label="Ny" label_selected="Ny" name="WLNewPreset"/> -	<button label="Gem" label_selected="Gem" name="WLSavePreset"/> -	<button label="Slet" label_selected="Slet" name="WLDeletePreset"/> -	<button label="Dags cyklus" label_selected="Dags cyklus" name="WLDayCycleMenuButton"/> +	<button label="Ny" label_selected="Ny" name="WLNewPreset" /> +	<button label="Gem" label_selected="Gem" name="WLSavePreset" /> +	<button label="Slet" label_selected="Slet" name="WLDeletePreset" /> +	<button label="Dags cyklus" label_selected="Dags cyklus" name="WLDayCycleMenuButton" />  	<tab_container name="WindLight Tabs">  		<panel label="ATMOSFÆRE" name="Atmosphere">  			<text name="BHText">  				Blå - horisont  			</text> -			<button label="?" name="WLBlueHorizonHelp"/> +			<button label="?" name="WLBlueHorizonHelp" />  			<text name="BHText2">  				R  			</text> @@ -25,19 +25,19 @@  			<text name="BHText5">  				I  			</text> -			<slider label="" name="WLBlueHorizonR"/> -			<slider label="" name="WLBlueHorizonG"/> -			<slider label="" name="WLBlueHorizonB"/> -			<slider label="" name="WLBlueHorizonI"/> +			<slider label="" name="WLBlueHorizonR" /> +			<slider label="" name="WLBlueHorizonG" /> +			<slider label="" name="WLBlueHorizonB" /> +			<slider label="" name="WLBlueHorizonI" />  			<text name="BDensText">  				Dis - horisont  			</text> -			<button label="?" name="WLHazeHorizonHelp"/> -			<slider label="" name="WLHazeHorizon"/> +			<button label="?" name="WLHazeHorizonHelp" /> +			<slider label="" name="WLHazeHorizon" />  			<text name="BDensText2">  				Blå - tæthed  			</text> -			<button label="?" name="WLBlueDensityHelp"/> +			<button label="?" name="WLBlueDensityHelp" />  			<text name="BHText6">  				R  			</text> @@ -50,36 +50,36 @@  			<text name="BHText9">  				I  			</text> -			<slider label="" name="WLBlueDensityR"/> -			<slider label="" name="WLBlueDensityG"/> -			<slider label="" name="WLBlueDensityB"/> -			<slider label="" name="WLBlueDensityI"/> +			<slider label="" name="WLBlueDensityR" /> +			<slider label="" name="WLBlueDensityG" /> +			<slider label="" name="WLBlueDensityB" /> +			<slider label="" name="WLBlueDensityI" />  			<text name="HDText">  				Dis - intensitet  			</text> -			<button label="?" name="WLHazeDensityHelp"/> -			<slider label="" name="WLHazeDensity"/> +			<button label="?" name="WLHazeDensityHelp" /> +			<slider label="" name="WLHazeDensity" />  			<text name="DensMultText">  				Densitet faktor  			</text> -			<button label="?" name="WLDensityMultHelp"/> -			<slider label="" name="WLDensityMult"/> +			<button label="?" name="WLDensityMultHelp" /> +			<slider label="" name="WLDensityMult" />  			<text name="WLDistanceMultText">  				Distance faktor  			</text> -			<button label="?" name="WLDistanceMultHelp"/> -			<slider label="" name="WLDistanceMult"/> +			<button label="?" name="WLDistanceMultHelp" /> +			<slider label="" name="WLDistanceMult" />  			<text name="MaxAltText">  				Maximum højde  			</text> -			<button label="?" name="WLMaxAltitudeHelp"/> -			<slider label="" name="WLMaxAltitude"/> +			<button label="?" name="WLMaxAltitudeHelp" /> +			<slider label="" name="WLMaxAltitude" />  		</panel>  		<panel label="LYS" name="Lighting">  			<text name="SLCText">  				Sol/Måne farve  			</text> -			<button label="?" name="WLSunlightColorHelp"/> +			<button label="?" name="WLSunlightColorHelp" />  			<text name="BHText">  				R  			</text> @@ -92,19 +92,19 @@  			<text name="BHText4">  				I  			</text> -			<slider label="" name="WLSunlightR"/> -			<slider label="" name="WLSunlightG"/> -			<slider label="" name="WLSunlightB"/> -			<slider label="" name="WLSunlightI"/> +			<slider label="" name="WLSunlightR" /> +			<slider label="" name="WLSunlightG" /> +			<slider label="" name="WLSunlightB" /> +			<slider label="" name="WLSunlightI" />  			<text name="TODText">  				Sol/Måne position  			</text> -			<button label="?" name="WLTimeOfDayHelp"/> -			<slider label="" name="WLSunAngle"/> +			<button label="?" name="WLTimeOfDayHelp" /> +			<slider label="" name="WLSunAngle" />  			<text name="WLAmbientText">  				Omgivende  			</text> -			<button label="?" name="WLAmbientHelp"/> +			<button label="?" name="WLAmbientHelp" />  			<text name="BHText5">  				R  			</text> @@ -117,37 +117,37 @@  			<text name="BHText8">  				I  			</text> -			<slider label="" name="WLAmbientR"/> -			<slider label="" name="WLAmbientG"/> -			<slider label="" name="WLAmbientB"/> -			<slider label="" name="WLAmbientI"/> +			<slider label="" name="WLAmbientR" /> +			<slider label="" name="WLAmbientG" /> +			<slider label="" name="WLAmbientB" /> +			<slider label="" name="WLAmbientI" />  			<text name="WLEastAngleText">  				Øst vinkel  			</text> -			<button label="?" name="WLEastAngleHelp"/> -			<slider label="" name="WLEastAngle"/> +			<button label="?" name="WLEastAngleHelp" /> +			<slider label="" name="WLEastAngle" />  			<text name="SunGlowText">  				Sol glød  			</text> -			<button label="?" name="WLSunGlowHelp"/> -			<slider label="Fokus " name="WLGlowB"/> -			<slider label="Størr. " name="WLGlowR"/> +			<button label="?" name="WLSunGlowHelp" /> +			<slider label="Fokus " name="WLGlowB" /> +			<slider label="Størr. " name="WLGlowR" />  			<text name="SceneGammaText">  				Lysintensitet (gamma)  			</text> -			<button label="?" name="WLSceneGammaHelp"/> -			<slider label="" name="WLGamma"/> +			<button label="?" name="WLSceneGammaHelp" /> +			<slider label="" name="WLGamma" />  			<text name="WLStarText">  				Stjerne intensitet  			</text> -			<button label="?" name="WLStarBrightnessHelp"/> -			<slider label="" name="WLStarAlpha"/> +			<button label="?" name="WLStarBrightnessHelp" /> +			<slider label="" name="WLStarAlpha" />  		</panel>  		<panel label="SKYER" name="Clouds">  			<text name="WLCloudColorText">  				Farve på skyer  			</text> -			<button label="?" name="WLCloudColorHelp"/> +			<button label="?" name="WLCloudColorHelp" />  			<text name="BHText">  				R  			</text> @@ -160,14 +160,14 @@  			<text name="BHText4">  				I  			</text> -			<slider label="" name="WLCloudColorR"/> -			<slider label="" name="WLCloudColorG"/> -			<slider label="" name="WLCloudColorB"/> -			<slider label="" name="WLCloudColorI"/> +			<slider label="" name="WLCloudColorR" /> +			<slider label="" name="WLCloudColorG" /> +			<slider label="" name="WLCloudColorB" /> +			<slider label="" name="WLCloudColorI" />  			<text name="WLCloudColorText2">  				Skyer XY/Tæthed  			</text> -			<button label="?" name="WLCloudDensityHelp"/> +			<button label="?" name="WLCloudDensityHelp" />  			<text name="BHText5">  				X  			</text> @@ -177,23 +177,23 @@  			<text name="BHText7">  				T  			</text> -			<slider label="" name="WLCloudX"/> -			<slider label="" name="WLCloudY"/> -			<slider label="" name="WLCloudDensity"/> +			<slider label="" name="WLCloudX" /> +			<slider label="" name="WLCloudY" /> +			<slider label="" name="WLCloudDensity" />  			<text name="WLCloudCoverageText">  				Skydække  			</text> -			<button label="?" name="WLCloudCoverageHelp"/> -			<slider label="" name="WLCloudCoverage"/> +			<button label="?" name="WLCloudCoverageHelp" /> +			<slider label="" name="WLCloudCoverage" />  			<text name="WLCloudScaleText">  				Skystørrelse  			</text> -			<button label="?" name="WLCloudScaleHelp"/> -			<slider label="" name="WLCloudScale"/> +			<button label="?" name="WLCloudScaleHelp" /> +			<slider label="" name="WLCloudScale" />  			<text name="WLCloudDetailText">  				Sky detaljer(XY/tæthed)  			</text> -			<button label="?" name="WLCloudDetailHelp"/> +			<button label="?" name="WLCloudDetailHelp" />  			<text name="BHText8">  				X  			</text> @@ -203,23 +203,23 @@  			<text name="BHText10">  				T  			</text> -			<slider label="" name="WLCloudDetailX"/> -			<slider label="" name="WLCloudDetailY"/> -			<slider label="" name="WLCloudDetailDensity"/> +			<slider label="" name="WLCloudDetailX" /> +			<slider label="" name="WLCloudDetailY" /> +			<slider label="" name="WLCloudDetailDensity" />  			<text name="WLCloudScrollXText">  				Sky drift X  			</text> -			<button label="?" name="WLCloudScrollXHelp"/> -			<check_box label="Lås" name="WLCloudLockX"/> -			<slider label="" name="WLCloudScrollX"/> +			<button label="?" name="WLCloudScrollXHelp" /> +			<check_box label="Lås" name="WLCloudLockX" /> +			<slider label="" name="WLCloudScrollX" />  			<text name="WLCloudScrollYText">  				Sky drift Y  			</text> -			<button label="?" name="WLCloudScrollYHelp"/> -			<check_box label="Lås" name="WLCloudLockY"/> -			<slider label="" name="WLCloudScrollY"/> -			<check_box label="Benyt simple skyer" name="DrawClassicClouds"/> -			<button label="?" name="WLClassicCloudsHelp"/> +			<button label="?" name="WLCloudScrollYHelp" /> +			<check_box label="Lås" name="WLCloudLockY" /> +			<slider label="" name="WLCloudScrollY" /> +			<check_box label="Benyt simple skyer" name="DrawClassicClouds" /> +			<button label="?" name="WLClassicCloudsHelp" />  		</panel>  	</tab_container>  	<string name="WLDefaultSkyNames"> diff --git a/indra/newview/skins/default/xui/da/panel_classified_info.xml b/indra/newview/skins/default/xui/da/panel_classified_info.xml index 28f8936457..0bb52b8fa6 100644 --- a/indra/newview/skins/default/xui/da/panel_classified_info.xml +++ b/indra/newview/skins/default/xui/da/panel_classified_info.xml @@ -40,7 +40,7 @@  				</layout_panel>  				<layout_panel name="descr_layout_panel">  					<text name="classified_desc_label" value="Beskrivelse:"/> -					<text_editor name="classified_desc" value="[description]"/> +			<text_editor name="classified_desc" value="[description]"/>  				</layout_panel>  			</layout_stack>  		</panel> diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml index 20e7c28db0..29fc58245f 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -1895,7 +1895,7 @@ Only large parcels can be listed in search.  			 name="access_estate_defined">  				(Defined by the Estate)  			</panel.string> -      <panel.string +            <panel.string         name="allow_public_access">          Allow Public Access ([MATURITY])        </panel.string> diff --git a/indra/newview/skins/default/xui/en/floater_avatar_picker.xml b/indra/newview/skins/default/xui/en/floater_avatar_picker.xml index f59badfcb4..489b7c0536 100644 --- a/indra/newview/skins/default/xui/en/floater_avatar_picker.xml +++ b/indra/newview/skins/default/xui/en/floater_avatar_picker.xml @@ -5,11 +5,11 @@   height="350"   layout="topleft"   min_height="200" - min_width="265" + min_width="400"   name="avatarpicker"   help_topic="avatarpicker"   title="CHOOSE RESIDENT" - width="265"> + width="500">      <floater.string       name="not_found">          '[TEXT]' not found @@ -40,7 +40,7 @@       name="ResidentChooserTabs"       tab_position="top"       top="20" -     width="265"> +     width="500">          <panel           border="none"           height="150" @@ -83,14 +83,28 @@               left_pad="5"               name="Find"               width="45" /> -            <scroll_list -             follows="all" -             height="98" -             layout="topleft" -             left="0" -             name="SearchResults" -             top="52" -             width="132" /> +          <scroll_list +            draw_heading="true"  +           follows="all" +           height="98" +           layout="topleft" +           left="0" +           name="SearchResults" +           top="52" +           width="132"> +            <columns +              label="Name" +              name="name" +              width="100" /> +            <columns +              label="SL ID" +              name="slid" +              width="100" /> +            <columns +              label="Age" +              name="age" +              width="100" /> +          </scroll_list>          </panel>          <panel           border="none" @@ -207,16 +221,16 @@          </panel>      </tab_container>      <button -     follows="right|bottom" +     follows="left|bottom"       height="23"       label="OK"       label_selected="OK"       name="ok_btn"       top_pad="3" -     left="46" +     left="10"       width="100" />      <button -     follows="right|bottom" +     follows="left|bottom"       height="23"       label="Cancel"       label_selected="Cancel" diff --git a/indra/newview/skins/default/xui/en/floater_bumps.xml b/indra/newview/skins/default/xui/en/floater_bumps.xml index 303c28d7c8..1f2fe62b3c 100644 --- a/indra/newview/skins/default/xui/en/floater_bumps.xml +++ b/indra/newview/skins/default/xui/en/floater_bumps.xml @@ -14,23 +14,23 @@      </floater.string>      <floater.string       name="bump"> -        [TIME]  [FIRST] [LAST] bumped you +        [TIME]  [NAME] bumped you      </floater.string>      <floater.string       name="llpushobject"> -        [TIME]  [FIRST] [LAST] pushed you with a script +        [TIME]  [NAME] pushed you with a script      </floater.string>      <floater.string       name="selected_object_collide"> -        [TIME]  [FIRST] [LAST] hit you with an object +        [TIME]  [NAME] hit you with an object      </floater.string>      <floater.string       name="scripted_object_collide"> -        [TIME]  [FIRST] [LAST] hit you with a scripted object +        [TIME]  [NAME] hit you with a scripted object      </floater.string>      <floater.string       name="physical_object_collide"> -        [TIME]  [FIRST] [LAST] hit you with a physical object +        [TIME]  [NAME] hit you with a physical object      </floater.string>      <floater.string       name="timeStr"> diff --git a/indra/newview/skins/default/xui/en/floater_incoming_call.xml b/indra/newview/skins/default/xui/en/floater_incoming_call.xml index 1d67123726..420ba172e8 100644 --- a/indra/newview/skins/default/xui/en/floater_incoming_call.xml +++ b/indra/newview/skins/default/xui/en/floater_incoming_call.xml @@ -8,7 +8,7 @@   layout="topleft"   name="incoming call"   help_topic="incoming_call" - title="UNKNOWN PERSON IS CALLING" + title="Incoming call"   width="410">      <floater.string       name="lifetime"> diff --git a/indra/newview/skins/default/xui/en/floater_pay.xml b/indra/newview/skins/default/xui/en/floater_pay.xml index 509cffe490..3730890e59 100644 --- a/indra/newview/skins/default/xui/en/floater_pay.xml +++ b/indra/newview/skins/default/xui/en/floater_pay.xml @@ -16,28 +16,7 @@      name="payee_resident">          Pay Resident     </string> -   <text -     type="string" -     length="1" -     follows="left|top" -     height="18" -     layout="topleft" -     left="12" -     name="payee_label" -     top="22" -     width="75"> -        Pay: -    </text> -   <icon -     height="16" -     width="16" -     image_name="Generic_Person" -     mouse_opaque="true" -     name="icon_person" -     tool_tip="Person" -     top_pad="0" -     left="10" -     /> +      <text       type="string"       length="1" @@ -45,10 +24,11 @@       font="SansSerifSmall"       height="16"       layout="topleft" -     left_pad="7" +     left="10"       name="payee_name" -     width="210"> -        [FIRST] [LAST] +     top="25"  +     width="230"> +        Test Name      </text>      <button       height="23" diff --git a/indra/newview/skins/default/xui/en/floater_pay_object.xml b/indra/newview/skins/default/xui/en/floater_pay_object.xml index d09a0a0535..c65dd6e49f 100644 --- a/indra/newview/skins/default/xui/en/floater_pay_object.xml +++ b/indra/newview/skins/default/xui/en/floater_pay_object.xml @@ -2,7 +2,7 @@  <floater   legacy_header_height="18"   can_minimize="false" - height="220" + height="225"   layout="topleft"   name="Give Money"   help_topic="give_money" @@ -16,27 +16,15 @@       name="payee_resident">          Pay Resident      </string> -   <icon -     height="16" -     width="16" -     image_name="Generic_Person" -     mouse_opaque="true" -     name="icon_person" -     tool_tip="Person" -     top_pad="24" -     left="10" -     />      <text -     type="string" -     length="1"       follows="left|top"       height="16"       layout="topleft" -     left_pad="7" -     top_delta="3" +     left="10" +     top_pad="24"       name="payee_name" -     width="184"> -      [FIRST] [LAST] +     width="200"> +      Ericacita Moostopolison      </text>      <text       type="string" @@ -45,9 +33,9 @@       halign="left"       height="14"       layout="topleft" -     left="34" +     left="10"       name="object_name_label" -     top_pad="0" +     top_pad="5"       width="180">          Via object:      </text> @@ -58,7 +46,7 @@       mouse_opaque="true"       name="icon_object"       tool_tip="Objects" -     top_pad="0" +     top_pad="5"       left="10"       />      <text diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index efc1a66d95..f06f3e431d 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -253,7 +253,7 @@       height="28"  	 control_name="EditLinkedParts"       label="Edit linked" -     layout="topleft"      +     layout="topleft"       name="checkbox edit linked parts"       top_pad="0">  		  <check_box.commit_callback @@ -771,7 +771,7 @@  	 name="General"  	 top="16"  	 width="295"> -<panel.string +	 <panel.string  	  name="text deed continued">  		Deed  	 </panel.string> diff --git a/indra/newview/skins/default/xui/en/inspect_avatar.xml b/indra/newview/skins/default/xui/en/inspect_avatar.xml index 194ae151d2..a7ab021225 100644 --- a/indra/newview/skins/default/xui/en/inspect_avatar.xml +++ b/indra/newview/skins/default/xui/en/inspect_avatar.xml @@ -9,7 +9,7 @@   bg_opaque_image="Inspector_Background"   can_close="false"   can_minimize="false" - height="148" + height="164"   layout="topleft"   name="inspect_avatar"   single_instance="true" @@ -47,9 +47,20 @@       follows="top|left"       height="16"       left="8" +     name="user_slid" +     font="SansSerifSmall" +     text_color="White" +     value="James.pinden" +     width="175" +     use_ellipses="true" /> +    <text +     follows="top|left" +     height="16" +     left="8"       name="user_subtitle"       font="SansSerifSmall"       text_color="White" +     top_pad="0"        value="11 Months, 3 days old"       width="175"       use_ellipses="true" /> @@ -108,7 +119,7 @@       height="20"       label="Add Friend"       left="8" -     top="119" +     top="135"       name="add_friend_btn"       width="90" />      <button diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 999f804e71..cc32941633 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -257,7 +257,7 @@ Save all changes to clothing/body parts?     name="GrantModifyRights"     type="alertmodal">  Granting modify rights to another Resident allows them to change, delete or take ANY objects you may have in-world. Be VERY careful when handing out this permission. -Do you want to grant modify rights for [FIRST_NAME] [LAST_NAME]? +Do you want to grant modify rights for [NAME]?      <usetemplate       name="okcancelbuttons"       notext="No" @@ -280,7 +280,7 @@ Do you want to grant modify rights for the selected Residents?     icon="alertmodal.tga"     name="RevokeModifyRights"     type="alertmodal"> -Do you want to revoke modify rights for [FIRST_NAME] [LAST_NAME]? +Do you want to revoke modify rights for [NAME]?      <usetemplate       name="okcancelbuttons"       notext="No" @@ -2070,7 +2070,7 @@ Would you be my friend?     icon="alertmodal.tga"     name="RemoveFromFriends"     type="alertmodal"> -Do you want to remove [FIRST_NAME] [LAST_NAME] from your Friends List? +Do you want to remove [NAME] from your Friends List?      <usetemplate       name="okcancelbuttons"       notext="Cancel" @@ -2323,7 +2323,7 @@ Deed this [AREA] m² of land to the group '[GROUP_NAME]'?     name="DeedLandToGroupWithContribution"     type="alertmodal">  By deeding this parcel, the group will be required to have and maintain sufficient land use credits. -The deed will include a simultaneous land contribution to the group from '[FIRST_NAME] [LAST_NAME]'. +The deed will include a simultaneous land contribution to the group from '[NAME]'.  The purchase price of the land is not refunded to the owner. If a deeded parcel is sold, the sale price will be divided evenly among group members.  Deed this [AREA] m² of land to the group '[GROUP_NAME]'? @@ -3143,6 +3143,79 @@ You are no longer frozen.    <notification     icon="alertmodal.tga" +   name="SetDisplayName" +   type="alertmodal"> +Change your display name? +    <form name="form"> +      <input name="display_name" type="text"> +[DISPLAY_NAME] +      </input> +      <button +       default="true" +       index="0" +       name="Change" +       text="Change"/> +      <button +       index="1" +       name="Cancel" +       text="Cancel"/> +    </form> +  </notification> + +  <notification +   icon="alertmodal.tga" +   name="SetDisplayNameSuccess" +   type="alertmodal"> +Thanks for updating your name! + +Just like in real life, it takes a while for everyone to learn about a new name.  Please allow [HOURS] hours for your name to update in object ownership, scripts, search, etc. + +See http://wiki.secondlife.com/wiki/Setting_your_display_name for details. +  </notification> + +  <notification +   icon="alertmodal.tga" +   name="SetDisplayNameFailedLength" +   type="alertmodal"> +Sorry, that name is too long.  Display names can have a maximum of [LENGTH] characters. + +Please try a shorter name. +  </notification> + +  <notification +   icon="alertmodal.tga" +   name="SetDisplayNameFailedGeneric" +   type="alertmodal"> +    Sorry, we could not set your display name.  Please try again later. +  </notification> + +  <notification +   icon="alertmodal.tga" +   name="AgentDisplayNameUpdateThresholdExceeded" +   type="alertmodal"> +Sorry, you can only change your name once every 24 hours. + +Please try again later. +  </notification> + +  <notification +   icon="alertmodal.tga" +   name="AgentDisplayNameSetBlocked" +   type="alertmodal"> + Sorry, we could not set your requested name because it contains a banned word. +  + Please try a different name. +  </notification> + +  <notification +   icon="notifytip.tga" +   name="DisplayNameUpdate" +   type="notifytip"> +    [OLD_NAME] ([SLID]) is now known as [NEW_NAME]. +  </notification> + +  <notification +   icon="alertmodal.tga"     name="OfferTeleport"     type="alertmodal">  Offer a teleport to your location with the following message? @@ -4445,14 +4518,14 @@ Topic: [SUBJECT], Message: [MESSAGE]     icon="notifytip.tga"     name="FriendOnline"     type="notifytip"> -[FIRST] [LAST] is Online +[NAME] is Online    </notification>    <notification     icon="notifytip.tga"     name="FriendOffline"     type="notifytip"> -[FIRST] [LAST] is Offline +[NAME] is Offline    </notification>    <notification @@ -4620,13 +4693,6 @@ You cannot remove protected categories.    <notification     icon="notifytip.tga" -   name="OfferedCard" -   type="notifytip"> -You have offered a calling card to [FIRST] [LAST] -  </notification> - -  <notification -   icon="notifytip.tga"     name="UnableToBuyWhileDownloading"     type="notifytip">  Unable to buy while downloading object data. @@ -4780,7 +4846,15 @@ Please select at least one type of content to search (General, Moderate, or Adul    <notification     icon="notify.tga" -   name="PaymentRecived" +   name="PaymentReceived" +   persist="true" +   type="notify"> +[MESSAGE] +  </notification> + +  <notification +   icon="notify.tga" +   name="PaymentSent"     persist="true"     type="notify">  [MESSAGE] @@ -4878,7 +4952,7 @@ The objects you own on the selected parcel of land have been returned back to yo     name="OtherObjectsReturned"     persist="true"     type="notify"> -The objects on the selected parcel of land that is owned by [FIRST] [LAST] have been returned to his or her inventory. +The objects on the selected parcel of land that is owned by [NAME] have been returned to his or her inventory.    </notification>    <notification @@ -5553,7 +5627,7 @@ Grant this request?     name="ScriptDialog"     persist="true"     type="notify"> -[FIRST] [LAST]'s '[TITLE]' +[NAME]'s '[TITLE]'  [MESSAGE]      <form name="form">        <button @@ -5784,7 +5858,7 @@ Click Accept to join the call or Decline to decline the invitation. Click Block     name="AutoUnmuteByIM"     persist="true"     type="notify"> -[FIRST] [LAST] was sent an instant message and has been automatically unblocked. +[NAME] was sent an instant message and has been automatically unblocked.    </notification>    <notification @@ -5792,7 +5866,7 @@ Click Accept to join the call or Decline to decline the invitation. Click Block     name="AutoUnmuteByMoney"     persist="true"     type="notify"> -[FIRST] [LAST] was given money and has been automatically unblocked. +[NAME] was given money and has been automatically unblocked.    </notification>    <notification @@ -5800,7 +5874,7 @@ Click Accept to join the call or Decline to decline the invitation. Click Block     name="AutoUnmuteByInventory"     persist="true"     type="notify"> -[FIRST] [LAST] was offered inventory and has been automatically unblocked. +[NAME] was offered inventory and has been automatically unblocked.    </notification>    <notification diff --git a/indra/newview/skins/default/xui/en/panel_edit_classified.xml b/indra/newview/skins/default/xui/en/panel_edit_classified.xml index 7383edf63d..62a364473c 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_classified.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_classified.xml @@ -218,12 +218,12 @@           value="Content type:"           width="250" />          <icons_combo_box -         follows="left|top" -         height="23" +         follows="left|top"  +         height="23"            label="General Content"           layout="topleft"           left="10" -         name="content_type" +         name="content_type"            top_pad="5"           width="156">              <icons_combo_box.drop_down_button @@ -233,8 +233,8 @@               pad_left="3"/>              <icons_combo_box.item               label="Moderate Content" -             name="mature_ci" -             value="Mature"> +          name="mature_ci"  +          value="Mature">                  <item.columns                   halign="center"                   type="icon" @@ -243,8 +243,8 @@              </icons_combo_box.item>              <icons_combo_box.item               label="General Content" -             name="pg_ci" -             value="PG"> +          name="pg_ci"  +          value="PG">                  <item.columns                   halign="center"                   type="icon" diff --git a/indra/newview/skins/default/xui/en/panel_edit_profile.xml b/indra/newview/skins/default/xui/en/panel_edit_profile.xml index dff2b9a214..bce988da9d 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_profile.xml @@ -87,12 +87,41 @@       min_height="300"           left="0"           width="292"> +      <text +       follows="top|left" +       font="SansSerifBigBold" +       height="20" +       layout="topleft" +       left="10" +       name="user_name" +       text_color="white" +       top="4" +       value="Hamilton Hitchings" +       width="280" /> +      <text +       follows="top|left" +       height="13" +       layout="topleft" +       left="10" +       name="user_slid" +       text_color="LtGray" +       top_pad="5" +       value="(hamilton.linden)" +       width="150" /> +      <button +       follows="top|left" +       height="20" +       label="Set Name..." +       left="170" +       name="set_name" +       top_delta="-4" +       width="110" />       <panel         name="lifes_images_panel"           follows="left|top|right"           height="244"           layout="topleft" -         top="0" +         top="37"           left="0"           width="292">  	 <panel @@ -145,8 +174,8 @@         height="102"         layout="topleft"         left="123" -       top="25" -       max_length="511" +       top="62" +       max_length="512"         name="sl_description_edit"         width="157"         word_wrap="true"> @@ -200,8 +229,8 @@         height="102"         layout="topleft"         left="123" -       max_length="254" -       top="157" +       max_length="512" +       top="195"         name="fl_description_edit"         width="157"         word_wrap="true"> diff --git a/indra/newview/skins/default/xui/en/panel_group_general.xml b/indra/newview/skins/default/xui/en/panel_group_general.xml index e79ae34627..9d50db6f79 100644 --- a/indra/newview/skins/default/xui/en/panel_group_general.xml +++ b/indra/newview/skins/default/xui/en/panel_group_general.xml @@ -113,6 +113,7 @@ Hover your mouse over the options for more help.       layout="topleft"       left="0"       name="visible_members" +     short_names="false"        top_pad="2">          <name_list.columns           label="Member" diff --git a/indra/newview/skins/default/xui/en/panel_group_roles.xml b/indra/newview/skins/default/xui/en/panel_group_roles.xml index 0eb5c47f85..0255cf80a1 100644 --- a/indra/newview/skins/default/xui/en/panel_group_roles.xml +++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml @@ -81,6 +81,7 @@ clicking on their names.               right="-1"               multi_select="true"               name="member_list" +             short_names="false"                top_pad="5">                  <name_list.columns                   label="Member" diff --git a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml b/indra/newview/skins/default/xui/en/panel_im_control_panel.xml index 33a5e01e4c..a36f078f4f 100644 --- a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml +++ b/indra/newview/skins/default/xui/en/panel_im_control_panel.xml @@ -24,25 +24,15 @@       top_pad="5"       width="114">          <layout_panel -         mouse_opaque="false" -         auto_resize="true" -         follows="top|left" -         height="0" -         layout="topleft" -         left="2" -         min_height="0" -         width="109" -         top="0" -         name="spacer" -         user_resize="false" /> -        <layout_panel           auto_resize="false"           follows="top|left|right"           height="20"           layout="topleft" +         left="2"            min_height="20"           width="109"           name="view_profile_btn_panel" +         top="0"            user_resize="false">              <button               follows="left|top|right" @@ -171,5 +161,15 @@               name="voice_ctrls_btn"               width="109" />          </layout_panel> +      <layout_panel +       mouse_opaque="false" +       auto_resize="true" +       follows="top|left" +       height="0" +       layout="topleft" +       min_height="0" +       width="109" +       name="spacer" +       user_resize="false" />      </layout_stack>  </panel> diff --git a/indra/newview/skins/default/xui/en/panel_landmarks.xml b/indra/newview/skins/default/xui/en/panel_landmarks.xml index a7e87f2a1e..8d43cc816c 100644 --- a/indra/newview/skins/default/xui/en/panel_landmarks.xml +++ b/indra/newview/skins/default/xui/en/panel_landmarks.xml @@ -3,7 +3,7 @@     name="Landmarks"     top="0"     height="400" -   layout="topleft" +   layout="topleft"      left="0"     width="313"     help_topic="panel_landmarks" @@ -88,7 +88,7 @@          </accordion_tab>      </accordion>      <panel -     background_visible="true" +       background_visible="true"       bevel_style="none"       bottom="0"       follows="left|right|bottom" diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml index a86762f53d..0f97301856 100644 --- a/indra/newview/skins/default/xui/en/panel_login.xml +++ b/indra/newview/skins/default/xui/en/panel_login.xml @@ -65,12 +65,13 @@ Username:  <line_editor  follows="left|bottom"  height="22" -label="Username" +label="bobsmith12 or Steller Sunshine"  left_delta="0" -max_length="31" +max_length="63"  name="username_edit" +prevalidate_callback="ascii"   select_on_focus="true" -tool_tip="[SECOND_LIFE] Username" +tool_tip="The username you chose when you registered, like bobsmith12 or Steller Sunshine"  top_pad="0"  width="150" />  <text @@ -159,8 +160,8 @@ width="135"  <layout_panel  follows="right|bottom"  name="links" -width="200" -min_width="200" +width="205" +min_width="205"  user_resize="false"  height="80">     <text @@ -172,7 +173,7 @@ height="16"  top="12"  right="-10"  name="create_new_account_text" -  width="180"> +  width="200">         Sign up   </text>  <text @@ -184,8 +185,8 @@ height="16"  name="forgot_password_text"  top_pad="12"  right="-10" -  width="180"> -       Forgot your name or password? +  width="200"> +       Forgot your username or password?  </text>  <text  follows="right|bottom" @@ -196,7 +197,7 @@ height="16"  name="login_help"  top_pad="2"  right="-10" -    width="180"> +    width="200">         Need help logging in?   </text>  <!--  <text      follows="right|bottom" diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index b79ef1e287..f5228f5d35 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -81,7 +81,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M       width="317">       	<panel           background_opaque="true" -         background_visible="true" +       background_visible="true"           bg_alpha_color="DkGray"           bg_opaque_color="DkGray"           follows="all" @@ -157,7 +157,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M          </panel>          <panel           background_opaque="true" -         background_visible="true" +       background_visible="true"           bg_alpha_color="DkGray"           bg_opaque_color="DkGray"           follows="all" @@ -282,7 +282,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M          </panel>          <panel           background_opaque="true" -         background_visible="true" +       background_visible="true"           bg_alpha_color="DkGray"           bg_opaque_color="DkGray"           follows="all" @@ -372,7 +372,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M          </panel>          <panel           background_opaque="true" -         background_visible="true" +       background_visible="true"           bg_alpha_color="DkGray"           bg_opaque_color="DkGray"           follows="all" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml index 40a644657a..73882fea4d 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml @@ -125,7 +125,8 @@ Automatic position for:       left_pad="30"       name="first_person_avatar_visible"       width="256" /> -    <check_box +    +<check_box       control_name="ArrowKeysAlwaysMove"       follows="left|top"       height="20" @@ -206,7 +207,7 @@ Automatic position for:     left="80"     name="UI Size:"     top_pad="25" -   width="160"> +   width="300">      UI size    </text>    <slider @@ -302,6 +303,7 @@ Automatic position for:       halign="center"       height="23"       image_overlay="Refresh_Off" +   layout="topleft"        tool_tip="Reset to Middle Mouse Button"       mouse_opaque="true"       name="set_voice_middlemouse_button" @@ -315,7 +317,7 @@ Automatic position for:   label="Other Devices"   left="30"   name="joystick_setup_button" - top="27" + top_pad="27"   width="155">      <button.commit_callback       function="Floater.Show" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_general.xml b/indra/newview/skins/default/xui/en/panel_preferences_general.xml index 9eaabbe77b..c43784a6f8 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_general.xml @@ -222,28 +222,27 @@     </text>     <radio_group       control_name="AvatarNameTagMode" -     height="20" +     height="45"       layout="topleft"       left="50"       name="Name_Tag_Preference">          <radio_item           label="Off" -         layout="topleft"           name="radio"           value="0"           width="75" />          <radio_item           label="On" -         layout="topleft" -         left_pad="12" +         left_delta="0"           name="radio2" +		 top_pad="5"           value="1"           width="75" />          <radio_item           label="Show briefly" -         layout="topleft" -         left_pad="12" +         left_delta="0"           name="radio3" +		 top_pad="5"           value="2"           width="160" />      </radio_group> @@ -253,18 +252,58 @@       height="16"       label="Show my name"       layout="topleft" -     left="50" +     left="70"       name="show_my_name_checkbox1" +	 top_pad="4"       width="300" /> -   <check_box +  <check_box +    control_name="NameTagShowFriends" +    enabled_control="AvatarNameTagMode" +    height="16" +    label="Highlight friends" +    left_delta="0" +    name="show_friends" +    tool_tip="Highlight the name tags of your friends" +    top_pad="2" /> +  <text +    follows="left|top" +    height="15" +	layout="topleft" +    left="250" +    name="name_tags_textbox" +    top="175" +    width="200"> +       Tags show: +   </text> +    <check_box +     control_name="NameTagShowGroupTitles"  	 enabled_control="AvatarNameTagMode" -     control_name="RenderShowGroupTitleAll"       height="16" -     label="Show group titles" -     layout="topleft" -     left_delta="175" +     label="Group titles" +     left="265"       name="show_all_title_checkbox1" -     width="200" /> +	 tool_tip="Show group titles, like Officer or Member" +     top_pad="5" /> +  <!-- +   <check_box +     control_name="NameTagShowDisplayNames" +	 enabled_control="AvatarNameTagMode" +     height="16" +     label="Display names" +     left_delta="0" +     name="show_display_names" +	 tool_tip="Show display names, like José Sanchez" +     top_pad="5" /> +     --> +   <check_box +     control_name="NameTagShowUsernames" +	 enabled_control="AvatarNameTagMode" +     height="16" +     label="Usernames" +     left_delta="0" +     name="show_slids" +     tool_tip="Show username, like bobsmith123" +     top_pad="2" />      <text       type="string"       length="1" @@ -273,7 +312,7 @@       layout="topleft"       left="30"       name="effects_color_textbox" -     top_pad="15" +     top="290"       width="200">          My effects:      </text> @@ -285,6 +324,7 @@        layout="topleft"        left_pad="5"        name="title_afk_text" +      top_delta="0"         width="190">      Away timeout:      </text> @@ -354,8 +394,8 @@        use_ellipses="false"        hover="false"       commit_on_focus_lost = "true" -     follows="left|top|right" -     height="60" +     follows="left|top" +     height="42"       layout="topleft"       left="50"       name="busy_response" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml index 2c6ceeef2e..7148aba00a 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml @@ -115,7 +115,7 @@     layout="topleft"     left="77"     name="connection_port_enabled" -   top_pad="20" +   top_pad="15"     width="256">      <check_box.commit_callback       function="Notification.Show" @@ -147,7 +147,7 @@     left="80"     mouse_opaque="false"     name="cache_size_label_l" -   top_pad="20" +   top_pad="10"     width="200">      Cache size    </text> @@ -375,4 +375,27 @@     name="web_proxy_port"     top_delta="0"     width="145" /> +  <text +       type="string" +       length="1" +       follows="left|top" +       height="10" +       layout="topleft" +       left="30" +       name="Communications:" +       top_pad="5" +       width="300"> +    Communications: +  </text> +  <check_box +control_name="UseDisplayNames" +follows="top|left" +height="15" +label="Use Display Names" +layout="topleft" +left_delta="50" +name="display_names_check" +width="237" +tool_tip="Check to use display names in chat, IM, name tags, etc." +top_pad="10"/>  </panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_view.xml b/indra/newview/skins/default/xui/en/panel_profile_view.xml index 5a96ba2dd2..aca778193a 100644 --- a/indra/newview/skins/default/xui/en/panel_profile_view.xml +++ b/indra/newview/skins/default/xui/en/panel_profile_view.xml @@ -48,8 +48,19 @@       height="13"       layout="topleft"       left="45" +     name="user_slid" +     text_color="LtGray" +     value="" +     width="150" /> +    <text +     follows="top|left" +     halign="right"  +     height="13" +     layout="topleft" +     left="150"       name="status"       text_color="LtGray_50" +     top_delta="0"        value="Online"       width="150" />      <tab_container diff --git a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml index d46783e058..0f7dc47401 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml @@ -167,7 +167,7 @@       left_pad="0"               name="Creator Name"  		     top_delta="0" -		     width="140"> +		     width="225">  	        Erica Linden  	     </text>  	    <text @@ -191,7 +191,7 @@  			    left_pad="0"  			    name="Owner Name"  			    top_delta="0" -			    width="140"> +			    width="225">  			    Erica Linden  	     </text>  	    	    <text diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index f8bb36b88a..b46fb6f890 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -89,8 +89,9 @@ or.</string>  	<!-- tooltips for Urls -->  	<string name="TooltipHttpUrl">Click to view this web page</string>  	<string name="TooltipSLURL">Click to view this location's information</string> -	<string name="TooltipAgentUrl">Click to view this Resident's profile</string> -	<string name="TooltipAgentMute">Click to mute this Resident</string> +  <string name="TooltipAgentUrl">Click to view this Resident's profile</string> +  <string name="TooltipAgentInspect">Learn more about this Resident</string> +  <string name="TooltipAgentMute">Click to mute this Resident</string>  	<string name="TooltipAgentUnmute">Click to unmute this Resident</string>  	<string name="TooltipAgentIM">Click to IM this Resident</string>  	<string name="TooltipAgentPay">Click to Pay this Resident</string> @@ -104,7 +105,7 @@ or.</string>  	<string name="TooltipObjectIMUrl">Click to view this object's description</string>  	<string name="TooltipMapUrl">Click to view this location on a map</string>  	<string name="TooltipSLAPP">Click to run the secondlife:// command</string> -	<string name="CurrentURL" value=" CurrentURL: [CurrentURL]" />	 +	<string name="CurrentURL" value=" CurrentURL: [CurrentURL]" />    <string name="TooltipPrice" value=" L$[PRICE]-" /> @@ -3007,7 +3008,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE].      You are the only user in this session.    </string>    <string name="offline_message"> -    [FIRST] [LAST] is offline. +    [NAME] is offline.    </string>    <string name="invite_message">      Click the [BUTTON NAME] button to accept/connect to this voice chat. @@ -3091,11 +3092,13 @@ If you continue to receive this message, contact the [SUPPORT_SITE].  	</string>    <!-- Financial operations strings --> -  <string name="paid_you_ldollars">[NAME] paid you L$[AMOUNT]</string> +  <string name="paid_you_ldollars">[NAME] paid you L$[AMOUNT] [REASON].</string> +  <string name="paid_you_ldollars_no_reason">[NAME] paid you L$[AMOUNT].</string>    <string name="you_paid_ldollars">You paid [NAME] L$[AMOUNT] [REASON].</string>    <string name="you_paid_ldollars_no_info">You paid L$[AMOUNT].</string>    <string name="you_paid_ldollars_no_reason">You paid [NAME] L$[AMOUNT].</string>    <string name="you_paid_ldollars_no_name">You paid L$[AMOUNT] [REASON].</string> +  <string name="for item">for [ITEM]</string>    <string name="for a parcel of land">for a parcel of land</string>    <string name="for a land access pass">for a land access pass</string>    <string name="for deeding land">for deeding land</string> diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml index 49f30ae807..777d52ca3a 100644 --- a/indra/newview/skins/default/xui/es/notifications.xml +++ b/indra/newview/skins/default/xui/es/notifications.xml @@ -1347,7 +1347,7 @@ Esta actualización no es obligatoria, pero te sugerimos instalarla para mejorar  	</notification>  	<notification name="BusyModeSet">  		Pasar al modo ocupado. -Se ocultará el chat y los mensajes instantáneos (éstos recibirán tu Respuesta en el modo ocupado). Se rehusarán todos los ofrecimientos de teleporte. Todas las ofertas de inventario irán a tu Papelera. +Se ocultará el chat y los mensajes instantáneos   (éstos recibirán tu Respuesta en el modo ocupado). Se rehusarán todos los ofrecimientos de teleporte. Todas las ofertas de inventario irán a tu Papelera.  		<usetemplate ignoretext="Cambio mi estado al modo ocupado" name="okignore" yestext="OK"/>  	</notification>  	<notification name="JoinedTooManyGroupsMember"> @@ -1814,7 +1814,7 @@ Linden Lab  		</form>  	</notification>  	<notification name="ConfirmDeleteProtectedCategory"> -		La carpeta '[FOLDERNAME]' pertenece al sistema, y borrar carpetas del sistema puede provocar inestabilidad.  ¿Estás seguro de que quieres borrarla? +		La carpeta '[FOLDERNAME]' pertenece al sistema,   y borrar carpetas del sistema puede provocar inestabilidad.  ¿Estás seguro de que quieres borrarla?  		<usetemplate ignoretext="Confirmar antes de borrar una carpeta del sistema" name="okcancelignore" notext="Cancelar" yestext="OK"/>  	</notification>  	<notification name="ConfirmEmptyTrash"> @@ -2387,7 +2387,7 @@ Esto añadirá un marcador en tu inventario para que puedas enviarle rápidament  Si permaneces en esta región serás desconectado.  	</notification>  	<notification name="RegionRestartSeconds"> -		Esta región se reiniciará en [SECONDS] segundos. +		Esta región se reiniciará en  [SECONDS] segundos.  Si permaneces en esta región serás desconectado.  	</notification>  	<notification name="LoadWebPage"> @@ -2454,7 +2454,7 @@ Si no confias en este objeto y en su creador, deberías rehusar esta petición.  	<notification name="BuyLindenDollarSuccess">  		¡Gracias por tu pago! -Tu saldo de L$ se actualizará cuando se complete el proceso. Si el proceso tarda más de 20 minutos, se cancelará tu transacción, y la cantidad se cargará en tu saldo de US$. +Tu saldo de L$ se actualizará cuando se complete el proceso. Si el proceso tarda más de 20 minutos, se cancelará tu transacción,    y la cantidad se cargará en tu saldo de US$.  Puedes revisar el estado de tu pago en el Historial de transacciones de tu [http://secondlife.com/account/ Panel de Control]  	</notification> diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml index d38afe13d2..a678782e4a 100644 --- a/indra/newview/skins/default/xui/fr/notifications.xml +++ b/indra/newview/skins/default/xui/fr/notifications.xml @@ -178,7 +178,7 @@ Voulez-vous continuer ?  	<notification name="JoinGroupNoCost">  		Vous vous apprêtez à rejoindre le groupe [NAME].  Voulez-vous continuer ? -		<usetemplate name="okcancelbuttons" notext="Annuler" yestext="Rejoindre"/> +		<usetemplate name="okcancelbuttons" notext="Annuler" yestext="Fusionner"/>  	</notification>  	<notification name="JoinGroupCannotAfford">  		Rejoindre ce groupe coûte [COST] L$. diff --git a/indra/newview/skins/default/xui/ja/panel_group_land_money.xml b/indra/newview/skins/default/xui/ja/panel_group_land_money.xml index ef6d8cce47..c0449f1221 100644 --- a/indra/newview/skins/default/xui/ja/panel_group_land_money.xml +++ b/indra/newview/skins/default/xui/ja/panel_group_land_money.xml @@ -45,7 +45,7 @@  			あなたの貢献:  		</text>  		<text name="your_contribution_units"> -			m² +			平方メートル  		</text>  		<text name="your_contribution_max_value">  			(最大 [AMOUNT]) diff --git a/indra/newview/skins/default/xui/ja/panel_group_roles.xml b/indra/newview/skins/default/xui/ja/panel_group_roles.xml index 8a629be910..db6fe268c7 100644 --- a/indra/newview/skins/default/xui/ja/panel_group_roles.xml +++ b/indra/newview/skins/default/xui/ja/panel_group_roles.xml @@ -17,7 +17,7 @@ Ctrl キーを押しながらメンバー名をクリックすると  			<name_list name="member_list">  				<name_list.columns label="メンバー" name="name"/>  				<name_list.columns label="寄付" name="donated"/> -				<name_list.columns label="ログイン" name="online"/> +				<name_list.columns label="ステータス" name="online"/>  			</name_list>  			<button label="招待" name="member_invite"/>  			<button label="追放" name="member_eject"/> @@ -44,7 +44,7 @@ Ctrl キーを押しながらメンバー名をクリックすると  			<filter_editor label="役割を選別" name="filter_input"/>  			<scroll_list name="role_list">  				<scroll_list.columns label="役割" name="name"/> -				<scroll_list.columns label="タイトル" name="title"/> +				<scroll_list.columns label="肩書き" name="title"/>  				<scroll_list.columns label="#" name="members"/>  			</scroll_list>  			<button label="新しい役割" name="role_create"/> diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml index 51b6581d42..66fbbfc916 100644 --- a/indra/newview/skins/default/xui/pt/strings.xml +++ b/indra/newview/skins/default/xui/pt/strings.xml @@ -1260,10 +1260,10 @@  		Script não encontrado no servidor.  	</string>  	<string name="CompileQueueProblemDownloading"> -		Problema no download +		Problema no  download  	</string>  	<string name="CompileQueueInsufficientPermDownload"> -		Permissões insuficientes para fazer o download do script. +		Permissões insuficientes para  fazer o download do script.  	</string>  	<string name="CompileQueueInsufficientPermFor">  		Permissões insuficientes para @@ -1564,7 +1564,7 @@  		(vai atualizar depois de publicado)  	</string>  	<string name="NoPicksClassifiedsText"> -		Você não criou nenhum Destaque ou Anúncio. Clique no botão "+" para criar um Destaque ou Anúncio. +		Você não criou nenhum Destaque ou Anúncio.  Clique no botão "+" para criar um Destaque ou Anúncio.  	</string>  	<string name="NoAvatarPicksClassifiedsText">  		O usuário não tem nenhum destaque ou anúncio diff --git a/indra/newview/tests/lldateutil_test.cpp b/indra/newview/tests/lldateutil_test.cpp index 7ba82fbd2c..9ec24eb515 100644 --- a/indra/newview/tests/lldateutil_test.cpp +++ b/indra/newview/tests/lldateutil_test.cpp @@ -189,4 +189,14 @@ namespace tut  			LLDateUtil::ageFromDate("12/13/2009", now),  			"3 weeks old" );  	} + +	//template<> template<> +	//void dateutil_object_t::test<6>() +	//{ +	//	set_test_name("ISO dates"); +	//	LLDate now(std::string("2010-01-04T12:00:00Z")); +	//	ensure_equals("days", +	//		LLDateUtil::ageFromDateISO("2009-12-13", now), +	//		"3 weeks old" ); +	//}  } | 
