From 40907986d4044e2be75f862fac1153f9a14f13ad Mon Sep 17 00:00:00 2001 From: James Cook Date: Fri, 22 Jan 2010 18:29:29 -0800 Subject: Pull llurlentryagent into newview so I can compile/link faster --- indra/llui/llurlregistry.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'indra/llui/llurlregistry.cpp') diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index ad5c0911f8..4fbdae9d38 100644 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -43,11 +43,13 @@ void LLUrlRegistryNullCallback(const std::string &url, const std::string &label) LLUrlRegistry::LLUrlRegistry() { + mUrlEntry.reserve(16); + // Urls are matched in the order that they were registered registerUrl(new LLUrlEntrySLURL()); registerUrl(new LLUrlEntryHTTP()); registerUrl(new LLUrlEntryHTTPLabel()); - registerUrl(new LLUrlEntryAgent()); + // IDEVO registerUrl(new LLUrlEntryAgent()); registerUrl(new LLUrlEntryGroup()); registerUrl(new LLUrlEntryParcel()); registerUrl(new LLUrlEntryTeleport()); @@ -73,11 +75,14 @@ LLUrlRegistry::~LLUrlRegistry() } } -void LLUrlRegistry::registerUrl(LLUrlEntryBase *url) +void LLUrlRegistry::registerUrl(LLUrlEntryBase *url, bool force_front) { if (url) { - mUrlEntry.push_back(url); + if (force_front) // IDEVO + mUrlEntry.insert(mUrlEntry.begin(), url); + else + mUrlEntry.push_back(url); } } -- cgit v1.3 From d489216b6ef41f0d22f3a9062ba6daacc67bc038 Mon Sep 17 00:00:00 2001 From: James Cook Date: Wed, 3 Feb 2010 12:48:40 -0800 Subject: Moved LLUrlEntryAgent back into llui library in prep for merge --- indra/llui/llurlentry.cpp | 127 +++++++++++++++++++++++++++++- indra/llui/llurlentry.h | 12 ++- indra/llui/llurlregistry.cpp | 2 +- indra/llui/tests/llurlentry_test.cpp | 36 ++++----- indra/newview/CMakeLists.txt | 2 - indra/newview/llstartup.cpp | 5 -- indra/newview/llurlentryagent.cpp | 146 ----------------------------------- indra/newview/llurlentryagent.h | 52 ------------- 8 files changed, 155 insertions(+), 227 deletions(-) delete mode 100644 indra/newview/llurlentryagent.cpp delete mode 100644 indra/newview/llurlentryagent.h (limited to 'indra/llui/llurlregistry.cpp') diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 40f8c27431..7a62ca5098 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -297,7 +297,132 @@ std::string LLUrlEntrySLURL::getLocation(const std::string &url) const return url.substr(pos, url.size() - pos); } -// LLUrlEntryAgent temporarily moved to newview IDEVO +// +// LLUrlEntryAgent Describes a Second Life agent Url, e.g., +// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about +// +LLUrlEntryAgent::LLUrlEntryAgent() +{ + mPattern = boost::regex("secondlife:///app/agent/[\\da-f-]+/\\w+", + boost::regex::perl|boost::regex::icase); + mMenuName = "menu_url_agent.xml"; + mIcon = "Generic_Person"; + mColor = LLUIColorTable::instance().getColor("AgentLinkColor"); +} + +// IDEVO demo code +static std::string clean_name(const std::string& full_name) +{ + std::string displayname; + if (full_name == "miyazaki23") // IDEVO demo code + { + // miyazaki + displayname += (char)(0xE5); + displayname += (char)(0xAE); + displayname += (char)(0xAE); + displayname += (char)(0xE5); + displayname += (char)(0xB4); + displayname += (char)(0x8E); + // hayao + displayname += (char)(0xE9); + displayname += (char)(0xA7); + displayname += (char)(0xBF); + // san + displayname += (char)(0xE3); + displayname += (char)(0x81); + displayname += (char)(0x95); + displayname += (char)(0xE3); + displayname += (char)(0x82); + displayname += (char)(0x93); + } + else if (full_name == "Jim Linden") + { + displayname = "Jos"; + displayname += (char)(0xC3); + displayname += (char)(0xA9); + displayname += " Sanchez"; + } + else if (full_name == "James Linden") + { + displayname = "James Cook"; + } + else if (full_name == "Hamilton Linden") + { + displayname = "Hamilton Hitchings"; + } + else if (full_name == "Rome Linden") + { + displayname = "Rome Portlock"; + } + else if (full_name == "M Linden") + { + displayname = "Mark Kingdon"; + } + else if (full_name == "T Linden") + { + displayname = "Tom Hale"; + } + else if (full_name == "Callen Linden") + { + displayname = "Christina Allen"; + } + + std::string final; + if (!displayname.empty()) + { + final = displayname + " (" + full_name + ")"; + } + else + { + final = full_name; + } + return final; +} + +void LLUrlEntryAgent::onNameCache(const LLUUID& id, + const std::string& full_name, + bool is_group) +{ + std::string final = clean_name(full_name); + // received the agent name from the server - tell our observers + callObservers(id.asString(), final); +} + +std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCallback &cb) +{ + if (!gCacheName) + { + // 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)) + { + return clean_name(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"); + } +} + // // LLUrlEntryGroup Describes a Second Life group Url, e.g., diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index 6d875a40c7..4fc2eb5e05 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -156,7 +156,17 @@ public: /*virtual*/ std::string getLocation(const std::string &url) const; }; -/// IDEVO LLUrlEntryAgent temporarily moved to newview +/// +/// 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); +private: + void onNameCache(const LLUUID& id, const std::string& full_name, bool is_group); +}; /// /// LLUrlEntryGroup Describes a Second Life group Url, e.g., diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index 4fbdae9d38..419d2322f9 100644 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -49,7 +49,7 @@ LLUrlRegistry::LLUrlRegistry() registerUrl(new LLUrlEntrySLURL()); registerUrl(new LLUrlEntryHTTP()); registerUrl(new LLUrlEntryHTTPLabel()); - // IDEVO registerUrl(new LLUrlEntryAgent()); + registerUrl(new LLUrlEntryAgent()); registerUrl(new LLUrlEntryGroup()); registerUrl(new LLUrlEntryParcel()); registerUrl(new LLUrlEntryTeleport()); diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp index 9200708784..30b59859d3 100644 --- a/indra/llui/tests/llurlentry_test.cpp +++ b/indra/llui/tests/llurlentry_test.cpp @@ -266,30 +266,28 @@ namespace tut // // test LLUrlEntryAgent - secondlife://app/agent Urls // - // IDEVO - moved temporarily into newview, not available for test - //LLUrlEntryAgent url; - //boost::regex r = url.getPattern(); - - //testRegex("Invalid Agent Url", r, - // "secondlife:///app/agent/0e346d8b-4433-4d66-XXXX-fd37083abc4c/about", - // ""); + LLUrlEntryAgent url; + boost::regex r = url.getPattern(); - //testRegex("Agent Url ", r, - // "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about", - // "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about"); + testRegex("Invalid Agent Url", r, + "secondlife:///app/agent/0e346d8b-4433-4d66-XXXX-fd37083abc4c/about", + ""); - //testRegex("Agent Url in text", r, - // "XXX secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about XXX", - // "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about"); + testRegex("Agent Url ", r, + "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about", + "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about"); - //testRegex("Agent Url multicase", r, - // "XXX secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/About XXX", - // "secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/About"); + testRegex("Agent Url in text", r, + "XXX secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about XXX", + "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about"); - //testRegex("Agent Url alternate command", r, - // "XXX secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/foobar", - // "secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/foobar"); + testRegex("Agent Url multicase", r, + "XXX secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/About XXX", + "secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/About"); + testRegex("Agent Url alternate command", r, + "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/CMakeLists.txt b/indra/newview/CMakeLists.txt index f4bbe7133f..5373556c20 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -445,7 +445,6 @@ set(viewer_SOURCE_FILES llurl.cpp llurldispatcher.cpp llurldispatcherlistener.cpp - llurlentryagent.cpp llurlhistory.cpp llurllineeditorctrl.cpp llurlsimstring.cpp @@ -953,7 +952,6 @@ set(viewer_HEADER_FILES llurl.h llurldispatcher.h llurldispatcherlistener.h - llurlentryagent.h llurlhistory.h llurllineeditorctrl.h llurlsimstring.h diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 0ba5fa9866..0f509422ef 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -144,9 +144,7 @@ #include "llui.h" #include "llurldispatcher.h" #include "llurlsimstring.h" -#include "llurlentryagent.h" // IDEVO #include "llurlhistory.h" -#include "llurlregistry.h" // IDEVO #include "llurlwhitelist.h" #include "llvieweraudio.h" #include "llviewerassetstorage.h" @@ -1284,9 +1282,6 @@ bool idle_startup() gCacheName->LocalizeCacheName("none", LLTrans::getString("GroupNameNone")); // Load stored cache if possible LLAppViewer::instance()->loadNameCache(); - - // Handle secondlife:///app/agent name lookups IDEVO - LLUrlRegistry::getInstance()->registerUrl(new LLUrlEntryAgent(), true); } // *Note: this is where gWorldMap used to be initialized. diff --git a/indra/newview/llurlentryagent.cpp b/indra/newview/llurlentryagent.cpp deleted file mode 100644 index bce64d7140..0000000000 --- a/indra/newview/llurlentryagent.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/** - * @file llurlentry.cpp - * @author Martin Reddy - * @brief Describes the Url types that can be registered in LLUrlRegistry - * - * $LicenseInfo:firstyear=2009&license=viewergpl$ - * - * Copyright (c) 2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llurlentryagent.h" - -#include "llcachename.h" -#include "lltrans.h" -#include "lluicolortable.h" - -// -// LLUrlEntryAgent Describes a Second Life agent Url, e.g., -// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about -// -LLUrlEntryAgent::LLUrlEntryAgent() -{ - mPattern = boost::regex("secondlife:///app/agent/[\\da-f-]+/\\w+", - boost::regex::perl|boost::regex::icase); - mMenuName = "menu_url_agent.xml"; - mIcon = "Generic_Person"; - mColor = LLUIColorTable::instance().getColor("AgentLinkColor"); -} - -// IDEVO demo code -static std::string clean_name(const std::string& full_name) -{ - std::string displayname; - if (full_name == "miyazaki23") // IDEVO demo code - { - // miyazaki - displayname += (char)(0xE5); - displayname += (char)(0xAE); - displayname += (char)(0xAE); - displayname += (char)(0xE5); - displayname += (char)(0xB4); - displayname += (char)(0x8E); - // hayao - displayname += (char)(0xE9); - displayname += (char)(0xA7); - displayname += (char)(0xBF); - // san - displayname += (char)(0xE3); - displayname += (char)(0x81); - displayname += (char)(0x95); - displayname += (char)(0xE3); - displayname += (char)(0x82); - displayname += (char)(0x93); - } - else if (full_name == "Jim Linden") - { - displayname = "Jos"; - displayname += (char)(0xC3); - displayname += (char)(0xA9); - displayname += " Sanchez"; - } - else if (full_name == "James Linden") - { - displayname = "James Cook"; - } - - std::string final; - if (!displayname.empty()) - { - final = displayname + " (" + full_name + ")"; - } - else - { - final = full_name; - } - return final; -} - -void LLUrlEntryAgent::onNameCache(const LLUUID& id, - const std::string& full_name, - bool is_group) -{ - std::string final = clean_name(full_name); - // received the agent name from the server - tell our observers - callObservers(id.asString(), final); -} - -std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCallback &cb) -{ - if (!gCacheName) - { - // 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)) - { - return clean_name(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"); - } -} diff --git a/indra/newview/llurlentryagent.h b/indra/newview/llurlentryagent.h deleted file mode 100644 index 76a54dfeb1..0000000000 --- a/indra/newview/llurlentryagent.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - * @file llurlentryagent.h - * - * $LicenseInfo:firstyear=2009&license=viewergpl$ - * - * Copyright (c) 2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_LLURLENTRYAGENT_H -#define LL_LLURLENTRYAGENT_H - -#include "llurlentry.h" - -/// -/// LLUrlEntryAgent Describes a Second Life agent Url, e.g., -/// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about -/// -/// IDEVO Pulled this temporarily into newview for faster compile/link -/// times while iterating on UI. -class LLUrlEntryAgent : public LLUrlEntryBase -{ -public: - LLUrlEntryAgent(); - /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); -private: - void onNameCache(const LLUUID& id, const std::string& full_name, bool is_group); -}; - -#endif -- cgit v1.3 From c16591c046fa76fc5d13387efa3bcaec3422e593 Mon Sep 17 00:00:00 2001 From: James Cook Date: Fri, 12 Feb 2010 16:12:12 -0800 Subject: Per-avatar customizable icons next to name links in text Changed LLUrlEntryAgent callbacks to handle both link label and icon Eliminated legacy LLNameCache file loading Reviewed with Kelly --- indra/llcommon/llavatarname.cpp | 7 + indra/llcommon/llavatarname.h | 11 ++ indra/llmessage/llavatarnamecache.cpp | 147 +++++++++++---------- indra/llmessage/llcachename.cpp | 83 +----------- indra/llmessage/llcachename.h | 5 +- indra/llui/lltextbase.cpp | 47 ++++++- indra/llui/lltextbase.h | 5 +- indra/llui/llurlentry.cpp | 61 ++++++--- indra/llui/llurlentry.h | 9 +- indra/llui/llurlregistry.cpp | 4 +- indra/llui/llurlregistry.h | 4 +- indra/newview/llappviewer.cpp | 12 +- indra/newview/llstartup.cpp | 36 +++-- indra/newview/llstartup.h | 4 + .../skins/default/textures/icons/Person_Check.png | Bin 0 -> 3824 bytes .../skins/default/textures/icons/Person_Star.png | Bin 0 -> 3762 bytes indra/newview/skins/default/textures/textures.xml | 2 + 17 files changed, 231 insertions(+), 206 deletions(-) create mode 100644 indra/newview/skins/default/textures/icons/Person_Check.png create mode 100644 indra/newview/skins/default/textures/icons/Person_Star.png (limited to 'indra/llui/llurlregistry.cpp') diff --git a/indra/llcommon/llavatarname.cpp b/indra/llcommon/llavatarname.cpp index 0563374785..3b1ab4d267 100644 --- a/indra/llcommon/llavatarname.cpp +++ b/indra/llcommon/llavatarname.cpp @@ -35,6 +35,13 @@ #include "llavatarname.h" +LLAvatarName::LLAvatarName() +: mSLID(), + mDisplayName(), + mLastUpdate(0), + mBadge() +{ } + bool LLAvatarName::operator<(const LLAvatarName& rhs) const { if (mSLID == rhs.mSLID) diff --git a/indra/llcommon/llavatarname.h b/indra/llcommon/llavatarname.h index 4264a8e655..7205eb4523 100644 --- a/indra/llcommon/llavatarname.h +++ b/indra/llcommon/llavatarname.h @@ -39,6 +39,8 @@ class LL_COMMON_API LLAvatarName { public: + LLAvatarName(); + bool operator<(const LLAvatarName& rhs) const; // "bobsmith123" or "james.linden", US-ASCII only @@ -48,6 +50,15 @@ public: // Contains data whether or not user has explicitly set // a display name; may duplicate their SLID. std::string mDisplayName; + + // Names can change, so need to keep track of when name was + // last checked. + // Unix time-from-epoch seconds + U32 mLastUpdate; + + // Can be a viewer UI image name ("Person_Check") or a server-side + // image UUID, or empty string. + std::string mBadge; }; #endif diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index 16bfa37b0e..610bc58057 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -38,6 +38,11 @@ #include // tolower() +namespace LLAvatarNameCache +{ + std::map sCache; +} + static std::string slid_from_full_name(const std::string& full_name) { std::string id = full_name; @@ -52,64 +57,67 @@ static std::string slid_from_full_name(const std::string& full_name) return id; } -static std::map sDisplayNames; - -// JAMESDEBUG HACK temporary IDEVO code -static std::string get_display_name(const LLUUID& id) -{ - if (sDisplayNames.empty()) - { - LLUUID id; - const unsigned char miyazaki_hayao_san[] - = { 0xE5, 0xAE, 0xAE, 0xE5, 0xB4, 0x8E, - 0xE9, 0xA7, 0xBF, - 0xE3, 0x81, 0x95, 0xE3, 0x82, 0x93, '\0' }; - id.set("27888d5f-4ddb-4df3-ad36-a1483ce0b3d9"); // miyazaki23 - sDisplayNames[id] = (const char*)miyazaki_hayao_san; - - id.set("3e5bf676-3577-c9ee-9fac-10df430015a1"); // Jim Linden - sDisplayNames[id] = "Jim Jenkins"; - - const unsigned char jose_sanchez[] = - { 'J','o','s',0xC3,0xA9,' ','S','a','n','c','h','e','z', '\0' }; - id.set("a2e76fcd-9360-4f6d-a924-938f923df11a"); // James Linden - sDisplayNames[id] = (const char*)jose_sanchez; - - id.set("a23fff6c-80ae-4997-9253-48272fd01d3c"); // bobsmith123 - sDisplayNames[id] = (const char*)jose_sanchez; - - id.set("3f7ced39-5e38-4fdd-90f2-423560b1e6e2"); // Hamilton Linden - sDisplayNames[id] = "Hamilton Hitchings"; - - id.set("537da1e1-a89f-4f9b-9056-b1f0757ccdd0"); // Rome Linden - sDisplayNames[id] = "Rome Portlock"; - - id.set("244195d6-c9b7-4fd6-9229-c3a8b2e60e81"); // M Linden - sDisplayNames[id] = "Mark Kingdon"; - - id.set("49856302-98d4-4e32-b5e9-035e5b4e83a4"); // T Linden - sDisplayNames[id] = "Tom Hale"; - - id.set("e6ed7825-708f-4c6b-b6a7-f3fe921a9176"); // Callen Linden - sDisplayNames[id] = "Christina Allen"; - - id.set("a7f0ac18-205f-41d2-b5b4-f75f096ae511"); // Crimp Linden - sDisplayNames[id] = "Chris Rimple"; - } - - std::map::iterator it = sDisplayNames.find(id); - if (it != sDisplayNames.end()) - { - return it->second; - } - else - { - return std::string(); - } -} - void LLAvatarNameCache::initClass() { + // HACK - prepopulate the cache + LLAvatarName name; + LLUUID id; + + name.mSLID = "miyazaki23"; + const unsigned char miyazaki_hayao_san[] + = { 0xE5, 0xAE, 0xAE, 0xE5, 0xB4, 0x8E, + 0xE9, 0xA7, 0xBF, + 0xE3, 0x81, 0x95, 0xE3, 0x82, 0x93, '\0' }; + name.mDisplayName = (const char*)miyazaki_hayao_san; + name.mBadge = "Person_Check"; + sCache[LLUUID("27888d5f-4ddb-4df3-ad36-a1483ce0b3d9")] = name; + + name.mSLID = "jim.linden"; + name.mDisplayName = "Jim Jenkins"; + name.mBadge = "Person_Star"; + sCache[LLUUID("3e5bf676-3577-c9ee-9fac-10df430015a1")] = name; + + name.mSLID = "james.linden"; + const unsigned char jose_sanchez[] = + { 'J','o','s',0xC3,0xA9,' ','S','a','n','c','h','e','z', '\0' }; + name.mDisplayName = (const char*)jose_sanchez; + name.mBadge = "35f217a3-f618-49cf-bbca-c86d486551a9"; // IMG_SHOT + sCache[LLUUID("a2e76fcd-9360-4f6d-a924-938f923df11a")] = name; + + name.mSLID = "bobsmith123"; + name.mDisplayName = (const char*)jose_sanchez; + name.mBadge = ""; + sCache[LLUUID("a23fff6c-80ae-4997-9253-48272fd01d3c")] = name; + + name.mSLID = "hamilton.linden"; + name.mDisplayName = "Hamilton Hitchings"; + name.mBadge = "Person_Star"; + sCache[LLUUID("3f7ced39-5e38-4fdd-90f2-423560b1e6e2")] = name; + + name.mSLID = "rome.linden"; + name.mDisplayName = "Rome Portlock"; + name.mBadge = "Person_Star"; + sCache[LLUUID("537da1e1-a89f-4f9b-9056-b1f0757ccdd0")] = name; + + name.mSLID = "m.linden"; + name.mDisplayName = "Mark Kingdon"; + name.mBadge = "Person_Star"; + sCache[LLUUID("244195d6-c9b7-4fd6-9229-c3a8b2e60e81")] = name; + + name.mSLID = "t.linden"; + name.mDisplayName = "Tom Hale"; + name.mBadge = "Person_Star"; + sCache[LLUUID("49856302-98d4-4e32-b5e9-035e5b4e83a4")] = name; + + name.mSLID = "callen.linden"; + name.mDisplayName = "Christina Allen"; + name.mBadge = "Person_Star"; + sCache[LLUUID("e6ed7825-708f-4c6b-b6a7-f3fe921a9176")] = name; + + name.mSLID = "crimp.linden"; + name.mDisplayName = "Chris Rimple"; + name.mBadge = "Person_Star"; + sCache[LLUUID("a7f0ac18-205f-41d2-b5b4-f75f096ae511")] = name; } void LLAvatarNameCache::cleanupClass() @@ -130,24 +138,23 @@ void LLAvatarNameCache::idle() bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name) { + std::map::iterator it = sCache.find(agent_id); + if (it != sCache.end()) + { + *av_name = it->second; + return true; + } + std::string full_name; - bool found = gCacheName->getFullName(agent_id, full_name); - if (found) + if (gCacheName->getFullName(agent_id, full_name)) { av_name->mSLID = slid_from_full_name(full_name); - - std::string display_name = get_display_name(agent_id); - if (!display_name.empty()) - { - av_name->mDisplayName = display_name; - } - else - { - // ...no explicit display name, use legacy name - av_name->mDisplayName = full_name; - } + av_name->mDisplayName = full_name; + av_name->mBadge = "Generic_Person"; + return true; } - return found; + + return false; } void LLAvatarNameCache::get(const LLUUID& agent_id, name_cache_callback_t callback) diff --git a/indra/llmessage/llcachename.cpp b/indra/llmessage/llcachename.cpp index 4e3c3630ab..b94788bd0c 100644 --- a/indra/llmessage/llcachename.cpp +++ b/indra/llmessage/llcachename.cpp @@ -308,89 +308,10 @@ boost::signals2::connection LLCacheName::addObserver(const LLCacheNameCallback& return impl.mSignal.connect(callback); } -void LLCacheName::importFile(LLFILE* fp) -{ - S32 count = 0; - - const S32 BUFFER_SIZE = 1024; - char buffer[BUFFER_SIZE]; /*Flawfinder: ignore*/ - - // *NOTE: These buffer sizes are hardcoded into sscanf() below - char id_string[MAX_STRING]; /*Flawfinder: ignore*/ - char firstname[MAX_STRING]; /*Flawfinder: ignore*/ - char lastname[MAX_STRING]; /*Flawfinder: ignore*/ - U32 create_time; - - // This is OK if the first line is actually a name. We just don't load it. - char* valid = fgets(buffer, BUFFER_SIZE, fp); - if (!valid) return; - - // *NOTE: This buffer size is hardcoded into sscanf() below - char version_string[BUFFER_SIZE]; /*Flawfinder: ignore*/ - S32 version = 0; - S32 match = sscanf( /* Flawfinder: ignore */ - buffer, - "%1023s %d", - version_string, &version); - if ( match != 2 - || strcmp(version_string, "version") - || version != CN_FILE_VERSION) - { - llwarns << "Ignoring old cache name file format" << llendl; - return; - } - - // We'll expire entries more than a week old - U32 now = (U32)time(NULL); - const U32 SECS_PER_DAY = 60 * 60 * 24; - U32 delete_before_time = now - (7 * SECS_PER_DAY); - - while(!feof(fp)) - { - valid = fgets(buffer, BUFFER_SIZE, fp); - if (!valid) break; - - match = sscanf( /* Flawfinder: ignore */ - buffer, - "%254s %u %254s %254s", - id_string, - &create_time, - firstname, - lastname); - if (4 != match) continue; - - LLUUID id(id_string); - if (id.isNull()) continue; - - // undo trivial XOR - S32 i; - for (i = 0; i < UUID_BYTES; i++) - { - id.mData[i] ^= 0x33; - } - - // Don't load entries that are more than a week old - if (create_time < delete_before_time) continue; - - LLCacheNameEntry* entry = new LLCacheNameEntry(); - entry->mIsGroup = false; - entry->mCreateTime = create_time; - entry->mFirstName = firstname; - entry->mLastName = lastname; - impl.mCache[id] = entry; - std::string fullname = entry->mFirstName + " " + entry->mLastName; - impl.mReverseCache[fullname] = id; - - count++; - } - - llinfos << "LLCacheName loaded " << count << " names" << llendl; -} - bool LLCacheName::importFile(std::istream& istr) { LLSD data; - if(LLSDSerialize::fromXML(data, istr) < 1) + if(LLSDSerialize::fromXMLDocument(data, istr) < 1) return false; // We'll expire entries more than a week old @@ -512,7 +433,7 @@ BOOL LLCacheName::Impl::getName(const LLUUID& id, std::string& first, std::strin } // static -void LLCacheName::LocalizeCacheName(std::string key, std::string value) +void LLCacheName::localizeCacheName(std::string key, std::string value) { if (key!="" && value!= "" ) sCacheName[key]=value; diff --git a/indra/llmessage/llcachename.h b/indra/llmessage/llcachename.h index 322ca4aa1a..8d8e172c08 100644 --- a/indra/llmessage/llcachename.h +++ b/indra/llmessage/llcachename.h @@ -70,9 +70,6 @@ public: boost::signals2::connection addObserver(const LLCacheNameCallback& callback); - // janky old format. Remove after a while. Phoenix. 2008-01-30 - void importFile(LLFILE* fp); - // storing cache on disk; for viewer, in name.cache bool importFile(std::istream& istr); void exportFile(std::ostream& ostr); @@ -116,7 +113,7 @@ public: void dumpStats(); // Dumps the sizes of the cache and associated queues. static std::string getDefaultName(); - static void LocalizeCacheName(std::string key, std::string value); + static void localizeCacheName(std::string key, std::string value); static std::map sCacheName; private: diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index ef422dbdc5..075f54ed30 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1527,6 +1527,20 @@ std::string LLTextBase::getText() const return getViewModel()->getValue().asString(); } +// IDEVO - icons can be UI image names or UUID sent from +// server with avatar display name +static LLUIImagePtr image_from_icon_name(const std::string& icon_name) +{ + if (LLUUID::validate(icon_name)) + { + return LLUI::getUIImageByID( LLUUID(icon_name) ); + } + else + { + return LLUI::getUIImage(icon_name); + } +} + void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params) { LLStyle::Params style_params(input_params); @@ -1539,7 +1553,7 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c LLUrlMatch match; std::string text = new_text; while ( LLUrlRegistry::instance().findUrl(text, match, - boost::bind(&LLTextBase::replaceUrlLabel, this, _1, _2)) ) + boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3)) ) { start = match.getStart(); end = match.getEnd()+1; @@ -1570,15 +1584,18 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c // output an optional icon before the Url if (! match.getIcon().empty()) { - LLUIImagePtr image = LLUI::getUIImage(match.getIcon()); + LLUIImagePtr image = image_from_icon_name( match.getIcon() ); if (image) { - LLStyle::Params icon; - icon.image = image; + LLStyle::Params icon_params; + icon_params.image = image; + // must refer to our link so we can update the icon later + // after name/group data is looked up + icon_params.link_href = match.getUrl(); // Text will be replaced during rendering with the icon, // but string cannot be empty or the segment won't be // added (or drawn). - appendAndHighlightText(" ", prepend_newline, part, icon); + appendAndHighlightText(" ", prepend_newline, part, icon_params); prepend_newline = false; } } @@ -1728,8 +1745,9 @@ void LLTextBase::appendAndHighlightText(const std::string &new_text, bool prepen } -void LLTextBase::replaceUrlLabel(const std::string &url, - const std::string &label) +void LLTextBase::replaceUrl(const std::string &url, + const std::string &label, + const std::string &icon) { // get the full (wide) text for the editor so we can change it LLWString text = getWText(); @@ -1759,6 +1777,21 @@ void LLTextBase::replaceUrlLabel(const std::string &url, modified = true; } + // Icon might be updated when more avatar or group info + // becomes available + if (style->isImage() && style->getLinkHREF() == url) + { + LLUIImagePtr image = image_from_icon_name( icon ); + if (image) + { + LLStyle::Params icon_params; + icon_params.image = image; + LLStyleConstSP new_style(new LLStyle(icon_params)); + seg->setStyle(new_style); + modified = true; + } + } + // work out the character offset for the next segment seg_start = seg->getEnd(); } diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 3dda6f4cc8..dc8bc0dca0 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -309,7 +309,10 @@ protected: // misc void updateRects(); void needsScroll() { mScrollNeeded = TRUE; } - void replaceUrlLabel(const std::string &url, const std::string &label); + + // Replace a URL with a new icon and label, for example, when + // avatar names are looked up. + void replaceUrl(const std::string &url, const std::string &label, const std::string& icon); protected: // text segmentation and flow diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index dae2c44f08..dbfac63a72 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -55,6 +55,12 @@ std::string LLUrlEntryBase::getUrl(const std::string &string) const return escapeUrl(string); } +//virtual +std::string LLUrlEntryBase::getIcon(const std::string &url) const +{ + return mIcon; +} + std::string LLUrlEntryBase::getIDStringFromUrl(const std::string &url) const { // return the id from a SLURL in the format /app/{cmd}/{id}/about @@ -133,7 +139,9 @@ void LLUrlEntryBase::addObserver(const std::string &id, } } -void LLUrlEntryBase::callObservers(const std::string &id, const std::string &label) +void LLUrlEntryBase::callObservers(const std::string &id, + const std::string &label, + const std::string &icon) { // notify all callbacks waiting on the given uuid std::multimap::iterator it; @@ -141,7 +149,7 @@ void LLUrlEntryBase::callObservers(const std::string &id, const std::string &lab { // call the callback - give it the new label LLUrlEntryObserver &observer = it->second; - (*observer.signal)(it->second.url, label); + (*observer.signal)(it->second.url, label, icon); // then remove the signal - we only need to call it once delete observer.signal; mObservers.erase(it++); @@ -312,22 +320,18 @@ LLUrlEntryAgent::LLUrlEntryAgent() mColor = LLUIColorTable::instance().getColor("AgentLinkColor"); } -// IDEVO demo code -std::string LLUrlEntryAgent::buildName(const LLUUID& id) -{ - // JAMESDEBUG HACK: assume name is there - LLAvatarName av_name; - LLAvatarNameCache::get(id, &av_name); - return av_name.mDisplayName + " (" + av_name.mSLID + ")"; -} - void LLUrlEntryAgent::onNameCache(const LLUUID& id, const std::string& full_name, bool is_group) { - std::string final = buildName(id); + // IDEVO demo code + LLAvatarName av_name; + LLAvatarNameCache::get(id, &av_name); + std::string label = av_name.mDisplayName + " (" + av_name.mSLID + ")"; + // use custom icon if available + std::string icon = (!av_name.mBadge.empty() ? av_name.mBadge : mIcon); // received the agent name from the server - tell our observers - callObservers(id.asString(), final); + callObservers(id.asString(), label, icon); } std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCallback &cb) @@ -353,7 +357,10 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa } else if (gCacheName->getFullName(agent_id, full_name)) { - return buildName(agent_id); + LLAvatarName av_name; + LLAvatarNameCache::get(agent_id, &av_name); + std::string label = av_name.mDisplayName + " (" + av_name.mSLID + ")"; + return label; } else { @@ -366,6 +373,30 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa } +std::string LLUrlEntryAgent::getIcon(const std::string &url) const +{ + std::string agent_id_string = getIDStringFromUrl(url); + if (agent_id_string.empty()) + { + return mIcon; + } + + LLUUID agent_id(agent_id_string); + if (agent_id.isNull()) + { + return mIcon; + } + + LLAvatarName av_name; + LLAvatarNameCache::get(agent_id, &av_name); + if (av_name.mBadge.empty()) + { + return mIcon; + } + + return av_name.mBadge; +} + // // LLUrlEntryGroup Describes a Second Life group Url, e.g., // secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about @@ -386,7 +417,7 @@ void LLUrlEntryGroup::onGroupNameReceived(const LLUUID& id, bool is_group) { // received the group name from the server - tell our observers - callObservers(id.asString(), name); + callObservers(id.asString(), name, mIcon); } std::string LLUrlEntryGroup::getLabel(const std::string &url, const LLUrlLabelCallback &cb) diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index 2bc21eb989..1f0caeacf5 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -42,7 +42,8 @@ #include typedef boost::signals2::signal LLUrlLabelSignal; + const std::string& label, + const std::string& icon)> LLUrlLabelSignal; typedef LLUrlLabelSignal::slot_type LLUrlLabelCallback; /// @@ -77,7 +78,7 @@ public: virtual std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) { return url; } /// Return an icon that can be displayed next to Urls of this type - std::string getIcon() const { return mIcon; } + virtual std::string getIcon(const std::string &url) const; /// Return the color to render the displayed text LLUIColor getColor() const { return mColor; } @@ -101,7 +102,7 @@ protected: std::string getLabelFromWikiLink(const std::string &url) const; std::string getUrlFromWikiLink(const std::string &string) const; void addObserver(const std::string &id, const std::string &url, const LLUrlLabelCallback &cb); - void callObservers(const std::string &id, const std::string &label); + void callObservers(const std::string &id, const std::string &label, const std::string& icon); typedef struct { std::string url; @@ -168,10 +169,10 @@ class LLUrlEntryAgent : public LLUrlEntryBase public: LLUrlEntryAgent(); /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); + /*virtual*/ std::string getIcon(const std::string &url) const; private: void onNameCache(const LLUUID& id, const std::string& full_name, bool is_group); - std::string buildName(const LLUUID& id); }; /// diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index 5db1f46b8d..1ee87a01de 100644 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -37,7 +37,7 @@ #include // default dummy callback that ignores any label updates from the server -void LLUrlRegistryNullCallback(const std::string &url, const std::string &label) +void LLUrlRegistryNullCallback(const std::string &url, const std::string &label, const std::string& icon) { } @@ -180,7 +180,7 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL match_entry->getUrl(url), match_entry->getLabel(url, cb), match_entry->getTooltip(), - match_entry->getIcon(), + match_entry->getIcon(url), match_entry->getColor(), match_entry->getMenuName(), match_entry->getLocation(url), diff --git a/indra/llui/llurlregistry.h b/indra/llui/llurlregistry.h index 6d47c2c2a2..dffbd9d4bf 100644 --- a/indra/llui/llurlregistry.h +++ b/indra/llui/llurlregistry.h @@ -43,7 +43,9 @@ #include /// This default callback for findUrl() simply ignores any label updates -void LLUrlRegistryNullCallback(const std::string &url, const std::string &label); +void LLUrlRegistryNullCallback(const std::string &url, + const std::string &label, + const std::string &icon); /// /// LLUrlRegistry is a singleton that contains a set of Url types that diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 00a9e4d745..ba2e13da9d 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1298,8 +1298,7 @@ bool LLAppViewer::cleanup() LLPolyMesh::freeAllMeshes(); - delete gCacheName; - gCacheName = NULL; + LLStartUp::cleanupNameCache(); // Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be deleted. @@ -3337,15 +3336,6 @@ void LLAppViewer::loadNameCache() { if(gCacheName->importFile(cache_file)) return; } - - // Try to load from the legacy format. This should go away after a - // while. Phoenix 2008-01-30 - LLFILE* name_cache_fp = LLFile::fopen(name_cache, "r"); // Flawfinder: ignore - if (name_cache_fp) - { - gCacheName->importFile(name_cache_fp); - fclose(name_cache_fp); - } } void LLAppViewer::saveNameCache() diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index cfad29df89..97e47fb05e 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -52,6 +52,7 @@ #endif #include "llares.h" +#include "llavatarnamecache.h" #include "lllandmark.h" #include "llcachename.h" #include "lldir.h" @@ -1280,16 +1281,7 @@ bool idle_startup() gXferManager->registerCallbacks(gMessageSystem); - if ( gCacheName == NULL ) - { - gCacheName = new LLCacheName(gMessageSystem); - gCacheName->addObserver(&callback_cache_name); - gCacheName->LocalizeCacheName("waiting", LLTrans::getString("AvatarNameWaiting")); - gCacheName->LocalizeCacheName("nobody", LLTrans::getString("AvatarNameNobody")); - gCacheName->LocalizeCacheName("none", LLTrans::getString("GroupNameNone")); - // Load stored cache if possible - LLAppViewer::instance()->loadNameCache(); - } + LLStartUp::initNameCache(); //gCacheName is required for nearby chat history loading //so I just moved nearby history loading a few states further @@ -2781,6 +2773,30 @@ void LLStartUp::fontInit() LLFontGL::loadDefaultFonts(); } +void LLStartUp::initNameCache() +{ + // Can be called multiple times + if ( gCacheName ) return; + + gCacheName = new LLCacheName(gMessageSystem); + gCacheName->addObserver(&callback_cache_name); + gCacheName->localizeCacheName("waiting", LLTrans::getString("AvatarNameWaiting")); + gCacheName->localizeCacheName("nobody", LLTrans::getString("AvatarNameNobody")); + gCacheName->localizeCacheName("none", LLTrans::getString("GroupNameNone")); + // Load stored cache if possible + LLAppViewer::instance()->loadNameCache(); + + LLAvatarNameCache::initClass(); +} + +void LLStartUp::cleanupNameCache() +{ + LLAvatarNameCache::cleanupClass(); + + delete gCacheName; + gCacheName = NULL; +} + bool LLStartUp::dispatchURL() { // ok, if we've gotten this far and have a startup URL diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h index 92fe9521d3..14a7c71544 100644 --- a/indra/newview/llstartup.h +++ b/indra/newview/llstartup.h @@ -95,6 +95,10 @@ public: // Load default fonts not already loaded at start screen static void fontInit(); + static void initNameCache(); + + static void cleanupNameCache(); + // outfit_folder_name can be a folder anywhere in your inventory, // but the name must be a case-sensitive exact match. // gender_name is either "male" or "female" diff --git a/indra/newview/skins/default/textures/icons/Person_Check.png b/indra/newview/skins/default/textures/icons/Person_Check.png new file mode 100644 index 0000000000..f8638540d4 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Person_Check.png differ diff --git a/indra/newview/skins/default/textures/icons/Person_Star.png b/indra/newview/skins/default/textures/icons/Person_Star.png new file mode 100644 index 0000000000..ad10580ac4 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Person_Star.png differ diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 18d1779702..753f62dc8d 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -410,6 +410,8 @@ with the same filename but different name + + -- cgit v1.3 From 4ea7d2de9fcab4dd4694fcbbd2fece1c57f41d2c Mon Sep 17 00:00:00 2001 From: Richard Nelson Date: Mon, 24 May 2010 17:25:35 -0700 Subject: DEV-50271 FIX SLURL support for non-clickable display names reviewed by James --- indra/llui/lltextbase.cpp | 4 +- indra/llui/llurlentry.cpp | 145 ++++++++++++++++++++++++++++++++-- indra/llui/llurlentry.h | 66 +++++++++++++++- indra/llui/llurlmatch.cpp | 4 +- indra/llui/llurlmatch.h | 8 +- indra/llui/llurlregistry.cpp | 9 ++- indra/llui/tests/llurlentry_stub.cpp | 103 ++++++++++++++++++++++++ indra/llui/tests/llurlmatch_test.cpp | 132 +++++++++++++++++++++++++++---- indra/newview/llpanelplaceprofile.cpp | 2 +- 9 files changed, 434 insertions(+), 39 deletions(-) (limited to 'indra/llui/llurlregistry.cpp') diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 78312eba73..c93e6c7257 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1583,9 +1583,7 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c end = match.getEnd()+1; LLStyle::Params link_params = style_params; - link_params.color = match.getColor(); - link_params.readonly_color = match.getColor(); - link_params.font.style("UNDERLINE"); + link_params.overwriteFrom(match.getStyle()); link_params.link_href = match.getUrl(); // output the text before the Url diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 36b644484d..7ba569408a 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -49,9 +49,11 @@ std::string localize_slapp_label(const std::string& url, const std::string& full LLUrlEntryBase::LLUrlEntryBase() : - mColor(LLUIColorTable::instance().getColor("HTMLLinkColor")), mDisabledLink(false) { + mStyle.color = LLUIColorTable::instance().getColor("HTMLLinkColor"); + mStyle.readonly_color = LLUIColorTable::instance().getColor("HTMLLinkColor"); + mStyle.font.style("UNDERLINE"); } LLUrlEntryBase::~LLUrlEntryBase() @@ -327,7 +329,8 @@ LLUrlEntryAgent::LLUrlEntryAgent() boost::regex::perl|boost::regex::icase); mMenuName = "menu_url_agent.xml"; mIcon = "Generic_Person"; - mColor = LLUIColorTable::instance().getColor("AgentLinkColor"); + mStyle.color = LLUIColorTable::instance().getColor("AgentLinkColor"); + mStyle.readonly_color = LLUIColorTable::instance().getColor("AgentLinkColor"); } // virtual @@ -421,11 +424,8 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa LLAvatarName av_name; if (LLAvatarNameCache::get(agent_id, &av_name)) { - std::string label = av_name.mDisplayName; - if (!av_name.mUsername.empty()) - { - label += " (" + av_name.mUsername + ")"; - } + std::string label = av_name.getCompleteName(); + // handle suffixes like /mute or /offerteleport label = localize_slapp_label(url, label); return label; @@ -478,6 +478,134 @@ std::string LLUrlEntryAgent::getIcon(const std::string &url) return mIcon; } +// +// LLUrlEntryAgentName describes a Second Life agent name Url, e.g., +// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username) +// x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username) +// +LLUrlEntryAgentName::LLUrlEntryAgentName() +{ + mDisabledLink = true; + mStyle.color.setProvided(false); + mStyle.readonly_color.setProvided(false); + mStyle.font.setProvided(false); +} + +// virtual +void LLUrlEntryAgentName::callObservers(const std::string &id, + const std::string &label, + const std::string &icon) +{ + // notify all callbacks waiting on the given uuid + std::multimap::iterator it; + for (it = mObservers.find(id); it != mObservers.end();) + { + // call the callback - give it the new label + LLUrlEntryObserver &observer = it->second; + (*observer.signal)(observer.url, label, icon); + // then remove the signal - we only need to call it once + delete observer.signal; + mObservers.erase(it++); + } +} + +void LLUrlEntryAgentName::onAvatarNameCache(const LLUUID& id, + const LLAvatarName& av_name) +{ + std::string label = getName(av_name); + // received the agent name from the server - tell our observers + callObservers(id.asString(), label, mIcon); +} + +std::string LLUrlEntryAgentName::getLabel(const std::string &url, const LLUrlLabelCallback &cb) +{ + if (!gCacheName) + { + // 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); + if (agent_id.isNull()) + { + return LLTrans::getString("AvatarNameNobody"); + } + + LLAvatarName av_name; + if (LLAvatarNameCache::get(agent_id, &av_name)) + { + return getName(av_name); + } + else + { + LLAvatarNameCache::get(agent_id, + boost::bind(&LLUrlEntryAgentCompleteName::onAvatarNameCache, + this, _1, _2)); + addObserver(agent_id_string, url, cb); + return LLTrans::getString("LoadingData"); + } +} + +std::string LLUrlEntryAgentName::getUrl(const std::string &url) const +{ + return LLStringUtil::null; +} + +// +// LLUrlEntryAgentCompleteName describes a Second Life agent complete name Url, e.g., +// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/completename +// x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/completename +// +LLUrlEntryAgentCompleteName::LLUrlEntryAgentCompleteName() +{ + mPattern = boost::regex(APP_HEADER_REGEX "/agent/[\\da-f-]+/completename", + boost::regex::perl|boost::regex::icase); +} + +std::string LLUrlEntryAgentCompleteName::getName(const LLAvatarName& avatar_name) +{ + return avatar_name.getCompleteName(); +} + +// +// LLUrlEntryAgentDisplayName describes a Second Life agent display name Url, e.g., +// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/displayname +// x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/displayname +// +LLUrlEntryAgentDisplayName::LLUrlEntryAgentDisplayName() +{ + mPattern = boost::regex(APP_HEADER_REGEX "/agent/[\\da-f-]+/displayname", + boost::regex::perl|boost::regex::icase); +} + +std::string LLUrlEntryAgentDisplayName::getName(const LLAvatarName& avatar_name) +{ + return avatar_name.mDisplayName; +} + +// +// LLUrlEntryAgentUserName describes a Second Life agent user name Url, e.g., +// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/username +// x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/username +// +LLUrlEntryAgentUserName::LLUrlEntryAgentUserName() +{ + mPattern = boost::regex(APP_HEADER_REGEX "/agent/[\\da-f-]+/username", + boost::regex::perl|boost::regex::icase); +} + +std::string LLUrlEntryAgentUserName::getName(const LLAvatarName& avatar_name) +{ + return avatar_name.mUsername.empty() ? avatar_name.getLegacyName() : avatar_name.mUsername; +} + // // LLUrlEntryGroup Describes a Second Life group Url, e.g., // secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about @@ -491,7 +619,8 @@ LLUrlEntryGroup::LLUrlEntryGroup() mMenuName = "menu_url_group.xml"; mIcon = "Generic_Group"; mTooltip = LLTrans::getString("TooltipGroupUrl"); - mColor = LLUIColorTable::instance().getColor("GroupLinkColor"); + mStyle.color = LLUIColorTable::instance().getColor("GroupLinkColor"); + mStyle.readonly_color = LLUIColorTable::instance().getColor("GroupLinkColor"); } void LLUrlEntryGroup::onGroupNameReceived(const LLUUID& id, diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index 0abf7a603f..21d4c29b2b 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -36,6 +36,7 @@ #include "lluuid.h" #include "lluicolor.h" +#include "llstyle.h" #include #include #include @@ -82,8 +83,8 @@ public: /// Return an icon that can be displayed next to Urls of this type virtual std::string getIcon(const std::string &url); - /// Return the color to render the displayed text - LLUIColor getColor() const { return mColor; } + /// Return the style to render the displayed text + LLStyle::Params getStyle() const { return mStyle; } /// Given a matched Url, return a tooltip string for the hyperlink virtual std::string getTooltip(const std::string &string) const { return mTooltip; } @@ -115,7 +116,7 @@ protected: std::string mIcon; std::string mMenuName; std::string mTooltip; - LLUIColor mColor; + LLStyle::Params mStyle; std::multimap mObservers; bool mDisabledLink; }; @@ -179,6 +180,65 @@ private: void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name); }; +/// +/// LLUrlEntryAgentName Describes a Second Life agent name Url, e.g., +/// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username) +/// that displays various forms of user name +/// This is a base class for the various implementations of name display +class LLUrlEntryAgentName : public LLUrlEntryBase +{ +public: + LLUrlEntryAgentName(); + /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); + /*virtual*/ std::string getUrl(const std::string &string) const; +protected: + /*virtual*/ void callObservers(const std::string &id, const std::string &label, const std::string& icon); + // override this to pull out relevant name fields + virtual std::string getName(const LLAvatarName& avatar_name) = 0; +private: + void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name); +}; + + +/// +/// LLUrlEntryAgentCompleteName Describes a Second Life agent name Url, e.g., +/// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/completename +/// that displays the full display name + user name for an avatar +/// such as "James Linden (james.linden)" +class LLUrlEntryAgentCompleteName : public LLUrlEntryAgentName +{ +public: + LLUrlEntryAgentCompleteName(); +private: + /*virtual*/ std::string getName(const LLAvatarName& avatar_name); +}; + +/// +/// LLUrlEntryAgentDisplayName Describes a Second Life agent display name Url, e.g., +/// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/displayname +/// that displays the just the display name for an avatar +/// such as "James Linden" +class LLUrlEntryAgentDisplayName : public LLUrlEntryAgentName +{ +public: + LLUrlEntryAgentDisplayName(); +private: + /*virtual*/ std::string getName(const LLAvatarName& avatar_name); +}; + +/// +/// LLUrlEntryAgentUserName Describes a Second Life agent username Url, e.g., +/// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/username +/// that displays the just the display name for an avatar +/// such as "james.linden" +class LLUrlEntryAgentUserName : public LLUrlEntryAgentName +{ +public: + LLUrlEntryAgentUserName(); +private: + /*virtual*/ std::string getName(const LLAvatarName& avatar_name); +}; + /// /// LLUrlEntryGroup Describes a Second Life group Url, e.g., /// secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about diff --git a/indra/llui/llurlmatch.cpp b/indra/llui/llurlmatch.cpp index 72a199c220..8a7e2e162b 100644 --- a/indra/llui/llurlmatch.cpp +++ b/indra/llui/llurlmatch.cpp @@ -49,7 +49,7 @@ LLUrlMatch::LLUrlMatch() : void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url, const std::string &label, const std::string &tooltip, - const std::string &icon, const LLUIColor& color, + const std::string &icon, const LLStyle::Params& style, const std::string &menu, const std::string &location, bool disabled_link) { @@ -59,7 +59,7 @@ void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url, mLabel = label; mTooltip = tooltip; mIcon = icon; - mColor = color; + mStyle = style; mMenuName = menu; mLocation = location; mDisabledLink = disabled_link; diff --git a/indra/llui/llurlmatch.h b/indra/llui/llurlmatch.h index e86762548b..92a87c3d4c 100644 --- a/indra/llui/llurlmatch.h +++ b/indra/llui/llurlmatch.h @@ -38,7 +38,7 @@ #include #include -#include "lluicolor.h" +#include "llstyle.h" /// /// LLUrlMatch describes a single Url that was matched within a string by @@ -75,7 +75,7 @@ public: std::string getIcon() const { return mIcon; } /// Return the color to render the displayed text - LLUIColor getColor() const { return mColor; } + LLStyle::Params getStyle() const { return mStyle; } /// Return the name of a XUI file containing the context menu items std::string getMenuName() const { return mMenuName; } @@ -89,7 +89,7 @@ public: /// Change the contents of this match object (used by LLUrlRegistry) void setValues(U32 start, U32 end, const std::string &url, const std::string &label, const std::string &tooltip, const std::string &icon, - const LLUIColor& color, const std::string &menu, + const LLStyle::Params& style, const std::string &menu, const std::string &location, bool disabled_link); private: @@ -101,7 +101,7 @@ private: std::string mIcon; std::string mMenuName; std::string mLocation; - LLUIColor mColor; + LLStyle::Params mStyle; bool mDisabledLink; }; diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index 7a866f44c2..f61603545f 100644 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -51,6 +51,11 @@ LLUrlRegistry::LLUrlRegistry() registerUrl(new LLUrlEntrySLURL()); registerUrl(new LLUrlEntryHTTP()); registerUrl(new LLUrlEntryHTTPLabel()); + registerUrl(new LLUrlEntryAgentCompleteName()); + registerUrl(new LLUrlEntryAgentDisplayName()); + registerUrl(new LLUrlEntryAgentUserName()); + // LLUrlEntryAgent*Name must appear before LLUrlEntryAgent since + // LLUrlEntryAgent is a less specific (catchall for agent urls) registerUrl(new LLUrlEntryAgent()); registerUrl(new LLUrlEntryGroup()); registerUrl(new LLUrlEntryParcel()); @@ -185,7 +190,7 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL match_entry->getLabel(url, cb), match_entry->getTooltip(url), match_entry->getIcon(url), - match_entry->getColor(), + match_entry->getStyle(), match_entry->getMenuName(), match_entry->getLocation(url), match_entry->isLinkDisabled()); @@ -219,7 +224,7 @@ bool LLUrlRegistry::findUrl(const LLWString &text, LLUrlMatch &match, const LLUr match.getLabel(), match.getTooltip(), match.getIcon(), - match.getColor(), + match.getStyle(), match.getMenuName(), match.getLocation(), match.isLinkDisabled()); diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp index e984f5cf81..5c57ac786e 100644 --- a/indra/llui/tests/llurlentry_stub.cpp +++ b/indra/llui/tests/llurlentry_stub.cpp @@ -79,3 +79,106 @@ std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil:: { return std::string(); } + +// +// Stub implementation for LLStyle::Params::Params +// + +LLStyle::Params::Params() +{ +} + +// +// Stub implementations for various LLInitParam classes +// + +namespace LLInitParam +{ + BaseBlock::BaseBlock() {} + BaseBlock::~BaseBlock() {} + Param::Param(BaseBlock* enclosing_block) + : mIsProvided(false) + { + const U8* my_addr = reinterpret_cast(this); + const U8* block_addr = reinterpret_cast(enclosing_block); + mEnclosingBlockOffset = (U16)(my_addr - block_addr); + } + void BaseBlock::setLastChangedParam(const Param& last_param, bool user_provided) {} + + void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptor& in_param, const char* char_name){} + param_handle_t BaseBlock::getHandleFromParam(const Param* param) const {return 0;} + + void BaseBlock::init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size) + { + mBlockDescriptor = &descriptor; + descriptor.mCurrentBlockPtr = this; + } + bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack){ return true; } + bool BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const { return true; } + bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack) const { return true; } + bool BaseBlock::merge(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) { return true; } + bool BaseBlock::validateBlock(bool emit_errors) const { return true; } + + TypedParam::TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) + : super_t(descriptor, name, value, func, min_count, max_count) + {} + + void TypedParam::setValueFromBlock() const + {} + + void TypedParam::setBlockFromValue() + {} + + void TypeValues::declareValues() + {} + + bool ParamCompare::equals(const LLFontGL* a, const LLFontGL* b) + { + return false; + } + + TypedParam::TypedParam(BlockDescriptor& descriptor, const char* _name, const LLFontGL*const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) + : super_t(descriptor, _name, value, func, min_count, max_count) + {} + + void TypedParam::setValueFromBlock() const + {} + + void TypedParam::setBlockFromValue() + {} + + void TypeValues::declareValues() + {} + + void TypeValues::declareValues() + {} + + void TypeValues::declareValues() + {} + + void TypedParam::setValueFromBlock() const + {} + + void TypedParam::setBlockFromValue() + {} + + + bool ParamCompare::equals( + LLUIImage* const &a, + LLUIImage* const &b) + { + return false; + } + + bool ParamCompare::equals(const LLUIColor &a, const LLUIColor &b) + { + return false; + } + +} + +//static +LLFontGL* LLFontGL::getFontDefault() +{ + return NULL; +} diff --git a/indra/llui/tests/llurlmatch_test.cpp b/indra/llui/tests/llurlmatch_test.cpp index 24a32de268..ab5770dbf2 100644 --- a/indra/llui/tests/llurlmatch_test.cpp +++ b/indra/llui/tests/llurlmatch_test.cpp @@ -23,11 +23,111 @@ #include "../llurlmatch.h" #include "lltut.h" -// link seam +// link seams + LLUIColor::LLUIColor() : mColorPtr(NULL) {} +LLStyle::Params::Params() +{ +} + +namespace LLInitParam +{ + BaseBlock::BaseBlock() {} + BaseBlock::~BaseBlock() {} + + void BaseBlock::setLastChangedParam(const Param& last_param, bool user_provided) {} + + void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptor& in_param, const char* char_name){} + param_handle_t BaseBlock::getHandleFromParam(const Param* param) const {return 0;} + + void BaseBlock::init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size) + { + mBlockDescriptor = &descriptor; + descriptor.mCurrentBlockPtr = this; + } + + Param::Param(BaseBlock* enclosing_block) + : mIsProvided(false) + { + const U8* my_addr = reinterpret_cast(this); + const U8* block_addr = reinterpret_cast(enclosing_block); + mEnclosingBlockOffset = (U16)(my_addr - block_addr); + } + + bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack){ return true; } + bool BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const { return true; } + bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack) const { return true; } + bool BaseBlock::merge(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) { return true; } + bool BaseBlock::validateBlock(bool emit_errors) const { return true; } + + TypedParam::TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) + : super_t(descriptor, name, value, func, min_count, max_count) + {} + + void TypedParam::setValueFromBlock() const + {} + + void TypedParam::setBlockFromValue() + {} + + void TypeValues::declareValues() + {} + + bool ParamCompare::equals(const LLFontGL* a, const LLFontGL* b) + { + return false; + } + + TypedParam::TypedParam(BlockDescriptor& descriptor, const char* _name, const LLFontGL*const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) + : super_t(descriptor, _name, value, func, min_count, max_count) + {} + + void TypedParam::setValueFromBlock() const + {} + + void TypedParam::setBlockFromValue() + {} + + void TypeValues::declareValues() + {} + + void TypeValues::declareValues() + {} + + void TypeValues::declareValues() + {} + + void TypedParam::setValueFromBlock() const + {} + + void TypedParam::setBlockFromValue() + {} + + + bool ParamCompare::equals( + LLUIImage* const &a, + LLUIImage* const &b) + { + return false; + } + + bool ParamCompare::equals(const LLUIColor &a, const LLUIColor &b) + { + return false; + } + +} + +//static +LLFontGL* LLFontGL::getFontDefault() +{ + return NULL; +} + + namespace tut { struct LLUrlMatchData @@ -54,7 +154,7 @@ namespace tut LLUrlMatch match; ensure("empty()", match.empty()); - match.setValues(0, 1, "http://secondlife.com", "Second Life", "", "", LLUIColor(), "", "", false); + match.setValues(0, 1, "http://secondlife.com", "Second Life", "", "", LLStyle::Params(), "", "", false); ensure("! empty()", ! match.empty()); } @@ -67,7 +167,7 @@ namespace tut LLUrlMatch match; ensure_equals("getStart() == 0", match.getStart(), 0); - match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false); + match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", false); ensure_equals("getStart() == 10", match.getStart(), 10); } @@ -80,7 +180,7 @@ namespace tut LLUrlMatch match; ensure_equals("getEnd() == 0", match.getEnd(), 0); - match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false); + match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", false); ensure_equals("getEnd() == 20", match.getEnd(), 20); } @@ -93,10 +193,10 @@ namespace tut LLUrlMatch match; ensure_equals("getUrl() == ''", match.getUrl(), ""); - match.setValues(10, 20, "http://slurl.com/", "", "", "", LLUIColor(), "", "", false); + match.setValues(10, 20, "http://slurl.com/", "", "", "", LLStyle::Params(), "", "", false); ensure_equals("getUrl() == 'http://slurl.com/'", match.getUrl(), "http://slurl.com/"); - match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false); + match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", false); ensure_equals("getUrl() == '' (2)", match.getUrl(), ""); } @@ -109,10 +209,10 @@ namespace tut LLUrlMatch match; ensure_equals("getLabel() == ''", match.getLabel(), ""); - match.setValues(10, 20, "", "Label", "", "", LLUIColor(), "", "", false); + match.setValues(10, 20, "", "Label", "", "", LLStyle::Params(), "", "", false); ensure_equals("getLabel() == 'Label'", match.getLabel(), "Label"); - match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false); + match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", false); ensure_equals("getLabel() == '' (2)", match.getLabel(), ""); } @@ -125,10 +225,10 @@ namespace tut LLUrlMatch match; ensure_equals("getTooltip() == ''", match.getTooltip(), ""); - match.setValues(10, 20, "", "", "Info", "", LLUIColor(), "", "", false); + match.setValues(10, 20, "", "", "Info", "", LLStyle::Params(), "", "", false); ensure_equals("getTooltip() == 'Info'", match.getTooltip(), "Info"); - match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false); + match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", false); ensure_equals("getTooltip() == '' (2)", match.getTooltip(), ""); } @@ -141,10 +241,10 @@ namespace tut LLUrlMatch match; ensure_equals("getIcon() == ''", match.getIcon(), ""); - match.setValues(10, 20, "", "", "", "Icon", LLUIColor(), "", "", false); + match.setValues(10, 20, "", "", "", "Icon", LLStyle::Params(), "", "", false); ensure_equals("getIcon() == 'Icon'", match.getIcon(), "Icon"); - match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false); + match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", false); ensure_equals("getIcon() == '' (2)", match.getIcon(), ""); } @@ -157,10 +257,10 @@ namespace tut LLUrlMatch match; ensure("getMenuName() empty", match.getMenuName().empty()); - match.setValues(10, 20, "", "", "", "Icon", LLUIColor(), "xui_file.xml", "", false); + match.setValues(10, 20, "", "", "", "Icon", LLStyle::Params(), "xui_file.xml", "", false); ensure_equals("getMenuName() == \"xui_file.xml\"", match.getMenuName(), "xui_file.xml"); - match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false); + match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", false); ensure("getMenuName() empty (2)", match.getMenuName().empty()); } @@ -173,10 +273,10 @@ namespace tut LLUrlMatch match; ensure("getLocation() empty", match.getLocation().empty()); - match.setValues(10, 20, "", "", "", "Icon", LLUIColor(), "xui_file.xml", "Paris", false); + match.setValues(10, 20, "", "", "", "Icon", LLStyle::Params(), "xui_file.xml", "Paris", false); ensure_equals("getLocation() == \"Paris\"", match.getLocation(), "Paris"); - match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false); + match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", false); ensure("getLocation() empty (2)", match.getLocation().empty()); } } diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp index 4a5be96a5e..23171d5ff2 100644 --- a/indra/newview/llpanelplaceprofile.cpp +++ b/indra/newview/llpanelplaceprofile.cpp @@ -50,7 +50,7 @@ #include "llagentui.h" #include "llappviewer.h" #include "llcallbacklist.h" -#include "llfloaterbuycurrency.h" +#include "llbuycurrencyhtml.h" #include "llslurl.h" #include "llstatusbar.h" #include "llviewercontrol.h" -- cgit v1.3 From f682c996d28c3841b6709f8fc67ba443bfcd1926 Mon Sep 17 00:00:00 2001 From: Richard Nelson Date: Mon, 24 May 2010 18:29:29 -0700 Subject: DEV-50271 FIX SLURL support for non-clickable display names --- indra/llui/lltextbase.cpp | 33 ++++++++----------- indra/llui/llurlentry.cpp | 64 +++++++++++++++++++++++------------- indra/llui/llurlentry.h | 11 +++---- indra/llui/llurlmatch.cpp | 8 ++--- indra/llui/llurlmatch.h | 6 +--- indra/llui/llurlregistry.cpp | 6 ++-- indra/llui/tests/llurlmatch_test.cpp | 30 ++++++++--------- 7 files changed, 81 insertions(+), 77 deletions(-) (limited to 'indra/llui/llurlregistry.cpp') diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index c93e6c7257..9a07712757 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1582,9 +1582,8 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c start = match.getStart(); end = match.getEnd()+1; - LLStyle::Params link_params = style_params; + LLStyle::Params link_params(style_params); link_params.overwriteFrom(match.getStyle()); - link_params.link_href = match.getUrl(); // output the text before the Url if (start > 0) @@ -1622,26 +1621,20 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c } } - // output the styled Url (unless we've been asked to suppress hyperlinking) - if (match.isLinkDisabled()) - { - appendAndHighlightText(match.getLabel(), prepend_newline, part, style_params); - } - else - { - appendAndHighlightText(match.getLabel(), prepend_newline, part, link_params); + // output the styled Url + appendAndHighlightText(match.getLabel(), prepend_newline, part, link_params); - // set the tooltip for the Url label - if (! match.getTooltip().empty()) - { - segment_set_t::iterator it = getSegIterContaining(getLength()-1); - if (it != mSegments.end()) - { - LLTextSegmentPtr segment = *it; - segment->setToolTip(match.getTooltip()); - } - } + // set the tooltip for the Url label + if (! match.getTooltip().empty()) + { + segment_set_t::iterator it = getSegIterContaining(getLength()-1); + if (it != mSegments.end()) + { + LLTextSegmentPtr segment = *it; + segment->setToolTip(match.getTooltip()); + } } + prepend_newline = false; // move on to the rest of the text after the Url diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 7ba569408a..2dda64c434 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -48,13 +48,8 @@ std::string localize_slapp_label(const std::string& url, const std::string& full_name); -LLUrlEntryBase::LLUrlEntryBase() : - mDisabledLink(false) -{ - mStyle.color = LLUIColorTable::instance().getColor("HTMLLinkColor"); - mStyle.readonly_color = LLUIColorTable::instance().getColor("HTMLLinkColor"); - mStyle.font.style("UNDERLINE"); -} +LLUrlEntryBase::LLUrlEntryBase() +{} LLUrlEntryBase::~LLUrlEntryBase() { @@ -71,6 +66,16 @@ std::string LLUrlEntryBase::getIcon(const std::string &url) return mIcon; } +LLStyle::Params LLUrlEntryBase::getStyle() const +{ + LLStyle::Params style_params; + style_params.color = LLUIColorTable::instance().getColor("HTMLLinkColor"); + style_params.readonly_color = LLUIColorTable::instance().getColor("HTMLLinkColor"); + style_params.font.style = "UNDERLINE"; + return style_params; +} + + std::string LLUrlEntryBase::getIDStringFromUrl(const std::string &url) const { // return the id from a SLURL in the format /app/{cmd}/{id}/about @@ -329,8 +334,6 @@ LLUrlEntryAgent::LLUrlEntryAgent() boost::regex::perl|boost::regex::icase); mMenuName = "menu_url_agent.xml"; mIcon = "Generic_Person"; - mStyle.color = LLUIColorTable::instance().getColor("AgentLinkColor"); - mStyle.readonly_color = LLUIColorTable::instance().getColor("AgentLinkColor"); } // virtual @@ -355,11 +358,8 @@ void LLUrlEntryAgent::callObservers(const std::string &id, void LLUrlEntryAgent::onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name) { - std::string label = av_name.mDisplayName; - if (!av_name.mUsername.empty()) - { - label += " (" + av_name.mUsername + ")"; - } + std::string label = av_name.getCompleteName(); + // received the agent name from the server - tell our observers callObservers(id.asString(), label, mIcon); } @@ -440,6 +440,14 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa } } +LLStyle::Params LLUrlEntryAgent::getStyle() const +{ + LLStyle::Params style_params = LLUrlEntryBase::getStyle(); + style_params.color = LLUIColorTable::instance().getColor("AgentLinkColor"); + style_params.readonly_color = LLUIColorTable::instance().getColor("AgentLinkColor"); + return style_params; +} + std::string localize_slapp_label(const std::string& url, const std::string& full_name) { // customize label string based on agent SLapp suffix @@ -485,10 +493,6 @@ std::string LLUrlEntryAgent::getIcon(const std::string &url) // LLUrlEntryAgentName::LLUrlEntryAgentName() { - mDisabledLink = true; - mStyle.color.setProvided(false); - mStyle.readonly_color.setProvided(false); - mStyle.font.setProvided(false); } // virtual @@ -558,6 +562,11 @@ std::string LLUrlEntryAgentName::getUrl(const std::string &url) const return LLStringUtil::null; } +LLStyle::Params LLUrlEntryAgentName::getStyle() const +{ + return LLStyle::Params(); +} + // // LLUrlEntryAgentCompleteName describes a Second Life agent complete name Url, e.g., // secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/completename @@ -619,8 +628,6 @@ LLUrlEntryGroup::LLUrlEntryGroup() mMenuName = "menu_url_group.xml"; mIcon = "Generic_Group"; mTooltip = LLTrans::getString("TooltipGroupUrl"); - mStyle.color = LLUIColorTable::instance().getColor("GroupLinkColor"); - mStyle.readonly_color = LLUIColorTable::instance().getColor("GroupLinkColor"); } void LLUrlEntryGroup::onGroupNameReceived(const LLUUID& id, @@ -666,6 +673,15 @@ std::string LLUrlEntryGroup::getLabel(const std::string &url, const LLUrlLabelCa } } +LLStyle::Params LLUrlEntryGroup::getStyle() const +{ + LLStyle::Params style_params = LLUrlEntryBase::getStyle(); + style_params.color = LLUIColorTable::instance().getColor("GroupLinkColor"); + style_params.readonly_color = LLUIColorTable::instance().getColor("GroupLinkColor"); + return style_params; +} + + // // LLUrlEntryInventory Describes a Second Life inventory Url, e.g., // secondlife:///app/inventory/0e346d8b-4433-4d66-a6b0-fd37083abc4c/select @@ -953,7 +969,6 @@ LLUrlEntryNoLink::LLUrlEntryNoLink() { mPattern = boost::regex("[^<]*", boost::regex::perl|boost::regex::icase); - mDisabledLink = true; } std::string LLUrlEntryNoLink::getUrl(const std::string &url) const @@ -967,6 +982,12 @@ std::string LLUrlEntryNoLink::getLabel(const std::string &url, const LLUrlLabelC return getUrl(url); } +LLStyle::Params LLUrlEntryNoLink::getStyle() const +{ + return LLStyle::Params(); +} + + // // LLUrlEntryIcon describes an icon with ... tags // @@ -974,7 +995,6 @@ LLUrlEntryIcon::LLUrlEntryIcon() { mPattern = boost::regex("\\s*([^<]*)?\\s*", boost::regex::perl|boost::regex::icase); - mDisabledLink = true; } std::string LLUrlEntryIcon::getUrl(const std::string &url) const diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index 21d4c29b2b..cd93d1ac41 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -84,7 +84,7 @@ public: virtual std::string getIcon(const std::string &url); /// Return the style to render the displayed text - LLStyle::Params getStyle() const { return mStyle; } + virtual LLStyle::Params getStyle() const; /// Given a matched Url, return a tooltip string for the hyperlink virtual std::string getTooltip(const std::string &string) const { return mTooltip; } @@ -95,9 +95,6 @@ public: /// Return the name of a SL location described by this Url, if any virtual std::string getLocation(const std::string &url) const { return ""; } - /// is this a match for a URL that should not be hyperlinked? - bool isLinkDisabled() const { return mDisabledLink; } - protected: std::string getIDStringFromUrl(const std::string &url) const; std::string escapeUrl(const std::string &url) const; @@ -116,9 +113,7 @@ protected: std::string mIcon; std::string mMenuName; std::string mTooltip; - LLStyle::Params mStyle; std::multimap mObservers; - bool mDisabledLink; }; /// @@ -174,6 +169,7 @@ public: /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); /*virtual*/ std::string getIcon(const std::string &url); /*virtual*/ std::string getTooltip(const std::string &string) const; + /*virtual*/ LLStyle::Params getStyle() const; protected: /*virtual*/ void callObservers(const std::string &id, const std::string &label, const std::string& icon); private: @@ -191,6 +187,7 @@ public: LLUrlEntryAgentName(); /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); /*virtual*/ std::string getUrl(const std::string &string) const; + /*virtual*/ LLStyle::Params getStyle() const; protected: /*virtual*/ void callObservers(const std::string &id, const std::string &label, const std::string& icon); // override this to pull out relevant name fields @@ -248,6 +245,7 @@ class LLUrlEntryGroup : public LLUrlEntryBase public: LLUrlEntryGroup(); /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); + /*virtual*/ LLStyle::Params getStyle() const; private: void onGroupNameReceived(const LLUUID& id, const std::string& name, bool is_group); }; @@ -357,6 +355,7 @@ public: LLUrlEntryNoLink(); /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); /*virtual*/ std::string getUrl(const std::string &string) const; + /*virtual*/ LLStyle::Params getStyle() const; }; /// diff --git a/indra/llui/llurlmatch.cpp b/indra/llui/llurlmatch.cpp index 8a7e2e162b..51fca6d7c0 100644 --- a/indra/llui/llurlmatch.cpp +++ b/indra/llui/llurlmatch.cpp @@ -42,16 +42,14 @@ LLUrlMatch::LLUrlMatch() : mTooltip(""), mIcon(""), mMenuName(""), - mLocation(""), - mDisabledLink(false) + mLocation("") { } void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url, const std::string &label, const std::string &tooltip, const std::string &icon, const LLStyle::Params& style, - const std::string &menu, const std::string &location, - bool disabled_link) + const std::string &menu, const std::string &location) { mStart = start; mEnd = end; @@ -60,7 +58,7 @@ void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url, mTooltip = tooltip; mIcon = icon; mStyle = style; + mStyle.link_href = url; mMenuName = menu; mLocation = location; - mDisabledLink = disabled_link; } diff --git a/indra/llui/llurlmatch.h b/indra/llui/llurlmatch.h index 92a87c3d4c..43bd9da14a 100644 --- a/indra/llui/llurlmatch.h +++ b/indra/llui/llurlmatch.h @@ -83,14 +83,11 @@ public: /// return the SL location that this Url describes, or "" if none. std::string getLocation() const { return mLocation; } - /// is this a match for a URL that should not be hyperlinked? - bool isLinkDisabled() const { return mDisabledLink; } - /// Change the contents of this match object (used by LLUrlRegistry) void setValues(U32 start, U32 end, const std::string &url, const std::string &label, const std::string &tooltip, const std::string &icon, const LLStyle::Params& style, const std::string &menu, - const std::string &location, bool disabled_link); + const std::string &location); private: U32 mStart; @@ -102,7 +99,6 @@ private: std::string mMenuName; std::string mLocation; LLStyle::Params mStyle; - bool mDisabledLink; }; #endif diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index f61603545f..f119233f8f 100644 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -192,8 +192,7 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL match_entry->getIcon(url), match_entry->getStyle(), match_entry->getMenuName(), - match_entry->getLocation(url), - match_entry->isLinkDisabled()); + match_entry->getLocation(url)); return true; } @@ -226,8 +225,7 @@ bool LLUrlRegistry::findUrl(const LLWString &text, LLUrlMatch &match, const LLUr match.getIcon(), match.getStyle(), match.getMenuName(), - match.getLocation(), - match.isLinkDisabled()); + match.getLocation()); return true; } return false; diff --git a/indra/llui/tests/llurlmatch_test.cpp b/indra/llui/tests/llurlmatch_test.cpp index ab5770dbf2..85318196e0 100644 --- a/indra/llui/tests/llurlmatch_test.cpp +++ b/indra/llui/tests/llurlmatch_test.cpp @@ -154,7 +154,7 @@ namespace tut LLUrlMatch match; ensure("empty()", match.empty()); - match.setValues(0, 1, "http://secondlife.com", "Second Life", "", "", LLStyle::Params(), "", "", false); + match.setValues(0, 1, "http://secondlife.com", "Second Life", "", "", LLStyle::Params(), "", ""); ensure("! empty()", ! match.empty()); } @@ -167,7 +167,7 @@ namespace tut LLUrlMatch match; ensure_equals("getStart() == 0", match.getStart(), 0); - match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", false); + match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", ""); ensure_equals("getStart() == 10", match.getStart(), 10); } @@ -180,7 +180,7 @@ namespace tut LLUrlMatch match; ensure_equals("getEnd() == 0", match.getEnd(), 0); - match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", false); + match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", ""); ensure_equals("getEnd() == 20", match.getEnd(), 20); } @@ -193,10 +193,10 @@ namespace tut LLUrlMatch match; ensure_equals("getUrl() == ''", match.getUrl(), ""); - match.setValues(10, 20, "http://slurl.com/", "", "", "", LLStyle::Params(), "", "", false); + match.setValues(10, 20, "http://slurl.com/", "", "", "", LLStyle::Params(), "", ""); ensure_equals("getUrl() == 'http://slurl.com/'", match.getUrl(), "http://slurl.com/"); - match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", false); + match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", ""); ensure_equals("getUrl() == '' (2)", match.getUrl(), ""); } @@ -209,10 +209,10 @@ namespace tut LLUrlMatch match; ensure_equals("getLabel() == ''", match.getLabel(), ""); - match.setValues(10, 20, "", "Label", "", "", LLStyle::Params(), "", "", false); + match.setValues(10, 20, "", "Label", "", "", LLStyle::Params(), "", ""); ensure_equals("getLabel() == 'Label'", match.getLabel(), "Label"); - match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", false); + match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", ""); ensure_equals("getLabel() == '' (2)", match.getLabel(), ""); } @@ -225,10 +225,10 @@ namespace tut LLUrlMatch match; ensure_equals("getTooltip() == ''", match.getTooltip(), ""); - match.setValues(10, 20, "", "", "Info", "", LLStyle::Params(), "", "", false); + match.setValues(10, 20, "", "", "Info", "", LLStyle::Params(), "", ""); ensure_equals("getTooltip() == 'Info'", match.getTooltip(), "Info"); - match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", false); + match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", ""); ensure_equals("getTooltip() == '' (2)", match.getTooltip(), ""); } @@ -241,10 +241,10 @@ namespace tut LLUrlMatch match; ensure_equals("getIcon() == ''", match.getIcon(), ""); - match.setValues(10, 20, "", "", "", "Icon", LLStyle::Params(), "", "", false); + match.setValues(10, 20, "", "", "", "Icon", LLStyle::Params(), "", ""); ensure_equals("getIcon() == 'Icon'", match.getIcon(), "Icon"); - match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", false); + match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", ""); ensure_equals("getIcon() == '' (2)", match.getIcon(), ""); } @@ -257,10 +257,10 @@ namespace tut LLUrlMatch match; ensure("getMenuName() empty", match.getMenuName().empty()); - match.setValues(10, 20, "", "", "", "Icon", LLStyle::Params(), "xui_file.xml", "", false); + match.setValues(10, 20, "", "", "", "Icon", LLStyle::Params(), "xui_file.xml", ""); ensure_equals("getMenuName() == \"xui_file.xml\"", match.getMenuName(), "xui_file.xml"); - match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", false); + match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", ""); ensure("getMenuName() empty (2)", match.getMenuName().empty()); } @@ -273,10 +273,10 @@ namespace tut LLUrlMatch match; ensure("getLocation() empty", match.getLocation().empty()); - match.setValues(10, 20, "", "", "", "Icon", LLStyle::Params(), "xui_file.xml", "Paris", false); + match.setValues(10, 20, "", "", "", "Icon", LLStyle::Params(), "xui_file.xml", "Paris"); ensure_equals("getLocation() == \"Paris\"", match.getLocation(), "Paris"); - match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", false); + match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", ""); ensure("getLocation() empty (2)", match.getLocation().empty()); } } -- cgit v1.3