diff options
216 files changed, 3146 insertions, 979 deletions
| diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index ae11988df8..3a8eabac09 100755 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -2176,8 +2176,7 @@ void* ll_aligned_malloc_fallback( size_t size, int align )  	SYSTEM_INFO sysinfo;  	GetSystemInfo(&sysinfo); -	unsigned int for_alloc = sysinfo.dwPageSize; -	while(for_alloc < size) for_alloc += sysinfo.dwPageSize; +	unsigned int for_alloc = (size/sysinfo.dwPageSize + !!(size%sysinfo.dwPageSize)) * sysinfo.dwPageSize;  	void *p = VirtualAlloc(NULL, for_alloc+sysinfo.dwPageSize, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);  	if(NULL == p) { diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index c4c9cc0566..fd09eb9deb 100755 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -97,7 +97,7 @@ template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address)  //------------------------------------------------------------------------------------------------  //------------------------------------------------------------------------------------------------  	// for enable buffer overrun detection predefine LL_DEBUG_BUFFER_OVERRUN in current library -	// change preprocessro code to: #if 1 && defined(LL_WINDOWS) +	// change preprocessor code to: #if 1 && defined(LL_WINDOWS)  #if 0 && defined(LL_WINDOWS)  	void* ll_aligned_malloc_fallback( size_t size, int align ); diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index 16df27bb8e..08462c7834 100755 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -40,6 +40,545 @@  #include "llimagedxt.h"  #include "llmemory.h" +#include <boost/preprocessor.hpp> + +//.................................................................................. +//.................................................................................. +// Helper macrose's for generate cycle unwrap templates +//.................................................................................. +#define _UNROL_GEN_TPL_arg_0(arg) +#define _UNROL_GEN_TPL_arg_1(arg) arg + +#define _UNROL_GEN_TPL_comma_0 +#define _UNROL_GEN_TPL_comma_1 BOOST_PP_COMMA() +//.................................................................................. +#define _UNROL_GEN_TPL_ARGS_macro(z,n,seq) \ +	BOOST_PP_CAT(_UNROL_GEN_TPL_arg_, BOOST_PP_MOD(n, 2))(BOOST_PP_SEQ_ELEM(n, seq)) BOOST_PP_CAT(_UNROL_GEN_TPL_comma_, BOOST_PP_AND(BOOST_PP_MOD(n, 2), BOOST_PP_NOT_EQUAL(BOOST_PP_INC(n), BOOST_PP_SEQ_SIZE(seq)))) + +#define _UNROL_GEN_TPL_ARGS(seq) \ +	BOOST_PP_REPEAT(BOOST_PP_SEQ_SIZE(seq), _UNROL_GEN_TPL_ARGS_macro, seq) +//.................................................................................. + +#define _UNROL_GEN_TPL_TYPE_ARGS_macro(z,n,seq) \ +	BOOST_PP_SEQ_ELEM(n, seq) BOOST_PP_CAT(_UNROL_GEN_TPL_comma_, BOOST_PP_AND(BOOST_PP_MOD(n, 2), BOOST_PP_NOT_EQUAL(BOOST_PP_INC(n), BOOST_PP_SEQ_SIZE(seq)))) + +#define _UNROL_GEN_TPL_TYPE_ARGS(seq) \ +	BOOST_PP_REPEAT(BOOST_PP_SEQ_SIZE(seq), _UNROL_GEN_TPL_TYPE_ARGS_macro, seq) +//.................................................................................. +#define _UNROLL_GEN_TPL_foreach_ee(z, n, seq) \ +	executor<n>(_UNROL_GEN_TPL_ARGS(seq)); + +#define _UNROLL_GEN_TPL(name, args_seq, operation, spec) \ +	template<> struct name<spec> { \ +	private: \ +		template<S32 _idx> inline void executor(_UNROL_GEN_TPL_TYPE_ARGS(args_seq)) { \ +			BOOST_PP_SEQ_ENUM(operation) ; \ +		} \ +	public: \ +		inline void operator()(_UNROL_GEN_TPL_TYPE_ARGS(args_seq)) { \ +			BOOST_PP_REPEAT(spec, _UNROLL_GEN_TPL_foreach_ee, args_seq) \ +		} \ +}; +//.................................................................................. +#define _UNROLL_GEN_TPL_foreach_seq_macro(r, data, elem) \ +	_UNROLL_GEN_TPL(BOOST_PP_SEQ_ELEM(0, data), BOOST_PP_SEQ_ELEM(1, data), BOOST_PP_SEQ_ELEM(2, data), elem) + +#define UNROLL_GEN_TPL(name, args_seq, operation, spec_seq) \ +	/*general specialization - should not be implemented!*/ \ +	template<U8> struct name { inline void operator()(_UNROL_GEN_TPL_TYPE_ARGS(args_seq)) { /*static_assert(!"Should not be instantiated.");*/  } }; \ +	BOOST_PP_SEQ_FOR_EACH(_UNROLL_GEN_TPL_foreach_seq_macro, (name)(args_seq)(operation), spec_seq) +//.................................................................................. +//.................................................................................. + + +//.................................................................................. +// Generated unrolling loop templates with specializations +//.................................................................................. +//example: for(c = 0; c < ch; ++c) comp[c] = cx[0] = 0; +UNROLL_GEN_TPL(uroll_zeroze_cx_comp, (S32 *)(cx)(S32 *)(comp), (cx[_idx] = comp[_idx] = 0), (1)(3)(4)); +//example: for(c = 0; c < ch; ++c) comp[c] >>= 4; +UNROLL_GEN_TPL(uroll_comp_rshftasgn_constval, (S32 *)(comp)(const S32)(cval), (comp[_idx] >>= cval), (1)(3)(4)); +//example: for(c = 0; c < ch; ++c) comp[c] = (cx[c] >> 5) * yap; +UNROLL_GEN_TPL(uroll_comp_asgn_cx_rshft_cval_all_mul_val, (S32 *)(comp)(S32 *)(cx)(const S32)(cval)(S32)(val), (comp[_idx] = (cx[_idx] >> cval) * val), (1)(3)(4)); +//example: for(c = 0; c < ch; ++c) comp[c] += (cx[c] >> 5) * Cy; +UNROLL_GEN_TPL(uroll_comp_plusasgn_cx_rshft_cval_all_mul_val, (S32 *)(comp)(S32 *)(cx)(const S32)(cval)(S32)(val), (comp[_idx] += (cx[_idx] >> cval) * val), (1)(3)(4)); +//example: for(c = 0; c < ch; ++c) comp[c] += pix[c] * info.xapoints[x]; +UNROLL_GEN_TPL(uroll_inp_plusasgn_pix_mul_val, (S32 *)(comp)(const U8 *)(pix)(S32)(val), (comp[_idx] += pix[_idx] * val), (1)(3)(4)); +//example: for(c = 0; c < ch; ++c) cx[c] = pix[c] * info.xapoints[x]; +UNROLL_GEN_TPL(uroll_inp_asgn_pix_mul_val, (S32 *)(comp)(const U8 *)(pix)(S32)(val), (comp[_idx] = pix[_idx] * val), (1)(3)(4)); +//example: for(c = 0; c < ch; ++c) comp[c] = ((cx[c] * info.yapoints[y]) + (comp[c] * (256 - info.yapoints[y]))) >> 16; +UNROLL_GEN_TPL(uroll_comp_asgn_cx_mul_apoint_plus_comp_mul_inv_apoint_allshifted_16_r, (S32 *)(comp)(S32 *)(cx)(S32)(apoint), (comp[_idx] = ((cx[_idx] * apoint) + (comp[_idx] * (256 - apoint))) >> 16), (1)(3)(4)); +//example: for(c = 0; c < ch; ++c) comp[c] = (comp[c] + pix[c] * info.yapoints[y]) >> 8; +UNROLL_GEN_TPL(uroll_comp_asgn_comp_plus_pix_mul_apoint_allshifted_8_r, (S32 *)(comp)(const U8 *)(pix)(S32)(apoint), (comp[_idx] = (comp[_idx] + pix[_idx] * apoint) >> 8), (1)(3)(4)); +//example: for(c = 0; c < ch; ++c) comp[c] = ((comp[c]*(256 - info.xapoints[x])) + ((cx[c] * info.xapoints[x]))) >> 12; +UNROLL_GEN_TPL(uroll_comp_asgn_comp_mul_inv_apoint_plus_cx_mul_apoint_allshifted_12_r, (S32 *)(comp)(S32)(apoint)(S32 *)(cx), (comp[_idx] = ((comp[_idx] * (256-apoint)) + (cx[_idx] * apoint)) >> 12), (1)(3)(4)); +//example: for(c = 0; c < ch; ++c) *dptr++ = comp[c]&0xff; +UNROLL_GEN_TPL(uroll_uref_dptr_inc_asgn_comp_and_ff, (U8 *&)(dptr)(S32 *)(comp), (*dptr++ = comp[_idx]&0xff), (1)(3)(4)); +//example: for(c = 0; c < ch; ++c) *dptr++ = (sptr[info.xpoints[x]*ch + c])&0xff; +UNROLL_GEN_TPL(uroll_uref_dptr_inc_asgn_sptr_apoint_plus_idx_alland_ff, (U8 *&)(dptr)(const U8 *)(sptr)(S32)(apoint), (*dptr++ = sptr[apoint + _idx]&0xff), (1)(3)(4)); +//example: for(c = 0; c < ch; ++c) *dptr++ = (comp[c]>>10)&0xff; +UNROLL_GEN_TPL(uroll_uref_dptr_inc_asgn_comp_rshft_cval_and_ff, (U8 *&)(dptr)(S32 *)(comp)(const S32)(cval), (*dptr++ = (comp[_idx]>>cval)&0xff), (1)(3)(4)); +//.................................................................................. + + +template<U8 ch> +struct scale_info  +{ +public: +	std::vector<S32> xpoints; +	std::vector<const U8*> ystrides; +	std::vector<S32> xapoints, yapoints; +	S32 xup_yup; + +public: +	//unrolling loop types declaration +	typedef uroll_zeroze_cx_comp<ch>														uroll_zeroze_cx_comp_t; +	typedef uroll_comp_rshftasgn_constval<ch>												uroll_comp_rshftasgn_constval_t; +	typedef uroll_comp_asgn_cx_rshft_cval_all_mul_val<ch>									uroll_comp_asgn_cx_rshft_cval_all_mul_val_t; +	typedef uroll_comp_plusasgn_cx_rshft_cval_all_mul_val<ch>								uroll_comp_plusasgn_cx_rshft_cval_all_mul_val_t; +	typedef uroll_inp_plusasgn_pix_mul_val<ch>												uroll_inp_plusasgn_pix_mul_val_t; +	typedef uroll_inp_asgn_pix_mul_val<ch>													uroll_inp_asgn_pix_mul_val_t; +	typedef uroll_comp_asgn_cx_mul_apoint_plus_comp_mul_inv_apoint_allshifted_16_r<ch>		uroll_comp_asgn_cx_mul_apoint_plus_comp_mul_inv_apoint_allshifted_16_r_t; +	typedef uroll_comp_asgn_comp_plus_pix_mul_apoint_allshifted_8_r<ch>						uroll_comp_asgn_comp_plus_pix_mul_apoint_allshifted_8_r_t; +	typedef uroll_comp_asgn_comp_mul_inv_apoint_plus_cx_mul_apoint_allshifted_12_r<ch>		uroll_comp_asgn_comp_mul_inv_apoint_plus_cx_mul_apoint_allshifted_12_r_t; +	typedef uroll_uref_dptr_inc_asgn_comp_and_ff<ch>										uroll_uref_dptr_inc_asgn_comp_and_ff_t; +	typedef uroll_uref_dptr_inc_asgn_sptr_apoint_plus_idx_alland_ff<ch>						uroll_uref_dptr_inc_asgn_sptr_apoint_plus_idx_alland_ff_t; +	typedef uroll_uref_dptr_inc_asgn_comp_rshft_cval_and_ff<ch>								uroll_uref_dptr_inc_asgn_comp_rshft_cval_and_ff_t; + +public: +	scale_info(const U8 *src, U32 srcW, U32 srcH, U32 dstW, U32 dstH, U32 srcStride) +		: xup_yup((dstW >= srcW) + ((dstH >= srcH) << 1)) +	{ +		calc_x_points(srcW, dstW); +		calc_y_strides(src, srcStride, srcH, dstH); +		calc_aa_points(srcW, dstW, xup_yup&1, xapoints); +		calc_aa_points(srcH, dstH, xup_yup&2, yapoints); +	} + +private: +	//........................................................................................... +	void calc_x_points(U32 srcW, U32 dstW) +	{ +		xpoints.resize(dstW+1); + +		S32 val = dstW >= srcW ? 0x8000 * srcW / dstW - 0x8000 : 0; +		S32 inc = (srcW << 16) / dstW; + +		for(U32 i = 0, j = 0; i < dstW; ++i, ++j, val += inc) +		{ +			xpoints[j] = llmax(0, val >> 16); +		} +	} +	//........................................................................................... +	void calc_y_strides(const U8 *src, U32 srcStride, U32 srcH, U32 dstH) +	{ +		ystrides.resize(dstH+1); + +		S32 val = dstH >= srcH ? 0x8000 * srcH / dstH - 0x8000 : 0; +		S32 inc = (srcH << 16) / dstH; + +		for(U32 i = 0, j = 0; i < dstH; ++i, ++j, val += inc) +		{ +			ystrides[j] = src + llmax(0, val >> 16) * srcStride; +		} +	} +	//........................................................................................... +	void calc_aa_points(U32 srcSz, U32 dstSz, bool scale_up, std::vector<S32> &vp) +	{ +		vp.resize(dstSz); + +		if(scale_up) +		{ +			S32 val = 0x8000 * srcSz / dstSz - 0x8000; +			S32 inc = (srcSz << 16) / dstSz; +			U32 pos; + +			for(U32 i = 0, j = 0; i < dstSz; ++i, ++j, val += inc) +			{ +				pos = val >> 16; + +				if (pos >= (srcSz - 1)) +					vp[j] = 0; +				else +					vp[j] = (val >> 8) - ((val >> 8) & 0xffffff00); +			} +		} +		else +		{  +			S32 inc = (srcSz << 16) / dstSz; +			S32 Cp = ((dstSz << 14) / srcSz) + 1; +			S32 ap; + +			for(U32 i = 0, j = 0, val = 0; i < dstSz; ++i, ++j, val += inc) +			{ +				ap = ((0x100 - ((val >> 8) & 0xff)) * Cp) >> 8; +				vp[j] = ap | (Cp << 16); +			} +		} +	} +}; + + +template<U8 ch> +inline void bilinear_scale( +	const U8 *src, U32 srcW, U32 srcH, U32 srcStride +	, U8 *dst, U32 dstW, U32 dstH, U32 dstStride +	) +{ +	typedef scale_info<ch> scale_info_t; + +	scale_info_t info(src, srcW, srcH, dstW, dstH, srcStride); + +	const U8 *sptr; +	U8 *dptr; +	U32 x, y; +	const U8 *pix; + +	S32 cx[ch], comp[ch]; + + +	if(3 == info.xup_yup) +	{ //scale x/y - up +		for(y = 0; y < dstH; ++y) +		{ +			dptr = dst + (y * dstStride); +			sptr = info.ystrides[y]; + +			if(0 < info.yapoints[y]) +			{ +				for(x = 0; x < dstW; ++x) +				{ +					//for(c = 0; c < ch; ++c) cx[c] = comp[c] = 0; +					typename scale_info_t::uroll_zeroze_cx_comp_t()(cx, comp); + +					if(0 < info.xapoints[x]) +					{ +						pix = info.ystrides[y] + info.xpoints[x] * ch; + +						//for(c = 0; c < ch; ++c) comp[c] = pix[c] * (256 - info.xapoints[x]); +						typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(comp, pix, 256 - info.xapoints[x]); + +						pix += ch; + +						//for(c = 0; c < ch; ++c) comp[c] += pix[c] * info.xapoints[x]; +						typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(comp, pix, info.xapoints[x]); + +						pix += srcStride; + +						//for(c = 0; c < ch; ++c) cx[c] = pix[c] * info.xapoints[x]; +						typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(cx, pix, info.xapoints[x]); + +						pix -= ch; + +						//for(c = 0; c < ch; ++c) {  +						//	cx[c] += pix[c] * (256 - info.xapoints[x]); +						//	comp[c] = ((cx[c] * info.yapoints[y]) + (comp[c] * (256 - info.yapoints[y]))) >> 16; +						//	*dptr++ = comp[c]&0xff; +						//} +						typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, 256 - info.xapoints[x]); +						typename scale_info_t::uroll_comp_asgn_cx_mul_apoint_plus_comp_mul_inv_apoint_allshifted_16_r_t()(comp, cx, info.yapoints[y]); +						typename scale_info_t::uroll_uref_dptr_inc_asgn_comp_and_ff_t()(dptr, comp); +					} +					else +					{ +						pix = info.ystrides[y] + info.xpoints[x] * ch; + +						//for(c = 0; c < ch; ++c) comp[c] = pix[c] * (256 - info.yapoints[y]); +						typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(comp, pix, 256-info.yapoints[y]); + +						pix += srcStride; + +						//for(c = 0; c < ch; ++c) {  +						//	comp[c] = (comp[c] + pix[c] * info.yapoints[y]) >> 8; +						//	*dptr++ = comp[c]&0xff; +						//} +						typename scale_info_t::uroll_comp_asgn_comp_plus_pix_mul_apoint_allshifted_8_r_t()(comp, pix, info.yapoints[y]); +						typename scale_info_t::uroll_uref_dptr_inc_asgn_comp_and_ff_t()(dptr, comp); +					} +				} +			} +			else +			{ +				for(x = 0; x < dstW; ++x) +				{ +					if(0 < info.xapoints[x]) +					{ +						pix = info.ystrides[y] + info.xpoints[x] * ch; + +						//for(c = 0; c < ch; ++c) { +						//	comp[c] = pix[c] * (256 - info.xapoints[x]); +						//	comp[c] = (comp[c] + pix[c] * info.xapoints[x]) >> 8; +						//	*dptr++ = comp[c]&0xff; +						//} +						typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(comp, pix, 256 - info.xapoints[x]); +						typename scale_info_t::uroll_comp_asgn_comp_plus_pix_mul_apoint_allshifted_8_r_t()(comp, pix, info.xapoints[x]); +						typename scale_info_t::uroll_uref_dptr_inc_asgn_comp_and_ff_t()(dptr, comp); +					} +					else  +					{ +						//for(c = 0; c < ch; ++c) *dptr++ = (sptr[info.xpoints[x]*ch + c])&0xff; +						typename scale_info_t::uroll_uref_dptr_inc_asgn_sptr_apoint_plus_idx_alland_ff_t()(dptr, sptr, info.xpoints[x]*ch); +					} +				} +			} +		} +	} +	else if(info.xup_yup == 1) +	{ //scaling down vertically +		S32 Cy, j; +		S32 yap; + +		for(y = 0; y < dstH; y++) +		{ +			Cy = info.yapoints[y] >> 16; +			yap = info.yapoints[y] & 0xffff; + +			dptr = dst + (y * dstStride); + +			for(x = 0; x < dstW; x++) +			{ +				pix = info.ystrides[y] + info.xpoints[x] * ch; + +				//for(c = 0; c < ch; ++c) comp[c] = pix[c] * yap; +				typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(comp, pix, yap); + +				pix += srcStride; + +				for(j = (1 << 14) - yap; j > Cy; j -= Cy, pix += srcStride) +				{ +					//for(c = 0; c < ch; ++c) comp[c] += pix[c] * Cy; +					typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(comp, pix, Cy); +				} + +				if(j > 0) +				{ +					//for(c = 0; c < ch; ++c) comp[c] += pix[c] * j; +					typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(comp, pix, j); +				} + +				if(info.xapoints[x] > 0) +				{ +					pix = info.ystrides[y] + info.xpoints[x]*ch + ch; +					//for(c = 0; c < ch; ++c) cx[c] = pix[c] * yap; +					typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(cx, pix, yap); + +					pix += srcStride; +					for(j = (1 << 14) - yap; j > Cy; j -= Cy) +					{ +						//for(c = 0; c < ch; ++c) cx[c] += pix[c] * Cy; +						typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, Cy); +						pix += srcStride; +					} + +					if(j > 0) +					{ +						//for(c = 0; c < ch; ++c) cx[c] += pix[c] * j; +						typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, j); +					} + +					//for(c = 0; c < ch; ++c) comp[c] = ((comp[c]*(256 - info.xapoints[x])) + ((cx[c] * info.xapoints[x]))) >> 12; +					typename scale_info_t::uroll_comp_asgn_comp_mul_inv_apoint_plus_cx_mul_apoint_allshifted_12_r_t()(comp, info.xapoints[x], cx); +				} +				else +				{ +					//for(c = 0; c < ch; ++c) comp[c] >>= 4; +					typename scale_info_t::uroll_comp_rshftasgn_constval_t()(comp, 4); +				} + +				//for(c = 0; c < ch; ++c) *dptr++ = (comp[c]>>10)&0xff; +				typename scale_info_t::uroll_uref_dptr_inc_asgn_comp_rshft_cval_and_ff_t()(dptr, comp, 10); +			} +		} +	} +	else if(info.xup_yup == 2) +	{ // scaling down horizontally +		S32 Cx, j; +		S32 xap; + +		for(y = 0; y < dstH; y++) +		{ +			dptr = dst + (y * dstStride); + +			for(x = 0; x < dstW; x++) +			{ +				Cx = info.xapoints[x] >> 16; +				xap = info.xapoints[x] & 0xffff; + +				pix = info.ystrides[y] + info.xpoints[x] * ch; + +				//for(c = 0; c < ch; ++c) comp[c] = pix[c] * xap; +				typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(comp, pix, xap); + +				pix+=ch; +				for(j = (1 << 14) - xap; j > Cx; j -= Cx) +				{ +					//for(c = 0; c < ch; ++c) comp[c] += pix[c] * Cx; +					typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(comp, pix, Cx); +					pix+=ch; +				} + +				if(j > 0) +				{ +					//for(c = 0; c < ch; ++c) comp[c] += pix[c] * j; +					typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(comp, pix, j); +				} + +				if(info.yapoints[y] > 0) +				{ +					pix = info.ystrides[y] + info.xpoints[x]*ch + srcStride; +					//for(c = 0; c < ch; ++c) cx[c] = pix[c] * xap; +					typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(cx, pix, xap); + +					pix+=ch; +					for(j = (1 << 14) - xap; j > Cx; j -= Cx) +					{ +						//for(c = 0; c < ch; ++c) cx[c] += pix[c] * Cx; +						typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, Cx); +						pix+=ch; +					} + +					if(j > 0) +					{ +						//for(c = 0; c < ch; ++c) cx[c] += pix[c] * j; +						typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, j); +					} + +					//for(c = 0; c < ch; ++c) comp[c] = ((comp[c] * (256 - info.yapoints[y])) + ((cx[c] * info.yapoints[y]))) >> 12; +					typename scale_info_t::uroll_comp_asgn_comp_mul_inv_apoint_plus_cx_mul_apoint_allshifted_12_r_t()(comp, info.yapoints[y], cx); +				} +				else +				{ +					//for(c = 0; c < ch; ++c) comp[c] >>= 4; +					typename scale_info_t::uroll_comp_rshftasgn_constval_t()(comp, 4); +				} + +				//for(c = 0; c < ch; ++c) *dptr++ = (comp[c]>>10)&0xff; +				typename scale_info_t::uroll_uref_dptr_inc_asgn_comp_rshft_cval_and_ff_t()(dptr, comp, 10); +			} +		} +	} +	else  +	{ //scale x/y - down +		S32 Cx, Cy, i, j; +		S32 xap, yap; + +		for(y = 0; y < dstH; y++) +		{ +			Cy = info.yapoints[y] >> 16; +			yap = info.yapoints[y] & 0xffff; + +			dptr = dst + (y * dstStride); +			for(x = 0; x < dstW; x++) +			{ +				Cx = info.xapoints[x] >> 16; +				xap = info.xapoints[x] & 0xffff; + +				sptr = info.ystrides[y] + info.xpoints[x] * ch; +				pix = sptr; +				sptr += srcStride; + +				//for(c = 0; c < ch; ++c) cx[c] = pix[c] * xap; +				typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(cx, pix, xap); + +				pix+=ch; +				for(i = (1 << 14) - xap; i > Cx; i -= Cx) +				{ +					//for(c = 0; c < ch; ++c) cx[c] += pix[c] * Cx; +					typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, Cx); +					pix+=ch; +				} + +				if(i > 0) +				{ +					//for(c = 0; c < ch; ++c) cx[c] += pix[c] * i; +					typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, i); +				} + +				//for(c = 0; c < ch; ++c) comp[c] = (cx[c] >> 5) * yap; +				typename scale_info_t::uroll_comp_asgn_cx_rshft_cval_all_mul_val_t()(comp, cx, 5, yap); + +				for(j = (1 << 14) - yap; j > Cy; j -= Cy) +				{ +					pix = sptr; +					sptr += srcStride; + +					//for(c = 0; c < ch; ++c) cx[c] = pix[c] * xap; +					typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(cx, pix, xap); + +					pix+=ch; +					for(i = (1 << 14) - xap; i > Cx; i -= Cx) +					{ +						//for(c = 0; c < ch; ++c) cx[c] += pix[c] * Cx; +						typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, Cx); +						pix+=ch; +					} + +					if(i > 0) +					{ +						//for(c = 0; c < ch; ++c) cx[c] += pix[c] * i; +						typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, i); +					} + +					//for(c = 0; c < ch; ++c) comp[c] += (cx[c] >> 5) * Cy; +					typename scale_info_t::uroll_comp_plusasgn_cx_rshft_cval_all_mul_val_t()(comp, cx, 5, Cy); +				} + +				if(j > 0) +				{ +					pix = sptr; +					sptr += srcStride; + +					//for(c = 0; c < ch; ++c) cx[c] = pix[c] * xap; +					typename scale_info_t::uroll_inp_asgn_pix_mul_val_t()(cx, pix, xap); + +					pix+=ch; +					for(i = (1 << 14) - xap; i > Cx; i -= Cx) +					{ +						//for(c = 0; c < ch; ++c) cx[c] += pix[c] * Cx; +						typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, Cx); +						pix+=ch; +					} + +					if(i > 0) +					{ +						//for(c = 0; c < ch; ++c) cx[c] += pix[c] * i; +						typename scale_info_t::uroll_inp_plusasgn_pix_mul_val_t()(cx, pix, i); +					} + +					//for(c = 0; c < ch; ++c) comp[c] += (cx[c] >> 5) * j; +					typename scale_info_t::uroll_comp_plusasgn_cx_rshft_cval_all_mul_val_t()(comp, cx, 5, j); +				} + +				//for(c = 0; c < ch; ++c) *dptr++ = (comp[c]>>23)&0xff; +				typename scale_info_t::uroll_uref_dptr_inc_asgn_comp_rshft_cval_and_ff_t()(dptr, comp, 23); +			} +		} +	} //else +} + +//wrapper +static void bilinear_scale(const U8 *src, U32 srcW, U32 srcH, U32 srcCh, U32 srcStride, U8 *dst, U32 dstW, U32 dstH, U32 dstCh, U32 dstStride) +{ +	llassert(srcCh == dstCh); + +	switch(srcCh) +	{ +	case 1: +		bilinear_scale<1>(src, srcW, srcH, srcStride, dst, dstW, dstH, dstStride); +		break; +	case 3: +		bilinear_scale<3>(src, srcW, srcH, srcStride, dst, dstW, dstH, dstStride); +		break; +	case 4: +		bilinear_scale<4>(src, srcW, srcH, srcStride, dst, dstW, dstH, dstStride); +		break; +	default: +		llassert(!"Implement if need"); +		break; +	} + +} +  //---------------------------------------------------------------------------  // LLImage  //--------------------------------------------------------------------------- @@ -559,6 +1098,7 @@ void LLImageRaw::composite( LLImageRaw* src )  	}  } +  // Src and dst can be any size.  Src has 4 components.  Dst has 3 components.  void LLImageRaw::compositeScaled4onto3(LLImageRaw* src)  { @@ -589,21 +1129,6 @@ void LLImageRaw::compositeScaled4onto3(LLImageRaw* src)  // Src and dst are same size.  Src has 4 components.  Dst has 3 components.  void LLImageRaw::compositeUnscaled4onto3( LLImageRaw* src )  { -	/* -	//test fastFractionalMult() -	{ -		U8 i = 255; -		U8 j = 255; -		do -		{ -			do -			{ -				llassert( fastFractionalMult(i, j) == (U8)(255*(i/255.f)*(j/255.f) + 0.5f) ); -			} while( j-- ); -		} while( i-- ); -	} -	*/ -  	LLImageRaw* dst = this;  // Just for clarity.  	llassert( (3 == src->getComponents()) || (4 == src->getComponents()) ); @@ -639,6 +1164,7 @@ void LLImageRaw::compositeUnscaled4onto3( LLImageRaw* src )  	}  } +  void LLImageRaw::copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill)  {  	LLImageRaw* dst = this;  // Just for clarity. @@ -846,6 +1372,12 @@ void LLImageRaw::copyScaled( LLImageRaw* src )  		return;  	} +	bilinear_scale( +			src->getData(), src->getWidth(), src->getHeight(), src->getComponents(), src->getWidth()*src->getComponents() +		,	dst->getData(), dst->getWidth(), dst->getHeight(), dst->getComponents(), dst->getWidth()*dst->getComponents() +	); + +	/*  	S32 temp_data_size = src->getWidth() * dst->getHeight() * getComponents();  	llassert_always(temp_data_size > 0);  	std::vector<U8> temp_buffer(temp_data_size); @@ -861,6 +1393,7 @@ void LLImageRaw::copyScaled( LLImageRaw* src )  	{  		copyLineScaled( &temp_buffer[0] + (getComponents() * src->getWidth() * row), dst->getData() + (getComponents() * dst->getWidth() * row), src->getWidth(), dst->getWidth(), 1, 1 );  	} +	*/  } @@ -880,6 +1413,7 @@ BOOL LLImageRaw::scale( S32 new_width, S32 new_height, BOOL scale_image_data )  	if (scale_image_data)  	{ +		/*  		S32 temp_data_size = old_width * new_height * getComponents();  		llassert_always(temp_data_size > 0);  		std::vector<U8> temp_buffer(temp_data_size); @@ -899,6 +1433,19 @@ BOOL LLImageRaw::scale( S32 new_width, S32 new_height, BOOL scale_image_data )  		{  			copyLineScaled( &temp_buffer[0] + (getComponents() * old_width * row), new_buffer + (getComponents() * new_width * row), old_width, new_width, 1, 1 );  		} +		*/ + +		S32 new_data_size = new_width * new_height * getComponents(); +		llassert_always(new_data_size > 0); + +		U8 *new_data = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), new_data_size);  +		if(NULL == new_data)  +		{ +			return FALSE;  +		} + +		bilinear_scale(getData(), old_width, old_height, getComponents(), old_width*getComponents(), new_data, new_width, new_height, getComponents(), new_width*getComponents()); +		setDataAndSize(new_data, new_width, new_height, getComponents());   	}  	else  	{ diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index c2198b91a7..82081ca853 100755 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -3178,6 +3178,16 @@ BOOL LLVolume::isFlat(S32 face)  } +LLVolumeParams::LLVolumeParams( LLProfileParams &profile, +								LLPathParams &path, +								LLUUID sculpt_id, +								U8 sculpt_type) : +mProfileParams(profile), +mPathParams(path) +{ +	setSculptID(sculpt_id, sculpt_type); +} +  bool LLVolumeParams::isSculpt() const  {  	return mSculptID.notNull(); @@ -3494,7 +3504,24 @@ bool LLVolumeParams::setSkew(const F32 skew_value)  bool LLVolumeParams::setSculptID(const LLUUID sculpt_id, U8 sculpt_type)  {  	mSculptID = sculpt_id; -	mSculptType = sculpt_type; +	// Check sculpt type value, it consist of type and flags +	U8 type = sculpt_type & LL_SCULPT_TYPE_MASK; +	U8 flags = sculpt_type & LL_SCULPT_FLAG_MASK; +	if (sculpt_type != (type | flags) || type > LL_SCULPT_TYPE_MAX) +	{ +		if (sculpt_id != LLUUID::null) +		{ +			mSculptType = LL_SCULPT_TYPE_MESH; +		} +		else +		{ +			mSculptType = LL_SCULPT_TYPE_SPHERE; +		} +	} +	else +	{ +		mSculptType = sculpt_type; +	}  	return true;  } @@ -5584,7 +5611,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  	{  		resizeVertices(num_vertices+1); -		if (!partial_build) +		//if (!partial_build)  		{  			resizeIndices(num_indices+3);  		} @@ -5592,7 +5619,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  	else  	{  		resizeVertices(num_vertices); -		if (!partial_build) +		//if (!partial_build)  		{  			resizeIndices(num_indices);  		} @@ -5714,10 +5741,10 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  	LL_CHECK_MEMORY -	if (partial_build) -	{ -		return TRUE; -	} +	//if (partial_build) +	//{ +	//	return TRUE; +	//}  	if (mTypeMask & HOLLOW_MASK)  	{ diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index c8476f6897..06688cacc9 100755 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -190,8 +190,12 @@ const U8 LL_SCULPT_TYPE_MESH      = 5;  const U8 LL_SCULPT_TYPE_MASK      = LL_SCULPT_TYPE_SPHERE | LL_SCULPT_TYPE_TORUS | LL_SCULPT_TYPE_PLANE |  	LL_SCULPT_TYPE_CYLINDER | LL_SCULPT_TYPE_MESH; +// for value checks, assign new value after adding new types +const U8 LL_SCULPT_TYPE_MAX = LL_SCULPT_TYPE_MESH; +  const U8 LL_SCULPT_FLAG_INVERT    = 64;  const U8 LL_SCULPT_FLAG_MIRROR    = 128; +const U8 LL_SCULPT_FLAG_MASK = LL_SCULPT_FLAG_INVERT | LL_SCULPT_FLAG_MIRROR;  const S32 LL_SCULPT_MESH_MAX_FACES = 8; @@ -556,11 +560,10 @@ public:  	{  	} -	LLVolumeParams(LLProfileParams &profile, LLPathParams &path, -				   LLUUID sculpt_id = LLUUID::null, U8 sculpt_type = LL_SCULPT_TYPE_NONE) -		: mProfileParams(profile), mPathParams(path), mSculptID(sculpt_id), mSculptType(sculpt_type) -	{ -	} +	LLVolumeParams( LLProfileParams &profile, +					LLPathParams &path, +					LLUUID sculpt_id = LLUUID::null, +					U8 sculpt_type = LL_SCULPT_TYPE_NONE);  	bool operator==(const LLVolumeParams ¶ms) const;  	bool operator!=(const LLVolumeParams ¶ms) const; diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 1571427d51..ed903146ef 100755 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -316,6 +316,14 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa  		if (indices.size()%3 == 0 && verts.size() >= 65532)  		{ +			std::string material; + +			if (tri->getMaterial()) +			{ +				material = std::string(tri->getMaterial()); +			} + +			materials.push_back(material);  			face_list.push_back(face);  			face_list.rbegin()->fillFromLegacyData(verts, indices);  			LLVolumeFace& new_face = *face_list.rbegin(); @@ -587,6 +595,14 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac  			if (indices.size()%3 == 0 && indices.size() >= 65532)  			{ +				std::string material; + +				if (poly->getMaterial()) +				{ +					material = std::string(poly->getMaterial()); +				} + +				materials.push_back(material);  				face_list.push_back(face);  				face_list.rbegin()->fillFromLegacyData(verts, indices);  				LLVolumeFace& new_face = *face_list.rbegin(); diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 29747cb09c..8e009972d0 100755 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -317,9 +317,9 @@ S32 LLPrimitive::setTEMaterialID(const U8 index, const LLMaterialID& pMaterialID  	return mTextureList.setMaterialID(index, pMaterialID);  } -S32 LLPrimitive::setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams) +S32 LLPrimitive::setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams, bool isInitFromServer)  { -	return mTextureList.setMaterialParams(index, pMaterialParams); +	return mTextureList.setMaterialParams(index, pMaterialParams, isInitFromServer);  }  LLMaterialPtr LLPrimitive::getTEMaterialParams(const U8 index) diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index 1bf83e36b4..db7327e900 100755 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -385,7 +385,7 @@ public:  	virtual S32 setTEMediaFlags(const U8 te, const U8 flags);  	virtual S32 setTEGlow(const U8 te, const F32 glow);  	virtual S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID); -	virtual S32 setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams); +	virtual S32 setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams, bool isInitFromServer);  	virtual BOOL setMaterial(const U8 material); // returns TRUE if material changed  	virtual void setTESelected(const U8 te, bool sel); diff --git a/indra/llprimitive/llprimtexturelist.cpp b/indra/llprimitive/llprimtexturelist.cpp index f4f08248b8..6aae2f97c6 100755 --- a/indra/llprimitive/llprimtexturelist.cpp +++ b/indra/llprimitive/llprimtexturelist.cpp @@ -368,11 +368,18 @@ S32 LLPrimTextureList::setMaterialID(const U8 index, const LLMaterialID& pMateri  	return TEM_CHANGE_NONE;  } -S32 LLPrimTextureList::setMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams) +S32 LLPrimTextureList::setMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams, bool isInitFromServer)  {  	if (index < mEntryList.size())  	{ -		return mEntryList[index]->setMaterialParams(pMaterialParams); +		if (!isInitFromServer && mEntryList[index]->isMatParamsInitFromServer()) +		{ +			return TEM_CHANGE_NONE; +		} +		else +		{ +			return mEntryList[index]->setMaterialParams(pMaterialParams); +		}  	}  	return TEM_CHANGE_NONE;  } diff --git a/indra/llprimitive/llprimtexturelist.h b/indra/llprimitive/llprimtexturelist.h index 49c636e40f..63e6372405 100755 --- a/indra/llprimitive/llprimtexturelist.h +++ b/indra/llprimitive/llprimtexturelist.h @@ -105,7 +105,7 @@ public:  	S32 setMediaFlags(const U8 index, const U8 media_flags);  	S32 setGlow(const U8 index, const F32 glow);  	S32 setMaterialID(const U8 index, const LLMaterialID& pMaterialID); -	S32 setMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams); +	S32 setMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams, bool isInitFromServer);  	LLMaterialPtr getMaterialParams(const U8 index); diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp index 284dfc15f4..6020031099 100755 --- a/indra/llprimitive/lltextureentry.cpp +++ b/indra/llprimitive/lltextureentry.cpp @@ -63,6 +63,7 @@ LLTextureEntry::LLTextureEntry()    : mMediaEntry(NULL)    , mSelected(false)    , mMaterialUpdatePending(false) +  , mInitMatParamsFromServer(false)  {  	init(LLUUID::null,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);  } @@ -71,6 +72,7 @@ LLTextureEntry::LLTextureEntry(const LLUUID& tex_id)    : mMediaEntry(NULL)    , mSelected(false)    , mMaterialUpdatePending(false) +  , mInitMatParamsFromServer(false)  {  	init(tex_id,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);  } @@ -79,6 +81,7 @@ LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)    : mMediaEntry(NULL)    , mSelected(false)    , mMaterialUpdatePending(false) +  , mInitMatParamsFromServer(false)  {  	mID = rhs.mID;  	mScaleS = rhs.mScaleS; @@ -562,6 +565,7 @@ S32 LLTextureEntry::setMaterialParams(const LLMaterialPtr pMaterialParams)  		mMaterialUpdatePending = true;  	}  	mMaterial = pMaterialParams; +	this->mInitMatParamsFromServer = TRUE;  	return TEM_CHANGE_TEXTURE;  } diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h index 19edcaa27d..3fe23d6c9f 100755 --- a/indra/llprimitive/lltextureentry.h +++ b/indra/llprimitive/lltextureentry.h @@ -156,6 +156,8 @@ public:  	const LLMaterialID& getMaterialID() const { return mMaterialID; };  	const LLMaterialPtr getMaterialParams() const { return mMaterial; }; +	bool isMatParamsInitFromServer() const { return mInitMatParamsFromServer; }; +      // *NOTE: it is possible for hasMedia() to return true, but getMediaData() to return NULL.      // CONVERSELY, it is also possible for hasMedia() to return false, but getMediaData()      // to NOT return NULL.   @@ -213,6 +215,8 @@ protected:  	bool                mMaterialUpdatePending;  	LLMaterialID        mMaterialID;  	LLMaterialPtr		mMaterial; +	bool                mInitMatParamsFromServer; // Flag to identification when material paramas initialized from  +  	// Note the media data is not sent via the same message structure as the rest of the TE  	LLMediaEntry*		mMediaEntry;			// The media data for the face diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 3ceed95248..f9f7d07c89 100755 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -722,10 +722,77 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)      GLint activeCount;      glGetObjectParameterivARB(mProgramObject, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &activeCount); +	//........................................................................................................................................ +	//........................................................................................ + +	/* +	EXPLANATION: +	This is part of code is temporary because as the final result the mapUniform() should be rewrited.  +	But it's a huge a volume of work which is need to be a more carefully performed for avoid possible  +	regression's (i.e. it should be formalized a separate ticket in JIRA). + +	RESON: +	The reason of this code is that SL engine is very sensitive to fact that "diffuseMap" should be appear  +	first as uniform parameter which is should get 0-"texture channel" index (see mapUniformTextureChannel() and mActiveTextureChannels)  +	it influence to which is texture matrix will be updated during rendering. + +	But, order of indexe's of uniform variables is not defined and GLSL compiler can change it as want +	, even if the "diffuseMap" will be appear and use first in shader code. + +	As example where this situation appear see: "Deferred Material Shader 28/29/30/31" +	And tickets: MAINT-4165, MAINT-4839 +	*/ +	 + +	S32 diffuseMap = glGetUniformLocationARB(mProgramObject, "diffuseMap"); +	S32 bumpMap = glGetUniformLocationARB(mProgramObject, "bumpMap"); + +	std::set<S32> skip_index; + +	if(diffuseMap != -1 && bumpMap != -1) +	{ +		GLenum type; +		GLsizei length; +		GLint size = -1; +		char name[1024];         + +		//diffuse map +		for (S32 i = 0; i < activeCount; i++) +		{ +			name[0] = 0; +			 +			glGetActiveUniformARB(mProgramObject, i, 1024, &length, &size, &type, (GLcharARB *)name); + +			if(std::string(name) == "diffuseMap") { +				diffuseMap = i; +			} + +			if(std::string(name) == "bumpMap") { +				bumpMap = i; +			} +		} +		 +		if(bumpMap < diffuseMap) +		{ +			mapUniform(diffuseMap, uniforms); +			mapUniform(bumpMap, uniforms); + +			skip_index.insert(diffuseMap); +			skip_index.insert(bumpMap); +		} +	} + +	//........................................................................................ +	      for (S32 i = 0; i < activeCount; i++)      { +		//........................................................................................ +		if(skip_index.end() != skip_index.find(i)) continue; +		//........................................................................................ +		          mapUniform(i, uniforms);      } +	//........................................................................................................................................      unbind(); diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 1ca6e99ecf..69420dd0bb 100755 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -104,10 +104,10 @@ LLTexUnit::LLTexUnit(S32 index)  	mCurrColorSrc1(TBS_TEX_COLOR), mCurrColorSrc2(TBS_PREV_COLOR),  	mCurrAlphaSrc1(TBS_TEX_ALPHA), mCurrAlphaSrc2(TBS_PREV_ALPHA),  	mCurrColorScale(1), mCurrAlphaScale(1), mCurrTexture(0), -	mHasMipMaps(false) +	mHasMipMaps(false), +	mIndex(index)  {  	llassert_always(index < (S32)LL_NUM_TEXTURE_LAYERS); -	mIndex = index;  }  //static @@ -227,33 +227,34 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)  	stop_glerror();  	if (mIndex >= 0)  	{ -	gGL.flush(); +		gGL.flush(); + +		LLImageGL* gl_tex = NULL ; -	LLImageGL* gl_tex = NULL ;  		if (texture != NULL && (gl_tex = texture->getGLTexture())) -	{ -			if (gl_tex->getTexName()) //if texture exists -	{ -	//in audit, replace the selected texture by the default one. -	if ((mCurrTexture != gl_tex->getTexName()) || forceBind) -	{ -		activate(); -		enable(gl_tex->getTarget()); -		mCurrTexture = gl_tex->getTexName(); -		glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture); -		if(gl_tex->updateBindStats(gl_tex->mTextureMemory)) -		{ -			texture->setActive() ; -			texture->updateBindStatsForTester() ; -		} -		mHasMipMaps = gl_tex->mHasMipMaps; -		if (gl_tex->mTexOptionsDirty)  		{ -			gl_tex->mTexOptionsDirty = false; -			setTextureAddressMode(gl_tex->mAddressMode); -			setTextureFilteringOption(gl_tex->mFilterOption); -		} -	} +			if (gl_tex->getTexName()) //if texture exists +			{ +				//in audit, replace the selected texture by the default one. +				if ((mCurrTexture != gl_tex->getTexName()) || forceBind) +				{ +					activate(); +					enable(gl_tex->getTarget()); +					mCurrTexture = gl_tex->getTexName(); +					glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture); +					if(gl_tex->updateBindStats(gl_tex->mTextureMemory)) +					{ +						texture->setActive() ; +						texture->updateBindStatsForTester() ; +					} +					mHasMipMaps = gl_tex->mHasMipMaps; +					if (gl_tex->mTexOptionsDirty) +					{ +						gl_tex->mTexOptionsDirty = false; +						setTextureAddressMode(gl_tex->mAddressMode); +						setTextureFilteringOption(gl_tex->mFilterOption); +					} +				}  			}  			else  			{ diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 42b02a8159..a67fb8da52 100755 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -198,7 +198,7 @@ public:  	void setHasMipMaps(bool hasMips) { mHasMipMaps = hasMips; }  protected: -	S32					mIndex; +	const S32			mIndex;  	U32					mCurrTexture;  	eTextureType		mCurrTexType;  	eTextureBlendType	mCurrBlendType; diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index b32aea5ffa..559895da1a 100755 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -443,6 +443,7 @@ void LLComboBox::onFocusLost()  	{  		mTextEntry->selectAll();  	} +	mButton->setForcePressedState(false);  	LLUICtrl::onFocusLost();  } diff --git a/indra/llui/lldockablefloater.cpp b/indra/llui/lldockablefloater.cpp index 3396213f1c..c937d190c6 100755 --- a/indra/llui/lldockablefloater.cpp +++ b/indra/llui/lldockablefloater.cpp @@ -153,7 +153,7 @@ void LLDockableFloater::setVisible(BOOL visible)  		mDockControl.get()->repositionDockable();  	} -	if (visible) +	if (visible && !isMinimized())  	{  		LLFloater::setFrontmost(getAutoFocus());  	} diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp index 747b472ac2..f16cd8e124 100644 --- a/indra/llui/llfolderviewitem.cpp +++ b/indra/llui/llfolderviewitem.cpp @@ -128,6 +128,7 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)  	mSelectPending(FALSE),  	mLabelStyle( LLFontGL::NORMAL ),  	mHasVisibleChildren(FALSE), +	mIsFolderComplete(true),      mLocalIndentation(p.folder_indentation),  	mIndentation(0),  	mItemHeight(p.item_height), @@ -672,7 +673,7 @@ void LLFolderViewItem::drawOpenFolderArrow(const Params& default_params, const L  	//  	const S32 TOP_PAD = default_params.item_top_pad; -	if (hasVisibleChildren()) +	if (hasVisibleChildren() || !isFolderComplete())  	{  		LLUIImage* arrow_image = default_params.folder_arrow_image;  		gl_draw_scaled_rotated_image( @@ -932,6 +933,8 @@ LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ):  	mLastArrangeGeneration( -1 ),  	mLastCalculatedWidth(0)  { +	// folder might have children that are not loaded yet. Mark it as incomplete until chance to check it. +	mIsFolderComplete = false;  }  void LLFolderViewFolder::updateLabelRotation() @@ -1014,6 +1017,12 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height )  		mHasVisibleChildren = found;  	} +	if (!mIsFolderComplete) +	{ +		mIsFolderComplete = getFolderViewModel()->isFolderComplete(this); +	} + +  	// calculate height as a single item (without any children), and reshapes rectangle to match  	LLFolderViewItem::arrange( width, height ); @@ -1461,31 +1470,37 @@ void LLFolderViewFolder::extendSelectionTo(LLFolderViewItem* new_selection)  	LLFolderView* root = getRoot(); -	for (std::vector<LLFolderViewItem*>::iterator it = items_to_select_forward.begin(), end_it = items_to_select_forward.end(); +	BOOL selection_reverse = new_selection->isSelected(); //indication that some elements are being deselected + +	// array always go from 'will be selected' to ' will be unselected', iterate +	// in opposite direction to simplify identification of 'point of origin' in +	// case it is in the list we are working with +	for (std::vector<LLFolderViewItem*>::reverse_iterator it = items_to_select_forward.rbegin(), end_it = items_to_select_forward.rend();  		it != end_it;  		++it)  	{  		LLFolderViewItem* item = *it; -		if (item->isSelected()) +		BOOL selected = item->isSelected(); +		if (!selection_reverse && selected)  		{ -			root->removeFromSelectionList(item); +			// it is our 'point of origin' where we shift/expand from +			// don't deselect it +			selection_reverse = TRUE;  		}  		else  		{ -			item->selectItem(); +			root->changeSelection(item, !selected);  		} -		root->addToSelectionList(item);  	} -	if (new_selection->isSelected()) +	if (selection_reverse)  	{ -		root->removeFromSelectionList(new_selection); +		// at some point we reversed selection, first element should be deselected +		root->changeSelection(last_selected_item_from_cur, FALSE);  	} -	else -	{ -		new_selection->selectItem(); -	} -	root->addToSelectionList(new_selection); + +	// element we expand to should always be selected +	root->changeSelection(new_selection, TRUE);  } @@ -1673,7 +1688,9 @@ void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType r  	mIsOpen = openitem;  		if(!was_open && openitem)  		{ -		getViewModelItem()->openItem(); +			getViewModelItem()->openItem(); +			// openItem() will request content, it won't be incomplete +			mIsFolderComplete = true;  		}  		else if(was_open && !openitem)  		{ diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h index 5ad5731cad..f77d676f46 100755 --- a/indra/llui/llfolderviewitem.h +++ b/indra/llui/llfolderviewitem.h @@ -114,6 +114,7 @@ protected:  	F32							mControlLabelRotation;  	LLFolderView*				mRoot;  	bool						mHasVisibleChildren, +								mIsFolderComplete, // indicates that some children were not loaded/added yet  								mIsCurSelection,  								mDragAndDropTarget,  								mIsMouseOverTitle, @@ -210,6 +211,9 @@ public:  	BOOL hasVisibleChildren() { return mHasVisibleChildren; } +	// true if object can't have children +	BOOL isFolderComplete() { return mIsFolderComplete; } +  	// Call through to the viewed object and return true if it can be  	// removed. Returns true if it's removed.  	//virtual BOOL removeRecursively(BOOL single_item); diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h index f6550eae42..8e780c6752 100755 --- a/indra/llui/llfolderviewmodel.h +++ b/indra/llui/llfolderviewmodel.h @@ -122,6 +122,7 @@ public:  	virtual void filter() = 0;  	virtual bool contentsReady() = 0; +	virtual bool isFolderComplete(class LLFolderViewFolder*) = 0;  	virtual void setFolderView(LLFolderView* folder_view) = 0;  	virtual LLFolderViewFilter& getFilter() = 0;  	virtual const LLFolderViewFilter& getFilter() const = 0; @@ -442,6 +443,7 @@ public:  	// By default, we assume the content is available. If a network fetch mechanism is implemented for the model,  	// this method needs to be overloaded and return the relevant fetch status.  	virtual bool contentsReady()					{ return true; } +	virtual bool isFolderComplete(LLFolderViewFolder* folder)					{ return true; }  	struct ViewModelCompare  	{ diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 7cdbcb0621..3b8d282445 100755 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -225,7 +225,6 @@ BOOL LLMenuItemGL::handleAcceleratorKey(KEY key, MASK mask)  BOOL LLMenuItemGL::handleHover(S32 x, S32 y, MASK mask)  { -	setHover(TRUE);  	getWindow()->setCursor(UI_CURSOR_ARROW);  	return TRUE;  } @@ -236,6 +235,18 @@ BOOL LLMenuItemGL::handleRightMouseDown(S32 x, S32 y, MASK mask)  	return LLUICtrl::handleRightMouseDown(x,y,mask);  } +void LLMenuItemGL::onMouseEnter(S32 x, S32 y, MASK mask) +{ +	setHover(TRUE); +	LLUICtrl::onMouseEnter(x,y,mask); +} + +void LLMenuItemGL::onMouseLeave(S32 x, S32 y, MASK mask) +{ +	setHover(FALSE); +	LLUICtrl::onMouseLeave(x,y,mask); +} +  //virtual  BOOL LLMenuItemGL::handleRightMouseUp(S32 x, S32 y, MASK mask)  { @@ -533,9 +544,6 @@ void LLMenuItemGL::draw( void )  			gl_line_2d(x_begin, (MENU_ITEM_PADDING / 2) + 1, x_end, (MENU_ITEM_PADDING / 2) + 1);  		}  	} - -	// clear got hover every frame -	setHover(FALSE);  }  BOOL LLMenuItemGL::setLabelArg( const std::string& key, const LLStringExplicit& text ) @@ -1043,7 +1051,7 @@ void LLMenuItemBranchGL::onCommit( void )  	// keyboard navigation automatically propagates highlight to sub-menu  	// to facilitate fast menu control via jump keys -	if (LLMenuGL::getKeyboardMode() && getBranch()&& !getBranch()->getHighlightedItem()) +	if (LLMenuGL::getKeyboardMode() && getBranch() && !getBranch()->getHighlightedItem())  	{  		getBranch()->highlightNextItem(NULL);  	} @@ -1456,7 +1464,16 @@ BOOL LLMenuItemBranchDownGL::handleMouseDown( S32 x, S32 y, MASK mask )  {  	// switch to mouse control mode  	LLMenuGL::setKeyboardMode(FALSE); -	onCommit(); + +	if (getVisible() && isOpen()) +	{ +		LLMenuGL::sMenuContainer->hideMenus(); +	} +	else +	{ +		onCommit(); +	} +  	make_ui_sound("UISndClick");  	return TRUE;  } @@ -1588,10 +1605,6 @@ void LLMenuItemBranchDownGL::draw( void )  			gl_line_2d(x_begin, LABEL_BOTTOM_PAD_PIXELS, x_end, LABEL_BOTTOM_PAD_PIXELS);  		}  	} - -	// reset every frame so that we only show highlight  -	// when we get hover events on that frame -	setHover(FALSE);  } @@ -3625,8 +3638,24 @@ BOOL LLMenuHolderGL::handleMouseDown( S32 x, S32 y, MASK mask )  	BOOL handled = LLView::childrenHandleMouseDown(x, y, mask) != NULL;  	if (!handled)  	{ -		// clicked off of menu, hide them all -		hideMenus(); +		LLMenuGL* visible_menu = (LLMenuGL*)getVisibleMenu(); +		LLMenuItemGL* parent_menu = visible_menu ? visible_menu->getParentMenuItem() : NULL; +		if (parent_menu && parent_menu->getVisible()) +		{ +			// don't hide menu if parent was hit +			LLRect parent_rect; +			parent_menu->localRectToOtherView(parent_menu->getLocalRect(), &parent_rect, this); +			if (!parent_rect.pointInRect(x, y)) +			{ +				// clicked off of menu and parent, hide them all +				hideMenus(); +			} +		} +		else +		{ +			// no visible parent, clicked off of menu, hide them all +			hideMenus(); +		}  	}  	return handled;  } diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index ae9b169691..28f9e3b6e9 100755 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -158,6 +158,10 @@ public:  	virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );  	virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask );  	virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks ); + +	virtual void	onMouseEnter(S32 x, S32 y, MASK mask); +	virtual void	onMouseLeave(S32 x, S32 y, MASK mask); +  	virtual void draw( void );  	BOOL getHover() const { return mGotHover; } diff --git a/indra/llui/llsearcheditor.cpp b/indra/llui/llsearcheditor.cpp index ea96fc573d..1fdd05a11c 100755 --- a/indra/llui/llsearcheditor.cpp +++ b/indra/llui/llsearcheditor.cpp @@ -29,6 +29,7 @@  #include "linden_common.h"  #include "llsearcheditor.h" +#include "llkeyboard.h"  LLSearchEditor::LLSearchEditor(const LLSearchEditor::Params& p)  :	LLUICtrl(p), @@ -166,4 +167,16 @@ void LLSearchEditor::handleKeystroke()  	{  		mKeystrokeCallback(this, getValue());  	} + +	KEY key = gKeyboard->currentKey(); +	if (key == KEY_LEFT || +		key == KEY_RIGHT) +	{ +			return; +	} + +	if (mTextChangedCallback) +	{ +		mTextChangedCallback(this, getValue()); +	}  } diff --git a/indra/llui/llsearcheditor.h b/indra/llui/llsearcheditor.h index c2d7916938..3b12868225 100755 --- a/indra/llui/llsearcheditor.h +++ b/indra/llui/llsearcheditor.h @@ -82,12 +82,14 @@ public:  	virtual void	setFocus( BOOL b );  	void			setKeystrokeCallback( commit_callback_t cb ) { mKeystrokeCallback = cb; } +	void			setTextChangedCallback( commit_callback_t cb ) { mTextChangedCallback = cb; }  protected:  	void onClearButtonClick(const LLSD& data);  	virtual void handleKeystroke();  	commit_callback_t mKeystrokeCallback; +	commit_callback_t mTextChangedCallback;  	LLLineEditor* mSearchEditor;  	LLButton* mSearchButton;  	LLButton* mClearButton; diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index 4b08798892..701a06a085 100755 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -1775,6 +1775,11 @@ void LLTabContainer::onNextBtn( const LLSD& data )  		scrollNext();  	}  	mScrolled = FALSE; + +	if(mCurrentTabIdx < mTabList.size()-1) +	{ +		selectNextTab(); +	}  }  void LLTabContainer::onNextBtnHeld( const LLSD& data ) @@ -1783,6 +1788,11 @@ void LLTabContainer::onNextBtnHeld( const LLSD& data )  	{  		mScrollTimer.reset();  		scrollNext(); + +		if(mCurrentTabIdx < mTabList.size()-1) +		{ +			selectNextTab(); +		}  		mScrolled = TRUE;  	}  } @@ -1794,6 +1804,11 @@ void LLTabContainer::onPrevBtn( const LLSD& data )  		scrollPrev();  	}  	mScrolled = FALSE; + +	if(mCurrentTabIdx > 0) +	{ +		selectPrevTab(); +	}  }  void LLTabContainer::onJumpFirstBtn( const LLSD& data ) @@ -1812,6 +1827,11 @@ void LLTabContainer::onPrevBtnHeld( const LLSD& data )  	{  		mScrollTimer.reset();  		scrollPrev(); + +		if(mCurrentTabIdx > 0) +		{ +			selectPrevTab(); +		}  		mScrolled = TRUE;  	}  } diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 6db0d88998..95f931de0a 100755 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -203,10 +203,10 @@ std::string LLUrlEntryBase::urlToGreyQuery(const std::string &url) const  {  	LLUriParser up(unescapeUrl(url)); -	std::string query; +	std::string label;  	up.extractParts(); -	up.glueSecond(query); - +	up.glueFirst(label); +	std::string query = url.substr(label.size());  	return query;  } @@ -293,11 +293,7 @@ std::string LLUrlEntryHTTPLabel::getUrl(const std::string &string) const  LLUrlEntryHTTPNoProtocol::LLUrlEntryHTTPNoProtocol()  	: LLUrlEntryBase()  { -	mPattern = boost::regex("(" -				"\\bwww\\.\\S+\\.\\S+" // i.e. www.FOO.BAR -				"|" // or -				"(?<!@)\\b[^[:space:]:@/>]+\\.(?:com|net|edu|org)([/:][^[:space:]<]*)?\\b" // i.e. FOO.net -				")", +	mPattern = boost::regex("\\bwww\\.\\S+\\.\\S+", // i.e. www.FOO.BAR  				boost::regex::perl|boost::regex::icase);  	mMenuName = "menu_url_http.xml";  	mTooltip = LLTrans::getString("TooltipHttpUrl"); @@ -1401,6 +1397,40 @@ std::string LLUrlEntryIcon::getIcon(const std::string &url)  	return mIcon;  } +// +// LLUrlEntryEmail Describes a generic mailto: Urls +// +LLUrlEntryEmail::LLUrlEntryEmail() +	: LLUrlEntryBase() +{ +	mPattern = boost::regex("(mailto:)?[\\w\\.\\-]+@[\\w\\.\\-]+\\.[a-z]{2,6}", +							boost::regex::perl | boost::regex::icase); +	mMenuName = "menu_url_email.xml"; +	mTooltip = LLTrans::getString("TooltipEmail"); +} + +std::string LLUrlEntryEmail::getLabel(const std::string &url, const LLUrlLabelCallback &cb) +{ +	int pos = url.find("mailto:"); + +	if (pos == std::string::npos) +	{ +		return escapeUrl(url); +	} + +	std::string ret = escapeUrl(url.substr(pos + 7, url.length() - pos + 8)); +	return ret; +} + +std::string LLUrlEntryEmail::getUrl(const std::string &string) const +{ +	if (string.find("mailto:") == std::string::npos) +	{ +		return "mailto:" + escapeUrl(string); +	} +	return escapeUrl(string); +} +  LLUrlEntryExperienceProfile::LLUrlEntryExperienceProfile()  {      mPattern = boost::regex(APP_HEADER_REGEX "/experience/[\\da-f-]+/\\w+\\S*", diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index dd1f257a3d..4d5e77c3bd 100755 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -506,5 +506,16 @@ public:  	/*virtual*/ std::string getIcon(const std::string &url);  }; +/// +/// LLUrlEntryEmail Describes a generic mailto: Urls +/// +class LLUrlEntryEmail : public LLUrlEntryBase +{ +public: +	LLUrlEntryEmail(); +	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); +	/*virtual*/ std::string getUrl(const std::string &string) const; +}; +  #endif diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index 2085505947..fcdb5b19d4 100755 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -76,9 +76,10 @@ LLUrlRegistry::LLUrlRegistry()  	registerUrl(new LLUrlEntrySL());  	mUrlEntrySLLabel = new LLUrlEntrySLLabel();  	registerUrl(mUrlEntrySLLabel); -	// most common pattern is a URL without any protocol, -	// e.g., "secondlife.com" +	// most common pattern is a URL without any protocol starting with "www", +	// e.g., "www.secondlife.com"  	registerUrl(new LLUrlEntryHTTPNoProtocol());	 +	registerUrl(new LLUrlEntryEmail());  }  LLUrlRegistry::~LLUrlRegistry() @@ -155,11 +156,9 @@ static bool stringHasUrl(const std::string &text)  	return (text.find("://") != std::string::npos ||  			text.find("www.") != std::string::npos ||  			text.find(".com") != std::string::npos || -			text.find(".net") != std::string::npos || -			text.find(".edu") != std::string::npos || -			text.find(".org") != std::string::npos ||  			text.find("<nolink>") != std::string::npos || -			text.find("<icon") != std::string::npos); +			text.find("<icon") != std::string::npos || +			text.find("@") != std::string::npos);  }  bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LLUrlLabelCallback &cb, bool is_content_trusted) @@ -218,6 +217,10 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL  	// did we find a match? if so, return its details in the match object  	if (match_entry)  	{ +		// Skip if link is an email with an empty username (starting with @). See MAINT-5371. +		if (match_start > 0 && text.substr(match_start - 1, 1) == "@") +			return false; +  		// fill in the LLUrlMatch object and return it  		std::string url = text.substr(match_start, match_end - match_start + 1); diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp index 5720660034..1b24250618 100755 --- a/indra/llwindow/llwindow.cpp +++ b/indra/llwindow/llwindow.cpp @@ -49,8 +49,8 @@ LLSplashScreen *gSplashScreenp = NULL;  BOOL gDebugClicks = FALSE;  BOOL gDebugWindowProc = FALSE; -const S32 gURLProtocolWhitelistCount = 4; -const std::string gURLProtocolWhitelist[] = { "secondlife:", "http:", "https:", "data:" }; +const S32 gURLProtocolWhitelistCount = 5; +const std::string gURLProtocolWhitelist[] = { "secondlife:", "http:", "https:", "data:", "mailto:" };  // CP: added a handler list - this is what's used to open the protocol and is based on registry entry  //	   only meaningful difference currently is that file: protocols are opened using http: diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h index f02052ca6a..e6e8f27f53 100755 --- a/indra/llwindow/llwindowmacosx-objc.h +++ b/indra/llwindow/llwindowmacosx-objc.h @@ -53,6 +53,7 @@ bool runMainLoop();  void initMainLoop();  void cleanupViewer();  void handleUrl(const char* url); +void dispatchUrl(std::string url);  /* Defined in llwindowmacosx-objc.mm: */  int createNSApp(int argc, const char **argv); diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index cd2be87fad..7e0eb9cf31 100755 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -2292,6 +2292,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_  					sHandleLeftMouseUp = true;  					break;  				} +				sHandleDoubleClick = true;  				//if (gDebugClicks)  				//{ diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 9d9bc43bd7..daeec74364 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -3459,6 +3459,17 @@        <key>Value</key>        <integer>0</integer>      </map> +    <key>MinObjectsForUnlinkConfirm</key> +    <map> +      <key>Comment</key> +      <string>Minimum amount of objects in linkset for showing confirmation dialog</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>S32</string> +      <key>Value</key> +      <integer>6</integer> +    </map>      <key>EffectScriptChatParticles</key>        <map>        <key>Comment</key> @@ -14131,6 +14142,17 @@        <key>Value</key>        <integer>-1</integer>      </map> +    <key>MaxFPS</key> +    <map> +      <key>Comment</key> +      <string>Yield some time to the local host if we reach a threshold framerate.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>F32</string> +      <key>Value</key> +      <real>-1.0</real> +    </map>      <key>ForcePeriodicRenderingTime</key>      <map>        <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl index 595c11fae2..58fb01d200 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl @@ -29,6 +29,7 @@ out vec4 frag_data[3];  #define frag_data gl_FragData  #endif +uniform float minimum_alpha;  uniform sampler2D diffuseMap;  uniform sampler2D bumpMap; @@ -47,16 +48,23 @@ vec2 encode_normal(vec3 n)  void main()   { -	vec3 col = vertex_color.rgb * texture2D(diffuseMap, vary_texcoord0.xy).rgb; -	vec3 norm = texture2D(bumpMap, vary_texcoord0.xy).rgb * 2.0 - 1.0; +	vec4 col = texture2D(diffuseMap, vary_texcoord0.xy); +	 +	if(col.a < minimum_alpha) +	{ +		discard; +    }		 +		col *= vertex_color; +		 +		vec3 norm = texture2D(bumpMap, vary_texcoord0.xy).rgb * 2.0 - 1.0; -	vec3 tnorm = vec3(dot(norm,vary_mat0), +		vec3 tnorm = vec3(dot(norm,vary_mat0),  			  dot(norm,vary_mat1),  			  dot(norm,vary_mat2)); -	frag_data[0] = vec4(col, 0.0); -	frag_data[1] = vertex_color.aaaa; // spec -	//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested -	vec3 nvn = normalize(tnorm); -	frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, 0.0); +		frag_data[0] = vec4(col.rgb, 0.0); +		frag_data[1] = vertex_color.aaaa; // spec +		//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested +		vec3 nvn = normalize(tnorm); +		frag_data[2] = vec4(encode_normal(nvn), vertex_color.a, 0.0);	  } diff --git a/indra/newview/app_settings/toolbars.xml b/indra/newview/app_settings/toolbars.xml index d61aee9a14..36e4eb91fd 100755 --- a/indra/newview/app_settings/toolbars.xml +++ b/indra/newview/app_settings/toolbars.xml @@ -23,4 +23,7 @@      <command name="snapshot"/>      <command name="facebook"/>    </left_toolbar> +  <right_toolbar +    button_display_mode="icons_only"> +  </right_toolbar>  </toolbars> diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index 8c8b4971cf..b8677fd9e4 100755 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -165,7 +165,9 @@ lbl_configure_default_lang:  	StrCpy $LANGUAGE $0
  # For silent installs, no language prompt, use default
 -    IfSilent lbl_return
 +    IfSilent 0 +3
 +    StrCpy $SKIP_AUTORUN "true"
 +    Goto lbl_return
      StrCmp $SKIP_DIALOGS "true" lbl_return
  lbl_build_menu:
 @@ -298,6 +300,11 @@ CreateShortCut "$INSTDIR\$INSTSHORTCUT.lnk" \  CreateShortCut "$INSTDIR\Uninstall $INSTSHORTCUT.lnk" \
  				'"$INSTDIR\uninst.exe"' ''
 +# Create *.bat file to specify lang params on first run from installer - see MAINT-5259
 +FileOpen $9 "$INSTDIR\autorun.bat" w
 +FileWrite $9 'start "$INSTDIR\$INSTEXE" "$INSTDIR\$INSTEXE" $SHORTCUT_LANG_PARAM$\r$\n'
 +FileClose $9
 +
  # Write registry
  WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "" "$INSTDIR"
  WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Version" "${VERSION_LONG}"
 @@ -682,7 +689,7 @@ Call CheckWindowsServPack		# Warn if not on the latest SP before asking to launc  	Push $R0					# Option value, unused
  	StrCmp $SKIP_AUTORUN "true" +2;
  # Assumes SetOutPath $INSTDIR
 -	Exec '"$WINDIR\explorer.exe" "$INSTDIR\$INSTEXE"'
 +	Exec '"$WINDIR\explorer.exe" "$INSTDIR\autorun.bat"'
  	Pop $R0
  FunctionEnd
 diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 359171c5bd..6f2c1859e4 100755 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -2843,7 +2843,7 @@ BOOL LLAgent::isInGroup(const LLUUID& group_id, BOOL ignore_god_mode /* FALSE */  // This implementation should mirror LLAgentInfo::hasPowerInGroup  BOOL LLAgent::hasPowerInGroup(const LLUUID& group_id, U64 power) const  { -	if (isGodlike()) +	if (isGodlikeWithoutAdminMenuFakery())  		return true;  	// GP_NO_POWERS can also mean no power is enough to grant an ability. diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 7f0330ee99..aed27924fe 100755 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -147,6 +147,7 @@ LLAgentCamera::LLAgentCamera() :  	mCameraUpVector(LLVector3::z_axis), // default is straight up  	mFocusOnAvatar(TRUE), +	mAllowChangeToFollow(FALSE),  	mFocusGlobal(),  	mFocusTargetGlobal(),  	mFocusObject(NULL), @@ -1152,8 +1153,10 @@ void LLAgentCamera::updateCamera()  		mCameraUpVector = mCameraUpVector * gAgentAvatarp->getRenderRotation();  	} -	if (cameraThirdPerson() && mFocusOnAvatar && LLFollowCamMgr::getActiveFollowCamParams()) +	if (cameraThirdPerson() && (mFocusOnAvatar || mAllowChangeToFollow) && LLFollowCamMgr::getActiveFollowCamParams())  	{ +		mAllowChangeToFollow = FALSE; +		mFocusOnAvatar = TRUE;  		changeCameraToFollow();  	} @@ -2610,6 +2613,7 @@ void LLAgentCamera::setFocusOnAvatar(BOOL focus_on_avatar, BOOL animate)  	{  		// keep camera focus point consistent, even though it is now unlocked  		setFocusGlobal(gAgent.getPositionGlobal() + calcThirdPersonFocusOffset(), gAgent.getID()); +		mAllowChangeToFollow = FALSE;  	}  	mFocusOnAvatar = focus_on_avatar; diff --git a/indra/newview/llagentcamera.h b/indra/newview/llagentcamera.h index 4d0f9a80de..ab793ff316 100755 --- a/indra/newview/llagentcamera.h +++ b/indra/newview/llagentcamera.h @@ -206,13 +206,15 @@ public:  	void			setCameraPosAndFocusGlobal(const LLVector3d& pos, const LLVector3d& focus, const LLUUID &object_id);  	void			clearFocusObject();  	void			setFocusObject(LLViewerObject* object); +	void			setAllowChangeToFollow(BOOL focus) 	{ mAllowChangeToFollow = focus; }  	void			setObjectTracking(BOOL track) 	{ mTrackFocusObject = track; }  	const LLVector3d &getFocusGlobal() const		{ return mFocusGlobal; }  	const LLVector3d &getFocusTargetGlobal() const	{ return mFocusTargetGlobal; }  private:  	LLVector3d		mCameraFocusOffset;				// Offset from focus point in build mode  	LLVector3d		mCameraFocusOffsetTarget;		// Target towards which we are lerping the camera's focus offset -	BOOL			mFocusOnAvatar;					 +	BOOL			mFocusOnAvatar; +	BOOL			mAllowChangeToFollow;  	LLVector3d		mFocusGlobal;  	LLVector3d		mFocusTargetGlobal;  	LLPointer<LLViewerObject> mFocusObject; diff --git a/indra/newview/llagentdata.cpp b/indra/newview/llagentdata.cpp index 5f6a082d75..d2c644a06f 100755 --- a/indra/newview/llagentdata.cpp +++ b/indra/newview/llagentdata.cpp @@ -31,3 +31,4 @@  LLUUID gAgentID;  LLUUID gAgentSessionID; +std::string gAgentUsername; diff --git a/indra/newview/llagentdata.h b/indra/newview/llagentdata.h index 83d6a53d5e..efdd97f6c4 100755 --- a/indra/newview/llagentdata.h +++ b/indra/newview/llagentdata.h @@ -30,5 +30,6 @@  extern LLUUID gAgentID;  extern LLUUID gAgentSessionID; +extern std::string gAgentUsername;  #endif diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 06b86e311a..cce1eb5895 100755 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -986,6 +986,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it  	S32 matched = 0, mismatched = 0;  	const S32 arr_size = LLWearableType::WT_COUNT;  	S32 type_counts[arr_size]; +	BOOL update_inventory = FALSE;  	std::fill(type_counts,type_counts+arr_size,0);  	for (S32 i = 0; i < count; i++)  	{ @@ -1013,10 +1014,9 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it  			continue;  		} -		// Don't care about this case - ordering of wearables with the same asset id has no effect. -		// Causes the two-alphas error case in MAINT-4158. +		// Update only inventory in this case - ordering of wearables with the same asset id has no effect. +		// Updating wearables in this case causes the two-alphas error in MAINT-4158.  		// We should actually disallow wearing two wearables with the same asset id. -#if 0  		if (curr_wearable->getName() != new_item->getName() ||  			curr_wearable->getItemID() != new_item->getUUID())  		{ @@ -1024,10 +1024,9 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it  								<< curr_wearable->getName() << " vs " << new_item->getName()  								<< " item ids " << curr_wearable->getItemID() << " vs " << new_item->getUUID()  								<< LL_ENDL; -			mismatched++; +			update_inventory = TRUE;  			continue;  		} -#endif  		// If we got here, everything matches.  		matched++;  	} @@ -1041,14 +1040,15 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it  			mismatched++;  		}  	} -	if (mismatched == 0) +	if (mismatched == 0 && !update_inventory)  	{  		LL_DEBUGS("Avatar") << "no changes, bailing out" << LL_ENDL;  		mCOFChangeInProgress = false;  		return;  	} -	 -	 + +	// updating inventory +  	// TODO: Removed check for ensuring that teens don't remove undershirt and underwear. Handle later  	// note: shirt is the first non-body part wearable item. Update if wearable order changes.  	// This loop should remove all clothing, but not any body parts @@ -1069,7 +1069,8 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it  		if (new_wearable)  		{  			const LLWearableType::EType type = new_wearable->getType(); -		 + +			LLUUID old_wearable_id = new_wearable->getItemID();  			new_wearable->setName(new_item->getName());  			new_wearable->setItemID(new_item->getUUID()); @@ -1077,11 +1078,18 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it  			{  				// exactly one wearable per body part  				setWearable(type,0,new_wearable); +				if (old_wearable_id.notNull()) +				{ +					// we changed id before setting wearable, update old item manually +					// to complete the swap. +					gInventory.addChangedMask(LLInventoryObserver::LABEL, old_wearable_id); +				}  			}  			else  			{  				pushWearable(type,new_wearable);  			} +  			const BOOL removed = FALSE;  			wearableUpdated(new_wearable, removed);  		} @@ -1089,6 +1097,15 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it  	gInventory.notifyObservers(); +	if (mismatched == 0) +	{ +		LL_DEBUGS("Avatar") << "inventory updated, wearable assets not changed, bailing out" << LL_ENDL; +		mCOFChangeInProgress = false; +		return; +	} + +	// updating agent avatar +  	if (isAgentAvatarValid())  	{  		gAgentAvatarp->setCompositeUpdatesEnabled(TRUE); diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index 9d887a61f1..714b456ae7 100755 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -315,7 +315,8 @@ SlamFolderCommand::SlamFolderCommand(const LLUUID& folder_id, const LLSD& conten  CopyLibraryCategoryCommand::CopyLibraryCategoryCommand(const LLUUID& source_id,  													   const LLUUID& dest_id, -													   LLPointer<LLInventoryCallback> callback): +													   LLPointer<LLInventoryCallback> callback, +													   bool copy_subfolders):  	AISCommand(callback)  {  	std::string cap; @@ -328,6 +329,10 @@ CopyLibraryCategoryCommand::CopyLibraryCategoryCommand(const LLUUID& source_id,  	LLUUID tid;  	tid.generate();  	std::string url = cap + std::string("/category/") + source_id.asString() + "?tid=" + tid.asString(); +	if (!copy_subfolders) +	{ +		url += ",depth=0"; +	}  	LL_INFOS() << url << LL_ENDL;  	LLCurl::ResponderPtr responder = this;  	LLSD headers; diff --git a/indra/newview/llaisapi.h b/indra/newview/llaisapi.h index 5a2ec94af9..bb483fb133 100755 --- a/indra/newview/llaisapi.h +++ b/indra/newview/llaisapi.h @@ -124,7 +124,7 @@ private:  class CopyLibraryCategoryCommand: public AISCommand  {  public: -	CopyLibraryCategoryCommand(const LLUUID& source_id, const LLUUID& dest_id, LLPointer<LLInventoryCallback> callback); +	CopyLibraryCategoryCommand(const LLUUID& source_id, const LLUUID& dest_id, LLPointer<LLInventoryCallback> callback, bool copy_subfolders = true);  protected:  	/* virtual */ bool getResponseUUID(const LLSD& content, LLUUID& id); diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 3be705dd95..142a3250c8 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -1786,9 +1786,15 @@ bool LLAppearanceMgr::getCanRemoveFromCOF(const LLUUID& outfit_cat_id)  	{  		return false;  	} - +	LLInventoryModel::cat_array_t cats; +	LLInventoryModel::item_array_t items;  	LLFindWearablesEx is_worn(/*is_worn=*/ true, /*include_body_parts=*/ false); -	return gInventory.hasMatchingDirectDescendent(outfit_cat_id, is_worn); +	gInventory.collectDescendentsIf(outfit_cat_id, +		cats, +		items, +		LLInventoryModel::EXCLUDE_TRASH, +		is_worn); +	return items.size() > 0;  }  // static @@ -1863,6 +1869,10 @@ bool LLAppearanceMgr::canAddWearables(const uuid_vec_t& item_ids)  		{  			++n_clothes;  		} +		else if (item->getType() == LLAssetType::AT_BODYPART) +		{ +			return isAgentAvatarValid(); +		}  		else  		{  			LL_WARNS() << "Unexpected wearable type" << LL_ENDL; @@ -2465,7 +2475,7 @@ void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool  		LLPointer<LLInventoryCallback> copy_cb = new LLWearCategoryAfterCopy(append);  		LLPointer<LLInventoryCallback> track_cb = new LLTrackPhaseWrapper(  													std::string("wear_inventory_category_callback"), copy_cb); -		LLPointer<AISCommand> cmd_ptr = new CopyLibraryCategoryCommand(category->getUUID(), parent_id, track_cb); +		LLPointer<AISCommand> cmd_ptr = new CopyLibraryCategoryCommand(category->getUUID(), parent_id, track_cb, false);  		ais_ran=cmd_ptr->run_command();  	} diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index a2aee2e000..fbf2a04bcc 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2784,10 +2784,12 @@ bool LLAppViewer::initConfiguration()  	//  	gWindowTitle = LLTrans::getString("APP_NAME");  #if LL_DEBUG -	gWindowTitle += std::string(" [DEBUG] ") + gArgs; -#else -	gWindowTitle += std::string(" ") + gArgs; +	gWindowTitle += std::string(" [DEBUG]")  #endif +	if (!gArgs.empty()) +	{ +		gWindowTitle += std::string(" ") + gArgs; +	}  	LLStringUtil::truncate(gWindowTitle, 255);  	//RN: if we received a URL, hand it off to the existing instance. @@ -3091,8 +3093,8 @@ void LLAppViewer::initUpdater()  	U32 check_period = gSavedSettings.getU32("UpdaterServiceCheckPeriod");  	bool willing_to_test;  	LL_DEBUGS("UpdaterService") << "channel " << channel << LL_ENDL; -	static const boost::regex is_test_channel("\\bTest$"); -	if (boost::regex_search(channel, is_test_channel))  + +	if (LLVersionInfo::TEST_VIEWER == LLVersionInfo::getViewerMaturity())   	{  		LL_INFOS("UpdaterService") << "Test build: overriding willing_to_test by sending testno" << LL_ENDL;  		willing_to_test = false; @@ -4948,6 +4950,7 @@ void LLAppViewer::idle()  		gIdleCallbacks.callFunctions();  		gInventory.idleNotifyObservers(); +		LLAvatarTracker::instance().idleNotifyObservers();  	}  	// Metrics logging (LLViewerAssetStats, etc.) diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index 56154a2de3..09227806fd 100755 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -62,9 +62,10 @@ namespace  	// They are not used immediately by the app.  	int gArgC;  	char** gArgV; -	LLAppViewerMacOSX* gViewerAppPtr; +	LLAppViewerMacOSX* gViewerAppPtr = NULL;      void (*gOldTerminateHandler)() = NULL; +    std::string gHandleSLURL;  }  static void exceptionTerminateHandler() @@ -107,7 +108,11 @@ bool initViewer()  	{  		LL_WARNS() << "Application init failed." << LL_ENDL;  	} - +    else if (!gHandleSLURL.empty()) +    { +        dispatchUrl(gHandleSLURL); +        gHandleSLURL = ""; +    }  	return ok;  } @@ -393,22 +398,31 @@ bool LLAppViewerMacOSX::getMasterSystemAudioMute()  void handleUrl(const char* url_utf8)  { -    if (url_utf8) +    if (url_utf8 && gViewerAppPtr)      { -        std::string url = url_utf8; -	    // Safari 3.2 silently mangles secondlife:///app/ URLs into -	    // secondlife:/app/ (only one leading slash). -	    // Fix them up to meet the URL specification. JC -	    const std::string prefix = "secondlife:/app/"; -	    std::string test_prefix = url.substr(0, prefix.length()); -	    LLStringUtil::toLower(test_prefix); -	    if (test_prefix == prefix) -	    { -		    url.replace(0, prefix.length(), "secondlife:///app/"); -	    } -		 -	    LLMediaCtrl* web = NULL; -    	const bool trusted_browser = false; -	    LLURLDispatcher::dispatch(url, "", web, trusted_browser); +        gHandleSLURL = ""; +        dispatchUrl(url_utf8);      } +    else if (url_utf8) +    { +        gHandleSLURL = url_utf8; +    } +} + +void dispatchUrl(std::string url) +{ +    // Safari 3.2 silently mangles secondlife:///app/ URLs into +    // secondlife:/app/ (only one leading slash). +    // Fix them up to meet the URL specification. JC +    const std::string prefix = "secondlife:/app/"; +    std::string test_prefix = url.substr(0, prefix.length()); +    LLStringUtil::toLower(test_prefix); +    if (test_prefix == prefix) +    { +        url.replace(0, prefix.length(), "secondlife:///app/"); +    } +     +    LLMediaCtrl* web = NULL; +    const bool trusted_browser = false; +    LLURLDispatcher::dispatch(url, "", web, trusted_browser);  } diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp index b6c5496c17..f79d1aa609 100755 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp @@ -97,7 +97,8 @@ static void on_avatar_name_cache_notify(const LLUUID& agent_id,  LLAvatarTracker::LLAvatarTracker() :  	mTrackingData(NULL),  	mTrackedAgentValid(false), -	mModifyMask(0x0)	 +	mModifyMask(0x0), +	mIsNotifyObservers(FALSE)  {  } @@ -272,7 +273,7 @@ S32 LLAvatarTracker::addBuddyList(const LLAvatarTracker::buddy_map_t& buds)  					<< "]" << LL_ENDL;  		}  	} -	notifyObservers(); +	// do not notify observers here - list can be large so let it be done on idle.  	return new_buddy_count;  } @@ -473,8 +474,25 @@ void LLAvatarTracker::removeObserver(LLFriendObserver* observer)  		mObservers.end());  } +void LLAvatarTracker::idleNotifyObservers() +{ +	if (mModifyMask == LLFriendObserver::NONE && mChangedBuddyIDs.size() == 0) +	{ +		return; +	} +	notifyObservers(); +} +  void LLAvatarTracker::notifyObservers()  { +	if (mIsNotifyObservers) +	{ +		// Don't allow multiple calls. +		// new masks and ids will be processed later from idle. +		return; +	} +	mIsNotifyObservers = TRUE; +  	observer_list_t observers(mObservers);  	observer_list_t::iterator it = observers.begin();  	observer_list_t::iterator end = observers.end(); @@ -490,6 +508,7 @@ void LLAvatarTracker::notifyObservers()  	mModifyMask = LLFriendObserver::NONE;  	mChangedBuddyIDs.clear(); +	mIsNotifyObservers = FALSE;  }  void LLAvatarTracker::addParticularFriendObserver(const LLUUID& buddy_id, LLFriendObserver* observer) @@ -531,7 +550,7 @@ void LLAvatarTracker::notifyParticularFriendObservers(const LLUUID& buddy_id)  // store flag for change  // and id of object change applies to  void LLAvatarTracker::addChangedMask(U32 mask, const LLUUID& referent) -{  +{  	mModifyMask |= mask;   	if (referent.notNull())  	{ diff --git a/indra/newview/llcallingcard.h b/indra/newview/llcallingcard.h index 6e5fc01cd8..1f819a42fd 100755 --- a/indra/newview/llcallingcard.h +++ b/indra/newview/llcallingcard.h @@ -143,6 +143,7 @@ public:  	// observers left behind.  	void addObserver(LLFriendObserver* observer);  	void removeObserver(LLFriendObserver* observer); +	void idleNotifyObservers();  	void notifyObservers();  	// Observers interested in updates of a particular avatar. @@ -209,6 +210,8 @@ private:  	LLAvatarTracker(const LLAvatarTracker&);  	bool operator==(const LLAvatarTracker&); +	BOOL mIsNotifyObservers; +  public:  	// don't you dare create or delete this object  	LLAvatarTracker(); diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index f0bd63ba46..dc0835eb1c 100755 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -376,6 +376,10 @@ public:  			|| mSourceType == CHAT_SOURCE_SYSTEM)  		{  			mFrom = LLTrans::getString("SECOND_LIFE"); +			if(!chat.mFromName.empty() && (mFrom != chat.mFromName)) +			{ +				mFrom += " (" + chat.mFromName + ")"; +			}  			user_name->setValue(mFrom);  			updateMinUserNameWidth();  		} @@ -934,7 +938,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL  	// compact mode: show a timestamp and name  	if (use_plain_text_chat_history)  	{ -		square_brackets = chat.mFromName == SYSTEM_FROM; +		square_brackets = chat.mSourceType == CHAT_SOURCE_SYSTEM;  		LLStyle::Params timestamp_style(body_message_params); diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h index b38d472156..62f08144b9 100755 --- a/indra/newview/llconversationlog.h +++ b/indra/newview/llconversationlog.h @@ -153,6 +153,7 @@ public:  	 * file name is conversation.log  	 */  	std::string getFileName(); +	LLConversation* findConversation(const LLIMModel::LLIMSession* session);  private: @@ -184,7 +185,7 @@ private:  	void updateConversationName(const LLIMModel::LLIMSession* session, const std::string& name);  	void updateOfflineIMs(const LLIMModel::LLIMSession* session, BOOL new_messages); -	LLConversation* findConversation(const LLIMModel::LLIMSession* session); +  	typedef std::vector<LLConversation> conversations_vec_t;  	std::vector<LLConversation>				mConversations; diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp index 6e32ce60ec..328a638f2f 100755 --- a/indra/newview/llconversationmodel.cpp +++ b/indra/newview/llconversationmodel.cpp @@ -136,7 +136,24 @@ void LLConversationItem::buildParticipantMenuOptions(menuentry_vec_t& items, U32  		items.push_back(std::string("im"));  		items.push_back(std::string("offer_teleport"));  		items.push_back(std::string("request_teleport")); -		items.push_back(std::string("voice_call")); + +		if (getType() != CONV_SESSION_1_ON_1) +		{ +			items.push_back(std::string("voice_call")); +		} +		else +		{ +			LLVoiceChannel* voice_channel = LLIMModel::getInstance() ? LLIMModel::getInstance()->getVoiceChannel(this->getUUID()) : NULL; +			if(voice_channel != LLVoiceChannel::getCurrentVoiceChannel()) +			{ +				items.push_back(std::string("voice_call")); +			} +			else +			{ +				items.push_back(std::string("disconnect_from_voice")); +			} +		} +  		items.push_back(std::string("chat_history"));  		items.push_back(std::string("separator_chat_history"));  		items.push_back(std::string("add_friend")); diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index e1d3d1a905..821d58a9b2 100755 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1797,9 +1797,12 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)  			if (mat)  			{ -				gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture(LLRender::DIFFUSE_MAP)); -				gGL.getTexUnit(normal_channel)->bind(face->getTexture(LLRender::NORMAL_MAP)); +				//order is important here LLRender::DIFFUSE_MAP should be last, becouse it change  +				//(gGL).mCurrTextureUnitIndex  				gGL.getTexUnit(specular_channel)->bind(face->getTexture(LLRender::SPECULAR_MAP)); +				gGL.getTexUnit(normal_channel)->bind(face->getTexture(LLRender::NORMAL_MAP)); +				gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture(LLRender::DIFFUSE_MAP), false, true); +  				LLColor4 col = mat->getSpecularLightColor();  				F32 spec = mat->getSpecularLightExponent()/255.f; diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 33f7bc305c..7b9fd5c6c6 100755 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -864,6 +864,7 @@ void LLDrawPoolBump::renderDeferred(S32 pass)  	{  		LLDrawInfo& params = **i; +		gDeferredBumpProgram.setMinimumAlpha(params.mAlphaMaskCutoff);  		LLDrawPoolBump::bindBumpMap(params, bump_channel);  		pushBatch(params, mask, TRUE);  	} diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index fc9e85caf8..8f3eaaa207 100755 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -380,9 +380,11 @@ LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p)  	mShowDragMarker(FALSE),  	mLandingTab(NULL),  	mLastTab(NULL), -	mTabsHighlightEnabled(TRUE) -  , mUpdateDropDownItems(true) -,	mRestoreOverflowMenu(false) +	mTabsHighlightEnabled(TRUE), +	mUpdateDropDownItems(true), +	mRestoreOverflowMenu(false), +	mGetPrevItems(true), +	mItemsChangedTimer()  {  	// Register callback for menus with current registrar (will be parent panel's registrar)  	LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Favorites.DoToSelected", @@ -659,6 +661,15 @@ void LLFavoritesBarCtrl::changed(U32 mask)  			LLFavoritesOrderStorage::instance().getSLURL((*i)->getAssetUUID());  		}  		updateButtons(); +		if (!mItemsChangedTimer.getStarted()) +		{ +			mItemsChangedTimer.start(); +		} +		else +		{ +			mItemsChangedTimer.reset(); +		} +  	}  } @@ -693,6 +704,21 @@ void LLFavoritesBarCtrl::draw()  		// Once drawn, mark this false so we won't draw it again (unless we hit the favorite bar again)  		mShowDragMarker = FALSE;  	} +	if (mItemsChangedTimer.getStarted()) +	{ +		if (mItemsChangedTimer.getElapsedTimeF32() > 1.f) +		{ +			LLFavoritesOrderStorage::instance().saveFavoritesRecord(); +			mItemsChangedTimer.stop(); +		} +	} + +	if(!mItemsChangedTimer.getStarted() && LLFavoritesOrderStorage::instance().mUpdateRequired) +	{ +		LLFavoritesOrderStorage::instance().mUpdateRequired = false; +		mItemsChangedTimer.start(); +	} +  }  const LLButton::Params& LLFavoritesBarCtrl::getButtonParams() @@ -723,6 +749,12 @@ void LLFavoritesBarCtrl::updateButtons()  		return;  	} +	if(mGetPrevItems) +	{ +		LLFavoritesOrderStorage::instance().mPrevFavorites = mItems; +		mGetPrevItems = false; +	} +  	const LLButton::Params& button_params = getButtonParams();  	if(mItems.empty()) @@ -844,6 +876,7 @@ void LLFavoritesBarCtrl::updateButtons()  	{  		mUpdateDropDownItems = false;  	} +  }  LLButton* LLFavoritesBarCtrl::createButton(const LLPointer<LLViewerInventoryItem> item, const LLButton::Params& button_params, S32 x_offset) @@ -912,9 +945,11 @@ BOOL LLFavoritesBarCtrl::postBuild()  BOOL LLFavoritesBarCtrl::collectFavoriteItems(LLInventoryModel::item_array_t &items)  { +  	if (mFavoriteFolderId.isNull())  		return FALSE; +  	LLInventoryModel::cat_array_t cats;  	LLIsType is_type(LLAssetType::AT_LANDMARK); @@ -1411,6 +1446,7 @@ void LLFavoritesBarCtrl::insertItem(LLInventoryModel::item_array_t& items, const  const std::string LLFavoritesOrderStorage::SORTING_DATA_FILE_NAME = "landmarks_sorting.xml";  const S32 LLFavoritesOrderStorage::NO_INDEX = -1; +bool LLFavoritesOrderStorage::mSaveOnExit = false;  void LLFavoritesOrderStorage::setSortIndex(const LLViewerInventoryItem* inv_item, S32 sort_index)  { @@ -1447,6 +1483,7 @@ void LLFavoritesOrderStorage::getSLURL(const LLUUID& asset_id)          LL_DEBUGS("FavoritesBar") << "landmark for " << asset_id << " already loaded" << LL_ENDL;  		onLandmarkLoaded(asset_id, lm);  	} +	return;  }  // static @@ -1482,13 +1519,16 @@ void LLFavoritesOrderStorage::destroyClass()  		LLFile::remove(old_filename);  	} -	if (gSavedPerAccountSettings.getBOOL("ShowFavoritesOnLogin")) -	{ -		LLFavoritesOrderStorage::instance().saveFavoritesSLURLs(); -	} -	else +	std::string filename = getSavedOrderFileName(); +	file.open(filename.c_str()); +	if (file.is_open())  	{ -		LLFavoritesOrderStorage::instance().removeFavoritesRecordOfUser(); +		file.close(); +		LLFile::remove(filename); +		if(mSaveOnExit) +		{ +			LLFavoritesOrderStorage::instance().saveFavoritesRecord(true); +		}  	}  } @@ -1503,108 +1543,57 @@ std::string LLFavoritesOrderStorage::getSavedOrderFileName()  void LLFavoritesOrderStorage::load()  { -	// load per-resident sorting information  	std::string filename = getSavedOrderFileName(); -  	LLSD settings_llsd;  	llifstream file;  	file.open(filename.c_str());  	if (file.is_open())  	{  		LLSDSerialize::fromXML(settings_llsd, file); -        LL_INFOS("FavoritesBar") << "loaded favorites order from '" << filename << "' " -                                 << (settings_llsd.isMap() ? "" : "un") << "successfully" -                                 << LL_ENDL; -        file.close(); -	} -    else -    { -        LL_WARNS("FavoritesBar") << "unable to open favorites order file at '" << filename << "'" << LL_ENDL; -    } - -	for (LLSD::map_const_iterator iter = settings_llsd.beginMap(); -		iter != settings_llsd.endMap(); ++iter) -	{ -		mSortIndexes.insert(std::make_pair(LLUUID(iter->first), (S32)iter->second.asInteger())); +		LL_INFOS("FavoritesBar") << "loaded favorites order from '" << filename << "' " +	                                 << (settings_llsd.isMap() ? "" : "un") << "successfully" +	                                 << LL_ENDL; +		file.close(); +		mSaveOnExit = true; + +		for (LLSD::map_const_iterator iter = settings_llsd.beginMap(); +			iter != settings_llsd.endMap(); ++iter) +		{ +			mSortIndexes.insert(std::make_pair(LLUUID(iter->first), (S32)iter->second.asInteger())); +		}  	} -} - -void LLFavoritesOrderStorage::saveFavoritesSLURLs() -{ -	// Do not change the file if we are not logged in yet. -	if (!LLLoginInstance::getInstance()->authSuccess()) +	else  	{ -		LL_WARNS("FavoritesBar") << "Cannot save favorites: not logged in" << LL_ENDL; -		return; +		filename = getStoredFavoritesFilename(); +		if (!filename.empty()) +		{ +			llifstream in_file; +			in_file.open(filename.c_str()); +			LLSD fav_llsd; +			LLSD user_llsd; +			if (in_file.is_open()) +			{ +				LLSDSerialize::fromXML(fav_llsd, in_file); +				LL_INFOS("FavoritesBar") << "loaded favorites from '" << filename << "' " +												<< (fav_llsd.isMap() ? "" : "un") << "successfully" +												<< LL_ENDL; +				in_file.close(); +				user_llsd = fav_llsd[gAgentUsername]; + +				S32 index = 0; +				for (LLSD::array_iterator iter = user_llsd.beginArray(); +						iter != user_llsd.endArray(); ++iter) +				{ +					mSortIndexes.insert(std::make_pair(iter->get("id").asUUID(), index)); +					index++; +				} +			} +			else +			{ +				LL_WARNS("FavoritesBar") << "unable to open favorites from '" << filename << "'" << LL_ENDL; +			} +		}  	} - -	std::string filename = getStoredFavoritesFilename(); -    if (!filename.empty()) -    { -        llifstream in_file; -        in_file.open(filename.c_str()); -        LLSD fav_llsd; -        if (in_file.is_open()) -        { -            LLSDSerialize::fromXML(fav_llsd, in_file); -            LL_INFOS("FavoritesBar") << "loaded favorites from '" << filename << "' " -                                     << (fav_llsd.isMap() ? "" : "un") << "successfully" -                                     << LL_ENDL; -            in_file.close(); -        } -        else -        { -            LL_WARNS("FavoritesBar") << "unable to open favorites from '" << filename << "'" << LL_ENDL; -        } - -        const LLUUID fav_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE); -        LLInventoryModel::cat_array_t cats; -        LLInventoryModel::item_array_t items; -        gInventory.collectDescendents(fav_id, cats, items, LLInventoryModel::EXCLUDE_TRASH); - -        LLSD user_llsd; -        for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); it++) -        { -            LLSD value; -            value["name"] = (*it)->getName(); -            value["asset_id"] = (*it)->getAssetUUID(); - -            slurls_map_t::iterator slurl_iter = mSLURLs.find(value["asset_id"]); -            if (slurl_iter != mSLURLs.end()) -            { -                LL_DEBUGS("FavoritesBar") << "Saving favorite: idx=" << LLFavoritesOrderStorage::instance().getSortIndex((*it)->getUUID()) << ", SLURL=" <<  slurl_iter->second << ", value=" << value << LL_ENDL; -                value["slurl"] = slurl_iter->second; -                user_llsd[LLFavoritesOrderStorage::instance().getSortIndex((*it)->getUUID())] = value; -            } -            else -            { -                LL_WARNS("FavoritesBar") << "Not saving favorite " << value["name"] << ": no matching SLURL" << LL_ENDL; -            } -        } - -        LLAvatarName av_name; -        LLAvatarNameCache::get( gAgentID, &av_name ); -        // Note : use the "John Doe" and not the "john.doe" version of the name  -        // as we'll compare it with the stored credentials in the login panel. -        fav_llsd[av_name.getUserName()] = user_llsd; - -        llofstream file; -        file.open(filename.c_str()); -        if ( file.is_open() ) -        { -            LLSDSerialize::toPrettyXML(fav_llsd, file); -            LL_INFOS("FavoritesBar") << "saved favorites for '" << av_name.getUserName() -                                     << "' to '" << filename << "' " -                                     << LL_ENDL; -            file.close(); -        } -        else -        { -            LL_WARNS("FavoritesBar") << "unable to open favorites storage for '" << av_name.getUserName() -                                     << "' at '" << filename << "' " -                                     << LL_ENDL; -        } -    }  }  void LLFavoritesOrderStorage::removeFavoritesRecordOfUser() @@ -1626,8 +1615,30 @@ void LLFavoritesOrderStorage::removeFavoritesRecordOfUser()              // See saveFavoritesSLURLs() here above for the reason why.              if (fav_llsd.has(av_name.getUserName()))              { -                LL_INFOS("FavoritesBar") << "Removed favorites for " << av_name.getUserName() << LL_ENDL; -                fav_llsd.erase(av_name.getUserName()); +            	LLSD user_llsd = fav_llsd[av_name.getUserName()]; + +            	if (user_llsd.beginArray()->has("id")) +            	{ +            		for (LLSD::array_iterator iter = user_llsd.beginArray();iter != user_llsd.endArray(); ++iter) +            		{ +            			LLSD value; +            			value["id"]= iter->get("id").asUUID(); +            			iter->assign(value); +            		} +            		fav_llsd[av_name.getUserName()] = user_llsd; +            		llofstream file; +            		file.open(filename.c_str()); +            		if ( file.is_open() ) +            		{ +            				LLSDSerialize::toPrettyXML(fav_llsd, file); +            				file.close(); +            		} +            	} +            	else +            	{ +            		LL_INFOS("FavoritesBar") << "Removed favorites for " << av_name.getUserName() << LL_ENDL; +            		fav_llsd.erase(av_name.getUserName()); +            	}              }              llofstream out_file; @@ -1648,20 +1659,20 @@ void LLFavoritesOrderStorage::onLandmarkLoaded(const LLUUID& asset_id, LLLandmar  	if (landmark)      {          LL_DEBUGS("FavoritesBar") << "landmark for " << asset_id << " loaded" << LL_ENDL; -	LLVector3d pos_global; -	if (!landmark->getGlobalPos(pos_global)) -	{ -		// If global position was unknown on first getGlobalPos() call -		// it should be set for the subsequent calls. -		landmark->getGlobalPos(pos_global); -	} +        LLVector3d pos_global; +        if (!landmark->getGlobalPos(pos_global)) +        { +        	// If global position was unknown on first getGlobalPos() call +        	// it should be set for the subsequent calls. +        	landmark->getGlobalPos(pos_global); +        } -	if (!pos_global.isExactlyZero()) -	{ -        LL_DEBUGS("FavoritesBar") << "requesting slurl for landmark " << asset_id << LL_ENDL; -		LLLandmarkActions::getSLURLfromPosGlobal(pos_global, +        if (!pos_global.isExactlyZero()) +        { +        	LL_DEBUGS("FavoritesBar") << "requesting slurl for landmark " << asset_id << LL_ENDL; +        	LLLandmarkActions::getSLURLfromPosGlobal(pos_global,  			boost::bind(&LLFavoritesOrderStorage::storeFavoriteSLURL, this, asset_id, _1)); -	} +        }      }  } @@ -1671,41 +1682,6 @@ void LLFavoritesOrderStorage::storeFavoriteSLURL(const LLUUID& asset_id, std::st  	mSLURLs[asset_id] = slurl;  } -void LLFavoritesOrderStorage::save() -{ -	if (mIsDirty) -    { -        // something changed, so save it -        std::string filename = LLFavoritesOrderStorage::getInstance()->getSavedOrderFileName(); -        if (!filename.empty()) -        { -            LLSD settings_llsd; - -            for(sort_index_map_t::const_iterator iter = mSortIndexes.begin(); iter != mSortIndexes.end(); ++iter) -            { -                settings_llsd[iter->first.asString()] = iter->second; -            } - -            llofstream file; -            file.open(filename.c_str()); -            if ( file.is_open() ) -            { -                LLSDSerialize::toPrettyXML(settings_llsd, file); -                LL_INFOS("FavoritesBar") << "saved favorites order to '" << filename << "' " << LL_ENDL; -            } -            else -            { -                LL_WARNS("FavoritesBar") << "failed to open favorites order file '" << filename << "' " << LL_ENDL; -            } -        } -        else -        { -            LL_DEBUGS("FavoritesBar") << "no user directory available to store favorites order file" << LL_ENDL; -        } -    } -} - -  void LLFavoritesOrderStorage::cleanup()  {  	// nothing to clean @@ -1720,7 +1696,7 @@ void LLFavoritesOrderStorage::cleanup()  	sort_index_map_t  aTempMap;  	//copy unremoved values from mSortIndexes to aTempMap -	std::remove_copy_if(mSortIndexes.begin(), mSortIndexes.end(),  +	std::remove_copy_if(mSortIndexes.begin(), mSortIndexes.end(),  		inserter(aTempMap, aTempMap.begin()),  		is_not_in_fav); @@ -1728,6 +1704,17 @@ void LLFavoritesOrderStorage::cleanup()  	mSortIndexes.swap(aTempMap);  } +// See also LLInventorySort where landmarks in the Favorites folder are sorted. +class LLViewerInventoryItemSort +{ +public: +	bool operator()(const LLPointer<LLViewerInventoryItem>& a, const LLPointer<LLViewerInventoryItem>& b) +	{ +		return LLFavoritesOrderStorage::instance().getSortIndex(a->getUUID()) +			< LLFavoritesOrderStorage::instance().getSortIndex(b->getUUID()); +	} +}; +  void LLFavoritesOrderStorage::saveOrder()  {  	LLInventoryModel::cat_array_t cats; @@ -1735,13 +1722,14 @@ void LLFavoritesOrderStorage::saveOrder()  	LLIsType is_type(LLAssetType::AT_LANDMARK);  	LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);  	gInventory.collectDescendentsIf(favorites_id, cats, items, LLInventoryModel::EXCLUDE_TRASH, is_type); +	std::sort(items.begin(), items.end(), LLViewerInventoryItemSort());  	saveItemsOrder(items);  }  void LLFavoritesOrderStorage::saveItemsOrder( const LLInventoryModel::item_array_t& items )  { -	int sortField = 0; +	int sortField = 0;  	// current order is saved by setting incremental values (1, 2, 3, ...) for the sort field  	for (LLInventoryModel::item_array_t::const_iterator i = items.begin(); i != items.end(); ++i)  	{ @@ -1760,16 +1748,7 @@ void LLFavoritesOrderStorage::saveItemsOrder( const LLInventoryModel::item_array  	gInventory.notifyObservers();  } -// See also LLInventorySort where landmarks in the Favorites folder are sorted. -class LLViewerInventoryItemSort -{ -public: -	bool operator()(const LLPointer<LLViewerInventoryItem>& a, const LLPointer<LLViewerInventoryItem>& b) -	{ -		return LLFavoritesOrderStorage::instance().getSortIndex(a->getUUID())  -			< LLFavoritesOrderStorage::instance().getSortIndex(b->getUUID()); -	} -}; +  // * @param source_item_id - LLUUID of the source item to be moved into new position  // * @param target_item_id - LLUUID of the target item before which source item should be placed. @@ -1790,6 +1769,110 @@ void LLFavoritesOrderStorage::rearrangeFavoriteLandmarks(const LLUUID& source_it  	saveItemsOrder(items);  } +BOOL LLFavoritesOrderStorage::saveFavoritesRecord(bool pref_changed) +{ + +	LLUUID favorite_folder= gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE); +	if (favorite_folder.isNull()) +			return FALSE; + +	LLInventoryModel::item_array_t items; +	LLInventoryModel::cat_array_t cats; + +	LLIsType is_type(LLAssetType::AT_LANDMARK); +	gInventory.collectDescendentsIf(favorite_folder, cats, items, LLInventoryModel::EXCLUDE_TRASH, is_type); + +	std::sort(items.begin(), items.end(), LLFavoritesSort()); + +	if((items != mPrevFavorites) || pref_changed) +	{ +		std::string filename = getStoredFavoritesFilename(); +		if (!filename.empty()) +		{ +			llifstream in_file; +			in_file.open(filename.c_str()); +			LLSD fav_llsd; +			if (in_file.is_open()) +			{ +				LLSDSerialize::fromXML(fav_llsd, in_file); +				in_file.close(); +			} +			else +			{ +				LL_WARNS("FavoritesBar") << "unable to open favorites from '" << filename << "'" << LL_ENDL; +			} + +			LLSD user_llsd; +			S32 fav_iter = 0; +			for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); it++) +			{ +				LLSD value; +				if (gSavedPerAccountSettings.getBOOL("ShowFavoritesOnLogin")) +				{ +					value["name"] = (*it)->getName(); +					value["asset_id"] = (*it)->getAssetUUID(); +					value["id"] = (*it)->getUUID(); +					slurls_map_t::iterator slurl_iter = mSLURLs.find(value["asset_id"]); +					if (slurl_iter != mSLURLs.end()) +					{ +						value["slurl"] = slurl_iter->second; +						user_llsd[fav_iter] = value; +					} +					else +					{ +						getSLURL((*it)->getAssetUUID()); +						mUpdateRequired = true; +						return FALSE; +					} +				} +				else +				{ +					value["id"] = (*it)->getUUID(); +					user_llsd[fav_iter] = value; +				} + +				fav_iter ++; +			} + +			LLAvatarName av_name; +			LLAvatarNameCache::get( gAgentID, &av_name ); +			// Note : use the "John Doe" and not the "john.doe" version of the name +			// as we'll compare it with the stored credentials in the login panel. +			fav_llsd[av_name.getUserName()] = user_llsd; +			llofstream file; +			file.open(filename.c_str()); +			if ( file.is_open() ) +			{ +				LLSDSerialize::toPrettyXML(fav_llsd, file); +				file.close(); +				mSaveOnExit = false; +			} +			else +			{ +				LL_WARNS("FavoritesBar") << "unable to open favorites storage for '" << av_name.getUserName() +												<< "' at '" << filename << "' " << LL_ENDL; +			} +		} + +		mPrevFavorites = items; +	} + +	return TRUE; + +} + +void LLFavoritesOrderStorage::showFavoritesOnLoginChanged(BOOL show) +{ +	if (show) +	{ +		saveFavoritesRecord(true); +	} +	else +	{ +		removeFavoritesRecordOfUser(); +	} +} +  void AddFavoriteLandmarkCallback::fire(const LLUUID& inv_item_id)  {  	if (mTargetLandmarkId.isNull()) return; diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h index a370724947..66fc8b2ae7 100755 --- a/indra/newview/llfavoritesbar.h +++ b/indra/newview/llfavoritesbar.h @@ -105,8 +105,10 @@ protected:  	bool mUpdateDropDownItems;  	bool mRestoreOverflowMenu; -	LLUUID mSelectedItemID; +	bool mGetPrevItems; +	LLUUID mSelectedItemID; +	LLFrameTimer mItemsChangedTimer;  	LLUIImage* mImageDragIndication;  private: @@ -204,12 +206,23 @@ public:  	 * @see cleanup()  	 */  	static void destroyClass(); +	static std::string getStoredFavoritesFilename(); +	static std::string getSavedOrderFileName(); + +	BOOL saveFavoritesRecord(bool pref_changed = false); +	void showFavoritesOnLoginChanged(BOOL show); + +	LLInventoryModel::item_array_t mPrevFavorites; +  	const static S32 NO_INDEX; +	static bool mSaveOnExit; +	bool mUpdateRequired; +  private:  	friend class LLSingleton<LLFavoritesOrderStorage>; -	LLFavoritesOrderStorage() : mIsDirty(false) { load(); } -	~LLFavoritesOrderStorage() { save(); } +	LLFavoritesOrderStorage() : mIsDirty(false), mUpdateRequired(false){ load(); } +	~LLFavoritesOrderStorage() {}  	/**  	 * Removes sort indexes for items which are not in Favorites bar for now. @@ -217,13 +230,8 @@ private:  	void cleanup();  	const static std::string SORTING_DATA_FILE_NAME; -    std::string getSavedOrderFileName(); -    static std::string getStoredFavoritesFilename(); -     -	void load(); -	void save(); -	void saveFavoritesSLURLs(); +	void load();  	// Remove record of current user's favorites from file on disk.  	void removeFavoritesRecordOfUser(); diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index b342d8fdf3..c5d637d1fc 100755 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -34,10 +34,12 @@  // Viewer includes  #include "llagent.h"  #include "llagentui.h" -#include "llappviewer.h"  +#include "llappviewer.h" +#include "llnotificationsutil.h"  #include "llslurl.h"  #include "llvoiceclient.h"  #include "lluictrlfactory.h" +#include "llupdaterservice.h"  #include "llviewertexteditor.h"  #include "llviewercontrol.h"  #include "llviewerstats.h" @@ -99,9 +101,23 @@ public:  	/// separated so that we can programmatically access the same info.  	static LLSD getInfo();  	void onClickCopyToClipboard(); +	void onClickUpdateCheck(); + +	// checks state of updater service and starts a check outside of schedule. +	// subscribes callback for closest state update +	static void setUpdateListener();  private:  	void setSupportText(const std::string& server_release_notes_url); + +	// notifications for user requested checks +	static void showCheckUpdateNotification(S32 state); + +	// callback method for manual checks +	static bool callbackCheckUpdate(LLSD const & event); + +	// listener name for update checks +	static const std::string sCheckUpdateListenerName;  }; @@ -132,6 +148,9 @@ BOOL LLFloaterAbout::postBuild()  	getChild<LLUICtrl>("copy_btn")->setCommitCallback(  		boost::bind(&LLFloaterAbout::onClickCopyToClipboard, this)); +	getChild<LLUICtrl>("update_btn")->setCommitCallback( +		boost::bind(&LLFloaterAbout::onClickUpdateCheck, this)); +  	static const LLUIColor about_color = LLUIColorTable::instance().getColor("TextFgReadOnlyColor");  	if (gAgent.getRegion()) @@ -235,6 +254,11 @@ void LLFloaterAbout::onClickCopyToClipboard()  	support_widget->deselect();  } +void LLFloaterAbout::onClickUpdateCheck() +{ +	setUpdateListener(); +} +  void LLFloaterAbout::setSupportText(const std::string& server_release_notes_url)  {  #if LL_WINDOWS @@ -256,6 +280,68 @@ void LLFloaterAbout::setSupportText(const std::string& server_release_notes_url)  }  ///---------------------------------------------------------------------------- +/// Floater About Update-check related functions +///---------------------------------------------------------------------------- + +const std::string LLFloaterAbout::sCheckUpdateListenerName = "LLUpdateNotificationListener"; + +void LLFloaterAbout::showCheckUpdateNotification(S32 state) +{ +	switch (state) +	{ +	case LLUpdaterService::UP_TO_DATE: +		LLNotificationsUtil::add("UpdateViewerUpToDate"); +		break; +	case LLUpdaterService::DOWNLOADING: +	case LLUpdaterService::INSTALLING: +		LLNotificationsUtil::add("UpdateDownloadInProgress"); +		break; +	case LLUpdaterService::TERMINAL: +		// download complete, user triggered check after download pop-up appeared +		LLNotificationsUtil::add("UpdateDownloadComplete"); +		break; +	default: +		LLNotificationsUtil::add("UpdateCheckError"); +		break; +	} +} + +bool LLFloaterAbout::callbackCheckUpdate(LLSD const & event) +{ +	if (!event.has("payload")) +	{ +		return false; +	} + +	LLSD payload = event["payload"]; +	if (payload.has("type") && payload["type"].asInteger() == LLUpdaterService::STATE_CHANGE) +	{ +		LLEventPumps::instance().obtain("mainlooprepeater").stopListening(sCheckUpdateListenerName); +		showCheckUpdateNotification(payload["state"].asInteger()); +	} +	return false; +} + +void LLFloaterAbout::setUpdateListener() +{ +	LLUpdaterService update_service; +	S32 service_state = update_service.getState(); +	// Note: Do not set state listener before forceCheck() since it set's new state +	if (update_service.forceCheck() || service_state == LLUpdaterService::CHECKING_FOR_UPDATE) +	{ +		LLEventPump& mainloop(LLEventPumps::instance().obtain("mainlooprepeater")); +		if (mainloop.getListener(sCheckUpdateListenerName) == LLBoundListener()) // dummy listener +		{ +			mainloop.listen(sCheckUpdateListenerName, boost::bind(&callbackCheckUpdate, _1)); +		} +	} +	else +	{ +		showCheckUpdateNotification(service_state); +	} +} + +///----------------------------------------------------------------------------  /// LLFloaterAboutUtil  ///----------------------------------------------------------------------------  void LLFloaterAboutUtil::registerFloater() @@ -265,6 +351,11 @@ void LLFloaterAboutUtil::registerFloater()  } +void LLFloaterAboutUtil::checkUpdatesAndNotify() +{ +	LLFloaterAbout::setUpdateListener(); +} +  ///----------------------------------------------------------------------------  /// Class LLServerReleaseNotesURLFetcher implementation  ///---------------------------------------------------------------------------- @@ -289,15 +380,11 @@ void LLServerReleaseNotesURLFetcher::httpCompleted()  	LL_DEBUGS("ServerReleaseNotes") << dumpResponse()   									<< " [headers:" << getResponseHeaders() << "]" << LL_ENDL; -	LLFloaterAbout* floater_about = LLFloaterReg::getTypedInstance<LLFloaterAbout>("sl_about"); -	if (floater_about) +	std::string location = getResponseHeader(HTTP_IN_HEADER_LOCATION); +	if (location.empty())  	{ -		std::string location = getResponseHeader(HTTP_IN_HEADER_LOCATION); -		if (location.empty()) -		{ -			location = LLTrans::getString("ErrorFetchingServerReleaseNotesURL"); -		} -		LLAppViewer::instance()->setServerReleaseNotesURL(location); +		location = LLTrans::getString("ErrorFetchingServerReleaseNotesURL");  	} +	LLAppViewer::instance()->setServerReleaseNotesURL(location);  } diff --git a/indra/newview/llfloaterabout.h b/indra/newview/llfloaterabout.h index 8fc1aa4f29..be34b631cc 100755 --- a/indra/newview/llfloaterabout.h +++ b/indra/newview/llfloaterabout.h @@ -30,6 +30,9 @@  namespace LLFloaterAboutUtil  {  	void registerFloater(); + +	// Support for user initialized update/state checks +	void checkUpdatesAndNotify();  }  #endif // LL_LLFLOATERABOUT_H diff --git a/indra/newview/llfloaterbump.cpp b/indra/newview/llfloaterbump.cpp index 34904cf7ed..957c91b226 100755 --- a/indra/newview/llfloaterbump.cpp +++ b/indra/newview/llfloaterbump.cpp @@ -32,6 +32,7 @@  #include "llavataractions.h"  #include "llfloaterbump.h" +#include "llfloaterreg.h"  #include "llfloaterreporter.h"  #include "llmutelist.h"  #include "llpanelblockedlist.h" @@ -87,11 +88,11 @@ BOOL LLFloaterBump::postBuild()  // virtual  void LLFloaterBump::onOpen(const LLSD& key)  { -	mNames.clear(); -	mList->deleteAllItems(); -  	if (gMeanCollisionList.empty())  	{ +		mNames.clear(); +		mList->deleteAllItems(); +  		std::string none_detected = getString("none_detected");  		LLSD row;  		row["columns"][0]["value"] = none_detected; @@ -100,12 +101,20 @@ void LLFloaterBump::onOpen(const LLSD& key)  	}  	else  	{ -		for (mean_collision_list_t::iterator iter = gMeanCollisionList.begin(); -			 iter != gMeanCollisionList.end(); ++iter) -		{ -			LLMeanCollisionData *mcd = *iter; -			add(mList, mcd); -		} +		populateCollisionList(); +	} +} + +void LLFloaterBump::populateCollisionList() +{ +	mNames.clear(); +	mList->deleteAllItems(); + +	for (mean_collision_list_t::iterator iter = gMeanCollisionList.begin(); +				 iter != gMeanCollisionList.end(); ++iter) +	{ +		LLMeanCollisionData *mcd = *iter; +		add(mList, mcd);  	}  } @@ -247,3 +256,8 @@ void LLFloaterBump::inviteToGroup()  {  	LLAvatarActions::inviteToGroup(mItemUUID);  } + +LLFloaterBump* LLFloaterBump::getInstance() +{ +	return LLFloaterReg::getTypedInstance<LLFloaterBump>("bumps"); +} diff --git a/indra/newview/llfloaterbump.h b/indra/newview/llfloaterbump.h index 11b7db9fee..ce52c75255 100755 --- a/indra/newview/llfloaterbump.h +++ b/indra/newview/llfloaterbump.h @@ -46,6 +46,10 @@ public:  	/*virtual*/	BOOL postBuild();  	/*virtual*/ void onOpen(const LLSD& key); +	static LLFloaterBump* getInstance(); + +	void populateCollisionList(); +  	void startIM();  	void startCall();  	void reportAbuse(); diff --git a/indra/newview/llfloaterfacebook.cpp b/indra/newview/llfloaterfacebook.cpp index 3a2047cfef..da85d378b2 100644 --- a/indra/newview/llfloaterfacebook.cpp +++ b/indra/newview/llfloaterfacebook.cpp @@ -64,9 +64,9 @@ const std::string DEFAULT_CHECKIN_ICON_URL = "http://map.secondlife.com.s3.amazo  const std::string DEFAULT_CHECKIN_QUERY_PARAMETERS = "?sourceid=slshare_checkin&utm_source=facebook&utm_medium=checkin&utm_campaign=slshare";  const std::string DEFAULT_PHOTO_QUERY_PARAMETERS = "?sourceid=slshare_photo&utm_source=facebook&utm_medium=photo&utm_campaign=slshare"; -const S32 MAX_QUALITY = 100;        // Max quality value for jpeg images -const S32 MIN_QUALITY = 0;          // Min quality value for jpeg images -const S32 TARGET_DATA_SIZE = 95000; // Size of the image (compressed) we're trying to send to Facebook +const S32 MAX_QUALITY = 100;         // Max quality value for jpeg images +const S32 MIN_QUALITY = 0;           // Min quality value for jpeg images +const S32 TARGET_DATA_SIZE = 950000; // Size of the image (compressed) we're trying to send to Facebook  std::string get_map_url()  { diff --git a/indra/newview/llfloaterhardwaresettings.cpp b/indra/newview/llfloaterhardwaresettings.cpp index 035eb307c2..62d7efc8b2 100755 --- a/indra/newview/llfloaterhardwaresettings.cpp +++ b/indra/newview/llfloaterhardwaresettings.cpp @@ -82,6 +82,7 @@ void LLFloaterHardwareSettings::refresh()  	mVideoCardMem = gSavedSettings.getS32("TextureMemory");  	mFogRatio = gSavedSettings.getF32("RenderFogRatio");  	mProbeHardwareOnStartup = gSavedSettings.getBOOL("ProbeHardwareOnStartup"); +	mCompressTextures = gSavedSettings.getBOOL("RenderCompressTextures");  	getChild<LLUICtrl>("fsaa")->setValue((LLSD::Integer) mFSAASamples);  	refreshEnabledState(); @@ -149,6 +150,7 @@ void LLFloaterHardwareSettings::refreshEnabledState()  BOOL LLFloaterHardwareSettings::postBuild()  {  	childSetAction("OK", onBtnOK, this); +	childSetAction("Cancel", onBtnCancel, this);  // Don't do this on Mac as their braindead GL versioning  // sets this when 8x and 16x are indeed available @@ -179,18 +181,17 @@ void LLFloaterHardwareSettings::apply()  void LLFloaterHardwareSettings::cancel()  { -	gSavedSettings.setBOOL("RenderVBOEnable", mUseVBO); -	gSavedSettings.setBOOL("RenderAnisotropic", mUseAniso); -	gSavedSettings.setU32("RenderFSAASamples", mFSAASamples); -	gSavedSettings.setF32("RenderGamma", mGamma); -	gSavedSettings.setS32("TextureMemory", mVideoCardMem); -	gSavedSettings.setF32("RenderFogRatio", mFogRatio); -	gSavedSettings.setBOOL("ProbeHardwareOnStartup", mProbeHardwareOnStartup ); -  	closeFloater();  }  // static  +void LLFloaterHardwareSettings::onBtnCancel( void* userdata ) +{ +	LLFloaterHardwareSettings *fp =(LLFloaterHardwareSettings *)userdata; +	fp->cancel(); +} + +// static  void LLFloaterHardwareSettings::onBtnOK( void* userdata )  {  	LLFloaterHardwareSettings *fp =(LLFloaterHardwareSettings *)userdata; @@ -198,4 +199,14 @@ void LLFloaterHardwareSettings::onBtnOK( void* userdata )  	fp->closeFloater(false);  } - +void LLFloaterHardwareSettings::onClose(bool app_quitting) +{ +	gSavedSettings.setBOOL("RenderVBOEnable", mUseVBO); +	gSavedSettings.setBOOL("RenderAnisotropic", mUseAniso); +	gSavedSettings.setU32("RenderFSAASamples", mFSAASamples); +	gSavedSettings.setF32("RenderGamma", mGamma); +	gSavedSettings.setS32("TextureMemory", mVideoCardMem); +	gSavedSettings.setF32("RenderFogRatio", mFogRatio); +	gSavedSettings.setBOOL("ProbeHardwareOnStartup", mProbeHardwareOnStartup ); +	gSavedSettings.setBOOL("RenderCompressTextures", mCompressTextures ); +} diff --git a/indra/newview/llfloaterhardwaresettings.h b/indra/newview/llfloaterhardwaresettings.h index 626771b1d2..11c27c266d 100755 --- a/indra/newview/llfloaterhardwaresettings.h +++ b/indra/newview/llfloaterhardwaresettings.h @@ -40,6 +40,7 @@ public:  	/*virtual*/ ~LLFloaterHardwareSettings();  	/*virtual*/ BOOL postBuild(); +	/*virtual*/ void onClose(bool app_quitting);  	/// initialize all the callbacks for the menu  	void initCallbacks(void); @@ -47,6 +48,9 @@ public:  	/// OK button  	static void onBtnOK( void* userdata ); +	/// Cancel button +	static void onBtnCancel( void* userdata ); +  	//// menu management  	/// show off our menu @@ -76,6 +80,7 @@ protected:  	S32 mVideoCardMem;  	F32 mFogRatio;  	BOOL mProbeHardwareOnStartup; +	BOOL mCompressTextures;  private:  }; diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index ab57e8c170..46fc6ea0cd 100755 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -261,6 +261,8 @@ BOOL LLFloaterIMContainer::postBuild()  	mInitialized = true; +	mIsFirstOpen = true; +  	// Add callbacks:  	// We'll take care of view updates on idle  	gIdleCallbacks.addFunction(idle, this); @@ -636,14 +638,16 @@ void LLFloaterIMContainer::setVisible(BOOL visible)  	{  		// Make sure we have the Nearby Chat present when showing the conversation container  		nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"); -		if (nearby_chat == NULL) +		if ((nearby_chat == NULL) || mIsFirstOpen)  		{ +			 mIsFirstOpen = false;  			// If not found, force the creation of the nearby chat conversation panel  			// *TODO: find a way to move this to XML as a default panel or something like that  			LLSD name("nearby_chat");  			LLFloaterReg::toggleInstanceOrBringToFront(name);              selectConversationPair(LLUUID(NULL), false, false);  		} +  		flashConversationItemWidget(mSelectedSession,false);  		LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(mSelectedSession); @@ -1216,7 +1220,22 @@ void LLFloaterIMContainer::doToSelectedConversation(const std::string& command,          {  			if (selectedIDS.size() > 0)  			{ -				LLAvatarActions::viewChatHistory(selectedIDS.front()); +				if(conversationItem->getType() == LLConversationItem::CONV_SESSION_GROUP) +				{ +					LLFloaterReg::showInstance("preview_conversation", conversationItem->getUUID(), true); +				} +				else if(conversationItem->getType() == LLConversationItem::CONV_SESSION_AD_HOC) +				{ +					LLConversation* conv = LLConversationLog::instance().findConversation(LLIMModel::getInstance()->findIMSession(conversationItem->getUUID())); +					if(conv) +					{ +						LLFloaterReg::showInstance("preview_conversation", conv->getSessionID(), true); +					} +				} +				else +				{ +					LLAvatarActions::viewChatHistory(selectedIDS.front()); +				}  			}          }          else @@ -1316,6 +1335,15 @@ bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata)  			{  				return LLLogChat::isNearbyTranscriptExist();  			} +			else if (getCurSelectedViewModelItem()->getType() == LLConversationItem::CONV_SESSION_AD_HOC) +			{ +				const LLConversation* conv = LLConversationLog::instance().findConversation(LLIMModel::getInstance()->findIMSession(uuids.front())); +				if(conv) +				{ +					return LLLogChat::isAdHocTranscriptExist(conv->getHistoryFileName()); +				} +				return false; +			}  			else  			{  				bool is_group = (getCurSelectedViewModelItem()->getType() == LLConversationItem::CONV_SESSION_GROUP); diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h index f21c0b9947..60cef83d9a 100755 --- a/indra/newview/llfloaterimcontainer.h +++ b/indra/newview/llfloaterimcontainer.h @@ -193,6 +193,8 @@ private:  	bool mInitialized;  	bool mIsFirstLaunch; +	bool mIsFirstOpen; +  	LLUUID mSelectedSession;  	std::string mGeneralTitle; diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp index b7fff6cae3..ee3d633dd0 100755 --- a/indra/newview/llfloaterjoystick.cpp +++ b/indra/newview/llfloaterjoystick.cpp @@ -326,7 +326,21 @@ void LLFloaterJoystick::onClickOK(void *joy_panel)  	}  } +void LLFloaterJoystick::onClickCloseBtn(bool app_quitting) +{ +	cancel(); +	closeFloater(app_quitting); +} +  void LLFloaterJoystick::setSNDefaults()  {  	LLViewerJoystick::getInstance()->setSNDefaults();  } + +void LLFloaterJoystick::onClose(bool app_quitting) +{ +	if (app_quitting) +	{ +		cancel(); +	} +} diff --git a/indra/newview/llfloaterjoystick.h b/indra/newview/llfloaterjoystick.h index 9c3752540d..a1b5951389 100755 --- a/indra/newview/llfloaterjoystick.h +++ b/indra/newview/llfloaterjoystick.h @@ -45,6 +45,11 @@ public:  	virtual void draw();  	static  void setSNDefaults(); +protected: + +	void onClose(bool app_quitting); +	void onClickCloseBtn(bool app_quitting); +  private:  	LLFloaterJoystick(const LLSD& data); diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index f9c39a02c9..f9fd5069af 100755 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -81,6 +81,8 @@  #include "llgroupactions.h" +const F64 COVENANT_REFRESH_TIME_SEC = 60.0f; +  static std::string OWNER_ONLINE 	= "0";  static std::string OWNER_OFFLINE	= "1";  static std::string OWNER_GROUP 		= "2"; @@ -2437,6 +2439,8 @@ void LLPanelLandAccess::refresh()  			mListAccess->clearSortOrder();  			mListAccess->deleteAllItems();  			S32 count = parcel->mAccessList.size(); +			getChild<LLUICtrl>("AllowedText")->setTextArg("[COUNT]", llformat("%d",count)); +  			getChild<LLUICtrl>("AccessList")->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",count));  			getChild<LLUICtrl>("AccessList")->setToolTipArg(LLStringExplicit("[MAX]"), llformat("%d",PARCEL_MAX_ACCESS_LIST)); @@ -2444,33 +2448,33 @@ void LLPanelLandAccess::refresh()  				 cit != parcel->mAccessList.end(); ++cit)  			{  				const LLAccessEntry& entry = (*cit).second; -				std::string suffix; +				std::string prefix;  				if (entry.mTime != 0)  				{  					LLStringUtil::format_map_t args;  					S32 now = time(NULL);  					S32 seconds = entry.mTime - now;  					if (seconds < 0) seconds = 0; -					suffix.assign(" ("); +					prefix.assign(" (");  					if (seconds >= 120)  					{  						args["[MINUTES]"] = llformat("%d", (seconds/60));  						std::string buf = parent_floater->getString ("Minutes", args); -						suffix.append(buf); +						prefix.append(buf);  					}  					else if (seconds >= 60)  					{ -						suffix.append("1 " + parent_floater->getString("Minute")); +						prefix.append("1 " + parent_floater->getString("Minute"));  					}  					else  					{  						args["[SECONDS]"] = llformat("%d", seconds);  						std::string buf = parent_floater->getString ("Seconds", args); -						suffix.append(buf); +						prefix.append(buf);  					} -					suffix.append(" " + parent_floater->getString("Remaining") + ")"); +					prefix.append(" " + parent_floater->getString("Remaining") + ") ");  				} -				mListAccess->addNameItem(entry.mID, ADD_DEFAULT, TRUE, suffix); +				mListAccess->addNameItem(entry.mID, ADD_DEFAULT, TRUE, "", prefix);  			}  			mListAccess->sortByName(TRUE);  		} @@ -2482,6 +2486,7 @@ void LLPanelLandAccess::refresh()  			mListBanned->clearSortOrder();  			mListBanned->deleteAllItems();  			S32 count = parcel->mBanList.size(); +			getChild<LLUICtrl>("BanCheck")->setTextArg("[COUNT]", llformat("%d",count));  			getChild<LLUICtrl>("BannedList")->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",count));  			getChild<LLUICtrl>("BannedList")->setToolTipArg(LLStringExplicit("[MAX]"), llformat("%d",PARCEL_MAX_ACCESS_LIST)); @@ -2490,33 +2495,33 @@ void LLPanelLandAccess::refresh()  				 cit != parcel->mBanList.end(); ++cit)  			{  				const LLAccessEntry& entry = (*cit).second; -				std::string suffix; +				std::string prefix;  				if (entry.mTime != 0)  				{  					LLStringUtil::format_map_t args;  					S32 now = time(NULL);  					S32 seconds = entry.mTime - now;  					if (seconds < 0) seconds = 0; -					suffix.assign(" ("); +					prefix.assign(" (");  					if (seconds >= 120)  					{  						args["[MINUTES]"] = llformat("%d", (seconds/60));  						std::string buf = parent_floater->getString ("Minutes", args); -						suffix.append(buf); +						prefix.append(buf);  					}  					else if (seconds >= 60)  					{ -						suffix.append("1 " + parent_floater->getString("Minute")); +						prefix.append("1 " + parent_floater->getString("Minute"));  					}  					else  					{  						args["[SECONDS]"] = llformat("%d", seconds);  						std::string buf = parent_floater->getString ("Seconds", args); -						suffix.append(buf); +						prefix.append(buf);  					} -					suffix.append(" " + parent_floater->getString("Remaining") + ")"); +					prefix.append(" " + parent_floater->getString("Remaining") + ") ");  				} -				mListBanned->addNameItem(entry.mID, ADD_DEFAULT, TRUE, suffix); +				mListBanned->addNameItem(entry.mID, ADD_DEFAULT, TRUE, "",  prefix);  			}  			mListBanned->sortByName(TRUE);  		} @@ -2919,14 +2924,23 @@ void LLPanelLandAccess::onClickRemoveBanned(void* data)  //---------------------------------------------------------------------------  LLPanelLandCovenant::LLPanelLandCovenant(LLParcelSelectionHandle& parcel)  	: LLPanel(), -	  mParcel(parcel) -{	 +	  mParcel(parcel), +	  mNextUpdateTime(0) +{  }  LLPanelLandCovenant::~LLPanelLandCovenant()  {  } +BOOL LLPanelLandCovenant::postBuild() +{ +	mLastRegionID = LLUUID::null; +	mNextUpdateTime = 0; + +	return TRUE; +} +  // virtual  void LLPanelLandCovenant::refresh()  { @@ -2973,14 +2987,23 @@ void LLPanelLandCovenant::refresh()  			changeable_clause->setText(getString("can_not_change"));  		}  	} -	 -	// send EstateCovenantInfo message -	LLMessageSystem *msg = gMessageSystem; -	msg->newMessage("EstateCovenantRequest"); -	msg->nextBlockFast(_PREHASH_AgentData); -	msg->addUUIDFast(_PREHASH_AgentID,	gAgent.getID()); -	msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID()); -	msg->sendReliable(region->getHost()); + +	if (mLastRegionID != region->getRegionID() +		|| mNextUpdateTime < LLTimer::getElapsedSeconds()) +	{ +		// Request Covenant Info +		// Note: LLPanelLandCovenant doesn't change Covenant's content and any +		// changes made by Estate floater should be requested by Estate floater +		LLMessageSystem *msg = gMessageSystem; +		msg->newMessage("EstateCovenantRequest"); +		msg->nextBlockFast(_PREHASH_AgentData); +		msg->addUUIDFast(_PREHASH_AgentID,	gAgent.getID()); +		msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID()); +		msg->sendReliable(region->getHost()); + +		mLastRegionID = region->getRegionID(); +		mNextUpdateTime = LLTimer::getElapsedSeconds() + COVENANT_REFRESH_TIME_SEC; +	}  }  // static diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h index 8e8b61c333..0540ddb880 100755 --- a/indra/newview/llfloaterland.h +++ b/indra/newview/llfloaterland.h @@ -394,6 +394,7 @@ class LLPanelLandCovenant  public:  	LLPanelLandCovenant(LLSafeHandle<LLParcelSelection>& parcelp);  	virtual ~LLPanelLandCovenant(); +	virtual BOOL postBuild();  	void refresh();  	static void updateCovenantText(const std::string& string);  	static void updateEstateName(const std::string& name); @@ -402,6 +403,10 @@ public:  protected:  	LLSafeHandle<LLParcelSelection>&	mParcel; + +private: +	LLUUID mLastRegionID; +	F64 mNextUpdateTime; //seconds since client start  };  #endif diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 72c9170b06..20760001fd 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -2226,10 +2226,15 @@ bool LLModelLoader::loadFromSLM(const std::string& filename)  		for (U32 lod = 0; lod < LLModel::NUM_LODS; ++lod)  		{ -			if (!model[lod].empty()) +			if (model[lod].size() > idx)  			{  				instance_list[i].mLOD[lod] = model[lod][idx];  			} +			else if (!model[lod].empty()) +			{ +				// slm load failed - indexes are corrupted +				return false; +			}  		}  		instance_list[i].mModel = model[LLModel::LOD_HIGH][idx]; @@ -3810,11 +3815,8 @@ void LLModelPreview::loadModelCallback(S32 lod)  		mFMP->getChild<LLCheckBoxCtrl>("confirm_checkbox")->set(FALSE);  		if (!mBaseModel.empty())  		{ -			if (mFMP->getChild<LLUICtrl>("description_form")->getValue().asString().empty()) -			{ -				const std::string& model_name = mBaseModel[0]->getName(); -				mFMP->getChild<LLUICtrl>("description_form")->setValue(model_name); -			} +			const std::string& model_name = mBaseModel[0]->getName(); +			mFMP->getChild<LLUICtrl>("description_form")->setValue(model_name);  		}  	}  	refresh(); @@ -4854,7 +4856,7 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)  		LLModel* base_mdl = *base_iter;  		base_iter++; -		for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i) +		for (S32 i = 0, e = mdl->getNumVolumeFaces(); i < e; ++i)  		{  			const LLVolumeFace &vf = mdl->getVolumeFace(i);  			U32 num_vertices = vf.mNumVertices; @@ -5138,8 +5140,11 @@ BOOL LLModelPreview::render()  			mViewOption["show_skin_weight"] = false;  			fmp->disableViewOption("show_skin_weight");  			fmp->disableViewOption("show_joint_positions"); + +			skin_weight = false; +			mFMP->childSetValue("show_skin_weight", false); +			fmp->setViewOptionEnabled("show_skin_weight", skin_weight);  		} -		skin_weight = false;  	}  	if (upload_skin && !has_skin_weights) @@ -5243,6 +5248,16 @@ BOOL LLModelPreview::render()  				const LLVertexBuffer* buff = vb_vec[0];  				regen = buff->hasDataType(LLVertexBuffer::TYPE_WEIGHT4) != skin_weight;  			} +			else +			{ +				LL_INFOS(" ") << "Vertex Buffer[" << mPreviewLOD << "]" << " is EMPTY!!!" << LL_ENDL; +				regen = TRUE; +			} +		} + +		if (regen) +		{ +			genBuffers(mPreviewLOD, skin_weight);  		}  		//make sure material lists all match @@ -5263,11 +5278,6 @@ BOOL LLModelPreview::render()  			}  		} -		if (regen) -		{ -			genBuffers(mPreviewLOD, skin_weight); -		} -  		if (!skin_weight)  		{  			for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter) @@ -5286,7 +5296,7 @@ BOOL LLModelPreview::render()  				gGL.multMatrix((GLfloat*) mat.mMatrix); -				for (U32 i = 0; i < mVertexBuffer[mPreviewLOD][model].size(); ++i) +				for (U32 i = 0, e = mVertexBuffer[mPreviewLOD][model].size(); i < e; ++i)  				{  					LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i]; @@ -5561,7 +5571,7 @@ BOOL LLModelPreview::render()  					if (!model->mSkinWeights.empty())  					{ -						for (U32 i = 0; i < mVertexBuffer[mPreviewLOD][model].size(); ++i) +						for (U32 i = 0, e = mVertexBuffer[mPreviewLOD][model].size(); i < e; ++i)  						{  							LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i]; @@ -5630,6 +5640,7 @@ BOOL LLModelPreview::render()  								position[j] = v;  							} +							llassert(model->mMaterialList.size() > i);  							const std::string& binding = instance.mModel->mMaterialList[i];  							const LLImportMaterial& material = instance.mMaterial[binding]; diff --git a/indra/newview/llfloaterperms.cpp b/indra/newview/llfloaterperms.cpp index 042cf47070..04a818c2c0 100755 --- a/indra/newview/llfloaterperms.cpp +++ b/indra/newview/llfloaterperms.cpp @@ -166,15 +166,59 @@ void LLFloaterPermsDefault::onCommitCopy(const LLSD& user_data)  	xfer->setEnabled(copyable);  } -class LLFloaterPermsResponder : public LLHTTPClient::Responder +const int MAX_HTTP_RETRIES = 5; +LLFloaterPermsRequester* LLFloaterPermsRequester::sPermsRequester = NULL; + +LLFloaterPermsRequester::LLFloaterPermsRequester(const std::string url, const LLSD report,  +	int maxRetries) +	: mRetriesCount(0), mMaxRetries(maxRetries), mUrl(url), mReport(report) +{} + +//static  +void LLFloaterPermsRequester::init(const std::string url, const LLSD report, int maxRetries) +{ +	if (sPermsRequester == NULL) { +		sPermsRequester = new LLFloaterPermsRequester(url, report, maxRetries); +	} +} +     +//static +void LLFloaterPermsRequester::finalize() +{ +	if (sPermsRequester != NULL) +	{ +		delete sPermsRequester; +		sPermsRequester = NULL; +	} +} + +//static +LLFloaterPermsRequester* LLFloaterPermsRequester::instance() +{ +	return sPermsRequester; +} + +void LLFloaterPermsRequester::start()  { -public: -	LLFloaterPermsResponder(): LLHTTPClient::Responder() {} -private: -	static	std::string sPreviousReason; +	++mRetriesCount; +	LLHTTPClient::post(mUrl, mReport, new LLFloaterPermsResponder()); +} +     +bool LLFloaterPermsRequester::retry() +{ +	if (++mRetriesCount < mMaxRetries) +	{ +		LLHTTPClient::post(mUrl, mReport, new LLFloaterPermsResponder()); +		return true; +	} +	return false; +} -	void httpFailure() +void LLFloaterPermsResponder::httpFailure() +{ +	if (!LLFloaterPermsRequester::instance() || !LLFloaterPermsRequester::instance()->retry())  	{ +		LLFloaterPermsRequester::finalize();  		const std::string& reason = getReason();  		// Do not display the same error more than once in a row  		if (reason != sPreviousReason) @@ -185,27 +229,27 @@ private:  			LLNotificationsUtil::add("DefaultObjectPermissions", args);  		}  	} +} -	void httpSuccess() -	{ -		//const LLSD& content = getContent(); -		//dump_sequential_xml("perms_responder_result.xml", content); - -		// Since we have had a successful POST call be sure to display the next error message -		// even if it is the same as a previous one. -		sPreviousReason = ""; -		LLFloaterPermsDefault::setCapSent(true); -		LL_INFOS("ObjectPermissionsFloater") << "Default permissions successfully sent to simulator" << LL_ENDL; -	} -}; +void LLFloaterPermsResponder::httpSuccess() +{ +	//const LLSD& content = getContent(); +	//dump_sequential_xml("perms_responder_result.xml", content); -	std::string	LLFloaterPermsResponder::sPreviousReason; +	// Since we have had a successful POST call be sure to display the next error message +	// even if it is the same as a previous one. +	sPreviousReason = ""; +	LL_INFOS("ObjectPermissionsFloater") << "Default permissions successfully sent to simulator" << LL_ENDL; +} + +std::string	LLFloaterPermsResponder::sPreviousReason;  void LLFloaterPermsDefault::sendInitialPerms()  {  	if(!mCapSent)  	{  		updateCap(); +		setCapSent(true);  	}  } @@ -230,8 +274,8 @@ void LLFloaterPermsDefault::updateCap()              LLSDSerialize::toPrettyXML(report, sent_perms_log);              LL_CONT << sent_perms_log.str() << LL_ENDL;          } -     -		LLHTTPClient::post(object_url, report, new LLFloaterPermsResponder()); +        LLFloaterPermsRequester::init(object_url, report, MAX_HTTP_RETRIES); +        LLFloaterPermsRequester::instance()->start();  	}      else      { diff --git a/indra/newview/llfloaterperms.h b/indra/newview/llfloaterperms.h index 2bb0a19dc1..d3b52c1fe5 100755 --- a/indra/newview/llfloaterperms.h +++ b/indra/newview/llfloaterperms.h @@ -29,6 +29,7 @@  #define LL_LLFLOATERPERMPREFS_H  #include "llfloater.h" +#include "llhttpclient.h"  class LLFloaterPerms : public LLFloater  { @@ -89,4 +90,36 @@ private:  	bool mNextOwnerTransfer[CAT_LAST];  }; +class LLFloaterPermsRequester +{ +public: +	LLFloaterPermsRequester(const std::string url, const LLSD report, int maxRetries); + +	static void init(const std::string url, const LLSD report, int maxRetries); +	static void finalize(); +	static LLFloaterPermsRequester* instance(); + +	void start(); +	bool retry(); + +private: +	int mRetriesCount; +	int mMaxRetries; +	const std::string mUrl; +	const LLSD mReport; +public: +	static LLFloaterPermsRequester* sPermsRequester; +}; + +class LLFloaterPermsResponder : public LLHTTPClient::Responder +{ +public: +	LLFloaterPermsResponder() : LLHTTPClient::Responder() {} +private: +	static	std::string sPreviousReason; + +	void httpFailure(); +	void httpSuccess(); +}; +  #endif diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index ee4396758e..dac610eda1 100755 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -49,6 +49,7 @@  //#include "llfirstuse.h"  #include "llfloaterreg.h"  #include "llfloaterabout.h" +#include "llfavoritesbar.h"  #include "llfloaterhardwaresettings.h"  #include "llfloatersidepanelcontainer.h"  #include "llfloaterimsession.h" @@ -1919,7 +1920,7 @@ BOOL LLPanelPreference::postBuild()  	}  	if (hasChild("favorites_on_login_check", TRUE))  	{ -		getChild<LLCheckBoxCtrl>("favorites_on_login_check")->setCommitCallback(boost::bind(&showFavoritesOnLoginWarning, _1, _2)); +		getChild<LLCheckBoxCtrl>("favorites_on_login_check")->setCommitCallback(boost::bind(&handleFavoritesOnLoginChanged, _1, _2));  		bool show_favorites_at_login = LLPanelLogin::getShowFavorites();  		getChild<LLCheckBoxCtrl>("favorites_on_login_check")->setValue(show_favorites_at_login);  	} @@ -2004,11 +2005,15 @@ void LLPanelPreference::showFriendsOnlyWarning(LLUICtrl* checkbox, const LLSD& v  	}  } -void LLPanelPreference::showFavoritesOnLoginWarning(LLUICtrl* checkbox, const LLSD& value) +void LLPanelPreference::handleFavoritesOnLoginChanged(LLUICtrl* checkbox, const LLSD& value)  { -	if (checkbox && checkbox->getValue()) +	if (checkbox)  	{ -		LLNotificationsUtil::add("FavoritesOnLogin"); +		LLFavoritesOrderStorage::instance().showFavoritesOnLoginChanged(checkbox->getValue().asBoolean()); +		if(checkbox->getValue()) +		{ +			LLNotificationsUtil::add("FavoritesOnLogin"); +		}  	}  } @@ -2235,6 +2240,11 @@ void LLFloaterPreferenceProxy::onOpen(const LLSD& key)  void LLFloaterPreferenceProxy::onClose(bool app_quitting)  { +	if(app_quitting) +	{ +		cancel(); +	} +  	if (mSocksSettingsDirty)  	{ @@ -2334,6 +2344,11 @@ void LLFloaterPreferenceProxy::onBtnCancel()  	cancel();  } +void LLFloaterPreferenceProxy::onClickCloseBtn(bool app_quitting) +{ +	cancel(); +} +  void LLFloaterPreferenceProxy::cancel()  { @@ -2344,7 +2359,7 @@ void LLFloaterPreferenceProxy::cancel()  		LLSD ctrl_value = iter->second;  		control->set(ctrl_value);  	} - +	mSocksSettingsDirty = false;  	closeFloater();  } diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index 7bf6ae7d79..04e5e37731 100755 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -229,7 +229,7 @@ private:  	//for "Only friends and groups can call or IM me"  	static void showFriendsOnlyWarning(LLUICtrl*, const LLSD&);  	//for "Show my Favorite Landmarks at Login" -	static void showFavoritesOnLoginWarning(LLUICtrl* checkbox, const LLSD& value); +	static void handleFavoritesOnLoginChanged(LLUICtrl* checkbox, const LLSD& value);  	typedef std::map<std::string, LLColor4> string_color_map_t;  	string_color_map_t mSavedColors; @@ -269,6 +269,7 @@ protected:  	void saveSettings();  	void onBtnOk();  	void onBtnCancel(); +	void onClickCloseBtn(bool app_quitting = false);  	void onChangeSocksSettings(); diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index 5e028e6d43..2f4d2a93b2 100755 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -107,14 +107,6 @@ LLFloaterReporter::LLFloaterReporter(const LLSD& key)  {  } -// static -void LLFloaterReporter::processRegionInfo(LLMessageSystem* msg) -{ -	if ( LLFloaterReg::instanceVisible("reporter") ) -	{ -		LLNotificationsUtil::add("HelpReportAbuseEmailLL"); -	}; -}  // virtual  BOOL LLFloaterReporter::postBuild()  { @@ -148,16 +140,6 @@ BOOL LLFloaterReporter::postBuild()  	mDefaultSummary = getChild<LLUICtrl>("details_edit")->getValue().asString(); -	// send a message and ask for information about this region -  -	// result comes back in processRegionInfo(..) -	LLMessageSystem* msg = gMessageSystem; -	msg->newMessage("RequestRegionInfo"); -	msg->nextBlock("AgentData"); -	msg->addUUID("AgentID", gAgent.getID()); -	msg->addUUID("SessionID", gAgent.getSessionID()); -	gAgent.sendReliableMessage(); -	 -	  	// abuser name is selected from a list  	LLUICtrl* le = getChild<LLUICtrl>("abuser_name_edit");  	le->setEnabled( false ); diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h index 5eb5c20665..d857528f10 100755 --- a/indra/newview/llfloaterreporter.h +++ b/indra/newview/llfloaterreporter.h @@ -100,10 +100,7 @@ public:  	static void uploadDoneCallback(const LLUUID &uuid, void* user_data, S32 result, LLExtStat ext_status);  	static void addDescription(const std::string& description, LLMeanCollisionData *mcd = NULL);  	static void setDescription(const std::string& description, LLMeanCollisionData *mcd = NULL); -	 -	// static -	static void processRegionInfo(LLMessageSystem* msg); -	 +  	void setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id);  private: diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index b27a42cb8e..afec981d56 100755 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -448,9 +448,9 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater)  	floater->getChild<LLUICtrl>("file_size_label")->setTextArg("[SIZE]", got_snap ? bytes_string : floater->getString("unknown"));  	floater->getChild<LLUICtrl>("file_size_label")->setColor( -		shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD  -		&& got_bytes -		&& previewp->getDataSize() > MAX_POSTCARD_DATASIZE ? LLUIColor(LLColor4::red) : LLUIColorTable::instance().getColor( "LabelTextColor" )); +			shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD +			&& got_bytes +			&& previewp->getDataSize() > MAX_POSTCARD_DATASIZE ? LLUIColor(LLColor4::red) : LLUIColorTable::instance().getColor( "LabelTextColor" ));  	// Update the width and height spinners based on the corresponding resolution combos. (?)  	switch(shot_type) @@ -600,7 +600,11 @@ void LLFloaterSnapshot::Impl::onClickUICheck(LLUICtrl *ctrl, void* data)  	LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;  	if (view)  	{ -		checkAutoSnapshot(getPreviewView(view), TRUE); +		LLSnapshotLivePreview* previewp = getPreviewView(view); +		if(previewp) +		{ +			previewp->updateSnapshot(TRUE, TRUE); +		}  		updateControls(view);  	}  } @@ -614,7 +618,11 @@ void LLFloaterSnapshot::Impl::onClickHUDCheck(LLUICtrl *ctrl, void* data)  	LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;  	if (view)  	{ -		checkAutoSnapshot(getPreviewView(view), TRUE); +		LLSnapshotLivePreview* previewp = getPreviewView(view); +		if(previewp) +		{ +			previewp->updateSnapshot(TRUE, TRUE); +		}  		updateControls(view);  	}  } @@ -655,14 +663,20 @@ void LLFloaterSnapshot::Impl::onCommitFreezeFrame(LLUICtrl* ctrl, void* data)  {  	LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl;  	LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; +	LLSnapshotLivePreview* previewp = getPreviewView(view); -	if (!view || !check_box) +	if (!view || !check_box || !previewp)  	{  		return;  	}  	gSavedSettings.setBOOL("UseFreezeFrame", check_box->get()); +	if (check_box->get()) +	{ +		previewp->prepareFreezeFrame(); +	} +  	updateLayout(view);  } diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 7477b02867..6dbb202c9d 100755 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -92,6 +92,7 @@  // Globals  LLFloaterTools *gFloaterTools = NULL;  bool LLFloaterTools::sShowObjectCost = true; +bool LLFloaterTools::sPreviousFocusOnAvatar = false;  const std::string PANEL_NAMES[LLFloaterTools::PANEL_COUNT] =  { @@ -891,6 +892,12 @@ void LLFloaterTools::onClose(bool app_quitting)  	// prepare content for next call  	mPanelContents->clearContents(); + +	if(sPreviousFocusOnAvatar) +	{ +		sPreviousFocusOnAvatar = false; +		gAgentCamera.setAllowChangeToFollow(TRUE); +	}  }  void click_popup_info(void*) diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h index 189bae46c2..df481b8d4c 100755 --- a/indra/newview/llfloatertools.h +++ b/indra/newview/llfloatertools.h @@ -201,11 +201,13 @@ private:  	std::map<std::string, std::string> mStatusText; +  protected:  	LLSD				mMediaSettings;  public:  	static bool		sShowObjectCost; +	static bool		sPreviousFocusOnAvatar;  }; diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index 1b1c24b19a..ece3e10faa 100755 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -284,12 +284,12 @@ BOOL LLFloaterWorldMap::postBuild()  	LLComboBox *avatar_combo = getChild<LLComboBox>("friend combo");  	avatar_combo->selectFirstItem();  	avatar_combo->setPrearrangeCallback( boost::bind(&LLFloaterWorldMap::onAvatarComboPrearrange, this) ); -	avatar_combo->setTextEntryCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) ); +	avatar_combo->setTextChangedCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) );  	mListFriendCombo = dynamic_cast<LLCtrlListInterface *>(avatar_combo);  	LLSearchEditor *location_editor = getChild<LLSearchEditor>("location");  	location_editor->setFocusChangedCallback(boost::bind(&LLFloaterWorldMap::onLocationFocusChanged, this, _1)); -	location_editor->setKeystrokeCallback( boost::bind(&LLFloaterWorldMap::onSearchTextEntry, this)); +	location_editor->setTextChangedCallback( boost::bind(&LLFloaterWorldMap::onSearchTextEntry, this));  	getChild<LLScrollListCtrl>("search_results")->setDoubleClickCallback( boost::bind(&LLFloaterWorldMap::onClickTeleportBtn, this));  	mListSearchResults = childGetListInterface("search_results"); @@ -297,7 +297,7 @@ BOOL LLFloaterWorldMap::postBuild()  	LLComboBox *landmark_combo = getChild<LLComboBox>( "landmark combo");  	landmark_combo->selectFirstItem();  	landmark_combo->setPrearrangeCallback( boost::bind(&LLFloaterWorldMap::onLandmarkComboPrearrange, this) ); -	landmark_combo->setTextEntryCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) ); +	landmark_combo->setTextChangedCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) );  	mListLandmarkCombo = dynamic_cast<LLCtrlListInterface *>(landmark_combo);  	mCurZoomVal = log(LLWorldMapView::sMapScale)/log(2.f); diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp index 3271a40ea0..5fad76eeec 100755 --- a/indra/newview/llfolderviewmodelinventory.cpp +++ b/indra/newview/llfolderviewmodelinventory.cpp @@ -108,6 +108,29 @@ bool LLFolderViewModelInventory::contentsReady()  	return !LLInventoryModelBackgroundFetch::instance().folderFetchActive();  } +bool LLFolderViewModelInventory::isFolderComplete(LLFolderViewFolder* folder) +{ +	LLFolderViewModelItemInventory* modelp = static_cast<LLFolderViewModelItemInventory*>(folder->getViewModelItem()); +	LLUUID cat_id = modelp->getUUID(); +	if (cat_id.isNull()) +	{ +		return false; +	} +	LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); +	if (cat) +	{ +		// don't need to check version - descendents_server == -1 if we have no data +		S32 descendents_server = cat->getDescendentCount(); +		S32 descendents_actual = cat->getViewerDescendentCount(); +		if (descendents_server == descendents_actual +			|| (descendents_actual > 0 && descendents_server == -1)) // content was loaded in previous session +		{ +			return true; +		} +	} +	return false; +} +  void LLFolderViewModelItemInventory::requestSort()  {  	LLFolderViewModelItemCommon::requestSort(); diff --git a/indra/newview/llfolderviewmodelinventory.h b/indra/newview/llfolderviewmodelinventory.h index 8772185ad0..6fe35666f2 100755 --- a/indra/newview/llfolderviewmodelinventory.h +++ b/indra/newview/llfolderviewmodelinventory.h @@ -113,6 +113,7 @@ public:  	void sort(LLFolderViewFolder* folder);  	bool contentsReady(); +	bool isFolderComplete(LLFolderViewFolder* folder);  	bool startDrag(std::vector<LLFolderViewModelItem*>& items);  private: diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index 56e671d902..6b4e242e3a 100755 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -1970,7 +1970,8 @@ void LLGroupMgr::processGroupBanRequest(const LLSD& content)  	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_id);  	if (!gdatap)  		return; -	 + +	gdatap->clearBanList();  	LLSD::map_const_iterator i		= content["ban_list"].beginMap();  	LLSD::map_const_iterator iEnd	= content["ban_list"].endMap();  	for(;i != iEnd; ++i) @@ -2082,11 +2083,6 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)  		return;  	} -	// If we have no members, there's no reason to do anything else -	S32	num_members	= content["member_count"]; -	if(num_members < 1) -		return; -	  	LLUUID group_id = content["group_id"].asUUID();  	LLGroupMgrGroupData* group_datap = LLGroupMgr::getInstance()->getGroupData(group_id); @@ -2096,6 +2092,18 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)  		return;  	} +	// If we have no members, there's no reason to do anything else +	S32	num_members	= content["member_count"]; +	if (num_members < 1) +	{ +		LL_INFOS("GrpMgr") << "Received empty group members list for group id: " << group_id.asString() << LL_ENDL; +		// Set mMemberDataComplete for correct handling of empty responses. See MAINT-5237 +		group_datap->mMemberDataComplete = true; +		group_datap->mChanged = TRUE; +		LLGroupMgr::getInstance()->notifyObservers(GC_MEMBER_DATA); +		return; +	} +	  	group_datap->mMemberCount = num_members;  	LLSD	member_list	= content["members"]; diff --git a/indra/newview/llgroupmgr.h b/indra/newview/llgroupmgr.h index 2e94e8d9a0..a58799350d 100755 --- a/indra/newview/llgroupmgr.h +++ b/indra/newview/llgroupmgr.h @@ -149,7 +149,7 @@ public:  	const uuid_vec_t& getRoleMembers() const { return mMemberIDs; }  	S32 getMembersInRole(uuid_vec_t members, BOOL needs_sort = TRUE); -	S32 getTotalMembersInRole() { return mMemberIDs.size(); } +	S32 getTotalMembersInRole() { return mMemberCount ? mMemberCount : mMemberIDs.size(); } //FIXME: Returns 0 for Everyone role when Member list isn't yet loaded, see MAINT-5225  	LLRoleData getRoleData() const { return mRoleData; }  	void setRoleData(LLRoleData data) { mRoleData = data; } diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 5d3a11e245..b8b6bdaa11 100755 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -1295,8 +1295,15 @@ void LLIMModel::sendMessage(const std::string& utf8_text,  		gAgent.sendReliableMessage();  	} +	bool is_group_chat = false; +	LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(im_session_id); +	if(session) +	{ +		is_group_chat = session->isGroupSessionType(); +	} +  	// If there is a mute list and this is not a group chat... -	if ( LLMuteList::getInstance() ) +	if ( LLMuteList::getInstance() && !is_group_chat)  	{  		// ... the target should not be in our mute list for some message types.  		// Auto-remove them if present. @@ -1345,7 +1352,6 @@ void LLIMModel::sendMessage(const std::string& utf8_text,  	if (is_not_group_id)  	{ -		LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(im_session_id);  		if( session == 0)//??? shouldn't really happen  		{  			LLRecentPeople::instance().add(other_participant_id); diff --git a/indra/newview/llinspecttoast.cpp b/indra/newview/llinspecttoast.cpp index d04378daaf..47560341e7 100755 --- a/indra/newview/llinspecttoast.cpp +++ b/indra/newview/llinspecttoast.cpp @@ -47,6 +47,7 @@ public:  	/*virtual*/ void onOpen(const LLSD& notification_id);  	/*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask); +	/*virtual*/ void removeChild(LLView* child);  private:  	void onToastDestroy(LLToast * toast); @@ -98,7 +99,7 @@ void LLInspectToast::onOpen(const LLSD& notification_id)  	panel->setMouseOpaque(FALSE);  	if(mPanel != NULL && mPanel->getParent() == this)  	{ -		removeChild(mPanel); +		LLInspect::removeChild(mPanel);  	}  	addChild(panel);  	panel->setFocus(TRUE); @@ -121,6 +122,16 @@ BOOL LLInspectToast::handleToolTip(S32 x, S32 y, MASK mask)  	return LLFloater::handleToolTip(x, y, mask);  } +// virtual +void LLInspectToast::removeChild(LLView* child) +{ +	if (mPanel == child) +	{ +		mPanel = NULL; +	} +	LLInspect::removeChild(child); +} +  void LLInspectToast::onToastDestroy(LLToast * toast)  {  	closeFloater(false); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 84f88e38ba..63e91f5d88 100755 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -863,15 +863,7 @@ void LLInvFVBridge::addDeleteContextMenuOptions(menuentry_vec_t &items,  		return;  	} -	// "Remove link" and "Delete" are the same operation. -	if (obj && obj->getIsLinkType() && !get_is_item_worn(mUUID)) -	{ -		items.push_back(std::string("Remove Link")); -	} -	else -	{ -		items.push_back(std::string("Delete")); -	} +	items.push_back(std::string("Delete"));  	if (!isItemRemovable())  	{ @@ -1572,7 +1564,9 @@ void LLItemBridge::restoreItem()  	if(item)  	{  		LLInventoryModel* model = getInventoryModel(); -		const LLUUID new_parent = model->findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(item->getType())); +		bool is_snapshot = (item->getInventoryType() == LLInventoryType::IT_SNAPSHOT); + +		const LLUUID new_parent = model->findCategoryUUIDForType(is_snapshot? LLFolderType::FT_SNAPSHOT_CATEGORY : LLFolderType::assetTypeToFolderType(item->getType()));  		// do not restamp on restore.  		LLInvFVBridge::changeItemParent(model, item, new_parent, FALSE);  	} @@ -2255,7 +2249,8 @@ int get_folder_path_length(const LLUUID& ancestor_id, const LLUUID& descendant_i  BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,  											BOOL drop, -											std::string& tooltip_msg) +											std::string& tooltip_msg, +											BOOL is_link)  {  	LLInventoryModel* model = getInventoryModel(); @@ -2297,6 +2292,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,  		const BOOL move_is_into_trash = (mUUID == trash_id) || model->isObjectDescendentOf(mUUID, trash_id);  		const BOOL move_is_into_my_outfits = (mUUID == my_outifts_id) || model->isObjectDescendentOf(mUUID, my_outifts_id);  		const BOOL move_is_into_outfit = move_is_into_my_outfits || (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT); +		const BOOL move_is_into_current_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_CURRENT_OUTFIT);  		const BOOL move_is_into_landmarks = (mUUID == landmarks_id) || model->isObjectDescendentOf(mUUID, landmarks_id);  		//-------------------------------------------------------------------------------- @@ -2322,8 +2318,18 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,  		}  		if (is_movable && move_is_into_outfit)  		{ +			if((mUUID == my_outifts_id) || (getCategory() && getCategory()->getPreferredType() == LLFolderType::FT_NONE)) +			{ +				is_movable = ((inv_cat->getPreferredType() == LLFolderType::FT_NONE) || (inv_cat->getPreferredType() == LLFolderType::FT_OUTFIT)); +			} +			else +			{ +				is_movable = false; +			} +		} +		if(is_movable && move_is_into_current_outfit && is_link) +		{  			is_movable = FALSE; -			// tooltip?  		}  		if (is_movable && (mUUID == model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE)))  		{ @@ -2539,9 +2545,11 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,  					}  				}  			} +  			// if target is current outfit folder we use link  			if (move_is_into_current_outfit && -				inv_cat->getPreferredType() == LLFolderType::FT_NONE) +				(inv_cat->getPreferredType() == LLFolderType::FT_NONE || +				inv_cat->getPreferredType() == LLFolderType::FT_OUTFIT))  			{  				// traverse category and add all contents to currently worn.  				BOOL append = true; @@ -3701,7 +3709,7 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop,  				LLInventoryCategory* linked_category = gInventory.getCategory(inv_item->getLinkedUUID());  				if (linked_category)  				{ -					accept = dragCategoryIntoFolder((LLInventoryCategory*)linked_category, drop, tooltip_msg); +					accept = dragCategoryIntoFolder((LLInventoryCategory*)linked_category, drop, tooltip_msg, TRUE);  				}  			}  			else @@ -5715,12 +5723,8 @@ void LLWearableBridge::performAction(LLInventoryModel* model, std::string action  void LLWearableBridge::openItem()  { -	LLViewerInventoryItem* item = getItem(); - -	if (item) -	{ -		LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel()); -	} +	performAction(getInventoryModel(), +			      get_is_item_worn(mUUID) ? "take_off" : "wear");  }  void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags) diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index da33e8e680..f6fea5df7c 100755 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -265,7 +265,7 @@ public:  	{}  	BOOL dragItemIntoFolder(LLInventoryItem* inv_item, BOOL drop, std::string& tooltip_msg); -	BOOL dragCategoryIntoFolder(LLInventoryCategory* inv_category, BOOL drop, std::string& tooltip_msg); +	BOOL dragCategoryIntoFolder(LLInventoryCategory* inv_category, BOOL drop, std::string& tooltip_msg, BOOL is_link = FALSE);      virtual void buildDisplayName() const; diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index c66e9da4a9..c054747308 100755 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -68,7 +68,8 @@ LLInventoryFilter::LLInventoryFilter(const Params& p)  :	mName(p.name),  	mFilterModified(FILTER_NONE),  	mEmptyLookupMessage("InventoryNoMatchingItems"), -    mFilterOps(p.filter_ops), +	mFilterOps(p.filter_ops), +	mBackupFilterOps(mFilterOps),  	mFilterSubString(p.substring),  	mCurrentGeneration(0),  	mFirstRequiredGeneration(0), @@ -546,6 +547,21 @@ void LLInventoryFilter::setFilterSubString(const std::string& string)  			setModified(FILTER_RESTART);  		} +		// Cancel out filter links once the search string is modified +		if (mFilterOps.mFilterLinks == FILTERLINK_ONLY_LINKS) +		{ +			if (mBackupFilterOps.mFilterLinks == FILTERLINK_ONLY_LINKS) +			{ +				// we started viewer/floater in 'only links' mode +				mFilterOps.mFilterLinks = FILTERLINK_INCLUDE_LINKS; +			} +			else +			{ +				mFilterOps = mBackupFilterOps; +				setModified(FILTER_RESTART); +			} +		} +  		// Cancel out UUID once the search string is modified  		if (mFilterOps.mFilterTypes == FILTERTYPE_UUID)  		{ @@ -553,11 +569,6 @@ void LLInventoryFilter::setFilterSubString(const std::string& string)  			mFilterOps.mFilterUUID = LLUUID::null;  			setModified(FILTER_RESTART);  		} - -		// Cancel out filter links once the search string is modified -		{ -			mFilterOps.mFilterLinks = FILTERLINK_INCLUDE_LINKS; -		}  	}  } @@ -748,6 +759,22 @@ void LLInventoryFilter::setShowFolderState(EFolderShow state)  	}  } +void LLInventoryFilter::setFindAllLinksMode(const std::string &search_name, const LLUUID& search_id) +{ +	// Save a copy of settings so that we will be able to restore it later +	// but make sure we are not searching for links already +	if(mFilterOps.mFilterLinks != FILTERLINK_ONLY_LINKS) +	{ +		mBackupFilterOps = mFilterOps; +	} +	 +	// set search options +	setFilterSubString(search_name); +	setFilterUUID(search_id); +	setShowFolderState(SHOW_NON_EMPTY_FOLDERS); +	setFilterLinks(FILTERLINK_ONLY_LINKS); +} +  void LLInventoryFilter::markDefault()  {  	mDefaultFilterOps = mFilterOps; diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h index 5e18ad4d20..6e35c48c7b 100755 --- a/indra/newview/llinventoryfilter.h +++ b/indra/newview/llinventoryfilter.h @@ -193,6 +193,9 @@ public:  	void 				setFilterLinks(U64 filter_link);  	U64					getFilterLinks() const; +	// sets params for Link-only search and backs up search settings for future restoration +	void				setFindAllLinksMode(const std::string &search_name, const LLUUID& search_id); +  	// +-------------------------------------------------------------------+  	// + Execution And Results  	// +-------------------------------------------------------------------+ @@ -267,6 +270,7 @@ private:  	FilterOps				mFilterOps;  	FilterOps				mDefaultFilterOps; +	FilterOps				mBackupFilterOps; // for backup purposes when leaving 'search link' mode  	std::string				mFilterSubString;  	std::string				mFilterSubStringOrig; diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 605a63aa33..ae799e8b18 100755 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -459,7 +459,7 @@ void show_item_original(const LLUUID& item_uuid)  	{  		return;  	} -	active_panel->setSelection(gInventory.getLinkedItemID(item_uuid), TAKE_FOCUS_NO); +	active_panel->setSelection(gInventory.getLinkedItemID(item_uuid), TAKE_FOCUS_YES);  	if(do_reset_inventory_filter)  	{ @@ -674,6 +674,19 @@ void copy_folder_to_outbox(LLInventoryCategory* inv_cat, const LLUUID& dest_fold  	open_outbox();  } +static void items_removal_confirmation(const LLSD& notification, const LLSD& response, LLHandle<LLFolderView> root) +{ +	S32 option = LLNotificationsUtil::getSelectedOption(notification, response); +	if (option == 0 && !root.isDead() && !root.get()->isDead()) +	{ +		LLFolderView* folder_root = root.get(); +		//Need to remove item from DND before item is removed from root folder view +		//because once removed from root folder view the item is no longer a selected item +		LLInventoryAction::removeItemFromDND(folder_root); +		folder_root->removeSelectedItems(); +	} +} +  ///----------------------------------------------------------------------------  /// LLInventoryCollectFunctor implementations  ///---------------------------------------------------------------------------- @@ -1100,7 +1113,7 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root  	{  		LLSD args;  		args["QUESTION"] = LLTrans::getString(root->getSelectedCount() > 1 ? "DeleteItems" :  "DeleteItem"); -		LLNotificationsUtil::add("DeleteItems", args, LLSD(), boost::bind(&LLInventoryAction::onItemsRemovalConfirmation, _1, _2, root)); +		LLNotificationsUtil::add("DeleteItems", args, LLSD(), boost::bind(&items_removal_confirmation, _1, _2, root->getHandle()));  		return;  	}  	if (("copy" == action) || ("cut" == action)) @@ -1205,15 +1218,3 @@ void LLInventoryAction::removeItemFromDND(LLFolderView* root)          }      }  } - -void LLInventoryAction::onItemsRemovalConfirmation( const LLSD& notification, const LLSD& response, LLFolderView* root ) -{ -	S32 option = LLNotificationsUtil::getSelectedOption(notification, response); -	if (option == 0) -	{ -        //Need to remove item from DND before item is removed from root folder view -        //because once removed from root folder view the item is no longer a selected item -        removeItemFromDND(root); -		root->removeSelectedItems(); -	} -} diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index 6b3861aa79..92780eb10f 100755 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -438,8 +438,6 @@ public:  struct LLInventoryAction  {  	static void doToSelected(class LLInventoryModel* model, class LLFolderView* root, const std::string& action); - -	static void onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response, LLFolderView* root);      static void removeItemFromDND(LLFolderView* root);  }; diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index 1380345164..4e9947fca0 100755 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -128,7 +128,7 @@ LLLocalBitmap::LLLocalBitmap(std::string filename)  LLLocalBitmap::~LLLocalBitmap()  {  	// replace IDs with defaults, if set to do so. -	if(LL_LOCAL_REPLACE_ON_DEL && mValid) // fix for STORM-1837 +	if(LL_LOCAL_REPLACE_ON_DEL && mValid && gAgentAvatarp) // fix for STORM-1837  	{  		replaceIDs(mWorldID, IMG_DEFAULT);  		LLLocalBitmapMgr::doRebake(); diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index 7ddacf3033..4116e38f11 100755 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -804,6 +804,22 @@ bool LLLogChat::isNearbyTranscriptExist()  	return false;  } +bool LLLogChat::isAdHocTranscriptExist(std::string file_name) +{ +	std::vector<std::string> list_of_transcriptions; +	LLLogChat::getListOfTranscriptFiles(list_of_transcriptions); + +	file_name = makeLogFileName(file_name); +	BOOST_FOREACH(std::string& transcript_file_name, list_of_transcriptions) +	{ +	   	if (transcript_file_name == file_name) +	   	{ +	   		return true; +		} +	} +	return false; +} +  //*TODO mark object's names in a special way so that they will be distinguishable form avatar name   //which are more strict by its nature (only firstname and secondname)  //Example, an object's name can be written like "Object <actual_object's_name>" diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h index ca597599dd..6022e539a9 100755 --- a/indra/newview/lllogchat.h +++ b/indra/newview/lllogchat.h @@ -120,6 +120,7 @@ public:  	static void deleteTranscripts();  	static bool isTranscriptExist(const LLUUID& avatar_id, bool is_group=false);  	static bool isNearbyTranscriptExist(); +	static bool isAdHocTranscriptExist(std::string file_name);  	static bool historyThreadsFinished(LLUUID session_id);  	static LLLoadHistoryThread* getLoadHistoryThread(LLUUID session_id); diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp index 407613d32c..85faa70552 100755 --- a/indra/newview/llmanipscale.cpp +++ b/indra/newview/llmanipscale.cpp @@ -1677,12 +1677,12 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)  				F32 alpha = (1.f - (1.f *  ((F32)llabs(i) / (F32)num_ticks_per_side1)));  				LLVector3 tick_pos = mScaleCenter + (mScaleDir * (grid_multiple1 + i) * smallest_subdivision1); -				F32 cur_subdivisions = llclamp(getSubdivisionLevel(tick_pos, mScaleDir, mScaleSnapUnit1, mTickPixelSpacing1), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel); - -				if (fmodf((F32)(i + sub_div_offset_1), (sGridMaxSubdivisionLevel / cur_subdivisions)) != 0.f) +				//No need check this condition to prevent tick position scaling (FIX MAINT-5207/5208) +				//F32 cur_subdivisions = llclamp(getSubdivisionLevel(tick_pos, mScaleDir, mScaleSnapUnit1, mTickPixelSpacing1), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel); +				/*if (fmodf((F32)(i + sub_div_offset_1), (sGridMaxSubdivisionLevel / cur_subdivisions)) != 0.f)  				{  					continue; -				} +				}*/  				F32 tick_scale = 1.f;  				for (F32 division_level = sGridMaxSubdivisionLevel; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f) @@ -1710,12 +1710,12 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)  				F32 alpha = (1.f - (1.f *  ((F32)llabs(i) / (F32)num_ticks_per_side2)));  				LLVector3 tick_pos = mScaleCenter + (mScaleDir * (grid_multiple2 + i) * smallest_subdivision2); -				F32 cur_subdivisions = llclamp(getSubdivisionLevel(tick_pos, mScaleDir, mScaleSnapUnit2, mTickPixelSpacing2), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel); - -				if (fmodf((F32)(i + sub_div_offset_2), (sGridMaxSubdivisionLevel / cur_subdivisions)) != 0.f) +				//No need check this condition to prevent tick position scaling (FIX MAINT-5207/5208) +				//F32 cur_subdivisions = llclamp(getSubdivisionLevel(tick_pos, mScaleDir, mScaleSnapUnit2, mTickPixelSpacing2), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel); +				/*if (fmodf((F32)(i + sub_div_offset_2), (sGridMaxSubdivisionLevel / cur_subdivisions)) != 0.f)  				{  					continue; -				} +				}*/  				F32 tick_scale = 1.f;  				for (F32 division_level = sGridMaxSubdivisionLevel; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f) diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp index 394db71fb9..b4259a456c 100755 --- a/indra/newview/llmaniptranslate.cpp +++ b/indra/newview/llmaniptranslate.cpp @@ -1285,12 +1285,12 @@ void LLManipTranslate::renderSnapGuides()  				{  					tick_start = selection_center + (translate_axis * (smallest_grid_unit_scale * (F32)i - offset_nearest_grid_unit)); -					F32 cur_subdivisions = getSubdivisionLevel(tick_start, translate_axis, getMinGridScale()); - -					if (fmodf((F32)(i + sub_div_offset), (max_subdivisions / cur_subdivisions)) != 0.f) +					//No need check this condition to prevent tick position scaling (FIX MAINT-5207/5208) +					//F32 cur_subdivisions = getSubdivisionLevel(tick_start, translate_axis, getMinGridScale()); +					/*if (fmodf((F32)(i + sub_div_offset), (max_subdivisions / cur_subdivisions)) != 0.f)  					{  						continue; -					} +					}*/  					// add in off-axis offset  					tick_start += (mSnapOffsetAxis * mSnapOffsetMeters); diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index b96bdd73ff..cd3d0cdbf2 100755 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -95,6 +95,7 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) :  	mStretchToFill( true ),  	mMaintainAspectRatio ( true ),  	mDecoupleTextureSize ( false ), +	mUpdateScrolls( false ),  	mTextureWidth ( 1024 ),  	mTextureHeight ( 1024 ),  	mClearCache(false), @@ -682,7 +683,13 @@ bool LLMediaCtrl::ensureMediaSourceExists()  			mMediaSource->addObserver( this );  			mMediaSource->setBackgroundColor( getBackgroundColor() );  			mMediaSource->setTrustedBrowser(mTrusted); -			mMediaSource->setPageZoomFactor( LLUI::getScaleFactor().mV[ VX ] ); + +			F32 scale_factor = LLUI::getScaleFactor().mV[ VX ]; +			if (scale_factor != mMediaSource->getPageZoomFactor()) +			{ +				mMediaSource->setPageZoomFactor( scale_factor ); +				mUpdateScrolls = true; +			}  			if(mClearCache)  			{ @@ -720,10 +727,11 @@ void LLMediaCtrl::draw()  {  	F32 alpha = getDrawContext().mAlpha; -	if ( gRestoreGL == 1 ) +	if ( gRestoreGL == 1 || mUpdateScrolls)  	{  		LLRect r = getRect();  		reshape( r.getWidth(), r.getHeight(), FALSE ); +		mUpdateScrolls = false;  		return;  	} @@ -765,7 +773,12 @@ void LLMediaCtrl::draw()  	{  		gGL.pushUIMatrix();  		{ -			mMediaSource->setPageZoomFactor( LLUI::getScaleFactor().mV[ VX ] ); +			F32 scale_factor = LLUI::getScaleFactor().mV[ VX ]; +			if (scale_factor != mMediaSource->getPageZoomFactor()) +			{ +				mMediaSource->setPageZoomFactor( scale_factor ); +				mUpdateScrolls = true; +			}  			// scale texture to fit the space using texture coords  			gGL.getTexUnit(0)->bind(media_texture); diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h index 785c57b78a..988733b85a 100755 --- a/indra/newview/llmediactrl.h +++ b/indra/newview/llmediactrl.h @@ -192,7 +192,8 @@ public:  				mHidingInitialLoad,  				mClearCache,  				mHoverTextChanged, -				mDecoupleTextureSize; +				mDecoupleTextureSize, +				mUpdateScrolls;  		std::string mHomePageUrl,  					mHomePageMimeType, diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 648056484e..9a0bd9d1bc 100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -72,6 +72,7 @@  #include "bufferstream.h"  #include "llfasttimer.h"  #include "llcorehttputil.h" +#include "lltrans.h"  #include "boost/lexical_cast.hpp" @@ -693,12 +694,16 @@ void log_upload_error(LLCore::HttpStatus status, const LLSD& content,  	args["MESSAGE"] = message;  	args["IDENTIFIER"] = identifier;  	args["LABEL"] = model_name; -	gMeshRepo.uploadError(args);  	// Log details.  	LL_WARNS(LOG_MESH) << "Error in stage:  " << stage  					   << ", Reason:  " << status.toString()  					   << " (" << status.toTerseString() << ")" << LL_ENDL; + +	std::ostringstream details; +	typedef std::set<std::string> mav_errors_set_t; +	mav_errors_set_t mav_errors; +  	if (content.has("error"))  	{  		const LLSD& err = content["error"]; @@ -708,8 +713,11 @@ void log_upload_error(LLCore::HttpStatus status, const LLSD& content,  						   << "', message '" << err["message"].asString()  						   << "', id '" << err["identifier"].asString()  						   << "'" << LL_ENDL; +  		if (err.has("errors"))  		{ +			details << std::endl << std::endl; +  			S32 error_num = 0;  			const LLSD& err_list = err["errors"];  			for (LLSD::array_const_iterator it = err_list.beginArray(); @@ -717,6 +725,13 @@ void log_upload_error(LLCore::HttpStatus status, const LLSD& content,  				 ++it)  			{  				const LLSD& err_entry = *it; +				std::string message = err_entry["message"]; + +				if (message.length() > 0) +				{ +					mav_errors.insert(message); +				} +  				LL_WARNS(LOG_MESH) << "  error[" << error_num << "]:" << LL_ENDL;  				for (LLSD::map_const_iterator map_it = err_entry.beginMap();  					 map_it != err_entry.endMap(); @@ -733,6 +748,21 @@ void log_upload_error(LLCore::HttpStatus status, const LLSD& content,  	{  		LL_WARNS(LOG_MESH) << "Bad response to mesh request, no additional error information available." << LL_ENDL;  	} +	 +	mav_errors_set_t::iterator mav_errors_it = mav_errors.begin(); +	for (; mav_errors_it != mav_errors.end(); ++mav_errors_it) +	{ +		std::string mav_details = "Mav_Details_" + *mav_errors_it; +		details << "Message: '" << *mav_errors_it << "': " << LLTrans::getString(mav_details) << std::endl << std::endl; +	} + +	std::string details_str = details.str(); +	if (details_str.length() > 0) +	{ +		args["DETAILS"] = details_str; +	} + +	gMeshRepo.uploadError(args);  }  LLMeshRepoThread::LLMeshRepoThread() diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp index fe562baf96..70035bcc74 100755 --- a/indra/newview/llmoveview.cpp +++ b/indra/newview/llmoveview.cpp @@ -303,7 +303,15 @@ void LLFloaterMove::onFlyButtonClick()  void LLFloaterMove::setMovementMode(const EMovementMode mode)  {  	mCurrentMode = mode; -	gAgent.setFlying(MM_FLY == mode); + +	if(MM_FLY == mode) +	{ +		LLAgent::toggleFlying(); +	} +	else +	{ +		gAgent.setFlying(FALSE); +	}  	// attempts to set avatar flying can not set it real flying in some cases.  	// For ex. when avatar fell down & is standing up. diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp index 65ac11092c..d79baf90e7 100755 --- a/indra/newview/llmutelist.cpp +++ b/indra/newview/llmutelist.cpp @@ -646,6 +646,22 @@ BOOL LLMuteList::isMuted(const LLUUID& id, const std::string& name, U32 flags) c  	return legacy_it != mLegacyMutes.end();  } +BOOL LLMuteList::isMuted(const std::string& username, U32 flags) const +{ +	mute_set_t::const_iterator mute_iter = mMutes.begin(); +	while(mute_iter != mMutes.end()) +	{ +		// can't convert "leha.test" into "LeHa TesT" so username comparison is more reliable +		if (mute_iter->mType == LLMute::AGENT +			&& LLCacheName::buildUsername(mute_iter->mName) == username) +		{ +			return TRUE; +		} +		mute_iter++; +	} +	return FALSE; +} +  //-----------------------------------------------------------------------------  // requestFromServer()  //----------------------------------------------------------------------------- diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h index 3e998b4f0e..4e7b6ee880 100755 --- a/indra/newview/llmutelist.h +++ b/indra/newview/llmutelist.h @@ -101,7 +101,10 @@ public:  	// Name is required to test against legacy text-only mutes.  	BOOL isMuted(const LLUUID& id, const std::string& name = LLStringUtil::null, U32 flags = 0) const; -	 + +	// Workaround for username-based mute search, a lot of string conversions so use cautiously +	BOOL isMuted(const std::string& username, U32 flags = 0) const; +  	// Alternate (convenience) form for places we don't need to pass the name, but do need flags  	BOOL isMuted(const LLUUID& id, U32 flags) const { return isMuted(id, LLStringUtil::null, flags); }; diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp index 54e4c6c1da..79988a0800 100755 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -70,7 +70,7 @@ LLNameListCtrl::LLNameListCtrl(const LLNameListCtrl::Params& p)  // public  LLScrollListItem* LLNameListCtrl::addNameItem(const LLUUID& agent_id, EAddPosition pos, -								 BOOL enabled, const std::string& suffix) +								 BOOL enabled, const std::string& suffix, const std::string& prefix)  {  	//LL_INFOS() << "LLNameListCtrl::addNameItem " << agent_id << LL_ENDL; @@ -79,7 +79,7 @@ LLScrollListItem* LLNameListCtrl::addNameItem(const LLUUID& agent_id, EAddPositi  	item.enabled = enabled;  	item.target = INDIVIDUAL; -	return addNameItemRow(item, pos, suffix); +	return addNameItemRow(item, pos, suffix, prefix);  }  // virtual, public @@ -291,7 +291,8 @@ LLScrollListItem* LLNameListCtrl::addElement(const LLSD& element, EAddPosition p  LLScrollListItem* LLNameListCtrl::addNameItemRow(  	const LLNameListCtrl::NameItem& name_item,  	EAddPosition pos, -	const std::string& suffix) +	const std::string& suffix, +	const std::string& prefix)  {  	LLUUID id = name_item.value().asUUID();  	LLNameListItem* item = new LLNameListItem(name_item,name_item.target() == GROUP); @@ -365,7 +366,7 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow(  	LLScrollListCell* cell = item->getColumn(mNameColumnIndex);  	if (cell)  	{ -		cell->setValue(fullname); +		cell->setValue(prefix + fullname);  	}  	dirtyColumns(); diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h index 2c40eeaaca..515962df7d 100755 --- a/indra/newview/llnamelistctrl.h +++ b/indra/newview/llnamelistctrl.h @@ -129,11 +129,12 @@ public:  	// Add a user to the list by name.  It will be added, the name  	// requested from the cache, and updated as necessary.  	LLScrollListItem* addNameItem(const LLUUID& agent_id, EAddPosition pos = ADD_BOTTOM, -					 BOOL enabled = TRUE, const std::string& suffix = LLStringUtil::null); +					 BOOL enabled = TRUE, const std::string& suffix = LLStringUtil::null, const std::string& prefix = LLStringUtil::null);  	LLScrollListItem* addNameItem(NameItem& item, EAddPosition pos = ADD_BOTTOM);  	/*virtual*/ LLScrollListItem* addElement(const LLSD& element, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL); -	LLScrollListItem* addNameItemRow(const NameItem& value, EAddPosition pos = ADD_BOTTOM, const std::string& suffix = LLStringUtil::null); +	LLScrollListItem* addNameItemRow(const NameItem& value, EAddPosition pos = ADD_BOTTOM, const std::string& suffix = LLStringUtil::null, +																							const std::string& prefix = LLStringUtil::null);  	// Add a user to the list by name.  It will be added, the name  	// requested from the cache, and updated as necessary. diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index 9bd6007772..b7e1b2d3a4 100755 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -1168,6 +1168,8 @@ void LLPanelEditWearable::showWearable(LLViewerWearable* wearable, BOOL show, BO          targetPanel->setVisible(show);          toggleTypeSpecificControls(type); +		// Update type controls here +		updateTypeSpecificControls(type);          if (show)          { @@ -1179,7 +1181,6 @@ void LLPanelEditWearable::showWearable(LLViewerWearable* wearable, BOOL show, BO                  mNameEditor->setText(mWearableItem->getName());                  updatePanelPickerControls(type); -                updateTypeSpecificControls(type);                  // clear and rebuild visual param list                  U8 num_subparts = wearable_entry->mSubparts.size(); diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 9823e84cd9..d7e89b4832 100755 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -307,7 +307,7 @@ private:  						LLMaterialMgr::getInstance()->put(object->getID(),face,*new_material);  					} -					object->setTEMaterialParams(face, new_material); +					object->setTEMaterialParams(face, new_material, TRUE);  					return new_material;  				}  				return NULL; diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp index f67a90fd01..342b57ba4a 100755 --- a/indra/newview/llpanelgroup.cpp +++ b/indra/newview/llpanelgroup.cpp @@ -338,7 +338,7 @@ void LLPanelGroup::update(LLGroupChange gc)  		group_name_ctrl->setToolTip(group_name);  		LLGroupData agent_gdatap; -		bool is_member = gAgent.getGroupData(mID,agent_gdatap) || gAgent.isGodlike(); +		bool is_member = gAgent.getGroupData(mID,agent_gdatap) || gAgent.isGodlikeWithoutAdminMenuFakery();  		bool join_btn_visible = !is_member && gdatap->mOpenEnrollment;  		mButtonJoin->setVisible(join_btn_visible); @@ -470,7 +470,7 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id)  		}  		LLGroupData agent_gdatap; -		bool is_member = gAgent.getGroupData(mID,agent_gdatap) || gAgent.isGodlike(); +		bool is_member = gAgent.getGroupData(mID,agent_gdatap) || gAgent.isGodlikeWithoutAdminMenuFakery();  		tab_roles->setVisible(is_member);  		tab_notices->setVisible(is_member); diff --git a/indra/newview/llpanelgroupbulk.cpp b/indra/newview/llpanelgroupbulk.cpp index 76792cc6fd..cffda02aa0 100644 --- a/indra/newview/llpanelgroupbulk.cpp +++ b/indra/newview/llpanelgroupbulk.cpp @@ -97,6 +97,7 @@ void LLPanelGroupBulkImpl::callbackClickAdd(void* userdata)  		if(picker)  		{  			root_floater->addDependentFloater(picker); +			LLGroupMgr::getInstance()->sendCapGroupMembersRequest(panelp->mImplementation->mGroupID);  		}  	}  } diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index 7ffaa05919..b2164c1f21 100755 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -287,11 +287,6 @@ void LLPanelGroupGeneral::activate()  	{  		LLGroupMgr::getInstance()->sendGroupTitlesRequest(mGroupID);  		LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mGroupID); -		 -		if (!gdatap || !gdatap->isMemberDataComplete() ) -		{ -			LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); -		}  		mFirstUse = FALSE;  	} diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp index e662a05dfc..866cb8dbef 100755 --- a/indra/newview/llpanelgroupinvite.cpp +++ b/indra/newview/llpanelgroupinvite.cpp @@ -243,56 +243,59 @@ void LLPanelGroupInvite::impl::addRoleNames(LLGroupMgrGroupData* gdatap)  	LLGroupMgrGroupData::member_list_t::iterator agent_iter =  		gdatap->mMembers.find(gAgent.getID()); +	//loop over the agent's roles in the group +	//then add those roles to the list of roles that the agent +	//can invite people to be. +	//if the user is the owner then we add +	//all of the roles in the group, +	//else if they have the add to roles power +	//we add every role but owner, +	//else if they have the limited add to roles power +	//we add every role the user is in, +	//else we just add to everyone +	bool is_owner = FALSE; +	bool can_assign_any = gAgent.hasPowerInGroup(mGroupID, +												 GP_ROLE_ASSIGN_MEMBER); +	bool can_assign_limited = gAgent.hasPowerInGroup(mGroupID, +													 GP_ROLE_ASSIGN_MEMBER_LIMITED); +	LLGroupMemberData* member_data = NULL;  	//get the member data for the agent if it exists -	if ( agent_iter != gdatap->mMembers.end() ) +	if (agent_iter != gdatap->mMembers.end())  	{ -		LLGroupMemberData* member_data = (*agent_iter).second; - -		//loop over the agent's roles in the group -		//then add those roles to the list of roles that the agent -		//can invite people to be -		if ( member_data && mRoleNames) +		member_data = (*agent_iter).second; +		if (member_data && mRoleNames)  		{ -			//if the user is the owner then we add -			//all of the roles in the group -			//else if they have the add to roles power -			//we add every role but owner, -			//else if they have the limited add to roles power -			//we add every role the user is in -			//else we just add to everyone -			bool is_owner   = member_data->isOwner(); -			bool can_assign_any = gAgent.hasPowerInGroup(mGroupID, -												 GP_ROLE_ASSIGN_MEMBER); -			bool can_assign_limited = gAgent.hasPowerInGroup(mGroupID, -												 GP_ROLE_ASSIGN_MEMBER_LIMITED); +			is_owner = member_data->isOwner(); +		}//end if member data is not null +	}//end if agent is in the group + -			LLGroupMgrGroupData::role_list_t::iterator rit = gdatap->mRoles.begin(); -			LLGroupMgrGroupData::role_list_t::iterator end = gdatap->mRoles.end(); -			//populate the role list -			for ( ; rit != end; ++rit) +	LLGroupMgrGroupData::role_list_t::iterator rit = gdatap->mRoles.begin(); +	LLGroupMgrGroupData::role_list_t::iterator end = gdatap->mRoles.end(); + +	//populate the role list: +	for ( ; rit != end; ++rit) +	{ +		LLUUID role_id = (*rit).first; +		LLRoleData rd; +		if ( gdatap->getRoleData(role_id,rd) ) +		{ +			// Owners can add any role. +			if ( is_owner  +				// Even 'can_assign_any' can't add owner role. +				|| (can_assign_any && role_id != gdatap->mOwnerRole) +				// Add all roles user is in +				|| (can_assign_limited && member_data && member_data->isInRole(role_id)) +				// Everyone role. +				|| role_id == LLUUID::null )  			{ -				LLUUID role_id = (*rit).first; -				LLRoleData rd; -				if ( gdatap->getRoleData(role_id,rd) ) -				{ -					// Owners can add any role. -					if ( is_owner  -						// Even 'can_assign_any' can't add owner role. -						 || (can_assign_any && role_id != gdatap->mOwnerRole) -						// Add all roles user is in -						 || (can_assign_limited && member_data->isInRole(role_id)) -						// Everyone role. -						 || role_id == LLUUID::null ) -					{ -							mRoleNames->add(rd.mRoleName, -											role_id, -											ADD_BOTTOM); -					} -				} +				mRoleNames->add(rd.mRoleName, +								role_id, +								ADD_BOTTOM);  			} -		}//end if member data is not null -	}//end if agent is in the group +		} +	}  }  //static @@ -579,7 +582,8 @@ void LLPanelGroupInvite::updateLists()  		{  			waiting = true;  		} -		if (gdatap->isRoleDataComplete() && gdatap->isMemberDataComplete() && gdatap->isRoleMemberDataComplete())  +		if (gdatap->isRoleDataComplete() && gdatap->isMemberDataComplete() +			&& (gdatap->isRoleMemberDataComplete() || !gdatap->mMembers.size())) // MAINT-5270: large groups receives an empty members list without some powers, so RoleMemberData wouldn't be complete for them  		{  			if ( mImplementation->mRoleNames )  			{ diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index c3a10b3fa0..00c204e702 100755 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -350,12 +350,10 @@ void LLPanelGroupRoles::update(LLGroupChange gc)  void LLPanelGroupRoles::activate()  { +	if (!gAgent.isInGroup(mGroupID)) return; +  	// Start requesting member and role data if needed.  	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); -	if (!gdatap || !gdatap->isMemberDataComplete() ) -	{ -		LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); -	}  	if (!gdatap || !gdatap->isRoleDataComplete() )  	{ @@ -364,13 +362,7 @@ void LLPanelGroupRoles::activate()  		LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mGroupID);  	} - -	// Check role-member mapping data. -	if (!gdatap || !gdatap->isRoleMemberDataComplete() ) -	{ -		LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mGroupID); -	} - +	  	// Need this to get base group member powers  	if (!gdatap || !gdatap->isGroupPropertiesDataComplete() )  	{ @@ -1163,7 +1155,37 @@ void LLPanelGroupMembersSubTab::onEjectMembers(void *userdata)  	if ( selfp )  	{ -		selfp->handleEjectMembers(); +		selfp->confirmEjectMembers(); +	} +} + +void LLPanelGroupMembersSubTab::confirmEjectMembers() +{ +	std::vector<LLScrollListItem*> selection = mMembersList->getAllSelected(); +	if (selection.empty()) return; + +	S32 selection_count = selection.size(); +	if (selection_count == 1) +	{ +		LLSD args; +		std::string fullname; +		gCacheName->getFullName(mMembersList->getValue(), fullname); +		args["AVATAR_NAME"] = fullname; +		LLSD payload; +		LLNotificationsUtil::add("EjectGroupMemberWarning", +				 	 	 	 	 args, +								 payload, +								 boost::bind(&LLPanelGroupMembersSubTab::handleEjectCallback, this, _1, _2)); +	} +	else +	{ +		LLSD args; +		args["COUNT"] = llformat("%d", selection_count); +		LLSD payload; +		LLNotificationsUtil::add("EjectGroupMembersWarning", +				 	 	 	 	 args, +								 payload, +								 boost::bind(&LLPanelGroupMembersSubTab::handleEjectCallback, this, _1, _2));  	}  } @@ -1190,6 +1212,16 @@ void LLPanelGroupMembersSubTab::handleEjectMembers()  	LLGroupMgr::getInstance()->sendGroupMemberEjects(mGroupID, selected_members);  } +bool LLPanelGroupMembersSubTab::handleEjectCallback(const LLSD& notification, const LLSD& response) +{ +	S32 option = LLNotificationsUtil::getSelectedOption(notification, response); +	if (0 == option) // Eject button +	{ +		handleEjectMembers(); +	} +	return false; +} +  void LLPanelGroupMembersSubTab::sendEjectNotifications(const LLUUID& group_id, const uuid_vec_t& selected_members)  {  	LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(group_id); @@ -1327,15 +1359,26 @@ void LLPanelGroupMembersSubTab::handleMemberDoubleClick()  void LLPanelGroupMembersSubTab::activate()  { +	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); +  	LLPanelGroupSubTab::activate();  	if(!mActivated)  	{ +		if (!gdatap || !gdatap->isMemberDataComplete()) +		{ +			LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); +		} + +		if (!gdatap || !gdatap->isRoleMemberDataComplete()) +		{ +			LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mGroupID); +		} +  		update(GC_ALL);  		mActivated = true;  	}  	else  	{ -		LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);  		// Members can be removed outside of this tab, checking changes  		if (!gdatap || (gdatap->isMemberDataComplete() && gdatap->mMembers.size() != mMembersList->getItemCount()))  		{ @@ -1636,7 +1679,13 @@ void LLPanelGroupMembersSubTab::update(LLGroupChange gc)  	{  		// Build a string with info on retrieval progress.  		std::ostringstream retrieved; -		if ( !gdatap->isMemberDataComplete() ) + +		if ( gdatap->isRoleDataComplete() && gdatap->isMemberDataComplete() && !gdatap->mMembers.size() ) +		{ +			// MAINT-5237 +			retrieved << "Member list not available."; +		} +		else if ( !gdatap->isMemberDataComplete() )  		{  			// Still busy retreiving member list.  			retrieved << "Retrieving member list (" << gdatap->mMembers.size() @@ -1783,7 +1832,7 @@ void LLPanelGroupMembersSubTab::updateMembers()  		{  			mMembersList->setEnabled(TRUE);  		} -		else +		else if (gdatap->mMembers.size())   		{  			mMembersList->setEnabled(FALSE);  			mMembersList->setCommentText(std::string("No match.")); @@ -1801,7 +1850,47 @@ void LLPanelGroupMembersSubTab::updateMembers()  void LLPanelGroupMembersSubTab::onBanMember(void* user_data)  {  	LLPanelGroupMembersSubTab* self = static_cast<LLPanelGroupMembersSubTab*>(user_data); -	self->handleBanMember(); +	self->confirmBanMembers(); +} + +void LLPanelGroupMembersSubTab::confirmBanMembers() +{ +	std::vector<LLScrollListItem*> selection = mMembersList->getAllSelected(); +	if (selection.empty()) return; + +	S32 selection_count = selection.size(); +	if (selection_count == 1) +	{ +		LLSD args; +		std::string fullname; +		gCacheName->getFullName(mMembersList->getValue(), fullname); +		args["AVATAR_NAME"] = fullname; +		LLSD payload; +		LLNotificationsUtil::add("BanGroupMemberWarning", +				 	 	 	 	 args, +								 payload, +								 boost::bind(&LLPanelGroupMembersSubTab::handleBanCallback, this, _1, _2)); +	} +	else +	{ +		LLSD args; +		args["COUNT"] = llformat("%d", selection_count); +		LLSD payload; +		LLNotificationsUtil::add("BanGroupMembersWarning", +				 	 	 	 	 args, +								 payload, +								 boost::bind(&LLPanelGroupMembersSubTab::handleBanCallback, this, _1, _2)); +	} +} + +bool LLPanelGroupMembersSubTab::handleBanCallback(const LLSD& notification, const LLSD& response) +{ +	S32 option = LLNotificationsUtil::getSelectedOption(notification, response); +	if (0 == option) // Eject button +	{ +		handleBanMember(); +	} +	return false;  }  void LLPanelGroupMembersSubTab::handleBanMember() @@ -2111,20 +2200,7 @@ void LLPanelGroupRolesSubTab::update(LLGroupChange gc)  			mDeleteRoleButton->setEnabled(FALSE);  		}  	} - -	if(!mFirstOpen) -	{ -		if (!gdatap || !gdatap->isMemberDataComplete()) -		{ -			LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); -		} - -		if (!gdatap || !gdatap->isRoleMemberDataComplete()) -		{ -			LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mGroupID); -		} -	} - +	  	if ((GC_ROLE_MEMBER_DATA == gc || GC_MEMBER_DATA == gc)  	    && gdatap  	    && gdatap->isMemberDataComplete() diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h index 540b24ada6..9a696124a8 100755 --- a/indra/newview/llpanelgrouproles.h +++ b/indra/newview/llpanelgrouproles.h @@ -171,6 +171,7 @@ public:  	void handleEjectMembers();  	void sendEjectNotifications(const LLUUID& group_id, const uuid_vec_t& selected_members);  	bool handleEjectCallback(const LLSD& notification, const LLSD& response); +	void confirmEjectMembers();  	static void onRoleCheck(LLUICtrl* check, void* user_data);  	void handleRoleCheck(const LLUUID& role_id, @@ -178,6 +179,8 @@ public:  	static void onBanMember(void* user_data);  	void handleBanMember(); +	bool handleBanCallback(const LLSD& notification, const LLSD& response); +	void confirmBanMembers();  	void applyMemberChanges(); diff --git a/indra/newview/llpanellandmarkinfo.cpp b/indra/newview/llpanellandmarkinfo.cpp index a660cb3b21..06bb886ae8 100755 --- a/indra/newview/llpanellandmarkinfo.cpp +++ b/indra/newview/llpanellandmarkinfo.cpp @@ -128,6 +128,10 @@ void LLPanelLandmarkInfo::setInfoType(EInfoType type)  			LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();  			std::string name = parcel_mgr->getAgentParcelName();  			LLVector3 agent_pos = gAgent.getPositionAgent(); +			 +			std::string desc; +			LLAgentUI::buildLocationString(desc, LLAgentUI::LOCATION_FORMAT_FULL, agent_pos); +			mNotesEditor->setText(desc);			  			if (name.empty())  			{ @@ -143,7 +147,8 @@ void LLPanelLandmarkInfo::setInfoType(EInfoType type)  				}  				else  				{ -					region_name = getString("unknown"); +					LLAgentUI::buildLocationString(desc, LLAgentUI::LOCATION_FORMAT_NORMAL, agent_pos); +					region_name = desc;  				}  				mLandmarkTitleEditor->setText(llformat("%s (%d, %d, %d)", @@ -154,10 +159,6 @@ void LLPanelLandmarkInfo::setInfoType(EInfoType type)  				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. diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index cc8c3edd51..953f234a53 100755 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -229,7 +229,6 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,  		}  	}  	server_choice_combo->sortByName(); -	server_choice_combo->addSeparator(ADD_TOP);  	LL_DEBUGS("AppInit")<<"adding current "<<current_grid<<LL_ENDL;  	server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(),   							 current_grid, diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index 17c0b226d0..4229419fce 100755 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -604,7 +604,7 @@ void LLPanelMainInventory::updateItemcountText()  	}  	else  	{ -		text = getString("ItemcountUnknown"); +		text = getString("ItemcountUnknown", string_args);  	}      mCounterCtrl->setValue(text); @@ -1134,14 +1134,12 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)  		const LLUUID& item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();  		const std::string &item_name = current_item->getViewModelItem()->getName();  		mFilterSubString = item_name; +  		LLInventoryFilter &filter = mActivePanel->getFilter(); -		filter.setFilterSubString(item_name); -		mFilterEditor->setText(item_name); +		filter.setFindAllLinksMode(item_name, item_id); +		mFilterEditor->setText(item_name);  		mFilterEditor->setFocus(TRUE); -		filter.setFilterUUID(item_id); -		filter.setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); -		filter.setFilterLinks(LLInventoryFilter::FILTERLINK_ONLY_LINKS);  	}  } diff --git a/indra/newview/llpanelmediasettingsgeneral.cpp b/indra/newview/llpanelmediasettingsgeneral.cpp index 2856ea9db1..d7c43c224c 100755 --- a/indra/newview/llpanelmediasettingsgeneral.cpp +++ b/indra/newview/llpanelmediasettingsgeneral.cpp @@ -319,6 +319,10 @@ void LLPanelMediaSettingsGeneral::initValues( void* userdata, const LLSD& _media  // Helper to set media control to media URL as required  void LLPanelMediaSettingsGeneral::updateMediaPreview()  { +	if(LLTrans::getString("Multiple Media") == mHomeURL->getValue().asString()) +	{ +		return; +	}  	if ( mHomeURL->getValue().asString().length() > 0 )  	{  		if(mPreviewMedia->getCurrentNavUrl() != mHomeURL->getValue().asString()) diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index dcd0aab3ab..420f8fde2e 100755 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -2000,7 +2000,11 @@ void LLPanelObject::onCancelSculpt(const LLSD& data)  	LLTextureCtrl* mTextureCtrl = getChild<LLTextureCtrl>("sculpt texture control");  	if(!mTextureCtrl)  		return; -	 + +	if(mSculptTextureRevert == LLUUID::null) +	{ +		mSculptTextureRevert = LLUUID(SCULPT_DEFAULT_TEXTURE); +	}  	mTextureCtrl->setImageAssetID(mSculptTextureRevert);  	sendSculpt(); diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index bf15f56b44..1ae9d916b3 100755 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -1163,7 +1163,13 @@ void LLTaskNotecardBridge::openItem()  	{  		return;  	} -	if(object->permModify() || gAgent.isGodlike()) + +	// Note: even if we are not allowed to modify copyable notecard, we should be able to view it +	LLInventoryItem *item = dynamic_cast<LLInventoryItem*>(object->getInventoryObject(mUUID)); +	BOOL item_copy = item && gAgent.allowOperation(PERM_COPY, item->getPermissions(), GP_OBJECT_MANIPULATE); +	if( item_copy +		|| object->permModify() +		|| gAgent.isGodlike())  	{  		LLPreviewNotecard* preview = LLFloaterReg::showTypedInstance<LLPreviewNotecard>("preview_notecard", LLSD(mUUID), TAKE_FOCUS_YES);  		if (preview) diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 5977d558d3..de4efc8612 100755 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -85,6 +85,8 @@ static const std::string RECENT_TAB_NAME	= "recent_panel";  static const std::string BLOCKED_TAB_NAME	= "blocked_panel"; // blocked avatars  static const std::string COLLAPSED_BY_USER  = "collapsed_by_user"; +const S32 BASE_MAX_AGENT_GROUPS = 42; +const S32 PREMIUM_MAX_AGENT_GROUPS = 60;  extern S32 gMaxAgentGroups; @@ -585,6 +587,7 @@ BOOL LLPanelPeople::postBuild()  	getChild<LLFilterEditor>("groups_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));  	getChild<LLFilterEditor>("recent_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));  	getChild<LLFilterEditor>("fbc_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2)); +	getChild<LLTextBox>("groupcount")->setURLClickedCallback(boost::bind(&LLPanelPeople::onGroupLimitInfo, this));  	mTabContainer = getChild<LLTabContainer>("tabs");  	mTabContainer->setCommitCallback(boost::bind(&LLPanelPeople::onTabSelected, this, _2)); @@ -902,8 +905,11 @@ void LLPanelPeople::updateButtons()  		LLPanel* groups_panel = mTabContainer->getCurrentPanel();  		groups_panel->getChildView("minus_btn")->setEnabled(item_selected && selected_id.notNull()); // a real group selected -		groups_panel->getChild<LLUICtrl>("groupcount")->setTextArg("[COUNT]", llformat("%d",gAgent.mGroups.size())); -		groups_panel->getChild<LLUICtrl>("groupcount")->setTextArg("[REMAINING]", llformat("%d",(gMaxAgentGroups-gAgent.mGroups.size()))); + +		U32 groups_count = gAgent.mGroups.size(); +		U32 groups_ramaining = gMaxAgentGroups > groups_count ? gMaxAgentGroups - groups_count : 0; +		groups_panel->getChild<LLUICtrl>("groupcount")->setTextArg("[COUNT]", llformat("%d", groups_count)); +		groups_panel->getChild<LLUICtrl>("groupcount")->setTextArg("[REMAINING]", llformat("%d", groups_ramaining));  	}  	else  	{ @@ -1114,6 +1120,14 @@ void LLPanelPeople::onFilterEdit(const std::string& search_string)  	}  } +void LLPanelPeople::onGroupLimitInfo() +{ +	LLSD args; +	args["MAX_BASIC"] = BASE_MAX_AGENT_GROUPS; +	args["MAX_PREMIUM"] = PREMIUM_MAX_AGENT_GROUPS; +	LLNotificationsUtil::add("GroupLimitInfo", args); +} +  void LLPanelPeople::onTabSelected(const LLSD& param)  {  	std::string tab_name = getChild<LLPanel>(param.asString())->getName(); diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h index c1d7a134fa..eb7e76a772 100755 --- a/indra/newview/llpanelpeople.h +++ b/indra/newview/llpanelpeople.h @@ -93,6 +93,7 @@ private:  	// UI callbacks  	void					onFilterEdit(const std::string& search_string); +	void					onGroupLimitInfo();  	void					onTabSelected(const LLSD& param);  	void					onAddFriendButtonClicked();  	void					onAddFriendWizButtonClicked(); diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp index d73a5b402e..55c09d85ea 100755 --- a/indra/newview/llpanelpicks.cpp +++ b/indra/newview/llpanelpicks.cpp @@ -432,7 +432,7 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)  		mNoPicks = !mPicksList->size();  	} -	else if(APT_CLASSIFIEDS == type) +	else if((APT_CLASSIFIEDS == type) || (APT_CLASSIFIED_INFO == type))  	{  		LLAvatarClassifieds* c_info = static_cast<LLAvatarClassifieds*>(data);  		if(c_info && getAvatarId() == c_info->target_id) diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp index e853b2d050..1a665d4c1d 100755 --- a/indra/newview/llpanelplaceprofile.cpp +++ b/indra/newview/llpanelplaceprofile.cpp @@ -53,6 +53,8 @@  #include "llviewerparcelmgr.h"  #include "llviewerregion.h" +const F64 COVENANT_REFRESH_TIME_SEC = 60.0f; +  static LLPanelInjector<LLPanelPlaceProfile> t_place_profile("panel_place_profile");  // Statics for textures filenames @@ -76,6 +78,7 @@ static std::string icon_see_avs_off;  LLPanelPlaceProfile::LLPanelPlaceProfile()  :	LLPanelPlaceInfo(), +	mNextCovenantUpdateTime(0),  	mForSalePanel(NULL),  	mYouAreHerePanel(NULL),  	mSelectedParcelID(-1), @@ -162,6 +165,9 @@ BOOL LLPanelPlaceProfile::postBuild()  	icon_see_avs_on = getString("icon_SeeAVs_On");  	icon_see_avs_off = getString("icon_SeeAVs_Off"); +	mLastSelectedRegionID = LLUUID::null; +	mNextCovenantUpdateTime = 0; +  	return TRUE;  } @@ -170,6 +176,9 @@ void LLPanelPlaceProfile::resetLocation()  {  	LLPanelPlaceInfo::resetLocation(); +	mLastSelectedRegionID = LLUUID::null; +	mNextCovenantUpdateTime = 0; +  	mForSalePanel->setVisible(FALSE);  	mYouAreHerePanel->setVisible(FALSE); @@ -330,13 +339,20 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,  	if (!region || !parcel)  		return; -	// send EstateCovenantInfo message -	LLMessageSystem *msg = gMessageSystem; -	msg->newMessage("EstateCovenantRequest"); -	msg->nextBlockFast(_PREHASH_AgentData); -	msg->addUUIDFast(_PREHASH_AgentID,	gAgent.getID()); -	msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID()); -	msg->sendReliable(region->getHost()); +	if (mLastSelectedRegionID != region->getRegionID() +		|| mNextCovenantUpdateTime < LLTimer::getElapsedSeconds()) +	{ +		// send EstateCovenantInfo message +		// Note: LLPanelPlaceProfile doesn't change Covenant's content and any +		// changes made by Estate floater should be requested by Estate floater +		LLMessageSystem *msg = gMessageSystem; +		msg->newMessage("EstateCovenantRequest"); +		msg->nextBlockFast(_PREHASH_AgentData); +		msg->addUUIDFast(_PREHASH_AgentID,	gAgent.getID()); +		msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID()); +		msg->sendReliable(region->getHost()); +		mNextCovenantUpdateTime = LLTimer::getElapsedSeconds() + COVENANT_REFRESH_TIME_SEC; +	}  	LLParcelData parcel_data; diff --git a/indra/newview/llpanelplaceprofile.h b/indra/newview/llpanelplaceprofile.h index 4547e14b2e..3d2654fc12 100755 --- a/indra/newview/llpanelplaceprofile.h +++ b/indra/newview/llpanelplaceprofile.h @@ -71,6 +71,7 @@ private:  	 */  	S32					mSelectedParcelID;  	LLUUID				mLastSelectedRegionID; +	F64					mNextCovenantUpdateTime;  //seconds since client start  	LLPanel*			mForSalePanel;  	LLPanel*			mYouAreHerePanel; diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 4bcd932d4b..a9a0c30e26 100755 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -921,7 +921,12 @@ void LLPanelPlaces::onBackButtonClicked()  void LLPanelPlaces::togglePickPanel(BOOL visible)  {  	if (mPickPanel) +	{  		mPickPanel->setVisible(visible); +		mPlaceProfile->setVisible(!visible); +		updateVerbs(); +	} +  }  void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible) @@ -1141,16 +1146,21 @@ void LLPanelPlaces::updateVerbs()  	bool is_agent_place_info_visible = mPlaceInfoType == AGENT_INFO_TYPE;  	bool is_create_landmark_visible = mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE; +	bool is_pick_panel_visible = false; +	if(mPickPanel) +	{ +		is_pick_panel_visible = mPickPanel->isInVisibleChain(); +	}  	bool have_3d_pos = ! mPosGlobal.isExactlyZero(); -	mTeleportBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn); -	mShowOnMapBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn); +	mTeleportBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible); +	mShowOnMapBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible);  	mOverflowBtn->setVisible(is_place_info_visible && !is_create_landmark_visible && !isLandmarkEditModeOn);  	mEditBtn->setVisible(mPlaceInfoType == LANDMARK_INFO_TYPE && !isLandmarkEditModeOn);  	mSaveBtn->setVisible(isLandmarkEditModeOn);  	mCancelBtn->setVisible(isLandmarkEditModeOn);  	mCloseBtn->setVisible(is_create_landmark_visible && !isLandmarkEditModeOn); -	mPlaceInfoBtn->setVisible(!is_place_info_visible && !is_create_landmark_visible && !isLandmarkEditModeOn); +	mPlaceInfoBtn->setVisible(!is_place_info_visible && !is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible);  	mPlaceInfoBtn->setEnabled(!is_create_landmark_visible && !isLandmarkEditModeOn && have_3d_pos); diff --git a/indra/newview/llpanelsnapshotinventory.cpp b/indra/newview/llpanelsnapshotinventory.cpp index c8a201a5c8..c55e230b5e 100755 --- a/indra/newview/llpanelsnapshotinventory.cpp +++ b/indra/newview/llpanelsnapshotinventory.cpp @@ -48,6 +48,8 @@ public:  	/*virtual*/ BOOL postBuild();  	/*virtual*/ void onOpen(const LLSD& key); +	void onResolutionCommit(LLUICtrl* ctrl); +  private:  	/*virtual*/ std::string getWidthSpinnerName() const		{ return "inventory_snapshot_width"; }  	/*virtual*/ std::string getHeightSpinnerName() const	{ return "inventory_snapshot_height"; } @@ -72,6 +74,8 @@ BOOL LLPanelSnapshotInventory::postBuild()  {  	getChild<LLSpinCtrl>(getWidthSpinnerName())->setAllowEdit(FALSE);  	getChild<LLSpinCtrl>(getHeightSpinnerName())->setAllowEdit(FALSE); + +	getChild<LLUICtrl>(getImageSizeComboName())->setCommitCallback(boost::bind(&LLPanelSnapshotInventory::onResolutionCommit, this, _1));  	return LLPanelSnapshot::postBuild();  } @@ -89,6 +93,13 @@ void LLPanelSnapshotInventory::updateControls(const LLSD& info)  	getChild<LLUICtrl>("save_btn")->setEnabled(have_snapshot);  } +void LLPanelSnapshotInventory::onResolutionCommit(LLUICtrl* ctrl) +{ +	BOOL current_window_selected = (getChild<LLComboBox>(getImageSizeComboName())->getCurrentIndex() == 3); +	getChild<LLSpinCtrl>(getWidthSpinnerName())->setVisible(!current_window_selected); +	getChild<LLSpinCtrl>(getHeightSpinnerName())->setVisible(!current_window_selected); +} +  void LLPanelSnapshotInventory::onSend()  {  	LLFloaterSnapshot::saveTexture(); diff --git a/indra/newview/llpanelsnapshotlocal.cpp b/indra/newview/llpanelsnapshotlocal.cpp index 43e38b95e2..01dfdc4ece 100755 --- a/indra/newview/llpanelsnapshotlocal.cpp +++ b/indra/newview/llpanelsnapshotlocal.cpp @@ -58,6 +58,8 @@ private:  	/*virtual*/ LLFloaterSnapshot::ESnapshotFormat getImageFormat() const;  	/*virtual*/ void updateControls(const LLSD& info); +	S32 mLocalFormat; +  	void onFormatComboCommit(LLUICtrl* ctrl);  	void onQualitySliderCommit(LLUICtrl* ctrl);  	void onSaveFlyoutCommit(LLUICtrl* ctrl); @@ -67,6 +69,7 @@ static LLPanelInjector<LLPanelSnapshotLocal> panel_class("llpanelsnapshotlocal")  LLPanelSnapshotLocal::LLPanelSnapshotLocal()  { +	mLocalFormat = gSavedSettings.getS32("SnapshotFormat");  	mCommitCallbackRegistrar.add("Local.Cancel",	boost::bind(&LLPanelSnapshotLocal::cancel,		this));  } @@ -83,6 +86,10 @@ BOOL LLPanelSnapshotLocal::postBuild()  // virtual  void LLPanelSnapshotLocal::onOpen(const LLSD& key)  { +	if(gSavedSettings.getS32("SnapshotFormat") != mLocalFormat) +	{ +		getChild<LLComboBox>("local_format_combo")->selectNthItem(mLocalFormat); +	}  	LLPanelSnapshot::onOpen(key);  } @@ -129,6 +136,7 @@ void LLPanelSnapshotLocal::updateControls(const LLSD& info)  void LLPanelSnapshotLocal::onFormatComboCommit(LLUICtrl* ctrl)  { +	mLocalFormat = getImageFormat();  	// will call updateControls()  	LLFloaterSnapshot::getInstance()->notify(LLSD().with("image-format-change", true));  } diff --git a/indra/newview/llpanelsnapshotpostcard.cpp b/indra/newview/llpanelsnapshotpostcard.cpp index 8e37b1418c..8e37b1418c 100755..100644 --- a/indra/newview/llpanelsnapshotpostcard.cpp +++ b/indra/newview/llpanelsnapshotpostcard.cpp diff --git a/indra/newview/llpreview.cpp b/indra/newview/llpreview.cpp index bf2652cb49..fb21b980dc 100755 --- a/indra/newview/llpreview.cpp +++ b/indra/newview/llpreview.cpp @@ -49,6 +49,7 @@  #include "llviewerinventory.h"  #include "llviewerwindow.h"  #include "lltrans.h" +#include "roles_constants.h"  // Constants @@ -230,8 +231,23 @@ void LLPreview::refreshFromItem()  	}  	getChild<LLUICtrl>("desc")->setValue(item->getDescription()); -	BOOL can_agent_manipulate = item->getPermissions().allowModifyBy(gAgent.getID()); -	getChildView("desc")->setEnabled(can_agent_manipulate); +	getChildView("desc")->setEnabled(canModify(mObjectUUID, item)); +} + +// static +BOOL LLPreview::canModify(const LLUUID taskUUID, const LLInventoryItem* item) +{ +	if (taskUUID.notNull()) +	{ +		LLViewerObject* object = gObjectList.findObject(taskUUID); +		if(object && !object->permModify()) +		{ +			// No permission to edit in-world inventory +			return FALSE; +		} +	} + +	return item && gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE);  }  // static  diff --git a/indra/newview/llpreview.h b/indra/newview/llpreview.h index 759430c3a5..49c114720b 100755 --- a/indra/newview/llpreview.h +++ b/indra/newview/llpreview.h @@ -105,7 +105,11 @@ public:  	// llview  	/*virtual*/ void draw();  	void refreshFromItem(); -	 + +	// We can't modify Item or description in preview if either in-world Object +	// or Item  itself is unmodifiable +	static BOOL canModify(const LLUUID taskUUID, const LLInventoryItem* item); +  protected:  	virtual void onCommit(); diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp index 1308d1e9a7..9f88b0db5f 100755 --- a/indra/newview/llpreviewnotecard.cpp +++ b/indra/newview/llpreviewnotecard.cpp @@ -218,7 +218,7 @@ void LLPreviewNotecard::loadAsset()  		LLPermissions perm(item->getPermissions());  		BOOL is_owner = gAgent.allowOperation(PERM_OWNER, perm, GP_OBJECT_MANIPULATE);  		BOOL allow_copy = gAgent.allowOperation(PERM_COPY, perm, GP_OBJECT_MANIPULATE); -		BOOL allow_modify = gAgent.allowOperation(PERM_MODIFY, perm, GP_OBJECT_MANIPULATE); +		BOOL allow_modify = canModify(mObjectUUID, item);  		if (allow_copy || gAgent.isGodlike())  		{ @@ -338,10 +338,7 @@ void LLPreviewNotecard::onLoadComplete(LLVFS *vfs,  			}  			previewEditor->makePristine(); - -			const LLInventoryItem* item = preview->getItem(); -			BOOL modifiable = item && gAgent.allowOperation(PERM_MODIFY, -								item->getPermissions(), GP_OBJECT_MANIPULATE); +			BOOL modifiable = preview->canModify(preview->mObjectID, preview->getItem());  			preview->setEnabled(modifiable);  			preview->mAssetStatus = PREVIEW_ASSET_LOADED;  		} diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 1bbb22416d..f4bcec344c 100755 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -2621,8 +2621,12 @@ void LLLiveLSLEditor::onLoad(void* userdata)  void LLLiveLSLEditor::onSave(void* userdata, BOOL close_after_save)  {  	LLLiveLSLEditor* self = (LLLiveLSLEditor*)userdata; -	self->mCloseAfterSave = close_after_save; -	self->saveIfNeeded(); +	if(self) +	{ +		self->mCloseAfterSave = close_after_save; +		self->mScriptEd->mErrorList->setCommentText(""); +		self->saveIfNeeded(); +	}  } diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp index f91a18d8d3..c8cf0faa15 100755 --- a/indra/newview/llpreviewtexture.cpp +++ b/indra/newview/llpreviewtexture.cpp @@ -618,4 +618,5 @@ void LLPreviewTexture::setObjectID(const LLUUID& object_id)  		mAssetStatus = PREVIEW_ASSET_UNLOADED;  		loadAsset();  	} +	refreshFromItem();  } diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp index 179a73413e..02912f12a9 100644 --- a/indra/newview/llscenemonitor.cpp +++ b/indra/newview/llscenemonitor.cpp @@ -39,6 +39,7 @@  #include "llspatialpartition.h"  #include "llagent.h"  #include "pipeline.h" +#include "llviewerparcelmgr.h"  #include "llviewerpartsim.h"  LLSceneMonitorView* gSceneMonitorView = NULL; @@ -702,6 +703,13 @@ LLSceneMonitorView::LLSceneMonitorView(const LLRect& rect)  	setCanMinimize(false);  	setCanClose(true); + +	sTeleportFinishConnection = LLViewerParcelMgr::getInstance()->setTeleportFinishedCallback(boost::bind(&LLSceneMonitorView::onTeleportFinished, this)); +} + +LLSceneMonitorView::~LLSceneMonitorView() +{ +	sTeleportFinishConnection.disconnect();  }  void LLSceneMonitorView::onClose(bool app_quitting) @@ -714,6 +722,14 @@ void LLSceneMonitorView::onClickCloseBtn(bool app_quitting)  	setVisible(false);  } +void LLSceneMonitorView::onTeleportFinished() +{ +	if(isInVisibleChain()) +	{ +		LLSceneMonitor::getInstance()->reset(); +	} +} +  void LLSceneMonitorView::onVisibilityChange(BOOL visible)  {  	if (!LLGLSLShader::sNoFixedFunction && visible) diff --git a/indra/newview/llscenemonitor.h b/indra/newview/llscenemonitor.h index 5bde3b5aab..2b6ea57b96 100644 --- a/indra/newview/llscenemonitor.h +++ b/indra/newview/llscenemonitor.h @@ -64,10 +64,12 @@ public:  	void dumpToFile(std::string file_name);  	bool hasResults() const { return mSceneLoadRecording.getResults().getDuration() != S32Seconds(0);} +	void reset(); +  private:  	void freezeScene();  	void unfreezeScene(); -	void reset(); +  	LLRenderTarget& getCaptureTarget();  	void generateDitheringTexture(S32 width, S32 height); @@ -109,7 +111,7 @@ class LLSceneMonitorView : public LLFloater  {  public:  	LLSceneMonitorView(const LLRect& rect); - +	~LLSceneMonitorView();  	virtual void draw();  	virtual void onVisibilityChange(BOOL visible); @@ -117,6 +119,8 @@ public:  protected:  	virtual void onClose(bool app_quitting=false);  	virtual void onClickCloseBtn(bool app_quitting=false); +	void onTeleportFinished(); +	boost::signals2::connection sTeleportFinishConnection;  };  extern LLSceneMonitorView* gSceneMonitorView; diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 69c577f445..ad86995b42 100755 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -620,10 +620,41 @@ bool LLSelectMgr::linkObjects()  bool LLSelectMgr::unlinkObjects()  { +	LLViewerObject *object = mSelectedObjects->getFirstRootObject(); +	if (!object) return false; + +	S32 min_objects_for_confirm = gSavedSettings.getS32("MinObjectsForUnlinkConfirm"); +	for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();  iter != getSelection()->root_end(); iter++) +	{ +		object = (*iter)->getObject(); +		if(object) +		{ +			S32 objects_in_linkset = object->numChildren() + 1; +			if(objects_in_linkset >= min_objects_for_confirm) +			{ +				LLNotificationsUtil::add("ConfirmUnlink", LLSD(), LLSD(), boost::bind(&LLSelectMgr::confirmUnlinkObjects, this, _1, _2)); +				return true; +			} +		} +	} +  	LLSelectMgr::getInstance()->sendDelink();  	return true;  } +void LLSelectMgr::confirmUnlinkObjects(const LLSD& notification, const LLSD& response) +{ +	S32 option = LLNotificationsUtil::getSelectedOption(notification, response); +	// if Cancel pressed +	if (option == 1) +	{ +		return; +	} + +	LLSelectMgr::getInstance()->sendDelink(); +	return; +} +  // in order to link, all objects must have the same owner, and the  // agent must have the ability to modify all of the objects. However,  // we're not answering that question with this method. The question @@ -2104,7 +2135,7 @@ void LLSelectMgr::selectionRemoveMaterial()  			{  			        LL_DEBUGS("Materials") << "Removing material from object " << object->getID() << " face " << face << LL_ENDL;  				LLMaterialMgr::getInstance()->remove(object->getID(),face); -				object->setTEMaterialParams(face, NULL); +				object->setTEMaterialParams(face, NULL, FALSE);  			}  			return true;  		} @@ -4927,6 +4958,7 @@ void LLSelectMgr::sendListToRegions(const std::string& message_name,  									ESendType send_type)  {  	LLSelectNode* node; +	LLSelectNode* linkset_root = NULL;  	LLViewerRegion*	last_region;  	LLViewerRegion*	current_region; @@ -4934,6 +4966,8 @@ void LLSelectMgr::sendListToRegions(const std::string& message_name,  	S32 packets_sent = 0;  	S32 objects_in_this_packet = 0; +	bool link_operation = message_name == "ObjectLink"; +  	//clear update override data (allow next update through)  	struct f : public LLSelectedNodeFunctor  	{ @@ -5042,6 +5076,12 @@ void LLSelectMgr::sendListToRegions(const std::string& message_name,  			&& (! gMessageSystem->isSendFull(NULL))  			&& (objects_in_this_packet < MAX_OBJECTS_PER_PACKET))  		{ +			if (link_operation && linkset_root == NULL) +			{ +				// linksets over 254 will be split into multiple messages, +				// but we need to provide same root for all messages or we will get separate linksets +				linkset_root = node; +			}  			// add another instance of the body of the data  			(*pack_body)(node, user_data);              // do any related logging @@ -5070,6 +5110,22 @@ void LLSelectMgr::sendListToRegions(const std::string& message_name,  			gMessageSystem->newMessage(message_name.c_str());  			(*pack_header)(user_data); +			if (linkset_root != NULL) +			{ +				if (current_region != last_region) +				{ +					// root should be in one region with the child, reset it +					linkset_root = NULL; +				} +				else +				{ +					// add root instance into new message +					(*pack_body)(linkset_root, user_data); +					++objects_sent; +					++objects_in_this_packet; +				} +			} +  			// don't move to the next object, we still need to add the  			// body data.   		} diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 29c111b24f..87d25e3a8c 100755 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -506,6 +506,8 @@ public:  	bool unlinkObjects(); +	void confirmUnlinkObjects(const LLSD& notification, const LLSD& response); +  	bool enableLinkObjects();  	bool enableUnlinkObjects(); diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp index 17ecfab4fb..2548d730f0 100755 --- a/indra/newview/llsidepaneltaskinfo.cpp +++ b/indra/newview/llsidepaneltaskinfo.cpp @@ -370,18 +370,25 @@ void LLSidepanelTaskInfo::refresh()  	// Update creator text field  	getChildView("Creator:")->setEnabled(TRUE); +  	std::string creator_name; -	LLSelectMgr::getInstance()->selectGetCreator(mCreatorID, creator_name); +	LLUUID creator_id; +	LLSelectMgr::getInstance()->selectGetCreator(creator_id, creator_name); -	getChild<LLUICtrl>("Creator Name")->setValue(creator_name); -	getChildView("Creator Name")->setEnabled(TRUE); +	if(creator_id != mCreatorID ) +	{ +		mDACreatorName->setValue(creator_name); +		mCreatorID = creator_id; +	} +	mDACreatorName->setEnabled(TRUE);  	// Update owner text field  	getChildView("Owner:")->setEnabled(TRUE);  	std::string owner_name; -	const BOOL owners_identical = LLSelectMgr::getInstance()->selectGetOwner(mOwnerID, owner_name); -	if (mOwnerID.isNull()) +	LLUUID owner_id; +	const BOOL owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name); +	if (owner_id.isNull())  	{  		if (LLSelectMgr::getInstance()->selectIsGroupOwned())  		{ @@ -402,7 +409,12 @@ void LLSidepanelTaskInfo::refresh()  			}  		}  	} -	getChild<LLUICtrl>("Owner Name")->setValue(owner_name); + +	if(owner_id.isNull() || (owner_id != mOwnerID)) +	{ +		mDAOwnerName->setValue(owner_name); +		mOwnerID = owner_id; +	}  	getChildView("Owner Name")->setEnabled(TRUE);  	// update group text field diff --git a/indra/newview/llslurl.cpp b/indra/newview/llslurl.cpp index 728fc69723..a8e012bfa1 100755 --- a/indra/newview/llslurl.cpp +++ b/indra/newview/llslurl.cpp @@ -271,7 +271,14 @@ LLSLURL::LLSLURL(const std::string& slurl)  			// at this point, head of the path array should be [ <region>, <x>, <y>, <z> ] where x, y and z   			// are collectively optional  			// are optional +  			mRegion = LLURI::unescape(path_array[0].asString()); + +			if(LLStringUtil::containsNonprintable(mRegion)) +			{ +				LLStringUtil::stripNonprintable(mRegion); +			} +  			path_array.erase(0);  			// parse the x, y, and optionally z diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp index 0ae8a338e0..6af9d61a54 100644 --- a/indra/newview/llsnapshotlivepreview.cpp +++ b/indra/newview/llsnapshotlivepreview.cpp @@ -195,7 +195,8 @@ void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail          // Stop shining animation.          mShineAnimTimer.stop();  		mSnapshotDelayTimer.start(); -		mSnapshotDelayTimer.setTimerExpirySec(delay); +		mSnapshotDelayTimer.resetWithExpiry(delay); +  		mPosTakenGlobal = gAgentCamera.getCameraPositionGlobal(); @@ -670,10 +671,27 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview )  		return FALSE;  	} -	// If we're in freeze-frame mode and camera has moved, update snapshot. +	if (previewp->mSnapshotDelayTimer.getStarted()) // Wait for a snapshot delay timer +	{ +		if (!previewp->mSnapshotDelayTimer.hasExpired()) +		{ +			return FALSE; +		} +		previewp->mSnapshotDelayTimer.stop(); +	} + +	if (LLToolCamera::getInstance()->hasMouseCapture()) // Hide full-screen preview while camming, either don't take snapshots while ALT-zoom active +	{ +		previewp->setVisible(FALSE); +		return FALSE; +	} + +	// If we're in freeze-frame and/or auto update mode and camera has moved, update snapshot.  	LLVector3 new_camera_pos = LLViewerCamera::getInstance()->getOrigin();  	LLQuaternion new_camera_rot = LLViewerCamera::getInstance()->getQuaternion(); -	if (previewp->mForceUpdateSnapshot || (gSavedSettings.getBOOL("FreezeTime") && previewp->mAllowFullScreenPreview && +	if (previewp->mForceUpdateSnapshot || +		(((gSavedSettings.getBOOL("AutoSnapshot") && LLView::isAvailable(previewp->mViewContainer)) || +		(gSavedSettings.getBOOL("FreezeTime") && previewp->mAllowFullScreenPreview)) &&  		(new_camera_pos != previewp->mCameraPos || dot(new_camera_rot, previewp->mCameraRot) < 0.995f)))  	{  		previewp->mCameraPos = new_camera_pos; @@ -688,11 +706,7 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview )  		previewp->mForceUpdateSnapshot = FALSE;  	} -	// see if it's time yet to snap the shot and bomb out otherwise. -	previewp->mSnapshotActive =  -		(previewp->mSnapshotDelayTimer.getStarted() &&	previewp->mSnapshotDelayTimer.hasExpired()) -		&& !LLToolCamera::getInstance()->hasMouseCapture(); // don't take snapshots while ALT-zoom active -	if (!previewp->mSnapshotActive && previewp->getSnapshotUpToDate() && previewp->getThumbnailUpToDate()) +	if (previewp->getSnapshotUpToDate() && previewp->getThumbnailUpToDate())  	{  		return FALSE;  	} @@ -706,6 +720,8 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview )              previewp->mPreviewImage = new LLImageRaw;          } +        previewp->mSnapshotActive = TRUE; +          previewp->setVisible(FALSE);          previewp->setEnabled(FALSE); @@ -734,40 +750,9 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview )              // Full size preview is set: get the decoded image result and save it for animation              if (gSavedSettings.getBOOL("UseFreezeFrame") && previewp->mAllowFullScreenPreview)              { -                // Get the decoded version of the formatted image -                previewp->getEncodedImage(); -             -                // We need to scale that a bit for display... -                LLPointer<LLImageRaw> scaled = new LLImageRaw( -                    previewp->mPreviewImageEncoded->getData(), -                    previewp->mPreviewImageEncoded->getWidth(), -                    previewp->mPreviewImageEncoded->getHeight(), -                    previewp->mPreviewImageEncoded->getComponents()); - -                if (!scaled->isBufferInvalid()) -                { -                    // leave original image dimensions, just scale up texture buffer -                    if (previewp->mPreviewImageEncoded->getWidth() > 1024 || previewp->mPreviewImageEncoded->getHeight() > 1024) -                    { -                        // go ahead and shrink image to appropriate power of 2 for display -                        scaled->biasedScaleToPowerOfTwo(1024); -                        previewp->setImageScaled(TRUE); -                    } -                    else -                    { -                        // expand image but keep original image data intact -                        scaled->expandToPowerOfTwo(1024, FALSE); -                    } - -                    previewp->mViewerImage[previewp->mCurImageIndex] = LLViewerTextureManager::getLocalTexture(scaled.get(), FALSE); -                    LLPointer<LLViewerTexture> curr_preview_image = previewp->mViewerImage[previewp->mCurImageIndex]; -                    gGL.getTexUnit(0)->bind(curr_preview_image); -                    curr_preview_image->setFilteringOption(previewp->getSnapshotType() == SNAPSHOT_TEXTURE ? LLTexUnit::TFO_ANISOTROPIC : LLTexUnit::TFO_POINT); -                    curr_preview_image->setAddressMode(LLTexUnit::TAM_CLAMP); - -                    previewp->mShineCountdown = 4; // wait a few frames to avoid animation glitch due to readback this frame -                } +                previewp->prepareFreezeFrame();              } +              // The snapshot is updated now...              previewp->mSnapshotUpToDate = TRUE; @@ -777,7 +762,6 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview )          }          previewp->getWindow()->decBusyCount();          previewp->setVisible(gSavedSettings.getBOOL("UseFreezeFrame") && previewp->mAllowFullScreenPreview); // only show fullscreen preview when in freeze frame mode -        previewp->mSnapshotDelayTimer.stop();          previewp->mSnapshotActive = FALSE;          LL_DEBUGS() << "done creating snapshot" << LL_ENDL;      } @@ -796,6 +780,47 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview )  	return TRUE;  } +void LLSnapshotLivePreview::prepareFreezeFrame() +{ +    // Get the decoded version of the formatted image +    getEncodedImage(); + +    // We need to scale that a bit for display... +    LLPointer<LLImageRaw> scaled = new LLImageRaw( +        mPreviewImageEncoded->getData(), +        mPreviewImageEncoded->getWidth(), +        mPreviewImageEncoded->getHeight(), +        mPreviewImageEncoded->getComponents()); + +    if (!scaled->isBufferInvalid()) +    { +        // leave original image dimensions, just scale up texture buffer +        if (mPreviewImageEncoded->getWidth() > 1024 || mPreviewImageEncoded->getHeight() > 1024) +        { +            // go ahead and shrink image to appropriate power of 2 for display +            scaled->biasedScaleToPowerOfTwo(1024); +            setImageScaled(TRUE); +        } +        else +        { +            // expand image but keep original image data intact +            scaled->expandToPowerOfTwo(1024, FALSE); +        } + +        mViewerImage[mCurImageIndex] = LLViewerTextureManager::getLocalTexture(scaled.get(), FALSE); +        LLPointer<LLViewerTexture> curr_preview_image = mViewerImage[mCurImageIndex]; +        gGL.getTexUnit(0)->bind(curr_preview_image); +        curr_preview_image->setFilteringOption(getSnapshotType() == SNAPSHOT_TEXTURE ? LLTexUnit::TFO_ANISOTROPIC : LLTexUnit::TFO_POINT); +        curr_preview_image->setAddressMode(LLTexUnit::TAM_CLAMP); + + +        if (gSavedSettings.getBOOL("UseFreezeFrame") && mAllowFullScreenPreview) +        { +            mShineCountdown = 4; // wait a few frames to avoid animation glitch due to readback this frame +        } +    } +} +  S32 LLSnapshotLivePreview::getEncodedImageWidth() const  {      S32 width = getWidth(); diff --git a/indra/newview/llsnapshotlivepreview.h b/indra/newview/llsnapshotlivepreview.h index fed33bf37c..57e5d83f8e 100644 --- a/indra/newview/llsnapshotlivepreview.h +++ b/indra/newview/llsnapshotlivepreview.h @@ -119,7 +119,7 @@ public:  	void generateThumbnailImage(BOOL force_update = FALSE) ;  	void resetThumbnailImage() { mThumbnailImage = NULL ; }  	void drawPreviewRect(S32 offset_x, S32 offset_y) ; - +	void prepareFreezeFrame();  	LLViewerTexture* getBigThumbnailImage();  	S32  getBigThumbnailWidth() const { return mBigThumbnailWidth ; } diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp index 7867e1573c..44c980c96f 100755 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -547,21 +547,8 @@ void LLSpeakerMgr::updateSpeakerList()  				// For groups, we need to hit the group manager.  				// Note: The session uuid and the group uuid are actually one and the same. If that was to change, this will fail.  				LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(session_id); -                F32 large_group_delay = 0.f; -                if (gdatap) -                { -                    //This is a viewer-side bandaid for maint-4414 it does not fix the core issue. -                    large_group_delay = (F32)(gdatap->mMemberCount / 5000); -                } -                 -                const F32 load_group_timeout = gSavedSettings.getF32("ChatLoadGroupTimeout") + large_group_delay; - -				if (!gdatap && (mGetListTime.getElapsedTimeF32() >= load_group_timeout)) -				{ -					// Request the data the first time around -					LLGroupMgr::getInstance()->sendCapGroupMembersRequest(session_id); -				} -				else if (gdatap && gdatap->isMemberDataComplete() && !gdatap->mMembers.empty()) + +				if (gdatap && gdatap->isMemberDataComplete() && !gdatap->mMembers.empty())  				{  					// Add group members when we get the complete list (note: can take a while before we get that list)  					LLGroupMgrGroupData::member_list_t::iterator member_it = gdatap->mMembers.begin(); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index d7bfd22cc9..e1d3c9efe0 100755 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -242,7 +242,8 @@ static LLVector3 gAgentStartLookAt(1.0f, 0.f, 0.f);  static std::string gAgentStartLocation = "safe";  static bool mLoginStatePastUI = false; -const S32 DEFAULT_MAX_AGENT_GROUPS = 25; +const S32 DEFAULT_MAX_AGENT_GROUPS = 42; +const S32 ALLOWED_MAX_AGENT_GROUPS = 500;  boost::scoped_ptr<LLEventPump> LLStartUp::sStateWatcher(new LLEventStream("StartupState"));  boost::scoped_ptr<LLStartupListener> LLStartUp::sListener(new LLStartupListener()); @@ -420,9 +421,7 @@ bool idle_startup()  		gSavedSettings.setS32("LastFeatureVersion", LLFeatureManager::getInstance()->getVersion());  		gSavedSettings.setString("LastGPUString", thisGPU); -		// load dynamic GPU/feature tables from website (S3) -		LLFeatureManager::getInstance()->fetchHTTPTables(); -		 +  		std::string xml_file = LLUI::locateSkin("xui_version.xml");  		LLXMLNodePtr root;  		bool xml_ok = false; @@ -3232,6 +3231,23 @@ bool process_login_success_response()  			LLStringUtil::trim(gDisplayName);  		}  	} +	std::string first_name; +	if(response.has("first_name")) +	{ +		first_name = response["first_name"].asString(); +		LLStringUtil::replaceChar(first_name, '"', ' '); +		LLStringUtil::trim(first_name); +		gAgentUsername = first_name; +	} + +	if(response.has("last_name") && !gAgentUsername.empty() && (gAgentUsername != "Resident")) +	{ +		std::string last_name = response["last_name"].asString(); +		LLStringUtil::replaceChar(last_name, '"', ' '); +		LLStringUtil::trim(last_name); +		gAgentUsername = gAgentUsername + " " + last_name; +	} +  	if(gDisplayName.empty())  	{  		if(response.has("first_name")) @@ -3252,6 +3268,7 @@ bool process_login_success_response()  			gDisplayName += text;  		}  	} +  	if(gDisplayName.empty())  	{  		gDisplayName.assign(gUserCredential->asString()); @@ -3504,15 +3521,24 @@ bool process_login_success_response()  		LLViewerMedia::openIDSetup(openid_url, openid_token);  	} -	if(response.has("max-agent-groups")) {		 -		std::string max_agent_groups(response["max-agent-groups"]); -		gMaxAgentGroups = atoi(max_agent_groups.c_str()); -		LL_INFOS("LLStartup") << "gMaxAgentGroups read from login.cgi: " -							  << gMaxAgentGroups << LL_ENDL; +	gMaxAgentGroups = DEFAULT_MAX_AGENT_GROUPS; +	if(response.has("max-agent-groups")) +	{ +		S32 agent_groups = atoi(std::string(response["max-agent-groups"]).c_str()); +		if (agent_groups > 0 && agent_groups <= ALLOWED_MAX_AGENT_GROUPS) +		{ +			gMaxAgentGroups = agent_groups; +			LL_INFOS("LLStartup") << "gMaxAgentGroups read from login.cgi: " +				<< gMaxAgentGroups << LL_ENDL; +		} +		else +		{ +			LL_INFOS("LLStartup") << "Invalid value received, using defaults for gMaxAgentGroups: " +				<< gMaxAgentGroups << LL_ENDL; +		}  	}  	else { -		gMaxAgentGroups = DEFAULT_MAX_AGENT_GROUPS; -		LL_INFOS("LLStartup") << "using gMaxAgentGroups default: " +		LL_INFOS("LLStartup") << "Missing max-agent-groups, using default value for gMaxAgentGroups: "  							  << gMaxAgentGroups << LL_ENDL;  	} diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index ef852bc905..bcdf8360ed 100755 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -1544,17 +1544,20 @@ void LLTextureCache::purgeAllTextures(bool purge_directories)  		{  			std::string dirname = mTexturesDirName + delem + subdirs[i];  			LL_INFOS() << "Deleting files in directory: " << dirname << LL_ENDL; -			gDirUtilp->deleteFilesInDir(dirname, mask);  			if (purge_directories)  			{ -				LLFile::rmdir(dirname); +				gDirUtilp->deleteDirAndContents(dirname); +			} +			else +			{ +				gDirUtilp->deleteFilesInDir(dirname, mask);  			}  		}  		if (purge_directories)  		{  			gDirUtilp->deleteFilesInDir(mTexturesDirName, mask);  			LLFile::rmdir(mTexturesDirName); -		}		 +		}  	}  	mHeaderIDMap.clear();  	mTexturesSizeMap.clear(); diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 717807f513..980810835e 100755 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -188,6 +188,7 @@ protected:  private:  	bool mCanApply;  	bool mCanPreview; +	bool mPreviewSettingChanged;  	texture_selected_callback mTextureSelectedCallback;  }; @@ -215,7 +216,8 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(  	mContextConeOpacity(0.f),  	mSelectedItemPinned( FALSE ),  	mCanApply(true), -	mCanPreview(true) +	mCanPreview(true), +	mPreviewSettingChanged(false)  {  	buildFromFile("floater_texture_ctrl.xml");  	mCanApplyImmediately = can_apply_immediately; @@ -823,6 +825,16 @@ void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem  			}  			setImageID(itemp->getAssetUUID(),false);  			mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here? + +			if(!mPreviewSettingChanged) +			{ +				mCanPreview = gSavedSettings.getBOOL("TextureLivePreview"); +			} +			else +			{ +				mPreviewSettingChanged = false; +			} +  			if (user_action && mCanPreview)  			{  				// only commit intentional selections, not implicit ones @@ -979,6 +991,7 @@ void LLFloaterTexturePicker::setCanApply(bool can_preview, bool can_apply)  	mCanApply = can_apply;  	mCanPreview = can_preview ? gSavedSettings.getBOOL("TextureLivePreview") : false; +	mPreviewSettingChanged = true;  }  void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string ) diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 526f8d1cd8..b8df063c53 100755 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -994,9 +994,15 @@ BOOL LLToolDragAndDrop::handleDropTextureProtections(LLViewerObject* hit_obj,  		return TRUE;  	} -	// In case the inventory has not been updated (e.g. due to some recent operation -	// causing a dirty inventory), stall the user while fetching the inventory. -	if (hit_obj->isInventoryDirty()) +	// In case the inventory has not been loaded (e.g. due to some recent operation +	// causing a dirty inventory) and we can do an update, stall the user +	// while fetching the inventory. +	// +	// Note: fetch only if inventory is both dirty and not present since previously checked faces +	// could have requested new fetch for same item (removed inventory and marked as dirty=false). +	// Objects without listeners (dirty==true and inventory!=NULL. In this specific case - before +	// first fetch) shouldn't be updated either since we won't receive any changes. +	if (hit_obj->isInventoryDirty() && hit_obj->getInventoryRoot() == NULL)  	{  		hit_obj->fetchInventoryFromServer();  		LLSD args; diff --git a/indra/newview/lltoolgrab.h b/indra/newview/lltoolgrab.h index 4e22732124..5d24c8813e 100755 --- a/indra/newview/lltoolgrab.h +++ b/indra/newview/lltoolgrab.h @@ -78,6 +78,8 @@ public:  	// Certain grabs should not highlight the "Build" toolbar button  	BOOL getHideBuildHighlight() { return mHideBuildHighlight; } +	void setClickedInMouselook(BOOL is_clickedInMouselook) {mClickedInMouselook = is_clickedInMouselook;} +  	static void		pickCallback(const LLPickInfo& pick_info);  private:  	LLVector3d		getGrabPointGlobal(); diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index e4353aafaa..2081297717 100755 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -319,6 +319,7 @@ BOOL LLToolPie::handleLeftClickPick()  	{  		gGrabTransientTool = this;  		mMouseButtonDown = false; +		LLToolGrab::getInstance()->setClickedInMouselook(gAgentCamera.cameraMouselook());  		LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolGrab::getInstance() );  		return LLToolGrab::getInstance()->handleObjectHit( mPick );  	} diff --git a/indra/newview/llurllineeditorctrl.cpp b/indra/newview/llurllineeditorctrl.cpp index cad5769042..8a61114852 100755 --- a/indra/newview/llurllineeditorctrl.cpp +++ b/indra/newview/llurllineeditorctrl.cpp @@ -84,7 +84,7 @@ void LLURLLineEditor::copyEscapedURLToClipboard()  	const std::string unescaped_text = wstring_to_utf8str(mText.getWString().substr(left_pos, length));  	LLWString text_to_copy;  	// *HACK: Because LLSLURL is currently broken we cannot use it to check if unescaped_text is a valid SLURL (see EXT-8335). -	if (LLStringUtil::startsWith(unescaped_text, "http://")) // SLURL +	if (LLStringUtil::startsWith(unescaped_text, "http://") || LLStringUtil::startsWith(unescaped_text, "secondlife://")) // SLURL  		text_to_copy = utf8str_to_wstring(LLWeb::escapeURL(unescaped_text));  	else // human-readable location  		text_to_copy = utf8str_to_wstring(unescaped_text); diff --git a/indra/newview/llversioninfo.cpp b/indra/newview/llversioninfo.cpp index 5cc7d7bed3..e53de8be32 100755 --- a/indra/newview/llversioninfo.cpp +++ b/indra/newview/llversioninfo.cpp @@ -29,6 +29,7 @@  #include <iostream>  #include <sstream>  #include "llversioninfo.h" +#include <boost/regex.hpp>  #if ! defined(LL_VIEWER_CHANNEL)       \   || ! defined(LL_VIEWER_VERSION_MAJOR) \ @@ -131,3 +132,43 @@ void LLVersionInfo::resetChannel(const std::string& channel)  	sWorkingChannelName = channel;  	sVersionChannel.clear(); // Reset version and channel string til next use.  } + +//static +LLVersionInfo::ViewerMaturity LLVersionInfo::getViewerMaturity() +{ +    ViewerMaturity maturity; +     +    std::string channel = getChannel(); + +	static const boost::regex is_test_channel("\\bTest\\b"); +	static const boost::regex is_beta_channel("\\bBeta\\b"); +	static const boost::regex is_project_channel("\\bProject\\b"); +	static const boost::regex is_release_channel("\\bRelease\\b"); + +    if (boost::regex_search(channel, is_release_channel)) +    { +        maturity = RELEASE_VIEWER; +    } +    else if (boost::regex_search(channel, is_beta_channel)) +    { +        maturity = BETA_VIEWER; +    } +    else if (boost::regex_search(channel, is_project_channel)) +    { +        maturity = PROJECT_VIEWER; +    } +    else if (boost::regex_search(channel, is_test_channel)) +    { +        maturity = TEST_VIEWER; +    } +    else +    { +        LL_WARNS() << "Channel '" << channel +                   << "' does not follow naming convention, assuming Test" +                   << LL_ENDL; +        maturity = TEST_VIEWER; +    } +    return maturity; +} + +     diff --git a/indra/newview/llversioninfo.h b/indra/newview/llversioninfo.h index 077105cae8..4e75535ec5 100755 --- a/indra/newview/llversioninfo.h +++ b/indra/newview/llversioninfo.h @@ -68,6 +68,15 @@ public:  	/// reset the channel name used by the viewer.  	static void resetChannel(const std::string& channel); + +    typedef enum +    { +        TEST_VIEWER, +        PROJECT_VIEWER, +        BETA_VIEWER, +        RELEASE_VIEWER +    } ViewerMaturity; +    static ViewerMaturity getViewerMaturity();  };  #endif diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index 6803adfaa2..1ce42e97b8 100755 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -248,6 +248,7 @@ public:  	void setHomeURL(const std::string& home_url, const std::string& mime_type = LLStringUtil::null) { mHomeURL = home_url; mHomeMimeType = mime_type;};  	void clearCache();  	void setPageZoomFactor( double factor ); +	double getPageZoomFactor() {return mZoomFactor;}  	std::string getMimeType() { return mMimeType; }  	void scaleMouse(S32 *mouse_x, S32 *mouse_y);  	void scaleTextureCoords(const LLVector2& texture_coords, S32 *x, S32 *y); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index b797e0c835..7282c67cf9 100755 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -57,6 +57,7 @@  #include "llfacebookconnect.h"  #include "llfilepicker.h"  #include "llfirstuse.h" +#include "llfloaterabout.h"  #include "llfloaterbuy.h"  #include "llfloaterbuycontents.h"  #include "llbuycurrencyhtml.h" @@ -2077,6 +2078,22 @@ class LLAdvancedCheckShowObjectUpdates : public view_listener_t +/////////////////////// +// CHECK FOR UPDATES // +/////////////////////// + + + +class LLAdvancedCheckViewerUpdates : public view_listener_t +{ +	bool handleEvent(const LLSD& userdata) +	{ +		LLFloaterAboutUtil::checkUpdatesAndNotify(); +		return true; +	} +}; + +  ////////////////////  // COMPRESS IMAGE //  //////////////////// @@ -2695,6 +2712,7 @@ void handle_object_edit()  	if (gAgentCamera.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit())  	{ +		LLFloaterTools::sPreviousFocusOnAvatar = true;  		LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();  		if (selection->getSelectType() == SELECT_TYPE_HUD || !gSavedSettings.getBOOL("EditCameraMovement")) @@ -7077,11 +7095,10 @@ void handle_selected_texture_info(void*)     			{     				msg.append( llformat("%d ", (S32)(it->second[i])));     			} - -			LLSD args; -			args["MESSAGE"] = msg; -			LLNotificationsUtil::add("SystemMessage", args);     		} +   		LLSD args; +   		args["MESSAGE"] = msg; +   		LLNotificationsUtil::add("SystemMessage", args);  	}  } @@ -8857,6 +8874,7 @@ void initialize_menus()  	// Advanced (toplevel)  	view_listener_t::addMenu(new LLAdvancedToggleShowObjectUpdates(), "Advanced.ToggleShowObjectUpdates");  	view_listener_t::addMenu(new LLAdvancedCheckShowObjectUpdates(), "Advanced.CheckShowObjectUpdates"); +	view_listener_t::addMenu(new LLAdvancedCheckViewerUpdates(), "Advanced.CheckViewerUpdates");  	view_listener_t::addMenu(new LLAdvancedCompressImage(), "Advanced.CompressImage");  	view_listener_t::addMenu(new LLAdvancedShowDebugSettings(), "Advanced.ShowDebugSettings");  	view_listener_t::addMenu(new LLAdvancedEnableViewAdminOptions(), "Advanced.EnableViewAdminOptions"); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 459bdca8df..62314a0f4e 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -57,6 +57,7 @@  #include "llcallingcard.h"  #include "llbuycurrencyhtml.h"  #include "llfirstuse.h" +#include "llfloaterbump.h"  #include "llfloaterbuyland.h"  #include "llfloaterland.h"  #include "llfloaterregioninfo.h" @@ -2348,7 +2349,8 @@ static void god_message_name_cb(const LLAvatarName& av_name, LLChat chat, std::s  	LLNotificationsUtil::add("GodMessage", args);  	// Treat like a system message and put in chat history. -	chat.mText = av_name.getCompleteName() + ": " + message; +	chat.mSourceType = CHAT_SOURCE_SYSTEM; +	chat.mText = message;  	LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");  	if (nearby_chat) @@ -2706,6 +2708,13 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)  		break;  	case IM_GROUP_INVITATION:  		{ +			if (!is_muted) +			{ +				// group is not blocked, but we still need to check agent that sent the invitation +				// and we have no agent's id +				// Note: server sends username "first.last". +				is_muted |= LLMuteList::getInstance()->isMuted(name); +			}  			if (is_do_not_disturb || is_muted)  			{  				send_do_not_disturb_message(msg, from_id); @@ -2852,6 +2861,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)  	case IM_FROM_TASK:  		{ +  			if (is_do_not_disturb && !is_owned_by_me)  			{  				return; @@ -2935,17 +2945,13 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)  			payload["from_id"] = from_id;  			payload["slurl"] = location;  			payload["name"] = name; -			std::string session_name; +  			if (from_group)  			{  				payload["group_owned"] = "true";  			} -			LLNotification::Params params("ServerObjectMessage"); -			params.substitutions = substitutions; -			params.payload = payload; - -			LLPostponedNotification::add<LLPostponedServerObjectNotification>(params, from_id, from_group); +			LLNotificationsUtil::add("ServerObjectMessage", substitutions, payload);  		}  		break; @@ -3600,6 +3606,11 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)  	is_linden = chat.mSourceType != CHAT_SOURCE_OBJECT &&  		LLMuteList::getInstance()->isLinden(from_name); +	if (is_muted && (chat.mSourceType == CHAT_SOURCE_OBJECT)) +	{ +		return; +	} +  	BOOL is_audible = (CHAT_AUDIBLE_FULLY == chat.mAudible);  	chatter = gObjectList.findObject(from_id);  	if (chatter) @@ -3776,11 +3787,15 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)  			}  		} -		LLSD msg_notify = LLSD(LLSD::emptyMap()); -		msg_notify["session_id"] = LLUUID(); -        msg_notify["from_id"] = chat.mFromID; -		msg_notify["source_type"] = chat.mSourceType; -        on_new_message(msg_notify); +		if (mesg != "") +		{ +			LLSD msg_notify = LLSD(LLSD::emptyMap()); +			msg_notify["session_id"] = LLUUID(); +			msg_notify["from_id"] = chat.mFromID; +			msg_notify["source_type"] = chat.mSourceType; +			on_new_message(msg_notify); +		} +  	}  } @@ -6232,6 +6247,11 @@ void process_mean_collision_alert_message(LLMessageSystem *msgsystem, void **use  			gCacheName->get(perp, false, boost::bind(&mean_name_callback, _1, _2, _3));  		}  	} +	LLFloaterBump* bumps_floater = LLFloaterBump::getInstance(); +	if(bumps_floater && bumps_floater->isInVisibleChain()) +	{ +		bumps_floater->populateCollisionList(); +	}  }  void process_frozen_message(LLMessageSystem *msgsystem, void **user_data) diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp index faa58d423f..6666aecca2 100755 --- a/indra/newview/llviewernetwork.cpp +++ b/indra/newview/llviewernetwork.cpp @@ -119,14 +119,14 @@ void LLGridManager::initialize(const std::string& grid_file)  	mGridFile = grid_file;  	// as we don't want an attacker to override our grid list  	// to point the default grid to an invalid grid -  	addSystemGrid("Second Life Main Grid (Agni)", +  	addSystemGrid(LLTrans::getString("AgniGridLabel"),  				  MAINGRID,  				  MAIN_GRID_LOGIN_URI,  				  "https://secondlife.com/helpers/",  				  DEFAULT_LOGIN_PAGE,  				  SL_UPDATE_QUERY_URL,  				  "Agni"); -	addSystemGrid("Second Life Beta Test Grid (Aditi)", +	addSystemGrid(LLTrans::getString("AditiGridLabel"),  				  "util.aditi.lindenlab.com",  				  "https://login.aditi.lindenlab.com/cgi-bin/login.cgi",  				  "http://aditi-secondlife.webdev.lindenlab.com/helpers/", diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index ac3f07fcd8..c521b00372 100755 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -4637,7 +4637,7 @@ S32 LLViewerObject::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID  	return retval;  } -S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams) +S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams, bool isInitFromServer)  {  	S32 retval = 0;  	const LLTextureEntry *tep = getTE(te); @@ -4647,13 +4647,14 @@ S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMateri  		return 0;  	} -	retval = LLPrimitive::setTEMaterialParams(te, pMaterialParams); +	setTENormalMap(te, (pMaterialParams) ? pMaterialParams->getNormalID() : LLUUID::null); +	setTESpecularMap(te, (pMaterialParams) ? pMaterialParams->getSpecularID() : LLUUID::null); + +	retval = LLPrimitive::setTEMaterialParams(te, pMaterialParams, isInitFromServer);  	LL_DEBUGS("Material") << "Changing material params for te " << (S32)te  							<< ", object " << mID  			               << " (" << retval << ")"  							<< LL_ENDL; -	setTENormalMap(te, (pMaterialParams) ? pMaterialParams->getNormalID() : LLUUID::null); -	setTESpecularMap(te, (pMaterialParams) ? pMaterialParams->getSpecularID() : LLUUID::null);  	refreshMaterials();  	return retval; diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 05c87c153b..db2749f413 100755 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -330,7 +330,7 @@ public:  	/*virtual*/	S32		setTEMediaFlags(const U8 te, const U8 media_flags );  	/*virtual*/ S32     setTEGlow(const U8 te, const F32 glow);  	/*virtual*/ S32     setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID); -	/*virtual*/ S32		setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams); +	/*virtual*/ S32		setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams, bool isInitFromServer);  	// Used by Materials update functions to properly kick off rebuilds  	// of VBs etc when materials updates require changes. diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 59f57c218e..2a6b105cab 100755 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -1602,8 +1602,14 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use  		}  		else if (local_id == parcel_mgr.mAgentParcel->getLocalID())  		{ -			// updated agent parcel -			parcel_mgr.mAgentParcel->unpackMessage(msg); +			// Parcels in different regions can have same ids. +			LLViewerRegion* parcel_region = LLWorld::getInstance()->getRegion( msg->getSender() ); +			LLViewerRegion* agent_region = gAgent.getRegion(); +			if (parcel_region && agent_region && parcel_region->getRegionID() == agent_region->getRegionID()) +			{ +				// updated agent parcel +				parcel_mgr.mAgentParcel->unpackMessage(msg); +			}  		}  	} diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index ec28461201..ea7af35842 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -828,7 +828,6 @@ void LLViewerRegion::processRegionInfo(LLMessageSystem* msg, void**)  	LLRegionInfoModel::instance().update(msg);  	LLFloaterGodTools::processRegionInfo(msg);  	LLFloaterRegionInfo::processRegionInfo(msg); -	LLFloaterReporter::processRegionInfo(msg);  }  void LLViewerRegion::setCacheID(const LLUUID& id) diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index f60829e9e8..24a6758312 100755 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -60,6 +60,7 @@  #include "llfeaturemanager.h"  #include "llviewernetwork.h"  #include "llmeshrepository.h" //for LLMeshRepository::sBytesReceived +#include "llsdserialize.h"  namespace LLStatViewer  { @@ -616,8 +617,10 @@ void send_stats()  	body["DisplayNamesShowUsername"] = gSavedSettings.getBOOL("NameTagShowUsernames");  	body["MinimalSkin"] = false; -	 +  	LLViewerStats::getInstance()->addToMessage(body); + +	LL_INFOS("LogViewerStatsPacket") << "Sending viewer statistics: " << body << LL_ENDL;  	LLHTTPClient::post(url, body, new ViewerStatsResponder());  	LLViewerStats::instance().getRecording().resume(); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index e317989f04..ba84d7aa2c 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -2336,12 +2336,6 @@ void LLViewerWindow::setMenuBackgroundColor(bool god_mode, bool dev_grid)      LLSD args;      LLColor4 new_bg_color; -	// no l10n problem because channel is always an english string -	std::string channel = LLVersionInfo::getChannel(); -	static const boost::regex is_beta_channel("\\bBeta\\b"); -	static const boost::regex is_project_channel("\\bProject\\b"); -	static const boost::regex is_test_channel("\\bTest$"); -	  	// god more important than project, proj more important than grid      if ( god_mode )       { @@ -2354,27 +2348,35 @@ void LLViewerWindow::setMenuBackgroundColor(bool god_mode, bool dev_grid)  			new_bg_color = LLUIColorTable::instance().getColor( "MenuNonProductionGodBgColor" );  		}      } -	else if (boost::regex_search(channel, is_beta_channel)) -	{ -		new_bg_color = LLUIColorTable::instance().getColor( "MenuBarBetaBgColor" ); -	} -	else if (boost::regex_search(channel, is_project_channel)) -	{ -		new_bg_color = LLUIColorTable::instance().getColor( "MenuBarProjectBgColor" ); -	} -	else if (boost::regex_search(channel, is_test_channel)) -	{ -		new_bg_color = LLUIColorTable::instance().getColor( "MenuBarTestBgColor" ); -	} -	else if(!LLGridManager::getInstance()->isInProductionGrid()) -	{ -		new_bg_color = LLUIColorTable::instance().getColor( "MenuNonProductionBgColor" ); -	} -	else  -	{ -		new_bg_color = LLUIColorTable::instance().getColor( "MenuBarBgColor" ); -	} - +    else +    { +        switch (LLVersionInfo::getViewerMaturity()) +        { +        case LLVersionInfo::TEST_VIEWER: +            new_bg_color = LLUIColorTable::instance().getColor( "MenuBarTestBgColor" ); +            break; + +        case LLVersionInfo::PROJECT_VIEWER: +            new_bg_color = LLUIColorTable::instance().getColor( "MenuBarProjectBgColor" ); +            break; +             +        case LLVersionInfo::BETA_VIEWER: +            new_bg_color = LLUIColorTable::instance().getColor( "MenuBarBetaBgColor" ); +            break; +             +        case LLVersionInfo::RELEASE_VIEWER: +            if(!LLGridManager::getInstance()->isInProductionGrid()) +            { +                new_bg_color = LLUIColorTable::instance().getColor( "MenuNonProductionBgColor" ); +            } +            else  +            { +                new_bg_color = LLUIColorTable::instance().getColor( "MenuBarBgColor" ); +            } +            break; +        } +    } +          if(gMenuBarView)      {          gMenuBarView->setBackgroundColor( new_bg_color ); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index f753448770..b97a1bde99 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -160,6 +160,9 @@ const F32 HEAD_MOVEMENT_AVG_TIME = 0.9f;  const S32 MORPH_MASK_REQUESTED_DISCARD = 0; +const F32 MAX_STANDOFF_FROM_ORIGIN = 3; +const F32 MAX_STANDOFF_DISTANCE_CHANGE = 32; +  // Discard level at which to switch to baked textures  // Should probably be 4 or 3, but didn't want to change it while change other logic - SJB  const S32 SWITCH_TO_BAKED_DISCARD = 5; @@ -2132,7 +2135,7 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)  	// animate the character  	// store off last frame's root position to be consistent with camera position -	LLVector3 root_pos_last = mRoot->getWorldPosition(); +	mLastRootPos = mRoot->getWorldPosition();  	BOOL detailed_update = updateCharacter(agent);  	static LLUICachedControl<bool> visualizers_in_calls("ShowVoiceVisualizersInCalls", false); @@ -2150,7 +2153,7 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)  		idleUpdateWindEffect();  	} -	idleUpdateNameTag( root_pos_last ); +	idleUpdateNameTag( mLastRootPos );  	idleUpdateRenderCost();  } @@ -6080,10 +6083,10 @@ void LLVOAvatar::getOffObject()  	{  		return;  	} -	 +  	LLViewerObject* sit_object = (LLViewerObject*)getParent(); -	if (sit_object)  +	if (sit_object)  	{  		stopMotionFromSource(sit_object->getID());  		LLFollowCamMgr::setCameraActive(sit_object->getID(), FALSE); @@ -6100,9 +6103,19 @@ void LLVOAvatar::getOffObject()  	}  	// assumes that transform will not be updated with drawable still having a parent +	// or that drawable had no parent from the start  	LLVector3 cur_position_world = mDrawable->getWorldPosition();  	LLQuaternion cur_rotation_world = mDrawable->getWorldRotation(); +	if (mLastRootPos.length() >= MAX_STANDOFF_FROM_ORIGIN +		&& (cur_position_world.length() < MAX_STANDOFF_FROM_ORIGIN +			|| dist_vec(cur_position_world, mLastRootPos) > MAX_STANDOFF_DISTANCE_CHANGE)) +	{ +		// Most likely drawable got updated too early or some updates were missed - we got relative position to non-existing parent +		// restore coordinates from cache +		cur_position_world = mLastRootPos; +	} +  	// set *local* position based on last *world* position, since we're unparenting the avatar  	mDrawable->mXform.setPosition(cur_position_world);  	mDrawable->mXform.setRotation(cur_rotation_world);	 @@ -6278,6 +6291,7 @@ void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color)  BOOL LLVOAvatar::isVisible() const  {  	return mDrawable.notNull() +		&& (!mOrphaned || isSelf())  		&& (mDrawable->isVisible() || mIsDummy);  } diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 1c3f4f2aa7..5b4379165a 100755 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -869,6 +869,8 @@ public:  private:  	// set this property only with LLVOAvatar::sitDown method  	BOOL 			mIsSitting; +	// position backup in case of missing data +	LLVector3		mLastRootPos;  /**                    Hierarchy   **                                                                            ** diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 0432f6f27c..4b0e4514a0 100755 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1624,6 +1624,66 @@ static LLTrace::BlockTimerStatHandle FTM_GEN_FLEX("Generate Flexies");  static LLTrace::BlockTimerStatHandle FTM_UPDATE_PRIMITIVES("Update Primitives");  static LLTrace::BlockTimerStatHandle FTM_UPDATE_RIGGED_VOLUME("Update Rigged"); +bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled) +{ +	bool regen_faces = false; + +	LLVolume *old_volumep, *new_volumep; +	F32 old_lod, new_lod; +	S32 old_num_faces, new_num_faces; + +	old_volumep = getVolume(); +	old_lod = old_volumep->getDetail(); +	old_num_faces = old_volumep->getNumFaces(); +	old_volumep = NULL; + +	{ +		LL_RECORD_BLOCK_TIME(FTM_GEN_VOLUME); +		const LLVolumeParams &volume_params = getVolume()->getParams(); +		setVolume(volume_params, 0); +	} + +	new_volumep = getVolume(); +	new_lod = new_volumep->getDetail(); +	new_num_faces = new_volumep->getNumFaces(); +	new_volumep = NULL; + +	if ((new_lod != old_lod) || mSculptChanged) +	{ +		compiled = TRUE; +		sNumLODChanges += new_num_faces; + +		if ((S32)getNumTEs() != getVolume()->getNumFaces()) +		{ +			setNumTEs(getVolume()->getNumFaces()); //mesh loading may change number of faces. +		} + +		drawable->setState(LLDrawable::REBUILD_VOLUME); // for face->genVolumeTriangles() + +		{ +			LL_RECORD_BLOCK_TIME(FTM_GEN_TRIANGLES); +			regen_faces = new_num_faces != old_num_faces || mNumFaces != (S32)getNumTEs(); +			if (regen_faces) +			{ +				regenFaces(); +			} + +			if (mSculptChanged) +			{ //changes in sculpt maps can thrash an object bounding box without  +				//triggering a spatial group bounding box update -- force spatial group +				//to update bounding boxes +				LLSpatialGroup* group = mDrawable->getSpatialGroup(); +				if (group) +				{ +					group->unbound(); +				} +			} +		} +	} + +	return regen_faces; +} +  BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)  {  	LL_RECORD_BLOCK_TIME(FTM_UPDATE_PRIMITIVES); @@ -1664,83 +1724,35 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)  		return TRUE; // No update to complete  	} -	if (mVolumeChanged || mFaceMappingChanged ) +	if (mVolumeChanged || mFaceMappingChanged)  	{  		dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1)); -		compiled = TRUE; +		bool was_regen_faces = false;  		if (mVolumeChanged)  		{ -			LL_RECORD_BLOCK_TIME(FTM_GEN_VOLUME); -			LLVolumeParams volume_params = getVolume()->getParams(); -			setVolume(volume_params, 0); +			was_regen_faces = lodOrSculptChanged(drawable, compiled);  			drawable->setState(LLDrawable::REBUILD_VOLUME);  		} - +		else if (mSculptChanged || mLODChanged)  		{ +			compiled = TRUE; +			was_regen_faces = lodOrSculptChanged(drawable, compiled); +		} + +		if (!was_regen_faces) {  			LL_RECORD_BLOCK_TIME(FTM_GEN_TRIANGLES);  			regenFaces(); -			genBBoxes(FALSE);  		} + +		genBBoxes(FALSE);  	} -	else if ((mLODChanged) || (mSculptChanged)) +	else if (mLODChanged || mSculptChanged)  	{  		dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1)); - -		LLVolume *old_volumep, *new_volumep; -		F32 old_lod, new_lod; -		S32 old_num_faces, new_num_faces ; - -		old_volumep = getVolume(); -		old_lod = old_volumep->getDetail(); -		old_num_faces = old_volumep->getNumFaces() ; -		old_volumep = NULL ; - -		{ -			LL_RECORD_BLOCK_TIME(FTM_GEN_VOLUME); -			LLVolumeParams volume_params = getVolume()->getParams(); -			setVolume(volume_params, 0); -		} - -		new_volumep = getVolume(); -		new_lod = new_volumep->getDetail(); -		new_num_faces = new_volumep->getNumFaces() ; -		new_volumep = NULL ; - -		if ((new_lod != old_lod) || mSculptChanged) -		{ -			compiled = TRUE; -			sNumLODChanges += new_num_faces ; -	 -			if((S32)getNumTEs() != getVolume()->getNumFaces()) -			{ -				setNumTEs(getVolume()->getNumFaces()); //mesh loading may change number of faces. -			} - -			drawable->setState(LLDrawable::REBUILD_VOLUME); // for face->genVolumeTriangles() - -			{ -				LL_RECORD_BLOCK_TIME(FTM_GEN_TRIANGLES); -				if (new_num_faces != old_num_faces || mNumFaces != (S32)getNumTEs()) -				{ -					regenFaces(); -				} -				genBBoxes(FALSE); - -				if (mSculptChanged) -				{ //changes in sculpt maps can thrash an object bounding box without  -				  //triggering a spatial group bounding box update -- force spatial group -				  //to update bounding boxes -					LLSpatialGroup* group = mDrawable->getSpatialGroup(); -					if (group) -					{ -						group->unbound(); -					} -				} -			} -		} - +		compiled = TRUE; +		lodOrSculptChanged(drawable, compiled);  		genBBoxes(FALSE);  	}  	// it has its own drawable (it's moved) or it has changed UVs or it has changed xforms from global<->local @@ -2010,7 +2022,7 @@ void LLVOVolume::setTEMaterialParamsCallbackTE(const LLUUID& objectID, const LLM  		LLTextureEntry* texture_entry = pVol->getTE(te);  		if (texture_entry && (texture_entry->getMaterialID() == pMaterialID))  		{ -			pVol->setTEMaterialParams(te, pMaterialParams); +			pVol->setTEMaterialParams(te, pMaterialParams, FALSE);  		}  	}  } @@ -2081,7 +2093,7 @@ bool LLVOVolume::notifyAboutCreatingTexture(LLViewerTexture *texture)  	for(map_te_material::const_iterator it = new_material.begin(), end = new_material.end(); it != end; ++it)  	{  		LLMaterialMgr::getInstance()->put(getID(), it->first, *it->second); -		LLViewerObject::setTEMaterialParams(it->first, it->second); +		LLViewerObject::setTEMaterialParams(it->first, it->second, FALSE);  	}  	//clear wait-list @@ -2158,7 +2170,7 @@ bool LLVOVolume::notifyAboutMissingAsset(LLViewerTexture *texture)  	for(map_te_material::const_iterator it = new_material.begin(), end = new_material.end(); it != end; ++it)  	{  		LLMaterialMgr::getInstance()->put(getID(), it->first, *it->second); -		LLViewerObject::setTEMaterialParams(it->first, it->second); +		LLViewerObject::setTEMaterialParams(it->first, it->second, FALSE);  	}  	//clear wait-list @@ -2167,7 +2179,7 @@ bool LLVOVolume::notifyAboutMissingAsset(LLViewerTexture *texture)  	return 0 != new_material.size();  } -S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams) +S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams, bool isInitFromServer)  {  	LLMaterialPtr pMaterial = const_cast<LLMaterialPtr&>(pMaterialParams); @@ -2264,7 +2276,7 @@ S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialPa  		}  	} -	S32 res = LLViewerObject::setTEMaterialParams(te, pMaterial); +	S32 res = LLViewerObject::setTEMaterialParams(te, pMaterial, isInitFromServer);  	LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterial) ? pMaterial->asLLSD() : LLSD("null")) << " res " << res  							 << ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" ) diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index bbaca316b0..ff7438ac09 100755 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -192,7 +192,7 @@ public:  	static void	setTEMaterialParamsCallbackTE(const LLUUID& objectID, const LLMaterialID& pMaterialID, const LLMaterialPtr pMaterialParams, U32 te); -	/*virtual*/ S32		setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams); +	/*virtual*/ S32		setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams, bool isInitFromServer);  	/*virtual*/ S32		setTEScale(const U8 te, const F32 s, const F32 t);  	/*virtual*/ S32		setTEScaleS(const U8 te, const F32 s);  	/*virtual*/ S32		setTEScaleT(const U8 te, const F32 t); @@ -339,6 +339,10 @@ protected:  	void cleanUpMediaImpls();  	void addMediaImpl(LLViewerMediaImpl* media_impl, S32 texture_index) ;  	void removeMediaImpl(S32 texture_index) ; + +private: +	bool lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled); +  public:  	static S32 getRenderComplexityMax() {return mRenderComplexity_last;} diff --git a/indra/newview/llworldmap.cpp b/indra/newview/llworldmap.cpp index bfae142812..837b30586b 100755 --- a/indra/newview/llworldmap.cpp +++ b/indra/newview/llworldmap.cpp @@ -383,6 +383,7 @@ void LLWorldMap::reloadItems(bool force)  		LLWorldMapMessage::getInstance()->sendItemRequest(MAP_ITEM_MATURE_EVENT);  		LLWorldMapMessage::getInstance()->sendItemRequest(MAP_ITEM_ADULT_EVENT);  		LLWorldMapMessage::getInstance()->sendItemRequest(MAP_ITEM_LAND_FOR_SALE); +		LLWorldMapMessage::getInstance()->sendItemRequest(MAP_ITEM_LAND_FOR_SALE_ADULT);  	}  } diff --git a/indra/newview/skins/default/xui/da/menu_viewer.xml b/indra/newview/skins/default/xui/da/menu_viewer.xml index aa6bc53672..299322001b 100755 --- a/indra/newview/skins/default/xui/da/menu_viewer.xml +++ b/indra/newview/skins/default/xui/da/menu_viewer.xml @@ -37,7 +37,7 @@  		<menu_item_separator/>  		<menu_item_call label="Profil for sted" name="Place Profile"/>  		<menu_item_call label="Om land" name="About Land"/> -		<menu_item_call label="Region/Estate" name="Region/Estate"/> +		<menu_item_call label="Region/Estate" name="RegionEstate"/>  		<menu_item_call label="Køb dette land" name="Buy Land"/>  		<menu_item_call label="Mit land" name="My Land"/>  		<menu label="Vis" name="LandShow"> diff --git a/indra/newview/skins/default/xui/da/notifications.xml b/indra/newview/skins/default/xui/da/notifications.xml index 33b876bdb9..aad3b9d062 100755 --- a/indra/newview/skins/default/xui/da/notifications.xml +++ b/indra/newview/skins/default/xui/da/notifications.xml @@ -1311,9 +1311,6 @@ Prøv igen om lidt.  	<notification name="NoValidCircuit">  		Ingen gyldig kode for kredsløb.  	</notification> -	<notification name="NoValidTimestamp"> -		Ikke et gyldigt klokkeslæt. -	</notification>  	<notification name="NoPendingConnection">  		Kunne ikke skabe fast forbindelse.  	</notification> diff --git a/indra/newview/skins/default/xui/de/menu_viewer.xml b/indra/newview/skins/default/xui/de/menu_viewer.xml index a328ca39f8..81b953515e 100755 --- a/indra/newview/skins/default/xui/de/menu_viewer.xml +++ b/indra/newview/skins/default/xui/de/menu_viewer.xml @@ -15,7 +15,7 @@  			<menu_item_check label="Fliegen" name="Fly"/>  			<menu_item_check label="Immer rennen" name="Always Run"/>  			<menu_item_call label="Animation meines Avatars stoppen" name="Stop Animating My Avatar"/> -			<menu_item_call label="Gehen/Rennen/Fliegen..." name="Walk / run / fly"/> +			<menu_item_call label="Gehen/Rennen/Fliegen..." name="WalkRunFly"/>  		</menu>  		<menu label="Status" name="Status">  			<menu_item_check label="Abwesend" name="Away"/> @@ -63,7 +63,7 @@  		<menu_item_call label="Foto" name="Take Snapshot"/>  		<menu_item_call label="Ortsprofil" name="Place Profile"/>  		<menu_item_call label="Landinformationen" name="About Land"/> -		<menu_item_call label="Region/Grundbesitz" name="Region/Estate"/> +		<menu_item_call label="Region/Grundbesitz" name="RegionEstate"/>  		<menu_item_call label="Mein Landbesitz..." name="My Land"/>  		<menu_item_call label="Dieses Land kaufen" name="Buy Land"/>  		<menu label="Anzeigen" name="LandShow"> diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml index 09cba36e25..2abbe3edd7 100755 --- a/indra/newview/skins/default/xui/de/notifications.xml +++ b/indra/newview/skins/default/xui/de/notifications.xml @@ -2709,9 +2709,6 @@ Versuchen Sie es in einigen Minuten erneut.  	<notification name="NoValidCircuit">  		Kein gültiger Verbindungscode.  	</notification> -	<notification name="NoValidTimestamp"> -		Kein gültiger Zeitstempel. -	</notification>  	<notification name="NoPendingConnection">  		Verbindung kann nicht hergestellt werden.  	</notification> diff --git a/indra/newview/skins/default/xui/de/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/de/panel_snapshot_postcard.xml index 3f5bbda724..3f5bbda724 100755..100644 --- a/indra/newview/skins/default/xui/de/panel_snapshot_postcard.xml +++ b/indra/newview/skins/default/xui/de/panel_snapshot_postcard.xml diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml index 60f36770bb..ec87b3684e 100755 --- a/indra/newview/skins/default/xui/en/floater_about.xml +++ b/indra/newview/skins/default/xui/en/floater_about.xml @@ -43,6 +43,14 @@          top_pad="5"          height="25"          width="180" /> +      <button +        follows="left|top" +        label="Check for updates" +        name="update_btn" +        left_pad="70" +        top_delta="0" +        height="25" +        width="180" />      </panel>      <panel        border="true"  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 62ab8ed193..edf028bf60 100755 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -23,15 +23,15 @@      </floater.string>      <floater.string       name="Minutes"> -        [MINUTES] minutes +        [MINUTES] min.      </floater.string>      <floater.string       name="Minute"> -        minute +        min.      </floater.string>      <floater.string       name="Seconds"> -        [SECONDS] seconds +        [SECONDS] sec.      </floater.string>      <floater.string       name="Remaining"> @@ -2013,7 +2013,7 @@ Only large parcels can be listed in search.               name="AllowedText"               top="0"               width="230"> -                Allowed Residents +                Allowed Residents ([COUNT])              </text>              <name_list               column_padding="0" @@ -2062,7 +2062,7 @@ Only large parcels can be listed in search.               name="BanCheck"               top="0"               width="200"> -                Banned Residents +                Banned Residents ([COUNT])              </text>              <name_list               column_padding="0" diff --git a/indra/newview/skins/default/xui/en/floater_bumps.xml b/indra/newview/skins/default/xui/en/floater_bumps.xml index 1f2fe62b3c..126e3aac48 100755 --- a/indra/newview/skins/default/xui/en/floater_bumps.xml +++ b/indra/newview/skins/default/xui/en/floater_bumps.xml @@ -7,7 +7,7 @@   help_topic="floater_bumps"   save_rect="true"   title="BUMPS, PUSHES & HITS" - width="400"> + width="420">      <floater.string       name="none_detected">          None detected @@ -34,7 +34,7 @@      </floater.string>      <floater.string       name="timeStr"> -        [[hour,datetime,slt]:[min,datetime,slt]] +        [[hour,datetime,slt]:[min,datetime,slt]:[second,datetime,slt]]      </floater.string>      <scroll_list       draw_border="false" @@ -45,5 +45,5 @@       multi_select="true"       name="bump_list"       top="20" -     width="388" /> +     width="408" />  </floater> diff --git a/indra/newview/skins/default/xui/en/floater_hardware_settings.xml b/indra/newview/skins/default/xui/en/floater_hardware_settings.xml index 9deb0d2030..dcd6d98581 100755 --- a/indra/newview/skins/default/xui/en/floater_hardware_settings.xml +++ b/indra/newview/skins/default/xui/en/floater_hardware_settings.xml @@ -191,8 +191,18 @@       label="OK"       label_selected="OK"       layout="topleft" -     left="-102" +     right="-105"       name="OK"       top="192"       width="90" /> +    <button +     follows="right|bottom" +     height="22" +     label="Cancel" +     label_selected="Cancel" +     layout="topleft" +     left_pad="5" +     name="Cancel" +     right="-10" +     width="90" />  </floater> diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index 7099db63ab..c0dddfc625 100755 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -490,14 +490,6 @@      <menu_item_call       label="Delete"       layout="topleft" -     name="Remove Link"> -        <menu_item_call.on_click -         function="Inventory.DoToSelected" -         parameter="delete" /> -    </menu_item_call> -    <menu_item_call -     label="Delete" -     layout="topleft"       name="Delete">          <menu_item_call.on_click           function="Inventory.DoToSelected" diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml index e91eea04d1..73ca7c529d 100755 --- a/indra/newview/skins/default/xui/en/menu_login.xml +++ b/indra/newview/skins/default/xui/en/menu_login.xml @@ -108,6 +108,12 @@               function="Floater.Show"               parameter="sl_about" />          </menu_item_call> +        <menu_item_call +         label="Check for Updates" +         name="Check for Updates"> +            <menu_item_call.on_click +             function="Advanced.CheckViewerUpdates"/> +        </menu_item_call>      </menu>      <menu_item_check        label="Show Debug Menu" diff --git a/indra/newview/skins/default/xui/en/menu_url_email.xml b/indra/newview/skins/default/xui/en/menu_url_email.xml new file mode 100644 index 0000000000..6467fe5c90 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_url_email.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<context_menu + layout="topleft" + name="Email Popup"> +    <menu_item_call +     label="Compose Email in an External client" +     layout="topleft" +     name="email_open_external"> +        <menu_item_call.on_click +         function="Url.OpenExternal" /> +    </menu_item_call> +    <menu_item_separator +     layout="topleft" /> +    <menu_item_call +     label="Copy Email to clipboard" +     layout="topleft" +     name="email_copy"> +        <menu_item_call.on_click +         function="Url.CopyLabel" /> +    </menu_item_call> +</context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 68ca55735a..2e248bcab9 100755 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -134,7 +134,7 @@          </menu_item_call>          <menu_item_call           label="Walk / run / fly..." -         name="Walk / run / fly"> +         name="WalkRunFly">            <menu_item_call.on_click             function="Floater.ToggleOrBringToFront"             parameter="moveview" /> @@ -502,7 +502,7 @@          </menu_item_call>          <menu_item_call           label="Region / Estate" -         name="Region/Estate"> +         name="RegionEstate">              <menu_item_call.on_click               function="Floater.Show"               parameter="region_info" /> @@ -1431,7 +1431,7 @@                   function="Floater.Show"                   parameter="bumps" />          </menu_item_call> -        <menu_item_separator/>     +        <menu_item_separator/>          <menu_item_call           label="About [APP_NAME]"           name="About Second Life"> @@ -1439,6 +1439,12 @@               function="Floater.Show"               parameter="sl_about" />          </menu_item_call> +        <menu_item_call +         label="Check for Updates" +         name="Check for Updates"> +          <menu_item_call.on_click +           function="Advanced.CheckViewerUpdates"/> +        </menu_item_call>      </menu>      <menu       create_jump_keys="true" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index cfe56e6a95..67d50d66c0 100755 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -577,6 +577,33 @@ If you no longer wish to have these abilities granted to this role, disable them        notext="Cancel"        yestext="Eject"/>    </notification> +   +  <notification +    icon="alertmodal.tga" +    name="BanGroupMemberWarning" +    type="alertmodal"> +     You are about to ban [AVATAR_NAME] from the group. +     <tag>group</tag> +     <tag>confirm</tag> +     <usetemplate +      ignoretext="Confirm banning a participant from group" +      name="okcancelignore" +      notext="Cancel" +      yestext="Ban"/> +  </notification> +  <notification +    icon="alertmodal.tga" +    name="BanGroupMembersWarning" +    type="alertmodal"> +     You are about to ban [COUNT] members from group. +     <tag>group</tag> +     <tag>confirm</tag> +     <usetemplate +      ignoretext="Confirm banning multiple members from group" +      name="okcancelignore" +      notext="Cancel" +      yestext="Ban"/> +  </notification>    <notification     icon="alertmodal.tga" @@ -783,7 +810,7 @@ Objects: [N]     icon="alertmodal.tga"     name="ReturnAllTopObjects"     type="alertmodal"> -Are you sure you want to return all listed objects back to their owner's inventory? +Are you sure you want to return all listed objects back to their owner's inventory? This will return ALL scripted objects in the region!      <tag>confirm</tag>      <usetemplate       name="okcancelbuttons" @@ -3650,6 +3677,53 @@ see [[INFO_URL] Information about this update]       name="okbutton"       yestext="OK"/>    </notification> +   +  <notification + icon="alertmodal.tga" + name="UpdateDownloadInProgress" + type="alertmodal"> +An update is available! +It's downloading in the background and we will prompt you to restart your viewer to finish installing it as soon as it's ready. +    <tag>confirm</tag> +    <usetemplate +     name="okbutton" +     yestext="OK"/> +  </notification> +   +  <notification + icon="alertmodal.tga" + name="UpdateDownloadComplete" + type="alertmodal"> +An update was downloaded. It will be installed during restart. +    <tag>confirm</tag> +    <usetemplate +     name="okbutton" +     yestext="OK"/> +  </notification> + +  <notification + icon="alertmodal.tga" + name="UpdateCheckError" + type="alertmodal"> +An error occured while checking for update. +Please try again later. +    <tag>confirm</tag> +    <usetemplate +     name="okbutton" +     yestext="OK"/> +  </notification> + +  <notification + icon="alertmodal.tga" + name="UpdateViewerUpToDate" + type="alertmodal"> +Your viewer is up to date! +If you can't wait to try out the latest features and fixes, check out the Alternate Viewers page. http://wiki.secondlife.com/wiki/Linden_Lab_Official:Alternate_Viewers. +    <tag>confirm</tag> +    <usetemplate +     name="okbutton" +     yestext="OK"/> +  </notification>    <notification     icon="alertmodal.tga" @@ -3975,6 +4049,21 @@ You have reached your maximum number of groups. Please leave some group before j    <notification     icon="alert.tga" +   name="GroupLimitInfo" +   type="alert"> +The group limit for base accounts is [MAX_BASIC], and for [https://secondlife.com/premium/ premium] +accounts is [MAX_PREMIUM]. +If you downgraded your account, you will need to get below [MAX_BASIC] group limit before you can join more. + +[https://secondlife.com/my/account/membership.php Upgrade today!] +    <tag>group</tag> +    <usetemplate +     name="okbutton" +     yestext="Close"/> +  </notification> + +  <notification +   icon="alert.tga"     name="KickUser"     type="alert">     <tag>win</tag> @@ -5460,16 +5549,19 @@ You cannot undo this action.       notext="Cancel"       yestext="OK"/>    </notification> - +      <notification -   icon="alertmodal.tga" -   name="HelpReportAbuseEmailLL" -   type="alert"> +     icon="alertmodal.tga" +     name="ConfirmUnlink" +     type="alertmodal">      <unique/> -     -Use this tool to report violations of the [http://secondlife.com/corporate/tos.php Terms of Service] and [http://secondlife.com/corporate/cs.php Community Standards]. - -All reported abuses are investigated and resolved. +    This is a large linkset. If you unlink it, you may not be able to link it again. You may wish to take a copy of the linkset into your inventory as a precaution. +    <tag>confirm</tag> +    <usetemplate +     ignoretext="Confirm when unlinking a linkset" +     name="okcancelignore" +     notext="Cancel" +     yestext="Unlink"/>    </notification>    <notification @@ -6777,15 +6869,6 @@ No valid circuit code.    <notification  	icon="notify.tga" -	name="NoValidTimestamp" -   persist="true" -	type="notify"> -   <tag>fail</tag> -No valid timestamp. -  </notification> - -  <notification -	icon="notify.tga"  	name="NoPendingConnection"     persist="true"  	type="notify"> @@ -8015,9 +8098,8 @@ Select residents to share with.      name="MeshUploadError"      icon="alert.tga"      type="alert"> -    [LABEL] failed to upload: [MESSAGE] [IDENTIFIER]  - -See the log file for details. +      [LABEL] failed to upload: [MESSAGE] [IDENTIFIER] +[DETAILS]See SecondLife.log for details    </notification>    <notification @@ -8258,7 +8340,7 @@ We cannot display a preview of this texture because it is no-copy and/or no-tran    <notification     icon="alertmodal.tga"     name="ConfirmLeaveCall" -   type="alert"> +   type="alertmodal">  Are you sure you want to leave this call?      <tag>confirm</tag>      <tag>voice</tag> diff --git a/indra/newview/skins/default/xui/en/panel_main_inventory.xml b/indra/newview/skins/default/xui/en/panel_main_inventory.xml index 0518688f45..0a85477bf4 100755 --- a/indra/newview/skins/default/xui/en/panel_main_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_main_inventory.xml @@ -21,7 +21,7 @@    </panel.string>    <panel.string     name="ItemcountUnknown"> - +    Fetched [ITEM_COUNT] Items [FILTER]    </panel.string>    <text  		     type="string" diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index 2d4665c128..4fb8b9a67f 100755 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -506,7 +506,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M                  left="3"                  use_ellipses="true"                  name="groupcount"> -              You belong to [COUNT] groups, and can join [REMAINING] more. +              You belong to [COUNT] groups, and can join [REMAINING] more.  [secondlife:/// Want more?]              </text>              <group_list               allow_select="true"  diff --git a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml index 2e778014c5..3e96160834 100755 --- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml @@ -216,7 +216,7 @@       control_name="QAMode"       follows="top|left"       height="15" -     label="Show Developer Menu" +     label="Show Develop Menu"       layout="topleft"       left="30"       name="show_develop_menu_check" diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml index ea579c6dae..d019a0a310 100755 --- a/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml @@ -60,6 +60,10 @@           name="Large(512x512)"           value="[i512,i512]" />          <combo_box.item +         label="Current Window(512x512)" +         name="CurrentWindow" +         value="[i0,i0]" /> +        <combo_box.item           label="Custom"           name="Custom"           value="[i-1,i-1]" /> diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/en/panel_snapshot_postcard.xml index 975b08be05..975b08be05 100755..100644 --- a/indra/newview/skins/default/xui/en/panel_snapshot_postcard.xml +++ b/indra/newview/skins/default/xui/en/panel_snapshot_postcard.xml diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index ca38a9bc3f..8c58ebc359 100755 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -96,7 +96,10 @@ Voice Server Version: [VOICE_VERSION]  	<string name="LoginFailed">Login failed.</string>  	<string name="Quit">Quit</string>  	<string name="create_account_url">http://join.secondlife.com/?sourceid=[sourceid]</string> - +	 +	<string name="AgniGridLabel">Second Life Main Grid (Agni)</string> +	<string name="AditiGridLabel">Second Life Beta Test Grid (Aditi)</string> +	  	<string name="ViewerDownloadURL">http://secondlife.com/download</string>  	<string name="LoginFailedViewerNotPermitted">  The viewer you are using can no longer access Second Life. Please visit the following page to download a new viewer: @@ -268,6 +271,7 @@ Please try logging in again in a minute.</string>  	<string name="TooltipMapUrl">Click to view this location on a map</string>  	<string name="TooltipSLAPP">Click to run the secondlife:// command</string>  	<string name="CurrentURL" value=" CurrentURL: [CurrentURL]" /> +	<string name="TooltipEmail">Click to compose an email</string>  	<!-- text for SLURL labels -->  	<string name="SLurlLabelTeleport">Teleport to</string> @@ -4075,5 +4079,17 @@ Try enclosing path to the editor with double quotes.    <string name="loading_chat_logs">      Loading...    </string> -   -  </strings> + +  <string name="Mav_Details_MAV_FOUND_DEGENERATE_TRIANGLES"> +      The physics shape contains triangles which are too small. Try simplifying the physics model. +  </string> + +  <string name="Mav_Details_MAV_CONFIRMATION_DATA_MISMATCH"> +      The physics shape contains bad confirmation data. Try to correct the physics model. +  </string> + +  <string name="Mav_Details_MAV_UNKNOWN_VERSION"> +      The physics shape does not have correct version. Set the correct version for the physics model. +  </string> + +</strings> diff --git a/indra/newview/skins/default/xui/es/menu_viewer.xml b/indra/newview/skins/default/xui/es/menu_viewer.xml index 797cf30387..63c84245b5 100755 --- a/indra/newview/skins/default/xui/es/menu_viewer.xml +++ b/indra/newview/skins/default/xui/es/menu_viewer.xml @@ -15,7 +15,7 @@  			<menu_item_check label="Volar" name="Fly"/>  			<menu_item_check label="Correr siempre" name="Always Run"/>  			<menu_item_call label="Parar mis animaciones" name="Stop Animating My Avatar"/> -			<menu_item_call label="Caminar / Correr / Volar..." name="Walk / run / fly"/> +			<menu_item_call label="Caminar / Correr / Volar..." name="WalkRunFly"/>  		</menu>  		<menu label="Estado" name="Status">  			<menu_item_check label="Ausente" name="Away"/> @@ -62,7 +62,7 @@  		<menu_item_call label="Foto" name="Take Snapshot"/>  		<menu_item_call label="Perfil del lugar" name="Place Profile"/>  		<menu_item_call label="Acerca del terreno" name="About Land"/> -		<menu_item_call label="Región/Estado" name="Region/Estate"/> +		<menu_item_call label="Región/Estado" name="RegionEstate"/>  		<menu_item_call label="Mis terrenos..." name="My Land"/>  		<menu_item_call label="Comprar este terreno" name="Buy Land"/>  		<menu label="Mostrar" name="LandShow"> diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml index cc0d46bfe0..4da731421a 100755 --- a/indra/newview/skins/default/xui/es/notifications.xml +++ b/indra/newview/skins/default/xui/es/notifications.xml @@ -2703,9 +2703,6 @@ Por favor, vuelve a intentarlo en unos momentos.  	<notification name="NoValidCircuit">  		Circuito de código inválido.  	</notification> -	<notification name="NoValidTimestamp"> -		Fecha inválida. -	</notification>  	<notification name="NoPendingConnection">  		No se puede crear la conexión.  	</notification> diff --git a/indra/newview/skins/default/xui/es/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/es/panel_snapshot_postcard.xml index 357b432c4c..357b432c4c 100755..100644 --- a/indra/newview/skins/default/xui/es/panel_snapshot_postcard.xml +++ b/indra/newview/skins/default/xui/es/panel_snapshot_postcard.xml diff --git a/indra/newview/skins/default/xui/fr/menu_viewer.xml b/indra/newview/skins/default/xui/fr/menu_viewer.xml index 9a4d721bc3..a13f549b1c 100755 --- a/indra/newview/skins/default/xui/fr/menu_viewer.xml +++ b/indra/newview/skins/default/xui/fr/menu_viewer.xml @@ -15,7 +15,7 @@  			<menu_item_check label="Voler" name="Fly"/>  			<menu_item_check label="Toujours courir" name="Always Run"/>  			<menu_item_call label="Arrêter mon animation" name="Stop Animating My Avatar"/> -			<menu_item_call label="Marcher / Courir / Voler..." name="Walk / run / fly"/> +			<menu_item_call label="Marcher / Courir / Voler..." name="WalkRunFly"/>  		</menu>  		<menu label="Statut" name="Status">  			<menu_item_check label="Absent" name="Away"/> @@ -63,7 +63,7 @@  		<menu_item_call label="Photo" name="Take Snapshot"/>  		<menu_item_call label="Profil du lieu" name="Place Profile"/>  		<menu_item_call label="À propos du terrain" name="About Land"/> -		<menu_item_call label="Région/Domaine" name="Region/Estate"/> +		<menu_item_call label="Région/Domaine" name="RegionEstate"/>  		<menu_item_call label="Mes terrains..." name="My Land"/>  		<menu_item_call label="Acheter ce terrain" name="Buy Land"/>  		<menu label="Afficher" name="LandShow"> diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml index 28689a93d6..a8e31951fb 100755 --- a/indra/newview/skins/default/xui/fr/notifications.xml +++ b/indra/newview/skins/default/xui/fr/notifications.xml @@ -2695,9 +2695,6 @@ Veuillez réessayer dans quelques minutes.  	<notification name="NoValidCircuit">  		Aucun code de circuit valide.  	</notification> -	<notification name="NoValidTimestamp"> -		Timestamp non valide. -	</notification>  	<notification name="NoPendingConnection">  		Impossible de créer la connexion en attente.  	</notification> diff --git a/indra/newview/skins/default/xui/fr/panel_login.xml b/indra/newview/skins/default/xui/fr/panel_login.xml index b39920fe13..1cb6d3c935 100755 --- a/indra/newview/skins/default/xui/fr/panel_login.xml +++ b/indra/newview/skins/default/xui/fr/panel_login.xml @@ -19,9 +19,9 @@  				<combo_box.item label="Domicile" name="MyHome"/>  			</combo_box>  			<button label="Connexion" name="connect_favorite_btn"/> -			<line_editor label="Tapez un emplacement" name="location_edit"/> +			<line_editor label="Tapez un emplacement" name="location_edit" left_pad="20"/>  			<button label="Connexion" name="connect_location_btn"/> -			<combo_box label="Sélectionner la grille" name="server_combo"/> +			<combo_box label="Sélectionner la grille" name="server_combo" left_pad="20"/>  		</layout_panel>  	</layout_stack>  </panel> diff --git a/indra/newview/skins/default/xui/fr/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/fr/panel_snapshot_postcard.xml index 067fa091d8..067fa091d8 100755..100644 --- a/indra/newview/skins/default/xui/fr/panel_snapshot_postcard.xml +++ b/indra/newview/skins/default/xui/fr/panel_snapshot_postcard.xml diff --git a/indra/newview/skins/default/xui/it/menu_viewer.xml b/indra/newview/skins/default/xui/it/menu_viewer.xml index 275315b455..7112d3b114 100755 --- a/indra/newview/skins/default/xui/it/menu_viewer.xml +++ b/indra/newview/skins/default/xui/it/menu_viewer.xml @@ -15,7 +15,7 @@  			<menu_item_check label="Vola" name="Fly"/>  			<menu_item_check label="Corri sempre" name="Always Run"/>  			<menu_item_call label="Ferma animazione" name="Stop Animating My Avatar"/> -			<menu_item_call label="Cammina / corri / vola..." name="Walk / run / fly"/> +			<menu_item_call label="Cammina / corri / vola..." name="WalkRunFly"/>  		</menu>  		<menu label="Stato" name="Status">  			<menu_item_check label="Assente" name="Away"/> @@ -63,7 +63,7 @@  		<menu_item_call label="Istantanea" name="Take Snapshot"/>  		<menu_item_call label="Profilo del luogo" name="Place Profile"/>  		<menu_item_call label="Informazioni sul terreno" name="About Land"/> -		<menu_item_call label="Regione/proprietà immobiliare" name="Region/Estate"/> +		<menu_item_call label="Regione/proprietà immobiliare" name="RegionEstate"/>  		<menu_item_call label="Terreni posseduti..." name="My Land"/>  		<menu_item_call label="Acquista questo terreno" name="Buy Land"/>  		<menu label="Mostra" name="LandShow"> diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml index fe53dd18dd..c9673ca70f 100755 --- a/indra/newview/skins/default/xui/it/notifications.xml +++ b/indra/newview/skins/default/xui/it/notifications.xml @@ -2700,9 +2700,6 @@ Riprova tra qualche istante.  	<notification name="NoValidCircuit">  		Nessun codice circuito valido.  	</notification> -	<notification name="NoValidTimestamp"> -		Nessuna data/timestamp valido. -	</notification>  	<notification name="NoPendingConnection">  		Impossibile creare la connessione in sospeso.  	</notification> diff --git a/indra/newview/skins/default/xui/it/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/it/panel_snapshot_postcard.xml index be7d8763b6..be7d8763b6 100755..100644 --- a/indra/newview/skins/default/xui/it/panel_snapshot_postcard.xml +++ b/indra/newview/skins/default/xui/it/panel_snapshot_postcard.xml diff --git a/indra/newview/skins/default/xui/ja/menu_viewer.xml b/indra/newview/skins/default/xui/ja/menu_viewer.xml index 40002b4f33..640d99fdda 100755 --- a/indra/newview/skins/default/xui/ja/menu_viewer.xml +++ b/indra/newview/skins/default/xui/ja/menu_viewer.xml @@ -15,7 +15,7 @@  			<menu_item_check label="飛ぶ" name="Fly"/>  			<menu_item_check label="常に走る" name="Always Run"/>  			<menu_item_call label="私のアニメーションを停止する" name="Stop Animating My Avatar"/> -			<menu_item_call label="歩行/走行/飛行..." name="Walk / run / fly"/> +			<menu_item_call label="歩行/走行/飛行..." name="WalkRunFly"/>  		</menu>  		<menu label="ログイン" name="Status">  			<menu_item_check label="一時退席中" name="Away"/> @@ -63,7 +63,7 @@  		<menu_item_call label="スナップショット" name="Take Snapshot"/>  		<menu_item_call label="場所のプロフィール" name="Place Profile"/>  		<menu_item_call label="土地情報" name="About Land"/> -		<menu_item_call label="地域 / 不動産" name="Region/Estate"/> +		<menu_item_call label="地域 / 不動産" name="RegionEstate"/>  		<menu_item_call label="保有地..." name="My Land"/>  		<menu_item_call label="この土地を購入" name="Buy Land"/>  		<menu label="表示" name="LandShow"> diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml index fba89dc296..7c9663838a 100755 --- a/indra/newview/skins/default/xui/ja/notifications.xml +++ b/indra/newview/skins/default/xui/ja/notifications.xml @@ -2743,9 +2743,6 @@ Web ページにリンクすると、他人がこの場所に簡単にアクセ  	<notification name="NoValidCircuit">  		回路コードが無効です。  	</notification> -	<notification name="NoValidTimestamp"> -		タイムスタンプが無効です。 -	</notification>  	<notification name="NoPendingConnection">  		接続を生成できません。  	</notification> diff --git a/indra/newview/skins/default/xui/ja/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/ja/panel_snapshot_postcard.xml index 569c07ad47..569c07ad47 100755..100644 --- a/indra/newview/skins/default/xui/ja/panel_snapshot_postcard.xml +++ b/indra/newview/skins/default/xui/ja/panel_snapshot_postcard.xml diff --git a/indra/newview/skins/default/xui/pl/menu_viewer.xml b/indra/newview/skins/default/xui/pl/menu_viewer.xml index a354cca9ad..65311c134c 100755 --- a/indra/newview/skins/default/xui/pl/menu_viewer.xml +++ b/indra/newview/skins/default/xui/pl/menu_viewer.xml @@ -37,7 +37,7 @@  		<menu_item_separator/>  		<menu_item_call label="Profil miejsca" name="Place Profile"/>  		<menu_item_call label="O posiadłości" name="About Land"/> -		<menu_item_call label="Region/Majątek" name="Region/Estate"/> +		<menu_item_call label="Region/Majątek" name="RegionEstate"/>  		<menu_item_call label="Kup posiadłość" name="Buy Land"/>  		<menu_item_call label="Moje posiadłości" name="My Land"/>  		<menu label="Pokaż" name="LandShow"> diff --git a/indra/newview/skins/default/xui/pl/notifications.xml b/indra/newview/skins/default/xui/pl/notifications.xml index f255b1b8ea..14f99ffa4e 100755 --- a/indra/newview/skins/default/xui/pl/notifications.xml +++ b/indra/newview/skins/default/xui/pl/notifications.xml @@ -2361,9 +2361,6 @@ Spróbuj ponowanie za kilka minut.  	<notification name="NoValidCircuit">  		Nieważny obwód kodowania.  	</notification> -	<notification name="NoValidTimestamp"> -		Niewłaściwy czas zapisu. -	</notification>  	<notification name="NoPendingConnection">  		Brak możliwości wykonania połączenia.  	</notification> diff --git a/indra/newview/skins/default/xui/pt/menu_viewer.xml b/indra/newview/skins/default/xui/pt/menu_viewer.xml index b5af342754..b02b9cdcef 100755 --- a/indra/newview/skins/default/xui/pt/menu_viewer.xml +++ b/indra/newview/skins/default/xui/pt/menu_viewer.xml @@ -15,7 +15,7 @@  			<menu_item_check label="Voar" name="Fly"/>  			<menu_item_check label="Correr sempre" name="Always Run"/>  			<menu_item_call label="Parar minha animação" name="Stop Animating My Avatar"/> -			<menu_item_call label="Andar/correr/voar..." name="Walk / run / fly"/> +			<menu_item_call label="Andar/correr/voar..." name="WalkRunFly"/>  		</menu>  		<menu label="Status" name="Status">  			<menu_item_check label="Ausente" name="Away"/> @@ -63,7 +63,7 @@  		<menu_item_call label="Foto" name="Take Snapshot"/>  		<menu_item_call label="Perfil da região" name="Place Profile"/>  		<menu_item_call label="Sobre terrenos" name="About Land"/> -		<menu_item_call label="Região/Propriedade" name="Region/Estate"/> +		<menu_item_call label="Região/Propriedade" name="RegionEstate"/>  		<menu_item_call label="Meus terrenos..." name="My Land"/>  		<menu_item_call label="Comprar este terreno" name="Buy Land"/>  		<menu label="Mostrar" name="LandShow"> diff --git a/indra/newview/skins/default/xui/pt/notifications.xml b/indra/newview/skins/default/xui/pt/notifications.xml index a01c9c757b..77dc377bbe 100755 --- a/indra/newview/skins/default/xui/pt/notifications.xml +++ b/indra/newview/skins/default/xui/pt/notifications.xml @@ -2684,9 +2684,6 @@ Por favor, tente novamente em alguns instantes.  	<notification name="NoValidCircuit">  		Código de circuito inválido.  	</notification> -	<notification name="NoValidTimestamp"> -		Hora inválida. -	</notification>  	<notification name="NoPendingConnection">  		Impossível criar a conexão pendente.  	</notification> diff --git a/indra/newview/skins/default/xui/pt/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/pt/panel_snapshot_postcard.xml index ab1545a231..ab1545a231 100755..100644 --- a/indra/newview/skins/default/xui/pt/panel_snapshot_postcard.xml +++ b/indra/newview/skins/default/xui/pt/panel_snapshot_postcard.xml diff --git a/indra/newview/skins/default/xui/ru/menu_viewer.xml b/indra/newview/skins/default/xui/ru/menu_viewer.xml index 69bb4c4af9..0480f53d66 100755 --- a/indra/newview/skins/default/xui/ru/menu_viewer.xml +++ b/indra/newview/skins/default/xui/ru/menu_viewer.xml @@ -15,7 +15,7 @@  			<menu_item_check label="Полет" name="Fly"/>  			<menu_item_check label="Всегда бегать" name="Always Run"/>  			<menu_item_call label="Остановить анимацию" name="Stop Animating My Avatar"/> -			<menu_item_call label="Ходьба / бег / полет..." name="Walk / run / fly"/> +			<menu_item_call label="Ходьба / бег / полет..." name="WalkRunFly"/>  		</menu>  		<menu label="Статус" name="Status">  			<menu_item_check label="Нет на месте" name="Away"/> @@ -61,7 +61,7 @@  		<menu_item_call label="Снимок" name="Take Snapshot"/>  		<menu_item_call label="Профиль места" name="Place Profile"/>  		<menu_item_call label="О земле" name="About Land"/> -		<menu_item_call label="Регион/землевладение" name="Region/Estate"/> +		<menu_item_call label="Регион/землевладение" name="RegionEstate"/>  		<menu_item_call label="Мои владения..." name="My Land"/>  		<menu_item_call label="Купить эту землю" name="Buy Land"/>  		<menu label="Показать" name="LandShow"> diff --git a/indra/newview/skins/default/xui/ru/notifications.xml b/indra/newview/skins/default/xui/ru/notifications.xml index 206be2e2df..0f6bbff58e 100755 --- a/indra/newview/skins/default/xui/ru/notifications.xml +++ b/indra/newview/skins/default/xui/ru/notifications.xml @@ -2695,9 +2695,6 @@ http://secondlife.com/download.  	<notification name="NoValidCircuit">  		Нет подходящего кода канала.  	</notification> -	<notification name="NoValidTimestamp"> -		Нет подходящей метки времени. -	</notification>  	<notification name="NoPendingConnection">  		Невозможно создать отложенное соединение.  	</notification> diff --git a/indra/newview/skins/default/xui/ru/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/ru/panel_snapshot_postcard.xml index 8f6ab612ff..8f6ab612ff 100755..100644 --- a/indra/newview/skins/default/xui/ru/panel_snapshot_postcard.xml +++ b/indra/newview/skins/default/xui/ru/panel_snapshot_postcard.xml diff --git a/indra/newview/skins/default/xui/tr/menu_viewer.xml b/indra/newview/skins/default/xui/tr/menu_viewer.xml index 25414b35fb..45ca6f0dcd 100755 --- a/indra/newview/skins/default/xui/tr/menu_viewer.xml +++ b/indra/newview/skins/default/xui/tr/menu_viewer.xml @@ -15,7 +15,7 @@  			<menu_item_check label="Uç" name="Fly"/>  			<menu_item_check label="Daima Koş" name="Always Run"/>  			<menu_item_call label="Beni Anime Etmeyi Durdur" name="Stop Animating My Avatar"/> -			<menu_item_call label="Yürü / koş / uç..." name="Walk / run / fly"/> +			<menu_item_call label="Yürü / koş / uç..." name="WalkRunFly"/>  		</menu>  		<menu label="Durum" name="Status">  			<menu_item_check label="Uzakta" name="Away"/> @@ -61,7 +61,7 @@  		<menu_item_call label="Anlık Görüntü" name="Take Snapshot"/>  		<menu_item_call label="Profili yerleştir" name="Place Profile"/>  		<menu_item_call label="Arazi hakkında" name="About Land"/> -		<menu_item_call label="Bölge / Gayrimenkul" name="Region/Estate"/> +		<menu_item_call label="Bölge / Gayrimenkul" name="RegionEstate"/>  		<menu_item_call label="Sahip olduğum arazi parçaları..." name="My Land"/>  		<menu_item_call label="Bu araziyi satın al" name="Buy Land"/>  		<menu label="Göster" name="LandShow"> diff --git a/indra/newview/skins/default/xui/tr/notifications.xml b/indra/newview/skins/default/xui/tr/notifications.xml index b854d3964b..750261b842 100755 --- a/indra/newview/skins/default/xui/tr/notifications.xml +++ b/indra/newview/skins/default/xui/tr/notifications.xml @@ -2695,9 +2695,6 @@ Lütfen biraz sonra tekrar deneyin.  	<notification name="NoValidCircuit">  		Geçerli bir devre kodu yok.  	</notification> -	<notification name="NoValidTimestamp"> -		Geçerli bir zaman damgası yok. -	</notification>  	<notification name="NoPendingConnection">  		Beklemedeki bağlantı oluşturulamıyor.  	</notification> diff --git a/indra/newview/skins/default/xui/tr/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/tr/panel_snapshot_postcard.xml index ecb47b2218..ecb47b2218 100755..100644 --- a/indra/newview/skins/default/xui/tr/panel_snapshot_postcard.xml +++ b/indra/newview/skins/default/xui/tr/panel_snapshot_postcard.xml diff --git a/indra/newview/skins/default/xui/zh/menu_viewer.xml b/indra/newview/skins/default/xui/zh/menu_viewer.xml index 45d3feec26..2d727b59ed 100755 --- a/indra/newview/skins/default/xui/zh/menu_viewer.xml +++ b/indra/newview/skins/default/xui/zh/menu_viewer.xml @@ -15,7 +15,7 @@  			<menu_item_check label="飛行" name="Fly"/>  			<menu_item_check label="以跑代步" name="Always Run"/>  			<menu_item_call label="停止我身上的動作" name="Stop Animating My Avatar"/> -			<menu_item_call label="行走 / 跑步 / 飛行…" name="Walk / run / fly"/> +			<menu_item_call label="行走 / 跑步 / 飛行…" name="WalkRunFly"/>  		</menu>  		<menu label="狀態" name="Status">  			<menu_item_check label="離開" name="Away"/> @@ -61,7 +61,7 @@  		<menu_item_call label="快照" name="Take Snapshot"/>  		<menu_item_call label="地點小檔案" name="Place Profile"/>  		<menu_item_call label="土地資料" name="About Land"/> -		<menu_item_call label="地區/領地" name="Region/Estate"/> +		<menu_item_call label="地區/領地" name="RegionEstate"/>  		<menu_item_call label="我所擁有的土地…" name="My Land"/>  		<menu_item_call label="購買這塊土地" name="Buy Land"/>  		<menu label="顯示" name="LandShow"> diff --git a/indra/newview/skins/default/xui/zh/notifications.xml b/indra/newview/skins/default/xui/zh/notifications.xml index 5b520dd745..4364de8c3a 100755 --- a/indra/newview/skins/default/xui/zh/notifications.xml +++ b/indra/newview/skins/default/xui/zh/notifications.xml @@ -2685,9 +2685,6 @@ SHA1 指紋:[MD5_DIGEST]  	<notification name="NoValidCircuit">  		沒有有效的線路碼。  	</notification> -	<notification name="NoValidTimestamp"> -		沒有有效的時間戳記。 -	</notification>  	<notification name="NoPendingConnection">  		無法建立待通的連線。  	</notification> diff --git a/indra/newview/skins/default/xui/zh/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/zh/panel_snapshot_postcard.xml index 77f8b335db..77f8b335db 100755..100644 --- a/indra/newview/skins/default/xui/zh/panel_snapshot_postcard.xml +++ b/indra/newview/skins/default/xui/zh/panel_snapshot_postcard.xml diff --git a/indra/newview/tests/llslurl_test.cpp b/indra/newview/tests/llslurl_test.cpp index 2bc0d5a086..4694f657b6 100755 --- a/indra/newview/tests/llslurl_test.cpp +++ b/indra/newview/tests/llslurl_test.cpp @@ -39,7 +39,21 @@ namespace  static const char * const TEST_FILENAME("llslurl_test.xml");  } -	 + +// +// Stub implementation for LLTrans +// +class LLTrans +{ +public: +	static std::string getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args); +}; + +std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args) +{ +	return std::string(); +} +  //----------------------------------------------------------------------------  // Mock objects for the dependencies of the code we're testing diff --git a/indra/newview/tests/llviewernetwork_test.cpp b/indra/newview/tests/llviewernetwork_test.cpp index 0eb0ab6500..e68da14fe9 100755 --- a/indra/newview/tests/llviewernetwork_test.cpp +++ b/indra/newview/tests/llviewernetwork_test.cpp @@ -38,6 +38,31 @@ namespace  static const char * const TEST_FILENAME("llviewernetwork_test.xml");  } + +// +// Stub implementation for LLTrans +// +class LLTrans +{ +public: +	static std::string getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args); +}; + +std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args) +{ +	std::string grid_label = std::string(); +	if(xml_desc == "AgniGridLabel") +	{ +		grid_label = "Second Life Main Grid (Agni)"; +	} +	else if(xml_desc == "AditiGridLabel") +	{ +		grid_label = "Second Life Beta Test Grid (Aditi)"; +	} + +	return grid_label; +} +  //----------------------------------------------------------------------------  // Mock objects for the dependencies of the code we're testing diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp index c152493a51..abf4ac5e21 100755 --- a/indra/viewer_components/updater/llupdaterservice.cpp +++ b/indra/viewer_components/updater/llupdaterservice.cpp @@ -132,6 +132,7 @@ public:  	void startChecking(bool install_if_ready);  	void stopChecking(); +	bool forceCheck();  	bool isChecking();  	LLUpdaterService::eUpdaterState getState(); @@ -266,6 +267,18 @@ void LLUpdaterServiceImpl::stopChecking()  	setState(LLUpdaterService::TERMINAL);  } +bool LLUpdaterServiceImpl::forceCheck() +{ +	if (mTimer.getStarted() +		&& !mIsDownloading) +	{ +		mTimer.setTimerExpirySec(0); +		setState(LLUpdaterService::CHECKING_FOR_UPDATE); +		return true; +	} +	return false; +} +  bool LLUpdaterServiceImpl::isChecking()  {  	return mIsChecking; @@ -672,6 +685,11 @@ void LLUpdaterService::stopChecking()  	mImpl->stopChecking();  } +bool LLUpdaterService::forceCheck() +{ +	return mImpl->forceCheck(); +} +  bool LLUpdaterService::isChecking()  {  	return mImpl->isChecking(); diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h index 0ddf24935b..95bbe1695c 100755 --- a/indra/viewer_components/updater/llupdaterservice.h +++ b/indra/viewer_components/updater/llupdaterservice.h @@ -84,6 +84,7 @@ public:  	void startChecking(bool install_if_ready = false);  	void stopChecking(); +	bool forceCheck();  	bool isChecking();  	eUpdaterState getState(); | 
