diff options
191 files changed, 2758 insertions, 863 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..41ee3941ac 100755 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -5584,7 +5584,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 +5592,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) else { resizeVertices(num_vertices); - if (!partial_build) + //if (!partial_build) { resizeIndices(num_indices); } @@ -5714,10 +5714,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/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..fbf2bb5f98 100755 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -1043,7 +1043,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 +1456,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; } @@ -3625,8 +3634,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/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..874046a4a8 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; } 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..95cdf90e99 100755 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -298,6 +298,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 +687,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 5589ab4aa7..13b16f5218 100755 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -985,6 +985,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++) { @@ -1012,10 +1013,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()) { @@ -1023,10 +1023,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++; } @@ -1040,14 +1039,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 @@ -1068,7 +1068,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()); @@ -1076,11 +1077,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); } @@ -1088,6 +1096,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 b3317e937e..4016529092 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -1753,9 +1753,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 @@ -1830,6 +1836,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; @@ -2432,7 +2442,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/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..e71daa6067 100755 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -289,15 +289,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/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 a047ed6fee..ddf72bc8cf 100755 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -1572,7 +1572,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 +2257,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 +2300,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 +2326,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 +2553,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 +3717,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 @@ -5739,12 +5755,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 300cef7deb..61c86ff05e 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 2546db546b..4075c329b9 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) { 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/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp index 8d21fda8f9..cf04c5f7a5 100755 --- a/indra/newview/lllocationinputctrl.cpp +++ b/indra/newview/lllocationinputctrl.cpp @@ -862,11 +862,14 @@ void LLLocationInputCtrl::refreshParcelIcons() bool see_avs = current_parcel->getSeeAVs(); bool pathfinding_dynamic_enabled = agent_region->dynamicPathfindingEnabled(); + bool is_parcel_owner = (gAgent.getID() == current_parcel->getOwnerID()); + bool allow_group_modify = (gAgent.isInGroup(current_parcel->getGroupID()) && current_parcel->getAllowGroupModify()); + // Most icons are "block this ability" mParcelIcon[VOICE_ICON]->setVisible( !allow_voice ); mParcelIcon[FLY_ICON]->setVisible( !allow_fly ); mParcelIcon[PUSH_ICON]->setVisible( !allow_push ); - mParcelIcon[BUILD_ICON]->setVisible( !allow_build ); + mParcelIcon[BUILD_ICON]->setVisible( !allow_build && !is_parcel_owner && !allow_group_modify ); mParcelIcon[SCRIPTS_ICON]->setVisible( !allow_scripts ); mParcelIcon[DAMAGE_ICON]->setVisible( allow_damage ); mParcelIcon[PATHFINDING_DIRTY_ICON]->setVisible(mIsNavMeshDirty); 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/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..d4894d4a42 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,7 @@ void LLPanelLandmarkInfo::setInfoType(EInfoType type) } else { - region_name = getString("unknown"); + region_name = desc; } mLandmarkTitleEditor->setText(llformat("%s (%d, %d, %d)", @@ -154,10 +158,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/llpaneltopinfobar.cpp b/indra/newview/llpaneltopinfobar.cpp index 109013498e..ac9a31ce4e 100755 --- a/indra/newview/llpaneltopinfobar.cpp +++ b/indra/newview/llpaneltopinfobar.cpp @@ -313,11 +313,14 @@ void LLPanelTopInfoBar::updateParcelIcons() bool allow_damage = vpm->allowAgentDamage(agent_region, current_parcel); bool see_avs = current_parcel->getSeeAVs(); + bool is_parcel_owner = (gAgent.getID() == current_parcel->getOwnerID()); + bool allow_group_modify = (gAgent.isInGroup(current_parcel->getGroupID()) && current_parcel->getAllowGroupModify()); + // Most icons are "block this ability" mParcelIcon[VOICE_ICON]->setVisible( !allow_voice ); mParcelIcon[FLY_ICON]->setVisible( !allow_fly ); mParcelIcon[PUSH_ICON]->setVisible( !allow_push ); - mParcelIcon[BUILD_ICON]->setVisible( !allow_build ); + mParcelIcon[BUILD_ICON]->setVisible( !allow_build && !is_parcel_owner && !allow_group_modify ); mParcelIcon[SCRIPTS_ICON]->setVisible( !allow_scripts ); mParcelIcon[DAMAGE_ICON]->setVisible( allow_damage ); mDamageText->setVisible(allow_damage); 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 fdc95c7784..2a107deb19 100755 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -619,10 +619,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 @@ -2103,7 +2134,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; } @@ -4889,6 +4920,7 @@ void LLSelectMgr::sendListToRegions(const std::string& message_name, ESendType send_type) { LLSelectNode* node; + LLSelectNode* linkset_root = NULL; LLViewerRegion* last_region; LLViewerRegion* current_region; @@ -4896,6 +4928,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 { @@ -5004,6 +5038,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); ++objects_sent; @@ -5030,6 +5070,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 23c41e4cc1..316e72b11c 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/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 3b0adcf7f4..6d7a8008ba 100755 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -2695,6 +2695,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 +7078,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); } } diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 459bdca8df..b3dd7207ef 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); @@ -3600,6 +3609,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 +3790,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 +6250,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 a2c0a91ea6..b8ed17f382 100755 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -4632,7 +4632,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); @@ -4642,13 +4642,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 a573b16954..2a393933d9 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(); } @@ -6054,10 +6057,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); @@ -6074,9 +6077,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); @@ -6252,6 +6265,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..cae67907dd 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); + 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,37 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) return TRUE; // No update to complete } - if (mVolumeChanged || mFaceMappingChanged ) + boost::function<bool(void)> fn_lod_or_sculpt_changed = boost::bind(&LLVOVolume::lodOrSculptChanged, this, drawable, boost::ref(compiled)); + + 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 = fn_lod_or_sculpt_changed(); drawable->setState(LLDrawable::REBUILD_VOLUME); } - + else if (mSculptChanged) { + compiled = TRUE; + was_regen_faces = fn_lod_or_sculpt_changed(); + } + + 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; + fn_lod_or_sculpt_changed(); 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 +2024,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 +2095,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 +2172,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 +2181,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 +2278,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/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/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_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_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 68ca55735a..dd02537f39 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" /> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index cfe56e6a95..227d1dd273 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" @@ -3975,6 +4002,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 +5502,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 @@ -8015,9 +8060,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 +8302,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..5e58360158 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: @@ -4075,5 +4078,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/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/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/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/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/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/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/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/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/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 |