diff options
Diffstat (limited to 'indra')
145 files changed, 2270 insertions, 1366 deletions
| diff --git a/indra/llcommon/llformat.cpp b/indra/llcommon/llformat.cpp index cf509bee14..689f649d0a 100644 --- a/indra/llcommon/llformat.cpp +++ b/indra/llcommon/llformat.cpp @@ -37,16 +37,40 @@  #include <cstdarg> -std::string llformat(const char *fmt, ...) +// common used function with va_list argument +// wrapper for vsnprintf to be called from llformatXXX functions. +static void va_format(std::string& out, const char *fmt, va_list va)  {  	char tstr[1024];	/* Flawfinder: ignore */ -	va_list va; -	va_start(va, fmt);  #if LL_WINDOWS  	_vsnprintf(tstr, 1024, fmt, va);  #else  	vsnprintf(tstr, 1024, fmt, va);	/* Flawfinder: ignore */  #endif +	out.assign(tstr); +} + +std::string llformat(const char *fmt, ...) +{ +	std::string res; +	va_list va; +	va_start(va, fmt); +	va_format(res, fmt, va);  	va_end(va); -	return std::string(tstr); +	return res; +} + +std::string llformat_to_utf8(const char *fmt, ...) +{ +	std::string res; +	va_list va; +	va_start(va, fmt); +	va_format(res, fmt, va); +	va_end(va); + +#if LL_WINDOWS +	// made converting to utf8. See EXT-8318. +	res = ll_convert_string_to_utf8_string(res); +#endif +	return res;  } diff --git a/indra/llcommon/llformat.h b/indra/llcommon/llformat.h index dc64edb26d..17d8b4a8ad 100644 --- a/indra/llcommon/llformat.h +++ b/indra/llcommon/llformat.h @@ -42,4 +42,8 @@  std::string LL_COMMON_API llformat(const char *fmt, ...); +// the same version as above but ensures that returned string is in utf8 on windows +// to enable correct converting utf8_to_wstring. +std::string LL_COMMON_API llformat_to_utf8(const char *fmt, ...); +  #endif // LL_LLFORMAT_H diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index 1561bda201..2693c0e22b 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -633,14 +633,14 @@ namespace snprintf_hack  	}  } -std::string ll_convert_wide_to_string(const wchar_t* in) +std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page)  {  	std::string out;  	if(in)  	{  		int len_in = wcslen(in);  		int len_out = WideCharToMultiByte( -			CP_ACP, +			code_page,  			0,  			in,  			len_in, @@ -655,7 +655,7 @@ std::string ll_convert_wide_to_string(const wchar_t* in)  		if(pout)  		{  			WideCharToMultiByte( -				CP_ACP, +				code_page,  				0,  				in,  				len_in, @@ -669,6 +669,38 @@ std::string ll_convert_wide_to_string(const wchar_t* in)  	}  	return out;  } + +wchar_t* ll_convert_string_to_wide(const std::string& in, unsigned int code_page) +{ +	// From review: +	// We can preallocate a wide char buffer that is the same length (in wchar_t elements) as the utf8 input, +	// plus one for a null terminator, and be guaranteed to not overflow. + +	//	Normally, I'd call that sort of thing premature optimization, +	// but we *are* seeing string operations taking a bunch of time, especially when constructing widgets. +//	int output_str_len = MultiByteToWideChar(code_page, 0, in.c_str(), in.length(), NULL, 0); + +	// reserve place to NULL terminator +	int output_str_len = in.length(); +	wchar_t* w_out = new wchar_t[output_str_len + 1]; + +	memset(w_out, 0, output_str_len + 1); +	int real_output_str_len = MultiByteToWideChar (code_page, 0, in.c_str(), in.length(), w_out, output_str_len); + +	//looks like MultiByteToWideChar didn't add null terminator to converted string, see EXT-4858. +	w_out[real_output_str_len] = 0; + +	return w_out; +} + +std::string ll_convert_string_to_utf8_string(const std::string& in) +{ +	wchar_t* w_mesg = ll_convert_string_to_wide(in, CP_ACP); +	std::string out_utf8(ll_convert_wide_to_string(w_mesg, CP_UTF8)); +	delete[] w_mesg; + +	return out_utf8; +}  #endif // LL_WINDOWS  long LLStringOps::sPacificTimeOffset = 0; diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index 8071c8aa2d..41fac0f8cc 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -564,7 +564,20 @@ using snprintf_hack::snprintf;   *   * This replaces the unsafe W2A macro from ATL.   */ -LL_COMMON_API std::string ll_convert_wide_to_string(const wchar_t* in); +LL_COMMON_API std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page); + +/** + * Converts a string to wide string. + * + * It will allocate memory for result string with "new []". Don't forget to release it with "delete []". + */ +LL_COMMON_API wchar_t* ll_convert_string_to_wide(const std::string& in, unsigned int code_page); + +/** + * Converts incoming string into urf8 string + * + */ +LL_COMMON_API std::string ll_convert_string_to_utf8_string(const std::string& in);  //@}  #endif // LL_WINDOWS diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 36874a5d48..ac50411de8 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -364,13 +364,6 @@ U32 LLCurl::Easy::report(CURLcode code)  		responseCode = 499;  		responseReason = strerror(code) + " : " + mErrorBuffer;  	} -		 -	if(responseCode >= 300 && responseCode < 400) //redirect -	{ -		char new_url[512] ; -		curl_easy_getinfo(mCurlEasyHandle, CURLINFO_REDIRECT_URL, new_url); -		responseReason = new_url ; //get the new URL. -	}  	if (mResponder)  	{	 @@ -469,6 +462,13 @@ void LLCurl::Easy::prepRequest(const std::string& url,  	setopt(CURLOPT_HEADERFUNCTION, (void*)&curlHeaderCallback);  	setopt(CURLOPT_HEADERDATA, (void*)this); +	// Allow up to five redirects +	if(responder && responder->followRedir()) +	{ +		setopt(CURLOPT_FOLLOWLOCATION, 1); +		setopt(CURLOPT_MAXREDIRS, MAX_REDIRECTS); +	} +  	setErrorBuffer();  	setCA(); @@ -1061,3 +1061,4 @@ void LLCurl::cleanupClass()  	curl_global_cleanup();  } +const unsigned int LLCurl::MAX_REDIRECTS = 5; diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index b6a637ae5b..20ca87c87b 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -123,6 +123,11 @@ public:  			// Used internally to set the url for debugging later.  			void setURL(const std::string& url); +			virtual bool followRedir()  +			{ +				return false; +			} +  	public: /* but not really -- don't touch this */  		U32 mReferenceCount; @@ -182,6 +187,7 @@ public:  private:  	static std::string sCAPath;  	static std::string sCAFile; +	static const unsigned int MAX_REDIRECTS;  };  namespace boost diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index a86bbbffff..0a16b5120a 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -259,10 +259,10 @@ F32 LLFontFreetype::getXAdvance(llwchar wch) const  	}  	else  	{ -		gi = get_if_there(mCharGlyphInfoMap, (llwchar)0, (LLFontGlyphInfo*)NULL); -		if (gi) +		char_glyph_info_map_t::iterator found_it = mCharGlyphInfoMap.find((llwchar)0); +		if (found_it != mCharGlyphInfoMap.end())  		{ -			return gi->mXAdvance; +			return found_it->second->mXAdvance;  		}  	} diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h index f60d09316d..4b4a0bb189 100644 --- a/indra/llrender/llfontfreetype.h +++ b/indra/llrender/llfontfreetype.h @@ -33,7 +33,7 @@  #ifndef LL_LLFONTFREETYPE_H  #define LL_LLFONTFREETYPE_H -#include <map> +#include <boost/unordered_map.hpp>  #include "llpointer.h"  #include "llstl.h" @@ -170,7 +170,7 @@ private:  	BOOL mValid; -	typedef std::map<llwchar, LLFontGlyphInfo*> char_glyph_info_map_t; +	typedef boost::unordered_map<llwchar, LLFontGlyphInfo*> char_glyph_info_map_t;  	mutable char_glyph_info_map_t mCharGlyphInfoMap; // Information about glyph location in bitmap  	mutable LLPointer<LLFontBitmapCache> mFontBitmapCachep; diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 6eb5e0eff4..2240a2146c 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -181,12 +181,17 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons  	gGL.loadUIIdentity(); -	gGL.translateUI(floorf(sCurOrigin.mX*sScaleX), floorf(sCurOrigin.mY*sScaleY), sCurOrigin.mZ); +	//gGL.translateUI(floorf(sCurOrigin.mX*sScaleX), floorf(sCurOrigin.mY*sScaleY), sCurOrigin.mZ);  	// this code snaps the text origin to a pixel grid to start with -	F32 pixel_offset_x = llround((F32)sCurOrigin.mX) - (sCurOrigin.mX); -	F32 pixel_offset_y = llround((F32)sCurOrigin.mY) - (sCurOrigin.mY); -	gGL.translateUI(-pixel_offset_x, -pixel_offset_y, 0.f); +	//F32 pixel_offset_x = llround((F32)sCurOrigin.mX) - (sCurOrigin.mX); +	//F32 pixel_offset_y = llround((F32)sCurOrigin.mY) - (sCurOrigin.mY); +	//gGL.translateUI(-pixel_offset_x, -pixel_offset_y, 0.f); + +	LLVector2 origin(floorf(sCurOrigin.mX*sScaleX), floorf(sCurOrigin.mY*sScaleY)); +	// snap the text origin to a pixel grid to start with +	origin.mV[VX] -= llround((F32)sCurOrigin.mX) - (sCurOrigin.mX); +	origin.mV[VY] -= llround((F32)sCurOrigin.mY) - (sCurOrigin.mY);  	LLFastTimer t(FTM_RENDER_FONTS); @@ -210,8 +215,8 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons   	// Not guaranteed to be set correctly  	gGL.setSceneBlendType(LLRender::BT_ALPHA); -	cur_x = ((F32)x * sScaleX); -	cur_y = ((F32)y * sScaleY); +	cur_x = ((F32)x * sScaleX) + origin.mV[VX]; +	cur_y = ((F32)y * sScaleY) + origin.mV[VY];  	// Offset y by vertical alignment.  	switch (valign) @@ -276,6 +281,12 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons  	const LLFontGlyphInfo* next_glyph = NULL; +	const S32 GLYPH_BATCH_SIZE = 30; +	LLVector3 vertices[GLYPH_BATCH_SIZE * 4]; +	LLVector2 uvs[GLYPH_BATCH_SIZE * 4]; +	LLColor4U colors[GLYPH_BATCH_SIZE * 4]; + +	S32 glyph_count = 0;  	for (i = begin_offset; i < begin_offset + length; i++)  	{  		llwchar wch = wstr[i]; @@ -313,7 +324,18 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons  				    llround(cur_render_x + (F32)fgi->mXBearing) + (F32)fgi->mWidth,  				    llround(cur_render_y + (F32)fgi->mYBearing) - (F32)fgi->mHeight); -		drawGlyph(screen_rect, uv_rect, color, style_to_add, shadow, drop_shadow_strength); +		if (glyph_count >= GLYPH_BATCH_SIZE) +		{ +			gGL.begin(LLRender::QUADS); +			{ +				gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 4); +			} +			gGL.end(); + +			glyph_count = 0; +		} + +		drawGlyph(glyph_count, vertices, uvs, colors, screen_rect, uv_rect, color, style_to_add, shadow, drop_shadow_strength);  		chars_drawn++;  		cur_x += fgi->mXAdvance; @@ -338,11 +360,19 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons  		cur_render_y = cur_y;  	} +	gGL.begin(LLRender::QUADS); +	{ +		gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 4); +	} +	gGL.end(); + +  	if (right_x)  	{ -		*right_x = cur_x / sScaleX; +		*right_x = (cur_x - origin.mV[VX]) / sScaleX;  	} +	//FIXME: add underline as glyph?  	if (style_to_add & UNDERLINE)  	{  		F32 descender = mFontFreetype->getDescenderHeight(); @@ -1091,95 +1121,96 @@ LLFontGL &LLFontGL::operator=(const LLFontGL &source)  	return *this;  } -void LLFontGL::renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F32 slant_amt) const +void LLFontGL::renderQuad(LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, F32 slant_amt) const  { -	gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop); -	gGL.vertex2f(llfont_round_x(screen_rect.mRight),  -				llfont_round_y(screen_rect.mTop)); - -	gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop); -	gGL.vertex2f(llfont_round_x(screen_rect.mLeft),  -				llfont_round_y(screen_rect.mTop)); - -	gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom); -	gGL.vertex2f(llfont_round_x(screen_rect.mLeft + slant_amt),  -				llfont_round_y(screen_rect.mBottom)); - -	gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom); -	gGL.vertex2f(llfont_round_x(screen_rect.mRight + slant_amt),  -				llfont_round_y(screen_rect.mBottom)); +	S32 index = 0; + +	vertex_out[index] = LLVector3(llfont_round_x(screen_rect.mRight), llfont_round_y(screen_rect.mTop), 0.f); +	uv_out[index] = LLVector2(uv_rect.mRight, uv_rect.mTop); +	colors_out[index] = color; +	index++; + +	vertex_out[index] = LLVector3(llfont_round_x(screen_rect.mLeft), llfont_round_y(screen_rect.mTop), 0.f); +	uv_out[index] = LLVector2(uv_rect.mLeft, uv_rect.mTop); +	colors_out[index] = color; +	index++; + +	vertex_out[index] = LLVector3(llfont_round_x(screen_rect.mLeft), llfont_round_y(screen_rect.mBottom), 0.f); +	uv_out[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom); +	colors_out[index] = color; +	index++; + +	vertex_out[index] = LLVector3(llfont_round_x(screen_rect.mRight), llfont_round_y(screen_rect.mBottom), 0.f); +	uv_out[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom); +	colors_out[index] = color;  } -void LLFontGL::drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, ShadowType shadow, F32 drop_shadow_strength) const +//FIXME: do colors out as well +void LLFontGL::drawGlyph(S32& glyph_count, LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, U8 style, ShadowType shadow, F32 drop_shadow_strength) const  {  	F32 slant_offset;  	slant_offset = ((style & ITALIC) ? ( -mFontFreetype->getAscenderHeight() * 0.2f) : 0.f); -	gGL.begin(LLRender::QUADS); +	//FIXME: bold and drop shadow are mutually exclusive only for convenience +	//Allow both when we need them. +	if (style & BOLD)  	{ -		//FIXME: bold and drop shadow are mutually exclusive only for convenience -		//Allow both when we need them. -		if (style & BOLD) +		for (S32 pass = 0; pass < 2; pass++)  		{ -			gGL.color4fv(color.mV); -			for (S32 pass = 0; pass < 2; pass++) -			{ -				LLRectf screen_rect_offset = screen_rect; +			LLRectf screen_rect_offset = screen_rect; -				screen_rect_offset.translate((F32)(pass * BOLD_OFFSET), 0.f); -				renderQuad(screen_rect_offset, uv_rect, slant_offset); -			} +			screen_rect_offset.translate((F32)(pass * BOLD_OFFSET), 0.f); +			renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect_offset, uv_rect, color, slant_offset); +			glyph_count++;  		} -		else if (shadow == DROP_SHADOW_SOFT) +	} +	else if (shadow == DROP_SHADOW_SOFT) +	{ +		LLColor4U shadow_color = LLFontGL::sShadowColor; +		shadow_color.mV[VALPHA] = U8(color.mV[VALPHA] * drop_shadow_strength * DROP_SHADOW_SOFT_STRENGTH); +		for (S32 pass = 0; pass < 5; pass++)  		{ -			LLColor4 shadow_color = LLFontGL::sShadowColor; -			shadow_color.mV[VALPHA] = color.mV[VALPHA] * drop_shadow_strength * DROP_SHADOW_SOFT_STRENGTH; -			gGL.color4fv(shadow_color.mV); -			for (S32 pass = 0; pass < 5; pass++) -			{ -				LLRectf screen_rect_offset = screen_rect; +			LLRectf screen_rect_offset = screen_rect; -				switch(pass) -				{ -				case 0: -					screen_rect_offset.translate(-1.f, -1.f); -					break; -				case 1: -					screen_rect_offset.translate(1.f, -1.f); -					break; -				case 2: -					screen_rect_offset.translate(1.f, 1.f); -					break; -				case 3: -					screen_rect_offset.translate(-1.f, 1.f); -					break; -				case 4: -					screen_rect_offset.translate(0, -2.f); -					break; -				} -			 -				renderQuad(screen_rect_offset, uv_rect, slant_offset); +			switch(pass) +			{ +			case 0: +				screen_rect_offset.translate(-1.f, -1.f); +				break; +			case 1: +				screen_rect_offset.translate(1.f, -1.f); +				break; +			case 2: +				screen_rect_offset.translate(1.f, 1.f); +				break; +			case 3: +				screen_rect_offset.translate(-1.f, 1.f); +				break; +			case 4: +				screen_rect_offset.translate(0, -2.f); +				break;  			} -			gGL.color4fv(color.mV); -			renderQuad(screen_rect, uv_rect, slant_offset); -		} -		else if (shadow == DROP_SHADOW) -		{ -			LLColor4 shadow_color = LLFontGL::sShadowColor; -			shadow_color.mV[VALPHA] = color.mV[VALPHA] * drop_shadow_strength; -			gGL.color4fv(shadow_color.mV); -			LLRectf screen_rect_shadow = screen_rect; -			screen_rect_shadow.translate(1.f, -1.f); -			renderQuad(screen_rect_shadow, uv_rect, slant_offset); -			gGL.color4fv(color.mV); -			renderQuad(screen_rect, uv_rect, slant_offset); -		} -		else // normal rendering -		{ -			gGL.color4fv(color.mV); -			renderQuad(screen_rect, uv_rect, slant_offset); +		 +			renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect_offset, uv_rect, shadow_color, slant_offset); +			glyph_count++;  		} - +		renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect, uv_rect, color, slant_offset); +		glyph_count++; +	} +	else if (shadow == DROP_SHADOW) +	{ +		LLColor4 shadow_color = LLFontGL::sShadowColor; +		shadow_color.mV[VALPHA] = color.mV[VALPHA] * drop_shadow_strength; +		LLRectf screen_rect_shadow = screen_rect; +		screen_rect_shadow.translate(1.f, -1.f); +		renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect_shadow, uv_rect, shadow_color, slant_offset); +		glyph_count++; +		renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect, uv_rect, color, slant_offset); +		glyph_count++; +	} +	else // normal rendering +	{ +		renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect, uv_rect, color, slant_offset); +		glyph_count++;  	} -	gGL.end();  } diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h index f29ac5165c..8bc45fbf74 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -217,8 +217,8 @@ private:  	LLFontDescriptor mFontDescriptor;  	LLPointer<LLFontFreetype> mFontFreetype; -	void renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F32 slant_amt) const; -	void drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, ShadowType shadow, F32 drop_shadow_fade) const; +	void renderQuad(LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, F32 slant_amt) const; +	void drawGlyph(S32& glyph_count, LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, U8 style, ShadowType shadow, F32 drop_shadow_fade) const;  	// Registry holds all instantiated fonts.  	static LLFontRegistry* sFontRegistry; diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index e22f8d2ddc..1a48c8a06c 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -109,11 +109,20 @@ void LLImageGL::checkTexSize(bool forced) const  {  	if ((forced || gDebugGL) && mTarget == GL_TEXTURE_2D)  	{ +		{ +			//check viewport +			GLint vp[4] ; +			glGetIntegerv(GL_VIEWPORT, vp) ; +			llcallstacks << "viewport: " << vp[0] << " : " << vp[1] << " : " << vp[2] << " : " << vp[3] << llcallstacksendl ; +		} +  		GLint texname;  		glGetIntegerv(GL_TEXTURE_BINDING_2D, &texname);  		BOOL error = FALSE;  		if (texname != mTexName)  		{ +			llinfos << "Bound: " << texname << " Should bind: " << mTexName << " Default: " << LLImageGL::sDefaultGLTexture->getTexName() << llendl; +  			error = TRUE;  			if (gDebugSession)  			{ diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 5597b23c69..64238b2008 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -851,9 +851,9 @@ void LLRender::translateUI(F32 x, F32 y, F32 z)  		llerrs << "Need to push a UI translation frame before offsetting" << llendl;  	} -	mUIOffset.front().mV[0] += x; -	mUIOffset.front().mV[1] += y; -	mUIOffset.front().mV[2] += z; +	mUIOffset.back().mV[0] += x; +	mUIOffset.back().mV[1] += y; +	mUIOffset.back().mV[2] += z;  }  void LLRender::scaleUI(F32 x, F32 y, F32 z) @@ -863,27 +863,27 @@ void LLRender::scaleUI(F32 x, F32 y, F32 z)  		llerrs << "Need to push a UI transformation frame before scaling." << llendl;  	} -	mUIScale.front().scaleVec(LLVector3(x,y,z)); +	mUIScale.back().scaleVec(LLVector3(x,y,z));  }  void LLRender::pushUIMatrix()  {  	if (mUIOffset.empty())  	{ -		mUIOffset.push_front(LLVector3(0,0,0)); +		mUIOffset.push_back(LLVector3(0,0,0));  	}  	else  	{ -		mUIOffset.push_front(mUIOffset.front()); +		mUIOffset.push_back(mUIOffset.back());  	}  	if (mUIScale.empty())  	{ -		mUIScale.push_front(LLVector3(1,1,1)); +		mUIScale.push_back(LLVector3(1,1,1));  	}  	else  	{ -		mUIScale.push_front(mUIScale.front()); +		mUIScale.push_back(mUIScale.back());  	}  } @@ -893,8 +893,8 @@ void LLRender::popUIMatrix()  	{  		llerrs << "UI offset stack blown." << llendl;  	} -	mUIOffset.pop_front(); -	mUIScale.pop_front(); +	mUIOffset.pop_back(); +	mUIScale.pop_back();  }  LLVector3 LLRender::getUITranslation() @@ -903,7 +903,7 @@ LLVector3 LLRender::getUITranslation()  	{  		llerrs << "UI offset stack empty." << llendl;  	} -	return mUIOffset.front(); +	return mUIOffset.back();  }  LLVector3 LLRender::getUIScale() @@ -912,7 +912,7 @@ LLVector3 LLRender::getUIScale()  	{  		llerrs << "UI scale stack empty." << llendl;  	} -	return mUIScale.front(); +	return mUIScale.back();  } @@ -922,8 +922,8 @@ void LLRender::loadUIIdentity()  	{  		llerrs << "Need to push UI translation frame before clearing offset." << llendl;  	} -	mUIOffset.front().setVec(0,0,0); -	mUIScale.front().setVec(1,1,1); +	mUIOffset.back().setVec(0,0,0); +	mUIScale.back().setVec(1,1,1);  }  void LLRender::setColorMask(bool writeColor, bool writeAlpha) @@ -1210,18 +1210,79 @@ void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z)  	}  	else  	{ -		LLVector3 vert = (LLVector3(x,y,z)+mUIOffset.front()).scaledVec(mUIScale.front()); +		LLVector3 vert = (LLVector3(x,y,z)+mUIOffset.back()).scaledVec(mUIScale.back());  		mVerticesp[mCount] = vert;  	}  	mCount++; -	if (mCount < 4096) +	mVerticesp[mCount] = mVerticesp[mCount-1]; +	mColorsp[mCount] = mColorsp[mCount-1]; +	mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; +} + +void LLRender::vertexBatchPreTransformed(LLVector3* verts, S32 vert_count) +{ +	if (mCount + vert_count > 4094)  	{ -		mVerticesp[mCount] = mVerticesp[mCount-1]; -		mColorsp[mCount] = mColorsp[mCount-1]; +		//	llwarns << "GL immediate mode overflow.  Some geometry not drawn." << llendl; +		return; +	} + +	for (S32 i = 0; i < vert_count; i++) +	{ +		mVerticesp[mCount] = verts[i]; + +		mCount++;  		mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; +		mColorsp[mCount] = mColorsp[mCount-1];  	} + +	mVerticesp[mCount] = mVerticesp[mCount-1];  } + +void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 vert_count) +{ +	if (mCount + vert_count > 4094) +	{ +		//	llwarns << "GL immediate mode overflow.  Some geometry not drawn." << llendl; +		return; +	} + +	for (S32 i = 0; i < vert_count; i++) +	{ +		mVerticesp[mCount] = verts[i]; +		mTexcoordsp[mCount] = uvs[i]; + +		mCount++; +		mColorsp[mCount] = mColorsp[mCount-1]; +	} + +	mVerticesp[mCount] = mVerticesp[mCount-1]; +	mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; +} + +void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, LLColor4U* colors, S32 vert_count) +{ +	if (mCount + vert_count > 4094) +	{ +		//	llwarns << "GL immediate mode overflow.  Some geometry not drawn." << llendl; +		return; +	} + +	for (S32 i = 0; i < vert_count; i++) +	{ +		mVerticesp[mCount] = verts[i]; +		mTexcoordsp[mCount] = uvs[i]; +		mColorsp[mCount] = colors[i]; + +		mCount++; +	} + +	mVerticesp[mCount] = mVerticesp[mCount-1]; +	mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; +	mColorsp[mCount] = mColorsp[mCount-1]; +} +  void LLRender::vertex2i(const GLint& x, const GLint& y)  {  	vertex3f((GLfloat) x, (GLfloat) y, 0);	 diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index f6c87aa1db..0fa503182e 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -317,6 +317,10 @@ public:  	void color3fv(const GLfloat* c);  	void color4ubv(const GLubyte* c); +	void vertexBatchPreTransformed(LLVector3* verts, S32 vert_count); +	void vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 vert_count); +	void vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, LLColor4U*, S32 vert_count); +  	void setColorMask(bool writeColor, bool writeAlpha);  	void setColorMask(bool writeColorR, bool writeColorG, bool writeColorB, bool writeAlpha);  	void setSceneBlendType(eBlendType type); @@ -373,8 +377,8 @@ private:  	F32				mMaxAnisotropy; -	std::list<LLVector3> mUIOffset; -	std::list<LLVector3> mUIScale; +	std::vector<LLVector3> mUIOffset; +	std::vector<LLVector3> mUIScale;  }; diff --git a/indra/llui/llaccordionctrl.cpp b/indra/llui/llaccordionctrl.cpp index 673631f99a..c3ef734823 100644 --- a/indra/llui/llaccordionctrl.cpp +++ b/indra/llui/llaccordionctrl.cpp @@ -765,6 +765,17 @@ S32	LLAccordionCtrl::notifyParent(const LLSD& info)  			}  			return 0;  		} +		else if(str_action == "deselect_current") +		{ +			// Reset selection to the currently selected tab. +			if (mSelectedTab) +			{ +				mSelectedTab->setSelected(false); +				mSelectedTab = NULL; +				return 1; +			} +			return 0; +		}  	}  	else if (info.has("scrollToShowRect"))  	{ @@ -811,6 +822,31 @@ void	LLAccordionCtrl::reset		()  		mScrollbar->setDocPos(0);  } +void LLAccordionCtrl::expandDefaultTab() +{ +	if (mAccordionTabs.size() > 0) +	{ +		LLAccordionCtrlTab* tab = mAccordionTabs.front(); + +		if (!tab->getDisplayChildren()) +		{ +			tab->setDisplayChildren(true); +		} + +		for (size_t i = 1; i < mAccordionTabs.size(); ++i) +		{ +			tab = mAccordionTabs[i]; + +			if (tab->getDisplayChildren()) +			{ +				tab->setDisplayChildren(false); +			} +		} + +		arrange(); +	} +} +  void LLAccordionCtrl::sort()  {  	if (!mTabComparator) diff --git a/indra/llui/llaccordionctrl.h b/indra/llui/llaccordionctrl.h index b5fdf796cd..f26a380e5f 100644 --- a/indra/llui/llaccordionctrl.h +++ b/indra/llui/llaccordionctrl.h @@ -122,6 +122,7 @@ public:  	S32		notifyParent(const LLSD& info);  	void	reset		(); +	void	expandDefaultTab();  	void	setComparator(const LLTabComparator* comp) { mTabComparator = comp; }  	void	sort(); @@ -140,6 +141,8 @@ public:  	const LLAccordionCtrlTab* getSelectedTab() const { return mSelectedTab; } +	bool getFitParent() const {return mFitParent;} +  private:  	void	initNoTabsWidget(const LLTextBox::Params& tb_params);  	void	updateNoTabsHelpTextVisibility(); diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp index 0cccd4e6de..84716394e6 100644 --- a/indra/llui/llaccordionctrltab.cpp +++ b/indra/llui/llaccordionctrltab.cpp @@ -33,6 +33,7 @@  #include "linden_common.h"  #include "llaccordionctrltab.h" +#include "llaccordionctrl.h"  #include "lllocalcliprect.h"  #include "llscrollbar.h" @@ -372,9 +373,11 @@ LLAccordionCtrlTab::LLAccordionCtrlTab(const LLAccordionCtrlTab::Params&p)  	mHeader = LLUICtrlFactory::create<LLAccordionCtrlTabHeader>(headerParams);  	addChild(mHeader, 1); -	if (mSelectionEnabled) +	LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLAccordionCtrlTab::selectOnFocusReceived, this)); + +	if (!p.selection_enabled)  	{ -		LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLAccordionCtrlTab::selectOnFocusReceived, this)); +		LLFocusableElement::setFocusLostCallback(boost::bind(&LLAccordionCtrlTab::deselectOnFocusLost, this));  	}  	reshape(100, 200,FALSE); @@ -599,6 +602,15 @@ void LLAccordionCtrlTab::selectOnFocusReceived()  		getParent()->notifyParent(LLSD().with("action", "select_current"));  } +void LLAccordionCtrlTab::deselectOnFocusLost() +{ +	if(getParent()) // A parent may not be set if tabs are added dynamically. +	{ +		getParent()->notifyParent(LLSD().with("action", "deselect_current")); +	} + +} +  S32 LLAccordionCtrlTab::getHeaderHeight()  {  	return mHeaderVisible?HEADER_HEIGHT:0;  @@ -699,7 +711,7 @@ S32	LLAccordionCtrlTab::notifyParent(const LLSD& info)  				setRect(panel_rect);  			} -			//LLAccordionCtrl should rearrange accodion tab if one of accordion change its size +			//LLAccordionCtrl should rearrange accordion tab if one of accordion change its size  			if (getParent()) // A parent may not be set if tabs are added dynamically.  				getParent()->notifyParent(info);  			return 1; @@ -710,6 +722,27 @@ S32	LLAccordionCtrlTab::notifyParent(const LLSD& info)  			return 1;  		}  	} +	else if (info.has("scrollToShowRect")) +	{ +		LLAccordionCtrl* parent = dynamic_cast<LLAccordionCtrl*>(getParent()); +		if (parent && parent->getFitParent()) +		{ +			//	EXT-8285 ('No attachments worn' text appears at the bottom of blank 'Attachments' accordion) +			//	The problem was in passing message "scrollToShowRect" IN LLAccordionCtrlTab::notifyParent +			//	FROM child LLScrollContainer TO parent LLAccordionCtrl with "it_parent" set to true. + +			//	It is wrong notification for parent accordion which leads to recursive call of adjustContainerPanel +			//	As the result of recursive call of adjustContainerPanel we got LLAccordionCtrlTab +			//	that reshaped and re-sized with different rectangles. + +			//	LLAccordionCtrl has own scrollContainer and LLAccordionCtrlTab has own scrollContainer +			//	both should handle own scroll container's event. +			//	So, if parent accordion "fit_parent" accordion tab should handle its scroll container events itself. + +			return 1; +		} +	} +  	return LLUICtrl::notifyParent(info);  } diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h index 1344ce0a30..00fb276f19 100644 --- a/indra/llui/llaccordionctrltab.h +++ b/indra/llui/llaccordionctrltab.h @@ -220,6 +220,7 @@ protected:  	LLView* findContainerView	();  	void selectOnFocusReceived(); +	void deselectOnFocusLost();  private: diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp index 3d32157406..0c524cd470 100644 --- a/indra/llui/llcheckboxctrl.cpp +++ b/indra/llui/llcheckboxctrl.cpp @@ -81,17 +81,6 @@ LLCheckBoxCtrl::LLCheckBoxCtrl(const LLCheckBoxCtrl::Params& p)  	// must be big enough to hold all children  	setUseBoundingRect(TRUE); -	// Label (add a little space to make sure text actually renders) -	const S32 FUDGE = 10; -	S32 text_width = mFont->getWidth( p.label ) + FUDGE; -	S32 text_height = llround(mFont->getLineHeight()); -	LLRect label_rect; -	label_rect.setOriginAndSize( -		llcheckboxctrl_hpad + llcheckboxctrl_btn_size + llcheckboxctrl_spacing, -		llcheckboxctrl_vpad + 1, // padding to get better alignment -		text_width + llcheckboxctrl_hpad, -		text_height ); -  	// *HACK Get rid of this with SL-55508...   	// this allows blank check boxes and radio boxes for now  	std::string local_label = p.label; @@ -101,7 +90,6 @@ LLCheckBoxCtrl::LLCheckBoxCtrl(const LLCheckBoxCtrl::Params& p)  	}  	LLTextBox::Params tbparams = p.label_text; -	tbparams.rect(label_rect);  	tbparams.initial_value(local_label);  	if (p.font.isProvided())  	{ @@ -111,6 +99,17 @@ LLCheckBoxCtrl::LLCheckBoxCtrl(const LLCheckBoxCtrl::Params& p)  	mLabel = LLUICtrlFactory::create<LLTextBox> (tbparams);  	addChild(mLabel); +	S32 text_width = mLabel->getTextBoundingRect().getWidth(); +	S32 text_height = llround(mFont->getLineHeight()); +	LLRect label_rect; +	label_rect.setOriginAndSize( +		llcheckboxctrl_hpad + llcheckboxctrl_btn_size + llcheckboxctrl_spacing, +		llcheckboxctrl_vpad + 1, // padding to get better alignment +		text_width + llcheckboxctrl_hpad, +		text_height ); +	mLabel->setShape(label_rect); + +  	// Button  	// Note: button cover the label by extending all the way to the right.  	LLRect btn_rect; @@ -190,8 +189,7 @@ void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent)  	static LLUICachedControl<S32> llcheckboxctrl_vpad ("UICheckboxctrlVPad", 0);  	static LLUICachedControl<S32> llcheckboxctrl_btn_size ("UICheckboxctrlBtnSize", 0); -	const S32 FUDGE = 10; -	S32 text_width = mFont->getWidth( mLabel->getText() ) + FUDGE; +	S32 text_width = mLabel->getTextBoundingRect().getWidth();  	S32 text_height = llround(mFont->getLineHeight());  	LLRect label_rect;  	label_rect.setOriginAndSize( @@ -199,7 +197,7 @@ void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent)  		llcheckboxctrl_vpad,  		text_width,  		text_height ); -	mLabel->setRect(label_rect); +	mLabel->setShape(label_rect);  	LLRect btn_rect;  	btn_rect.setOriginAndSize( @@ -207,7 +205,7 @@ void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent)  		llcheckboxctrl_vpad,  		llcheckboxctrl_btn_size + llcheckboxctrl_spacing + text_width,  		llmax( text_height, llcheckboxctrl_btn_size() ) ); -	mButton->setRect( btn_rect ); +	mButton->setShape( btn_rect );  	LLUICtrl::reshape(width, height, called_from_parent);  } diff --git a/indra/llui/lldockablefloater.cpp b/indra/llui/lldockablefloater.cpp index 3d8670fef2..4f5fcddbf4 100644 --- a/indra/llui/lldockablefloater.cpp +++ b/indra/llui/lldockablefloater.cpp @@ -49,12 +49,12 @@ void LLDockableFloater::init(LLDockableFloater* thiz)  	thiz->setCanClose(TRUE);  	thiz->setCanDock(true);  	thiz->setCanMinimize(TRUE); +	thiz->setOverlapsScreenChannel(false);  }  LLDockableFloater::LLDockableFloater(LLDockControl* dockControl,  		const LLSD& key, const Params& params) :  	LLFloater(key, params), mDockControl(dockControl), mUniqueDocking(true) -	, mOverlapsScreenChannel(false)  {  	init(this);  	mUseTongue = true; diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp index 90c6f15d23..70558f8eb8 100644 --- a/indra/llui/llflatlistview.cpp +++ b/indra/llui/llflatlistview.cpp @@ -615,7 +615,7 @@ void LLFlatListView::onItemMouseClick(item_pair_t* item_pair, MASK mask)  	//only CTRL usage allows to deselect an item, usual clicking on an item cannot deselect it  	if (mask & MASK_CONTROL) -		selectItemPair(item_pair, select_item); +	selectItemPair(item_pair, select_item);  	else  		selectItemPair(item_pair, true);  } @@ -1078,25 +1078,6 @@ void LLFlatListView::setNoItemsCommentVisible(bool visible) const  {  	if (mNoItemsCommentTextbox)  	{ -		if (visible) -		{ -/* -// *NOTE: MA 2010-02-04 -// Deprecated after params of the comment text box were moved into widget (flat_list_view.xml) -// can be removed later if nothing happened. -			// We have to update child rect here because of issues with rect after reshaping while creating LLTextbox -			// It is possible to have invalid LLRect if Flat List is in LLAccordionTab -			LLRect comment_rect = getLocalRect(); - -			// To see comment correctly (EXT - 3244) in mNoItemsCommentTextbox we must get border width -			// of LLFlatListView (@see getBorderWidth()) and stretch mNoItemsCommentTextbox to this width -			// But getBorderWidth() returns 0 if LLFlatListView not visible. So we have to get border width -			// from 'scroll_border' -			LLViewBorder* scroll_border = getChild<LLViewBorder>("scroll border"); -			comment_rect.stretch(-scroll_border->getBorderWidth()); -			mNoItemsCommentTextbox->setRect(comment_rect); -*/ -		}  		mSelectedItemsBorder->setVisible(!visible);  		mNoItemsCommentTextbox->setVisible(visible);  	} diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 39a6855273..22d6f6ca52 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -451,6 +451,14 @@ void LLFloater::enableResizeCtrls(bool enable)  	}  } +void LLFloater::destroy() +{ +	// LLFloaterReg should be synchronized with "dead" floater to avoid returning dead instance before +	// it was deleted via LLMortician::updateClass(). See EXT-8458. +	LLFloaterReg::removeInstance(mInstanceName, mKey); +	die(); +} +  // virtual  LLFloater::~LLFloater()  { diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 3ea035777c..42f422f91c 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -308,7 +308,7 @@ protected:  	BOOL			getAutoFocus() const { return mAutoFocus; }  	LLDragHandle*	getDragHandle() const { return mDragHandle; } -	void			destroy() { die(); } // Don't call this directly.  You probably want to call closeFloater() +	void			destroy(); // Don't call this directly.  You probably want to call closeFloater()  	virtual	void	onClickCloseBtn(); diff --git a/indra/llui/lllocalcliprect.cpp b/indra/llui/lllocalcliprect.cpp index 43c21e250c..55329f64e4 100644 --- a/indra/llui/lllocalcliprect.cpp +++ b/indra/llui/lllocalcliprect.cpp @@ -33,33 +33,8 @@  #include "lllocalcliprect.h"  #include "llfontgl.h" -#include "llgl.h"  #include "llui.h" -#include <stack> - -//--------------------------------------------------------------------------- -// LLScreenClipRect -// implementation class in screen space -//--------------------------------------------------------------------------- -class LLScreenClipRect -{ -public: -	LLScreenClipRect(const LLRect& rect, BOOL enabled = TRUE); -	virtual ~LLScreenClipRect(); - -private: -	static void pushClipRect(const LLRect& rect); -	static void popClipRect(); -	static void updateScissorRegion(); - -private: -	LLGLState		mScissorState; -	BOOL			mEnabled; - -	static std::stack<LLRect> sClipRectStack; -}; -  /*static*/ std::stack<LLRect> LLScreenClipRect::sClipRectStack; @@ -131,16 +106,11 @@ void LLScreenClipRect::updateScissorRegion()  // LLLocalClipRect  //---------------------------------------------------------------------------  LLLocalClipRect::LLLocalClipRect(const LLRect& rect, BOOL enabled /* = TRUE */) -{ -	LLRect screen(rect.mLeft + LLFontGL::sCurOrigin.mX,  -		rect.mTop + LLFontGL::sCurOrigin.mY,  -		rect.mRight + LLFontGL::sCurOrigin.mX,  -		rect.mBottom + LLFontGL::sCurOrigin.mY); -	mScreenClipRect = new LLScreenClipRect(screen, enabled); -} +:	LLScreenClipRect(LLRect(rect.mLeft + LLFontGL::sCurOrigin.mX,  +					rect.mTop + LLFontGL::sCurOrigin.mY,  +					rect.mRight + LLFontGL::sCurOrigin.mX,  +					rect.mBottom + LLFontGL::sCurOrigin.mY), enabled) +{}  LLLocalClipRect::~LLLocalClipRect() -{ -	delete mScreenClipRect; -	mScreenClipRect = NULL; -} +{} diff --git a/indra/llui/lllocalcliprect.h b/indra/llui/lllocalcliprect.h index cd0c55ca72..36413f1496 100644 --- a/indra/llui/lllocalcliprect.h +++ b/indra/llui/lllocalcliprect.h @@ -31,7 +31,9 @@  #ifndef LLLOCALCLIPRECT_H  #define LLLOCALCLIPRECT_H +#include "llgl.h"  #include "llrect.h"		// can't forward declare, it's templated +#include <stack>  // Clip rendering to a specific rectangle using GL scissor  // Just create one of these on the stack: @@ -39,15 +41,29 @@  //     LLLocalClipRect(rect);  //     draw();  // } -class LLLocalClipRect +class LLScreenClipRect  {  public: -	LLLocalClipRect(const LLRect& rect, BOOL enabled = TRUE); -	~LLLocalClipRect(); +	LLScreenClipRect(const LLRect& rect, BOOL enabled = TRUE); +	virtual ~LLScreenClipRect(); + +private: +	static void pushClipRect(const LLRect& rect); +	static void popClipRect(); +	static void updateScissorRegion();  private: -	// implementation class -	class LLScreenClipRect* mScreenClipRect; +	LLGLState		mScissorState; +	BOOL			mEnabled; + +	static std::stack<LLRect> sClipRectStack; +}; + +class LLLocalClipRect : public LLScreenClipRect +{ +public: +	LLLocalClipRect(const LLRect& rect, BOOL enabled = TRUE); +	~LLLocalClipRect();  };  #endif diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index b4a1bcb7c5..12007f7b52 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -218,6 +218,12 @@ void LLMenuItemGL::setValue(const LLSD& value)  }  //virtual +LLSD LLMenuItemGL::getValue() const +{ +	return getLabel(); +} + +//virtual  BOOL LLMenuItemGL::handleAcceleratorKey(KEY key, MASK mask)  {  	if( getEnabled() && (!gKeyboard->getKeyRepeated(key) || mAllowKeyRepeat) && (key == mAcceleratorKey) && (mask == (mAcceleratorMask & MASK_NORMALKEYS)) ) @@ -922,6 +928,15 @@ void LLMenuItemCheckGL::setValue(const LLSD& value)  	}  } +//virtual +LLSD LLMenuItemCheckGL::getValue() const +{ +	// Get our boolean value from the view model. +	// If we don't override this method then the implementation from +	// LLMenuItemGL will return a string. (EXT-8501) +	return LLUICtrl::getValue(); +} +  // called to rebuild the draw label  void LLMenuItemCheckGL::buildDrawLabel( void )  { diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 7668f301ea..bf40163dac 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -95,6 +95,7 @@ public:  	// LLUICtrl overrides  	/*virtual*/ void setValue(const LLSD& value); +	/*virtual*/ LLSD getValue() const;  	virtual BOOL handleAcceleratorKey(KEY key, MASK mask); @@ -321,6 +322,7 @@ public:  	virtual void onCommit( void );  	virtual void setValue(const LLSD& value); +	virtual LLSD getValue() const;  	// called to rebuild the draw label  	virtual void buildDrawLabel( void ); diff --git a/indra/llui/llresmgr.cpp b/indra/llui/llresmgr.cpp index ed870d46d5..9158bc70f5 100644 --- a/indra/llui/llresmgr.cpp +++ b/indra/llui/llresmgr.cpp @@ -298,11 +298,11 @@ void LLResMgr::getIntegerString( std::string& output, S32 input ) const  		{  			if (fraction == remaining_count)  			{ -				fraction_string = llformat("%d%c", fraction, getThousandsSeparator()); +				fraction_string = llformat_to_utf8("%d%c", fraction, getThousandsSeparator());  			}  			else  			{ -				fraction_string = llformat("%3.3d%c", fraction, getThousandsSeparator()); +				fraction_string = llformat_to_utf8("%3.3d%c", fraction, getThousandsSeparator());  			}  			output = fraction_string + output;  		} diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 617c496d6a..4bcf7e6980 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1012,21 +1012,26 @@ void LLTextBase::draw()  	if (mBGVisible)  	{  		// clip background rect against extents, if we support scrolling -		LLLocalClipRect clip(doc_rect, mScroller != NULL); - +		LLRect bg_rect = mVisibleTextRect; +		if (mScroller) +		{ +			bg_rect.intersectWith(doc_rect); +		}  		LLColor4 bg_color = mReadOnly   							? mReadOnlyBgColor.get()  							: hasFocus()   								? mFocusBgColor.get()   								: mWriteableBgColor.get(); -		gl_rect_2d(mVisibleTextRect, bg_color, TRUE); +		gl_rect_2d(doc_rect, bg_color, TRUE);  	}  	// draw document view  	LLUICtrl::draw();  	{ -		// only clip if we support scrolling (mScroller != NULL) +		// only clip if we support scrolling... +		// since convention is that text boxes never vertically truncate their contents +		// regardless of rect bounds  		LLLocalClipRect clip(doc_rect, mScroller != NULL);  		drawSelectionBackground();  		drawText(); @@ -1495,6 +1500,7 @@ LLTextBase::segment_set_t::iterator LLTextBase::getSegIterContaining(S32 index)  	// when there are no segments, we return the end iterator, which must be checked by caller  	if (mSegments.size() <= 1) { return mSegments.begin(); } +	//FIXME: avoid operator new somehow (without running into refcount problems)  	segment_set_t::iterator it = mSegments.upper_bound(new LLIndexSegment(index));  	return it;  } @@ -1642,7 +1648,7 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para  			}  			else  			{ -				appendAndHighlightText(match.getLabel(), part, link_params); +				appendAndHighlightText(match.getLabel(), part, link_params, match.underlineOnHoverOnly());  				// set the tooltip for the Url label  				if (! match.getTooltip().empty()) @@ -1725,7 +1731,7 @@ void LLTextBase::appendWidget(const LLInlineViewSegment::Params& params, const s  	insertStringNoUndo(getLength(), widget_wide_text, &segments);  } -void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params) +void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params, bool underline_on_hover_only)  {  	// Save old state  	S32 selection_start = mSelectionStart; @@ -1756,7 +1762,17 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig  			S32 cur_length = getLength();  			LLStyleConstSP sp(new LLStyle(highlight_params)); -			LLTextSegmentPtr segmentp = new LLNormalTextSegment(sp, cur_length, cur_length + wide_text.size(), *this); +			LLTextSegmentPtr segmentp; +			if(underline_on_hover_only) +			{ +				highlight_params.font.style("NORMAL"); +				LLStyleConstSP normal_sp(new LLStyle(highlight_params)); +				segmentp = new LLOnHoverChangeableTextSegment(sp, normal_sp, cur_length, cur_length + wide_text.size(), *this); +			} +			else +			{ +				segmentp = new LLNormalTextSegment(sp, cur_length, cur_length + wide_text.size(), *this); +			}  			segment_vec_t segments;  			segments.push_back(segmentp);  			insertStringNoUndo(cur_length, wide_text, &segments); @@ -1771,7 +1787,17 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig  		S32 segment_start = old_length;  		S32 segment_end = old_length + wide_text.size();  		LLStyleConstSP sp(new LLStyle(style_params)); +		if (underline_on_hover_only) +		{ +			LLStyle::Params normal_style_params(style_params); +			normal_style_params.font.style("NORMAL"); +			LLStyleConstSP normal_sp(new LLStyle(normal_style_params)); +			segments.push_back(new LLOnHoverChangeableTextSegment(sp, normal_sp, segment_start, segment_end, *this )); +		} +		else +		{  		segments.push_back(new LLNormalTextSegment(sp, segment_start, segment_end, *this )); +		}  		insertStringNoUndo(getLength(), wide_text, &segments);  	} @@ -1795,7 +1821,7 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig  	}  } -void LLTextBase::appendAndHighlightText(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params) +void LLTextBase::appendAndHighlightText(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params, bool underline_on_hover_only)  {  	if (new_text.empty()) return;  @@ -1807,7 +1833,7 @@ void LLTextBase::appendAndHighlightText(const std::string &new_text, S32 highlig  		if(pos!=start)  		{  			std::string str = std::string(new_text,start,pos-start); -			appendAndHighlightTextImpl(str,highlight_part, style_params); +			appendAndHighlightTextImpl(str,highlight_part, style_params, underline_on_hover_only);  		}  		appendLineBreakSegment(style_params);  		start = pos+1; @@ -1815,7 +1841,7 @@ void LLTextBase::appendAndHighlightText(const std::string &new_text, S32 highlig  	}  	std::string str = std::string(new_text,start,new_text.length()-start); -	appendAndHighlightTextImpl(str,highlight_part, style_params); +	appendAndHighlightTextImpl(str,highlight_part, style_params, underline_on_hover_only);  } @@ -2269,6 +2295,7 @@ void LLTextBase::updateRects()  	// allow horizontal scrolling?  	// if so, use entire width of text contents  	// otherwise, stop at width of mVisibleTextRect +	//FIXME: consider use of getWordWrap() instead  	doc_rect.mRight = mScroller   		? llmax(mVisibleTextRect.getWidth(), mTextBoundingRect.mRight)  		: mVisibleTextRect.getWidth(); @@ -2675,6 +2702,30 @@ void LLNormalTextSegment::dump() const  		llendl;  } +// +// LLOnHoverChangeableTextSegment +// + +LLOnHoverChangeableTextSegment::LLOnHoverChangeableTextSegment( LLStyleConstSP style, LLStyleConstSP normal_style, S32 start, S32 end, LLTextBase& editor ): +	  LLNormalTextSegment(normal_style, start, end, editor), +	  mHoveredStyle(style), +	  mNormalStyle(normal_style){} + +/*virtual*/  +F32 LLOnHoverChangeableTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect) +{ +	F32 result = LLNormalTextSegment::draw(start, end, selection_start, selection_end, draw_rect); +	mStyle = mNormalStyle; +	return result; +} + +/*virtual*/ +BOOL LLOnHoverChangeableTextSegment::handleHover(S32 x, S32 y, MASK mask) +{ +	mStyle = mHoveredStyle; +	return LLNormalTextSegment::handleHover(x, y, mask); +} +  //  // LLInlineViewSegment diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 86f0e55a1d..4b83d5effb 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -145,6 +145,21 @@ protected:  	boost::signals2::connection mImageLoadedConnection;  }; +// Text segment that changes it's style depending of mouse pointer position ( is it inside or outside segment) +class LLOnHoverChangeableTextSegment : public LLNormalTextSegment +{ +public: +	LLOnHoverChangeableTextSegment( LLStyleConstSP style, LLStyleConstSP normal_style, S32 start, S32 end, LLTextBase& editor ); +	/*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect); +	/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); +protected: +	// Style used for text when mouse pointer is over segment +	LLStyleConstSP		mHoveredStyle; +	// Style used for text when mouse pointer is outside segment +	LLStyleConstSP		mNormalStyle; + +}; +  class LLIndexSegment : public LLTextSegment  {  public: @@ -443,7 +458,7 @@ protected:  	S32								insertStringNoUndo(S32 pos, const LLWString &wstr, segment_vec_t* segments = NULL); // returns num of chars actually inserted  	S32 							removeStringNoUndo(S32 pos, S32 length);  	S32								overwriteCharNoUndo(S32 pos, llwchar wc); -	void							appendAndHighlightText(const std::string &new_text, S32 highlight_part, const LLStyle::Params& stylep); +	void							appendAndHighlightText(const std::string &new_text, S32 highlight_part, const LLStyle::Params& stylep, bool underline_on_hover_only = false);  	// manage segments  @@ -486,7 +501,7 @@ protected:  	void							replaceUrlLabel(const std::string &url, const std::string &label);  	void							appendTextImpl(const std::string &new_text, const LLStyle::Params& input_params = LLStyle::Params()); -	void							appendAndHighlightTextImpl(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params); +	void							appendAndHighlightTextImpl(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params, bool underline_on_hover_only = false);  protected: diff --git a/indra/llui/lltextvalidate.cpp b/indra/llui/lltextvalidate.cpp index 8b6bc5bd7d..53c4d21151 100644 --- a/indra/llui/lltextvalidate.cpp +++ b/indra/llui/lltextvalidate.cpp @@ -50,6 +50,7 @@ namespace LLTextValidate  		declare("alpha_num_space", validateAlphaNumSpace);  		declare("ascii_printable_no_pipe", validateASCIIPrintableNoPipe);  		declare("ascii_printable_no_space", validateASCIIPrintableNoSpace); +		declare("ascii_with_newline", validateASCIIWithNewLine);  	}  	// Limits what characters can be used to [1234567890.-] with [-] only valid in the first position. @@ -299,4 +300,21 @@ namespace LLTextValidate  		}  		return rv;  	} + +	// Used for multiline text stored on the server. +	// Example is landmark description in Places SP. +	bool validateASCIIWithNewLine(const LLWString &str) +	{ +		bool rv = TRUE; +		S32 len = str.length(); +		while(len--) +		{ +			if (str[len] < 0x20 && str[len] != 0xA || str[len] > 0x7f) +			{ +				rv = FALSE; +				break; +			} +		} +		return rv; +	}  } diff --git a/indra/llui/lltextvalidate.h b/indra/llui/lltextvalidate.h index ffb4e85e7c..c033f5045b 100644 --- a/indra/llui/lltextvalidate.h +++ b/indra/llui/lltextvalidate.h @@ -57,6 +57,7 @@ namespace LLTextValidate  	bool	validateASCIIPrintableNoPipe(const LLWString &str);   	bool	validateASCIIPrintableNoSpace(const LLWString &str);  	bool	validateASCII(const LLWString &str); +	bool	validateASCIIWithNewLine(const LLWString &str);  } diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index e075699a6e..17d211fb36 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -363,6 +363,12 @@ std::string LLUrlEntryAgent::getTooltip(const std::string &string) const  	return LLTrans::getString("TooltipAgentUrl");  } +bool LLUrlEntryAgent::underlineOnHoverOnly(const std::string &string) const +{ +	std::string url = getUrl(string); +	return LLStringUtil::endsWith(url, "/about"); +} +  std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCallback &cb)  {  	if (!gCacheName) @@ -730,6 +736,19 @@ std::string LLUrlEntrySLLabel::getTooltip(const std::string &string) const  	return LLUrlEntryBase::getTooltip(string);  } +bool LLUrlEntrySLLabel::underlineOnHoverOnly(const std::string &string) const +{ +	std::string url = getUrl(string); +	LLUrlMatch match; +	if (LLUrlRegistry::instance().findUrl(url, match)) +	{ +		return match.underlineOnHoverOnly(); +	} + +	// unrecognized URL? should not happen +	return LLUrlEntryBase::underlineOnHoverOnly(string); +} +  //  // LLUrlEntryWorldMap Describes secondlife:///<location> URLs  // diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index 7d718b67a9..f8588dd760 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -94,6 +94,9 @@ public:  	/// is this a match for a URL that should not be hyperlinked?  	bool isLinkDisabled() const { return mDisabledLink; } +	/// Should this link text be underlined only when mouse is hovered over it? +	virtual bool underlineOnHoverOnly(const std::string &string) const { return false; } +  	virtual LLUUID	getID(const std::string &string) const { return LLUUID::null; }  protected: @@ -173,6 +176,7 @@ public:  	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);  	/*virtual*/ std::string getTooltip(const std::string &string) const;  	/*virtual*/ LLUUID	getID(const std::string &string) const; +	/*virtual*/ bool underlineOnHoverOnly(const std::string &string) const;  private:  	void onAgentNameReceived(const LLUUID& id, const std::string& first,  							 const std::string& last, BOOL is_group); @@ -275,6 +279,7 @@ public:  	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);  	/*virtual*/ std::string getUrl(const std::string &string) const;  	/*virtual*/ std::string getTooltip(const std::string &string) const; +	/*virtual*/ bool underlineOnHoverOnly(const std::string &string) const;  };  /// diff --git a/indra/llui/llurlmatch.cpp b/indra/llui/llurlmatch.cpp index 7c96665ce4..a6d3dcb40f 100644 --- a/indra/llui/llurlmatch.cpp +++ b/indra/llui/llurlmatch.cpp @@ -43,7 +43,8 @@ LLUrlMatch::LLUrlMatch() :  	mIcon(""),  	mMenuName(""),  	mLocation(""), -	mDisabledLink(false) +	mDisabledLink(false), +	mUnderlineOnHoverOnly(false)  {  } @@ -51,7 +52,7 @@ 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 &menu, const std::string &location, -						   bool disabled_link, const LLUUID& id) +						   bool disabled_link, const LLUUID& id, bool underline_on_hover_only)  {  	mStart = start;  	mEnd = end; @@ -64,4 +65,5 @@ void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url,  	mLocation = location;  	mDisabledLink = disabled_link;  	mID = id; +	mUnderlineOnHoverOnly = underline_on_hover_only;  } diff --git a/indra/llui/llurlmatch.h b/indra/llui/llurlmatch.h index 78dd2c528f..7090dd3f93 100644 --- a/indra/llui/llurlmatch.h +++ b/indra/llui/llurlmatch.h @@ -86,12 +86,15 @@ public:  	/// is this a match for a URL that should not be hyperlinked?  	bool isLinkDisabled() const { return mDisabledLink; } +	/// Should this link text be underlined only when mouse is hovered over it? +	bool underlineOnHoverOnly() const { return mUnderlineOnHoverOnly; } +  	/// 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 std::string &location, bool disabled_link -				   , const LLUUID& id ); +				   , const LLUUID& id, bool underline_on_hover_only  = false );  	const LLUUID& getID() const { return mID;} @@ -108,6 +111,7 @@ private:  	LLUUID		mID;  	LLUIColor	mColor;  	bool        mDisabledLink; +	bool		mUnderlineOnHoverOnly;  };  #endif diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index 1f86f72faa..b37a52cad2 100644 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -184,7 +184,8 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL  						match_entry->getMenuName(),  						match_entry->getLocation(url),  						match_entry->isLinkDisabled(), -						match_entry->getID(url)); +						match_entry->getID(url), +						match_entry->underlineOnHoverOnly(url));  		return true;  	} @@ -219,7 +220,8 @@ bool LLUrlRegistry::findUrl(const LLWString &text, LLUrlMatch &match, const LLUr  						match.getMenuName(),  						match.getLocation(),  						match.isLinkDisabled(), -						match.getID()); +						match.getID(), +						match.underlineOnHoverOnly());  		return true;  	}  	return false; diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index fa7343ed62..ce22db97b4 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -7339,7 +7339,7 @@      <key>Value</key>      <integer>0</integer>    </map> -   +    <key>RenderDeferredGI</key>    <map>      <key>Comment</key> @@ -8032,7 +8032,7 @@        <integer>2</integer>      </map> -  <key>RenderReflectionRes</key> +    <key>RenderReflectionRes</key>      <map>        <key>Comment</key>        <string>Reflection map resolution.</string> diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 53b7febba7..e85d108bb2 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -3079,7 +3079,7 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void *  		return;  	} -	if (gAgentCamera.cameraCustomizeAvatar()) +	if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures())  	{  		// ignore baked textures when in customize mode  		return; @@ -3548,7 +3548,7 @@ void LLAgent::sendAgentSetAppearance()  {  	if (!isAgentAvatarValid()) return; -	if (gAgentQueryManager.mNumPendingQueries > 0 && !gAgentCamera.cameraCustomizeAvatar())  +	if (gAgentQueryManager.mNumPendingQueries > 0 && (isAgentAvatarValid() && gAgentAvatarp->isUsingBakedTextures()))   	{  		return;  	} diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 1ef9e34f87..4dc78e9a1d 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -941,7 +941,7 @@ void LLAgentCamera::cameraZoomIn(const F32 fraction)  		*/  	} -	if( cameraCustomizeAvatar() ) +	if(cameraCustomizeAvatar())  	{  		new_distance = llclamp( new_distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM );  	} diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index d2449abf08..63315ce2ae 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -983,6 +983,10 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up  		LLNotificationsUtil::add("CannotWearTrash");  		return false;  	} +	else if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), LLAppearanceMgr::instance().getCOF())) // EXT-84911 +	{ +		return false; +	}  	switch (item_to_wear->getType())  	{ @@ -2699,6 +2703,21 @@ BOOL LLAppearanceMgr::getIsInCOF(const LLUUID& obj_id) const  	return gInventory.isObjectDescendentOf(obj_id, getCOF());  } +// static +bool LLAppearanceMgr::isLinkInCOF(const LLUUID& obj_id) +{ +	 LLInventoryModel::cat_array_t cats; +	 LLInventoryModel::item_array_t items; +	 LLLinkedItemIDMatches find_links(gInventory.getLinkedItemID(obj_id)); +	 gInventory.collectDescendentsIf(LLAppearanceMgr::instance().getCOF(), +	 cats, +	 items, +	 LLInventoryModel::EXCLUDE_TRASH, +	 find_links); + +	 return !items.empty(); +} +  BOOL LLAppearanceMgr::getIsProtectedCOFItem(const LLUUID& obj_id) const  {  	if (!getIsInCOF(obj_id)) return FALSE; @@ -2726,3 +2745,192 @@ BOOL LLAppearanceMgr::getIsProtectedCOFItem(const LLUUID& obj_id) const  	return FALSE;  	*/  } + +// Shim class to allow arbitrary boost::bind +// expressions to be run as one-time idle callbacks. +// +// TODO: rework idle function spec to take a boost::function in the first place. +class OnIdleCallbackOneTime +{ +public: +	OnIdleCallbackOneTime(nullary_func_t callable): +		mCallable(callable) +	{ +	} +	static void onIdle(void *data) +	{ +		gIdleCallbacks.deleteFunction(onIdle, data); +		OnIdleCallbackOneTime* self = reinterpret_cast<OnIdleCallbackOneTime*>(data); +		self->call(); +		delete self; +	} +	void call() +	{ +		mCallable(); +	} +private: +	nullary_func_t mCallable; +}; + +void doOnIdleOneTime(nullary_func_t callable) +{ +	OnIdleCallbackOneTime* cb_functor = new OnIdleCallbackOneTime(callable); +	gIdleCallbacks.addFunction(&OnIdleCallbackOneTime::onIdle,cb_functor); +} + +// Shim class to allow generic boost functions to be run as +// recurring idle callbacks.  Callable should return true when done, +// false to continue getting called. +// +// TODO: rework idle function spec to take a boost::function in the first place. +class OnIdleCallbackRepeating +{ +public: +	OnIdleCallbackRepeating(bool_func_t callable): +		mCallable(callable) +	{ +	} +	// Will keep getting called until the callable returns true. +	static void onIdle(void *data) +	{ +		OnIdleCallbackRepeating* self = reinterpret_cast<OnIdleCallbackRepeating*>(data); +		bool done = self->call(); +		if (done) +		{ +			gIdleCallbacks.deleteFunction(onIdle, data); +			delete self; +		} +	} +	bool call() +	{ +		return mCallable(); +	} +private: +	bool_func_t mCallable; +}; + +void doOnIdleRepeating(bool_func_t callable) +{ +	OnIdleCallbackRepeating* cb_functor = new OnIdleCallbackRepeating(callable); +	gIdleCallbacks.addFunction(&OnIdleCallbackRepeating::onIdle,cb_functor); +} + +class CallAfterCategoryFetchStage2: public LLInventoryFetchItemsObserver +{ +public: +	CallAfterCategoryFetchStage2(const uuid_vec_t& ids, +								 nullary_func_t callable) : +		LLInventoryFetchItemsObserver(ids), +		mCallable(callable) +	{ +	} +	~CallAfterCategoryFetchStage2() +	{ +	} +	virtual void done() +	{ +		llinfos << this << " done with incomplete " << mIncomplete.size() +				<< " complete " << mComplete.size() <<  " calling callable" << llendl; + +		gInventory.removeObserver(this); +		doOnIdleOneTime(mCallable); +		delete this; +	} +protected: +	nullary_func_t mCallable; +}; + +class CallAfterCategoryFetchStage1: public LLInventoryFetchDescendentsObserver +{ +public: +	CallAfterCategoryFetchStage1(const LLUUID& cat_id, nullary_func_t callable) : +		LLInventoryFetchDescendentsObserver(cat_id), +		mCallable(callable) +	{ +	} +	~CallAfterCategoryFetchStage1() +	{ +	} +	virtual void done() +	{ +		// What we do here is get the complete information on the items in +		// the library, and set up an observer that will wait for that to +		// happen. +		LLInventoryModel::cat_array_t cat_array; +		LLInventoryModel::item_array_t item_array; +		gInventory.collectDescendents(mComplete.front(), +									  cat_array, +									  item_array, +									  LLInventoryModel::EXCLUDE_TRASH); +		S32 count = item_array.count(); +		if(!count) +		{ +			llwarns << "Nothing fetched in category " << mComplete.front() +					<< llendl; +			//dec_busy_count(); +			gInventory.removeObserver(this); + +			// lets notify observers that loading is finished. +			gAgentWearables.notifyLoadingFinished(); +			delete this; +			return; +		} + +		llinfos << "stage1 got " << item_array.count() << " items, passing to stage2 " << llendl; +		uuid_vec_t ids; +		for(S32 i = 0; i < count; ++i) +		{ +			ids.push_back(item_array.get(i)->getUUID()); +		} +		 +		gInventory.removeObserver(this); +		 +		// do the fetch +		CallAfterCategoryFetchStage2 *stage2 = new CallAfterCategoryFetchStage2(ids, mCallable); +		stage2->startFetch(); +		if(stage2->isFinished()) +		{ +			// everything is already here - call done. +			stage2->done(); +		} +		else +		{ +			// it's all on it's way - add an observer, and the inventory +			// will call done for us when everything is here. +			gInventory.addObserver(stage2); +		} +		delete this; +	} +protected: +	nullary_func_t mCallable; +}; + +void callAfterCategoryFetch(const LLUUID& cat_id, nullary_func_t cb) +{ +	CallAfterCategoryFetchStage1 *stage1 = new CallAfterCategoryFetchStage1(cat_id, cb); +	stage1->startFetch(); +	if (stage1->isFinished()) +	{ +		stage1->done(); +	} +	else +	{ +		gInventory.addObserver(stage1); +	} +} + +void wear_multiple(const uuid_vec_t& ids, bool replace) +{ +	LLPointer<LLInventoryCallback> cb = new LLUpdateAppearanceOnDestroy; +	 +	bool first = true; +	uuid_vec_t::const_iterator it; +	for (it = ids.begin(); it != ids.end(); ++it) +	{ +		// if replace is requested, the first item worn will replace the current top +		// item, and others will be added. +		LLAppearanceMgr::instance().wearItemOnAvatar(*it,false,first && replace,cb); +		first = false; +	} +} + diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 84c911c038..9f554dbdef 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -223,6 +223,11 @@ public:  	BOOL getIsInCOF(const LLUUID& obj_id) const;  	// Is this in the COF and can the user delete it from the COF?  	BOOL getIsProtectedCOFItem(const LLUUID& obj_id) const; + +	/** +	 * Checks if COF contains link to specified object. +	 */ +	static bool isLinkInCOF(const LLUUID& obj_id);  };  class LLUpdateAppearanceOnDestroy: public LLInventoryCallback @@ -242,180 +247,19 @@ private:  LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id,const std::string& name); -// Shim class and template function to allow arbitrary boost::bind -// expressions to be run as one-time idle callbacks. -template <typename T> -class OnIdleCallbackOneTime -{ -public: -	OnIdleCallbackOneTime(T callable): -		mCallable(callable) -	{ -	} -	static void onIdle(void *data) -	{ -		gIdleCallbacks.deleteFunction(onIdle, data); -		OnIdleCallbackOneTime<T>* self = reinterpret_cast<OnIdleCallbackOneTime<T>*>(data); -		self->call(); -		delete self; -	} -	void call() -	{ -		mCallable(); -	} -private: -	T mCallable; -}; +typedef boost::function<void ()> nullary_func_t; +typedef boost::function<bool ()> bool_func_t; -template <typename T> -void doOnIdleOneTime(T callable) -{ -	OnIdleCallbackOneTime<T>* cb_functor = new OnIdleCallbackOneTime<T>(callable); -	gIdleCallbacks.addFunction(&OnIdleCallbackOneTime<T>::onIdle,cb_functor); -} - -// Shim class and template function to allow arbitrary boost::bind -// expressions to be run as recurring idle callbacks. -// Callable should return true when done, false to continue getting called. -template <typename T> -class OnIdleCallbackRepeating -{ -public: -	OnIdleCallbackRepeating(T callable): -		mCallable(callable) -	{ -	} -	// Will keep getting called until the callable returns true. -	static void onIdle(void *data) -	{ -		OnIdleCallbackRepeating<T>* self = reinterpret_cast<OnIdleCallbackRepeating<T>*>(data); -		bool done = self->call(); -		if (done) -		{ -			gIdleCallbacks.deleteFunction(onIdle, data); -			delete self; -		} -	} -	bool call() -	{ -		return mCallable(); -	} -private: -	T mCallable; -}; +// Call a given callable once in idle loop. +void doOnIdleOneTime(nullary_func_t callable); -template <typename T> -void doOnIdleRepeating(T callable) -{ -	OnIdleCallbackRepeating<T>* cb_functor = new OnIdleCallbackRepeating<T>(callable); -	gIdleCallbacks.addFunction(&OnIdleCallbackRepeating<T>::onIdle,cb_functor); -} +// Repeatedly call a callable in idle loop until it returns true. +void doOnIdleRepeating(bool_func_t callable); -template <class T> -class CallAfterCategoryFetchStage2: public LLInventoryFetchItemsObserver -{ -public: -	CallAfterCategoryFetchStage2(const uuid_vec_t& ids, -								 T callable) : -		LLInventoryFetchItemsObserver(ids), -		mCallable(callable) -	{ -	} -	~CallAfterCategoryFetchStage2() -	{ -	} -	virtual void done() -	{ -		llinfos << this << " done with incomplete " << mIncomplete.size() -				<< " complete " << mComplete.size() <<  " calling callable" << llendl; - -		gInventory.removeObserver(this); -		doOnIdleOneTime(mCallable); -		delete this; -	} -protected: -	T mCallable; -}; +// Invoke a given callable after category contents are fully fetched. +void callAfterCategoryFetch(const LLUUID& cat_id, nullary_func_t cb); -template <class T> -class CallAfterCategoryFetchStage1: public LLInventoryFetchDescendentsObserver -{ -public: -	CallAfterCategoryFetchStage1(const LLUUID& cat_id, T callable) : -		LLInventoryFetchDescendentsObserver(cat_id), -		mCallable(callable) -	{ -	} -	~CallAfterCategoryFetchStage1() -	{ -	} -	virtual void done() -	{ -		// What we do here is get the complete information on the items in -		// the library, and set up an observer that will wait for that to -		// happen. -		LLInventoryModel::cat_array_t cat_array; -		LLInventoryModel::item_array_t item_array; -		gInventory.collectDescendents(mComplete.front(), -									  cat_array, -									  item_array, -									  LLInventoryModel::EXCLUDE_TRASH); -		S32 count = item_array.count(); -		if(!count) -		{ -			llwarns << "Nothing fetched in category " << mComplete.front() -					<< llendl; -			//dec_busy_count(); -			gInventory.removeObserver(this); - -			// lets notify observers that loading is finished. -			gAgentWearables.notifyLoadingFinished(); -			delete this; -			return; -		} - -		llinfos << "stage1 got " << item_array.count() << " items, passing to stage2 " << llendl; -		uuid_vec_t ids; -		for(S32 i = 0; i < count; ++i) -		{ -			ids.push_back(item_array.get(i)->getUUID()); -		} -		 -		gInventory.removeObserver(this); -		 -		// do the fetch -		CallAfterCategoryFetchStage2<T> *stage2 = new CallAfterCategoryFetchStage2<T>(ids, mCallable); -		stage2->startFetch(); -		if(stage2->isFinished()) -		{ -			// everything is already here - call done. -			stage2->done(); -		} -		else -		{ -			// it's all on it's way - add an observer, and the inventory -			// will call done for us when everything is here. -			gInventory.addObserver(stage2); -		} -		delete this; -	} -protected: -	T mCallable; -}; - -template <class T>  -void callAfterCategoryFetch(const LLUUID& cat_id, T callable) -{ -	CallAfterCategoryFetchStage1<T> *stage1 = new CallAfterCategoryFetchStage1<T>(cat_id, callable); -	stage1->startFetch(); -	if (stage1->isFinished()) -	{ -		stage1->done(); -	} -	else -	{ -		gInventory.addObserver(stage1); -	} -} +// Wear all items in a uuid vector. +void wear_multiple(const uuid_vec_t& ids, bool replace);  #endif diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 21766a731d..d222d94ec6 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -357,7 +357,7 @@ static void ui_audio_callback(const LLUUID& uuid)  bool	create_text_segment_icon_from_url_match(LLUrlMatch* match,LLTextBase* base)  { -	if(!match || !base) +	if(!match || !base || base->getPlainText())  		return false;  	LLUUID match_id = match->getID(); diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 752a2e7504..1e59e5b805 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -550,9 +550,10 @@ namespace action_give_inventory  		}  		LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); -		if (NULL == active_panel) +		if (!active_panel)  		{ -			return; +			active_panel = get_outfit_editor_inventory_panel(); +			if (!active_panel) return;  		}  		const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList(); diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index c0fa910f86..7c33923f04 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -111,6 +111,12 @@ public:  		return pInstance;  	} +	~LLChatHistoryHeader() +	{ +		// Detach the info button so that it doesn't get destroyed (EXT-8463). +		hideInfoCtrl(); +	} +  	BOOL handleMouseUp(S32 x, S32 y, MASK mask)  	{  		return LLPanel::handleMouseUp(x,y,mask); @@ -382,8 +388,18 @@ protected:  		if (!sInfoCtrl)  		{ +			// *TODO: Delete the button at exit.  			sInfoCtrl = LLUICtrlFactory::createFromFile<LLUICtrl>("inspector_info_ctrl.xml", NULL, LLPanel::child_registry_t::instance()); -			sInfoCtrl->setCommitCallback(boost::bind(&LLChatHistoryHeader::onClickInfoCtrl, sInfoCtrl)); +			if (sInfoCtrl) +			{ +				sInfoCtrl->setCommitCallback(boost::bind(&LLChatHistoryHeader::onClickInfoCtrl, sInfoCtrl)); +			} +		} + +		if (!sInfoCtrl) +		{ +			llassert(sInfoCtrl != NULL); +			return;  		}  		LLTextBase* name = getChild<LLTextBase>("user_name"); diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp index b4c380b2d0..04c70cb7d8 100644 --- a/indra/newview/llcofwearables.cpp +++ b/indra/newview/llcofwearables.cpp @@ -163,7 +163,7 @@ public:  	}  protected: -	static void replaceWearable(const LLUUID& item_id) +	static void replaceWearable()  	{  		// *TODO: Most probable that accessing to LLPanelOutfitEdit instance should be:  		// LLSideTray::getInstance()->getSidepanelAppearance()->getPanelOutfitEdit() @@ -175,7 +175,7 @@ protected:  								"panel_outfit_edit"));  		if (panel_outfit_edit != NULL)  		{ -			panel_outfit_edit->onReplaceMenuItemClicked(item_id); +			panel_outfit_edit->showAddWearablesPanel(true);  		}  	} @@ -187,7 +187,7 @@ protected:  		functor_t take_off = boost::bind(&LLAppearanceMgr::removeItemFromAvatar, LLAppearanceMgr::getInstance(), _1);  		registrar.add("Clothing.TakeOff", boost::bind(handleMultiple, take_off, mUUIDs)); -		registrar.add("Clothing.Replace", boost::bind(replaceWearable, selected_id)); +		registrar.add("Clothing.Replace", boost::bind(replaceWearable));  		registrar.add("Clothing.Edit", boost::bind(LLAgentWearables::editWearable, selected_id));  		registrar.add("Clothing.Create", boost::bind(&CofClothingContextMenu::createNew, this, selected_id)); @@ -244,7 +244,7 @@ protected:  		// *HACK* need to pass pointer to LLPanelOutfitEdit instead of LLSideTray::getInstance()->getPanel().  		// LLSideTray::getInstance()->getPanel() is rather slow variant  		LLPanelOutfitEdit* panel_oe = dynamic_cast<LLPanelOutfitEdit*>(LLSideTray::getInstance()->getPanel("panel_outfit_edit")); -		registrar.add("BodyPart.Replace", boost::bind(&LLPanelOutfitEdit::onReplaceMenuItemClicked, panel_oe, selected_id)); +		registrar.add("BodyPart.Replace", boost::bind(&LLPanelOutfitEdit::onReplaceBodyPartMenuItemClicked, panel_oe, selected_id));  		registrar.add("BodyPart.Edit", boost::bind(LLAgentWearables::editWearable, selected_id));  		registrar.add("BodyPart.Create", boost::bind(&CofBodyPartContextMenu::createNew, this, selected_id)); @@ -284,7 +284,8 @@ LLCOFWearables::LLCOFWearables() : LLPanel(),  	mAttachmentsTab(NULL),  	mBodyPartsTab(NULL),  	mLastSelectedTab(NULL), -	mCOFVersion(-1) +	mCOFVersion(-1), +	mAccordionCtrl(NULL)  {  	mClothingMenu = new CofClothingContextMenu(this);  	mAttachmentMenu = new CofAttachmentContextMenu(this); @@ -336,6 +337,8 @@ BOOL LLCOFWearables::postBuild()  	mTab2AssetType[mAttachmentsTab] = LLAssetType::AT_OBJECT;  	mTab2AssetType[mBodyPartsTab] = LLAssetType::AT_BODYPART; +	mAccordionCtrl = getChild<LLAccordionCtrl>("cof_wearables_accordion"); +  	return LLPanel::postBuild();  } @@ -652,20 +655,37 @@ LLAssetType::EType LLCOFWearables::getExpandedAccordionAssetType()  	typedef std::map<std::string, LLAssetType::EType> type_map_t;  	static type_map_t type_map; -	static LLAccordionCtrl* accordion_ctrl = getChild<LLAccordionCtrl>("cof_wearables_accordion"); -	const LLAccordionCtrlTab* expanded_tab = accordion_ctrl->getExpandedTab(); + +	if (mAccordionCtrl != NULL) +	{ +		const LLAccordionCtrlTab* expanded_tab = mAccordionCtrl->getExpandedTab();  	return get_if_there(mTab2AssetType, expanded_tab, LLAssetType::AT_NONE);  	} +	return LLAssetType::AT_NONE; +} +  LLAssetType::EType LLCOFWearables::getSelectedAccordionAssetType()  	{ -	static LLAccordionCtrl* accordion_ctrl = getChild<LLAccordionCtrl>("cof_wearables_accordion"); -	const LLAccordionCtrlTab* selected_tab = accordion_ctrl->getSelectedTab(); +	if (mAccordionCtrl != NULL) +	{ +		const LLAccordionCtrlTab* selected_tab = mAccordionCtrl->getSelectedTab();  	return get_if_there(mTab2AssetType, selected_tab, LLAssetType::AT_NONE);  } +	return LLAssetType::AT_NONE; +} + +void LLCOFWearables::expandDefaultAccordionTab() +{ +	if (mAccordionCtrl != NULL) +	{ +		mAccordionCtrl->expandDefaultTab(); +	} +} +  void LLCOFWearables::onListRightClick(LLUICtrl* ctrl, S32 x, S32 y, LLListContextMenu* menu)  {  	if(menu) diff --git a/indra/newview/llcofwearables.h b/indra/newview/llcofwearables.h index 511a65c31a..b23c097b21 100644 --- a/indra/newview/llcofwearables.h +++ b/indra/newview/llcofwearables.h @@ -40,6 +40,7 @@  #include "llappearancemgr.h"  #include "llinventorymodel.h" +class LLAccordionCtrl;  class LLAccordionCtrlTab;  class LLListContextMenu;  class LLPanelClothingListItem; @@ -87,6 +88,7 @@ public:  	LLAssetType::EType getExpandedAccordionAssetType();  	LLAssetType::EType getSelectedAccordionAssetType(); +	void expandDefaultAccordionTab();  	LLCOFCallbacks& getCOFCallbacks() { return mCOFCallbacks; } @@ -125,6 +127,8 @@ protected:  	LLListContextMenu* mAttachmentMenu;  	LLListContextMenu* mBodyPartMenu; +	LLAccordionCtrl*	mAccordionCtrl; +  	/* COF category version since last refresh */  	S32 mCOFVersion;  }; diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index c423473740..bb4e6c7a3e 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -167,6 +167,10 @@ void LLViewerDynamicTexture::postRender(BOOL success)  			{  				generateGLTexture() ;  			} +			if(!mGLTexturep->getHasGLTexture()) +			{ +				generateGLTexture() ; +			}  			llcallstacks << "class type: " << (S32)getType() << llcallstacksendl ;  			success = mGLTexturep->setSubImageFromFrameBuffer(0, 0, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight); diff --git a/indra/newview/llexpandabletextbox.cpp b/indra/newview/llexpandabletextbox.cpp index 8ccc5fb248..8c6265fbc2 100644 --- a/indra/newview/llexpandabletextbox.cpp +++ b/indra/newview/llexpandabletextbox.cpp @@ -141,13 +141,7 @@ void LLExpandableTextBox::LLTextBoxEx::setText(const LLStringExplicit& text,cons  	// LLTextBox::setText will obliterate the expander segment, so make sure  	// we generate it again by clearing mExpanderVisible  	mExpanderVisible = false; - -	// Workaround for EXT-8259: trim text before rendering it. -	{ -		std::string trimmed_text(text); -		LLStringUtil::trim(trimmed_text); -		LLTextEditor::setText(trimmed_text, input_params); -	} +	LLTextEditor::setText(text, input_params);  	// text contents have changed, segments are cleared out  	// so hide the expander and determine if we need it diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 5c26344436..625b443abc 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -2079,7 +2079,8 @@ void LLPanelLandOptions::refresh()  			LLStyle::Params style;  			style.image(LLUI::getUIImage(gFloaterView->getParentFloater(this)->getString("maturity_icon_moderate")));  			LLCheckBoxWithTBAcess* fullaccess_mature_ctrl = (LLCheckBoxWithTBAcess*)mMatureCtrl; -			fullaccess_mature_ctrl->getTextBox()->setText(std::string("icon"),style); +			fullaccess_mature_ctrl->getTextBox()->setText(LLStringExplicit("")); +			fullaccess_mature_ctrl->getTextBox()->appendImageSegment(style);  			fullaccess_mature_ctrl->getTextBox()->appendText(getString("mature_check_mature"), false);  			fullaccess_mature_ctrl->setToolTip(getString("mature_check_mature_tooltip"));  			fullaccess_mature_ctrl->reshape(fullaccess_mature_ctrl->getRect().getWidth(), fullaccess_mature_ctrl->getRect().getHeight(), FALSE); diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index d5e8801247..7fd073ea67 100644 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -206,6 +206,7 @@ LLFloaterWorldMap::LLFloaterWorldMap(const LLSD& key)  	mFactoryMap["objects_mapview"] = LLCallbackMap(createWorldMapView, NULL);  	//Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_world_map.xml", FALSE); +	mCommitCallbackRegistrar.add("WMap.Coordinates",	boost::bind(&LLFloaterWorldMap::onCoordinatesCommit, this));  	mCommitCallbackRegistrar.add("WMap.Location",		boost::bind(&LLFloaterWorldMap::onLocationCommit, this));  	mCommitCallbackRegistrar.add("WMap.AvatarCombo",	boost::bind(&LLFloaterWorldMap::onAvatarComboCommit, this));  	mCommitCallbackRegistrar.add("WMap.Landmark",		boost::bind(&LLFloaterWorldMap::onLandmarkComboCommit, this)); @@ -336,8 +337,6 @@ void LLFloaterWorldMap::onOpen(const LLSD& key)  	}  } - -  // static  void LLFloaterWorldMap::reloadIcons(void*)  { @@ -582,6 +581,10 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global)  		S32 world_y = S32(pos_global.mdV[1] / 256);  		LLWorldMapMessage::getInstance()->sendMapBlockRequest(world_x, world_y, world_x, world_y, true);  		setDefaultBtn(""); + +		// clicked on a non-region - turn off coord display +		enableTeleportCoordsDisplay( false ); +  		return;  	}  	if (sim_info->isDown()) @@ -592,6 +595,10 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global)  		LLWorldMap::getInstance()->setTrackingInvalid();  		LLTracker::stopTracking(NULL);  		setDefaultBtn(""); + +		// clicked on a down region - turn off coord display +		enableTeleportCoordsDisplay( false ); +  		return;  	} @@ -609,9 +616,40 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global)  	LLTracker::trackLocation(pos_global, full_name, tooltip);  	LLWorldMap::getInstance()->cancelTracking();		// The floater is taking over the tracking +	LLVector3d coord_pos = LLTracker::getTrackedPositionGlobal(); +	updateTeleportCoordsDisplay( coord_pos ); + +	// we have a valid region - turn on coord display +	enableTeleportCoordsDisplay( true ); +  	setDefaultBtn("Teleport");  } +// enable/disable teleport destination coordinates  +void LLFloaterWorldMap::enableTeleportCoordsDisplay( bool enabled ) +{ +	childSetEnabled("teleport_coordinate_x", enabled ); +	childSetEnabled("teleport_coordinate_y", enabled ); +	childSetEnabled("teleport_coordinate_z", enabled ); +} + +// update display of teleport destination coordinates - pos is in global coordinates +void LLFloaterWorldMap::updateTeleportCoordsDisplay( const LLVector3d& pos ) +{ +	// if we're going to update their value, we should also enable them +	enableTeleportCoordsDisplay( true ); + +	// convert global specified position to a local one +	F32 region_local_x = (F32)fmod( pos.mdV[VX], (F64)REGION_WIDTH_METERS ); +	F32 region_local_y = (F32)fmod( pos.mdV[VY], (F64)REGION_WIDTH_METERS ); +	F32 region_local_z = (F32)fmod( pos.mdV[VZ], (F64)REGION_WIDTH_METERS ); + +	// write in the values +	childSetValue("teleport_coordinate_x", region_local_x ); +	childSetValue("teleport_coordinate_y", region_local_y ); +	childSetValue("teleport_coordinate_z", region_local_z ); +} +  void LLFloaterWorldMap::updateLocation()  {  	bool gotSimName; @@ -638,6 +676,9 @@ void LLFloaterWorldMap::updateLocation()  				// Fill out the location field  				getChild<LLUICtrl>("location")->setValue(agent_sim_name); +				// update the coordinate display with location of avatar in region +				updateTeleportCoordsDisplay( agentPos ); +  				// Figure out where user is  				// Set the current SLURL  				mSLURL = LLSLURL(agent_sim_name, gAgent.getPositionGlobal()); @@ -668,6 +709,10 @@ void LLFloaterWorldMap::updateLocation()  		getChild<LLUICtrl>("location")->setValue(sim_name); +		// refresh coordinate display to reflect where user clicked. +		LLVector3d coord_pos = LLTracker::getTrackedPositionGlobal(); +		updateTeleportCoordsDisplay( coord_pos ); +  		// simNameFromPosGlobal can fail, so don't give the user an invalid SLURL  		if ( gotSimName )  		{ @@ -1139,6 +1184,22 @@ void LLFloaterWorldMap::onLocationCommit()  	}  } +void LLFloaterWorldMap::onCoordinatesCommit() +{ +	if( mIsClosing ) +	{ +		return; +	} + +	S32 x_coord = (S32)childGetValue("teleport_coordinate_x").asReal(); +	S32 y_coord = (S32)childGetValue("teleport_coordinate_y").asReal(); +	S32 z_coord = (S32)childGetValue("teleport_coordinate_z").asReal(); + +	const std::string region_name = childGetValue("location").asString(); + +	trackURL( region_name, x_coord, y_coord, z_coord ); +} +  void LLFloaterWorldMap::onClearBtn()  {  	mTrackedStatus = LLTracker::TRACKING_NOTHING; @@ -1199,6 +1260,9 @@ void LLFloaterWorldMap::centerOnTarget(BOOL animate)  	else if(LLWorldMap::getInstance()->isTracking())  	{  		pos_global = LLWorldMap::getInstance()->getTrackedPositionGlobal() - gAgentCamera.getCameraPositionGlobal();; + + +  	}  	else  	{ diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h index 550b4ef689..e31bafaf9b 100644 --- a/indra/newview/llfloaterworldmap.h +++ b/indra/newview/llfloaterworldmap.h @@ -149,6 +149,7 @@ protected:  	void			updateSearchEnabled();  	void			onLocationFocusChanged( LLFocusableElement* ctrl );  	void		    onLocationCommit(); +	void			onCoordinatesCommit();  	void		    onCommitSearchResult();  	void			cacheLandmarkPosition(); @@ -160,6 +161,12 @@ private:  	F32						mCurZoomVal;  	LLFrameTimer			mZoomTimer; +	// update display of teleport destination coordinates - pos is in global coordinates +	void updateTeleportCoordsDisplay( const LLVector3d& pos ); + +	// enable/disable teleport destination coordinates  +	void enableTeleportCoordsDisplay( bool enabled ); +  	LLDynamicArray<LLUUID>	mLandmarkAssetIDList;  	LLDynamicArray<LLUUID>	mLandmarkItemIDList; diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index 24e818908a..d3d52e20f7 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -1874,13 +1874,18 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )  		}  		// Successively filter out invalid options -		selected_items_t::iterator item_itor; +  		U32 flags = FIRST_SELECTED_ITEM; -		for (item_itor = mSelectedItems.begin(); item_itor != mSelectedItems.end(); ++item_itor) +		for (selected_items_t::iterator item_itor = mSelectedItems.begin();  +			 item_itor != mSelectedItems.end();  +			 ++item_itor)  		{ -			(*item_itor)->buildContextMenu(*menu, flags); +			LLFolderViewItem* selected_item = (*item_itor); +			selected_item->buildContextMenu(*menu, flags);  			flags = 0x0;  		} +	    +		addNoOptions(menu);  		menu->updateParent(LLMenuGL::sMenuContainer);  		LLMenuGL::showPopup(this, menu, x, y); @@ -1889,7 +1894,7 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )  	}  	else  	{ -		if(menu && menu->getVisible()) +		if (menu && menu->getVisible())  		{  			menu->setVisible(FALSE);  		} @@ -1898,6 +1903,37 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )  	return handled;  } +// Add "--no options--" if the menu is completely blank. +BOOL LLFolderView::addNoOptions(LLMenuGL* menu) const +{ +	const std::string nooptions_str = "--no options--"; +	LLView *nooptions_item = NULL; +	 +	const LLView::child_list_t *list = menu->getChildList(); +	for (LLView::child_list_t::const_iterator itor = list->begin();  +		 itor != list->end();  +		 ++itor) +	{ +		LLView *menu_item = (*itor); +		if (menu_item->getVisible()) +		{ +			return FALSE; +		} +		std::string name = menu_item->getName(); +		if (menu_item->getName() == nooptions_str) +		{ +			nooptions_item = menu_item; +		} +	} +	if (nooptions_item) +	{ +		nooptions_item->setVisible(TRUE); +		nooptions_item->setEnabled(FALSE); +		return TRUE; +	} +	return FALSE; +} +  BOOL LLFolderView::handleHover( S32 x, S32 y, MASK mask )  {  	return LLView::handleHover( x, y, mask ); diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h index 3944fa53c9..c69f08eb2d 100644 --- a/indra/newview/llfolderview.h +++ b/indra/newview/llfolderview.h @@ -263,6 +263,7 @@ public:  	BOOL needsAutoRename() { return mNeedsAutoRename; }  	void setNeedsAutoRename(BOOL val) { mNeedsAutoRename = val; }  	void setAutoSelectOverride(BOOL val) { mAutoSelectOverride = val; } +	void setPinningSelectedItem(BOOL val) { mPinningSelectedItem = val; }  	void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; } @@ -291,6 +292,8 @@ protected:  	bool selectFirstItem();  	bool selectLastItem(); +	BOOL addNoOptions(LLMenuGL* menu) const; +  protected:  	LLHandle<LLView>					mPopupMenuHandle; diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp index 7f28e09933..2f4dae0af8 100644 --- a/indra/newview/llfriendcard.cpp +++ b/indra/newview/llfriendcard.cpp @@ -299,6 +299,17 @@ void LLFriendCardsManager::collectFriendsLists(folderid_buddies_map_t& folderBud  {  	folderBuddiesMap.clear(); +	static bool syncronize_friends_folders = true; +	if (syncronize_friends_folders) +	{ +		// Checks whether "Friends" and "Friends/All" folders exist in "Calling Cards" folder, +		// fetches their contents if needed and synchronizes it with buddies list. +		// If the folders are not found they are created. +		LLFriendCardsManager::instance().syncFriendCardsFolders(); +		syncronize_friends_folders = false; +	} + +  	LLInventoryModel::cat_array_t* listFolders;  	LLInventoryModel::item_array_t* items; diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index 996553ccf7..d464b67105 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -903,7 +903,15 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data)  			if (member_id.notNull())  			{ -				formatDateString(online_status); // reformat for sorting, e.g. 12/25/2008 -> 2008/12/25 +				if (online_status == "Online") +				{ +					static std::string localized_online(LLTrans::getString("group_member_status_online")); +					online_status = localized_online; +				} +				else +				{ +					formatDateString(online_status); // reformat for sorting, e.g. 12/25/2008 -> 2008/12/25 +				}  				//llinfos << "Member " << member_id << " has powers " << std::hex << agent_powers << std::dec << llendl;  				LLGroupMemberData* newdata = new LLGroupMemberData(member_id,  diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index d2bddfdd9a..cd35ec5d39 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -237,6 +237,25 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&  		new LLSessionTimeoutTimer(mSessionID, SESSION_INITIALIZATION_TIMEOUT);  	} +	// *WORKAROUND: for server hard-coded string in indra\newsim\llsimchatterbox.cpp +	if (isAdHocSessionType() && IM_SESSION_INVITE == type) +	{ +		// For an ad-hoc incoming chat name is received from the server and is in a form of "<Avatar's name> Conference" +		// Lets update it to localize the "Conference" word. See EXT-8429. +		S32 separator_index = mName.rfind(" "); +		std::string name = mName.substr(0, separator_index); +		++separator_index; +		std::string conference_word = mName.substr(separator_index, mName.length()); + +		// additional check that session name is what we expected +		if ("Conference" == conference_word) +		{ +			LLStringUtil::format_map_t args; +			args["[AGENT_NAME]"] = name; +			LLTrans::findString(mName, "conference-title-incoming", args); +		} +	} +  	if (IM_NOTHING_SPECIAL == type)  	{  		mCallBackEnabled = LLVoiceClient::getInstance()->isSessionCallBackPossible(mSessionID); diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index ffa8a16797..57d31795ca 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -233,7 +233,8 @@ public:  	 * Get a session's name.   	 * For a P2P chat - it's an avatar's name,   	 * For a group chat - it's a group's name -	 * For an ad-hoc chat - is received from the server and is in a from of "<Avatar's name> conference" +	 * For an incoming ad-hoc chat - is received from the server and is in a from of "<Avatar's name> Conference" +	 *	It is updated in LLIMModel::LLIMSession's constructor to localize the "Conference".  	 */  	const std::string& getName(const LLUUID& session_id) const; diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 0b1408616e..38f3521b2d 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -952,6 +952,8 @@ void LLInvFVBridge::purgeItem(LLInventoryModel *model, const LLUUID &uuid)  BOOL LLInvFVBridge::canShare() const  { +	if (!isAgentInventory()) return FALSE; +  	const LLInventoryModel* model = getInventoryModel();  	if (!model) return FALSE; @@ -963,9 +965,10 @@ BOOL LLInvFVBridge::canShare() const  		return (BOOL)LLGiveInventory::isInventoryGiveAcceptable(item);  	} -	// All categories can be given. -	const LLViewerInventoryCategory* cat = model->getCategory(mUUID); -	return (cat != NULL); +	// Categories can be given. +	if (model->getCategory(mUUID)) return TRUE; + +	return FALSE;  }  // +=================================================+ @@ -2612,12 +2615,6 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  		mDisabledItems.push_back(std::string("Share"));  	} -	if (mItems.empty()) -	{ -		mItems.push_back(std::string("--no options--")); -		mDisabledItems.push_back(std::string("--no options--")); -	} -  	hide_context_entries(menu, mItems, mDisabledItems);  	// Add menu items that are dependent on the contents of the folder. diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index f20acbd016..303031ab29 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -221,7 +221,13 @@ BOOL get_is_item_worn(const LLUUID& id)  	const LLViewerInventoryItem* item = gInventory.getItem(id);  	if (!item)  		return FALSE; -	 + +	// Consider the item as worn if it has links in COF. +	if (LLAppearanceMgr::instance().isLinkInCOF(id)) +	{ +		return TRUE; +	} +  	switch(item->getType())  	{  		case LLAssetType::AT_OBJECT: @@ -250,7 +256,29 @@ BOOL get_can_item_be_worn(const LLUUID& id)  	const LLViewerInventoryItem* item = gInventory.getItem(id);  	if (!item)  		return FALSE; + +	if (LLAppearanceMgr::isLinkInCOF(item->getLinkedUUID())) +	{ +		// an item having links in COF (i.e. a worn item) +		return FALSE; +	} + +	if (gInventory.isObjectDescendentOf(id, LLAppearanceMgr::instance().getCOF())) +	{ +		// a non-link object in COF (should not normally happen) +		return FALSE; +	} +	const LLUUID trash_id = gInventory.findCategoryUUIDForType( +			LLFolderType::FT_TRASH); + +	// item can't be worn if base obj in trash, see EXT-7015 +	if (gInventory.isObjectDescendentOf(item->getLinkedUUID(), +			trash_id)) +	{ +		return false; +	} +  	switch(item->getType())  	{  		case LLAssetType::AT_OBJECT: diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index 4a7721098d..833ff3bfcd 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -301,6 +301,7 @@ public:  	virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item)  	{ +		//converting an inventory type to a bitmap filter mask  		if(item && (mFilterMask & (1LL << item->getInventoryType())) )  		{  			return true; diff --git a/indra/newview/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp index 3090371a73..2201481df3 100644 --- a/indra/newview/llinventoryicon.cpp +++ b/indra/newview/llinventoryicon.cpp @@ -117,6 +117,7 @@ const std::string& LLInventoryIcon::getIconName(LLAssetType::EType asset_type,  	if (item_is_multi)  	{  		idx = ICONNAME_OBJECT_MULTI; +		return getIconName(idx);  	}  	switch(asset_type) diff --git a/indra/newview/llinventorylistitem.cpp b/indra/newview/llinventorylistitem.cpp index ea57d36c06..b743ac3dcb 100644 --- a/indra/newview/llinventorylistitem.cpp +++ b/indra/newview/llinventorylistitem.cpp @@ -44,6 +44,7 @@  // newview  #include "llinventorymodel.h"  #include "llviewerinventory.h" +#include "llinventorydefines.h"  static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelInventoryListItemBaseParams(&typeid(LLPanelInventoryListItemBase::Params), "inventory_list_item"); @@ -96,9 +97,12 @@ void LLPanelInventoryListItemBase::draw()  	if (mSeparatorVisible && mSeparatorImage)  	{ -		// stretch along bottom of listitem, using image height +		// place under bottom of listitem, using image height +		// item_pad in list using the item should be >= image height +		// to avoid cropping of top of the next item.  		LLRect separator_rect = getLocalRect(); -		separator_rect.mTop = mSeparatorImage->getHeight(); +		separator_rect.mTop = separator_rect.mBottom; +		separator_rect.mBottom -= mSeparatorImage->getHeight();  		mSeparatorImage->draw(separator_rect);  	} @@ -163,7 +167,7 @@ BOOL LLPanelInventoryListItemBase::postBuild()  	LLViewerInventoryItem* inv_item = getItem();  	if (inv_item)  	{ -		mIconImage = LLInventoryIcon::getIcon(inv_item->getType(), inv_item->getInventoryType(), inv_item->getFlags(), FALSE); +		mIconImage = LLInventoryIcon::getIcon(inv_item->getType(), inv_item->getInventoryType(), inv_item->getFlags(), LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS & inv_item->getFlags());  		updateItem(inv_item->getName());  	} diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index 06f490e8e3..ae8efc01a3 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -58,6 +58,7 @@  #endif  #include "llsecapi.h"  #include "llstartup.h" +#include "llmachineid.h"  static const char * const TOS_REPLY_PUMP = "lllogininstance_tos_callback";  static const char * const TOS_LISTENER_NAME = "lllogininstance_tos"; @@ -165,22 +166,24 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia  	// (re)initialize the request params with creds.  	LLSD request_params = user_credential->getLoginParams(); -	char hashed_mac_string[MD5HEX_STR_SIZE];		/* Flawfinder: ignore */ -	LLMD5 hashed_mac; -	unsigned char MACAddress[MAC_ADDRESS_BYTES]; -	if(LLUUID::getNodeID(MACAddress) == 0) { -		llerrs << "Failed to get node id; cannot uniquely identify this machine." << llendl; +	char hashed_unique_id_string[MD5HEX_STR_SIZE];		/* Flawfinder: ignore */ +	LLMD5 hashed_unique_id; +	unsigned char unique_id[MAC_ADDRESS_BYTES]; +	if(LLUUID::getNodeID(unique_id) == 0) { +		if(LLMachineID::getUniqueID(unique_id, sizeof(unique_id)) == 0) { +			llerrs << "Failed to get an id; cannot uniquely identify this machine." << llendl; +		}  	} -	hashed_mac.update( MACAddress, MAC_ADDRESS_BYTES ); -	hashed_mac.finalize(); -	hashed_mac.hex_digest(hashed_mac_string); +	hashed_unique_id.update(unique_id, MAC_ADDRESS_BYTES); +	hashed_unique_id.finalize(); +	hashed_unique_id.hex_digest(hashed_unique_id_string);  	request_params["start"] = construct_start_string();  	request_params["skipoptional"] = mSkipOptionalUpdate;  	request_params["agree_to_tos"] = false; // Always false here. Set true in   	request_params["read_critical"] = false; // handleTOSResponse  	request_params["last_exec_event"] = mLastExecEvent; -	request_params["mac"] = hashed_mac_string; +	request_params["mac"] = hashed_unique_id_string;  	request_params["version"] = gCurrentVersion; // Includes channel name  	request_params["channel"] = gSavedSettings.getString("VersionChannelName");  	request_params["id0"] = mSerialNumber; diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp index 6ae4a5e5e4..fc41137686 100644 --- a/indra/newview/llmoveview.cpp +++ b/indra/newview/llmoveview.cpp @@ -83,6 +83,16 @@ LLFloaterMove::LLFloaterMove(const LLSD& key)  {  } +LLFloaterMove::~LLFloaterMove() +{ +	// Ensure LLPanelStandStopFlying panel is not among floater's children. See EXT-8458. +	setVisible(FALSE); + +	// Otherwise it can be destroyed and static pointer in LLPanelStandStopFlying::getInstance() will become invalid. +	// Such situation was possible when LLFloaterReg returns "dead" instance of floater. +	// Should not happen after LLFloater::destroy was modified to remove "dead" instances from LLFloaterReg. +} +  // virtual  BOOL LLFloaterMove::postBuild()  { diff --git a/indra/newview/llmoveview.h b/indra/newview/llmoveview.h index d463861188..43b0342744 100644 --- a/indra/newview/llmoveview.h +++ b/indra/newview/llmoveview.h @@ -51,7 +51,7 @@ class LLFloaterMove  private:  	LLFloaterMove(const LLSD& key); -	~LLFloaterMove() {} +	~LLFloaterMove();  public:  	/*virtual*/	BOOL	postBuild(); diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp index a300e15edd..6cfd810c10 100644 --- a/indra/newview/llnearbychatbar.cpp +++ b/indra/newview/llnearbychatbar.cpp @@ -317,9 +317,19 @@ void LLGestureComboList::refreshGestures()  	if (gestures)  	{ -		S32 index = gestures->getSelectedValue().asInteger(); -		if(index > 0) -			gesture = mGestures.at(index); +		S32 sel_index = gestures->getFirstSelectedIndex(); +		if (sel_index != 0) +		{ +			S32 index = gestures->getSelectedValue().asInteger(); +			if (index<0 || index >= (S32)mGestures.size()) +			{ +				llwarns << "out of range gesture access" << llendl; +			} +			else +			{ +				gesture = mGestures.at(index); +			} +		}  	}  	if(gesture && LLGestureMgr::instance().isGesturePlaying(gesture)) @@ -335,13 +345,13 @@ void LLGestureComboList::onCommitGesture()  	LLCtrlListInterface* gestures = getListInterface();  	if (gestures)  	{ -		S32 index = gestures->getFirstSelectedIndex(); -		if (index == 0) +		S32 sel_index = gestures->getFirstSelectedIndex(); +		if (sel_index == 0)  		{  			return;  		} -		index = gestures->getSelectedValue().asInteger(); +		S32 index = gestures->getSelectedValue().asInteger();  		if (mViewAllItemIndex == index)  		{ @@ -357,13 +367,20 @@ void LLGestureComboList::onCommitGesture()  			return;  		} -		LLMultiGesture* gesture = mGestures.at(index); -		if(gesture) +		if (index<0 || index >= (S32)mGestures.size()) +		{ +			llwarns << "out of range gesture index" << llendl; +		} +		else  		{ -			LLGestureMgr::instance().playGesture(gesture); -			if(!gesture->mReplaceText.empty()) +			LLMultiGesture* gesture = mGestures.at(index); +			if(gesture)  			{ -				LLNearbyChatBar::sendChatFromViewer(gesture->mReplaceText, CHAT_TYPE_NORMAL, FALSE); +				LLGestureMgr::instance().playGesture(gesture); +				if(!gesture->mReplaceText.empty()) +				{ +					LLNearbyChatBar::sendChatFromViewer(gesture->mReplaceText, CHAT_TYPE_NORMAL, FALSE); +				}  			}  		}  	} @@ -374,6 +391,11 @@ LLGestureComboList::~LLGestureComboList()  	LLGestureMgr::instance().removeObserver(this);  } +LLCtrlListInterface* LLGestureComboList::getListInterface() +{ +	return mList; +} +  LLNearbyChatBar::LLNearbyChatBar()   	: LLPanel()  	, mChatBox(NULL) diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h index 83c174fd10..0eaa60ce81 100644 --- a/indra/newview/llnearbychatbar.h +++ b/indra/newview/llnearbychatbar.h @@ -68,7 +68,7 @@ public:  	~LLGestureComboList(); -	LLCtrlListInterface* getListInterface()		{ return (LLCtrlListInterface*)mList; }; +	LLCtrlListInterface* getListInterface();  	virtual void	showList();  	virtual void	hideList();  	virtual BOOL	handleKeyHere(KEY key, MASK mask); diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 63ffb80ff2..8147a97317 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -665,7 +665,18 @@ bool LLOutfitsList::isActionEnabled(const LLSD& userdata)  	}  	if (command_name == "wear")  	{ -		return !gAgentWearables.isCOFChangeInProgress(); +		if (gAgentWearables.isCOFChangeInProgress()) +		{ +			return false; +		} + +		if (hasItemSelected()) +		{ +			return canWearSelected(); +		} + +		// outfit selected +		return LLAppearanceMgr::getCanAddToCOF(mSelectedOutfitUUID);  	}  	if (command_name == "take_off")  	{ @@ -677,6 +688,7 @@ bool LLOutfitsList::isActionEnabled(const LLSD& userdata)  	if (command_name == "wear_add")  	{ +		// *TODO: do we ever get here?  		if (gAgentWearables.isCOFChangeInProgress())  		{  			return false; @@ -984,6 +996,26 @@ bool LLOutfitsList::canTakeOffSelected()  	return false;  } +bool LLOutfitsList::canWearSelected() +{ +	uuid_vec_t selected_items; +	getSelectedItemsUUIDs(selected_items); + +	for (uuid_vec_t::const_iterator it = selected_items.begin(); it != selected_items.end(); ++it) +	{ +		const LLUUID& id = *it; + +		// Check whether the item is worn. +		if (!get_can_item_be_worn(id)) +		{ +			return false; +		} +	} + +	// All selected items can be worn. +	return true; +} +  void LLOutfitsList::onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id)  {  	LLAccordionCtrlTab* tab = dynamic_cast<LLAccordionCtrlTab*>(ctrl); diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h index d7cf8a8c08..206854b232 100644 --- a/indra/newview/lloutfitslist.h +++ b/indra/newview/lloutfitslist.h @@ -183,6 +183,11 @@ private:  	 */  	bool canTakeOffSelected(); +	/** +	 * Returns true if all selected items can be worn. +	 */ +	bool canWearSelected(); +  	void onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id);  	void onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y);  	void onCOFChanged(); diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index d8ae6ad9f4..c928d83965 100644 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -47,6 +47,7 @@  #include "llvoavatarself.h"  #include "lltexteditor.h"  #include "lltextbox.h" +#include "llaccordionctrl.h"  #include "llaccordionctrltab.h"  #include "llagentwearables.h"  #include "llscrollingpanelparam.h" @@ -666,6 +667,35 @@ void LLPanelEditWearable::updateAvatarHeightLabel()  	mTxtAvatarHeight->appendText(this->mReplacementMetricUrl, false, param);  } +void LLPanelEditWearable::onWearablePanelVisibilityChange(const LLSD &in_visible_chain, LLAccordionCtrl* accordion_ctrl) +{ +	if (in_visible_chain.asBoolean() && accordion_ctrl != NULL) +	{ +		accordion_ctrl->expandDefaultTab(); +	} +} + +void LLPanelEditWearable::setWearablePanelVisibilityChangeCallback(LLPanel* bodypart_panel) +{ +	if (bodypart_panel != NULL) +	{ +		LLAccordionCtrl* accordion_ctrl = bodypart_panel->getChild<LLAccordionCtrl>("wearable_accordion"); + +		if (accordion_ctrl != NULL) +		{ +			bodypart_panel->setVisibleCallback( +					boost::bind(&LLPanelEditWearable::onWearablePanelVisibilityChange, this, _2, accordion_ctrl)); +		} +		else +		{ +			llwarns << "accordion_ctrl is NULL" << llendl; +		} +	} +	else +	{ +		llwarns << "bodypart_panel is NULL" << llendl; +	} +}  // virtual   BOOL LLPanelEditWearable::postBuild() @@ -695,6 +725,14 @@ BOOL LLPanelEditWearable::postBuild()  	mPanelEyes = getChild<LLPanel>("edit_eyes_panel");  	mPanelHair = getChild<LLPanel>("edit_hair_panel"); +	// Setting the visibility callback is applied only to the bodyparts panel +	// because currently they are the only ones whose 'wearable_accordion' has +	// multiple accordion tabs (see EXT-8164 for details). +	setWearablePanelVisibilityChangeCallback(mPanelShape); +	setWearablePanelVisibilityChangeCallback(mPanelSkin); +	setWearablePanelVisibilityChangeCallback(mPanelEyes); +	setWearablePanelVisibilityChangeCallback(mPanelHair); +  	//clothes  	mPanelShirt = getChild<LLPanel>("edit_shirt_panel");  	mPanelPants = getChild<LLPanel>("edit_pants_panel"); @@ -905,7 +943,7 @@ void LLPanelEditWearable::onTexturePickerCommit(const LLUICtrl* ctrl)  		{  			// Set the new version  			LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(texture_ctrl->getImageAssetID()); -			if( image->getID().isNull() ) +			if( image->getID() == IMG_DEFAULT )  			{  				image = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR);  			} diff --git a/indra/newview/llpaneleditwearable.h b/indra/newview/llpaneleditwearable.h index 1c980c207e..03b2cb7932 100644 --- a/indra/newview/llpaneleditwearable.h +++ b/indra/newview/llpaneleditwearable.h @@ -39,6 +39,7 @@  #include "llvoavatardefines.h"  #include "llwearabletype.h" +class LLAccordionCtrl;  class LLCheckBoxCtrl;  class LLWearable;  class LLTextBox; @@ -115,6 +116,10 @@ private:  	// updates avatar height label  	void updateAvatarHeightLabel(); +	void onWearablePanelVisibilityChange(const LLSD &in_visible_chain, LLAccordionCtrl* accordion_ctrl); + +	void setWearablePanelVisibilityChangeCallback(LLPanel* bodypart_panel); +  	// the pointer to the wearable we're editing. NULL means we're not editing a wearable.  	LLWearable *mWearablePtr;  	LLViewerInventoryItem* mWearableItem; diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp index 62852f98d9..c383d04940 100644 --- a/indra/newview/llpanelgroup.cpp +++ b/indra/newview/llpanelgroup.cpp @@ -182,6 +182,11 @@ BOOL LLPanelGroup::postBuild()  	LLPanelGroupTab* panel_notices = findChild<LLPanelGroupTab>("group_notices_tab_panel");  	LLPanelGroupTab* panel_land = findChild<LLPanelGroupTab>("group_land_tab_panel"); +	if (LLAccordionCtrl* accordion_ctrl = getChild<LLAccordionCtrl>("groups_accordion")) +	{ +		setVisibleCallback(boost::bind(&LLPanelGroup::onVisibilityChange, this, _2, accordion_ctrl)); +	} +  	if(panel_general)	mTabs.push_back(panel_general);  	if(panel_roles)		mTabs.push_back(panel_roles);  	if(panel_notices)	mTabs.push_back(panel_notices); @@ -305,6 +310,13 @@ void LLPanelGroup::onBtnCancel()  	onBackBtnClick();  } +void LLPanelGroup::onVisibilityChange(const LLSD &in_visible_chain, LLAccordionCtrl* accordion_ctrl) +{ +	if (in_visible_chain.asBoolean() && accordion_ctrl != NULL) +	{ +		accordion_ctrl->expandDefaultTab(); +	} +}  void LLPanelGroup::changed(LLGroupChange gc)  { @@ -321,7 +333,7 @@ void LLPanelGroup::onChange(EStatusType status, const std::string &channelURI, b  		return;  	} -	getChildView("btn_call")->setEnabled(LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking()); +	childSetEnabled("btn_call", LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking());  }  void LLPanelGroup::notifyObservers() @@ -335,8 +347,8 @@ void LLPanelGroup::update(LLGroupChange gc)  	if(gdatap)  	{  		std::string group_name =  gdatap->mName.empty() ? LLTrans::getString("LoadingData") : gdatap->mName; -		getChild<LLUICtrl>("group_name")->setValue(group_name); -		getChildView("group_name")->setToolTip(group_name); +		childSetValue("group_name", group_name); +		childSetToolTip("group_name",group_name);  		LLGroupData agent_gdatap;  		bool is_member = gAgent.getGroupData(mID,agent_gdatap) || gAgent.isGodlike(); @@ -382,8 +394,8 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id)  	if(gdatap)  	{  		std::string group_name =  gdatap->mName.empty() ? LLTrans::getString("LoadingData") : gdatap->mName; -		getChild<LLUICtrl>("group_name")->setValue(group_name); -		getChildView("group_name")->setToolTip(group_name); +		childSetValue("group_name", group_name); +		childSetToolTip("group_name",group_name);  	}  	LLButton* button_apply = findChild<LLButton>("btn_apply"); @@ -413,19 +425,14 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id)  	getChild<LLUICtrl>("prepend_founded_by")->setVisible(!is_null_group_id); -	LLAccordionCtrl* tab_ctrl = findChild<LLAccordionCtrl>("group_accordion"); -	if(tab_ctrl) -		tab_ctrl->reset(); - -	LLAccordionCtrlTab* tab_general = findChild<LLAccordionCtrlTab>("group_general_tab"); -	LLAccordionCtrlTab* tab_roles = findChild<LLAccordionCtrlTab>("group_roles_tab"); -	LLAccordionCtrlTab* tab_notices = findChild<LLAccordionCtrlTab>("group_notices_tab"); -	LLAccordionCtrlTab* tab_land = findChild<LLAccordionCtrlTab>("group_land_tab"); +	LLAccordionCtrl* tab_ctrl = getChild<LLAccordionCtrl>("groups_accordion"); +	tab_ctrl->reset(); +	LLAccordionCtrlTab* tab_general = getChild<LLAccordionCtrlTab>("group_general_tab"); +	LLAccordionCtrlTab* tab_roles = getChild<LLAccordionCtrlTab>("group_roles_tab"); +	LLAccordionCtrlTab* tab_notices = getChild<LLAccordionCtrlTab>("group_notices_tab"); +	LLAccordionCtrlTab* tab_land = getChild<LLAccordionCtrlTab>("group_land_tab"); -	if(!tab_general || !tab_roles || !tab_notices || !tab_land) -		return; -	  	if(mButtonJoin)  		mButtonJoin->setVisible(false); @@ -486,6 +493,8 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id)  			button_chat->setVisible(is_member);  	} +	tab_ctrl->arrange(); +  	reposButtons();  	update(GC_ALL);//show/hide "join" button if data is already ready  } @@ -535,7 +544,8 @@ void LLPanelGroup::draw()  	if (mRefreshTimer.hasExpired())  	{  		mRefreshTimer.stop(); -		getChildView("btn_refresh")->setEnabled(TRUE); +		childEnable("btn_refresh"); +		childEnable("groups_accordion");  	}  	LLButton* button_apply = findChild<LLButton>("btn_apply"); @@ -547,7 +557,7 @@ void LLPanelGroup::draw()  		for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it)  			enable = enable || (*it)->needsApply(mesg); -		getChildView("btn_apply")->setEnabled(enable); +		childSetEnabled("btn_apply", enable);  	}  } @@ -563,7 +573,9 @@ void LLPanelGroup::refreshData()  	setGroupID(getID());  	// 5 second timeout -	getChildView("btn_refresh")->setEnabled(FALSE); +	childDisable("btn_refresh"); +	childDisable("groups_accordion"); +  	mRefreshTimer.start();  	mRefreshTimer.setTimerExpirySec(5);  } diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h index 13a03b0713..2b21e9895a 100644 --- a/indra/newview/llpanelgroup.h +++ b/indra/newview/llpanelgroup.h @@ -42,6 +42,7 @@ class LLOfferInfo;  const S32 UPDATE_MEMBERS_PER_FRAME = 500;  // Forward declares +class LLAccordionCtrl;  class LLPanelGroupTab;  class LLTabContainer;  class LLAgent; @@ -102,6 +103,7 @@ protected:  	void onBackBtnClick();  	void onBtnJoin();  	void onBtnCancel(); +	void onVisibilityChange(const LLSD &in_visible_chain, LLAccordionCtrl* accordion_ctrl);  	static void onBtnApply(void*);  	static void onBtnRefresh(void*); @@ -126,7 +128,6 @@ protected:  	LLButton*		mButtonJoin;  	LLUICtrl*		mJoinText; -  };  class LLPanelGroupTab : public LLPanel diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index 8e1b7ba4d9..2302772803 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -184,8 +184,7 @@ BOOL LLPanelGroupGeneral::postBuild()  	mComboActiveTitle = getChild<LLComboBox>("active_title", recurse);  	if (mComboActiveTitle)  	{ -		mComboActiveTitle->setCommitCallback(onCommitTitle, this); -		mComboActiveTitle->resetDirty(); +		mComboActiveTitle->setCommitCallback(onCommitAny, this);  	}  	mIncompleteMemberDataStr = getString("incomplete_member_data_str"); @@ -278,16 +277,6 @@ void LLPanelGroupGeneral::onCommitEnrollment(LLUICtrl* ctrl, void* data)  }  // static -void LLPanelGroupGeneral::onCommitTitle(LLUICtrl* ctrl, void* data) -{ -	LLPanelGroupGeneral* self = (LLPanelGroupGeneral*)data; -	if (self->mGroupID.isNull() || !self->mAllowEdit) return; -	LLGroupMgr::getInstance()->sendGroupTitleUpdate(self->mGroupID,self->mComboActiveTitle->getCurrentID()); -	self->update(GC_TITLES); -	self->mComboActiveTitle->resetDirty(); -} - -// static  void LLPanelGroupGeneral::onClickInfo(void *userdata)  {  	LLPanelGroupGeneral *self = (LLPanelGroupGeneral *)userdata; @@ -356,6 +345,13 @@ void LLPanelGroupGeneral::draw()  bool LLPanelGroupGeneral::apply(std::string& mesg)  { +	if (!mGroupID.isNull() && mAllowEdit && mComboActiveTitle && mComboActiveTitle->isDirty()) +	{ +		LLGroupMgr::getInstance()->sendGroupTitleUpdate(mGroupID,mComboActiveTitle->getCurrentID()); +		update(GC_TITLES); +		mComboActiveTitle->resetDirty(); +	} +  	BOOL has_power_in_group = gAgent.hasPowerInGroup(mGroupID,GP_GROUP_CHANGE_IDENTITY);  	if (has_power_in_group || mGroupID.isNull()) diff --git a/indra/newview/llpanelgroupgeneral.h b/indra/newview/llpanelgroupgeneral.h index 6f4fa994da..358d353074 100644 --- a/indra/newview/llpanelgroupgeneral.h +++ b/indra/newview/llpanelgroupgeneral.h @@ -77,7 +77,6 @@ private:  	static void onFocusEdit(LLFocusableElement* ctrl, void* data);  	static void onCommitAny(LLUICtrl* ctrl, void* data);  	static void onCommitUserOnly(LLUICtrl* ctrl, void* data); -	static void onCommitTitle(LLUICtrl* ctrl, void* data);  	static void onCommitEnrollment(LLUICtrl* ctrl, void* data);  	static void onClickInfo(void* userdata);  	static void onReceiveNotices(LLUICtrl* ctrl, void* data); diff --git a/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp index 7f4a273e32..1404cfcea2 100644 --- a/indra/newview/llpanelgrouplandmoney.cpp +++ b/indra/newview/llpanelgrouplandmoney.cpp @@ -1432,10 +1432,10 @@ void LLGroupMoneyPlanningTabEventHandler::processReply(LLMessageSystem* msg,  // 	text.append(llformat( "%-24s %6d      %6d \n", LLTrans::getString("GroupMoneyDebits").c_str(), total_debits, (S32)floor((F32)total_debits/(F32)non_exempt_members)));  // 	text.append(llformat( "%-24s %6d      %6d \n", LLTrans::getString("GroupMoneyTotal").c_str(), total_credits + total_debits,  (S32)floor((F32)(total_credits + total_debits)/(F32)non_exempt_members))); -	text.append( "                      Group\n"); -	text.append(llformat( "%-24s %6d\n", "Credits", total_credits)); -	text.append(llformat( "%-24s %6d\n", "Debits", total_debits)); -	text.append(llformat( "%-24s %6d\n", "Total", total_credits + total_debits)); +	text.append(llformat( "%s\n", LLTrans::getString("GroupColumn").c_str())); +	text.append(llformat( "%-24s %6d\n", LLTrans::getString("GroupMoneyCredits").c_str(), total_credits)); +	text.append(llformat( "%-24s %6d\n", LLTrans::getString("GroupMoneyDebits").c_str(), total_debits)); +	text.append(llformat( "%-24s %6d\n", LLTrans::getString("GroupMoneyTotal").c_str(), total_credits + total_debits));  	if ( mImplementationp->mTextEditorp )  	{ diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index 26e8a932aa..7a28d10baf 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -51,6 +51,7 @@  #include "lltabcontainer.h"  #include "lltextbox.h"  #include "lltexteditor.h" +#include "lltrans.h"  #include "llviewertexturelist.h"  #include "llviewerwindow.h"  #include "llfocusmgr.h" @@ -587,7 +588,7 @@ void LLPanelGroupSubTab::buildActionCategory(LLScrollListCtrl* ctrl,  		row["columns"][1]["column"] = "action";  		row["columns"][1]["type"] = "text"; -		row["columns"][1]["value"] = action_set->mActionSetData->mName; +		row["columns"][1]["value"] = LLTrans::getString(action_set->mActionSetData->mName);  		row["columns"][1]["font"]["name"] = "SANSSERIF_SMALL"; @@ -1593,6 +1594,7 @@ void LLPanelGroupMembersSubTab::updateMembers()  	LLGroupMgrGroupData::member_list_t::iterator end = gdatap->mMembers.end(); +	LLUIString donated = getString("donation_area");  	S32 i = 0;  	for( ; mMemberProgress != end && i<UPDATE_MEMBERS_PER_FRAME;  @@ -1614,9 +1616,7 @@ void LLPanelGroupMembersSubTab::updateMembers()  		if (add_member)  		{ -			// Build the donated tier string. -			std::ostringstream donated; -			donated << mMemberProgress->second->getContribution() << " sq. m."; +			donated.setArg("[AREA]", llformat("%d", mMemberProgress->second->getContribution()));  			LLSD row;  			row["id"] = (*mMemberProgress).first; @@ -1625,7 +1625,7 @@ void LLPanelGroupMembersSubTab::updateMembers()  			// value is filled in by name list control  			row["columns"][1]["column"] = "donated"; -			row["columns"][1]["value"] = donated.str(); +			row["columns"][1]["value"] = donated.getString();  			row["columns"][2]["column"] = "online";  			row["columns"][2]["value"] = mMemberProgress->second->getOnlineStatus(); diff --git a/indra/newview/llpanellandmarkinfo.cpp b/indra/newview/llpanellandmarkinfo.cpp index 4ffd43cb0f..c05cffc59e 100644 --- a/indra/newview/llpanellandmarkinfo.cpp +++ b/indra/newview/llpanellandmarkinfo.cpp @@ -123,11 +123,54 @@ void LLPanelLandmarkInfo::setInfoType(EInfoType type)  	switch(type)  	{  		case CREATE_LANDMARK: +		{  			mCurrentTitle = getString("title_create_landmark");  			mLandmarkTitle->setVisible(FALSE);  			mLandmarkTitleEditor->setVisible(TRUE);  			mNotesEditor->setEnabled(TRUE); + +			LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance(); +			std::string name = parcel_mgr->getAgentParcelName(); +			LLVector3 agent_pos = gAgent.getPositionAgent(); + +			if (name.empty()) +			{ +				S32 region_x = llround(agent_pos.mV[VX]); +				S32 region_y = llround(agent_pos.mV[VY]); +				S32 region_z = llround(agent_pos.mV[VZ]); + +				std::string region_name; +				LLViewerRegion* region = parcel_mgr->getSelectionRegion(); +				if (region) +				{ +					region_name = region->getName(); +				} +				else +				{ +					region_name = getString("unknown"); +				} + +				mLandmarkTitleEditor->setText(llformat("%s (%d, %d, %d)", +									  region_name.c_str(), region_x, region_y, region_z)); +			} +			else +			{ +				mLandmarkTitleEditor->setText(name); +			} + +			std::string desc; +			LLAgentUI::buildLocationString(desc, LLAgentUI::LOCATION_FORMAT_FULL, agent_pos); +			mNotesEditor->setText(desc); + +			// Moved landmark creation here from LLPanelLandmarkInfo::processParcelInfo() +			// because we use only agent's current coordinates instead of waiting for +			// remote parcel request to complete. +			if (!LLLandmarkActions::landmarkAlreadyExists()) +			{ +				createLandmark(LLUUID()); +			} +		}  		break;  		case LANDMARK: @@ -192,28 +235,6 @@ void LLPanelLandmarkInfo::processParcelInfo(const LLParcelData& parcel_data)  	info["global_y"] = parcel_data.global_y;  	info["global_z"] = parcel_data.global_z;  	notifyParent(info); - -	if (mInfoType == CREATE_LANDMARK) -	{ -		if (parcel_data.name.empty()) -		{ -			mLandmarkTitleEditor->setText(llformat("%s (%d, %d, %d)", -								  parcel_data.sim_name.c_str(), region_x, region_y, region_z)); -		} -		else -		{ -			mLandmarkTitleEditor->setText(parcel_data.name); -		} - -		std::string desc; -		LLAgentUI::buildLocationString(desc, LLAgentUI::LOCATION_FORMAT_FULL, gAgent.getPositionAgent()); -		mNotesEditor->setText(desc); - -		if (!LLLandmarkActions::landmarkAlreadyExists()) -		{ -			createLandmark(mFolderCombo->getValue().asUUID()); -		} -	}  }  void LLPanelLandmarkInfo::displayItemInfo(const LLInventoryItem* pItem) diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index ca1361c84b..116e5ba4cb 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -750,8 +750,6 @@ void LLTaskCategoryBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  {  	std::vector<std::string> items;  	std::vector<std::string> disabled_items; -	items.push_back(std::string("--no options--")); -	disabled_items.push_back(std::string("--no options--"));  	hide_context_entries(menu, items, disabled_items);  } diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index b37fc23f95..17e7965ab7 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -44,6 +44,7 @@  #include "llfilteredwearablelist.h"  #include "llfolderviewitem.h"  #include "llinventory.h" +#include "llinventoryitemslist.h"  #include "llviewercontrol.h"  #include "llui.h"  #include "llfloater.h" @@ -85,11 +86,6 @@ const U64 ALL_ITEMS_MASK = WEARABLE_MASK | ATTACHMENT_MASK;  static const std::string REVERT_BTN("revert_btn"); - -/////////////////////////////////////////////////////////////////////////////// -// LLShopURLDispatcher -/////////////////////////////////////////////////////////////////////////////// -  class LLShopURLDispatcher  {  public: @@ -149,10 +145,6 @@ std::string LLShopURLDispatcher::resolveURL(LLAssetType::EType asset_type, ESex  	return gSavedSettings.getString(setting_name);  } -/////////////////////////////////////////////////////////////////////////////// -// LLPanelOutfitEditGearMenu -/////////////////////////////////////////////////////////////////////////////// -  class LLPanelOutfitEditGearMenu  {  public: @@ -168,6 +160,7 @@ public:  		if (menu)  		{  			populateCreateWearableSubmenus(menu); +			menu->buildDrawLabels();  		}  		return menu; @@ -216,131 +209,6 @@ private:  	}  }; -/////////////////////////////////////////////////////////////////////////////// -// LLAddWearablesGearMenu -/////////////////////////////////////////////////////////////////////////////// - -class LLAddWearablesGearMenu : public LLInitClass<LLAddWearablesGearMenu> -{ -public: -	static LLMenuGL* create(LLWearableItemsList* flat_list, LLInventoryPanel* inventory_panel) -	{ -		LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; -		LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; - -		llassert(flat_list); -		llassert(inventory_panel); - -		registrar.add("AddWearable.Gear.Sort", boost::bind(onSort, flat_list, inventory_panel, _2)); -		enable_registrar.add("AddWearable.Gear.Check", boost::bind(onCheck, flat_list, inventory_panel, _2)); -		enable_registrar.add("AddWearable.Gear.Visible", boost::bind(onVisible, inventory_panel, _2)); - -		LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>( -			"menu_add_wearable_gear.xml", -			LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance()); - -		return menu; -	} - -private: -	static void onSort(LLWearableItemsList* flat_list, -					   LLInventoryPanel* inventory_panel, -					   LLSD::String sort_order_str) -	{ -		if (!flat_list || !inventory_panel) return; - -		LLWearableItemsList::ESortOrder	sort_order; - -		if ("by_most_recent" == sort_order_str) -		{ -			sort_order = LLWearableItemsList::E_SORT_BY_MOST_RECENT; -		} -		else if ("by_name" == sort_order_str) -		{ -			sort_order = LLWearableItemsList::E_SORT_BY_NAME; -		} -		else if ("by_type" == sort_order_str) -		{ -			sort_order = LLWearableItemsList::E_SORT_BY_TYPE; -		} -		else -		{ -			llwarns << "Unrecognized sort order action" << llendl; -			return; -		} - -		if (inventory_panel->getVisible()) -		{ -			inventory_panel->setSortOrder(sort_order); -		} -		else -		{ -			flat_list->setSortOrder(sort_order); -			gSavedSettings.setU32("AddWearableSortOrder", sort_order); -		} -	} - -	static bool onCheck(LLWearableItemsList* flat_list, -						LLInventoryPanel* inventory_panel, -						LLSD::String sort_order_str) -	{ -		if (!inventory_panel || !flat_list) return false; - -		// Inventory panel uses its own sort order independent from -		// flat list view so this flag is used to distinguish between -		// currently visible "tree" or "flat" representation of inventory. -		bool inventory_tree_visible = inventory_panel->getVisible(); - -		if (inventory_tree_visible) -		{ -			U32 sort_order = inventory_panel->getSortOrder(); - -			if ("by_most_recent" == sort_order_str) -			{ -				return LLWearableItemsList::E_SORT_BY_MOST_RECENT & sort_order; -			} -			else if ("by_name" == sort_order_str) -			{ -				// If inventory panel is not sorted by date then it is sorted by name. -				return LLWearableItemsList::E_SORT_BY_MOST_RECENT & ~sort_order; -			} -			llwarns << "Unrecognized inventory panel sort order" << llendl; -		} -		else -		{ -			LLWearableItemsList::ESortOrder	sort_order = flat_list->getSortOrder(); - -			if ("by_most_recent" == sort_order_str) -			{ -				return LLWearableItemsList::E_SORT_BY_MOST_RECENT == sort_order; -			} -			else if ("by_name" == sort_order_str) -			{ -				return LLWearableItemsList::E_SORT_BY_NAME == sort_order; -			} -			else if ("by_type" == sort_order_str) -			{ -				return LLWearableItemsList::E_SORT_BY_TYPE == sort_order; -			} -			llwarns << "Unrecognized wearable list sort order" << llendl; -		} -		return false; -	} - -	static bool onVisible(LLInventoryPanel* inventory_panel, -						  LLSD::String sort_order_str) -	{ -		// Enable sorting by type only for the flat list of items -		// because inventory panel doesn't support this kind of sorting. -		return ( "by_type" == sort_order_str ) -				&&	( !inventory_panel || !inventory_panel->getVisible() ); -	} -}; - -/////////////////////////////////////////////////////////////////////////////// -// LLCOFDragAndDropObserver -/////////////////////////////////////////////////////////////////////////////// -  class LLCOFDragAndDropObserver : public LLInventoryAddItemByAssetObserver  {  public: @@ -376,17 +244,12 @@ void LLCOFDragAndDropObserver::done()  	LLAppearanceMgr::instance().updateAppearanceFromCOF();  } -/////////////////////////////////////////////////////////////////////////////// -// LLPanelOutfitEdit -/////////////////////////////////////////////////////////////////////////////// -  LLPanelOutfitEdit::LLPanelOutfitEdit()  :	LLPanel(),   	mSearchFilter(NULL),  	mCOFWearables(NULL),  	mInventoryItemsPanel(NULL),  	mGearMenu(NULL), -	mAddWearablesGearMenu(NULL),  	mCOFDragAndDropObserver(NULL),  	mInitialized(false),  	mAddWearablesPanel(NULL), @@ -421,6 +284,8 @@ LLPanelOutfitEdit::~LLPanelOutfitEdit()  	delete mCOFDragAndDropObserver; +	delete mWearableListViewItemsComparator; +  	while (!mListViewItemTypes.empty()) {  		delete mListViewItemTypes.back();  		mListViewItemTypes.pop_back(); @@ -439,7 +304,7 @@ BOOL LLPanelOutfitEdit::postBuild()  	mListViewItemTypes.push_back(new LLFilterItem(getString("Filter.All"), new LLFindNonLinksByMask(ALL_ITEMS_MASK)));  	mListViewItemTypes.push_back(new LLFilterItem(getString("Filter.Clothing"), new LLIsTypeActual(LLAssetType::AT_CLOTHING)));  	mListViewItemTypes.push_back(new LLFilterItem(getString("Filter.Bodyparts"), new LLIsTypeActual(LLAssetType::AT_BODYPART))); -	mListViewItemTypes.push_back(new LLFilterItem(getString("Filter.Objects"), new LLFindByMask(ATTACHMENT_MASK)));; +	mListViewItemTypes.push_back(new LLFilterItem(getString("Filter.Objects"), new LLFindNonLinksByMask(ATTACHMENT_MASK)));;  	mListViewItemTypes.push_back(new LLFilterItem(LLTrans::getString("shape"), new LLFindActualWearablesOfType(LLWearableType::WT_SHAPE)));  	mListViewItemTypes.push_back(new LLFilterItem(LLTrans::getString("skin"), new LLFindActualWearablesOfType(LLWearableType::WT_SKIN)));  	mListViewItemTypes.push_back(new LLFilterItem(LLTrans::getString("hair"), new LLFindActualWearablesOfType(LLWearableType::WT_HAIR))); @@ -526,12 +391,24 @@ BOOL LLPanelOutfitEdit::postBuild()  	childSetAction(REVERT_BTN, boost::bind(&LLAppearanceMgr::wearBaseOutfit, LLAppearanceMgr::getInstance())); +	/* +	 * By default AT_CLOTHING are sorted by (in in MY OUTFITS): +	 *  - by type (types order determined in LLWearableType::EType) +	 *  - each LLWearableType::EType by outer layer on top +	 * +	 * In Add More panel AT_CLOTHING should be sorted in a such way: +	 *  - by type (types order determined in LLWearableType::EType) +	 *  - each LLWearableType::EType by name (EXT-8205) +	*/ +	mWearableListViewItemsComparator = new LLWearableItemTypeNameComparator(); +	mWearableListViewItemsComparator->setOrder(LLAssetType::AT_CLOTHING, LLWearableItemTypeNameComparator::ORDER_RANK_1, false, true); +  	mWearablesListViewPanel = getChild<LLPanel>("filtered_wearables_panel"); -	mWearableItemsList = getChild<LLWearableItemsList>("list_view"); +	mWearableItemsList = getChild<LLInventoryItemsList>("list_view");  	mWearableItemsList->setCommitOnSelectionChange(true);  	mWearableItemsList->setCommitCallback(boost::bind(&LLPanelOutfitEdit::updatePlusButton, this));  	mWearableItemsList->setDoubleClickCallback(boost::bind(&LLPanelOutfitEdit::onPlusBtnClicked, this)); -	mWearableItemsList->setSortOrder((LLWearableItemsList::ESortOrder)gSavedSettings.getU32("AddWearableSortOrder")); +	mWearableItemsList->setComparator(mWearableListViewItemsComparator);  	mSaveComboBtn.reset(new LLSaveOutfitComboBtn(this));  	return TRUE; @@ -746,11 +623,11 @@ void LLPanelOutfitEdit::onAddWearableClicked(void)  	}  } -void LLPanelOutfitEdit::onReplaceMenuItemClicked(LLUUID selected_item_id) +void LLPanelOutfitEdit::onReplaceBodyPartMenuItemClicked(LLUUID selected_item_id)  {  	LLViewerInventoryItem* item = gInventory.getLinkedItem(selected_item_id); -	if (item) +	if (item && item->getType() == LLAssetType::AT_BODYPART)  	{  		showFilteredWearablesListView(item->getWearableType());  	} @@ -777,21 +654,21 @@ void LLPanelOutfitEdit::onShopButtonClicked()  		}  		else  		{ -			if (type == LLWearableType::WT_NONE) -			{ -				type = getCOFWearablesSelectionType(); -			} +		if (type == LLWearableType::WT_NONE) +		{ +			type = getCOFWearablesSelectionType(); +		} -			ESex sex = gAgentAvatarp->getSex(); +		ESex sex = gAgentAvatarp->getSex(); -			// WT_INVALID comes for attachments -			if (type != LLWearableType::WT_INVALID && type != LLWearableType::WT_NONE) -			{ -				url = url_resolver.resolveURL(type, sex); -			} +		// WT_INVALID comes for attachments +		if (type != LLWearableType::WT_INVALID && type != LLWearableType::WT_NONE) +		{ +			url = url_resolver.resolveURL(type, sex); +		} -			if (url.empty()) -			{ +		if (url.empty()) +		{  				url = url_resolver.resolveURL(  						mCOFWearables->getExpandedAccordionAssetType(), sex);  			} @@ -901,7 +778,7 @@ void LLPanelOutfitEdit::updatePlusButton()  	}  	// If any of the selected items are not wearable (due to already being worn OR being of the wrong type), disable the add button. -	uuid_vec_t::iterator unwearable_item = std::find_if(selected_items.begin(), selected_items.end(), !boost::bind(& get_can_item_be_worn, _1)); +	uuid_vec_t::iterator unwearable_item = std::find_if(selected_items.begin(), selected_items.end(), !boost::bind(&get_can_item_be_worn, _1));  	bool can_add = ( unwearable_item == selected_items.end() );  	mPlusBtn->setEnabled(can_add); @@ -961,15 +838,38 @@ void LLPanelOutfitEdit::filterWearablesBySelectedItem(void)  	bool more_than_one_selected = ids.size() > 1;  	bool is_dummy_item = (ids.size() && dynamic_cast<LLPanelDummyClothingListItem*>(mCOFWearables->getSelectedItem())); -	//selected and expanded accordion tabs determine filtering when no item is selected +	// selected, expanded accordion tabs and selection in flat list view determine filtering when no item is selected in COF +	// selection in flat list view participates in determining filtering because of EXT-7963 +	// So the priority of criterions in is: +	//                   1. Selected accordion tab            |  IF (any accordion selected) +	//                                                        |     filter_type = selected_accordion_type +	//                   2. Selected item in flat list view   |  ELSEIF (any item in flat list view selected) +	//                                                        |     filter_type = selected_item_type +	//                   3. Expanded accordion tab            |  ELSEIF (any accordion expanded) +	//                                                        |      filter_type = expanded accordion_type  	if (nothing_selected)  	{  		showWearablesListView(); -		//selected accordion tab is more priority than expanded tab when determining filtering +		//selected accordion tab is more priority than expanded tab +		//and selected item in flat list view of 'Add more' panel when +		//determining filtering  		LLAssetType::EType type = mCOFWearables->getSelectedAccordionAssetType();  		if (type == LLAssetType::AT_NONE) +		{ //no accordion selected + +			// when no accordion selected then selected item from flat list view +			// has more priority than expanded when determining filtering +			LLUUID selected_item_id = mWearableItemsList->getSelectedUUID(); +			LLViewerInventoryItem* item = gInventory.getLinkedItem(selected_item_id); +			if(item)  		{ +				showFilteredWearablesListView(item->getWearableType()); +				return; +			} + +			// when no accordion selected and no selected items in flat list view +			// determine filtering according to expanded accordion  			type = mCOFWearables->getExpandedAccordionAssetType();  		} @@ -1149,35 +1049,27 @@ bool LLPanelOutfitEdit::switchPanels(LLPanel* switch_from_panel, LLPanel* switch  	return false;  } -void LLPanelOutfitEdit::onGearButtonClick(LLUICtrl* clicked_button) +void LLPanelOutfitEdit::resetAccordionState()  { -	LLMenuGL* menu = NULL; - -	if (mAddWearablesPanel->getVisible()) +	if (mCOFWearables != NULL)  	{ -		if (!mAddWearablesGearMenu) -		{ -			mAddWearablesGearMenu = LLAddWearablesGearMenu::create(mWearableItemsList, mInventoryItemsPanel); -		} - -		menu = mAddWearablesGearMenu; +		mCOFWearables->expandDefaultAccordionTab();  	}  	else  	{ -		if (!mGearMenu) -		{ -			mGearMenu = LLPanelOutfitEditGearMenu::create(); -		} - -		menu = mGearMenu; +		llwarns << "mCOFWearables is NULL" << llendl;  	} +} -	if (!menu) return; +void LLPanelOutfitEdit::onGearButtonClick(LLUICtrl* clicked_button) +{ +	if(!mGearMenu) +	{ +		mGearMenu = LLPanelOutfitEditGearMenu::create(); +	} -	menu->arrangeAndClear(); // update menu height -	S32 menu_y = menu->getRect().getHeight() + clicked_button->getRect().getHeight(); -	menu->buildDrawLabels(); -	LLMenuGL::showPopup(clicked_button, menu, 0, menu_y); +	S32 menu_y = mGearMenu->getRect().getHeight() + clicked_button->getRect().getHeight(); +	LLMenuGL::showPopup(clicked_button, mGearMenu, 0, menu_y);  }  void LLPanelOutfitEdit::onAddMoreButtonClicked() @@ -1257,6 +1149,11 @@ void LLPanelOutfitEdit::getSelectedItemsUUID(uuid_vec_t& uuid_list)  //	return selected_id;  } +void LLPanelOutfitEdit::onCOFChanged() +{ +	update(); +} +  void LLPanelOutfitEdit::updateWearablesPanelVerbButtons()  {  	if(mWearablesListViewPanel->getVisible()) @@ -1315,12 +1212,6 @@ void LLPanelOutfitEdit::saveListSelection()  		}  		mInventoryItemsPanel->getRootFolder()->scrollToShowSelection();  	} - -} - -void LLPanelOutfitEdit::onCOFChanged() -{ -	update();  }  // EOF diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h index 93215c5920..b3394e45a3 100644 --- a/indra/newview/llpaneloutfitedit.h +++ b/indra/newview/llpaneloutfitedit.h @@ -43,8 +43,8 @@  #include "llremoteparcelrequest.h"  #include "llinventory.h"  #include "llinventoryfunctions.h" +#include "llinventoryitemslist.h"  #include "llinventorymodel.h" -#include "llwearableitemslist.h"  class LLButton;  class LLCOFWearables; @@ -64,6 +64,7 @@ class LLMenuGL;  class LLFindNonLinksByMask;  class LLFindWearablesOfType;  class LLSaveOutfitComboBtn; +class LLWearableItemTypeNameComparator;  class LLPanelOutfitEdit : public LLPanel  { @@ -140,12 +141,6 @@ public:  	void showWearablesListView();  	void showWearablesFolderView(); -	/** -	 * Method preserves selection while switching between folder/list view modes -	*/ -	void saveListSelection(); - -	void updateWearablesPanelVerbButtons();  	void updateFiltersVisibility();  	void onFolderViewFilterCommitted(LLUICtrl* ctrl); @@ -170,7 +165,7 @@ public:  	void onRemoveFromOutfitClicked(void);  	void onEditWearableClicked(void);  	void onAddWearableClicked(void); -	void onReplaceMenuItemClicked(LLUUID selected_item_id); +	void onReplaceBodyPartMenuItemClicked(LLUUID selected_item_id);  	void onShopButtonClicked();  	void displayCurrentOutfit(); @@ -188,6 +183,8 @@ public:  	 */  	bool switchPanels(LLPanel* switch_from_panel, LLPanel* switch_to_panel); +	void resetAccordionState(); +  	virtual BOOL	handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,  									  EDragAndDropType cargo_type,  									  void* cargo_data, @@ -204,6 +201,13 @@ private:  	void getCurrentItemUUID(LLUUID& selected_id);  	void onCOFChanged(); +	/** +	 * Method preserves selection while switching between folder/list view modes +	*/ +	void saveListSelection(); + +	void updateWearablesPanelVerbButtons(); +  	typedef std::pair<LLWearableType::EType, size_t> selection_info_t;  	LLWearableType::EType getCOFWearablesSelectionType() const; @@ -226,8 +230,9 @@ private:  	LLComboBox*			mListViewFilterCmbBox;  	LLFilteredWearableListManager* 	mWearableListManager; -	LLWearableItemsList* 			mWearableItemsList; +	LLInventoryItemsList* 			mWearableItemsList;  	LLPanel*						mWearablesListViewPanel; +	LLWearableItemTypeNameComparator* mWearableListViewItemsComparator;  	LLCOFDragAndDropObserver* mCOFDragAndDropObserver; @@ -236,7 +241,6 @@ private:  	LLCOFWearables*		mCOFWearables;  	LLMenuGL*			mGearMenu; -	LLMenuGL*			mAddWearablesGearMenu;  	bool				mInitialized;  	std::auto_ptr<LLSaveOutfitComboBtn> mSaveComboBtn; diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp index dfe4680035..16ef7998b3 100644 --- a/indra/newview/llpaneloutfitsinventory.cpp +++ b/indra/newview/llpaneloutfitsinventory.cpp @@ -258,17 +258,17 @@ void LLPanelOutfitsInventory::updateListCommands()  	bool wear_visible = !isCOFPanelActive();  	bool make_outfit_enabled = isActionEnabled("save_outfit"); -	mMyOutfitsPanel->getChildView("trash_btn")->setEnabled(trash_enabled); -	mListCommands->getChildView("wear_btn")->setEnabled(wear_enabled); -	mListCommands->getChildView("wear_btn")->setVisible( wear_visible); +	mMyOutfitsPanel->childSetEnabled("trash_btn", trash_enabled); +	mListCommands->childSetEnabled("wear_btn", wear_enabled); +	mListCommands->childSetVisible("wear_btn", wear_visible);  	mSaveComboBtn->setMenuItemEnabled("save_outfit", make_outfit_enabled);  	if (mMyOutfitsPanel->hasItemSelected())  	{ -		mListCommands->getChildView("wear_btn")->setToolTip(getString("wear_items_tooltip")); +		mListCommands->childSetToolTip("wear_btn", getString("wear_items_tooltip"));  	}  	else  	{ -		mListCommands->getChildView("wear_btn")->setToolTip(getString("wear_outfit_tooltip")); +		mListCommands->childSetToolTip("wear_btn", getString("wear_outfit_tooltip"));  	}  } @@ -337,7 +337,7 @@ bool LLPanelOutfitsInventory::isCOFPanelActive() const  void LLPanelOutfitsInventory::setWearablesLoading(bool val)  { -	mListCommands->getChildView("wear_btn")->setEnabled(!val); +	updateVerbs();  }  void LLPanelOutfitsInventory::onWearablesLoaded() diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 7573dd7ad3..58765d0ad8 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -272,6 +272,7 @@ public:  	friend class LLInventoryFriendCardObserver;  	LLFriendListUpdater(callback_t cb)  	:	LLAvatarListUpdater(cb, FRIEND_LIST_UPDATE_TIMEOUT) +	,	mIsActive(false)  	{  		LLAvatarTracker::instance().addObserver(this); @@ -290,9 +291,12 @@ public:  	/*virtual*/ void changed(U32 mask)  	{ -		// events can arrive quickly in bulk - we need not process EVERY one of them - -		// so we wait a short while to let others pile-in, and process them in aggregate. -		mEventTimer.start(); +		if (mIsActive) +		{ +			// events can arrive quickly in bulk - we need not process EVERY one of them - +			// so we wait a short while to let others pile-in, and process them in aggregate. +			mEventTimer.start(); +		}  		// save-up all the mask-bits which have come-in  		mMask |= mask; @@ -301,8 +305,12 @@ public:  	/*virtual*/ BOOL tick()  	{ +		if (!mIsActive) return FALSE; +  		if (mMask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE)) +		{  			updateList(); +		}  		// Stop updates.  		mEventTimer.stop(); @@ -311,9 +319,20 @@ public:  		return FALSE;  	} +	// virtual +	void setActive(bool active) +	{ +		mIsActive = active; +		if (active) +		{ +			tick(); +		} +	} +  private:  	U32 mMask;  	LLInventoryFriendCardObserver* mInvObserver; +	bool mIsActive;  	/**  	 *	This class is intended for updating Friend List when Inventory Friend Card is added/removed. @@ -496,22 +515,25 @@ void LLPanelPeople::onFriendsAccordionExpandedCollapsed(LLUICtrl* ctrl, const LL  BOOL LLPanelPeople::postBuild()  { -	setVisibleCallback(boost::bind(&LLPanelPeople::onVisibilityChange, this, _2)); -	  	mFilterEditor = getChild<LLFilterEditor>("filter_input");  	mFilterEditor->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));  	mTabContainer = getChild<LLTabContainer>("tabs");  	mTabContainer->setCommitCallback(boost::bind(&LLPanelPeople::onTabSelected, this, _2)); -	mOnlineFriendList = getChild<LLPanel>(FRIENDS_TAB_NAME)->getChild<LLAvatarList>("avatars_online"); -	mAllFriendList = getChild<LLPanel>(FRIENDS_TAB_NAME)->getChild<LLAvatarList>("avatars_all"); +	LLPanel* friends_tab = getChild<LLPanel>(FRIENDS_TAB_NAME); +	// updater is active only if panel is visible to user. +	friends_tab->setVisibleCallback(boost::bind(&Updater::setActive, mFriendListUpdater, _2)); +	mOnlineFriendList = friends_tab->getChild<LLAvatarList>("avatars_online"); +	mAllFriendList = friends_tab->getChild<LLAvatarList>("avatars_all");  	mOnlineFriendList->setNoItemsCommentText(getString("no_friends_online"));  	mOnlineFriendList->setShowIcons("FriendsListShowIcons");  	mAllFriendList->setNoItemsCommentText(getString("no_friends"));  	mAllFriendList->setShowIcons("FriendsListShowIcons"); -	mNearbyList = getChild<LLPanel>(NEARBY_TAB_NAME)->getChild<LLAvatarList>("avatar_list"); +	LLPanel* nearby_tab = getChild<LLPanel>(NEARBY_TAB_NAME); +	nearby_tab->setVisibleCallback(boost::bind(&Updater::setActive, mNearbyListUpdater, _2)); +	mNearbyList = nearby_tab->getChild<LLAvatarList>("avatar_list");  	mNearbyList->setNoItemsCommentText(getString("no_one_near"));  	mNearbyList->setNoItemsMsg(getString("no_one_near"));  	mNearbyList->setNoFilteredItemsMsg(getString("no_one_filtered_near")); @@ -955,28 +977,6 @@ void LLPanelPeople::setSortOrder(LLAvatarList* list, ESortOrder order, bool save  	}  } -void LLPanelPeople::onVisibilityChange(const LLSD& new_visibility) -{ -	if (new_visibility.asBoolean() == FALSE) -	{ -		// Don't update anything while we're invisible. -		mNearbyListUpdater->setActive(FALSE); -	} -	else -	{ -		reSelectedCurrentTab(); -	} -} - -// Make the tab-container re-select current tab -// for onTabSelected() callback to get called. -// (currently this is needed to reactivate nearby list updates -// when we get visible) -void LLPanelPeople::reSelectedCurrentTab() -{ -	mTabContainer->selectTab(mTabContainer->getCurrentPanelIndex()); -} -  bool LLPanelPeople::isRealGroup()  {  	return getCurrentItemID() != LLUUID::null; @@ -1024,7 +1024,6 @@ void LLPanelPeople::onFilterEdit(const std::string& search_string)  void LLPanelPeople::onTabSelected(const LLSD& param)  {  	std::string tab_name = getChild<LLPanel>(param.asString())->getName(); -	mNearbyListUpdater->setActive(tab_name == NEARBY_TAB_NAME);  	updateButtons();  	showFriendsAccordionsIfNeeded(); @@ -1388,8 +1387,6 @@ void	LLPanelPeople::onOpen(const LLSD& key)  	if (!tab_name.empty())  		mTabContainer->selectTabByName(tab_name); -	else -		reSelectedCurrentTab();  }  bool LLPanelPeople::notifyChildren(const LLSD& info) diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h index 17c45a034b..ff8df5c7a8 100644 --- a/indra/newview/llpanelpeople.h +++ b/indra/newview/llpanelpeople.h @@ -91,10 +91,6 @@ private:  	void					showGroupMenu(LLMenuGL* menu);  	void					setSortOrder(LLAvatarList* list, ESortOrder order, bool save = true); -	void					onVisibilityChange( const LLSD& new_visibility); - -	void					reSelectedCurrentTab(); -  	// UI callbacks  	void					onFilterEdit(const std::string& search_string);  	void					onTabSelected(const LLSD& param); diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp index 8c1f5d0915..1ca4a048a4 100644 --- a/indra/newview/llpanelplaceinfo.cpp +++ b/indra/newview/llpanelplaceinfo.cpp @@ -60,7 +60,8 @@ LLPanelPlaceInfo::LLPanelPlaceInfo()  	mScrollingPanelWidth(0),  	mInfoType(UNKNOWN),  	mScrollingPanel(NULL), -	mScrollContainer(NULL) +	mScrollContainer(NULL), +	mDescEditor(NULL)  {}  //virtual @@ -103,11 +104,11 @@ void LLPanelPlaceInfo::resetLocation()  	mPosRegion.clearVec();  	std::string loading = LLTrans::getString("LoadingData"); -	mMaturityRatingIcon->setValue(loading);  	mMaturityRatingText->setValue(loading);  	mRegionName->setText(loading);  	mParcelName->setText(loading);  	mDescEditor->setText(loading); +	mMaturityRatingIcon->setValue(LLUUID::null);  	mSnapshotCtrl->setImageAssetID(LLUUID::null);  } @@ -185,7 +186,21 @@ void LLPanelPlaceInfo::setErrorStatus(U32 status, const std::string& reason)  	{  		error_text = getString("server_forbidden_text");  	} +	else +	{ +		error_text = getString("server_error_text"); +	} +  	mDescEditor->setText(error_text); + +	std::string not_available = getString("not_available"); +	mMaturityRatingText->setValue(not_available); +	mRegionName->setText(not_available); +	mParcelName->setText(not_available); +	mMaturityRatingIcon->setValue(LLUUID::null); + +	// Enable "Back" button that was disabled when parcel request was sent. +	getChild<LLButton>("back_btn")->setEnabled(TRUE);  }  // virtual @@ -248,6 +263,16 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)  // virtual  void LLPanelPlaceInfo::reshape(S32 width, S32 height, BOOL called_from_parent)  { + +	// This if was added to force collapsing description textbox on Windows at the beginning of reshape +	// (the only case when reshape is skipped here is when it's caused by this textbox, so called_from_parent is FALSE) +	// This way it is consistent with Linux where topLost collapses textbox at the beginning of reshape. +	// On windows it collapsed only after reshape which caused EXT-8342. +	if(called_from_parent) +	{ +		if(mDescEditor) mDescEditor->onTopLost(); +	} +  	LLPanel::reshape(width, height, called_from_parent);  	if (!mScrollContainer || !mScrollingPanel) diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp index 1f979b0ef1..08835dc2b8 100644 --- a/indra/newview/llpanelplaceprofile.cpp +++ b/indra/newview/llpanelplaceprofile.cpp @@ -79,7 +79,8 @@ LLPanelPlaceProfile::LLPanelPlaceProfile()  :	LLPanelPlaceInfo(),  	mForSalePanel(NULL),  	mYouAreHerePanel(NULL), -	mSelectedParcelID(-1) +	mSelectedParcelID(-1), +	mAccordionCtrl(NULL)  {}  // virtual @@ -139,6 +140,7 @@ BOOL LLPanelPlaceProfile::postBuild()  	mSubdivideText = getChild<LLTextEditor>("subdivide");  	mResaleText = getChild<LLTextEditor>("resale");  	mSaleToText = getChild<LLTextBox>("sale_to"); +	mAccordionCtrl = getChild<LLAccordionCtrl>("advanced_info_accordion");  	icon_pg = getString("icon_PG");  	icon_m = getString("icon_M"); @@ -278,6 +280,11 @@ void LLPanelPlaceProfile::handleVisibilityChange(BOOL new_visibility)  			parcel_mgr->deselectUnused();  		}  	} + +	if (mAccordionCtrl != NULL) +	{ +		mAccordionCtrl->expandDefaultTab(); +	}  }  void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel, diff --git a/indra/newview/llpanelplaceprofile.h b/indra/newview/llpanelplaceprofile.h index e77b441567..49c13ff5e3 100644 --- a/indra/newview/llpanelplaceprofile.h +++ b/indra/newview/llpanelplaceprofile.h @@ -35,6 +35,7 @@  #include "llpanelplaceinfo.h" +class LLAccordionCtrl;  class LLIconCtrl;  class LLTextEditor; @@ -118,6 +119,7 @@ private:  	LLTextEditor*		mSubdivideText;  	LLTextEditor*		mResaleText;  	LLTextBox*			mSaleToText; +	LLAccordionCtrl*	mAccordionCtrl;  };  #endif // LL_LLPANELPLACEPROFILE_H diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index 6b5672414e..adfd457664 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -190,13 +190,16 @@ void LLSidepanelAppearance::onVisibilityChange(const LLSD &new_visibility)  {  	if (new_visibility.asBoolean())  	{ -		if ((mOutfitEdit && mOutfitEdit->getVisible()) || (mEditWearable && mEditWearable->getVisible())) +		bool is_outfit_edit_visible = mOutfitEdit && mOutfitEdit->getVisible(); +		bool is_wearable_edit_visible = mEditWearable && mEditWearable->getVisible(); + +		if (is_outfit_edit_visible || is_wearable_edit_visible)  		{  			if (!gAgentCamera.cameraCustomizeAvatar() && gSavedSettings.getBOOL("AppearanceCameraMovement"))  			{  				gAgentCamera.changeCameraToCustomizeAvatar();  			} -			if (mEditWearable && mEditWearable->getVisible()) +			if (is_wearable_edit_visible)  			{  				LLWearable *wearable_ptr = mEditWearable->getWearable();  				if (gAgentWearables.getWearableIndex(wearable_ptr) == LLAgentWearables::MAX_CLOTHING_PER_TYPE) @@ -205,6 +208,11 @@ void LLSidepanelAppearance::onVisibilityChange(const LLSD &new_visibility)  					showOutfitEditPanel();  				}  			} + +			if (is_outfit_edit_visible) +			{ +				mOutfitEdit->resetAccordionState(); +			}  		}  	}  	else @@ -283,6 +291,15 @@ void LLSidepanelAppearance::showOutfitsInventoryPanel()  void LLSidepanelAppearance::showOutfitEditPanel()  { +	// Accordion's state must be reset in all cases except the one when user +	// is returning back to the mOutfitEdit panel from the mEditWearable panel. +	// The simplest way to control this is to check the visibility state of the mEditWearable +	// BEFORE it is changed by the call to the toggleWearableEditPanel(FALSE, NULL, TRUE). +	if (mEditWearable != NULL && !mEditWearable->getVisible() && mOutfitEdit != NULL) +	{ +		mOutfitEdit->resetAccordionState(); +	} +  	togglMyOutfitsPanel(FALSE);  	toggleWearableEditPanel(FALSE, NULL, TRUE); // don't switch out of edit appearance mode  	toggleOutfitEditPanel(TRUE); diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp index de59af49da..0951586dd5 100644 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -33,10 +33,13 @@  #include "llsidepanelinventory.h"  #include "llagent.h" +#include "llappearancemgr.h"  #include "llavataractions.h"  #include "llbutton.h"  #include "llinventorybridge.h" +#include "llinventoryfunctions.h"  #include "llinventorypanel.h" +#include "lloutfitobserver.h"  #include "llpanelmaininventory.h"  #include "llsidepaneliteminfo.h"  #include "llsidepaneltaskinfo.h" @@ -98,6 +101,8 @@ BOOL LLSidepanelInventory::postBuild()  		my_inventory_panel->addHideFolderType(LLFolderType::FT_LANDMARK);  		my_inventory_panel->addHideFolderType(LLFolderType::FT_FAVORITE);  		*/ + +		LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLSidepanelInventory::updateVerbs, this));  	}  	// UI elements from item panel @@ -283,7 +288,7 @@ void LLSidepanelInventory::updateVerbs()  		case LLInventoryType::IT_OBJECT:  		case LLInventoryType::IT_ATTACHMENT:  			mWearBtn->setVisible(TRUE); -			mWearBtn->setEnabled(TRUE); +			mWearBtn->setEnabled(get_can_item_be_worn(item->getLinkedUUID()));  		 	mShopBtn->setVisible(FALSE);  			break;  		case LLInventoryType::IT_SOUND: diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 1ee73034f6..2475870b17 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -118,7 +118,6 @@  #include "llinventorybridge.h"  #include "llinventorymodel.h"  #include "llinventorymodelbackgroundfetch.h" -#include "llfriendcard.h"  #include "llkeyboard.h"  #include "llloginhandler.h"			// gLoginHandler, SLURL support  #include "lllogininstance.h" // Host the login module. @@ -1645,12 +1644,6 @@ bool idle_startup()  		//all categories loaded. lets create "My Favorites" category  		gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE,true); -		// Checks whether "Friends" and "Friends/All" folders exist in "Calling Cards" folder, -		// fetches their contents if needed and synchronizes it with buddies list. -		// If the folders are not found they are created. -		LLFriendCardsManager::instance().syncFriendCardsFolders(); - -  		// set up callbacks  		llinfos << "Registering Callbacks" << llendl;  		LLMessageSystem* msg = gMessageSystem; diff --git a/indra/newview/lltexlayerparams.cpp b/indra/newview/lltexlayerparams.cpp index f2d1b5d032..dc97c4b673 100644 --- a/indra/newview/lltexlayerparams.cpp +++ b/indra/newview/lltexlayerparams.cpp @@ -180,7 +180,7 @@ void LLTexLayerParamAlpha::setWeight(F32 weight, BOOL upload_bake)  		if ((mAvatar->getSex() & getSex()) && (mAvatar->isSelf() && !mIsDummy)) // only trigger a baked texture update if we're changing a wearable's visual param.  		{ -			if (gAgentCamera.cameraCustomizeAvatar()) +			if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures())  			{  				upload_bake = FALSE;  			} diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 476b210ae6..127e4010ca 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -175,6 +175,8 @@ protected:  	BOOL				mNoCopyTextureSelected;  	F32					mContextConeOpacity;  	LLSaveFolderState	mSavedFolderState; + +	BOOL				mSelectedItemPinned;  };  LLFloaterTexturePicker::LLFloaterTexturePicker(	 @@ -197,7 +199,8 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(  	mFilterEdit(NULL),  	mImmediateFilterPermMask(immediate_filter_perm_mask),  	mNonImmediateFilterPermMask(non_immediate_filter_perm_mask), -	mContextConeOpacity(0.f) +	mContextConeOpacity(0.f), +	mSelectedItemPinned( FALSE )  {  	mCanApplyImmediately = can_apply_immediately;  	LLUICtrlFactory::getInstance()->buildFloater(this,"floater_texture_ctrl.xml",NULL); @@ -597,6 +600,31 @@ void LLFloaterTexturePicker::draw()  			mTentativeLabel->setVisible( TRUE );  			drawChild(mTentativeLabel);  		} + +		if (mSelectedItemPinned) return; + +		LLFolderView* folder_view = mInventoryPanel->getRootFolder(); +		if (!folder_view) return; + +		LLInventoryFilter* filter = folder_view->getFilter(); +		if (!filter) return; + +		bool is_filter_active = folder_view->getCompletedFilterGeneration() < filter->getCurrentGeneration() && +				filter->isNotDefault(); + +		// After inventory panel filter is applied we have to update +		// constraint rect for the selected item because of folder view +		// AutoSelectOverride set to TRUE. We force PinningSelectedItem +		// flag to FALSE state and setting filter "dirty" to update +		// scroll container to show selected item (see LLFolderView::doIdle()). +		if (!is_filter_active && !mSelectedItemPinned) +		{ +			folder_view->setPinningSelectedItem(mSelectedItemPinned); +			folder_view->dirtyFilter(); +			folder_view->arrangeFromRoot(); + +			mSelectedItemPinned = TRUE; +		}  	}  } diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index ceed90e210..dddfed097d 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -290,8 +290,8 @@ class HTTPGetResponder : public LLCurl::Responder  {  	LOG_CLASS(HTTPGetResponder);  public: -	HTTPGetResponder(LLTextureFetch* fetcher, const LLUUID& id, U64 startTime, S32 requestedSize, U32 offset) -		: mFetcher(fetcher), mID(id), mStartTime(startTime), mRequestedSize(requestedSize), mOffset(offset) +	HTTPGetResponder(LLTextureFetch* fetcher, const LLUUID& id, U64 startTime, S32 requestedSize, U32 offset, bool redir) +		: mFetcher(fetcher), mID(id), mStartTime(startTime), mRequestedSize(requestedSize), mOffset(offset), mFollowRedir(redir)  	{  	}  	~HTTPGetResponder() @@ -344,6 +344,11 @@ public:   			llwarns << "Worker not found: " << mID << llendl;  		}  	} + +	virtual bool followRedir() +	{ +		return mFollowRedir; +	}  private:  	LLTextureFetch* mFetcher; @@ -351,6 +356,7 @@ private:  	U64 mStartTime;  	S32 mRequestedSize;  	U32 mOffset; +	bool mFollowRedir;  };  ////////////////////////////////////////////////////////////////////////////// @@ -897,7 +903,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  				std::vector<std::string> headers;  				headers.push_back("Accept: image/x-j2c");  				res = mFetcher->mCurlGetRequest->getByteRange(mUrl, headers, offset, mRequestedSize, -															  new HTTPGetResponder(mFetcher, mID, LLTimer::getTotalTime(), mRequestedSize, offset)); +															  new HTTPGetResponder(mFetcher, mID, LLTimer::getTotalTime(), mRequestedSize, offset, true));  			}  			if (!res)  			{ @@ -945,17 +951,6 @@ bool LLTextureFetchWorker::doWork(S32 param)  					max_attempts = mHTTPFailCount+1; // Keep retrying  					LL_INFOS_ONCE("Texture") << "Texture server busy (503): " << mUrl << LL_ENDL;  				} -				else if(mGetStatus >= HTTP_MULTIPLE_CHOICES && mGetStatus < HTTP_BAD_REQUEST) //http re-direct -				{ -					++mHTTPFailCount; -					max_attempts = 5 ; //try at most 5 times to avoid infinite redirection loop. - -					llwarns << "HTTP GET failed because of redirection: "  << mUrl -							<< " Status: " << mGetStatus << " Reason: '" << mGetReason << llendl ; - -					//assign to the new url -					mUrl = mGetReason ; -				}  				else  				{  					const S32 HTTP_MAX_RETRY_COUNT = 3; diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 2d57c16889..a6e8ea032a 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -96,6 +96,7 @@ public:  		mInventoryItemsDict["New Gesture"]		= LLTrans::getString("New Gesture");  		mInventoryItemsDict["New Script"]		= LLTrans::getString("New Script");  		mInventoryItemsDict["New Folder"]		= LLTrans::getString("New Folder"); +		mInventoryItemsDict["New Note"]			= LLTrans::getString("New Note");  		mInventoryItemsDict["Contents"]			= LLTrans::getString("Contents");  		mInventoryItemsDict["Gesture"]			= LLTrans::getString("Gesture"); @@ -1172,6 +1173,14 @@ void move_inventory_item(  void copy_inventory_from_notecard(const LLUUID& object_id, const LLUUID& notecard_inv_id, const LLInventoryItem *src, U32 callback_id)  { +	if (NULL == src) +	{ +		LL_WARNS("copy_inventory_from_notecard") << "Null pointer to item was passed for object_id " +												 << object_id << " and notecard_inv_id " +												 << notecard_inv_id << LL_ENDL; +		return; +	} +  	LLViewerRegion* viewer_region = NULL;      LLViewerObject* vo = NULL;  	if (object_id.notNull() && (vo = gObjectList.findObject(object_id)) != NULL) @@ -1194,6 +1203,16 @@ void copy_inventory_from_notecard(const LLUUID& object_id, const LLUUID& notecar          return;      } +	// check capability to prevent a crash while LL_ERRS in LLCapabilityListener::capListener. See EXT-8459. +	std::string url = viewer_region->getCapability("CopyInventoryFromNotecard"); +	if (url.empty()) +	{ +        LL_WARNS("copy_inventory_from_notecard") << "There is no 'CopyInventoryFromNotecard' capability" +												 << " for region: " << viewer_region->getName() +                                                 << LL_ENDL; +		return; +	} +      LLSD request, body;      body["notecard-id"] = notecard_inv_id;      body["object-id"] = object_id; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 82143f656d..a83980dc23 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -108,9 +108,12 @@  #include "llappearancemgr.h"  #include "lltrans.h"  #include "lleconomy.h" +#include "boost/unordered_map.hpp"  using namespace LLVOAvatarDefines; +static boost::unordered_map<std::string, LLStringExplicit> sDefaultItemLabels; +  BOOL enable_land_build(void*);  BOOL enable_object_build(void*); @@ -327,11 +330,11 @@ LLMenuParcelObserver::~LLMenuParcelObserver()  void LLMenuParcelObserver::changed()  { -	gMenuHolder->getChildView("Land Buy Pass")->setEnabled(LLPanelLandGeneral::enableBuyPass(NULL)); +	gMenuHolder->childSetEnabled("Land Buy Pass", LLPanelLandGeneral::enableBuyPass(NULL));  	BOOL buyable = enable_buy_land(NULL); -	gMenuHolder->getChildView("Land Buy")->setEnabled(buyable); -	gMenuHolder->getChildView("Buy Land...")->setEnabled(buyable); +	gMenuHolder->childSetEnabled("Land Buy", buyable); +	gMenuHolder->childSetEnabled("Buy Land...", buyable);  } @@ -451,10 +454,10 @@ void init_menus()  	// Assume L$10 for now, the server will tell us the real cost at login  	// *TODO:Also fix cost in llfolderview.cpp for Inventory menus  	const std::string upload_cost("10"); -	gMenuHolder->getChild<LLUICtrl>("Upload Image")->setLabelArg("[COST]", upload_cost); -	gMenuHolder->getChild<LLUICtrl>("Upload Sound")->setLabelArg("[COST]", upload_cost); -	gMenuHolder->getChild<LLUICtrl>("Upload Animation")->setLabelArg("[COST]", upload_cost); -	gMenuHolder->getChild<LLUICtrl>("Bulk Upload")->setLabelArg("[COST]", upload_cost); +	gMenuHolder->childSetLabelArg("Upload Image", "[COST]", upload_cost); +	gMenuHolder->childSetLabelArg("Upload Sound", "[COST]", upload_cost); +	gMenuHolder->childSetLabelArg("Upload Animation", "[COST]", upload_cost); +	gMenuHolder->childSetLabelArg("Bulk Upload", "[COST]", upload_cost);  	gAFKMenu = gMenuBarView->getChild<LLMenuItemCallGL>("Set Away", TRUE);  	gBusyMenu = gMenuBarView->getChild<LLMenuItemCallGL>("Set Busy", TRUE); @@ -2403,31 +2406,55 @@ void handle_object_touch()  		msg->sendMessage(object->getRegion()->getHost());  } -// One object must have touch sensor -class LLObjectEnableTouch : public view_listener_t +static void init_default_item_label(const std::string& item_name)  { -	bool handleEvent(const LLSD& userdata) +	boost::unordered_map<std::string, LLStringExplicit>::iterator it = sDefaultItemLabels.find(item_name); +	if (it == sDefaultItemLabels.end())  	{ -		LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); -		 -		bool new_value = obj && obj->flagHandleTouch(); - -		// Update label based on the node touch name if available. -		std::string touch_text; -		LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); -		if (node && node->mValid && !node->mTouchName.empty()) -		{ -			touch_text = node->mTouchName; -		} -		else +		// *NOTE: This will not work for items of type LLMenuItemCheckGL because they return boolean value +		//       (doesn't seem to matter much ATM). +		LLStringExplicit default_label = gMenuHolder->childGetValue(item_name).asString(); +		if (!default_label.empty())  		{ -			touch_text = userdata.asString(); +			sDefaultItemLabels.insert(std::pair<std::string, LLStringExplicit>(item_name, default_label));  		} -		gMenuHolder->getChild<LLUICtrl>("Object Touch")->setValue(touch_text); -		gMenuHolder->getChild<LLUICtrl>("Attachment Object Touch")->setValue(touch_text); +	} +} -		return new_value; +static LLStringExplicit get_default_item_label(const std::string& item_name) +{ +	LLStringExplicit res(""); +	boost::unordered_map<std::string, LLStringExplicit>::iterator it = sDefaultItemLabels.find(item_name); +	if (it != sDefaultItemLabels.end()) +	{ +		res = it->second; +	} + +	return res; +} + + +bool enable_object_touch(LLUICtrl* ctrl) +{ +	LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + +	bool new_value = obj && obj->flagHandleTouch(); + +	std::string item_name = ctrl->getName(); +	init_default_item_label(item_name); + +	// Update label based on the node touch name if available. +	LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); +	if (node && node->mValid && !node->mTouchName.empty()) +	{ +		gMenuHolder->childSetText(item_name, node->mTouchName); +	} +	else +	{ +		gMenuHolder->childSetText(item_name, get_default_item_label(item_name));  	} + +	return new_value;  };  //void label_touch(std::string& label, void*) @@ -5519,27 +5546,27 @@ bool enable_object_stand_up()  	return sitting_on_selection();  } -bool enable_object_sit() +bool enable_object_sit(LLUICtrl* ctrl)  {  	// 'Object Sit' menu item is enabled when agent is not sitting on selection  	bool sitting_on_sel = sitting_on_selection();  	if (!sitting_on_sel)  	{ -		LLMenuItemGL* sit_menu_item = gMenuHolder->getChild<LLMenuItemGL>("Object Sit"); -		// Init default 'Object Sit' menu item label -		static const LLStringExplicit sit_text(sit_menu_item->getLabel()); +		std::string item_name = ctrl->getName(); + +		// init default labels +		init_default_item_label(item_name); +  		// Update label -		std::string label;  		LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();  		if (node && node->mValid && !node->mSitName.empty())  		{ -			label.assign(node->mSitName); +			gMenuHolder->childSetText(item_name, node->mSitName);  		}  		else  		{ -			label = sit_text; +			gMenuHolder->childSetText(item_name, get_default_item_label(item_name));  		} -		sit_menu_item->setLabel(label);  	}  	return !sitting_on_sel && is_object_sittable();  } @@ -7668,7 +7695,7 @@ class LLUploadCostCalculator : public view_listener_t  	bool handleEvent(const LLSD& userdata)  	{  		std::string menu_name = userdata.asString(); -		gMenuHolder->getChildView(menu_name)->setLabelArg("[COST]", mCostStr); +		gMenuHolder->childSetLabelArg(menu_name, "[COST]", mCostStr);  		return true;  	} @@ -8087,7 +8114,6 @@ void initialize_menus()  	view_listener_t::addMenu(new LLObjectBuild(), "Object.Build");  	commit.add("Object.Touch", boost::bind(&handle_object_touch));  	commit.add("Object.SitOrStand", boost::bind(&handle_object_sit_or_stand)); -	enable.add("Object.EnableGearSit", boost::bind(&is_object_sittable));  	commit.add("Object.Delete", boost::bind(&handle_object_delete));  	view_listener_t::addMenu(new LLObjectAttachToAvatar(), "Object.AttachToAvatar");  	view_listener_t::addMenu(new LLObjectReturn(), "Object.Return"); @@ -8103,12 +8129,12 @@ void initialize_menus()  	commit.add("Object.Open", boost::bind(&handle_object_open));  	commit.add("Object.Take", boost::bind(&handle_take));  	enable.add("Object.EnableOpen", boost::bind(&enable_object_open)); -	view_listener_t::addMenu(new LLObjectEnableTouch(), "Object.EnableTouch"); +	enable.add("Object.EnableTouch", boost::bind(&enable_object_touch, _1));  	enable.add("Object.EnableDelete", boost::bind(&enable_object_delete));  	enable.add("Object.EnableWear", boost::bind(&object_selected_and_point_valid));  	enable.add("Object.EnableStandUp", boost::bind(&enable_object_stand_up)); -	enable.add("Object.EnableSit", boost::bind(&enable_object_sit)); +	enable.add("Object.EnableSit", boost::bind(&enable_object_sit, _1));  	view_listener_t::addMenu(new LLObjectEnableReturn(), "Object.EnableReturn");  	view_listener_t::addMenu(new LLObjectEnableReportAbuse(), "Object.EnableReportAbuse"); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 6d447aecca..a04c919310 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1138,10 +1138,26 @@ void open_inventory_offer(const uuid_vec_t& objects, const std::string& from_nam  						}  						else if(from_name.empty())  						{ +							std::string folder_name; +							if (parent_folder) +							{ +								// Localize folder name. +								// *TODO: share this code? +								folder_name = parent_folder->getName(); +								if (LLFolderType::lookupIsProtectedType(parent_folder->getPreferredType())) +								{ +									LLTrans::findString(folder_name, "InvFolder " + folder_name); +								} +							} +							else +							{ +								 folder_name = LLTrans::getString("Unknown"); +							} +  							// we receive a message from LLOpenTaskOffer, it mean that new landmark has been added.  							LLSD args;  							args["LANDMARK_NAME"] = item->getName(); -							args["FOLDER_NAME"] = std::string(parent_folder ? parent_folder->getName() : "unknown"); +							args["FOLDER_NAME"] = folder_name;  							LLNotificationsUtil::add("LandmarkCreated", args);  						}  					} diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index 59efae4cb2..8bd43bb30c 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -90,7 +90,7 @@ public:  	}  	static void processForeignLandmark(LLLandmark* landmark,  			const LLUUID& object_id, const LLUUID& notecard_inventory_id, -			LLInventoryItem* item) +			LLPointer<LLInventoryItem> item_ptr)  	{  		LLVector3d global_pos;  		landmark->getGlobalPos(global_pos); @@ -103,8 +103,16 @@ public:  		}  		else  		{ -			LLPointer<LLEmbeddedLandmarkCopied> cb = new LLEmbeddedLandmarkCopied(); -			copy_inventory_from_notecard(object_id, notecard_inventory_id, item, gInventoryCallbacks.registerCB(cb)); +			if (item_ptr.isNull()) +			{ +				// check to prevent a crash. See EXT-8459. +				llwarns << "Passed handle contains a dead inventory item. Most likely notecard has been closed and embedded item was destroyed." << llendl; +			} +			else +			{ +				LLPointer<LLEmbeddedLandmarkCopied> cb = new LLEmbeddedLandmarkCopied(); +				copy_inventory_from_notecard(object_id, notecard_inventory_id, item_ptr.get(), gInventoryCallbacks.registerCB(cb)); +			}  		}  	}  }; @@ -300,14 +308,14 @@ public:  	void	markSaved(); -	static LLInventoryItem* getEmbeddedItem(llwchar ext_char); // returns item from static list +	static LLPointer<LLInventoryItem> getEmbeddedItemPtr(llwchar ext_char); // returns pointer to item from static list  	static BOOL getEmbeddedItemSaved(llwchar ext_char); // returns whether item from static list is saved  private:  	struct embedded_info_t  	{ -		LLPointer<LLInventoryItem> mItem; +		LLPointer<LLInventoryItem> mItemPtr;  		BOOL mSaved;  	};  	typedef std::map<llwchar, embedded_info_t > item_map_t; @@ -378,7 +386,7 @@ BOOL LLEmbeddedItems::insertEmbeddedItem( LLInventoryItem* item, llwchar* ext_ch  		++wc_emb;  	} -	sEntries[wc_emb].mItem = item; +	sEntries[wc_emb].mItemPtr = item;  	sEntries[wc_emb].mSaved = is_new ? FALSE : TRUE;  	*ext_char = wc_emb;  	mEmbeddedUsedChars.insert(wc_emb); @@ -400,14 +408,14 @@ BOOL LLEmbeddedItems::removeEmbeddedItem( llwchar ext_char )  }  // static -LLInventoryItem* LLEmbeddedItems::getEmbeddedItem(llwchar ext_char) +LLPointer<LLInventoryItem> LLEmbeddedItems::getEmbeddedItemPtr(llwchar ext_char)  {  	if( ext_char >= LLTextEditor::FIRST_EMBEDDED_CHAR && ext_char <= LLTextEditor::LAST_EMBEDDED_CHAR )  	{  		item_map_t::iterator iter = sEntries.find(ext_char);  		if (iter != sEntries.end())  		{ -			return iter->second.mItem; +			return iter->second.mItemPtr;  		}  	}  	return NULL; @@ -505,7 +513,7 @@ BOOL LLEmbeddedItems::hasEmbeddedItem(llwchar ext_char)  LLUIImagePtr LLEmbeddedItems::getItemImage(llwchar ext_char) const  { -	LLInventoryItem* item = getEmbeddedItem(ext_char); +	LLInventoryItem* item = getEmbeddedItemPtr(ext_char);  	if (item)  	{  		const char* img_name = ""; @@ -567,7 +575,7 @@ void LLEmbeddedItems::getEmbeddedItemList( std::vector<LLPointer<LLInventoryItem  	for (std::set<llwchar>::iterator iter = mEmbeddedUsedChars.begin(); iter != mEmbeddedUsedChars.end(); ++iter)  	{  		llwchar wc = *iter; -		LLPointer<LLInventoryItem> item = getEmbeddedItem(wc); +		LLPointer<LLInventoryItem> item = getEmbeddedItemPtr(wc);  		if (item)  		{  			items.push_back(item); @@ -698,7 +706,7 @@ BOOL LLViewerTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)  			{  				wc = getWText()[mCursorPos];  			} -			LLInventoryItem* item_at_pos = LLEmbeddedItems::getEmbeddedItem(wc); +			LLPointer<LLInventoryItem> item_at_pos = LLEmbeddedItems::getEmbeddedItemPtr(wc);  			if (item_at_pos)  			{  				mDragItem = item_at_pos; @@ -1019,7 +1027,7 @@ llwchar LLViewerTextEditor::pasteEmbeddedItem(llwchar ext_char)  	{  		return ext_char; // already exists in my list  	} -	LLInventoryItem* item = LLEmbeddedItems::getEmbeddedItem(ext_char); +	LLInventoryItem* item = LLEmbeddedItems::getEmbeddedItemPtr(ext_char);  	if (item)  	{  		// Add item to my list and return new llwchar associated with it @@ -1053,7 +1061,7 @@ void LLViewerTextEditor::findEmbeddedItemSegments(S32 start, S32 end)  			&& embedded_char <= LAST_EMBEDDED_CHAR   			&& mEmbeddedItemList->hasEmbeddedItem(embedded_char) )  		{ -			LLInventoryItem* itemp = mEmbeddedItemList->getEmbeddedItem(embedded_char); +			LLInventoryItem* itemp = mEmbeddedItemList->getEmbeddedItemPtr(embedded_char);  			LLUIImagePtr image = mEmbeddedItemList->getItemImage(embedded_char);  			insertSegment(new LLEmbeddedItemSegment(idx, image, itemp, *this));  		} @@ -1065,7 +1073,7 @@ BOOL LLViewerTextEditor::openEmbeddedItemAtPos(S32 pos)  	if( pos < getLength())  	{  		llwchar wc = getWText()[pos]; -		LLInventoryItem* item = LLEmbeddedItems::getEmbeddedItem( wc ); +		LLPointer<LLInventoryItem> item = LLEmbeddedItems::getEmbeddedItemPtr( wc );  		if( item )  		{  			BOOL saved = LLEmbeddedItems::getEmbeddedItemSaved( wc ); @@ -1083,7 +1091,7 @@ BOOL LLViewerTextEditor::openEmbeddedItemAtPos(S32 pos)  } -BOOL LLViewerTextEditor::openEmbeddedItem(LLInventoryItem* item, llwchar wc) +BOOL LLViewerTextEditor::openEmbeddedItem(LLPointer<LLInventoryItem> item, llwchar wc)  {  	switch( item->getType() ) @@ -1151,17 +1159,17 @@ void LLViewerTextEditor::openEmbeddedSound( LLInventoryItem* item, llwchar wc )  } -void LLViewerTextEditor::openEmbeddedLandmark( LLInventoryItem* item, llwchar wc ) +void LLViewerTextEditor::openEmbeddedLandmark( LLPointer<LLInventoryItem> item_ptr, llwchar wc )  { -	if (!item) +	if (item_ptr.isNull())  		return; -	LLLandmark* landmark = gLandmarkList.getAsset(item->getAssetUUID(), -			boost::bind(&LLEmbeddedLandmarkCopied::processForeignLandmark, _1, mObjectID, mNotecardInventoryID, item)); +	LLLandmark* landmark = gLandmarkList.getAsset(item_ptr->getAssetUUID(), +			boost::bind(&LLEmbeddedLandmarkCopied::processForeignLandmark, _1, mObjectID, mNotecardInventoryID, item_ptr));  	if (landmark)  	{  		LLEmbeddedLandmarkCopied::processForeignLandmark(landmark, mObjectID, -				mNotecardInventoryID, item); +				mNotecardInventoryID, item_ptr);  	}  } @@ -1220,7 +1228,7 @@ bool LLViewerTextEditor::onCopyToInvDialog(const LLSD& notification, const LLSD&  	{  		LLUUID item_id = notification["payload"]["item_id"].asUUID();  		llwchar wc = llwchar(notification["payload"]["item_wc"].asInteger()); -		LLInventoryItem* itemp = LLEmbeddedItems::getEmbeddedItem(wc); +		LLInventoryItem* itemp = LLEmbeddedItems::getEmbeddedItemPtr(wc);  		if (itemp)  			copyInventory(itemp);  	} diff --git a/indra/newview/llviewertexteditor.h b/indra/newview/llviewertexteditor.h index ba0c40cb2e..74b6d70640 100644 --- a/indra/newview/llviewertexteditor.h +++ b/indra/newview/llviewertexteditor.h @@ -104,13 +104,16 @@ private:  	virtual llwchar	pasteEmbeddedItem(llwchar ext_char);  	BOOL			openEmbeddedItemAtPos( S32 pos ); -	BOOL			openEmbeddedItem(LLInventoryItem* item, llwchar wc); +	BOOL			openEmbeddedItem(LLPointer<LLInventoryItem> item, llwchar wc);  	S32				insertEmbeddedItem(S32 pos, LLInventoryItem* item); +	// *NOTE: most of openEmbeddedXXX methods except openEmbeddedLandmark take pointer to LLInventoryItem. +	// Be sure they don't bind it to callback function to avoid situation when it gets invalid when +	// callback is trigged after text editor is closed. See EXT-8459.  	void			openEmbeddedTexture( LLInventoryItem* item, llwchar wc );  	void			openEmbeddedSound( LLInventoryItem* item, llwchar wc ); -	void			openEmbeddedLandmark( LLInventoryItem* item, llwchar wc ); +	void			openEmbeddedLandmark( LLPointer<LLInventoryItem> item_ptr, llwchar wc );  	void			openEmbeddedNotecard( LLInventoryItem* item, llwchar wc);  	void			openEmbeddedCallingcard( LLInventoryItem* item, llwchar wc);  	void			showCopyToInvDialog( LLInventoryItem* item, llwchar wc ); diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index e38608bcfc..9d4f6fdd0c 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -2131,7 +2131,7 @@ void LLViewerFetchedTexture::deleteCallbackEntry(const LLLoadedCallbackEntry::so  void LLViewerFetchedTexture::unpauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list)  {  	if(!callback_list) -	{ +{  		mPauseLoadedCallBacks = FALSE ;  		return ;  	} @@ -2160,7 +2160,7 @@ void LLViewerFetchedTexture::unpauseLoadedCallbacks(const LLLoadedCallbackEntry:  void LLViewerFetchedTexture::pauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list)  {  	if(!callback_list) -	{ +{  		return ;  	} diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 2f63e7ef01..00873a797c 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -4390,7 +4390,7 @@ void LLViewerWindow::restoreGL(const std::string& progress_message)  		gResizeScreenTexture = TRUE; -		if (gAgentCamera.cameraCustomizeAvatar()) +		if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures())  		{  			LLVisualParamHint::requestHintUpdates();  		} diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 9353c6daef..4fac7fe510 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -2005,8 +2005,8 @@ void LLVOAvatar::updateMeshData()  				}  				else  				{ -					facep->mVertexBuffer->resizeBuffer(num_vertices, num_indices) ; -				} +				facep->mVertexBuffer->resizeBuffer(num_vertices, num_indices) ; +			}  			}  			facep->setGeomIndex(0); @@ -3789,11 +3789,11 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)  	{	//LOD changed or new mesh created, allocate new vertex buffer if needed  		if (needs_rebuild || mDirtyMesh >= 2 || mVisibilityRank <= 4)  		{ -			updateMeshData(); +		updateMeshData();  			mDirtyMesh = 0; -			mNeedsSkin = TRUE; -			mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY); -		} +		mNeedsSkin = TRUE; +		mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY); +	}  	}  	if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) <= 0) @@ -4095,9 +4095,13 @@ void LLVOAvatar::updateTextures()  	}  	else  	{ -		render_avatar = isVisible() && !mCulled; +		if(!isVisible()) +		{ +			return ;//do not update for invisible avatar. +		} + +		render_avatar = !mCulled; //visible and not culled.  	} -	checkTextureLoading() ;  	std::vector<BOOL> layer_baked;  	// GL NOT ACTIVE HERE - *TODO @@ -4138,7 +4142,7 @@ void LLVOAvatar::updateTextures()  				}  			}  		} -		if (isIndexBakedTexture((ETextureIndex) texture_index) && render_avatar) +		if (isIndexBakedTexture((ETextureIndex) texture_index))  		{  			const S32 boost_level = getAvatarBakedBoostLevel();  			imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index,0), TRUE); @@ -4172,10 +4176,11 @@ void LLVOAvatar::addLocalTextureStats( ETextureIndex idx, LLViewerFetchedTexture  	return;  } -			     +const S32 MAX_TEXTURE_UPDATE_INTERVAL = 64 ; //need to call updateTextures() at least every 32 frames.	 +const S32 MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL = S32_MAX ; //frames  void LLVOAvatar::checkTextureLoading()  { -	static const F32 MAX_INVISIBLE_WAITING_TIME = 30.f ; //seconds +	static const F32 MAX_INVISIBLE_WAITING_TIME = 15.f ; //seconds  	BOOL pause = !isVisible() ;  	if(!pause) @@ -4195,7 +4200,7 @@ void LLVOAvatar::checkTextureLoading()  	if(pause && mInvisibleTimer.getElapsedTimeF32() < MAX_INVISIBLE_WAITING_TIME)  	{ -		return ; +		return ; //have not been invisible for enough time.  	}  	for(LLLoadedCallbackEntry::source_callback_list_t::iterator iter = mCallbackTextureList.begin(); @@ -4207,17 +4212,22 @@ void LLVOAvatar::checkTextureLoading()  			if(pause)//pause texture fetching.  			{  				tex->pauseLoadedCallbacks(&mCallbackTextureList) ; + +				//set to terminate texture fetching after MAX_TEXTURE_UPDATE_INTERVAL frames. +				tex->setMaxVirtualSizeResetInterval(MAX_TEXTURE_UPDATE_INTERVAL); +				tex->resetMaxVirtualSizeResetCounter() ;  			}  			else//unpause  			{ -				static const F32 START_AREA = 100.f ; - -				tex->unpauseLoadedCallbacks(&mCallbackTextureList) ; -				tex->addTextureStats(START_AREA); //jump start the fetching again +				tex->unpauseLoadedCallbacks(&mCallbackTextureList) ;				  			}  		}		  	}			 +	if(!pause) +	{ +		updateTextures() ; //refresh texture stats. +	}  	mLoadedCallbacksPaused = pause ;  	return ;  } @@ -4226,12 +4236,14 @@ const F32  SELF_ADDITIONAL_PRI = 0.75f ;  const F32  ADDITIONAL_PRI = 0.5f;  void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel_area, F32 texel_area_ratio, S32 boost_level)  { -	//if this function is not called for the last 512 frames, the texture pipeline will stop fetching this texture. -	static const S32  MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL = 512 ; //frames		 +	//Note: +	//if this function is not called for the last MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL frames,  +	//the texture pipeline will stop fetching this texture.  	imagep->resetTextureStats();  	imagep->setCanUseHTTP(false) ; //turn off http fetching for baked textures.  	imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL); +	imagep->resetMaxVirtualSizeResetCounter() ;  	mMaxPixelArea = llmax(pixel_area, mMaxPixelArea);  	mMinPixelArea = llmin(pixel_area, mMinPixelArea);	 @@ -6051,7 +6063,7 @@ void LLVOAvatar::updateMeshTextures()  		}  	} -	const BOOL self_customizing = isSelf() && gAgentCamera.cameraCustomizeAvatar(); // During face edit mode, we don't use baked textures +	const BOOL self_customizing = isSelf() && !gAgentAvatarp->isUsingBakedTextures(); // During face edit mode, we don't use baked textures  	const BOOL other_culled = !isSelf() && mCulled;  	LLLoadedCallbackEntry::source_callback_list_t* src_callback_list = NULL ;  	BOOL paused = FALSE; diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 83ca299da1..eb622ce7c7 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -623,7 +623,7 @@ private:  public:  	void			setClothesColor(LLVOAvatarDefines::ETextureIndex te, const LLColor4& new_color, BOOL upload_bake);  	LLColor4		getClothesColor(LLVOAvatarDefines::ETextureIndex te); -	static BOOL		teToColorParams(LLVOAvatarDefines::ETextureIndex te, U32 *param_name); +	static BOOL			teToColorParams(LLVOAvatarDefines::ETextureIndex te, U32 *param_name);  	//--------------------------------------------------------------------  	// Global colors @@ -1050,5 +1050,6 @@ protected: // Shared with LLVOAvatarSelf  }; // LLVOAvatar  extern const F32  SELF_ADDITIONAL_PRI; +extern const S32 MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL;  #endif // LL_VO_AVATAR_H diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 8961d2c285..bddde08ca9 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -1148,11 +1148,11 @@ void LLVOAvatarSelf::localTextureLoaded(BOOL success, LLViewerFetchedTexture *sr  			discard_level < local_tex_obj->getDiscard())  		{  			local_tex_obj->setDiscard(discard_level); -			if (!gAgentCamera.cameraCustomizeAvatar()) +			if (isUsingBakedTextures())  			{  				requestLayerSetUpdate(index);  			} -			else if (gAgentCamera.cameraCustomizeAvatar()) +			else  			{  				LLVisualParamHint::requestHintUpdates();  			} @@ -1622,15 +1622,18 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te  				if (tex_discard >= 0 && tex_discard <= desired_discard)  				{  					local_tex_obj->setDiscard(tex_discard); -					if (isSelf() && !gAgentCamera.cameraCustomizeAvatar()) +					if (isSelf()) +					{ +						if (gAgentAvatarp->isUsingBakedTextures())  					{  						requestLayerSetUpdate(type);  					} -					else if (isSelf() && gAgentCamera.cameraCustomizeAvatar()) +						else  					{  						LLVisualParamHint::requestHintUpdates();  					}  				} +				}  				else  				{					  					tex->setLoadedCallback(onLocalTextureLoaded, desired_discard, TRUE, FALSE, new LLAvatarTexData(getID(), type), NULL); @@ -2032,7 +2035,7 @@ void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTe  			imagep->setBoostLevel(getAvatarBoostLevel());  			imagep->resetTextureStats(); -			imagep->setMaxVirtualSizeResetInterval(16); +			imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL);  			imagep->addTextureStats( desired_pixels / texel_area_ratio );  			imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ;  			imagep->forceUpdateBindStats() ; diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp index dfa7ca7136..c5042ca016 100644 --- a/indra/newview/llwearable.cpp +++ b/indra/newview/llwearable.cpp @@ -698,7 +698,7 @@ void LLWearable::removeFromAvatar( LLWearableType::EType type, BOOL upload_bake  		}  	} -	if( gAgentCamera.cameraCustomizeAvatar() ) +	if(gAgentCamera.cameraCustomizeAvatar())  	{  		LLSideTray::getInstance()->showPanel("sidepanel_appearance", LLSD().with("type", "edit_outfit"));  	} diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index b614860b74..34f6fbebd6 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -465,6 +465,29 @@ std::string LLPanelDummyClothingListItem::wearableTypeToString(LLWearableType::E  //////////////////////////////////////////////////////////////////////////  ////////////////////////////////////////////////////////////////////////// +LLWearableItemTypeNameComparator::LLWearableTypeOrder::LLWearableTypeOrder(LLWearableItemTypeNameComparator::ETypeListOrder order_priority, bool sort_asset_by_name, bool sort_wearable_by_name): +		mOrderPriority(order_priority), +		mSortAssetTypeByName(sort_asset_by_name), +		mSortWearableTypeByName(sort_wearable_by_name) +{ +} + +LLWearableItemTypeNameComparator::LLWearableItemTypeNameComparator() +{ +	// By default the sort order conforms the order by spec of MY OUTFITS items list: +	// 1. CLOTHING - sorted by name +	// 2. OBJECT   - sorted by type +	// 3. BODYPART - sorted by name +	mWearableOrder[LLAssetType::AT_CLOTHING] = LLWearableTypeOrder(ORDER_RANK_1, false, false); +	mWearableOrder[LLAssetType::AT_OBJECT]   = LLWearableTypeOrder(ORDER_RANK_2, true, true); +	mWearableOrder[LLAssetType::AT_BODYPART] = LLWearableTypeOrder(ORDER_RANK_3, false, true); +} + +void LLWearableItemTypeNameComparator::setOrder(LLAssetType::EType items_of_type,  LLWearableItemTypeNameComparator::ETypeListOrder order_priority, bool sort_asset_items_by_name, bool sort_wearable_items_by_name) +{ +	mWearableOrder[items_of_type] = LLWearableTypeOrder(order_priority, sort_asset_items_by_name, sort_wearable_items_by_name); +} +  /*virtual*/  bool LLWearableItemNameComparator::doCompare(const LLPanelInventoryListItemBase* wearable_item1, const LLPanelInventoryListItemBase* wearable_item2) const  { @@ -493,7 +516,7 @@ bool LLWearableItemTypeNameComparator::doCompare(const LLPanelInventoryListItemB  		return item_type_order1 < item_type_order2;  	} -	if (item_type_order1 & TLO_SORTABLE_BY_NAME) +	if (sortAssetTypeByName(item_type1))  	{  		// If both items are of the same asset type except AT_CLOTHING and AT_BODYPART  		// we can compare them by name. @@ -505,59 +528,66 @@ bool LLWearableItemTypeNameComparator::doCompare(const LLPanelInventoryListItemB  	if (item_wearable_type1 != item_wearable_type2)  	{ -		// If items are of different clothing types they are compared -		// by clothing types order determined in LLWearableType::EType. +		// If items are of different LLWearableType::EType types they are compared +		// by LLWearableType::EType. types order determined in LLWearableType::EType.  		return item_wearable_type1 < item_wearable_type2;  	}  	else  	{  		// If both items are of the same clothing type they are compared -		// by description and place in reverse order i.e. outer layer item -		// on top. +		// by description and place in reverse order (i.e. outer layer item +		// on top) OR by name +		if(sortWearableTypeByName(item_type1)) +		{ +			return LLWearableItemNameComparator::doCompare(wearable_item1, wearable_item2); +		}  		return wearable_item1->getDescription() > wearable_item2->getDescription();  	}  } -// static -LLWearableItemTypeNameComparator::ETypeListOrder LLWearableItemTypeNameComparator::getTypeListOrder(LLAssetType::EType item_type) +LLWearableItemTypeNameComparator::ETypeListOrder LLWearableItemTypeNameComparator::getTypeListOrder(LLAssetType::EType item_type) const  { -	switch (item_type) -	{ -	case LLAssetType::AT_OBJECT: -		return TLO_ATTACHMENT; - -	case LLAssetType::AT_CLOTHING: -		return TLO_CLOTHING; - -	case LLAssetType::AT_BODYPART: -		return TLO_BODYPART; +	wearable_type_order_map_t::const_iterator const_it = mWearableOrder.find(item_type); -	default: -		return TLO_UNKNOWN; +	if(const_it == mWearableOrder.end()) +	{ +		llwarns<<"Absent information about order rang of items of "<<LLAssetType::getDesc(item_type)<<" type"<<llendl; +		return ORDER_RANK_UNKNOWN;  	} + +	return const_it->second.mOrderPriority;  } -/*virtual*/ -bool LLWearableItemCreationDateComparator::doCompare(const LLPanelInventoryListItemBase* item1, const LLPanelInventoryListItemBase* item2) const +bool LLWearableItemTypeNameComparator::sortAssetTypeByName(LLAssetType::EType item_type) const  { -	time_t date1 = item1->getCreationDate(); -	time_t date2 = item2->getCreationDate(); +	wearable_type_order_map_t::const_iterator const_it = mWearableOrder.find(item_type); -	if (date1 == date2) +	if(const_it == mWearableOrder.end())  	{ -		return LLWearableItemNameComparator::doCompare(item1, item2); +		llwarns<<"Absent information about sorting items of "<<LLAssetType::getDesc(item_type)<<" type"<<llendl; +		return true; +	} + +	return const_it->second.mSortAssetTypeByName;  	} -	return date1 > date2; +bool LLWearableItemTypeNameComparator::sortWearableTypeByName(LLAssetType::EType item_type) const +{ +	wearable_type_order_map_t::const_iterator const_it = mWearableOrder.find(item_type); + +	if(const_it == mWearableOrder.end()) +	{ +		llwarns<<"Absent information about sorting items of "<<LLAssetType::getDesc(item_type)<<" type"<<llendl; +		return true;  } +	return const_it->second.mSortWearableTypeByName; +}  //////////////////////////////////////////////////////////////////////////  //////////////////////////////////////////////////////////////////////////  //////////////////////////////////////////////////////////////////////////  static const LLWearableItemTypeNameComparator WEARABLE_TYPE_NAME_COMPARATOR; -static const LLWearableItemNameComparator WEARABLE_NAME_COMPARATOR; -static const LLWearableItemCreationDateComparator WEARABLE_CREATION_DATE_COMPARATOR;  static const LLDefaultChildRegistry::Register<LLWearableItemsList> r("wearable_items_list"); @@ -569,7 +599,7 @@ LLWearableItemsList::Params::Params()  LLWearableItemsList::LLWearableItemsList(const LLWearableItemsList::Params& p)  :	LLInventoryItemsList(p)  { -	setSortOrder(E_SORT_BY_TYPE, false); +	setComparator(&WEARABLE_TYPE_NAME_COMPARATOR);  	mIsStandalone = p.standalone;  	if (mIsStandalone)  	{ @@ -669,32 +699,6 @@ void LLWearableItemsList::onRightClick(S32 x, S32 y)  	ContextMenu::instance().show(this, selected_uuids, x, y);  } -void LLWearableItemsList::setSortOrder(ESortOrder sort_order, bool sort_now) -{ -	switch (sort_order) -	{ -	case E_SORT_BY_MOST_RECENT: -		setComparator(&WEARABLE_CREATION_DATE_COMPARATOR); -		break; -	case E_SORT_BY_NAME: -		setComparator(&WEARABLE_NAME_COMPARATOR); -		break; -	case E_SORT_BY_TYPE: -		setComparator(&WEARABLE_TYPE_NAME_COMPARATOR); -		break; - -	// No "default:" to raise compiler warning -	// if we're not handling something -	} - -	mSortOrder = sort_order; - -	if (sort_now) -	{ -		sort(); -	} -} -  //////////////////////////////////////////////////////////////////////////  /// ContextMenu  ////////////////////////////////////////////////////////////////////////// @@ -718,13 +722,11 @@ LLContextMenu* LLWearableItemsList::ContextMenu::createMenu()  	const uuid_vec_t& ids = mUUIDs;		// selected items IDs  	LLUUID selected_id = ids.front();	// ID of the first selected item -	functor_t wear = boost::bind(&LLAppearanceMgr::wearItemOnAvatar, LLAppearanceMgr::getInstance(), _1, true, true, LLPointer<LLInventoryCallback>(NULL)); -	functor_t add = boost::bind(&LLAppearanceMgr::wearItemOnAvatar, LLAppearanceMgr::getInstance(), _1, true, false, LLPointer<LLInventoryCallback>(NULL));  	functor_t take_off = boost::bind(&LLAppearanceMgr::removeItemFromAvatar, LLAppearanceMgr::getInstance(), _1);  	// Register handlers common for all wearable types. -	registrar.add("Wearable.Wear", boost::bind(handleMultiple, wear, ids)); -	registrar.add("Wearable.Add", boost::bind(handleMultiple, add, ids)); +	registrar.add("Wearable.Wear", boost::bind(wear_multiple, ids, true)); +	registrar.add("Wearable.Add", boost::bind(wear_multiple, ids, false));  	registrar.add("Wearable.Edit", boost::bind(handleMultiple, LLAgentWearables::editWearable, ids));  	registrar.add("Wearable.CreateNew", boost::bind(createNewWearable, selected_id));  	registrar.add("Wearable.ShowOriginal", boost::bind(show_item_original, selected_id)); @@ -767,6 +769,8 @@ void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu  	U32 n_links = 0;				// number of links among the selected items  	U32 n_editable = 0;				// number of editable items among the selected ones +	bool can_be_worn = true; +  	for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it)  	{  		LLUUID id = *it; @@ -802,16 +806,21 @@ void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu  		{  			++n_already_worn;  		} + +		if (can_be_worn) +		{ +			can_be_worn = get_can_item_be_worn(item->getLinkedUUID()); +		}  	} // for  	bool standalone = mParent ? mParent->isStandalone() : false;  	// *TODO: eliminate multiple traversals over the menu items -	setMenuItemVisible(menu, "wear_wear", 			n_already_worn == 0 && n_worn == 0); +	setMenuItemVisible(menu, "wear_wear", 			n_already_worn == 0 && n_worn == 0 && can_be_worn);  	setMenuItemEnabled(menu, "wear_wear", 			n_already_worn == 0 && n_worn == 0); -	setMenuItemVisible(menu, "wear_add",			mask == MASK_CLOTHING && n_worn == 0 && n_already_worn != 0); +	setMenuItemVisible(menu, "wear_add",			mask == MASK_CLOTHING && n_worn == 0 && n_already_worn != 0 && can_be_worn);  	setMenuItemEnabled(menu, "wear_add",			n_items == 1 && canAddWearable(ids.front()) && n_already_worn != 0); -	setMenuItemVisible(menu, "wear_replace",		n_worn == 0 && n_already_worn != 0); +	setMenuItemVisible(menu, "wear_replace",		n_worn == 0 && n_already_worn != 0 && can_be_worn);  	//visible only when one item selected and this item is worn  	setMenuItemVisible(menu, "edit",				!standalone && mask & (MASK_CLOTHING|MASK_BODYPART) && n_worn == n_items && n_worn == 1);  	setMenuItemEnabled(menu, "edit",				n_editable == 1 && n_worn == 1 && n_items == 1); diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h index 55f8996140..2e720d13bb 100644 --- a/indra/newview/llwearableitemslist.h +++ b/indra/newview/llwearableitemslist.h @@ -307,46 +307,76 @@ class LLWearableItemTypeNameComparator : public LLWearableItemNameComparator  	LOG_CLASS(LLWearableItemTypeNameComparator);  public: -	LLWearableItemTypeNameComparator() {}; + +	LLWearableItemTypeNameComparator();  	virtual ~LLWearableItemTypeNameComparator() {}; +	enum ETypeListOrder +	{ +		ORDER_RANK_1 = 1, +		ORDER_RANK_2, +		ORDER_RANK_3, +		ORDER_RANK_UNKNOWN +	}; + +	void setOrder(LLAssetType::EType items_of_type, ETypeListOrder order_priority, bool sort_items_by_name, bool sort_wearable_items_by_name); +  protected:  	/** -	 * Returns "true" if wearable_item1 is placed before wearable_item2 sorted by the following: -	 *   - Attachments (abc order) -	 *   - Clothing +	 * All information about sort order is stored in mWearableOrder map +	 * +	 * mWearableOrder :      KYES              VALUES +	 *                  [LLAssetType] [struct LLWearableTypeOrder] +	 * +	 *--------------------------------------------------------------------------------------------- +	 * I. Determines order (ORDER_RANK) in which items of LLAssetType should be displayed in list. +	 *     For example by spec in MY OUTFITS the order is: +	 *     1. AT_CLOTHING (ORDER_RANK_1) +	 *     2. AT_OBJECT   (ORDER_RANK_2) +	 *     3. AT_BODYPART (ORDER_RANK_3) +	 * +	 * II.Items of each type(LLAssetType) are sorted by name or type(LLWearableType) +	 *     For example by spec in MY OUTFITS the order within each items type(LLAssetType) is: +	 *     1. AT_OBJECTS (abc order) +	 *     2. AT_CLOTHINGS  	 *         - by type (types order determined in LLWearableType::EType)  	 *         - outer layer on top -	 *   - Body Parts (abc order), -	 * "false" otherwise. +	 *     3. AT_BODYPARTS  (abc order) +	 *--------------------------------------------------------------------------------------------- +	 * +	 * For each LLAssetType (KEYS in mWearableOrder) the information about: +	 * +	 *                                             I.  ORDER_RANK (the flag is LLWearableTypeOrder::mOrderPriority) +	 * +	 *                                             II. whether items of this LLAssetType type should be ordered +	 *                                                 by name or by LLWearableType::EType (the flag is LLWearableTypeOrder::mSortAssetTypeByName) +	 * +	 *                                             III.whether items of LLWearableType type within this LLAssetType +	 *                                                 should be ordered by name (the flag is LLWearableTypeOrder::mSortWearableTypeByName) +	 * +	 *  holds in mWearableOrder map as VALUES (struct LLWearableTypeOrder).  	 */  	/*virtual*/ bool doCompare(const LLPanelInventoryListItemBase* wearable_item1, const LLPanelInventoryListItemBase* wearable_item2) const;  private: -	enum ETypeListOrder + +	struct LLWearableTypeOrder  	{ -		TLO_CLOTHING	= 0x01, -		TLO_ATTACHMENT	= 0x02, -		TLO_BODYPART	= 0x04, -		TLO_UNKNOWN		= 0x08, +		ETypeListOrder mOrderPriority; +		bool mSortAssetTypeByName; +		bool mSortWearableTypeByName; -		TLO_SORTABLE_BY_NAME = TLO_ATTACHMENT | TLO_UNKNOWN +		LLWearableTypeOrder(ETypeListOrder order_priority, bool sort_asset_by_name, bool sort_wearable_by_name); +		LLWearableTypeOrder(){};  	}; -	static LLWearableItemTypeNameComparator::ETypeListOrder getTypeListOrder(LLAssetType::EType item_type); -}; +	ETypeListOrder getTypeListOrder(LLAssetType::EType item_type) const; -/** - * @class LLWearableItemCreationDateComparator - * - * Comparator for sorting wearable list items by creation date (newest go first). - */ -class LLWearableItemCreationDateComparator : public LLWearableItemNameComparator -{ -	LOG_CLASS(LLWearableItemCreationDateComparator); +	bool sortAssetTypeByName(LLAssetType::EType item_type) const; +	bool sortWearableTypeByName(LLAssetType::EType item_type) const; -protected: -	/*virtual*/ bool doCompare(const LLPanelInventoryListItemBase* item1, const LLPanelInventoryListItemBase* item2) const; +	typedef std::map<LLAssetType::EType,LLWearableTypeOrder> wearable_type_order_map_t; +	wearable_type_order_map_t mWearableOrder;  };  /** @@ -401,13 +431,6 @@ public:  		Params();  	}; -	typedef enum e_sort_order { -		// Values should be compatible with InventorySortOrder setting. -		E_SORT_BY_NAME			= 0, -		E_SORT_BY_MOST_RECENT	= 1, -		E_SORT_BY_TYPE			= 2, -	} ESortOrder; -  	virtual ~LLWearableItemsList();  	/*virtual*/ void addNewItem(LLViewerInventoryItem* item, bool rearrange = true); @@ -422,10 +445,6 @@ public:  	bool isStandalone() const { return mIsStandalone; } -	ESortOrder getSortOrder() const { return mSortOrder; } - -	void setSortOrder(ESortOrder sort_order, bool sort_now = true); -  protected:  	friend class LLUICtrlFactory;  	LLWearableItemsList(const LLWearableItemsList::Params& p); @@ -434,8 +453,6 @@ protected:  	bool mIsStandalone;  	bool mWornIndicationEnabled; - -	ESortOrder		mSortOrder;  };  #endif //LL_LLWEARABLEITEMSLIST_H diff --git a/indra/newview/llworldmap.cpp b/indra/newview/llworldmap.cpp index 66cb02ce99..9bbe005de8 100644 --- a/indra/newview/llworldmap.cpp +++ b/indra/newview/llworldmap.cpp @@ -37,6 +37,7 @@  #include "llworldmapmessage.h"  #include "message.h"  #include "lltracker.h" +#include "lluistring.h"  #include "llviewertexturelist.h"  #include "lltrans.h" @@ -522,8 +523,12 @@ bool LLWorldMap::insertItem(U32 x_world, U32 y_world, std::string& name, LLUUID&  		case MAP_ITEM_LAND_FOR_SALE:		// land for sale  		case MAP_ITEM_LAND_FOR_SALE_ADULT:	// adult land for sale   		{ -			std::string tooltip = llformat("%d sq. m. L$%d", extra, extra2); -			new_item.setTooltip(tooltip); +			static LLUIString tooltip_fmt = LLTrans::getString("worldmap_item_tooltip_format"); + +			tooltip_fmt.setArg("[AREA]",  llformat("%d", extra)); +			tooltip_fmt.setArg("[PRICE]", llformat("%d", extra2)); +			new_item.setTooltip(tooltip_fmt.getString()); +  			if (type == MAP_ITEM_LAND_FOR_SALE)  			{  				siminfo->insertLandForSale(new_item); diff --git a/indra/newview/llworldmap.h b/indra/newview/llworldmap.h index e4e677eb64..b97e5249e1 100644 --- a/indra/newview/llworldmap.h +++ b/indra/newview/llworldmap.h @@ -52,7 +52,7 @@ public:  	LLItemInfo(F32 global_x, F32 global_y, const std::string& name, LLUUID id);  	// Setters -	void setTooltip(std::string& tooltip) { mToolTip = tooltip; } +	void setTooltip(const std::string& tooltip) { mToolTip = tooltip; }  	void setElevation(F64 z) { mPosGlobal.mdV[VZ] = z; }  	void setCount(S32 count) { mCount = count; }  //	void setSelected(bool selected) { mSelected = selected; } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 1dc46a4012..c8f834c7f7 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -635,10 +635,10 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  void LLPipeline::updateRenderDeferred()  {  	BOOL deferred = (gSavedSettings.getBOOL("RenderDeferred") &&  -			 LLRenderTarget::sUseFBO && +		LLRenderTarget::sUseFBO &&  			 LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && -			 gSavedSettings.getBOOL("VertexShaderEnable") &&  -			 gSavedSettings.getBOOL("RenderAvatarVP") && +		gSavedSettings.getBOOL("VertexShaderEnable") &&  +		gSavedSettings.getBOOL("RenderAvatarVP") &&  			 (gSavedSettings.getBOOL("WindLightUseAtmosShaders")) ? TRUE : FALSE) &&  		!gUseWireframe; @@ -1975,8 +1975,8 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera)  	if(drawablep && !drawablep->isDead())  	{ -		if (drawablep->isSpatialBridge()) -		{ +	if (drawablep->isSpatialBridge()) +	{  			const LLDrawable* root = ((LLSpatialBridge*) drawablep)->mDrawable;  			llassert(root); // trying to catch a bad assumption  			if (root && //  // this test may not be needed, see above @@ -1988,24 +1988,24 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera)  					LLViewerObject *vobj = rootparent->getVObj();  					llassert(vobj); // trying to catch a bad assumption  					if (vobj) // this test may not be needed, see above -					{ +		{  						const LLVOAvatar* av = vobj->asAvatar(); -						if (av && av->isImpostor()) -						{ -							return; -						} -					} -				} +			if (av && av->isImpostor()) +			{ +				return;  			} -			sCull->pushBridge((LLSpatialBridge*) drawablep); -		} -		else -		{ -			sCull->pushDrawable(drawablep);  		} - -		drawablep->setVisible(camera); +				} +			} +		sCull->pushBridge((LLSpatialBridge*) drawablep); +	} +	else +	{ +		sCull->pushDrawable(drawablep);  	} + +	drawablep->setVisible(camera); +}  }  void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion) @@ -3616,7 +3616,7 @@ void LLPipeline::renderDebug()  			if (i > 3)  			{ //render shadow frusta as volumes  				if (mShadowFrustPoints[i-4].empty()) -				{ +			{  					continue;  				} @@ -3649,22 +3649,22 @@ void LLPipeline::renderDebug()  			if (i < 4)  			{ - +				  				if (i == 0 || !mShadowFrustPoints[i].empty())  				{  					//render visible point cloud  					gGL.flush();  					glPointSize(8.f);  					gGL.begin(LLRender::POINTS); - +					  					F32* c = col+i*4;  					gGL.color3fv(c);  					for (U32 j = 0; j < mShadowFrustPoints[i].size(); ++j) -					{	 -						gGL.vertex3fv(mShadowFrustPoints[i][j].mV); +						{ +							gGL.vertex3fv(mShadowFrustPoints[i][j].mV); -					} +						}  					gGL.end();  					gGL.flush(); @@ -3690,7 +3690,7 @@ void LLPipeline::renderDebug()  					gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[6].mV);  					gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[7].mV);  					gGL.end(); -				} +					}  			} @@ -4315,7 +4315,7 @@ void LLPipeline::setupAvatarLights(BOOL for_edit)  		glLightf (GL_LIGHT1, GL_LINEAR_ATTENUATION, 	 0.0f);  		glLightf (GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.0f);  		glLightf (GL_LIGHT1, GL_SPOT_EXPONENT, 		 0.0f); -		glLightf (GL_LIGHT1, GL_SPOT_CUTOFF,		 180.0f); +		glLightf (GL_LIGHT1, GL_SPOT_CUTOFF, 			 180.0f);  	}  	else if (gAvatarBacklight) // Always true (unless overridden in a devs .ini)  	{ @@ -4631,8 +4631,8 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)  			}  			else // omnidirectional (point) light  			{ -				glLightf (gllight, GL_SPOT_EXPONENT, 0.0f); -				glLightf (gllight, GL_SPOT_CUTOFF,   180.0f); +			glLightf (gllight, GL_SPOT_EXPONENT,          0.0f); +			glLightf (gllight, GL_SPOT_CUTOFF,            180.0f);  				// we use specular.w = 1.0 as a cheap hack for the shaders to know that this is omnidirectional rather than a spotlight  				const float specular[] = {0.f, 0.f, 0.f, 1.f}; @@ -4666,7 +4666,7 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)  		F32 light_radius = 16.f; -		F32 x = 3.f; +			F32 x = 3.f;  		float linatten = x / (light_radius); // % of brightness at radius  		mHWLightColors[2] = light_color; @@ -6336,13 +6336,13 @@ void LLPipeline::renderDeferredLighting()  			glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], 0);  		} -		glPushMatrix(); -		glLoadIdentity(); -		glMatrixMode(GL_PROJECTION); -		glPushMatrix(); -		glLoadIdentity(); +			glPushMatrix(); +			glLoadIdentity(); +			glMatrixMode(GL_PROJECTION); +			glPushMatrix(); +			glLoadIdentity(); -		mDeferredLight[0].bindTarget(); +			mDeferredLight[0].bindTarget();  		if (gSavedSettings.getBOOL("RenderDeferredSSAO") || gSavedSettings.getS32("RenderShadowDetail") > 0)  		{ @@ -6387,19 +6387,19 @@ void LLPipeline::renderDeferredLighting()  				unbindDeferredShader(gDeferredSunProgram);  			}  		} -		else -		{ +			else +			{  			glClearColor(1,1,1,1); -			mDeferredLight[0].clear(GL_COLOR_BUFFER_BIT); +				mDeferredLight[0].clear(GL_COLOR_BUFFER_BIT);  			glClearColor(0,0,0,0); -		} +			} -		mDeferredLight[0].flush(); +			mDeferredLight[0].flush();  		{ //global illumination specific block (still experimental)  			if (gSavedSettings.getBOOL("RenderDeferredBlurLight") && -				gSavedSettings.getBOOL("RenderDeferredGI")) -			{  +			    gSavedSettings.getBOOL("RenderDeferredGI")) +			{  				LLFastTimer ftm(FTM_EDGE_DETECTION);  				//generate edge map  				LLGLDisable blend(GL_BLEND); @@ -6501,75 +6501,75 @@ void LLPipeline::renderDeferredLighting()  		}  		if (gSavedSettings.getBOOL("RenderDeferredSSAO")) -		{ //soften direct lighting lightmap -			LLFastTimer ftm(FTM_SOFTEN_SHADOW); -			//blur lightmap -			mDeferredLight[1].bindTarget(); +			{ //soften direct lighting lightmap +				LLFastTimer ftm(FTM_SOFTEN_SHADOW); +				//blur lightmap +				mDeferredLight[1].bindTarget(); -			glClearColor(1,1,1,1); -			mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT); -			glClearColor(0,0,0,0); -			 -			bindDeferredShader(gDeferredBlurLightProgram); +				glClearColor(1,1,1,1); +				mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT); +				glClearColor(0,0,0,0); +				 +				bindDeferredShader(gDeferredBlurLightProgram); -			LLVector3 go = gSavedSettings.getVector3("RenderShadowGaussian"); -			const U32 kern_length = 4; -			F32 blur_size = gSavedSettings.getF32("RenderShadowBlurSize"); -			F32 dist_factor = gSavedSettings.getF32("RenderShadowBlurDistFactor"); +				LLVector3 go = gSavedSettings.getVector3("RenderShadowGaussian"); +				const U32 kern_length = 4; +				F32 blur_size = gSavedSettings.getF32("RenderShadowBlurSize"); +				F32 dist_factor = gSavedSettings.getF32("RenderShadowBlurDistFactor"); -			// sample symmetrically with the middle sample falling exactly on 0.0 -			F32 x = 0.f; +				// sample symmetrically with the middle sample falling exactly on 0.0 +				F32 x = 0.f; -			LLVector3 gauss[32]; // xweight, yweight, offset +				LLVector3 gauss[32]; // xweight, yweight, offset -			for (U32 i = 0; i < kern_length; i++) -			{ -				gauss[i].mV[0] = llgaussian(x, go.mV[0]); -				gauss[i].mV[1] = llgaussian(x, go.mV[1]); -				gauss[i].mV[2] = x; -				x += 1.f; -			} +				for (U32 i = 0; i < kern_length; i++) +				{ +					gauss[i].mV[0] = llgaussian(x, go.mV[0]); +					gauss[i].mV[1] = llgaussian(x, go.mV[1]); +					gauss[i].mV[2] = x; +					x += 1.f; +				} -			gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f); -			gDeferredBlurLightProgram.uniform1f("dist_factor", dist_factor); -			gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); -			gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); -			gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); -		 -			{ -				LLGLDisable blend(GL_BLEND); -				LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); -				stop_glerror(); -				glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); -				stop_glerror(); -			} +				gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f); +				gDeferredBlurLightProgram.uniform1f("dist_factor", dist_factor); +				gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); +				gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); +				gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); -			mDeferredLight[1].flush(); -			unbindDeferredShader(gDeferredBlurLightProgram); +				{ +					LLGLDisable blend(GL_BLEND); +					LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); +					stop_glerror(); +					glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); +					stop_glerror(); +				} +				 +				mDeferredLight[1].flush(); +				unbindDeferredShader(gDeferredBlurLightProgram); -			bindDeferredShader(gDeferredBlurLightProgram, 1); -			mDeferredLight[0].bindTarget(); +				bindDeferredShader(gDeferredBlurLightProgram, 1); +				mDeferredLight[0].bindTarget(); -			gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f); +				gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f); -			{ -				LLGLDisable blend(GL_BLEND); -				LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); -				stop_glerror(); -				glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); -				stop_glerror(); +				{ +					LLGLDisable blend(GL_BLEND); +					LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); +					stop_glerror(); +					glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); +					stop_glerror(); +				} +				mDeferredLight[0].flush(); +				unbindDeferredShader(gDeferredBlurLightProgram);  			} -			mDeferredLight[0].flush(); -			unbindDeferredShader(gDeferredBlurLightProgram); -		} -		stop_glerror(); -		glPopMatrix(); -		stop_glerror(); -		glMatrixMode(GL_MODELVIEW); -		stop_glerror(); -		glPopMatrix(); -		stop_glerror(); +			stop_glerror(); +			glPopMatrix(); +			stop_glerror(); +			glMatrixMode(GL_MODELVIEW); +			stop_glerror(); +			glPopMatrix(); +			stop_glerror();  		//copy depth and stencil from deferred screen  		//mScreen.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), @@ -7232,7 +7232,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  		LLPipeline::sUseOcclusion = llmin(occlusion, 1);  		gPipeline.pushRenderTypeMask(); -		 +  		glh::matrix4f projection = glh_get_current_projection();  		glh::matrix4f mat; @@ -7322,24 +7322,24 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  				}  				gPipeline.pushRenderTypeMask(); -				 +  				clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER,  									LLPipeline::RENDER_TYPE_GROUND,  									LLPipeline::RENDER_TYPE_SKY,  									LLPipeline::RENDER_TYPE_CLOUDS,  									LLPipeline::END_RENDER_TYPES);	 -				S32 detail = gSavedSettings.getS32("RenderReflectionDetail"); +					S32 detail = gSavedSettings.getS32("RenderReflectionDetail");  				if (detail > 0)  				{ //mask out selected geometry based on reflection detail  					if (detail < 4)  					{  						clearRenderTypeMask(LLPipeline::RENDER_TYPE_PARTICLES, END_RENDER_TYPES); -						if (detail < 3) -						{ +					if (detail < 3) +					{  							clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES); -							if (detail < 2) -							{ +						if (detail < 2) +						{  								clearRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME, END_RENDER_TYPES);  							}  						} @@ -7351,15 +7351,15 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  					stateSort(camera, ref_result);  				} -				if (LLDrawPoolWater::sNeedsDistortionUpdate) -				{ +			if (LLDrawPoolWater::sNeedsDistortionUpdate) +			{  					if (gSavedSettings.getS32("RenderReflectionDetail") > 0) -					{ -						gPipeline.grabReferences(ref_result); -						LLGLUserClipPlane clip_plane(plane, mat, projection); -						renderGeom(camera); -					} +				{ +					gPipeline.grabReferences(ref_result); +					LLGLUserClipPlane clip_plane(plane, mat, projection); +					renderGeom(camera);  				} +			}	  				gPipeline.popRenderTypeMask();  			}	 @@ -7663,7 +7663,7 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector  	//bounding box line segments  	U32 bs[] =  -	{ +			{  		0,1,  		1,3,  		3,2, @@ -7701,9 +7701,9 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector  				LLVector3 intersect = v2+line*t;  				pp.push_back(intersect);  			} +			}  		} -	} - +			  	//camera frustum line segments  	const U32 fs[] =  	{ @@ -7716,7 +7716,7 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector  		5,6,  		6,7,  		7,4, - +	  		0,4,  		1,5,  		2,6, @@ -7725,7 +7725,7 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector  	LLVector3 center = (max+min)*0.5f;  	LLVector3 size = (max-min)*0.5f; - +	  	for (U32 i = 0; i < 12; i++)  	{  		for (U32 j = 0; j < 6; ++j) @@ -7748,17 +7748,17 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector  				pp.push_back(intersect);  			}	  		} -	} -	 +				} +  	LLVector3 ext[] = { min-LLVector3(0.05f,0.05f,0.05f),  		max+LLVector3(0.05f,0.05f,0.05f) };  	for (U32 i = 0; i < pp.size(); ++i)  	{  		bool found = true; -		 -		const F32* p = pp[i].mV; +		const F32* p = pp[i].mV; +			  		for (U32 j = 0; j < 3; ++j)  		{  			if (p[j] < ext[0].mV[j] || @@ -7768,24 +7768,24 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector  				break;  			}  		} -			 +				  		for (U32 j = 0; j < 6; ++j)  		{  			const LLPlane& cp = camera.getAgentPlane(j);  			F32 dist = cp.dist(pp[i]);  			if (dist > 0.05f) //point is above some plane, not contained -			{ +					{  				found = false;  				break; -			} -		} +						} +					} -		if (found) -		{ +					if (found) +					{  			fp.push_back(pp[i]);  		}  	} - +	  	if (fp.empty())  	{  		return FALSE; @@ -8588,141 +8588,141 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  		}  	} - +	  	//hack to disable projector shadows   	static bool clear = true;  	bool gen_shadow = gSavedSettings.getS32("RenderShadowDetail") > 1; -	 +  	if (gen_shadow)  	{  		clear = true; -		F32 fade_amt = gFrameIntervalSeconds * llmax(LLViewerCamera::getInstance()->getVelocityStat()->getCurrentPerSec(), 1.f); +	F32 fade_amt = gFrameIntervalSeconds * llmax(LLViewerCamera::getInstance()->getVelocityStat()->getCurrentPerSec(), 1.f); -		//update shadow targets -		for (U32 i = 0; i < 2; i++) -		{ //for each current shadow -			LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW4+i; - -			if (mShadowSpotLight[i].notNull() &&  -				(mShadowSpotLight[i] == mTargetShadowSpotLight[0] || -				mShadowSpotLight[i] == mTargetShadowSpotLight[1])) -			{ //keep this spotlight -				mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f); -			} -			else -			{ //fade out this light -				mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f); -				 -				if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull()) -				{ //faded out, grab one of the pending spots (whichever one isn't already taken) -					if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2]) -					{ -						mShadowSpotLight[i] = mTargetShadowSpotLight[0]; -					} -					else -					{ -						mShadowSpotLight[i] = mTargetShadowSpotLight[1]; -					} +	//update shadow targets +	for (U32 i = 0; i < 2; i++) +	{ //for each current shadow +		LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW4+i; + +		if (mShadowSpotLight[i].notNull() &&  +			(mShadowSpotLight[i] == mTargetShadowSpotLight[0] || +			mShadowSpotLight[i] == mTargetShadowSpotLight[1])) +		{ //keep this spotlight +			mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f); +		} +		else +		{ //fade out this light +			mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f); +			 +			if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull()) +			{ //faded out, grab one of the pending spots (whichever one isn't already taken) +				if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2]) +				{ +					mShadowSpotLight[i] = mTargetShadowSpotLight[0]; +				} +				else +				{ +					mShadowSpotLight[i] = mTargetShadowSpotLight[1];  				}  			}  		} -		 -		for (S32 i = 0; i < 2; i++) -		{ -			glh_set_current_modelview(saved_view); -			glh_set_current_projection(saved_proj); +	} -			if (mShadowSpotLight[i].isNull()) -			{ -				continue; -			} +	for (S32 i = 0; i < 2; i++) +	{ +		glh_set_current_modelview(saved_view); +		glh_set_current_projection(saved_proj); -			LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume(); +		if (mShadowSpotLight[i].isNull()) +		{ +			continue; +		} -			if (!volume) -			{ -				mShadowSpotLight[i] = NULL; -				continue; -			} +		LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume(); -			LLDrawable* drawable = mShadowSpotLight[i]; +		if (!volume) +		{ +			mShadowSpotLight[i] = NULL; +			continue; +		} -			LLVector3 params = volume->getSpotLightParams(); -			F32 fov = params.mV[0]; +		LLDrawable* drawable = mShadowSpotLight[i]; -			//get agent->light space matrix (modelview) -			LLVector3 center = drawable->getPositionAgent(); -			LLQuaternion quat = volume->getRenderRotation(); +		LLVector3 params = volume->getSpotLightParams(); +		F32 fov = params.mV[0]; -			//get near clip plane -			LLVector3 scale = volume->getScale(); -			LLVector3 at_axis(0,0,-scale.mV[2]*0.5f); -			at_axis *= quat; +		//get agent->light space matrix (modelview) +		LLVector3 center = drawable->getPositionAgent(); +		LLQuaternion quat = volume->getRenderRotation(); -			LLVector3 np = center+at_axis; -			at_axis.normVec(); +		//get near clip plane +		LLVector3 scale = volume->getScale(); +		LLVector3 at_axis(0,0,-scale.mV[2]*0.5f); +		at_axis *= quat; -			//get origin that has given fov for plane np, at_axis, and given scale -			F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f); +		LLVector3 np = center+at_axis; +		at_axis.normVec(); -			LLVector3 origin = np - at_axis*dist; +		//get origin that has given fov for plane np, at_axis, and given scale +		F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f); -			LLMatrix4 mat(quat, LLVector4(origin, 1.f)); +		LLVector3 origin = np - at_axis*dist; -			view[i+4] = glh::matrix4f((F32*) mat.mMatrix); +		LLMatrix4 mat(quat, LLVector4(origin, 1.f)); -			view[i+4] = view[i+4].inverse(); +		view[i+4] = glh::matrix4f((F32*) mat.mMatrix); -			//get perspective matrix -			F32 near_clip = dist+0.01f; -			F32 width = scale.mV[VX]; -			F32 height = scale.mV[VY]; -			F32 far_clip = dist+volume->getLightRadius()*1.5f; +		view[i+4] = view[i+4].inverse(); -			F32 fovy = fov * RAD_TO_DEG; -			F32 aspect = width/height; -			 -			proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip); +		//get perspective matrix +		F32 near_clip = dist+0.01f; +		F32 width = scale.mV[VX]; +		F32 height = scale.mV[VY]; +		F32 far_clip = dist+volume->getLightRadius()*1.5f; -			//translate and scale to from [-1, 1] to [0, 1] -			glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, -							0.f, 0.5f, 0.f, 0.5f, -							0.f, 0.f, 0.5f, 0.5f, -							0.f, 0.f, 0.f, 1.f); +		F32 fovy = fov * RAD_TO_DEG; +		F32 aspect = width/height; +		 +		proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip); -			glh_set_current_modelview(view[i+4]); -			glh_set_current_projection(proj[i+4]); +		//translate and scale to from [-1, 1] to [0, 1] +		glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, +						0.f, 0.5f, 0.f, 0.5f, +						0.f, 0.f, 0.5f, 0.5f, +						0.f, 0.f, 0.f, 1.f); -			mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view; -			 -			for (U32 j = 0; j < 16; j++) -			{ -				gGLLastModelView[j] = mShadowModelview[i+4].m[j]; -				gGLLastProjection[j] = mShadowProjection[i+4].m[j]; -			} +		glh_set_current_modelview(view[i+4]); +		glh_set_current_projection(proj[i+4]); + +		mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view; +		 +		for (U32 j = 0; j < 16; j++) +		{ +			gGLLastModelView[j] = mShadowModelview[i+4].m[j]; +			gGLLastProjection[j] = mShadowProjection[i+4].m[j]; +		} -			mShadowModelview[i+4] = view[i+4]; -			mShadowProjection[i+4] = proj[i+4]; +		mShadowModelview[i+4] = view[i+4]; +		mShadowProjection[i+4] = proj[i+4]; -			LLCamera shadow_cam = camera; -			shadow_cam.setFar(far_clip); -			shadow_cam.setOrigin(origin); +		LLCamera shadow_cam = camera; +		shadow_cam.setFar(far_clip); +		shadow_cam.setOrigin(origin); -			LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); +		LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); -			stop_glerror(); +		stop_glerror(); -			mShadow[i+4].bindTarget(); -			mShadow[i+4].getViewport(gGLViewport); +		mShadow[i+4].bindTarget(); +		mShadow[i+4].getViewport(gGLViewport); -			static LLCullResult result[2]; +		static LLCullResult result[2]; -			LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+i+4; +		LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+i+4; -			renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE); +		renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE); -			mShadow[i+4].flush(); - 		} +		mShadow[i+4].flush(); + 	}  	}  	else  	{ diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 2188c71ff9..5ba1fc9b21 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -113,7 +113,7 @@       reference="LtYellow" />      <color       name="AgentLinkColor" -     reference="White" /> +     reference="EmphasisColor" />      <color       name="AlertTextColor"       value="0.58 0.66 0.84 1" /> diff --git a/indra/newview/skins/default/xui/da/panel_nearby_media.xml b/indra/newview/skins/default/xui/da/panel_nearby_media.xml index 7d25b2af99..a269e35f4b 100644 --- a/indra/newview/skins/default/xui/da/panel_nearby_media.xml +++ b/indra/newview/skins/default/xui/da/panel_nearby_media.xml @@ -42,7 +42,7 @@  			<scroll_list.columns label="Navn" name="media_name"/>  			<scroll_list.columns label="Debug" name="media_debug"/>  		</scroll_list> -		<panel> +		<panel name="media_controls_panel">  			<layout_stack name="media_controls">  				<layout_panel name="stop">  					<button name="stop_btn" tool_tip="Stop valgte medie"/> diff --git a/indra/newview/skins/default/xui/da/sidepanel_item_info.xml b/indra/newview/skins/default/xui/da/sidepanel_item_info.xml index 070b4218a8..b1ec2c44df 100644 --- a/indra/newview/skins/default/xui/da/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/da/sidepanel_item_info.xml @@ -23,7 +23,8 @@  	</panel.string>  	<text name="title" value="Profil for genstand"/>  	<text name="origin" value="(Beholdning)"/> -	<panel label=""> +	<panel label="" +           name="item_profile">  		<text name="LabelItemNameTitle">  			Navn:  		</text> diff --git a/indra/newview/skins/default/xui/de/panel_nearby_media.xml b/indra/newview/skins/default/xui/de/panel_nearby_media.xml index e7886fa149..ef66148902 100644 --- a/indra/newview/skins/default/xui/de/panel_nearby_media.xml +++ b/indra/newview/skins/default/xui/de/panel_nearby_media.xml @@ -42,7 +42,7 @@  			<scroll_list.columns label="Name" name="media_name"/>  			<scroll_list.columns label="Fehler beseitigen" name="media_debug"/>  		</scroll_list> -		<panel> +		<panel name="media_controls_panel">  			<layout_stack name="media_controls">  				<layout_panel name="stop">  					<button name="stop_btn" tool_tip="Ausgewählte Medien stoppen"/> diff --git a/indra/newview/skins/default/xui/de/sidepanel_item_info.xml b/indra/newview/skins/default/xui/de/sidepanel_item_info.xml index 63e7bce8ae..b9ca969ac5 100644 --- a/indra/newview/skins/default/xui/de/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/de/sidepanel_item_info.xml @@ -23,7 +23,8 @@  	</panel.string>  	<text name="title" value="Objektprofil"/>  	<text name="origin" value="(Inventar)"/> -	<panel label=""> +	<panel label="" +           name="item_profile">  		<text name="LabelItemNameTitle">  			Name:  		</text> diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml index 68e36ff0b3..99bf3e6bc1 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -1472,8 +1472,10 @@ Only large parcels can be listed in search.               left="14"               name="MatureCheck"               top="177" +             label_text.valign="center"  +             label_text.v_pad="-5"                tool_tip=" " -             width="107" /> +             width="200" />              <text               type="string"               length="1" diff --git a/indra/newview/skins/default/xui/en/floater_buy_land.xml b/indra/newview/skins/default/xui/en/floater_buy_land.xml index 0ad4fbc967..c88de878f4 100644 --- a/indra/newview/skins/default/xui/en/floater_buy_land.xml +++ b/indra/newview/skins/default/xui/en/floater_buy_land.xml @@ -529,13 +529,14 @@ sold with objects       length="1"       follows="top|left"       font="SansSerifBig" -     height="16" +     height="32"       layout="topleft"       left="72"       name="account_action"       right="438"       top="200" -     width="218"> +     width="218" +     wrap="true">          Upgrade you to premium membership.      </text>      <text @@ -577,19 +578,21 @@ sold with objects       layout="topleft"       left="0"       name="step_2" +     top_pad="-10"       width="64" />      <text       type="string"       length="1"       follows="top|left"       font="SansSerifBig" -     height="16" +     height="32"       layout="topleft"       left="72"       name="land_use_action"       right="438"       top="284" -     width="218"> +     width="218" +     wrap="true">          Increase your monthly land use fees to US$ 40/month.      </text>      <text @@ -620,14 +623,15 @@ This parcel is 512 m² of land.      <text       type="string"       length="1" -     bottom_delta="-38" +     bottom_delta="-22"       follows="top|left"       font="SansSerifBig" -     height="16" +     height="32"       layout="topleft"       left="72"       name="purchase_action" -     right="438"> +     right="438" +     wrap="true">          Pay Joe Resident L$ 4000 for the land      </text>      <text @@ -665,7 +669,7 @@ This parcel is 512 m² of land.       layout="topleft"       left="170"       name="currency_amt" -     top="408" +     top="424"       width="80">          1000      </line_editor> @@ -681,7 +685,7 @@ This parcel is 512 m² of land.       layout="topleft"       left="260"       name="currency_est" -     top="409" +     top="425"       width="178">          for approx. [LOCAL_AMOUNT]      </text> @@ -713,7 +717,7 @@ This parcel is 512 m² of land.       layout="topleft"       left="70"       name="buy_btn" -     top="448" +     top="460"       width="100" />      <button       follows="bottom|right" diff --git a/indra/newview/skins/default/xui/en/floater_world_map.xml b/indra/newview/skins/default/xui/en/floater_world_map.xml index a59db1420f..20629018e2 100644 --- a/indra/newview/skins/default/xui/en/floater_world_map.xml +++ b/indra/newview/skins/default/xui/en/floater_world_map.xml @@ -395,7 +395,7 @@      <panel       follows="right|top|bottom" -	 height="310" +	 height="330"  	 top_pad="0"  	 width="238"  	 name="layout_panel_4"> @@ -534,7 +534,66 @@  		<scroll_list.commit_callback  		function="WMap.SearchResult" />      </scroll_list> -    <button +      <text +      type="string" +      length="1" +      follows="right|bottom" +      halign="right" +      height="16" +      layout="topleft" +      left="25" +      name="events_label" +      top_pad="16" +      width="70"> +      Location: +      </text> +      <spinner +        control_name="Teleport_Coordinate_X" +        decimal_digits="0" +        follows="right|bottom" +        height="23" +        increment="1" +        initial_value="128" +        layout="topleft" +        left_delta="74" +        max_val="255" +        min_val="0" +        name="teleport_coordinate_x" +        width="44" > +        <spinner.commit_callback  +          function="WMap.Coordinates" /> +      </spinner> +      <spinner +        control_name="Teleport_Coordinate_Y" +        decimal_digits="0" +        follows="right|bottom" +        height="23" +        increment="1" +        initial_value="128" +        layout="topleft" +        left_delta="47" +        max_val="255" +        min_val="0" +        name="teleport_coordinate_y" > +        <spinner.commit_callback +          function="WMap.Coordinates" /> +      </spinner> +      <spinner +        control_name="Teleport_Coordinate_Z" +        decimal_digits="0" +        follows="right|bottom" +        height="23" +        increment="1" +        initial_value="128" +        layout="topleft" +        left_delta="47" +        max_val="255" +        min_val="0" +        name="teleport_coordinate_z"> +        <spinner.commit_callback +          function="WMap.Coordinates" /> +      </spinner> +      <button       follows="right|bottom"       height="23"       image_unselected="PushButton_On" @@ -574,66 +633,6 @@  		<button.commit_callback  		function="WMap.ShowTarget" />      </button> - -<!-- <text -     type="string" -     length="1" -     follows="bottom|right" -     halign="left" -     height="16" -     top_pad="4" -     left="25" -     layout="topleft" -     name="land_sale_label" -     width="250"> -        Location: -    </text> -      <spinner -     decimal_digits="0" -     follows="bottom|right" -     increment="1" -     initial_value="128" -     layout="topleft" -     top_pad="0" -     left="25" -     max_val="255" -     name="spin x" -     tool_tip="X coordinate of location to show on map" -     width="48"> -		<spinner.commit_callback -		function="WMap.CommitLocation" /> -    </spinner> -    <spinner -     decimal_digits="0" -     follows="bottom|right" -     height="16" -     increment="1" -     initial_value="128" -     layout="topleft" -     left_pad="2" -     max_val="255" -     name="spin y" -     tool_tip="Y coordinate of location to show on map" -     top_delta="0" -     width="48" > -		<spinner.commit_callback -		function="WMap.CommitLocation" /> -    </spinner> -    <spinner -     decimal_digits="0" -     follows="bottom|right" -     increment="1" -     initial_value="0" -     layout="topleft" -     left_pad="2" -     max_val="4096" -     name="spin z" -     tool_tip="Z coordinate of location to show on map" -     top_delta="0" -     width="48"> -		<spinner.commit_callback -		function="WMap.CommitLocation" /> -    </spinner>-->      </panel>        <panel      follows="right|bottom" diff --git a/indra/newview/skins/default/xui/en/menu_attachment_self.xml b/indra/newview/skins/default/xui/en/menu_attachment_self.xml index 7239b13466..e2348375d5 100644 --- a/indra/newview/skins/default/xui/en/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/en/menu_attachment_self.xml @@ -11,8 +11,7 @@           function="Object.Touch" />          <menu_item_call.on_enable           function="Object.EnableTouch" -         name="EnableTouch" -         parameter="Touch" /> +         name="EnableTouch"/>      </menu_item_call>      <!--menu_item_call       label="Stand Up" diff --git a/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml index b6f00ef6d1..8ec7689819 100644 --- a/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml @@ -22,7 +22,7 @@      <menu_item_call.on_click       function="InspectObject.Sit"/>      <menu_item_call.on_visible -     function="Object.EnableGearSit" /> +     function="Object.EnableSit"/>    </menu_item_call>    <menu_item_call     label="Pay" diff --git a/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml b/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml index 3e38503e43..77cc3910fd 100644 --- a/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml +++ b/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml @@ -94,6 +94,9 @@          <on_enable           function="Places.LandmarksGear.Enable"           parameter="expand" /> +        <on_visible +         function="Places.LandmarksGear.Enable" +         parameter="expand" />      </menu_item_call>      <menu_item_call       label="Collapse" @@ -105,6 +108,9 @@          <on_enable           function="Places.LandmarksGear.Enable"           parameter="collapse" /> +        <on_visible +         function="Places.LandmarksGear.Enable" +         parameter="collapse" />      </menu_item_call>      <menu_item_call       label="Expand all folders" diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 67b8c81a01..52cf24333f 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -951,17 +951,6 @@       name="Advanced"       tear_off="true"       visible="false"> -        <menu_item_check -         label="Show Advanced Menu" -         name="Show Advanced Menu" -         shortcut="control|alt|D"> -          <on_check -           function="CheckControl" -           parameter="UseDebugMenus" /> -          <on_click -           function="ToggleControl" -           parameter="UseDebugMenus" /> -        </menu_item_check>          <menu_item_call           label="Stop Animating Me"           name="Stop Animating My Avatar"> @@ -1681,7 +1670,24 @@                  <menu_item_call.on_click                   function="View.ZoomOut" />              </menu_item_call> -        </menu> +            <menu_item_separator +             visible="false"/> +            <!-- Made invisible to avoid a dissonance: menu item toggle menu where it is located. EXT-8069. +              Can't be removed to keep sortcut workable. +            --> +            <menu_item_check +             label="Show Advanced Menu" +             name="Show Advanced Menu" +             shortcut="control|alt|D" +             visible="false"> +                <on_check +                 function="CheckControl" +                 parameter="UseDebugMenus" /> +                <on_click +                 function="ToggleControl" +                 parameter="UseDebugMenus" /> +        </menu_item_check> +        </menu> <!--Shortcuts-->          <menu_item_separator/> @@ -3389,4 +3395,4 @@              </menu>          </menu>      </menu> -</menu_bar>
\ No newline at end of file +</menu_bar> diff --git a/indra/newview/skins/default/xui/en/panel_bars.xml b/indra/newview/skins/default/xui/en/panel_bars.xml deleted file mode 100644 index 96722ce278..0000000000 --- a/indra/newview/skins/default/xui/en/panel_bars.xml +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel - follows="left|right|top|bottom" - height="768" - layout="topleft" - left="0" - mouse_opaque="false" - name="screen" - width="1024"> -  <layout_stack name="menu_stack" orientation="vertical" height="768" border_size="0"> -    <panel auto_resize="false" width="1024" name="status_bar" filename="panel_status_bar.xml"/> -    <panel auto_resize="false" width="1024" height="60" name="navigation bar" filename="panel_navigation_bar.xml"/> -    <layout_stack name="hud_stack" orientation="horizontal" auto_resize="true" width="1024" height="500" follows="all"> -      <panel auto_resize="true" name="floater_view" height="500"/> -      <panel auto_resize="false" filename="panel_side_tray.xml" height="500" width="333"/> -    </layout_stack> -  </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/en/panel_group_notices.xml b/indra/newview/skins/default/xui/en/panel_group_notices.xml index 6523b0d491..41f2b28004 100644 --- a/indra/newview/skins/default/xui/en/panel_group_notices.xml +++ b/indra/newview/skins/default/xui/en/panel_group_notices.xml @@ -76,19 +76,22 @@ Maximum 200 per group daily         follows="top|left"         height="23"         image_overlay="AddItem_Off" +       image_overlay_alignment="left" +       imgoverlay_label_space="-10" +       label="New Notice"         layout="topleft"         left="5"         name="create_new_notice"         tool_tip="Create a new notice" -       top_delta="-3" -       width="23" /> +       top_delta="0" +       width="93" />       <button       follows="top|left"       height="23"       image_overlay="Refresh_Off"       layout="topleft"       name="refresh_notices" -     left_pad="230" +     left="260"       tool_tip="Refresh list of notices"       top_delta="0"       width="23" /> @@ -113,7 +116,7 @@ Maximum 200 per group daily           mouse_opaque="false"           name="lbl"           text_color="EmphasisColor" -         top="0" +         top="5"           width="200">              Create a Notice          </text> @@ -270,7 +273,7 @@ Maximum 200 per group daily           mouse_opaque="false"           name="lbl"           text_color="EmphasisColor" -         top_pad="0" +         top_pad="5"           width="265">              Archived Notice          </text> diff --git a/indra/newview/skins/default/xui/en/panel_group_roles.xml b/indra/newview/skins/default/xui/en/panel_group_roles.xml index 0eb5c47f85..18a2f37ba2 100644 --- a/indra/newview/skins/default/xui/en/panel_group_roles.xml +++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml @@ -50,6 +50,10 @@ Select multiple Members by holding the Ctrl key and  clicking on their names.              </panel.string>              <panel.string +             name="donation_area"> +                [AREA] m² +            </panel.string> +            <panel.string               name="power_folder_icon" translate="false">                  Inv_FolderClosed              </panel.string> diff --git a/indra/newview/skins/default/xui/en/panel_landmark_info.xml b/indra/newview/skins/default/xui/en/panel_landmark_info.xml index 40cb7c7f4b..c5d6aced7a 100644 --- a/indra/newview/skins/default/xui/en/panel_landmark_info.xml +++ b/indra/newview/skins/default/xui/en/panel_landmark_info.xml @@ -275,7 +275,7 @@                   name="notes_editor"                   read_only="true"                   text_readonly_color="white" -                 text_type="ascii" +                 text_type="ascii_with_newline"                   top_pad="5"                   width="290"                   wrap="true" /> diff --git a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml index 50df227fbf..49b252174c 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml @@ -80,10 +80,11 @@  	<panel           follows="all"           height="493" +         help_topic=""           label=""           layout="topleft"           left="9" -         help_topic="" +         name="item_profile"           top="45"           width="313"     background_visible="true" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index e5bd549036..9941732c30 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -278,6 +278,7 @@  	<!-- world map -->  	<string name="texture_loading">Loading...</string>  	<string name="worldmap_offline">Offline</string> +	<string name="worldmap_item_tooltip_format">[AREA] m² L$[PRICE]</string>  	<string name="worldmap_results_none_found">None found.</string>  	<!-- animations uploading status codes --> @@ -2102,6 +2103,7 @@ Clears (deletes) the media and all params from the given face.  	<string name="SummaryForTheWeek"    value="Summary for this week, beginning on " />  	<string name="NextStipendDay"       value="The next stipend day is " />  	<string name="GroupIndividualShare" value="                      Group       Individual Share" /> +	<string name="GroupColumn"          value="                      Group" />  	<string name="Balance">Balance</string>  	<string name="Credits">Credits</string>  	<string name="Debits">Debits</string> @@ -3022,6 +3024,9 @@ If you continue to receive this message, contact the [SUPPORT_SITE].    <string name="conference-title">      Ad-hoc Conference    </string> +  <string name="conference-title-incoming"> +    [AGENT_NAME] Conference +  </string>    <string name="inventory_item_offered-im">      Inventory item offered    </string> @@ -3141,6 +3146,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE].    <string name="group_role_everyone">Everyone</string>    <string name="group_role_officers">Officers</string>    <string name="group_role_owners">Owners</string> +  <string name="group_member_status_online">Online</string>    <string name="uploading_abuse_report">Uploading... @@ -3165,6 +3171,7 @@ Abuse Report</string>    <string name="Invalid Wearable">Invalid Wearable</string>    <string name="New Gesture">New Gesture</string>    <string name="New Script">New Script</string> +  <string name="New Note">New Note</string>    <string name="New Folder">New Folder</string>    <string name="Contents">Contents</string>    <string name="Gesture">Gesture</string> @@ -3235,4 +3242,20 @@ Abuse Report</string>    <!--  currency formatting -->    <string name="LocalEstimateUSD">US$ [AMOUNT]</string> + +  <!-- Group Profile roles and powers --> +  <string name="Membership">Membership</string> +  <string name="Roles">Roles</string> +  <string name="Group Identity">Group Identity</string> +  <string name="Parcel Management">Parcel Management</string> +  <string name="Parcel Identity">Parcel Identity</string> +  <string name="Parcel Settings">Parcel Settings</string> +  <string name="Parcel Powers">Parcel Powers</string> +  <string name="Parcel Access">Parcel Access</string> +  <string name="Parcel Content">Parcel Content</string> +  <string name="Object Management">Object Management</string> +  <string name="Accounting">Accounting</string> +  <string name="Notices">Notices</string> +  <string name="Chat">Chat</string> +    </strings> diff --git a/indra/newview/skins/default/xui/es/panel_nearby_media.xml b/indra/newview/skins/default/xui/es/panel_nearby_media.xml index b78ecd0cd0..f03338e4c7 100644 --- a/indra/newview/skins/default/xui/es/panel_nearby_media.xml +++ b/indra/newview/skins/default/xui/es/panel_nearby_media.xml @@ -42,7 +42,7 @@  			<scroll_list.columns label="Nombre" name="media_name"/>  			<scroll_list.columns label="Depurar" name="media_debug"/>  		</scroll_list> -		<panel> +		<panel name="media_controls_panel">  			<layout_stack name="media_controls">  				<layout_panel name="stop">  					<button name="stop_btn" tool_tip="Parar los media seleccionados"/> diff --git a/indra/newview/skins/default/xui/es/sidepanel_item_info.xml b/indra/newview/skins/default/xui/es/sidepanel_item_info.xml index 38f43c3cbc..d3b91e7a71 100644 --- a/indra/newview/skins/default/xui/es/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/es/sidepanel_item_info.xml @@ -23,7 +23,8 @@  	</panel.string>  	<text name="title" value="Perfil del elemento"/>  	<text name="origin" value="(Inventario)"/> -	<panel label=""> +	<panel label="" +           name="item_profile">  		<text name="LabelItemNameTitle">  			Nombre:  		</text> diff --git a/indra/newview/skins/default/xui/fr/floater_water.xml b/indra/newview/skins/default/xui/fr/floater_water.xml index 96723b0fe6..7d1e3cd65c 100644 --- a/indra/newview/skins/default/xui/fr/floater_water.xml +++ b/indra/newview/skins/default/xui/fr/floater_water.xml @@ -1,7 +1,7 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <floater name="Water Floater" title="ÉDITEUR D'EAU AVANCÉ">  	<floater.string name="WLDefaultWaterNames"> -		Default:Glassy:Pond:Murky:Second Plague:SNAKE!!!:Valdez +		Valeur par défaut:Transparente:Bassin:Trouble:Première plaie:SERPENT !!!:Valdez  	</floater.string>  	<text name="KeyFramePresetsText" width="120">  		Préréglages : diff --git a/indra/newview/skins/default/xui/fr/floater_windlight_options.xml b/indra/newview/skins/default/xui/fr/floater_windlight_options.xml index 74f1697449..657e5f5051 100644 --- a/indra/newview/skins/default/xui/fr/floater_windlight_options.xml +++ b/indra/newview/skins/default/xui/fr/floater_windlight_options.xml @@ -184,6 +184,6 @@  		</panel>  	</tab_container>  	<string name="WLDefaultSkyNames"> -		A-12AM:A-12PM:A-3AM:A-3PM:A-4.30PM:A-6AM:A-6PM:A-9AM:A-9PM:Barcelona:Blizzard:Blue Midday:Coastal Afternoon:Coastal Sunset:Default:Desert Sunset:Fine Day:Fluffy Big Clouds:Foggy:Funky Funky:Funky Funky Funky:Gelatto:Ghost:Incongruent Truths:Midday 1:Midday 2:Midday 3:Midday 4:Night:Pirate:Purple:Sailor's Delight:Sheer Sensuality +		A-Minuit:A-Midi:A-3h:A-15h:A-16h30:A-6h:A-18h:A-9h:A-21h:Barcelone:Blizzard:Bleu mi-journée:Après-midi sur la côte:Coucher de soleil (côte):Valeur par défaut:Coucher de soleil (désert):Belle journée:Gros nuages floconneux:Brumeux:Funky Funky:Funky Funky Funky:Gelatto:Fantôme:Vérités incohérentes:Mi-journée 1:Mi-journée 2:Mi-journée 3:Mi-journée 4:Nuit:Pirate:Mauve:Rêve de navigateur:Sensualité pure  	</string>  </floater> diff --git a/indra/newview/skins/default/xui/fr/menu_object.xml b/indra/newview/skins/default/xui/fr/menu_object.xml index 257c44795f..6492a83e06 100644 --- a/indra/newview/skins/default/xui/fr/menu_object.xml +++ b/indra/newview/skins/default/xui/fr/menu_object.xml @@ -1,9 +1,7 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <context_menu name="Object Pie"> -	<menu_item_call label="Toucher" name="Object Touch"> -		<on_enable parameter="Toucher" name="EnableTouch"/> -	</menu_item_call> -	<menu_item_call label="Modifier" name="Edit..."/> +	<menu_item_call label="Toucher" name="Object Touch"/> +	<menu_item_call label="Éditer" name="Edit..."/>  	<menu_item_call label="Construire" name="Build"/>  	<menu_item_call label="Ouvrir" name="Open"/>  	<menu_item_call label="M'asseoir ici" name="Object Sit"/> diff --git a/indra/newview/skins/default/xui/fr/panel_nearby_media.xml b/indra/newview/skins/default/xui/fr/panel_nearby_media.xml index 978ca86d62..66bfd01a2a 100644 --- a/indra/newview/skins/default/xui/fr/panel_nearby_media.xml +++ b/indra/newview/skins/default/xui/fr/panel_nearby_media.xml @@ -27,7 +27,7 @@  			Médias proches  		</text>  		<text name="show_text"> -			Afficher : +			Voir :  		</text>  		<combo_box name="show_combo">  			<combo_box.item label="Tout" name="All"/> @@ -42,7 +42,7 @@  			<scroll_list.columns label="Nom" name="media_name"/>  			<scroll_list.columns label="Débogage" name="media_debug"/>  		</scroll_list> -		<panel> +		<panel name="media_controls_panel">  			<layout_stack name="media_controls">  				<layout_panel name="stop">  					<button name="stop_btn" tool_tip="Arrêter le média sélectionné"/> diff --git a/indra/newview/skins/default/xui/fr/sidepanel_item_info.xml b/indra/newview/skins/default/xui/fr/sidepanel_item_info.xml index 0a5680fe06..0350ea5116 100644 --- a/indra/newview/skins/default/xui/fr/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/fr/sidepanel_item_info.xml @@ -23,7 +23,8 @@  	</panel.string>  	<text name="title" value="Profil de l'article"/>  	<text name="origin" value="(inventaire)"/> -	<panel label=""> +	<panel label="" +           name="item_profile">  		<text name="LabelItemNameTitle">  			Nom :  		</text> diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml index 0a269016f5..7aadaed209 100644 --- a/indra/newview/skins/default/xui/fr/strings.xml +++ b/indra/newview/skins/default/xui/fr/strings.xml @@ -1472,7 +1472,7 @@  		Solde  	</string>  	<string name="Credits"> -		Remerciements +		Crédits  	</string>  	<string name="Debits">  		Débits @@ -1787,7 +1787,7 @@  		Solde  	</string>  	<string name="GroupMoneyCredits"> -		Remerciements +		Crédits  	</string>  	<string name="GroupMoneyDebits">  		Débits @@ -3859,4 +3859,5 @@ de l'infraction signalée  	<string name="dateTimePM">  		PM  	</string> +	<string name="LocalEstimateUSD">[AMOUNT] US$</string>   </strings> diff --git a/indra/newview/skins/default/xui/it/panel_nearby_media.xml b/indra/newview/skins/default/xui/it/panel_nearby_media.xml index bec36fd427..40312f76b4 100644 --- a/indra/newview/skins/default/xui/it/panel_nearby_media.xml +++ b/indra/newview/skins/default/xui/it/panel_nearby_media.xml @@ -42,7 +42,7 @@  			<scroll_list.columns label="Nome" name="media_name"/>  			<scroll_list.columns label="Debug" name="media_debug"/>  		</scroll_list> -		<panel> +		<panel name="media_controls_panel">  			<layout_stack name="media_controls">  				<layout_panel name="stop">  					<button name="stop_btn" tool_tip="Interrompi supporto selezionato"/> diff --git a/indra/newview/skins/default/xui/it/sidepanel_item_info.xml b/indra/newview/skins/default/xui/it/sidepanel_item_info.xml index d0ec943e67..627aeb5cb5 100644 --- a/indra/newview/skins/default/xui/it/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/it/sidepanel_item_info.xml @@ -23,7 +23,8 @@  	</panel.string>  	<text name="title" value="Profilo articolo"/>  	<text name="origin" value="(Inventario)"/> -	<panel label=""> +	<panel label="" +           name="item_profile">  		<text name="LabelItemNameTitle">  			Nome:  		</text> diff --git a/indra/newview/skins/default/xui/ja/panel_nearby_media.xml b/indra/newview/skins/default/xui/ja/panel_nearby_media.xml index b3df3503bb..07293e6c79 100644 --- a/indra/newview/skins/default/xui/ja/panel_nearby_media.xml +++ b/indra/newview/skins/default/xui/ja/panel_nearby_media.xml @@ -42,7 +42,7 @@  			<scroll_list.columns label="名前" name="media_name"/>  			<scroll_list.columns label="デバッグ" name="media_debug"/>  		</scroll_list> -		<panel> +		<panel name="media_controls_panel">  			<layout_stack name="media_controls">  				<layout_panel name="stop">  					<button name="stop_btn" tool_tip="選択したメディアを停止"/> diff --git a/indra/newview/skins/default/xui/ja/sidepanel_item_info.xml b/indra/newview/skins/default/xui/ja/sidepanel_item_info.xml index fdabe88362..414eba0509 100644 --- a/indra/newview/skins/default/xui/ja/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/ja/sidepanel_item_info.xml @@ -23,7 +23,8 @@  	</panel.string>  	<text name="title" value="アイテムのプロフィール"/>  	<text name="origin" value="(持ち物)"/> -	<panel label=""> +	<panel label="" +           name="item_profile">  		<text name="LabelItemNameTitle">  			名前:  		</text> diff --git a/indra/newview/skins/default/xui/pl/panel_nearby_media.xml b/indra/newview/skins/default/xui/pl/panel_nearby_media.xml index 86c7275e79..926ca806ac 100644 --- a/indra/newview/skins/default/xui/pl/panel_nearby_media.xml +++ b/indra/newview/skins/default/xui/pl/panel_nearby_media.xml @@ -42,7 +42,7 @@  			<scroll_list.columns label="Nazwa" name="media_name"/>  			<scroll_list.columns label="Debugowanie" name="media_debug"/>  		</scroll_list> -		<panel> +		<panel name="media_controls_panel">  			<layout_stack name="media_controls">  				<layout_panel name="stop">  					<button name="stop_btn" tool_tip="Wyłącz wybrane media"/> diff --git a/indra/newview/skins/default/xui/pl/sidepanel_item_info.xml b/indra/newview/skins/default/xui/pl/sidepanel_item_info.xml index 2f43e0c215..0c6169c9c0 100644 --- a/indra/newview/skins/default/xui/pl/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/pl/sidepanel_item_info.xml @@ -23,7 +23,8 @@  	</panel.string>  	<text name="title" value="Profil obiektu"/>  	<text name="origin" value="(Szafa)"/> -	<panel label=""> +	<panel label="" +           name="item_profile">  		<text name="LabelItemNameTitle">  			Nazwa:  		</text> diff --git a/indra/newview/skins/default/xui/pt/panel_nearby_media.xml b/indra/newview/skins/default/xui/pt/panel_nearby_media.xml index 672b8e6735..7d1b48ad76 100644 --- a/indra/newview/skins/default/xui/pt/panel_nearby_media.xml +++ b/indra/newview/skins/default/xui/pt/panel_nearby_media.xml @@ -42,7 +42,7 @@  			<scroll_list.columns label="Nome" name="media_name"/>  			<scroll_list.columns label="Depurar" name="media_debug"/>  		</scroll_list> -		<panel> +		<panel name="media_controls_panel">  			<layout_stack name="media_controls">  				<layout_panel name="stop">  					<button name="stop_btn" tool_tip="Parar mídia selecionada"/> diff --git a/indra/newview/skins/default/xui/pt/sidepanel_item_info.xml b/indra/newview/skins/default/xui/pt/sidepanel_item_info.xml index 8e880588e9..d2050f4660 100644 --- a/indra/newview/skins/default/xui/pt/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/pt/sidepanel_item_info.xml @@ -23,7 +23,8 @@  	</panel.string>  	<text name="title" value="Perfil do item"/>  	<text name="origin" value="(Inventário)"/> -	<panel label=""> +	<panel label="" +           name="item_profile">  		<text name="LabelItemNameTitle">  			Nome:  		</text> diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp index 1c29feec5f..347a5e8ab8 100644 --- a/indra/newview/tests/lllogininstance_test.cpp +++ b/indra/newview/tests/lllogininstance_test.cpp @@ -226,6 +226,16 @@ S32 LLNotification::getSelectedOption(const LLSD& notification, const LLSD& resp  	return response.asInteger();  } +//----------------------------------------------------------------------------- +#include "../llmachineid.h" +unsigned char gMACAddress[MAC_ADDRESS_BYTES] = {77,21,46,31,89,2}; + +S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len) +{ +	memcpy(unique_id, gMACAddress, len); +	return 1; +} +//-----------------------------------------------------------------------------  // misc  std::string xml_escape_string(const std::string& in)  { diff --git a/indra/win_crash_logger/llcrashloggerwindows.cpp b/indra/win_crash_logger/llcrashloggerwindows.cpp index 2884231299..01c750487e 100644 --- a/indra/win_crash_logger/llcrashloggerwindows.cpp +++ b/indra/win_crash_logger/llcrashloggerwindows.cpp @@ -145,7 +145,7 @@ void LLCrashLoggerWindows::ProcessCaption(HWND hWnd)  	TCHAR header[MAX_STRING];  	std::string final;  	GetWindowText(hWnd, templateText, sizeof(templateText)); -	final = llformat(ll_convert_wide_to_string(templateText).c_str(), gProductName.c_str()); +	final = llformat(ll_convert_wide_to_string(templateText, CP_ACP).c_str(), gProductName.c_str());  	ConvertLPCSTRToLPWSTR(final.c_str(), header);  	SetWindowText(hWnd, header);  } @@ -158,7 +158,7 @@ void LLCrashLoggerWindows::ProcessDlgItemText(HWND hWnd, int nIDDlgItem)  	TCHAR header[MAX_STRING];  	std::string final;  	GetDlgItemText(hWnd, nIDDlgItem, templateText, sizeof(templateText)); -	final = llformat(ll_convert_wide_to_string(templateText).c_str(), gProductName.c_str()); +	final = llformat(ll_convert_wide_to_string(templateText, CP_ACP).c_str(), gProductName.c_str());  	ConvertLPCSTRToLPWSTR(final.c_str(), header);  	SetDlgItemText(hWnd, nIDDlgItem, header);  } @@ -201,7 +201,7 @@ bool handle_button_click(WORD button_id)  						wbuffer, // pointer to buffer for text  						20000 // maximum size of string  						); -		std::string user_text(ll_convert_wide_to_string(wbuffer)); +		std::string user_text(ll_convert_wide_to_string(wbuffer, CP_ACP));  		// Activate and show the window.  		ShowWindow(gHwndProgress, SW_SHOW);   		// Try doing this second to make the progress window go frontmost. | 
