diff options
author | James Cook <james@lindenlab.com> | 2010-03-08 10:54:23 -0800 |
---|---|---|
committer | James Cook <james@lindenlab.com> | 2010-03-08 10:54:23 -0800 |
commit | 18ebacefcfb5909a58a213a97c6a687afe9b877e (patch) | |
tree | 5b48ebad64a253bd9aa50371c2308389cbec64bf | |
parent | 34d1d34ca100fd137c2a85f0e0f330730fb70aba (diff) | |
parent | 42606dbbb5f452211e4fc30ee0ed41334fc14e8d (diff) |
Merge with viewer 2 beta 4
126 files changed, 2455 insertions, 1253 deletions
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 4481d334b2..bed7b46cd0 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -32,6 +32,7 @@ set(llcommon_SOURCE_FILES llapp.cpp llapr.cpp llassettype.cpp + llavatarname.cpp llbase32.cpp llbase64.cpp llcommon.cpp @@ -113,6 +114,7 @@ set(llcommon_HEADER_FILES llallocator.h llallocator_heap_profile.h llagentconstants.h + llavatarname.h llapp.h llapr.h llassettype.h diff --git a/indra/llcommon/llavatarname.cpp b/indra/llcommon/llavatarname.cpp new file mode 100644 index 0000000000..3950fc3af1 --- /dev/null +++ b/indra/llcommon/llavatarname.cpp @@ -0,0 +1,52 @@ +/** + * @file llavatarname.cpp + * @brief Represents name-related data for an avatar, such as the + * username/SLID ("bobsmith123" or "james.linden") and the display + * name ("James Cook") + * + * $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 "linden_common.h" + +#include "llavatarname.h" + +LLAvatarName::LLAvatarName() +: mSLID(), + mDisplayName(), + mIsLegacy(false), + mLastUpdate(0), + mBadge() +{ } + +bool LLAvatarName::operator<(const LLAvatarName& rhs) const +{ + if (mSLID == rhs.mSLID) + return mDisplayName < rhs.mDisplayName; + else + return mSLID < rhs.mSLID; +} diff --git a/indra/llcommon/llavatarname.h b/indra/llcommon/llavatarname.h new file mode 100644 index 0000000000..fb67c16f45 --- /dev/null +++ b/indra/llcommon/llavatarname.h @@ -0,0 +1,68 @@ +/** + * @file llavatarname.h + * @brief Represents name-related data for an avatar, such as the + * username/SLID ("bobsmith123" or "james.linden") and the display + * name ("James Cook") + * + * $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 LLAVATARNAME_H +#define LLAVATARNAME_H + +#include <string> + +class LL_COMMON_API LLAvatarName +{ +public: + LLAvatarName(); + + bool operator<(const LLAvatarName& rhs) const; + + // "bobsmith123" or "james.linden", US-ASCII only + std::string mSLID; + + // "Jose' Sanchez" or "James Linden", UTF-8 encoded Unicode + // Contains data whether or not user has explicitly set + // a display name; may duplicate their SLID. + std::string mDisplayName; + + // If true, both display name and SLID were generated from + // a legacy first and last name, like "James Linden (james.linden)" + bool mIsLegacy; + + // Names can change, so need to keep track of when name was + // last checked. + // Unix time-from-epoch seconds + U32 mLastUpdate; + + // Can be a viewer UI image name ("Person_Check") or a server-side + // image UUID, or empty string. + std::string mBadge; +}; + +#endif diff --git a/indra/llcommon/llchat.h b/indra/llcommon/llchat.h index f1b9091298..91302618e9 100644 --- a/indra/llcommon/llchat.h +++ b/indra/llcommon/llchat.h @@ -34,7 +34,6 @@ #ifndef LL_LLCHAT_H #define LL_LLCHAT_H -#include "llstring.h" #include "lluuid.h" #include "v3math.h" @@ -77,7 +76,7 @@ typedef enum e_chat_style class LLChat { public: - LLChat(const std::string& text = LLStringUtil::null) + LLChat(const std::string& text = std::string()) : mText(text), mFromName(), mFromID(), diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h index 540aea4252..d53036844d 100644 --- a/indra/llcommon/llversionviewer.h +++ b/indra/llcommon/llversionviewer.h @@ -36,7 +36,7 @@ const S32 LL_VERSION_MAJOR = 2; const S32 LL_VERSION_MINOR = 0; const S32 LL_VERSION_PATCH = 0; -const S32 LL_VERSION_BUILD = 200030; +const S32 LL_VERSION_BUILD = 999999; const char * const LL_CHANNEL = "Second Life Developer"; diff --git a/indra/llinventory/lltransactionflags.cpp b/indra/llinventory/lltransactionflags.cpp index e0f87aa7db..79f8589bb1 100644 --- a/indra/llinventory/lltransactionflags.cpp +++ b/indra/llinventory/lltransactionflags.cpp @@ -114,6 +114,9 @@ std::string build_transfer_message_to_source( std::ostringstream ostr; if(dest_id.isNull()) { + // *NOTE: Do not change these strings! The viewer matches + // them in llviewermessage.cpp to perform localization. + // If you need to make changes, add a new, localizable message. JC ostr << "You paid L$" << amount; switch(transaction_type) { @@ -160,6 +163,9 @@ std::string build_transfer_message_to_destination( return description; } std::ostringstream ostr; + // *NOTE: Do not change these strings! The viewer matches + // them in llviewermessage.cpp to perform localization. + // If you need to make changes, add a new, localizable message. JC ostr << source_name << " paid you L$" << amount; append_reason(ostr, transaction_type, description); ostr << "."; diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt index 1f8ee26716..0d07015f24 100644 --- a/indra/llmessage/CMakeLists.txt +++ b/indra/llmessage/CMakeLists.txt @@ -25,6 +25,7 @@ set(llmessage_SOURCE_FILES llares.cpp llareslistener.cpp llassetstorage.cpp + llavatarnamecache.cpp llblowfishcipher.cpp llbuffer.cpp llbufferstream.cpp @@ -110,6 +111,7 @@ set(llmessage_HEADER_FILES llares.h llareslistener.h llassetstorage.h + llavatarnamecache.h llblowfishcipher.h llbuffer.h llbufferstream.h diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp new file mode 100644 index 0000000000..5384e1f067 --- /dev/null +++ b/indra/llmessage/llavatarnamecache.cpp @@ -0,0 +1,315 @@ +/** + * @file llavatarnamecache.cpp + * @brief Provides lookup of avatar SLIDs ("bobsmith123") and display names + * ("James Cook") from avatar UUIDs. + * + * $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 "linden_common.h" + +#include "llavatarnamecache.h" + +#include "llcachename.h" // *TODO: remove +#include "llframetimer.h" +#include "llhttpclient.h" + +#include <map> +#include <set> + +namespace LLAvatarNameCache +{ + bool sUseDisplayNames = false; + + // *TODO: configure the base URL for this in viewer with data + // from login.cgi + std::string sNameServiceBaseURL = "http://pdp15.lindenlab.com:8050/my-service/"; + + // accumulated agent IDs for next query against service + typedef std::set<LLUUID> ask_queue_t; + ask_queue_t sAskQueue; + + // agent IDs that have been requested, but with no reply + // maps agent ID to frame time request was made + typedef std::map<LLUUID, F32> pending_queue_t; + pending_queue_t sPendingQueue; + + // Callbacks to fire when we received a name. + // May have multiple callbacks for a single ID, which are + // represented as multiple slots bound to the signal. + // Avoid copying signals via pointers. + typedef std::map<LLUUID, callback_signal_t*> signal_map_t; + signal_map_t sSignalMap; + + // names we know about + typedef std::map<LLUUID, LLAvatarName> cache_t; + cache_t sCache; + + // only need per-frame timing resolution + LLFrameTimer sRequestTimer; + + bool isRequestPending(const LLUUID& agent_id); + void processNameFromService(const LLSD& row); +} + +class LLAvatarNameResponder : public LLHTTPClient::Responder +{ +public: + /*virtual*/ void result(const LLSD& content) + { + LLSD::array_const_iterator it = content.beginArray(); + for ( ; it != content.endArray(); ++it) + { + const LLSD& row = *it; + LLAvatarNameCache::processNameFromService(row); + } + } + + /*virtual*/ void error(U32 status, const std::string& reason) + { + llinfos << "JAMESDEBUG error " << status << " " << reason << llendl; + } +}; + +void LLAvatarNameCache::processNameFromService(const LLSD& row) +{ + U32 now = (U32)LLFrameTimer::getTotalSeconds(); + + LLAvatarName av_name; + av_name.mSLID = row["slid"].asString(); + av_name.mDisplayName = row["display_name"].asString(); + av_name.mLastUpdate = now; + + // HACK for pretty stars + if (row["last_name"].asString() == "Linden") + { + av_name.mBadge = "Person_Star"; + } + + // Some avatars don't have explicit display names set + if (av_name.mDisplayName.empty()) + { + // make up a display name + std::string first_name = row["first_name"].asString(); + std::string last_name = row["last_name"].asString(); + av_name.mDisplayName = + LLCacheName::buildFullName(first_name, last_name); + av_name.mIsLegacy = true; + } + + // add to cache + LLUUID agent_id = row["agent_id"].asUUID(); + sCache[agent_id] = av_name; + + sPendingQueue.erase(agent_id); + + // signal everyone waiting on this name + signal_map_t::iterator sig_it = sSignalMap.find(agent_id); + if (sig_it != sSignalMap.end()) + { + callback_signal_t* signal = sig_it->second; + (*signal)(agent_id, av_name); + + sSignalMap.erase(agent_id); + + delete signal; + signal = NULL; + } +} + +void LLAvatarNameCache::initClass() +{ +} + +void LLAvatarNameCache::cleanupClass() +{ +} + +void LLAvatarNameCache::importFile(std::istream& istr) +{ +} + +void LLAvatarNameCache::exportFile(std::ostream& ostr) +{ +} + +void LLAvatarNameCache::idle() +{ + const F32 SECS_BETWEEN_REQUESTS = 0.2f; // JAMESDEBUG set to 0.1? + if (sRequestTimer.checkExpirationAndReset(SECS_BETWEEN_REQUESTS)) + { + return; + } + + if (sAskQueue.empty()) + { + return; + } + + LLSD body; + body["agent_ids"] = LLSD::emptyArray(); + LLSD& agent_ids = body["agent_ids"]; + + ask_queue_t::const_iterator it = sAskQueue.begin(); + for ( ; it != sAskQueue.end(); ++it) + { + agent_ids.append( LLSD( *it ) ); + } + + // *TODO: configure the base URL for this + std::string url = sNameServiceBaseURL + "agent/display-names/"; + LLHTTPClient::post(url, body, new LLAvatarNameResponder()); + + // Move requests from Ask queue to Pending queue + U32 now = (U32)LLFrameTimer::getTotalSeconds(); + for (it = sAskQueue.begin(); it != sAskQueue.end(); ++it) + { + sPendingQueue[*it] = now; + } + sAskQueue.clear(); +} + +bool LLAvatarNameCache::isRequestPending(const LLUUID& agent_id) +{ + const U32 PENDING_TIMEOUT_SECS = 5 * 60; + U32 now = (U32)LLFrameTimer::getTotalSeconds(); + U32 expire_time = now - PENDING_TIMEOUT_SECS; + + pending_queue_t::const_iterator it = sPendingQueue.find(agent_id); + if (it != sPendingQueue.end()) + { + bool expired = (it->second < expire_time); + return !expired; + } + return false; +} + +bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name) +{ + std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id); + if (it != sCache.end()) + { + *av_name = it->second; + return true; + } + + if (!isRequestPending(agent_id)) + { + sAskQueue.insert(agent_id); + } + + return false; +} + +void LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot) +{ + std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id); + if (it != sCache.end()) + { + // ...name already exists in cache, fire callback now + callback_signal_t signal; + signal.connect(slot); + signal(agent_id, it->second); + return; + } + + // schedule a request + if (!isRequestPending(agent_id)) + { + sAskQueue.insert(agent_id); + } + + // always store additional callback, even if request is pending + signal_map_t::iterator sig_it = sSignalMap.find(agent_id); + if (sig_it == sSignalMap.end()) + { + // ...new callback for this id + callback_signal_t* signal = new callback_signal_t(); + signal->connect(slot); + sSignalMap[agent_id] = signal; + } + else + { + // ...existing callback, bind additional slot + callback_signal_t* signal = sig_it->second; + signal->connect(slot); + } +} + +class LLSetNameResponder : public LLHTTPClient::Responder +{ +public: + LLUUID mAgentID; + + LLSetNameResponder(const LLUUID& agent_id) : mAgentID(agent_id) { } + + /*virtual*/ void result(const LLSD& content) + { + // force re-fetch + LLAvatarNameCache::sCache.erase(mAgentID); + } + + /*virtual*/ void error(U32 status, const std::string& reason) + { + llinfos << "JAMESDEBUG set names failed " << status + << " reason " << reason << llendl; + } +}; + +void LLAvatarNameCache::setDisplayName(const LLUUID& agent_id, const std::string& display_name) +{ + LLSD body; + body["display_name"] = display_name; + + // *TODO: configure the base URL for this + std::string url = sNameServiceBaseURL + "agent/"; + url += agent_id.asString(); + url += "/set-display-name/"; + LLHTTPClient::post(url, body, new LLSetNameResponder(agent_id)); +} + +void LLAvatarNameCache::toggleDisplayNames() +{ + sUseDisplayNames = !sUseDisplayNames; + // flush our cache + sCache.clear(); + // force re-lookups + if (gCacheName) + { + gCacheName->clear(); + } +} + +bool LLAvatarNameCache::useDisplayNames() +{ + return sUseDisplayNames; +} + +void LLAvatarNameCache::erase(const LLUUID& agent_id) +{ + sCache.erase(agent_id); +} diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h new file mode 100644 index 0000000000..a09f549877 --- /dev/null +++ b/indra/llmessage/llavatarnamecache.h @@ -0,0 +1,74 @@ +/** + * @file llavatarnamecache.h + * @brief Provides lookup of avatar SLIDs ("bobsmith123") and display names + * ("James Cook") from avatar UUIDs. + * + * $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 LLAVATARNAMECACHE_H +#define LLAVATARNAMECACHE_H + +#include "llavatarname.h" // for convenience + +#include <boost/signals2.hpp> + +namespace LLAvatarNameCache +{ + void initClass(); + void cleanupClass(); + + void importFile(std::istream& istr); + void exportFile(std::ostream& ostr); + + // Periodically makes a batch request for display names not already in + // cache. Call once per frame. + void idle(); + + // If name is in cache, returns true and fills in provided LLAvatarName + // otherwise returns false + bool get(const LLUUID& agent_id, LLAvatarName *av_name); + + typedef boost::signals2::signal< + void (const LLUUID& agent_id, const LLAvatarName& av_name)> + callback_signal_t; + typedef callback_signal_t::slot_type callback_slot_t; + + // Fetches name information and calls callback. + // If name information is in cache, callback will be called immediately. + void get(const LLUUID& agent_id, callback_slot_t slot); + + // Sends an update to the server + void setDisplayName(const LLUUID& agent_id, const std::string& display_name); + + // HACK: turn display names on and off + void toggleDisplayNames(); + bool useDisplayNames(); + void erase(const LLUUID& agent_id); +} + +#endif diff --git a/indra/llmessage/llcachename.cpp b/indra/llmessage/llcachename.cpp index 9363b3a8d5..d7d49eac8d 100644 --- a/indra/llmessage/llcachename.cpp +++ b/indra/llmessage/llcachename.cpp @@ -75,6 +75,8 @@ public: public: bool mIsGroup; U32 mCreateTime; // unix time_t + // IDEVO TODO collapse names to one field, which will eliminate + // many string compares on "Resident" std::string mFirstName; std::string mLastName; std::string mGroupName; @@ -220,7 +222,9 @@ public: Impl(LLMessageSystem* msg); ~Impl(); - + + BOOL getName(const LLUUID& id, std::string& first, std::string& last); + boost::signals2::connection addPending(const LLUUID& id, const LLCacheNameCallback& callback); void addPending(const LLUUID& id, const LLHost& host); @@ -306,89 +310,10 @@ boost::signals2::connection LLCacheName::addObserver(const LLCacheNameCallback& return impl.mSignal.connect(callback); } -void LLCacheName::importFile(LLFILE* fp) -{ - S32 count = 0; - - const S32 BUFFER_SIZE = 1024; - char buffer[BUFFER_SIZE]; /*Flawfinder: ignore*/ - - // *NOTE: These buffer sizes are hardcoded into sscanf() below - char id_string[MAX_STRING]; /*Flawfinder: ignore*/ - char firstname[MAX_STRING]; /*Flawfinder: ignore*/ - char lastname[MAX_STRING]; /*Flawfinder: ignore*/ - U32 create_time; - - // This is OK if the first line is actually a name. We just don't load it. - char* valid = fgets(buffer, BUFFER_SIZE, fp); - if (!valid) return; - - // *NOTE: This buffer size is hardcoded into sscanf() below - char version_string[BUFFER_SIZE]; /*Flawfinder: ignore*/ - S32 version = 0; - S32 match = sscanf( /* Flawfinder: ignore */ - buffer, - "%1023s %d", - version_string, &version); - if ( match != 2 - || strcmp(version_string, "version") - || version != CN_FILE_VERSION) - { - llwarns << "Ignoring old cache name file format" << llendl; - return; - } - - // We'll expire entries more than a week old - U32 now = (U32)time(NULL); - const U32 SECS_PER_DAY = 60 * 60 * 24; - U32 delete_before_time = now - (7 * SECS_PER_DAY); - - while(!feof(fp)) - { - valid = fgets(buffer, BUFFER_SIZE, fp); - if (!valid) break; - - match = sscanf( /* Flawfinder: ignore */ - buffer, - "%254s %u %254s %254s", - id_string, - &create_time, - firstname, - lastname); - if (4 != match) continue; - - LLUUID id(id_string); - if (id.isNull()) continue; - - // undo trivial XOR - S32 i; - for (i = 0; i < UUID_BYTES; i++) - { - id.mData[i] ^= 0x33; - } - - // Don't load entries that are more than a week old - if (create_time < delete_before_time) continue; - - LLCacheNameEntry* entry = new LLCacheNameEntry(); - entry->mIsGroup = false; - entry->mCreateTime = create_time; - entry->mFirstName = firstname; - entry->mLastName = lastname; - impl.mCache[id] = entry; - std::string fullname = entry->mFirstName + " " + entry->mLastName; - impl.mReverseCache[fullname] = id; - - count++; - } - - llinfos << "LLCacheName loaded " << count << " names" << llendl; -} - bool LLCacheName::importFile(std::istream& istr) { LLSD data; - if(LLSDSerialize::fromXML(data, istr) < 1) + if(LLSDSerialize::fromXMLDocument(data, istr) < 1) return false; // We'll expire entries more than a week old @@ -414,7 +339,7 @@ bool LLCacheName::importFile(std::istream& istr) entry->mFirstName = agent[FIRST].asString(); entry->mLastName = agent[LAST].asString(); impl.mCache[id] = entry; - std::string fullname = entry->mFirstName + " " + entry->mLastName; + std::string fullname = buildFullName(entry->mFirstName, entry->mLastName); impl.mReverseCache[fullname] = id; ++count; @@ -463,6 +388,7 @@ void LLCacheName::exportFile(std::ostream& ostr) // store it LLUUID id = iter->first; std::string id_str = id.asString(); + // IDEVO TODO: Should we store SLIDs with last name "Resident" or not? if(!entry->mFirstName.empty() && !entry->mLastName.empty()) { data[AGENTS][id_str][FIRST] = entry->mFirstName; @@ -480,7 +406,7 @@ void LLCacheName::exportFile(std::ostream& ostr) } -BOOL LLCacheName::getName(const LLUUID& id, std::string& first, std::string& last) +BOOL LLCacheName::Impl::getName(const LLUUID& id, std::string& first, std::string& last) { if(id.isNull()) { @@ -489,7 +415,7 @@ BOOL LLCacheName::getName(const LLUUID& id, std::string& first, std::string& las return FALSE; } - LLCacheNameEntry* entry = get_ptr_in_map(impl.mCache, id ); + LLCacheNameEntry* entry = get_ptr_in_map(mCache, id ); if (entry) { first = entry->mFirstName; @@ -500,16 +426,17 @@ BOOL LLCacheName::getName(const LLUUID& id, std::string& first, std::string& las { first = sCacheName["waiting"]; last.clear(); - if (!impl.isRequestPending(id)) + if (!isRequestPending(id)) { - impl.mAskNameQueue.insert(id); + mAskNameQueue.insert(id); } return FALSE; } } + // static -void LLCacheName::LocalizeCacheName(std::string key, std::string value) +void LLCacheName::localizeCacheName(std::string key, std::string value) { if (key!="" && value!= "" ) sCacheName[key]=value; @@ -520,11 +447,13 @@ void LLCacheName::LocalizeCacheName(std::string key, std::string value) BOOL LLCacheName::getFullName(const LLUUID& id, std::string& fullname) { std::string first_name, last_name; - BOOL res = getName(id, first_name, last_name); - fullname = first_name + " " + last_name; + BOOL res = impl.getName(id, first_name, last_name); + fullname = buildFullName(first_name, last_name); return res; } + + BOOL LLCacheName::getGroupName(const LLUUID& id, std::string& group) { if(id.isNull()) @@ -561,13 +490,13 @@ BOOL LLCacheName::getGroupName(const LLUUID& id, std::string& group) BOOL LLCacheName::getUUID(const std::string& first, const std::string& last, LLUUID& id) { - std::string fullname = first + " " + last; - return getUUID(fullname, id); + std::string full_name = buildFullName(first, last); + return getUUID(full_name, id); } -BOOL LLCacheName::getUUID(const std::string& fullname, LLUUID& id) +BOOL LLCacheName::getUUID(const std::string& full_name, LLUUID& id) { - ReverseCache::iterator iter = impl.mReverseCache.find(fullname); + ReverseCache::iterator iter = impl.mReverseCache.find(full_name); if (iter != impl.mReverseCache.end()) { id = iter->second; @@ -579,6 +508,25 @@ BOOL LLCacheName::getUUID(const std::string& fullname, LLUUID& id) } } +//static +std::string LLCacheName::buildFullName(const std::string& first, const std::string& last) +{ + std::string fullname = first; + if (!last.empty() + && last != "Resident") + { + fullname += ' '; + fullname += last; + } + return fullname; +} + +//static +std::string LLCacheName::cleanFullName(const std::string& full_name) +{ + return full_name.substr(0, full_name.find(" Resident")); +} + // This is a little bit kludgy. LLCacheNameCallback is a slot instead of a function pointer. // The reason it is a slot is so that the legacy get() function below can bind an old callback // and pass it as a slot. The reason it isn't a boost::function is so that trackable behavior @@ -586,7 +534,7 @@ BOOL LLCacheName::getUUID(const std::string& fullname, LLUUID& id) // we call it immediately. -Steve // NOTE: Even though passing first and last name is a bit of extra overhead, it eliminates the // potential need for any parsing should any code need to handle first and last name independently. -boost::signals2::connection LLCacheName::get(const LLUUID& id, BOOL is_group, const LLCacheNameCallback& callback) +boost::signals2::connection LLCacheName::get(const LLUUID& id, bool is_group, const LLCacheNameCallback& callback) { boost::signals2::connection res; @@ -594,7 +542,7 @@ boost::signals2::connection LLCacheName::get(const LLUUID& id, BOOL is_group, co { LLCacheNameSignal signal; signal.connect(callback); - signal(id, sCacheName["nobody"], "", is_group); + signal(id, sCacheName["nobody"], is_group); return res; } @@ -606,11 +554,13 @@ boost::signals2::connection LLCacheName::get(const LLUUID& id, BOOL is_group, co // id found in map therefore we can call the callback immediately. if (entry->mIsGroup) { - signal(id, entry->mGroupName, "", entry->mIsGroup); + signal(id, entry->mGroupName, entry->mIsGroup); } else { - signal(id, entry->mFirstName, entry->mLastName, entry->mIsGroup); + std::string fullname = + buildFullName(entry->mFirstName, entry->mLastName); + signal(id, fullname, entry->mIsGroup); } } else @@ -632,9 +582,9 @@ boost::signals2::connection LLCacheName::get(const LLUUID& id, BOOL is_group, co return res; } -boost::signals2::connection LLCacheName::get(const LLUUID& id, BOOL is_group, old_callback_t callback, void* user_data) +boost::signals2::connection LLCacheName::get(const LLUUID& id, bool is_group, old_callback_t callback, void* user_data) { - return get(id, is_group, boost::bind(callback, _1, _2, _3, _4, user_data)); + return get(id, is_group, boost::bind(callback, _1, _2, _3, user_data)); } void LLCacheName::processPending() @@ -706,7 +656,7 @@ void LLCacheName::dump() { llinfos << iter->first << " = " - << entry->mFirstName << " " << entry->mLastName + << buildFullName(entry->mFirstName, entry->mLastName) << " @ " << entry->mCreateTime << llendl; } @@ -725,12 +675,24 @@ void LLCacheName::dumpStats() << llendl; } +void LLCacheName::clear() +{ + for_each(impl.mCache.begin(), impl.mCache.end(), DeletePairedPointer()); + impl.mCache.clear(); +} + //static std::string LLCacheName::getDefaultName() { return sCacheName["waiting"]; } +//static +std::string LLCacheName::getDefaultLastName() +{ + return "Resident"; +} + void LLCacheName::Impl::processPendingAsks() { LLMemType mt_ppa(LLMemType::MTYPE_CACHE_PROCESS_PENDING_ASKS); @@ -752,11 +714,13 @@ void LLCacheName::Impl::processPendingReplies() if (!entry->mIsGroup) { - (reply->mSignal)(reply->mID, entry->mFirstName, entry->mLastName, FALSE); + std::string fullname = + LLCacheName::buildFullName(entry->mFirstName, entry->mLastName); + (reply->mSignal)(reply->mID, fullname, false); } else { - (reply->mSignal)(reply->mID, entry->mGroupName, "", TRUE); + (reply->mSignal)(reply->mID, entry->mGroupName, true); } } @@ -927,13 +891,27 @@ void LLCacheName::Impl::processUUIDReply(LLMessageSystem* msg, bool isGroup) if (!isGroup) { - mSignal(id, entry->mFirstName, entry->mLastName, FALSE); - std::string fullname = entry->mFirstName + " " + entry->mLastName; - mReverseCache[fullname] = id; + // NOTE: Very occasionally the server sends down a full name + // in the first name field with an empty last name, for example, + // first = "Ladanie1 Resident", last = "". + // I cannot reproduce this, nor can I find a bug in the server code. + // Ensure "Resident" does not appear via cleanFullName, because + // buildFullName only checks last name. JC + std::string full_name; + if (entry->mLastName.empty()) + { + full_name = cleanFullName(entry->mFirstName); + } + else + { + full_name = LLCacheName::buildFullName(entry->mFirstName, entry->mLastName); + } + mSignal(id, full_name, false); + mReverseCache[full_name] = id; } else { - mSignal(id, entry->mGroupName, "", TRUE); + mSignal(id, entry->mGroupName, true); mReverseCache[entry->mGroupName] = id; } } @@ -962,4 +940,3 @@ void LLCacheName::Impl::handleUUIDGroupNameReply(LLMessageSystem* msg, void** us { ((LLCacheName::Impl*)userData)->processUUIDReply(msg, true); } - diff --git a/indra/llmessage/llcachename.h b/indra/llmessage/llcachename.h index 111cc8b650..6b6bbde6ab 100644 --- a/indra/llmessage/llcachename.h +++ b/indra/llmessage/llcachename.h @@ -42,13 +42,12 @@ class LLUUID; typedef boost::signals2::signal<void (const LLUUID& id, - const std::string& first_name, - const std::string& last_name, - BOOL is_group)> LLCacheNameSignal; + const std::string& name, + bool is_group)> LLCacheNameSignal; typedef LLCacheNameSignal::slot_type LLCacheNameCallback; // Old callback with user data for compatability -typedef void (*old_callback_t)(const LLUUID&, const std::string&, const std::string&, BOOL, void*); +typedef void (*old_callback_t)(const LLUUID&, const std::string&, bool, void*); // Here's the theory: // If you request a name that isn't in the cache, it returns "waiting" @@ -71,24 +70,26 @@ public: boost::signals2::connection addObserver(const LLCacheNameCallback& callback); - // janky old format. Remove after a while. Phoenix. 2008-01-30 - void importFile(LLFILE* fp); - // storing cache on disk; for viewer, in name.cache bool importFile(std::istream& istr); void exportFile(std::ostream& ostr); - // If available, copies the first and last name into the strings provided. - // first must be at least DB_FIRST_NAME_BUF_SIZE characters. - // last must be at least DB_LAST_NAME_BUF_SIZE characters. + // If available, copies name ("bobsmith123" or "James Linden") into string // If not available, copies the string "waiting". // Returns TRUE iff available. - BOOL getName(const LLUUID& id, std::string& first, std::string& last); - BOOL getFullName(const LLUUID& id, std::string& fullname); - + BOOL getFullName(const LLUUID& id, std::string& full_name); + // Reverse lookup of UUID from name BOOL getUUID(const std::string& first, const std::string& last, LLUUID& id); BOOL getUUID(const std::string& fullname, LLUUID& id); + + // IDEVO Temporary code + // Clean up new-style "bobsmith123 Resident" names to "bobsmith123" for display + static std::string buildFullName(const std::string& first, const std::string& last); + + // Clean up legacy "bobsmith123 Resident" to "bobsmith123" + // If name does not contain "Resident" returns it unchanged. + static std::string cleanFullName(const std::string& full_name); // If available, this method copies the group name into the string // provided. The caller must allocate at least @@ -100,10 +101,10 @@ public: // If the data is currently available, may call the callback immediatly // otherwise, will request the data, and will call the callback when // available. There is no garuntee the callback will ever be called. - boost::signals2::connection get(const LLUUID& id, BOOL is_group, const LLCacheNameCallback& callback); + boost::signals2::connection get(const LLUUID& id, bool is_group, const LLCacheNameCallback& callback); // LEGACY - boost::signals2::connection get(const LLUUID& id, BOOL is_group, old_callback_t callback, void* user_data); + boost::signals2::connection get(const LLUUID& id, bool is_group, old_callback_t callback, void* user_data); // This method needs to be called from time to time to send out // requests. void processPending(); @@ -114,9 +115,15 @@ public: // Debugging void dump(); // Dumps the contents of the cache void dumpStats(); // Dumps the sizes of the cache and associated queues. + void clear(); // Deletes all entries from the cache static std::string getDefaultName(); - static void LocalizeCacheName(std::string key, std::string value); + + // Returns "Resident", the default last name for SLID-based accounts + // that have no last name. + static std::string getDefaultLastName(); + + static void localizeCacheName(std::string key, std::string value); static std::map<std::string, std::string> sCacheName; private: diff --git a/indra/llmessage/mean_collision_data.h b/indra/llmessage/mean_collision_data.h index 03b96f9f90..a6c635e81e 100644 --- a/indra/llmessage/mean_collision_data.h +++ b/indra/llmessage/mean_collision_data.h @@ -61,7 +61,7 @@ public: LLMeanCollisionData(LLMeanCollisionData *mcd) : mVictim(mcd->mVictim), mPerp(mcd->mPerp), mTime(mcd->mTime), mType(mcd->mType), mMag(mcd->mMag), - mFirstName(mcd->mFirstName), mLastName(mcd->mLastName) + mFullName(mcd->mFullName) { } @@ -95,8 +95,7 @@ public: time_t mTime; EMeanCollisionType mType; F32 mMag; - std::string mFirstName; - std::string mLastName; + std::string mFullName; }; diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index ce25ee32b3..c693c18d1a 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -58,8 +58,6 @@ #include "lltooltip.h" // Globals -S32 LLCOMBOBOX_HEIGHT = 0; -S32 LLCOMBOBOX_WIDTH = 0; S32 MAX_COMBO_WIDTH = 500; static LLDefaultChildRegistry::Register<LLComboBox> register_combo_box("combo_box"); diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h index c694724248..7cac4cc738 100644 --- a/indra/llui/llcombobox.h +++ b/indra/llui/llcombobox.h @@ -49,9 +49,6 @@ class LLFontGL; class LLViewBorder; -extern S32 LLCOMBOBOX_HEIGHT; -extern S32 LLCOMBOBOX_WIDTH; - class LLComboBox : public LLUICtrl, public LLCtrlListInterface { diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 851fb966ec..385812416d 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1527,6 +1527,20 @@ std::string LLTextBase::getText() const return getViewModel()->getValue().asString(); } +// IDEVO - icons can be UI image names or UUID sent from +// server with avatar display name +static LLUIImagePtr image_from_icon_name(const std::string& icon_name) +{ + if (LLUUID::validate(icon_name)) + { + return LLUI::getUIImageByID( LLUUID(icon_name) ); + } + else + { + return LLUI::getUIImage(icon_name); + } +} + void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params) { LLStyle::Params style_params(input_params); @@ -1539,7 +1553,7 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c LLUrlMatch match; std::string text = new_text; while ( LLUrlRegistry::instance().findUrl(text, match, - boost::bind(&LLTextBase::replaceUrlLabel, this, _1, _2)) ) + boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3)) ) { start = match.getStart(); end = match.getEnd()+1; @@ -1570,15 +1584,18 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c // output an optional icon before the Url if (! match.getIcon().empty()) { - LLUIImagePtr image = LLUI::getUIImage(match.getIcon()); + LLUIImagePtr image = image_from_icon_name( match.getIcon() ); if (image) { - LLStyle::Params icon; - icon.image = image; + LLStyle::Params icon_params; + icon_params.image = image; + // must refer to our link so we can update the icon later + // after name/group data is looked up + icon_params.link_href = match.getUrl(); // Text will be replaced during rendering with the icon, // but string cannot be empty or the segment won't be // added (or drawn). - appendAndHighlightText(" ", prepend_newline, part, icon); + appendAndHighlightText(" ", prepend_newline, part, icon_params); prepend_newline = false; } } @@ -1728,8 +1745,9 @@ void LLTextBase::appendAndHighlightText(const std::string &new_text, bool prepen } -void LLTextBase::replaceUrlLabel(const std::string &url, - const std::string &label) +void LLTextBase::replaceUrl(const std::string &url, + const std::string &label, + const std::string &icon) { // get the full (wide) text for the editor so we can change it LLWString text = getWText(); @@ -1759,6 +1777,21 @@ void LLTextBase::replaceUrlLabel(const std::string &url, modified = true; } + // Icon might be updated when more avatar or group info + // becomes available + if (style->isImage() && style->getLinkHREF() == url) + { + LLUIImagePtr image = image_from_icon_name( icon ); + if (image) + { + LLStyle::Params icon_params; + icon_params.image = image; + LLStyleConstSP new_style(new LLStyle(icon_params)); + seg->setStyle(new_style); + modified = true; + } + } + // work out the character offset for the next segment seg_start = seg->getEnd(); } diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 5b24c63557..39cdaa0a58 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -313,7 +313,10 @@ protected: // misc void updateRects(); void needsScroll() { mScrollNeeded = TRUE; } - void replaceUrlLabel(const std::string &url, const std::string &label); + + // Replace a URL with a new icon and label, for example, when + // avatar names are looked up. + void replaceUrl(const std::string &url, const std::string &label, const std::string& icon); protected: // text segmentation and flow diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 35428e4227..ff6454c141 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -37,6 +37,7 @@ #include "llurlmatch.h" #include "llurlregistry.h" +#include "llavatarnamecache.h" #include "llcachename.h" #include "lltrans.h" #include "lluicolortable.h" @@ -56,6 +57,12 @@ std::string LLUrlEntryBase::getUrl(const std::string &string) const return escapeUrl(string); } +//virtual +std::string LLUrlEntryBase::getIcon(const std::string &url) const +{ + return mIcon; +} + std::string LLUrlEntryBase::getIDStringFromUrl(const std::string &url) const { // return the id from a SLURL in the format /app/{cmd}/{id}/about @@ -134,7 +141,9 @@ void LLUrlEntryBase::addObserver(const std::string &id, } } -void LLUrlEntryBase::callObservers(const std::string &id, const std::string &label) +void LLUrlEntryBase::callObservers(const std::string &id, + const std::string &label, + const std::string &icon) { // notify all callbacks waiting on the given uuid std::multimap<std::string, LLUrlEntryObserver>::iterator it; @@ -142,7 +151,7 @@ void LLUrlEntryBase::callObservers(const std::string &id, const std::string &lab { // call the callback - give it the new label LLUrlEntryObserver &observer = it->second; - (*observer.signal)(it->second.url, label); + (*observer.signal)(it->second.url, label, icon); // then remove the signal - we only need to call it once delete observer.signal; mObservers.erase(it++); @@ -314,13 +323,22 @@ LLUrlEntryAgent::LLUrlEntryAgent() mColor = LLUIColorTable::instance().getColor("AgentLinkColor"); } -void LLUrlEntryAgent::onAgentNameReceived(const LLUUID& id, - const std::string& first, - const std::string& last, - BOOL is_group) +void LLUrlEntryAgent::onNameCache(const LLUUID& id, + const std::string& full_name, + bool is_group) { + callObservers(id.asString(), full_name, mIcon); +} + +void LLUrlEntryAgent::onAvatarNameCache(const LLUUID& id, + const LLAvatarName& av_name) +{ + // IDEVO demo code + std::string label = av_name.mDisplayName + " (" + av_name.mSLID + ")"; + // use custom icon if available + std::string icon = (!av_name.mBadge.empty() ? av_name.mBadge : mIcon); // received the agent name from the server - tell our observers - callObservers(id.asString(), first + " " + last); + callObservers(id.asString(), label, icon); } std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCallback &cb) @@ -330,34 +348,80 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa // probably at the login screen, use short string for layout return LLTrans::getString("LoadingData"); } - + std::string agent_id_string = getIDStringFromUrl(url); if (agent_id_string.empty()) { // something went wrong, just give raw url return unescapeUrl(url); } - + LLUUID agent_id(agent_id_string); - std::string full_name; if (agent_id.isNull()) { return LLTrans::getString("AvatarNameNobody"); } - else if (gCacheName->getFullName(agent_id, full_name)) + + if (LLAvatarNameCache::useDisplayNames()) { - return full_name; + LLAvatarName av_name; + if (LLAvatarNameCache::get(agent_id, &av_name)) + { + return av_name.mDisplayName + " (" + av_name.mSLID + ")"; + } + else + { + LLAvatarNameCache::get(agent_id, + boost::bind(&LLUrlEntryAgent::onAvatarNameCache, + this, _1, _2)); + addObserver(agent_id_string, url, cb); + return LLTrans::getString("LoadingData"); + } } else { - gCacheName->get(agent_id, FALSE, - boost::bind(&LLUrlEntryAgent::onAgentNameReceived, - this, _1, _2, _3, _4)); - addObserver(agent_id_string, url, cb); - return LLTrans::getString("LoadingData"); + // ...no display names + std::string full_name; + if (gCacheName->getFullName(agent_id, full_name)) + { + return full_name; + } + else + { + gCacheName->get(agent_id, false, + boost::bind(&LLUrlEntryAgent::onNameCache, + this, _1, _2, _3)); + addObserver(agent_id_string, url, cb); + return LLTrans::getString("LoadingData"); + } } } + +std::string LLUrlEntryAgent::getIcon(const std::string &url) const +{ + std::string agent_id_string = getIDStringFromUrl(url); + if (agent_id_string.empty()) + { + return mIcon; + } + + LLUUID agent_id(agent_id_string); + if (agent_id.isNull()) + { + return mIcon; + } + + LLAvatarName av_name; + LLAvatarNameCache::get(agent_id, &av_name); + if (av_name.mBadge.empty()) + { + return mIcon; + } + + return av_name.mBadge; +} + // // LLUrlEntryGroup Describes a Second Life group Url, e.g., // secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about @@ -374,12 +438,11 @@ LLUrlEntryGroup::LLUrlEntryGroup() } void LLUrlEntryGroup::onGroupNameReceived(const LLUUID& id, - const std::string& first, - const std::string& last, - BOOL is_group) + const std::string& name, + bool is_group) { // received the group name from the server - tell our observers - callObservers(id.asString(), first); + callObservers(id.asString(), name, mIcon); } std::string LLUrlEntryGroup::getLabel(const std::string &url, const LLUrlLabelCallback &cb) @@ -409,9 +472,9 @@ std::string LLUrlEntryGroup::getLabel(const std::string &url, const LLUrlLabelCa } else { - gCacheName->get(group_id, TRUE, + gCacheName->get(group_id, true, boost::bind(&LLUrlEntryGroup::onGroupNameReceived, - this, _1, _2, _3, _4)); + this, _1, _2, _3)); addObserver(group_id_string, url, cb); return LLTrans::getString("LoadingData"); } diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index c947ef7259..c2cbe4d4c8 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -41,8 +41,11 @@ #include <string> #include <map> +class LLAvatarName; + typedef boost::signals2::signal<void (const std::string& url, - const std::string& label)> LLUrlLabelSignal; + const std::string& label, + const std::string& icon)> LLUrlLabelSignal; typedef LLUrlLabelSignal::slot_type LLUrlLabelCallback; /// @@ -77,7 +80,7 @@ public: virtual std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) { return url; } /// Return an icon that can be displayed next to Urls of this type - std::string getIcon() const { return mIcon; } + virtual std::string getIcon(const std::string &url) const; /// Return the color to render the displayed text LLUIColor getColor() const { return mColor; } @@ -101,7 +104,7 @@ protected: std::string getLabelFromWikiLink(const std::string &url) const; std::string getUrlFromWikiLink(const std::string &string) const; void addObserver(const std::string &id, const std::string &url, const LLUrlLabelCallback &cb); - void callObservers(const std::string &id, const std::string &label); + void callObservers(const std::string &id, const std::string &label, const std::string& icon); typedef struct { std::string url; @@ -163,15 +166,16 @@ public: /// /// LLUrlEntryAgent Describes a Second Life agent Url, e.g., /// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about -/// class LLUrlEntryAgent : public LLUrlEntryBase { public: LLUrlEntryAgent(); /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); + /*virtual*/ std::string getIcon(const std::string &url) const; + private: - void onAgentNameReceived(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); + void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name); }; /// @@ -184,8 +188,7 @@ public: LLUrlEntryGroup(); /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); private: - void onGroupNameReceived(const LLUUID& id, const std::string& first, - const std::string& last, BOOL is_group); + void onGroupNameReceived(const LLUUID& id, const std::string& name, bool is_group); }; /// diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index faa02e1904..3fadf3dd11 100644 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -37,12 +37,14 @@ #include <boost/regex.hpp> // default dummy callback that ignores any label updates from the server -void LLUrlRegistryNullCallback(const std::string &url, const std::string &label) +void LLUrlRegistryNullCallback(const std::string &url, const std::string &label, const std::string& icon) { } LLUrlRegistry::LLUrlRegistry() { + mUrlEntry.reserve(16); + // Urls are matched in the order that they were registered registerUrl(new LLUrlEntryNoLink()); registerUrl(new LLUrlEntrySLURL()); @@ -74,10 +76,13 @@ LLUrlRegistry::~LLUrlRegistry() } } -void LLUrlRegistry::registerUrl(LLUrlEntryBase *url) +void LLUrlRegistry::registerUrl(LLUrlEntryBase *url, bool force_front) { if (url) { + if (force_front) // IDEVO + mUrlEntry.insert(mUrlEntry.begin(), url); + else mUrlEntry.push_back(url); } } @@ -175,7 +180,7 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL match_entry->getUrl(url), match_entry->getLabel(url, cb), match_entry->getTooltip(url), - match_entry->getIcon(), + match_entry->getIcon(url), match_entry->getColor(), match_entry->getMenuName(), match_entry->getLocation(url), diff --git a/indra/llui/llurlregistry.h b/indra/llui/llurlregistry.h index 399ee0a988..dffbd9d4bf 100644 --- a/indra/llui/llurlregistry.h +++ b/indra/llui/llurlregistry.h @@ -43,7 +43,9 @@ #include <vector> /// This default callback for findUrl() simply ignores any label updates -void LLUrlRegistryNullCallback(const std::string &url, const std::string &label); +void LLUrlRegistryNullCallback(const std::string &url, + const std::string &label, + const std::string &icon); /// /// LLUrlRegistry is a singleton that contains a set of Url types that @@ -70,7 +72,9 @@ public: ~LLUrlRegistry(); /// add a new Url handler to the registry (will be freed on destruction) - void registerUrl(LLUrlEntryBase *url); + /// optionally force it to the front of the list, making it take + /// priority over other regular expression matches for URLs + void registerUrl(LLUrlEntryBase *url, bool force_front = false); /// get the next Url in an input string, starting at a given character offset /// your callback is invoked if the matched Url's label changes in the future diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp index 26d1f2e067..e984f5cf81 100644 --- a/indra/llui/tests/llurlentry_stub.cpp +++ b/indra/llui/tests/llurlentry_stub.cpp @@ -22,11 +22,28 @@ #include "llstring.h" #include "llfile.h" +#include "llavatarnamecache.h" #include "llcachename.h" #include "lluuid.h" #include <string> +// Stub for LLAvatarNameCache +bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name) +{ + return false; +} + +void LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot) +{ + return; +} + +bool LLAvatarNameCache::useDisplayNames() +{ + return false; +} + // // Stub implementation for LLCacheName // @@ -42,7 +59,7 @@ BOOL LLCacheName::getGroupName(const LLUUID& id, std::string& group) return TRUE; } -boost::signals2::connection LLCacheName::get(const LLUUID& id, BOOL is_group, const LLCacheNameCallback& callback) +boost::signals2::connection LLCacheName::get(const LLUUID& id, bool is_group, const LLCacheNameCallback& callback) { return boost::signals2::connection(); } diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp index cbb303a059..bcb1e65092 100644 --- a/indra/llui/tests/llurlentry_test.cpp +++ b/indra/llui/tests/llurlentry_test.cpp @@ -285,7 +285,6 @@ namespace tut testRegex("Agent Url alternate command", url, "XXX secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/foobar", "secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/foobar"); - } template<> template<> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 74037f8b21..cf8e238855 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -7135,7 +7135,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> @@ -7144,6 +7144,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>NameTagShowSLIDs</key> + <map> + <key>Comment</key> + <string>Show Second Life IDs in name labels</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>NameTagShowStatus</key> + <map> + <key>Comment</key> + <string>Show status (AFK, Busy) in name labels</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> <integer>1</integer> </map> <key>RenderInitError</key> diff --git a/indra/newview/llagentui.cpp b/indra/newview/llagentui.cpp index 72ab9235cf..c890988930 100644 --- a/indra/newview/llagentui.cpp +++ b/indra/newview/llagentui.cpp @@ -46,31 +46,6 @@ #include "llslurl.h" //static -void LLAgentUI::buildName(std::string& name) -{ - name.clear(); - - LLVOAvatarSelf* avatar_object = gAgent.getAvatarObject(); - if (avatar_object) - { - LLNameValue *first_nv = avatar_object->getNVPair("FirstName"); - LLNameValue *last_nv = avatar_object->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 (gAgent.getAvatarObject()) name = gAgent.getAvatarObject()->getFullname(); diff --git a/indra/newview/llagentui.h b/indra/newview/llagentui.h index 3478793e38..c682d3c951 100644 --- a/indra/newview/llagentui.h +++ b/indra/newview/llagentui.h @@ -45,7 +45,6 @@ public: LOCATION_FORMAT_FULL, // Parcel, Region (x, y, z) - Maturity }; - static void buildName(std::string& name); static void buildFullname(std::string &name); static std::string buildSLURL(const bool escaped = true); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 36faeb100f..e6206ba0d2 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -85,6 +85,7 @@ #include "llsecondlifeurls.h" // Linden library includes +#include "llavatarnamecache.h" #include "llimagej2c.h" #include "llmemory.h" #include "llprimitive.h" @@ -157,7 +158,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" @@ -400,9 +400,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"); @@ -1299,8 +1296,7 @@ bool LLAppViewer::cleanup() LLPolyMesh::freeAllMeshes(); - delete gCacheName; - gCacheName = NULL; + LLStartUp::cleanupNameCache(); // Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be deleted. @@ -3368,15 +3364,6 @@ void LLAppViewer::loadNameCache() { if(gCacheName->importFile(cache_file)) return; } - - // Try to load from the legacy format. This should go away after a - // while. Phoenix 2008-01-30 - LLFILE* name_cache_fp = LLFile::fopen(name_cache, "r"); // Flawfinder: ignore - if (name_cache_fp) - { - gCacheName->importFile(name_cache_fp); - fclose(name_cache_fp); - } } void LLAppViewer::saveNameCache() @@ -3942,6 +3929,8 @@ void LLAppViewer::idleNetwork() // deal with any queued name requests and replies. gCacheName->processPending(); + LLAvatarNameCache::idle(); + llpushcallstacks ; LLTimer check_message_timer; // Read all available packets from network diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index e6666c7f83..f947300f54 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -35,11 +35,11 @@ #include "llavataractions.h" +#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" @@ -63,6 +63,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) @@ -74,7 +75,7 @@ void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::strin } LLSD args; - args["NAME"] = name; + args["NAME"] = LLSLURL::buildCommand("agent", id, "inspect"); LLSD payload; payload["id"] = id; payload["name"] = name; @@ -129,11 +130,10 @@ void LLAvatarActions::removeFriendsDialog(const std::vector<LLUUID>& 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"; @@ -188,6 +188,14 @@ void LLAvatarActions::startIM(const LLUUID& id) return; } + // IDEVO + LLAvatarName av_name; + if (LLAvatarNameCache::useDisplayNames() + && LLAvatarNameCache::get(id, &av_name)) + { + name = av_name.mDisplayName + " (" + av_name.mSLID + ")"; + } + LLUUID session_id = gIMMgr->addSession(name, IM_NOTHING_SPECIAL, id); if (session_id != LLUUID::null) { @@ -219,6 +227,13 @@ void LLAvatarActions::startCall(const LLUUID& id) std::string name; gCacheName->getFullName(id, name); + // IDEVO + LLAvatarName av_name; + if (LLAvatarNameCache::useDisplayNames() + && LLAvatarNameCache::get(id, &av_name)) + { + name = av_name.mDisplayName + " (" + av_name.mSLID + ")"; + } LLUUID session_id = gIMMgr->addSession(name, IM_NOTHING_SPECIAL, id, true); if (session_id != LLUUID::null) { @@ -636,9 +651,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/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp index 9645e75e60..c70570b532 100644 --- a/indra/newview/llavatarlistitem.cpp +++ b/indra/newview/llavatarlistitem.cpp @@ -225,7 +225,7 @@ void LLAvatarListItem::setAvatarId(const LLUUID& id, const LLUUID& session_id, b LLAvatarTracker::instance().addParticularFriendObserver(mAvatarId, this); // Set avatar name. - gCacheName->get(id, FALSE, boost::bind(&LLAvatarListItem::onNameCache, this, _2, _3)); + gCacheName->get(id, false, boost::bind(&LLAvatarListItem::onNameCache, this, _2)); } void LLAvatarListItem::showLastInteractionTime(bool show) @@ -330,10 +330,9 @@ void LLAvatarListItem::setNameInternal(const std::string& name, const std::strin mAvatarName->setToolTip(name); } -void LLAvatarListItem::onNameCache(const std::string& first_name, const std::string& last_name) +void LLAvatarListItem::onNameCache(const std::string& fullname) { - std::string name = first_name + " " + last_name; - setName(name); + setName(fullname); } // Convert given number of seconds to a string like "23 minutes", "15 hours" or "3 years", diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h index cecb64add7..70750723dc 100644 --- a/indra/newview/llavatarlistitem.h +++ b/indra/newview/llavatarlistitem.h @@ -151,7 +151,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 onNameCache(const std::string& fullname); std::string formatSeconds(U32 secs); diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp index 79a2631c31..2b124118ca 100644 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp @@ -250,7 +250,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 +260,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") @@ -867,10 +868,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); @@ -880,10 +879,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); @@ -893,10 +890,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); @@ -907,5 +902,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 e1c96d4a16..bf3e8795a5 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -240,7 +240,7 @@ public: mAvatarID = chat.mFromID; mSessionID = chat.mSessionID; mSourceType = chat.mSourceType; - gCacheName->get(mAvatarID, FALSE, boost::bind(&LLChatHistoryHeader::nameUpdatedCallback, this, _1, _2, _3, _4)); + gCacheName->get(mAvatarID, false, boost::bind(&LLChatHistoryHeader::nameUpdatedCallback, this, _1, _2, _3)); //*TODO overly defensive thing, source type should be maintained out there if((chat.mFromID.isNull() && chat.mFromName.empty()) || chat.mFromName == SYSTEM_FROM) @@ -317,11 +317,11 @@ public: LLPanel::draw(); } - void nameUpdatedCallback(const LLUUID& id,const std::string& first,const std::string& last,BOOL is_group) + void nameUpdatedCallback(const LLUUID& id,const std::string& full_name, bool is_group) { if (id != mAvatarID) return; - mFrom = first + " " + last; + mFrom = full_name; } protected: static const S32 PADDING = 20; @@ -747,7 +747,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL { LLButton * button = dynamic_cast<LLButton*> (*it); if (button != NULL) - { + { button->setOrigin( offset, button->getRect().mBottom); button->setLeftHPad(2 * HPAD); @@ -760,7 +760,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL button->autoResize(); offset += 2 * HPAD + button->getRect().getWidth(); button->setFollowsNone(); - } + } } LLTextEditor* text_editor = notify_box->getChild<LLTextEditor>("text_editor_box", TRUE); diff --git a/indra/newview/lldateutil.cpp b/indra/newview/lldateutil.cpp index abb2fdeb9a..150edb5bf8 100644 --- a/indra/newview/lldateutil.cpp +++ b/indra/newview/lldateutil.cpp @@ -59,12 +59,9 @@ static S32 days_from_month(S32 year, S32 month) } } -std::string LLDateUtil::ageFromDate(const std::string& date_string, - const LLDate& now) +static std::string age_from_date(S32 born_year, S32 born_month, S32 born_day, + const LLDate& now) { - S32 born_month, born_day, born_year; - S32 matched = sscanf(date_string.c_str(), "%d/%d/%d", &born_month, &born_day, &born_year); - if (matched != 3) return "???"; LLDate born_date; born_date.fromYMDHMS(born_year, born_month, born_day); F64 born_date_secs_since_epoch = born_date.secondsSinceEpoch(); @@ -155,7 +152,31 @@ std::string LLDateUtil::ageFromDate(const std::string& date_string, return LLTrans::getString("TodayOld"); } +std::string LLDateUtil::ageFromDate(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_month, &born_day, &born_year); + if (matched != 3) return "???"; + return age_from_date(born_year, born_month, born_day, now); +} + 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 "???"; + return age_from_date(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 041be07f12..d077f4eefb 100644 --- a/indra/newview/lldateutil.h +++ b/indra/newview/lldateutil.h @@ -44,6 +44,12 @@ 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); } #endif diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index a0b2de85f0..ed458a4b02 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -36,13 +36,17 @@ // Viewer includes #include "llagent.h" #include "llcallingcard.h" +#include "lldateutil.h" // IDEVO #include "llfocusmgr.h" #include "llfloaterreg.h" #include "llviewercontrol.h" #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" @@ -338,23 +342,55 @@ BOOL LLFloaterAvatarPicker::visibleItemsSelected() const return FALSE; } -void LLFloaterAvatarPicker::find() +class LLAvatarPickerResponder : public LLHTTPClient::Responder { - std::string text = childGetValue("Edit").asString(); +public: + LLUUID mQueryID; - mQueryID.generate(); + LLAvatarPickerResponder(const LLUUID& id) : mQueryID(id) { } - LLMessageSystem* msg = gMessageSystem; + /*virtual*/ void result(const LLSD& content) + { + LLFloaterAvatarPicker* floater = + LLFloaterReg::findTypedInstance<LLFloaterAvatarPicker>("avatar_picker"); + if (floater) + { + floater->processResponse(mQueryID, content); + } + } - 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); + /*virtual*/ void error(U32 status, const std::string& reason) + { + llinfos << "JAMESDEBUG avatar picker failed " << status + << " reason " << reason << llendl; + } +}; - gAgent.sendReliableMessage(); +void LLFloaterAvatarPicker::find() +{ + std::string text = childGetValue("Edit").asString(); + + mQueryID.generate(); + // IDEVO + if (LLAvatarNameCache::useDisplayNames()) + { + std::string url = "http://pdp15.lindenlab.com:8050/my-service/agent/search/"; + url += LLURI::escape(text); + url += "/"; + 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")); @@ -420,12 +456,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); } @@ -439,6 +476,56 @@ 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"); + + if (content.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 = content.beginArray(); + for ( ; it != content.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["slid"]; + std::string born_on = row["born_on"].asString(); + columns[2]["column"] = "age"; + columns[2]["value"] = LLDateUtil::ageFromDateISO(born_on); + columns[3]["column"] = "profile"; + columns[3]["value"] = row["profile"]; + 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) { diff --git a/indra/newview/llfloateravatarpicker.h b/indra/newview/llfloateravatarpicker.h index e35466cec8..bae43d3211 100644 --- a/indra/newview/llfloateravatarpicker.h +++ b/indra/newview/llfloateravatarpicker.h @@ -58,6 +58,7 @@ public: void setOkBtnEnableCb(validate_callback_t cb); static void processAvatarPickerReply(class LLMessageSystem* msg, void**); + void processResponse(const LLUUID& query_id, const LLSD& content); private: void editKeystroke(class LLLineEditor* caller, void* user_data); 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 d37bc01885..c0e20685c6 100644 --- a/indra/newview/llfloaterbuyland.cpp +++ b/indra/newview/llfloaterbuyland.cpp @@ -185,9 +185,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(); @@ -823,9 +822,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 { @@ -835,16 +834,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 26c6db9652..f09459d5db 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -1363,10 +1363,9 @@ bool LLPanelLandObjects::callbackReturnOwnerObjects(const LLSD& notification, co } else { - std::string first, last; - gCacheName->getName(owner_id, first, last); - args["FIRST"] = first; - args["LAST"] = last; + std::string full_name; + gCacheName->getFullName(owner_id, full_name); + args["NAME"] = full_name; LLNotificationsUtil::add("OtherObjectsReturned", args); } send_return_objects_message(parcel->getLocalID(), RT_OWNER); diff --git a/indra/newview/llfloaterpay.cpp b/indra/newview/llfloaterpay.cpp index 51364594e4..7dbcc9555c 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::buildCommand("group", target_id, "inspect"); } else { setTitle(getString("payee_resident")); + slurl = LLSLURL::buildCommand("agent", target_id, "inspect"); } + 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/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index d54736e942..0139d0e301 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -1972,8 +1972,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 0f3c176cea..a97c21ff6c 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" @@ -270,9 +271,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 122bdc8bc7..d56bc7b75b 100644 --- a/indra/newview/llfloaterscriptlimits.cpp +++ b/indra/newview/llfloaterscriptlimits.cpp @@ -563,11 +563,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) { @@ -639,6 +636,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; @@ -664,15 +664,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, - boost::bind(&LLPanelScriptLimitsRegionMemory::onNameCache, - this, _1, _2, _3)); + gCacheName->get(owner_id, is_group_owned, + boost::bind(&LLPanelScriptLimitsRegionMemory::onNameCache, + this, _1, _2)); } } } diff --git a/indra/newview/llfloaterscriptlimits.h b/indra/newview/llfloaterscriptlimits.h index 0cba4d72f2..ce49209039 100644 --- a/indra/newview/llfloaterscriptlimits.h +++ b/indra/newview/llfloaterscriptlimits.h @@ -173,10 +173,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/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp index 8ab050beaa..83700e6264 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 8569e208eb..4b2fc54753 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" @@ -987,7 +988,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/llhudtext.cpp b/indra/newview/llhudtext.cpp index 8d1d27444b..b14753ff2a 100644 --- a/indra/newview/llhudtext.cpp +++ b/indra/newview/llhudtext.cpp @@ -87,7 +87,6 @@ bool lltextobject_further_away::operator()(const LLPointer<LLHUDText>& lhs, cons LLHUDText::LLHUDText(const U8 type) : LLHUDObject(type), mUseBubble(FALSE), - mUsePixelSize(TRUE), mVisibleOffScreen(FALSE), mWidth(0.f), mHeight(0.f), @@ -491,6 +490,7 @@ void LLHUDText::renderText(BOOL for_select) 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(); @@ -528,7 +528,7 @@ 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; @@ -562,15 +562,10 @@ void LLHUDText::renderText(BOOL for_select) } } -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 +574,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 +599,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 = (mUseBubble ? HUD_TEXT_MAX_WIDTH : 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,18 +611,17 @@ void LLHUDText::addLine(const LLWString &wstr, const LLColor4& color, const LLFo } } -void LLHUDText::setLabel(const std::string &label) +void LLHUDText::setLabel(const std::string &label_utf8) { - setLabel(utf8str_to_wstring(label)); + mLabelSegments.clear(); + addLabel(label_utf8); } -void LLHUDText::setLabel(const LLWString &wlabel) +void LLHUDText::addLabel(const std::string& label_utf8) { - mLabelSegments.clear(); - - if (!wlabel.empty()) + LLWString wstr = utf8string_to_wstring(label_utf8); + if (!wstr.empty()) { - LLWString wstr(wlabel); LLWString seps(utf8str_to_wstring("\r\n")); LLWString empty; @@ -643,7 +637,8 @@ void LLHUDText::setLabel(const LLWString &wlabel) 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)); + 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()); @@ -678,12 +673,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; @@ -827,12 +827,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,13 +841,16 @@ 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()) { + height += mFontp->getLineHeight(); width = llmax(width, llmin(iter->getWidth(mFontp), HUD_TEXT_MAX_WIDTH)); ++iter; } diff --git a/indra/newview/llhudtext.h b/indra/newview/llhudtext.h index dc14a8c764..8219358cc1 100644 --- a/indra/newview/llhudtext.h +++ b/indra/newview/llhudtext.h @@ -34,7 +34,6 @@ #define LL_LLHUDTEXT_H #include "llpointer.h" -#include "lldarrayptr.h" #include "llhudobject.h" #include "v4color.h" @@ -45,7 +44,6 @@ #include "llfontgl.h" #include <set> #include <vector> -#include "lldarray.h" // Renders a 2D text billboard floating at the location specified. class LLDrawable; @@ -62,14 +60,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,17 +92,18 @@ public: } EVertAlignment; public: - void setStringUTF8(const std::string &utf8string); - void setString(const LLWString &wstring); + void setString(const std::string& text_utf8); +// void setString(const LLWString &wstring); 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 addLine(const std::string &text_utf8, const LLColor4& color, const LLFontGL::StyleFlags style = LLFontGL::NORMAL, const LLFontGL* font = NULL); +// void addLine(const LLWString &wtext, const LLColor4& color, const LLFontGL::StyleFlags style = LLFontGL::NORMAL, const LLFontGL* font = NULL); + void setLabel(const std::string& label_utf8); +// void setLabel(const LLWString &label); + void addLabel(const std::string& label_utf8); void setDropShadow(const BOOL do_shadow); 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; } @@ -150,7 +154,6 @@ private: F32 mFadeRange; F32 mFadeDistance; F32 mLastDistance; - BOOL mUsePixelSize; BOOL mZCompare; BOOL mVisibleOffScreen; BOOL mOffscreen; diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index b3f085ef6d..2d3971ff43 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 "llrect.h" @@ -1850,6 +1851,11 @@ BOOL LLIncomingCallDialog::postBuild() { caller_name = LLTextUtil::formatPhoneNumber(caller_name); } + else + { + // IDEVO + caller_name = LLCacheName::cleanFullName(caller_name); + } setTitle(caller_name + " " + call_type); @@ -1978,6 +1984,13 @@ void LLIncomingCallDialog::processCallResponse(S32 response) { if (gCacheName->getFullName(caller_id, correct_session_name)) { + // IDEVO really should be using callbacks here + LLAvatarName av_name; + if (LLAvatarNameCache::useDisplayNames() + && LLAvatarNameCache::get(caller_id, &av_name)) + { + correct_session_name = av_name.mDisplayName + " (" + av_name.mSLID + ")"; + } correct_session_name.append(ADHOC_NAME_SUFFIX); } } @@ -2488,7 +2501,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 { @@ -2498,9 +2512,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(); @@ -2715,13 +2729,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 e7404074e0..c5ceaf3a89 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -429,7 +429,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); diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp index 14bc4376fe..1c68c50ec6 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" @@ -142,11 +143,9 @@ private: 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 onNameCache(const LLUUID& id, + const std::string& name, + bool is_group); private: LLUUID mAvatarID; @@ -370,9 +369,9 @@ void LLInspectAvatar::requestUpdate() childSetValue("avatar_icon", LLSD(mAvatarID) ); - gCacheName->get(mAvatarID, FALSE, - boost::bind(&LLInspectAvatar::nameUpdatedCallback, - this, _1, _2, _3, _4)); + gCacheName->get(mAvatarID, false, + boost::bind(&LLInspectAvatar::onNameCache, + this, _1, _2, _3)); } void LLInspectAvatar::processAvatarData(LLAvatarData* data) @@ -613,16 +612,28 @@ void LLInspectAvatar::onVolumeChange(const LLSD& data) gVoiceClient->setUserVolume(mAvatarID, volume); } -void LLInspectAvatar::nameUpdatedCallback( +void LLInspectAvatar::onNameCache( const LLUUID& id, - const std::string& first, - const std::string& last, - BOOL is_group) + const std::string& full_name, + bool is_group) { if (id == mAvatarID) { - mAvatarName = first + " " + last; - childSetValue("user_name", LLSD(mAvatarName) ); + mAvatarName = full_name; + + // IDEVO JAMESDEBUG - need to always display a display name + LLAvatarName av_name; + if (LLAvatarNameCache::useDisplayNames() + && LLAvatarNameCache::get(mAvatarID, &av_name)) + { + getChild<LLUICtrl>("user_name")->setValue(av_name.mDisplayName); + getChild<LLUICtrl>("user_slid")->setValue(av_name.mSLID); + } + else + { + getChild<LLUICtrl>("user_name")->setValue(full_name); + getChild<LLUICtrl>("user_slid")->setValue(""); + } } } 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 66e4a1bf66..e91f68f0c9 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 27a40c6ba0..734e1767ac 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -36,6 +36,8 @@ #include "llinventorybridge.h" +#include "llavatarnamecache.h" // IDEVO + #include "llagent.h" #include "llagentwearables.h" #include "llappearancemgr.h" @@ -3579,6 +3581,13 @@ void LLCallingCardBridge::performAction(LLFolderView* folder, LLInventoryModel* { 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.mSLID + ")"; + } 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 83a466a243..b19df3156f 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -756,7 +756,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/llmutelist.cpp b/indra/newview/llmutelist.cpp index 2d3c4b187e..38a518c5fd 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; } @@ -443,7 +442,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) @@ -461,8 +460,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) @@ -477,7 +475,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; @@ -487,24 +485,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 full_name; + if (gCacheName->getFullName(agent_id, full_name)) { - std::string cache_first, cache_last; - if (gCacheName->getName(agent_id, cache_first, cache_last)) - { - // name in cache, call callback directly - notify_automute_callback(agent_id, cache_first, cache_last, 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)); - } + // name in cache, call callback directly + notify_automute_callback(agent_id, full_name, false, reason); } else { - // call callback directly - notify_automute_callback(agent_id, first_name, last_name, FALSE, reason); + // not in cache, lookup name from cache + 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 e1e81a24b4..777b4843c8 100644 --- a/indra/newview/llmutelist.h +++ b/indra/newview/llmutelist.h @@ -74,7 +74,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 }; @@ -107,7 +107,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 883d4cdf4b..c3ff61aae3 100644 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -341,22 +341,11 @@ 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::refresh(const LLUUID& id, const std::string& full_name, bool is_group) { //llinfos << "LLNameListCtrl::refresh " << id << " '" << first << " " // << last << "'" << llendl; - std::string fullname; - if (!is_group) - { - fullname = first + " " + last; - } - else - { - fullname = first; - } - // TODO: scan items for that ID, fix if necessary item_list::iterator iter; for (iter = getItemList().begin(); iter != getItemList().end(); iter++) @@ -367,7 +356,7 @@ void LLNameListCtrl::refresh(const LLUUID& id, const std::string& first, LLScrollListCell* cell = item->getColumn(mNameColumnIndex); if (cell) { - cell->setValue(fullname); + cell->setValue(full_name); } } } @@ -377,15 +366,14 @@ 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) +void LLNameListCtrl::refreshAll(const LLUUID& id, const std::string& full_name, 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); + ctrl.refresh(id, full_name, is_group); } } diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h index 1c26ee5db4..6d61214712 100644 --- a/indra/newview/llnamelistctrl.h +++ b/indra/newview/llnamelistctrl.h @@ -105,10 +105,9 @@ public: void removeNameItem(const LLUUID& agent_id); - 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); // LLView interface /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp index 88bb769109..125a55902b 100644 --- a/indra/newview/llnotificationhandlerutil.cpp +++ b/indra/newview/llnotificationhandlerutil.cpp @@ -114,8 +114,10 @@ void LLSysHandler::removeExclusiveNotifications(const LLNotificationPtr& notif) const static std::string GRANTED_MODIFY_RIGHTS("GrantedModifyRights"), REVOKED_MODIFY_RIGHTS("RevokedModifyRights"), OBJECT_GIVE_ITEM( - "ObjectGiveItem"), OBJECT_GIVE_ITEM_UNKNOWN_USER( - "ObjectGiveItemUnknownUser"), PAYMENT_RECIVED("PaymentRecived"), + "ObjectGiveItem"), + PAYMENT_RECEIVED("PaymentReceived"), + PAYMENT_RECEIVED_FOR("PaymentReceivedFor"), + PAYMENT_SENT("PaymentSent"), ADD_FRIEND_WITH_MESSAGE("AddFriendWithMessage"), USER_GIVE_ITEM("UserGiveItem"), INVENTORY_ACCEPTED("InventoryAccepted"), @@ -134,7 +136,9 @@ 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_RECEIVED_FOR == notification->getName() + || PAYMENT_SENT == notification->getName() || OFFER_FRIENDSHIP == notification->getName() || FRIENDSHIP_OFFERED == notification->getName() || FRIENDSHIP_ACCEPTED_BYME == notification->getName() @@ -231,8 +235,7 @@ void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_fi "SESSION_NAME") ? notification->getPayload()["SESSION_NAME"].asString() : name; // don't create IM p2p session with objects, it's necessary condition to log - if (notification->getName() != OBJECT_GIVE_ITEM && notification->getName() - != OBJECT_GIVE_ITEM_UNKNOWN_USER) + if (notification->getName() != OBJECT_GIVE_ITEM) { LLUUID from_id = notification->getPayload()["from_id"]; diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index 57b478ffef..4680e3b7bf 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -223,12 +223,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 05261a65de..3f0eca0780 100644 --- a/indra/newview/llpanelgroupinvite.cpp +++ b/indra/newview/llpanelgroupinvite.cpp @@ -404,16 +404,18 @@ void LLPanelGroupInvite::addUsers(std::vector<LLUUID>& 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(std::vector<LLUUID>& 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(std::vector<LLUUID>& 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; std::vector<LLUUID> 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 b095dd2395..df865c9a63 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 5f913d5469..295a7aadb1 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 "llinventoryfunctions.h" @@ -533,6 +534,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 c34f0633b9..ed1de8d612 100644 --- a/indra/newview/llpanelimcontrolpanel.cpp +++ b/indra/newview/llpanelimcontrolpanel.cpp @@ -184,7 +184,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); } @@ -226,6 +226,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)); } } @@ -241,6 +250,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 56d52ccc65..e376fe4c32 100644 --- a/indra/newview/llpanellandmarkinfo.cpp +++ b/indra/newview/llpanellandmarkinfo.cpp @@ -44,6 +44,7 @@ #include "llagent.h" #include "llagentui.h" #include "lllandmarkactions.h" +#include "llslurl.h" #include "llviewerinventory.h" #include "llviewerparcelmgr.h" #include "llviewerregion.h" @@ -230,13 +231,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::buildCommand("agent", creator_id, "inspect"); + //if (!gCacheName->getFullName(creator_id, name)) + //{ + // gCacheName->get(creator_id, FALSE, + // boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, mCreator, _2, _3)); + //} mCreator->setText(name); } else @@ -253,20 +256,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::buildCommand("group", group_id, "inspect"); } 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::buildCommand("agent", owner_id, "inspect"); } mOwner->setText(name); } diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 7bd03167fd..e02224da84 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -213,7 +213,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, } #if !USE_VIEWER_AUTH - childSetPrevalidate("first_name_edit", LLTextValidate::validateASCIIPrintableNoSpace); + //childSetPrevalidate("login_id_edit", LLTextValidate::validateASCIIPrintableNoSpace); childSetPrevalidate("last_name_edit", LLTextValidate::validateASCIIPrintableNoSpace); childSetCommitCallback("password_edit", mungePassword, this); @@ -499,7 +499,7 @@ void LLPanelLogin::giveFocus() if( sInstance ) { // Grab focus and move cursor to first blank input field - std::string first = sInstance->childGetText("first_name_edit"); + std::string first = sInstance->childGetText("login_id_edit"); std::string pass = sInstance->childGetText("password_edit"); BOOL have_first = !first.empty(); @@ -515,7 +515,7 @@ void LLPanelLogin::giveFocus() else { // User doesn't have a name, so start there. - edit = sInstance->getChild<LLLineEditor>("first_name_edit"); + edit = sInstance->getChild<LLLineEditor>("login_id_edit"); } if (edit) @@ -537,8 +537,8 @@ void LLPanelLogin::showLoginWidgets() // *TODO: Append all the usual login parameters, like first_login=Y etc. std::string splash_screen_url = sInstance->getString("real_url"); web_browser->navigateTo( splash_screen_url, "text/html" ); - LLUICtrl* first_name_edit = sInstance->getChild<LLUICtrl>("first_name_edit"); - first_name_edit->setFocus(TRUE); + LLUICtrl* login_id_edit = sInstance->getChild<LLUICtrl>("login_id_edit"); + login_id_edit->setFocus(TRUE); } // static @@ -570,8 +570,15 @@ void LLPanelLogin::setFields(const std::string& firstname, return; } - sInstance->childSetText("first_name_edit", firstname); - sInstance->childSetText("last_name_edit", lastname); + std::string login_id = firstname; + if (!lastname.empty() && lastname != "Resident") + { + // support traditional First Last name slurls + login_id += " "; + login_id += lastname; + } + sInstance->childSetText("login_id_edit", login_id); + sInstance->childSetText("last_name_edit", std::string()); // Max "actual" password length is 16 characters. // Hex digests are always 32 characters. @@ -624,10 +631,24 @@ void LLPanelLogin::getFields(std::string *firstname, return; } - *firstname = sInstance->childGetText("first_name_edit"); - LLStringUtil::trim(*firstname); + std::string login_id = sInstance->childGetText("login_id_edit"); + LLStringUtil::trim(login_id); - *lastname = sInstance->childGetText("last_name_edit"); + U32 pos = login_id.find(' '); + if (pos != std::string::npos) + { + // old-style Firstname Lastname + *firstname = login_id.substr(0, pos); + *lastname = login_id.substr(pos+1); + } + else + { + // new-style single SLID string + *firstname = login_id; + *lastname = "Resident"; + } + + LLStringUtil::trim(*firstname); LLStringUtil::trim(*lastname); *password = sInstance->mMungedPassword; @@ -912,8 +933,10 @@ void LLPanelLogin::onClickConnect(void *) // JC - Make sure the fields all get committed. sInstance->setFocus(FALSE); - std::string first = sInstance->childGetText("first_name_edit"); - std::string last = sInstance->childGetText("last_name_edit"); + // Do SLID "Resident" name mangling + std::string first, last, unused_password; + getFields(&first, &last, &unused_password); + LLComboBox* combo = sInstance->getChild<LLComboBox>("start_location_combo"); std::string combo_text = combo->getSimple(); diff --git a/indra/newview/llpanelme.cpp b/indra/newview/llpanelme.cpp index 3504cbd1ef..84ed7356f1 100644 --- a/indra/newview/llpanelme.cpp +++ b/indra/newview/llpanelme.cpp @@ -32,16 +32,23 @@ #include "llviewerprecompiledheaders.h" +#include "llpanelme.h" + +// Viewer includes #include "llpanelprofile.h" #include "llavatarconstants.h" -#include "llpanelme.h" #include "llagent.h" #include "llagentwearables.h" -#include "lliconctrl.h" #include "llsidetray.h" +#include "llviewercontrol.h" + +// Linden libraries +#include "llavatarnamecache.h" // IDEVO +#include "llchat.h" // IDEVO HACK +#include "lliconctrl.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" @@ -221,13 +228,28 @@ 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) + // 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); + //} + std::string full_name; + LLAvatarName av_name; + if (LLAvatarNameCache::useDisplayNames() + && LLAvatarNameCache::get(avatar_data->avatar_id, &av_name)) { - childSetTextArg("name_text", "[FIRST]", first); - childSetTextArg("name_text", "[LAST]", last); + getChild<LLUICtrl>("user_name")->setValue( av_name.mDisplayName ); + getChild<LLUICtrl>("user_slid")->setValue( av_name.mSLID ); } + else if (gCacheName->getFullName(avatar_data->avatar_id, full_name)) + { + getChild<LLUICtrl>("user_name")->setValue(full_name); + getChild<LLUICtrl>("user_slid")->setValue(""); + } + + getChild<LLUICtrl>("set_name")->setVisible( LLAvatarNameCache::useDisplayNames() ); } BOOL LLPanelMyProfileEdit::postBuild() @@ -237,6 +259,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(); } /** @@ -264,8 +289,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) @@ -277,6 +304,54 @@ void LLPanelMyProfileEdit::onTexturePickerMouseLeave(LLUICtrl* ctrl) mTextureEditIconMap[ctrl->getName()]->setVisible(FALSE); } +// IDEVO HACK +extern void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel); + +void LLPanelMyProfileEdit::callbackSetName(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 = response["display_name"].asString(); + LLAvatarNameCache::setDisplayName(agent_id, display_name); + + // HACK: Use chat to invalidate names + send_chat_from_viewer("refreshname", CHAT_TYPE_NORMAL, 0); + + getChild<LLUICtrl>("user_name")->setValue( display_name ); + } +} + +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::callbackSetName, 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 1325192bbf..ed630133ca 100644 --- a/indra/newview/llpanelme.h +++ b/indra/newview/llpanelme.h @@ -34,7 +34,7 @@ #define LL_LLPANELMEPROFILE_H #include "llpanel.h" -#include "llpanelavatar.h" +#include "llpanelprofile.h" class LLPanelMyProfileEdit; class LLPanelProfile; @@ -95,6 +95,8 @@ private: void initTexturePickerMouseEvents(); void onTexturePickerMouseEnter(LLUICtrl* ctrl); void onTexturePickerMouseLeave(LLUICtrl* ctrl); + void onClickSetName(); + void callbackSetName(const LLSD& notification, const LLSD& response); /** * 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 01b6e8ffad..78a0a5cfac 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 2ff2597f08..6b45cd82fd 100644 --- a/indra/newview/llpanelpicks.cpp +++ b/indra/newview/llpanelpicks.cpp @@ -265,9 +265,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]; @@ -853,13 +853,13 @@ void LLPanelPicks::onPanelClassifiedClose(LLPanelClassifiedInfo* panel) llassert(c_item); if (c_item) { - c_item->setClassifiedName(panel->getClassifiedName()); - c_item->setDescription(panel->getDescription()); - c_item->setSnapshotId(panel->getSnapshotId()); - } + c_item->setClassifiedName(panel->getClassifiedName()); + c_item->setDescription(panel->getDescription()); + c_item->setSnapshotId(panel->getSnapshotId()); } } } + } onPanelPickClose(panel); updateButtons(); 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 9e5f9da0ea..5fe24b15f6 100644 --- a/indra/newview/llpanelplaceprofile.cpp +++ b/indra/newview/llpanelplaceprofile.cpp @@ -51,6 +51,7 @@ #include "llappviewer.h" #include "llcallbacklist.h" #include "llfloaterbuycurrency.h" +#include "llslurl.h" // IDEVO #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::buildCommand("agent", parcel->getOwnerID(), "inspect"); + 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..5688c6960b 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" @@ -107,8 +108,8 @@ void LLPanelProfileView::onOpen(const LLSD& key) } // Update the avatar name. - gCacheName->get(getAvatarId(), FALSE, - boost::bind(&LLPanelProfileView::onAvatarNameCached, this, _1, _2, _3, _4)); + gCacheName->get(getAvatarId(), false, + boost::bind(&LLPanelProfileView::onNameCache, this, _1, _2, _3)); updateOnlineStatus(); @@ -198,10 +199,22 @@ 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::onNameCache(const LLUUID& id, const std::string& full_name, bool is_group) { llassert(getAvatarId() == id); - getChild<LLUICtrl>("user_name", FALSE)->setValue(first_name + " " + last_name); + // IDEVO + LLAvatarName av_name; + if (LLAvatarNameCache::useDisplayNames() + && LLAvatarNameCache::get(id, &av_name)) + { + getChild<LLUICtrl>("user_name")->setValue( av_name.mDisplayName ); + getChild<LLUICtrl>("user_slid")->setValue( av_name.mSLID ); + } + else + { + getChild<LLUICtrl>("user_name")->setValue(full_name); + getChild<LLUICtrl>("user_slid")->setValue(""); + } } // EOF diff --git a/indra/newview/llpanelprofileview.h b/indra/newview/llpanelprofileview.h index 9b87e146a8..2b67be12e5 100644 --- a/indra/newview/llpanelprofileview.h +++ b/indra/newview/llpanelprofileview.h @@ -99,11 +99,10 @@ 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( + void onNameCache( const LLUUID& id, - const std::string& first_name, - const std::string& last_name, - BOOL is_group); + const std::string& full_name, + bool is_group); 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 717a8bda1e..4e121021fc 100644 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -75,12 +75,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 b924fb2f2c..8c9e85dd14 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 025dd6029a..cdbd9d8eb3 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" @@ -263,11 +264,11 @@ 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); + LLNameListCtrl::refreshAll(id, full_name, 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. @@ -1275,16 +1276,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 @@ -2767,6 +2759,30 @@ void LLStartUp::fontInit() LLFontGL::loadDefaultFonts(); } +void LLStartUp::initNameCache() +{ + // Can be called multiple times + if ( gCacheName ) return; + + gCacheName = new LLCacheName(gMessageSystem); + gCacheName->addObserver(&callback_cache_name); + gCacheName->localizeCacheName("waiting", LLTrans::getString("AvatarNameWaiting")); + gCacheName->localizeCacheName("nobody", LLTrans::getString("AvatarNameNobody")); + gCacheName->localizeCacheName("none", LLTrans::getString("GroupNameNone")); + // Load stored cache if possible + LLAppViewer::instance()->loadNameCache(); + + LLAvatarNameCache::initClass(); +} + +void LLStartUp::cleanupNameCache() +{ + LLAvatarNameCache::cleanupClass(); + + delete gCacheName; + gCacheName = NULL; +} + bool LLStartUp::dispatchURL() { // ok, if we've gotten this far and have a startup URL diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h index 92fe9521d3..14a7c71544 100644 --- a/indra/newview/llstartup.h +++ b/indra/newview/llstartup.h @@ -95,6 +95,10 @@ public: // Load default fonts not already loaded at start screen static void fontInit(); + static void initNameCache(); + + static void cleanupNameCache(); + // outfit_folder_name can be a folder anywhere in your inventory, // but the name must be a case-sensitive exact match. // gender_name is either "male" or "female" diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index fb78b6a415..e345784f71 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -39,6 +39,7 @@ #include "llparcel.h" #include "llagent.h" +#include "llavatarnamecache.h" #include "llviewercontrol.h" #include "llfocusmgr.h" //#include "llfirstuse.h" @@ -854,23 +855,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.mSLID + ")"; } 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 407cc23d0d..280763be57 100644 --- a/indra/newview/lltracker.cpp +++ b/indra/newview/lltracker.cpp @@ -568,16 +568,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 6c1c1d1096..9682dc7af8 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/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 80336e5c5a..4d6756c573 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -1583,9 +1583,9 @@ bool LLViewerInventoryItem::checkPermissionsSet(PermissionMask mask) 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 3d3f80b9b5..f86f8f1f5b 100644 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -161,7 +161,7 @@ public: bool checkPermissionsSet(PermissionMask mask) 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 bc3b8ac9d6..cb6844f9df 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" @@ -2767,9 +2768,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; @@ -3115,58 +3115,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) { @@ -3584,21 +3532,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 { @@ -5352,14 +5296,14 @@ void handle_look_at_selection(const LLSD& param) distance = llmin(distance, (F32) orig_distance.length()); gAgent.setCameraPosAndFocusGlobal(LLSelectMgr::getInstance()->getSelectionCenterGlobal() + LLVector3d(obj_to_cam * distance), - LLSelectMgr::getInstance()->getSelectionCenterGlobal(), - object_id ); + LLSelectMgr::getInstance()->getSelectionCenterGlobal(), + object_id ); } else { gAgent.setFocusGlobal( LLSelectMgr::getInstance()->getSelectionCenterGlobal(), object_id ); - } + } } } @@ -7804,6 +7748,11 @@ 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"); + + // IDEVO + commit.add("IDEVO.ToggleDisplayNames", boost::bind(&LLAvatarNameCache::toggleDisplayNames)); + enable.add("IDEVO.CheckDisplayNames", boost::bind(&LLAvatarNameCache::useDisplayNames)); + // Advanced > HUD Info view_listener_t::addMenu(new LLAdvancedToggleHUDInfo(), "Advanced.ToggleHUDInfo"); view_listener_t::addMenu(new LLAdvancedCheckHUDInfo(), "Advanced.CheckHUDInfo"); @@ -7982,7 +7931,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 361f4e2326..6a8832b64d 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -33,9 +33,11 @@ #include "llviewerprecompiledheaders.h" #include "llviewermessage.h" +// 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" @@ -82,6 +84,7 @@ #include "llspeakers.h" #include "lltrans.h" #include "llviewerfoldertype.h" +#include "llvoavatar.h" // IDEVO HACK #include "lluri.h" #include "llviewergenericmessage.h" #include "llviewermenu.h" @@ -105,6 +108,7 @@ #include "llpanelplaceprofile.h" #include <boost/algorithm/string/split.hpp> // +#include <boost/regex.hpp> #if LL_WINDOWS // For Windows specific error handler #include "llwindebug.h" // For the invalid message handler @@ -933,7 +937,7 @@ void open_inventory_offer(const std::vector<LLUUID>& items, const std::string& f // TODO* LLPanelPlaces dependency is going to be removed. See EXT-4347. //if("create_landmark" == places_panel->getPlaceInfoType() && !places_panel->getItem()) //{ - // places_panel->setItem(item); + //places_panel->setItem(item); //} //else // we are opening a group notice attachment @@ -1013,27 +1017,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 @@ -1051,7 +1052,6 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id, bool matches(const LLNotificationPtr notification) const { if(notification->getName() == "ObjectGiveItem" - || notification->getName() == "ObjectGiveItemUnknownUser" || notification->getName() == "UserGiveItem") { return (notification->getPayload()["from_id"].asUUID() == blocked_id); @@ -1159,7 +1159,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. @@ -1296,7 +1296,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; @@ -1344,12 +1344,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 { @@ -1513,30 +1513,6 @@ void inventory_offer_handler(LLOfferInfo* info) return; } - // Name cache callbacks don't store userdata, so can't save - // off the LLOfferInfo. Argh. - BOOL name_found = FALSE; - if (info->mFromGroup) - { - std::string group_name; - if (gCacheName->getGroupName(info->mFromID, group_name)) - { - args["FIRST"] = group_name; - args["LAST"] = ""; - name_found = TRUE; - } - } - else - { - std::string first_name, last_name; - if (gCacheName->getName(info->mFromID, first_name, last_name)) - { - args["FIRST"] = first_name; - args["LAST"] = last_name; - name_found = TRUE; - } - } - // If mObjectID is null then generate the object_id based on msg to prevent // multiple creation of chiclets for same object. LLUUID object_id = info->mObjectID; @@ -1551,7 +1527,14 @@ void inventory_offer_handler(LLOfferInfo* info) payload["give_inventory_notification"] = FALSE; args["OBJECTFROMNAME"] = info->mFromName; args["NAME"] = info->mFromName; - args["NAME_SLURL"] = LLSLURL::buildCommand("agent", info->mFromID, "about"); + if (info->mFromGroup) + { + args["NAME_SLURL"] = LLSLURL::buildCommand("group", info->mFromID, "about"); + } + else + { + args["NAME_SLURL"] = LLSLURL::buildCommand("agent", info->mFromID, "about"); + } std::string verb = "select?name=" + LLURI::escape(msg); args["ITEM_SLURL"] = LLSLURL::buildCommand("inventory", info->mObjectID, verb.c_str()); @@ -1564,7 +1547,7 @@ void inventory_offer_handler(LLOfferInfo* info) args["ITEM_SLURL"] = msg; // Note: sets inventory_task_offer_callback as the callback p.substitutions(args).payload(payload).functor.function(boost::bind(&LLOfferInfo::inventory_task_offer_callback, info, _1, _2)); - p.name = name_found ? "ObjectGiveItem" : "ObjectGiveItemUnknownUser"; + p.name = "ObjectGiveItem"; // Pop up inv offer chiclet and let the user accept (keep), or reject (and silently delete) the inventory. LLNotifications::instance().add(p); } @@ -1659,6 +1642,75 @@ bool inspect_remote_object_callback(const LLSD& notification, const LLSD& respon } static LLNotificationFunctorRegistration inspect_remote_object_callback_reg("ServerObjectMessage", inspect_remote_object_callback); +// 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) @@ -1706,6 +1758,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); @@ -2015,6 +2069,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; @@ -2200,6 +2263,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) chat.mFromID = from_id = LLUUID::null; } + // 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; @@ -2491,9 +2557,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()); } } @@ -2526,7 +2591,6 @@ void process_decline_callingcard(LLMessageSystem* msg, void**) LLNotificationsUtil::add("CallingCardDeclined"); } - void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) { LLChat chat; @@ -2542,7 +2606,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; @@ -2561,6 +2624,16 @@ 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) + { + chat.mFromName = LLCacheName::cleanFullName(from_name); + } + else + { + chat.mFromName = from_name; + } + BOOL is_busy = gAgent.getBusy(); BOOL is_muted = FALSE; @@ -2624,6 +2697,20 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) } chat.mText = mesg; + // IDEVO HACK Use chat to invalidate names + if (chat.mSourceType == CHAT_SOURCE_AGENT + && chat.mText == "refreshname") + { + LLAvatarNameCache::erase(chat.mFromID); + + // force name tag to update + LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(chatter); + if (avatar) + { + avatar->clearNameTag(); + } + } + // Look for the start of typing so we can put "..." in the bubbles. if (CHAT_TYPE_START == chat.mChatType) { @@ -4410,6 +4497,67 @@ void process_time_dilation(LLMessageSystem *msg, void **user_data) */ +static void show_money_balance_notification(const std::string& desc) +{ + // Intercept some messages constructed in lltransactionflags.cpp + // to fix avatar names and allow localization. + LLSD args; + LLSD payload; + std::string name; + boost::smatch match; + const char* notification_name = NULL; + + // <name> paid you L$<amount> for <reason>. + static const boost::regex paid_you_for("(.+) paid you L\\$(\\d+) for (.*)\\."); + // <name> paid you L$<amount>. + static const boost::regex paid_you("(.+) paid you L\\$(\\d+)\\."); + // You paid <name> L$<amount> [for <reason>]. + static const boost::regex you_paid("You paid (.*) L\\$(\\d+)(.*)\\."); + + if (boost::regex_match(desc, match, paid_you_for)) + { + name = match[1].str(); + // IDEVO strip legacy "Resident" name + name = LLCacheName::cleanFullName(name); + args["NAME"] = name; + args["AMOUNT"] = match[2].str(); + args["REASON"] = match[3].str(); + notification_name = "PaymentReceivedFor"; + } + else if (boost::regex_match(desc, match, paid_you)) + { + name = match[1].str(); + // IDEVO strip legacy "Resident" name + name = LLCacheName::cleanFullName(name); + args["NAME"] = name; + args["AMOUNT"] = match[2].str(); + notification_name = "PaymentReceived"; + } + else if (boost::regex_match(desc, match, you_paid)) + { + name = match[1].str(); + // IDEVO strip legacy "Resident" name + name = LLCacheName::cleanFullName(name); + args["NAME"] = name; + args["AMOUNT"] = match[2].str(); + args["REASON"] = match[3].str(); + notification_name = "PaymentSent"; + } + + // if name extracted and name cache contains avatar id send loggable notification + LLUUID from_id; + if (notification_name != NULL + && gCacheName->getUUID(name, from_id)) + { + payload["from_id"] = from_id; + LLNotificationsUtil::add(notification_name, args, payload); + } + else + { + args["MESSAGE"] = desc; + LLNotificationsUtil::add("SystemMessage", args); + } +} void process_money_balance_reply( LLMessageSystem* msg, void** ) { @@ -4454,33 +4602,7 @@ void process_money_balance_reply( LLMessageSystem* msg, void** ) if(!desc.empty() && gSavedSettings.getBOOL("NotifyMoneyChange") && (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; - args["MESSAGE"] = desc; - - // this is a marker to retrieve avatar name from server message: - // "<avatar name> paid you L$" - const std::string marker = "paid you L$"; - - // extract avatar name from system message - std::string name = desc.substr(0, desc.find(marker, 0)); - LLStringUtil::trim(name); - - // if name extracted and name cache contains avatar id send loggable notification - LLUUID from_id; - if(name.size() > 0 && gCacheName->getUUID(name, from_id)) - { - args["NAME"] = name; - LLSD payload; - payload["from_id"] = from_id; - LLNotificationsUtil::add("PaymentRecived", args, payload); - } - else - { - LLNotificationsUtil::add("SystemMessage", args); - } + show_money_balance_notification(desc); // Once the 'recent' container gets large enough, chop some // off the beginning. @@ -4733,7 +4855,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) { @@ -4755,8 +4877,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; } } } @@ -4810,8 +4931,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)); } } } @@ -5033,7 +5153,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(); @@ -5069,7 +5189,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++) @@ -5676,8 +5796,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())); } @@ -5710,7 +5829,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(); ) @@ -5723,11 +5842,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. @@ -5787,7 +5906,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 b5642d07a5..daa48e7054 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -67,6 +67,7 @@ #include "llface.h" #include "llfloaterproperties.h" #include "llfollowcam.h" +#include "llhudtext.h" #include "llselectmgr.h" #include "llrendersphere.h" #include "lltooldraganddrop.h" @@ -1071,7 +1072,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()) { @@ -1463,7 +1464,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); } @@ -4122,7 +4123,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 266c40d493..9f2eb10065 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/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 1f6bbcbae8..7eeb6c7ad0 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/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index d0a1a31ebd..ea1afafe85 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1202,12 +1202,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)); @@ -1744,7 +1740,7 @@ void LLViewerWindow::shutdownViews() // destroy the nav bar, not currently part of gViewerWindow // *TODO: Make LLNavigationBar part of gViewerWindow delete LLNavigationBar::getInstance(); - + // destroy menus after instantiating navbar above, as it needs // access to gMenuHolder cleanup_menus(); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 72b9c6df98..f7df0dc2cf 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -44,14 +44,17 @@ #include <ctype.h> #include "llaudioengine.h" +#include "llcachename.h" #include "noise.h" #include "sound_ids.h" #include "llagent.h" // Get state values from here #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" @@ -60,6 +63,7 @@ #include "llheadrotmotion.h" #include "llhudeffecttrail.h" #include "llhudmanager.h" +#include "llhudtext.h" #include "llkeyframefallmotion.h" #include "llkeyframestandmotion.h" #include "llkeyframewalkmotion.h" @@ -650,11 +654,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), + mUseDisplayNames( LLAvatarNameCache::useDisplayNames() ), mFirstTEMessageReceived( FALSE ), mFirstAppearanceMessageReceived( FALSE ), mCulled( FALSE ), @@ -2676,289 +2683,381 @@ 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; + } + + // IDEVO HACK to force refresh + if (LLAvatarNameCache::useDisplayNames() != mUseDisplayNames) + { + mUseDisplayNames = LLAvatarNameCache::useDisplayNames(); + 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 { - mRenderGroupTitles = sRenderGroupTitles; - new_name = TRUE; + // ...not fading, full alpha + alpha = 1.f; } + } + else if (mAppAngle > 2.f) + { + // far away is faded out also + alpha = (mAppAngle-2.f)/3.f; + } - // First Calculate Alpha - // If alpha > 0, create mNameText if necessary, otherwise delete it + if (alpha <= 0.f) + { + if (mNameText) { - F32 alpha = 0.f; - if (mAppAngle > 5.f) + mNameText->markDead(); + mNameText = NULL; + sNumVisibleChatBubbles--; + } + return; + } + + 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; + } + + 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"); + + // 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()); + + // 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) + { + LLColor4 name_tag_color = getNameTagColor(is_friend); + + clearNameTag(); + + if (sRenderGroupTitles + && title && title->getString() && title->getString()[0] != '\0') + { + std::string title_str = title->getString(); + LLStringFn::replace_ascii_controlchars(title_str,LL_UNKNOWN_CHAR); + addNameTagLine(title_str, name_tag_color, LLFontGL::NORMAL, + LLFontGL::getFontSansSerifSmall()); + } + + static LLUICachedControl<bool> show_display_names("NameTagShowDisplayNames"); + static LLUICachedControl<bool> show_slids("NameTagShowSLIDs"); + + if (LLAvatarNameCache::useDisplayNames()) + { + LLAvatarName av_name; + if (!LLAvatarNameCache::get(getID(), &av_name)) { - 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; - } + // ...call this function back when the name arrives + // and force a rebuild + LLAvatarNameCache::get(getID(), + boost::bind(&LLVOAvatar::clearNameTag, this)); } - else if (mAppAngle > 2.f) + + // Might be blank if name not available yet, that's OK + if (show_display_names) { - // far away is faded out also - alpha = (mAppAngle-2.f)/3.f; + addNameTagLine(av_name.mDisplayName, name_tag_color, LLFontGL::NORMAL, + LLFontGL::getFontSansSerifBig()); } - - if (alpha > 0.f) + if (show_slids) + { + addNameTagLine(av_name.mSLID, name_tag_color, LLFontGL::NORMAL, + LLFontGL::getFontSansSerif()); + } + } + else + { + if (show_display_names || show_slids) { - 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); + static LLUICachedControl<bool> small_avatar_names("SmallAvatarNames"); + const LLFontGL* font = + (small_avatar_names ? LLFontGL::getFontSansSerif() : LLFontGL::getFontSansSerifBig() ); + std::string full_name = + LLCacheName::buildFullName( firstname->getString(), lastname->getString() ); + addNameTagLine(full_name, name_tag_color, LLFontGL::NORMAL, font); + } + } - 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); + static LLUICachedControl<bool> show_status("NameTagShowStatus"); + if (show_status + && (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 += ", "; + } + // trim last ", " + line.resize( line.length() - 2 ); + addNameTagLine(line, name_tag_color, LLFontGL::NORMAL, + LLFontGL::getFontSansSerifSmall()); } - - LLNameValue *title = getNVPair("Title"); - LLNameValue* firstname = getNVPair("FirstName"); - LLNameValue* lastname = getNVPair("LastName"); + mNameAway = is_away; + mNameBusy = is_busy; + mNameMute = is_muted; + mNameAppearance = is_appearance; + mNameFriend = is_friend; + mTitle = title ? title->getString() : ""; + LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR); + new_name = TRUE; + } + + if (mVisibleChat) + { + mNameText->setDropShadow(TRUE); + mNameText->setFont(LLFontGL::getFontSansSerif()); + mNameText->setTextAlignment(LLHUDText::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(); - if (mNameText.notNull() && firstname && lastname) + LLColor4 new_chat = LLUIColorTable::instance().getColor( "AvatarNameColor" ); + 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) { - 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()) + ++chat_iter; + } + + for(; chat_iter != mChats.end(); ++chat_iter) + { + F32 chat_fade_amt = llclamp((F32)((LLFrameTimer::getElapsedSeconds() - chat_iter->mTime) / CHAT_FADE_TIME), 0.f, 4.f); + LLFontGL::StyleFlags style; + switch(chat_iter->mChatType) { - is_muted = FALSE; + case CHAT_TYPE_WHISPER: + style = LLFontGL::ITALIC; + break; + case CHAT_TYPE_SHOUT: + style = LLFontGL::BOLD; + break; + default: + style = LLFontGL::NORMAL; + break; } - else + if (chat_fade_amt < 1.f) { - is_muted = LLMuteList::getInstance()->isMuted(getID()); + F32 u = clamp_rescale(chat_fade_amt, 0.9f, 1.f, 0.f, 1.f); + 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(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(chat_iter->mText, old_chat, style); + } + } + mNameText->setVisibleOffScreen(TRUE); - if (mNameString.empty() || - new_name || - (!title && !mTitle.empty()) || - (title && mTitle != title->getString()) || - (is_away != mNameAway || is_busy != mNameBusy || is_muted != mNameMute) - || is_appearance != mNameAppearance) + if (mTyping) + { + S32 dot_count = (llfloor(mTypingTimer.getElapsedTimeF32() * 3.f) + 2) % 3 + 1; + switch(dot_count) { - 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(); - } + case 1: + mNameText->addLine(".", new_chat); + break; + case 2: + mNameText->addLine("..", new_chat); + break; + case 3: + mNameText->addLine("...", new_chat); + break; + } - line += " "; - line += lastname->getString(); - BOOL need_comma = FALSE; + } + } + else + { + // ...not using chat bubbles, just names + mNameText->setTextAlignment(LLHUDText::ALIGN_TEXT_CENTER); + mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); + mNameText->setVisibleOffScreen(FALSE); + } +} - 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_appearance) - { - line += "\n"; - line += LLTrans::getString("AvatarEditingAppearance"); - } - mNameAway = is_away; - mNameBusy = is_busy; - mNameMute = is_muted; - mNameAppearance = is_appearance; - 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); - } - - 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 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) - { - ++chat_iter; - } +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'; +} - for(; chat_iter != mChats.end(); ++chat_iter) - { - F32 chat_fade_amt = llclamp((F32)((LLFrameTimer::getElapsedSeconds() - chat_iter->mTime) / CHAT_FADE_TIME), 0.f, 4.f); - LLFontGL::StyleFlags style; - switch(chat_iter->mChatType) - { - case CHAT_TYPE_WHISPER: - style = LLFontGL::ITALIC; - break; - case CHAT_TYPE_SHOUT: - style = LLFontGL::BOLD; - break; - default: - style = LLFontGL::NORMAL; - break; - } - 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); - } - 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); - } - 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->setVisibleOffScreen(TRUE); +void LLVOAvatar::clearNameTag() +{ + mNameString.clear(); + if (mNameText) + { + mNameText->setLabel( "" ); + mNameText->setString( "" ); + } +} - if (mTyping) - { - S32 dot_count = (llfloor(mTypingTimer.getElapsedTimeF32() * 3.f) + 2) % 3 + 1; - switch(dot_count) - { - case 1: - mNameText->addLine(".", new_chat); - break; - case 2: - mNameText->addLine("..", new_chat); - break; - case 3: - mNameText->addLine("...", new_chat); - break; - } +// 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; - } - } - else - { - if (gSavedSettings.getBOOL("SmallAvatarNames")) - { - mNameText->setFont(LLFontGL::getFontSansSerif()); - } - else - { - mNameText->setFont(LLFontGL::getFontSansSerifBig()); - } - mNameText->setTextAlignment(LLHUDText::ALIGN_TEXT_CENTER); - mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); - mNameText->setVisibleOffScreen(FALSE); - if (new_name) - { - mNameText->setLabel(""); - mNameText->setString(mNameString); - } - } - } + 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; } - else if (mNameText) +} + +LLColor4 LLVOAvatar::getNameTagColor(bool is_friend) +{ + const char* color_name = "AvatarNameColor"; + if (is_friend) { - mNameText->markDead(); - mNameText = NULL; - sNumVisibleChatBubbles--; + color_name = "AvatarNameFriendColor"; + } + else + { + // IDEVO can we avoid doing this lookup repeatedly? + LLAvatarName av_name; + if (LLAvatarNameCache::useDisplayNames() + && LLAvatarNameCache::get(getID(), &av_name) + && av_name.mIsLegacy) + { + color_name = "AvatarNameLegacyColor"; + } } + return LLUIColorTable::getInstance()->getColor( color_name ); } //-------------------------------------------------------------------- @@ -7534,9 +7633,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 b5f0ec7176..b63e3b2ebd 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -210,6 +210,12 @@ 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(); + void addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font); void idleUpdateRenderCost(); void idleUpdateTractorBeam(); void idleUpdateBelowWater(); @@ -820,13 +826,16 @@ 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 mNameAway; + bool mNameBusy; + bool mNameMute; + bool mNameAppearance; + bool mNameFriend; + F32 mNameAlpha; BOOL mRenderGroupTitles; + bool mUseDisplayNames; // IDEVO HACK to force refresh //-------------------------------------------------------------------- // Display the name (then optionally fade it out) diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 5ba13efca2..223ebc0081 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -7119,18 +7119,8 @@ void LLVoiceClient::notifyFriendObservers() void LLVoiceClient::lookupName(const LLUUID &id) { - BOOL is_group = FALSE; - gCacheName->get(id, is_group, &LLVoiceClient::onAvatarNameLookup); -} - -//static -void LLVoiceClient::onAvatarNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group) -{ - if(gVoiceClient) - { - std::string name = llformat("%s %s", first.c_str(), last.c_str()); - gVoiceClient->avatarNameResolved(id, name); - } + gCacheName->get(id, false, + boost::bind(&LLVoiceClient::avatarNameResolved, this, _1, _2)); } void LLVoiceClient::avatarNameResolved(const LLUUID &id, const std::string &name) diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index aaacab69e0..c164391d7c 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -477,7 +477,6 @@ static void updatePosition(void); void removeObserver(LLFriendObserver* observer); void lookupName(const LLUUID &id); - static void onAvatarNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group); void avatarNameResolved(const LLUUID &id, const std::string &name); typedef std::vector<std::string> deviceList; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 259ca21e93..4de1560f16 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -69,6 +69,7 @@ #include "llfloaterreg.h" #include "llgldbg.h" #include "llhudmanager.h" +#include "llhudtext.h" #include "lllightconstants.h" #include "llresmgr.h" #include "llselectmgr.h" diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index d45d6155dd..4580efe688 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -118,6 +118,12 @@ name="AvatarNameColor" reference="White" /> <color + name="AvatarNameFriendColor" + reference="Green" /> + <color + name="AvatarNameLegacyColor" + reference="Yellow" /> + <color name="AvatarListItemIconDefaultColor" reference="White" /> <color diff --git a/indra/newview/skins/default/textures/icons/Person_Check.png b/indra/newview/skins/default/textures/icons/Person_Check.png Binary files differnew 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.png Binary files differnew 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 b1594816b2..3b08408661 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -410,6 +410,8 @@ with the same filename but different name <texture name="Pause_Off" file_name="icons/Pause_Off.png" preload="false" /> <texture name="Pause_Over" file_name="icons/Pause_Over.png" preload="false" /> <texture name="Pause_Press" file_name="icons/Pause_Press.png" preload="false" /> + <texture name="Person_Check" file_name="icons/Person_Check.png" preload="false" /> + <texture name="Person_Star" file_name="icons/Person_Star.png" preload="false" /> <texture name="Play_Off" file_name="icons/Play_Off.png" preload="false" /> <texture name="Play_Over" file_name="icons/Play_Over.png" preload="false" /> <texture name="Play_Press" file_name="icons/Play_Press.png" preload="false" /> 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..59923bec96 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,32 @@ 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" /> + <columns + label="Profile" + name="profile" + width="100" /> + </scroll_list> </panel> <panel border="none" @@ -207,16 +225,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_pay.xml b/indra/newview/skins/default/xui/en/floater_pay.xml index 509cffe490..8f60dd6f28 100644 --- a/indra/newview/skins/default/xui/en/floater_pay.xml +++ b/indra/newview/skins/default/xui/en/floater_pay.xml @@ -28,16 +28,6 @@ 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 +35,11 @@ font="SansSerifSmall" height="16" layout="topleft" - left_pad="7" + left="10" name="payee_name" - width="210"> - [FIRST] [LAST] + top_pad="0" + 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/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/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml index ba74104594..3570237e92 100644 --- a/indra/newview/skins/default/xui/en/menu_login.xml +++ b/indra/newview/skins/default/xui/en/menu_login.xml @@ -12,6 +12,15 @@ label="Me" tear_off="true" name="File"> + <menu_item_check + label="IDEVO Display Name Prototype" + name="display_name_prototype"> + <menu_item_check.on_check + function="IDEVO.CheckDisplayNames" /> + <menu_item_check.on_click + function="IDEVO.ToggleDisplayNames" /> + </menu_item_check> + <menu_item_separator /> <menu_item_call label="Preferences" name="Preferences..." diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 158e764eae..806c28d141 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -9,6 +9,15 @@ layout="topleft" name="Me" tear_off="true"> + <menu_item_check + label="IDEVO Display Name Prototype" + name="display_name_prototype"> + <menu_item_check.on_check + function="IDEVO.CheckDisplayNames" /> + <menu_item_check.on_click + function="IDEVO.ToggleDisplayNames" /> + </menu_item_check> + <menu_item_separator /> <menu_item_call label="Preferences" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index a2540237c8..7f0a3ff360 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" @@ -392,9 +392,9 @@ Add this Ability to '[ROLE_NAME]'? yestext="Yes"/> </notification> <notification - icon="alertmodal.tga" + icon="alertmodal.tga" name="JoinGroupCanAfford" - type="alertmodal"> + type="alertmodal"> Joining this group costs L$[COST]. Do you wish to proceed? <usetemplate @@ -614,7 +614,7 @@ To place the media on only one face, choose Select Face and click on the desired notext="Cancel" yestext="OK"/> </notification> - + <notification icon="alertmodal.tga" name="MustBeInParcel" @@ -785,7 +785,7 @@ Save changes to classified [NAME]? notext="Don't Save" yestext="Save"/> </notification> - + <notification icon="alertmodal.tga" name="ClassifiedInsufficientFunds" @@ -836,7 +836,7 @@ Please select a proposal to view. Please select a history item to view. </notification> -<!-- +<!-- <notification icon="alertmodal.tga" name="ResetShowNextTimeDialogs" @@ -2027,7 +2027,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" @@ -2267,7 +2267,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]'? @@ -3034,6 +3034,27 @@ 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="OfferTeleport" type="alertmodal"> Offer a teleport to your location with the following message? @@ -4471,13 +4492,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. @@ -4630,9 +4644,23 @@ Please select at least one type of content to search (General, Moderate, or Adul <notification icon="notify.tga" - name="PaymentRecived" + name="PaymentReceived" type="notify"> -[MESSAGE] +[NAME] paid you L$[AMOUNT]. + </notification> + + <notification + icon="notify.tga" + name="PaymentReceivedFor" + type="notify"> +[NAME] paid you L$[AMOUNT] for [REASON]. + </notification> + + <notification + icon="notify.tga" + name="PaymentSent" + type="notify"> +You paid [NAME] L$[AMOUNT][REASON]. </notification> <notification @@ -4719,7 +4747,7 @@ The objects you own on the selected parcel of land have been returned back to yo icon="notify.tga" name="OtherObjectsReturned" 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 @@ -5027,28 +5055,6 @@ An object named [OBJECTFROMNAME] owned by [NAME_SLURL] has given you this [OBJEC <notification icon="notify.tga" - name="ObjectGiveItemUnknownUser" - type="offer"> -An object named [OBJECTFROMNAME] owned by (an unknown Resident) has given you this [OBJECTTYPE]: -[ITEM_SLURL] - <form name="form"> - <button - index="0" - name="Keep" - text="Keep"/> - <button - index="1" - name="Discard" - text="Discard"/> - <button - index="2" - name="Mute" - text="Block"/> - </form> - </notification> - - <notification - icon="notify.tga" name="UserGiveItem" type="offer"> [NAME_SLURL] has given you this [OBJECTTYPE]: @@ -5164,7 +5170,7 @@ An object named [OBJECTFROMNAME] owned by (an unknown Resident) has given you th text="Decline"/> </form> </notification> - + <notification icon="notify.tga" name="FriendshipOffered" @@ -5355,7 +5361,7 @@ Grant this request? icon="notify.tga" name="ScriptDialog" type="notify"> -[FIRST] [LAST]'s '[TITLE]' +[NAME]'s '[TITLE]' [MESSAGE] <form name="form"> <button @@ -5428,8 +5434,8 @@ Your L$ balance will be updated when processing completes. If processing takes m The status of your payment can be checked on your Transaction History page on your [http://secondlife.com/account/ Dashboard] </notification> - -<!-- + +<!-- <notification icon="notify.tga" name="FirstSit" @@ -5456,7 +5462,7 @@ You have opened the Build Tools. Every object you see around you was created usi </notification> --> -<!-- +<!-- <notification icon="notify.tga" name="FirstLeftClickNoHit" @@ -5542,7 +5548,7 @@ To toggle this menu, type="notify"> You are editing a Sculpted prim. Sculpties require a special texture to define their shape. </notification> ---> +--> <!-- <notification @@ -5589,21 +5595,21 @@ Click Accept to join the call or Decline to decline the invitation. Click Block icon="notify.tga" name="AutoUnmuteByIM" 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 icon="notify.tga" name="AutoUnmuteByMoney" type="notify"> -[FIRST] [LAST] was given money and has been automatically unblocked. +[NAME] was given money and has been automatically unblocked. </notification> <notification icon="notify.tga" name="AutoUnmuteByInventory" type="notify"> -[FIRST] [LAST] was offered inventory and has been automatically unblocked. +[NAME] was offered inventory and has been automatically unblocked. </notification> <notification @@ -5831,7 +5837,7 @@ A SLurl was received from an untrusted browser and has been blocked for your sec priority="high" type="notifytip"> Multiple SLurls were received from an untrusted browser within a short period. -They will be blocked for a few seconds for your security. +They will be blocked for a few seconds for your security. </notification> <notification name="IMToast" type="notifytoast"> 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 26be8440e7..1b624da68a 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,42 @@ 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" + visible="false" + 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,7 +175,7 @@ height="102" layout="topleft" left="123" - top="25" + top="62" max_length="512" name="sl_description_edit" width="157" @@ -201,7 +231,7 @@ layout="topleft" left="123" max_length="512" - top="157" + top="195" name="fl_description_edit" width="157" word_wrap="true"> diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml index 627e616af5..bf839f13e5 100644 --- a/indra/newview/skins/default/xui/en/panel_login.xml +++ b/indra/newview/skins/default/xui/en/panel_login.xml @@ -60,7 +60,7 @@ name="first_name_text" top="20" left="20" width="150"> -First name: + Username or First Last: </text> <line_editor follows="left|bottom" @@ -69,20 +69,23 @@ height="22" label="First" left_delta="0" max_length="31" -name="first_name_edit" +name="login_id_edit" +prevalidate_callback="ascii" select_on_focus="true" -tool_tip="[SECOND_LIFE] First Name" +tool_tip="[SECOND_LIFE] ID" top_pad="0" - width="135" /> + width="200" /> <text follows="left|bottom" font="SansSerifSmall" height="16" - left_pad="8" + left="230" name="last_name_text" top="20" + visible="false" width="150"> - Last name: </text> + Last name: + </text> <line_editor follows="left|bottom" handle_edit_keys_directly="true" @@ -93,12 +96,13 @@ name="last_name_edit" select_on_focus="true" tool_tip="[SECOND_LIFE] Last Name" top_pad="0" + visible="false" width="135" /> <text follows="left|bottom" font="SansSerifSmall" height="15" -left_pad="8" +left="230" name="password_text" top="20" width="150"> 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 d11aebe943..39a597a372 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_general.xml @@ -222,60 +222,97 @@ </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> <check_box enabled_control="AvatarNameTagMode" - control_name="RenderNameShowSelf" - height="16" - label="Show my name" - layout="topleft" - left="50" - name="show_my_name_checkbox1" - width="300" /> - <check_box - enabled_control="AvatarNameTagMode" control_name="SmallAvatarNames" height="16" initial_value="true" label="Small name tags" layout="topleft" - left_delta="175" + left="70" name="small_avatar_names_checkbox" + top_pad="4" width="200" /> - <check_box + <check_box enabled_control="AvatarNameTagMode" - control_name="RenderShowGroupTitleAll" + control_name="RenderNameShowSelf" height="16" - label="Show group titles" + label="Show my name" layout="topleft" - left_delta="-175" - name="show_all_title_checkbox1" - top_pad="5" + left="70" + name="show_my_name_checkbox1" + top_pad="4" width="300" /> + <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" + height="16" + label="Group titles" + left="265" + name="show_all_title_checkbox1" + 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="NameTagShowSLIDs" + enabled_control="AvatarNameTagMode" + height="16" + label="Second Life IDs" + left_delta="0" + name="show_slids" + tool_tip="Show SL ID, like bobsmith123" + top_pad="5" /> + <check_box + control_name="NameTagShowStatus" + enabled_control="AvatarNameTagMode" + height="16" + label="Status" + left_delta="0" + name="show_status" + tool_tip="Show status, like AFK or Busy" + top_pad="5" /> <text type="string" length="1" @@ -284,7 +321,7 @@ layout="topleft" left="30" name="effects_color_textbox" - top_pad="15" + top="290" width="200"> My effects: </text> @@ -366,7 +403,7 @@ hover="false" commit_on_focus_lost = "true" follows="left|top" - height="60" + height="45" layout="topleft" left="50" name="busy_response" 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/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 59c54f0cad..543f047ce5 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2934,7 +2934,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. diff --git a/indra/newview/tests/lldateutil_test.cpp b/indra/newview/tests/lldateutil_test.cpp index 7ba82fbd2c..e19983db8f 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" ); + } } |