diff options
| author | Oz Linden <oz@lindenlab.com> | 2010-12-20 09:06:06 -0500 | 
|---|---|---|
| committer | Oz Linden <oz@lindenlab.com> | 2010-12-20 09:06:06 -0500 | 
| commit | 25eef545fd7f6513ae4c590126aef1dc06494f56 (patch) | |
| tree | 68ed170395a66eb78c6de7f77c677c49e56ad971 | |
| parent | b59dad36ba7b6d45c25f596e690df3150d94f1b4 (diff) | |
| parent | 81b5931146d983246621b8606e747472941b6d39 (diff) | |
merge fix for storm-412
| -rw-r--r-- | indra/llui/llurlentry.cpp | 63 | ||||
| -rw-r--r-- | indra/llui/llurlentry.h | 12 | ||||
| -rw-r--r-- | indra/llui/llurlregistry.cpp | 1 | ||||
| -rw-r--r-- | indra/llui/tests/llurlentry_test.cpp | 149 | ||||
| -rw-r--r-- | indra/newview/llinspecttoast.cpp | 11 | ||||
| -rw-r--r-- | indra/newview/lltoastgroupnotifypanel.cpp | 1 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/panel_preferences_advanced.xml | 2 | 
7 files changed, 238 insertions, 1 deletions
| diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index e51f28e2e9..4f7b4be526 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -806,6 +806,69 @@ std::string LLUrlEntryPlace::getLocation(const std::string &url) const  }  // +// LLUrlEntryRegion Describes secondlife:///app/region/REGION_NAME/X/Y/Z URLs, e.g. +// secondlife:///app/region/Ahern/128/128/0 +// +LLUrlEntryRegion::LLUrlEntryRegion() +{ +	mPattern = boost::regex("secondlife:///app/region/[^/\\s]+(/\\d+)?(/\\d+)?(/\\d+)?/?", +							boost::regex::perl|boost::regex::icase); +	mMenuName = "menu_url_slurl.xml"; +	mTooltip = LLTrans::getString("TooltipSLURL"); +} + +std::string LLUrlEntryRegion::getLabel(const std::string &url, const LLUrlLabelCallback &cb) +{ +	// +	// we handle SLURLs in the following formats: +	//   - secondlife:///app/region/Place/X/Y/Z +	//   - secondlife:///app/region/Place/X/Y +	//   - secondlife:///app/region/Place/X +	//   - secondlife:///app/region/Place +	// + +	LLSD path_array = LLURI(url).pathArray(); +	S32 path_parts = path_array.size(); + +	if (path_parts < 3) // no region name +	{ +		llwarns << "Failed to parse url [" << url << "]" << llendl; +		return url; +	} + +	std::string label = unescapeUrl(path_array[2]); // region name + +	if (path_parts > 3) // secondlife:///app/region/Place/X +	{ +		std::string x = path_array[3]; +		label += " (" + x; + +		if (path_parts > 4) // secondlife:///app/region/Place/X/Y +		{ +			std::string y = path_array[4]; +			label += "," + y; + +			if (path_parts > 5) // secondlife:///app/region/Place/X/Y/Z +			{ +				std::string z = path_array[5]; +				label = label + "," + z; +			} +		} + +		label += ")"; +	} + +	return label; +} + +std::string LLUrlEntryRegion::getLocation(const std::string &url) const +{ +	LLSD path_array = LLURI(url).pathArray(); +	std::string region_name = unescapeUrl(path_array[2]); +	return region_name; +} + +//  // LLUrlEntryTeleport Describes a Second Life teleport Url, e.g.,  // secondlife:///app/teleport/Ahern/50/50/50/  // x-grid-location-info://lincoln.lindenlab.com/app/teleport/Ahern/50/50/50/ diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index 43a667c390..1791739061 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -302,6 +302,18 @@ public:  };  /// +/// LLUrlEntryRegion Describes a Second Life location Url, e.g., +/// secondlife:///app/region/Ahern/128/128/0 +/// +class LLUrlEntryRegion : public LLUrlEntryBase +{ +public: +	LLUrlEntryRegion(); +	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); +	/*virtual*/ std::string getLocation(const std::string &url) const; +}; + +///  /// LLUrlEntryTeleport Describes a Second Life teleport Url, e.g.,  /// secondlife:///app/teleport/Ahern/50/50/50/  /// diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index 478b412d5e..523ee5d78c 100644 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -54,6 +54,7 @@ LLUrlRegistry::LLUrlRegistry()  	registerUrl(new LLUrlEntryGroup());  	registerUrl(new LLUrlEntryParcel());  	registerUrl(new LLUrlEntryTeleport()); +	registerUrl(new LLUrlEntryRegion());  	registerUrl(new LLUrlEntryWorldMap());  	registerUrl(new LLUrlEntryObjectIM());  	registerUrl(new LLUrlEntryPlace()); diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp index 59c0826ad7..8f0a48018f 100644 --- a/indra/llui/tests/llurlentry_test.cpp +++ b/indra/llui/tests/llurlentry_test.cpp @@ -103,6 +103,45 @@ namespace tut  		ensure_equals(testname, url, expected);  	} +	void dummyCallback(const std::string &url, const std::string &label, const std::string& icon) +	{ +	} + +	void testLabel(const std::string &testname, LLUrlEntryBase &entry, +				   const char *text, const std::string &expected) +	{ +		boost::regex regex = entry.getPattern(); +		std::string label = ""; +		boost::cmatch result; +		bool found = boost::regex_search(text, result, regex); +		if (found) +		{ +			S32 start = static_cast<U32>(result[0].first - text); +			S32 end = static_cast<U32>(result[0].second - text); +			std::string url = std::string(text+start, end-start); +			label = entry.getLabel(url, boost::bind(dummyCallback, _1, _2, _3)); +		} +		ensure_equals(testname, label, expected); +	} + +	void testLocation(const std::string &testname, LLUrlEntryBase &entry, +					  const char *text, const std::string &expected) +	{ +		boost::regex regex = entry.getPattern(); +		std::string location = ""; +		boost::cmatch result; +		bool found = boost::regex_search(text, result, regex); +		if (found) +		{ +			S32 start = static_cast<U32>(result[0].first - text); +			S32 end = static_cast<U32>(result[0].second - text); +			std::string url = std::string(text+start, end-start); +			location = entry.getLocation(url); +		} +		ensure_equals(testname, location, expected); +	} + +  	template<> template<>  	void object::test<1>()  	{ @@ -697,4 +736,114 @@ namespace tut  				  "<nolink>My Object</nolink>",  				  "My Object");  	} + +	template<> template<> +	void object::test<13>() +	{ +		// +		// test LLUrlEntryRegion - secondlife:///app/region/<location> URLs +		// +		LLUrlEntryRegion url; + +		// Regex tests. +		testRegex("no valid region", url, +				  "secondlife:///app/region/", +				  ""); + +		testRegex("invalid coords", url, +				  "secondlife:///app/region/Korea2/a/b/c", +				  "secondlife:///app/region/Korea2/"); // don't count invalid coords + +		testRegex("Ahern (50,50,50) [1]", url, +				  "secondlife:///app/region/Ahern/50/50/50/", +				  "secondlife:///app/region/Ahern/50/50/50/"); + +		testRegex("Ahern (50,50,50) [2]", url, +				  "XXX secondlife:///app/region/Ahern/50/50/50/ XXX", +				  "secondlife:///app/region/Ahern/50/50/50/"); + +		testRegex("Ahern (50,50,50) [3]", url, +				  "XXX secondlife:///app/region/Ahern/50/50/50 XXX", +				  "secondlife:///app/region/Ahern/50/50/50"); + +		testRegex("Ahern (50,50,50) multicase", url, +				  "XXX secondlife:///app/region/Ahern/50/50/50/ XXX", +				  "secondlife:///app/region/Ahern/50/50/50/"); + +		testRegex("Ahern (50,50) [1]", url, +				  "XXX secondlife:///app/region/Ahern/50/50/ XXX", +				  "secondlife:///app/region/Ahern/50/50/"); + +		testRegex("Ahern (50,50) [2]", url, +				  "XXX secondlife:///app/region/Ahern/50/50 XXX", +				  "secondlife:///app/region/Ahern/50/50"); + +		// DEV-21577: In-world SLURLs containing "(" or ")" are not treated as a hyperlink in chat +		testRegex("Region with brackets", url, +				  "XXX secondlife:///app/region/Burning%20Life%20(Hyper)/27/210/30 XXX", +				  "secondlife:///app/region/Burning%20Life%20(Hyper)/27/210/30"); + +		// DEV-35459: SLURLs and teleport Links not parsed properly +		testRegex("Region with quote", url, +				  "XXX secondlife:///app/region/A'ksha%20Oasis/41/166/701 XXX", +			          "secondlife:///app/region/A%27ksha%20Oasis/41/166/701"); + +		// Rendering tests. +		testLabel("Render /app/region/Ahern/50/50/50/", url, +			"secondlife:///app/region/Ahern/50/50/50/", +			"Ahern (50,50,50)"); + +		testLabel("Render /app/region/Ahern/50/50/50", url, +			"secondlife:///app/region/Ahern/50/50/50", +			"Ahern (50,50,50)"); + +		testLabel("Render /app/region/Ahern/50/50/", url, +			"secondlife:///app/region/Ahern/50/50/", +			"Ahern (50,50)"); + +		testLabel("Render /app/region/Ahern/50/50", url, +			"secondlife:///app/region/Ahern/50/50", +			"Ahern (50,50)"); + +		testLabel("Render /app/region/Ahern/50/", url, +			"secondlife:///app/region/Ahern/50/", +			"Ahern (50)"); + +		testLabel("Render /app/region/Ahern/50", url, +			"secondlife:///app/region/Ahern/50", +			"Ahern (50)"); + +		testLabel("Render /app/region/Ahern/", url, +			"secondlife:///app/region/Ahern/", +			"Ahern"); + +		testLabel("Render /app/region/Ahern/ within context", url, +			"XXX secondlife:///app/region/Ahern/ XXX", +			"Ahern"); + +		testLabel("Render /app/region/Ahern", url, +			"secondlife:///app/region/Ahern", +			"Ahern"); + +		testLabel("Render /app/region/Ahern within context", url, +			"XXX secondlife:///app/region/Ahern XXX", +			"Ahern"); + +		testLabel("Render /app/region/Product%20Engine/", url, +			"secondlife:///app/region/Product%20Engine/", +			"Product Engine"); + +		testLabel("Render /app/region/Product%20Engine", url, +			"secondlife:///app/region/Product%20Engine", +			"Product Engine"); + +		// Location parsing texts. +		testLocation("Location /app/region/Ahern/50/50/50/", url, +			"secondlife:///app/region/Ahern/50/50/50/", +			"Ahern"); + +		testLocation("Location /app/region/Product%20Engine", url, +			"secondlife:///app/region/Product%20Engine", +			"Product Engine"); +	}  } diff --git a/indra/newview/llinspecttoast.cpp b/indra/newview/llinspecttoast.cpp index 58b3f0309f..d7b82667d1 100644 --- a/indra/newview/llinspecttoast.cpp +++ b/indra/newview/llinspecttoast.cpp @@ -46,6 +46,7 @@ public:  	virtual ~LLInspectToast();  	/*virtual*/ void onOpen(const LLSD& notification_id); +	/*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask);  private:  	void onToastDestroy(LLToast * toast); @@ -73,6 +74,7 @@ LLInspectToast::~LLInspectToast()  	LLTransientFloaterMgr::getInstance()->removeControlView(this);  } +// virtual  void LLInspectToast::onOpen(const LLSD& notification_id)  {  	LLInspect::onOpen(notification_id); @@ -103,6 +105,15 @@ void LLInspectToast::onOpen(const LLSD& notification_id)  	LLUI::positionViewNearMouse(this);  } +// virtual +BOOL LLInspectToast::handleToolTip(S32 x, S32 y, MASK mask) +{ +	// We don't like the way LLInspect handles tooltips +	// (black tooltips look weird), +	// so force using the default implementation (STORM-511). +	return LLFloater::handleToolTip(x, y, mask); +} +  void LLInspectToast::onToastDestroy(LLToast * toast)  {  	closeFloater(false); diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp index 563c27c4d7..75178a6ef8 100644 --- a/indra/newview/lltoastgroupnotifypanel.cpp +++ b/indra/newview/lltoastgroupnotifypanel.cpp @@ -77,6 +77,7 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification  	from << from_name << "/" << groupData.mName;  	LLTextBox* pTitleText = getChild<LLTextBox>("title");  	pTitleText->setValue(from.str()); +	pTitleText->setToolTip(from.str());  	//message subject  	const std::string& subject = payload["subject"].asString(); diff --git a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml index d6e4c56113..37aab059a9 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml @@ -82,7 +82,7 @@       control_name="AllowMultipleViewers"       follows="top|left"       height="15" -     label="Allow Multiple Viewer" +     label="Allow Multiple Viewers"       layout="topleft"       left="30"       name="allow_multiple_viewer_check" | 
