merge changes for 3.8.3-release

master
Oz Linden 2015-08-17 16:00:04 -04:00
commit fe2eefd913
419 changed files with 12767 additions and 4406 deletions

View File

@ -505,3 +505,5 @@ d07f76c5b9860fb87924d00ca729f7d4532534d6 3.7.29-release
67edc442c80b8d2fadd2a6c4a7184b469906cdbf 3.7.30-release
797ed69e6134ef48bb922577ab2540fb2d964668 3.8.0-release
3f61ed662347dc7c6941b8266e72746a66d90e2a 3.8.1-release
3a62616f3dd8bd512fcdfd29ef033b2505b11213 3.8.2-release
60572f718879f786f6bc8b5c9373ebebf4693078 3.8.3-release

View File

@ -107,6 +107,9 @@ public:
AT_LINK_FOLDER = 25,
// Inventory folder link
AT_MARKETPLACE_FOLDER = 26,
// Marketplace folder. Same as an AT_CATEGORY but different display methods.
AT_WIDGET = 40,
// UI Widget: this is *not* an inventory asset type, only a viewer side asset (e.g. button, other ui items...)

View File

@ -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
{

View File

@ -96,6 +96,10 @@ LLFolderDictionary::LLFolderDictionary()
addEntry(LLFolderType::FT_OUTBOX, new FolderEntry("outbox", TRUE));
addEntry(LLFolderType::FT_BASIC_ROOT, new FolderEntry("basic_rt", TRUE));
addEntry(LLFolderType::FT_MARKETPLACE_LISTINGS, new FolderEntry("merchant", FALSE));
addEntry(LLFolderType::FT_MARKETPLACE_STOCK, new FolderEntry("stock", FALSE));
addEntry(LLFolderType::FT_MARKETPLACE_VERSION, new FolderEntry("version", FALSE));
addEntry(LLFolderType::FT_NONE, new FolderEntry("-1", FALSE));
};

4
indra/llinventory/llfoldertype.h Executable file → Normal file
View File

@ -87,6 +87,10 @@ public:
FT_BASIC_ROOT = 52,
FT_MARKETPLACE_LISTINGS = 53,
FT_MARKETPLACE_STOCK = 54,
FT_MARKETPLACE_VERSION = 55, // Note: We actually *never* create folders with that type. This is used for icon override only.
FT_COUNT,
FT_NONE = -1

View File

@ -633,6 +633,10 @@ void LLAssetStorage::downloadCompleteCallback(
vfile.remove();
}
}
// we will be deleting elements of mPendingDownloads which req might be part of, save id and type for reference
LLUUID callback_id = req->getUUID();
LLAssetType::EType callback_type = req->getType();
// find and callback ALL pending requests for this UUID
// SJB: We process the callbacks in reverse order, I do not know if this is important,
@ -660,7 +664,7 @@ void LLAssetStorage::downloadCompleteCallback(
{
add(sFailedDownloadCount, 1);
}
tmp->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getType(), tmp->mUserData, result, ext_status);
tmp->mDownCallback(gAssetStorage->mVFS, callback_id, callback_type, tmp->mUserData, result, ext_status);
}
delete tmp;
}

View File

@ -572,6 +572,17 @@ void LLHTTPClient::patch(
request(url, HTTP_PATCH, new LLSDInjector(body), responder, timeout, headers);
}
void LLHTTPClient::putRaw(
const std::string& url,
const U8* data,
S32 size,
ResponderPtr responder,
const LLSD& headers,
const F32 timeout)
{
request(url, HTTP_PUT, new RawInjector(data, size), responder, timeout, headers);
}
void LLHTTPClient::post(
const std::string& url,
const LLSD& body,

View File

@ -79,6 +79,14 @@ public:
ResponderPtr,
const LLSD& headers = LLSD(),
const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
static void putRaw(
const std::string& url,
const U8* data,
S32 size,
ResponderPtr responder,
const LLSD& headers = LLSD(),
const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
static void patch(
const std::string& url,

View File

@ -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();

View File

@ -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();

View File

@ -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);
}
}
{
//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
{

View File

@ -198,7 +198,7 @@ public:
void setHasMipMaps(bool hasMips) { mHasMipMaps = hasMips; }
protected:
S32 mIndex;
const S32 mIndex;
U32 mCurrTexture;
eTextureType mCurrTexType;
eTextureBlendType mCurrBlendType;

View File

@ -443,6 +443,7 @@ void LLComboBox::onFocusLost()
{
mTextEntry->selectAll();
}
mButton->setForcePressedState(false);
LLUICtrl::onFocusLost();
}

View File

@ -131,6 +131,25 @@ LLCommand * LLCommandManager::getCommand(const LLCommandId& commandId)
return command_match;
}
LLCommand * LLCommandManager::getCommand(const std::string& name)
{
LLCommand * command_match = NULL;
CommandVector::const_iterator it = mCommands.begin();
while (it != mCommands.end())
{
if ((*it)->name() == name)
{
command_match = *it;
break;
}
it++;
}
return command_match;
}
void LLCommandManager::addCommand(LLCommand * command)
{
LLCommandId command_id = command->id();

View File

@ -190,6 +190,7 @@ public:
U32 commandCount() const;
LLCommand * getCommand(U32 commandIndex);
LLCommand * getCommand(const LLCommandId& commandId);
LLCommand * getCommand(const std::string& name);
static bool load();

View File

@ -730,7 +730,7 @@ void LLFolderView::removeSelectedItems()
// structures.
std::vector<LLFolderViewItem*> items;
S32 count = mSelectedItems.size();
if(count == 0) return;
if(count <= 0) return;
LLFolderViewItem* item = NULL;
selected_items_t::iterator item_it;
for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
@ -947,7 +947,6 @@ void LLFolderView::cut()
if (listener)
{
listener->cutToClipboard();
listener->removeItem();
}
}

View File

@ -104,7 +104,8 @@ LLFolderViewItem::Params::Params()
item_height("item_height"),
item_top_pad("item_top_pad"),
creation_date(),
allow_open("allow_open", true),
allow_wear("allow_wear", true),
allow_drop("allow_drop", true),
font_color("font_color"),
font_highlight_color("font_highlight_color"),
left_pad("left_pad", 0),
@ -137,7 +138,8 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
mRoot(p.root),
mViewModelItem(p.listener),
mIsMouseOverTitle(false),
mAllowOpen(p.allow_open),
mAllowWear(p.allow_wear),
mAllowDrop(p.allow_drop),
mFontColor(p.font_color),
mFontHighlightColor(p.font_highlight_color),
mLeftPad(p.left_pad),
@ -471,7 +473,7 @@ void LLFolderViewItem::buildContextMenu(LLMenuGL& menu, U32 flags)
void LLFolderViewItem::openItem( void )
{
if (mAllowOpen)
if (mAllowWear || !getViewModelItem()->isItemWearable())
{
getViewModelItem()->openItem();
}
@ -1337,7 +1339,7 @@ void LLFolderViewFolder::gatherChildRangeExclusive(LLFolderViewItem* start, LLFo
{
return;
}
if (selecting)
if (selecting && (*it)->getVisible())
{
items.push_back(*it);
}
@ -1356,7 +1358,7 @@ void LLFolderViewFolder::gatherChildRangeExclusive(LLFolderViewItem* start, LLFo
return;
}
if (selecting)
if (selecting && (*it)->getVisible())
{
items.push_back(*it);
}
@ -1378,7 +1380,7 @@ void LLFolderViewFolder::gatherChildRangeExclusive(LLFolderViewItem* start, LLFo
return;
}
if (selecting)
if (selecting && (*it)->getVisible())
{
items.push_back(*it);
}
@ -1397,7 +1399,7 @@ void LLFolderViewFolder::gatherChildRangeExclusive(LLFolderViewItem* start, LLFo
return;
}
if (selecting)
if (selecting && (*it)->getVisible())
{
items.push_back(*it);
}
@ -1494,12 +1496,14 @@ void LLFolderViewFolder::destroyView()
while (!mItems.empty())
{
LLFolderViewItem *itemp = mItems.back();
mItems.pop_back();
itemp->destroyView(); // LLFolderViewItem::destroyView() removes entry from mItems
}
while (!mFolders.empty())
{
LLFolderViewFolder *folderp = mFolders.back();
mFolders.pop_back();
folderp->destroyView(); // LLFolderVievFolder::destroyView() removes entry from mFolders
}
@ -1797,9 +1801,16 @@ BOOL LLFolderViewFolder::handleDragAndDropToThisFolder(MASK mask,
EAcceptance* accept,
std::string& tooltip_msg)
{
if (!mAllowDrop)
{
*accept = ACCEPT_NO;
tooltip_msg = LLTrans::getString("TooltipOutboxCannotDropOnRoot");
return TRUE;
}
BOOL accepted = getViewModelItem()->dragOrDrop(mask,drop,cargo_type,cargo_data, tooltip_msg);
if (accepted)
if (accepted)
{
mDragAndDropTarget = TRUE;
*accept = ACCEPT_YES_MULTI;

View File

@ -59,7 +59,8 @@ public:
item_top_pad;
Optional<time_t> creation_date;
Optional<bool> allow_open;
Optional<bool> allow_wear;
Optional<bool> allow_drop;
Optional<LLUIColor> font_color;
Optional<LLUIColor> font_highlight_color;
@ -117,7 +118,8 @@ protected:
mIsCurSelection,
mDragAndDropTarget,
mIsMouseOverTitle,
mAllowOpen,
mAllowWear,
mAllowDrop,
mSelectPending;
LLUIColor mFontColor;

View File

@ -156,6 +156,8 @@ public:
virtual void openItem( void ) = 0;
virtual void closeItem( void ) = 0;
virtual void selectItem(void) = 0;
virtual BOOL isItemWearable() const { return FALSE; }
virtual BOOL isItemRenameable() const = 0;
virtual BOOL renameItem(const std::string& new_name) = 0;
@ -169,7 +171,7 @@ public:
virtual BOOL isItemCopyable() const = 0;
virtual BOOL copyToClipboard() const = 0;
virtual BOOL cutToClipboard() const = 0;
virtual BOOL cutToClipboard() = 0;
virtual BOOL isClipboardPasteable() const = 0;
virtual void pasteFromClipboard() = 0;

View File

@ -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;
}
}

View File

@ -2292,6 +2292,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
sHandleLeftMouseUp = true;
break;
}
sHandleDoubleClick = true;
//if (gDebugClicks)
//{

View File

@ -267,6 +267,7 @@ set(viewer_SOURCE_FILES
llfloaterlagmeter.cpp
llfloaterland.cpp
llfloaterlandholdings.cpp
llfloatermarketplacelistings.cpp
llfloatermap.cpp
llfloatermediasettings.cpp
llfloatermemleak.cpp
@ -887,6 +888,7 @@ set(viewer_HEADER_FILES
llfloaterland.h
llfloaterlandholdings.h
llfloatermap.h
llfloatermarketplacelistings.h
llfloatermediasettings.h
llfloatermemleak.h
llfloatermodelpreview.h

View File

@ -1 +1 @@
3.8.2
3.8.4

View File

@ -118,6 +118,18 @@
tooltip_ref="Command_Marketplace_Tooltip"
execute_function="Avatar.OpenMarketplace"
/>
<command name="marketplacelistings"
available_in_toybox="true"
icon="Command_MktListings_Icon"
label_ref="Command_MarketplaceListings_Label"
tooltip_ref="Command_MarketplaceListings_Tooltip"
execute_function="Marketplace.Toggle"
execute_parameters="marketplace"
is_enabled_function="Marketplace.Enabled"
is_enabled_parameters="marketplace"
is_running_function="Floater.IsOpen"
is_running_parameters="marketplace_listings"
/>
<command name="minimap"
available_in_toybox="true"
icon="Command_MiniMap_Icon"

View File

@ -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>
@ -4680,17 +4691,6 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>InventoryDisplayOutbox</key>
<map>
<key>Comment</key>
<string>Override merchant inventory outbox display</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>InventoryInboxToggleState</key>
<map>
<key>Comment</key>
@ -4713,6 +4713,17 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>InventoryOutboxDisplayBoth</key>
<map>
<key>Comment</key>
<string>Show the legacy Merchant Outbox UI as well as the Marketplace Listings UI</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>InventoryOutboxLogging</key>
<map>
<key>Comment</key>
@ -4744,7 +4755,7 @@
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>21</integer>
<integer>20</integer>
</map>
<key>InventoryOutboxMaxFolderDepth</key>
<map>
@ -4768,6 +4779,17 @@
<key>Value</key>
<integer>200</integer>
</map>
<key>InventoryOutboxMaxStockItemCount</key>
<map>
<key>Comment</key>
<string>Maximum number of items allowed in a stock folder.</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>200</integer>
</map>
<key>InventorySortOrder</key>
<map>
<key>Comment</key>
@ -4779,6 +4801,17 @@
<key>Value</key>
<integer>7</integer>
</map>
<key>MarketplaceListingsSortOrder</key>
<map>
<key>Comment</key>
<string>Specifies sort for marketplace listings</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>2</integer>
</map>
<key>InvertMouse</key>
<map>
<key>Comment</key>
@ -5628,6 +5661,17 @@
<key>Value</key>
<string />
</map>
<key>MarketplaceListingsLogging</key>
<map>
<key>Comment</key>
<string>Enable debug output associated with the Marketplace Listings (SLM) API.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>MarketplaceURL</key>
<map>
<key>Comment</key>
@ -14131,6 +14175,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>

View File

@ -23,4 +23,7 @@
<command name="snapshot"/>
<command name="facebook"/>
</left_toolbar>
<right_toolbar
button_display_mode="icons_only">
</right_toolbar>
</toolbars>

View File

@ -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

View File

@ -3873,6 +3873,12 @@ void LLAgent::handleTeleportFinished()
LLNotificationsUtil::add("PreferredMaturityChanged", args);
mIsMaturityRatingChangingDuringTeleport = false;
}
// Init SLM Marketplace connection so we know which UI should be used for the user as a merchant
// Note: Eventually, all merchant will be migrated to the new SLM system and there will be no reason to show the old UI at all.
// Note: Some regions will not support the SLM cap for a while so we need to do that check for each teleport.
// *TODO : Suppress that line from here once the whole grid migrated to SLM and move it to idle_startup() (llstartup.cpp)
check_merchant_status();
}
void LLAgent::handleTeleportFailed()

View File

@ -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;

View File

@ -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;

View File

@ -986,6 +986,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
S32 matched = 0, mismatched = 0;
const S32 arr_size = LLWearableType::WT_COUNT;
S32 type_counts[arr_size];
BOOL update_inventory = FALSE;
std::fill(type_counts,type_counts+arr_size,0);
for (S32 i = 0; i < count; i++)
{
@ -1013,10 +1014,9 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
continue;
}
// Don't care about this case - ordering of wearables with the same asset id has no effect.
// Causes the two-alphas error case in MAINT-4158.
// Update only inventory in this case - ordering of wearables with the same asset id has no effect.
// Updating wearables in this case causes the two-alphas error in MAINT-4158.
// We should actually disallow wearing two wearables with the same asset id.
#if 0
if (curr_wearable->getName() != new_item->getName() ||
curr_wearable->getItemID() != new_item->getUUID())
{
@ -1024,10 +1024,9 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
<< curr_wearable->getName() << " vs " << new_item->getName()
<< " item ids " << curr_wearable->getItemID() << " vs " << new_item->getUUID()
<< LL_ENDL;
mismatched++;
update_inventory = TRUE;
continue;
}
#endif
// If we got here, everything matches.
matched++;
}
@ -1041,14 +1040,15 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
mismatched++;
}
}
if (mismatched == 0)
if (mismatched == 0 && !update_inventory)
{
LL_DEBUGS("Avatar") << "no changes, bailing out" << LL_ENDL;
mCOFChangeInProgress = false;
return;
}
// updating inventory
// TODO: Removed check for ensuring that teens don't remove undershirt and underwear. Handle later
// note: shirt is the first non-body part wearable item. Update if wearable order changes.
// This loop should remove all clothing, but not any body parts
@ -1069,7 +1069,8 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
if (new_wearable)
{
const LLWearableType::EType type = new_wearable->getType();
LLUUID old_wearable_id = new_wearable->getItemID();
new_wearable->setName(new_item->getName());
new_wearable->setItemID(new_item->getUUID());
@ -1077,11 +1078,18 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
{
// exactly one wearable per body part
setWearable(type,0,new_wearable);
if (old_wearable_id.notNull())
{
// we changed id before setting wearable, update old item manually
// to complete the swap.
gInventory.addChangedMask(LLInventoryObserver::LABEL, old_wearable_id);
}
}
else
{
pushWearable(type,new_wearable);
}
const BOOL removed = FALSE;
wearableUpdated(new_wearable, removed);
}
@ -1089,6 +1097,15 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
gInventory.notifyObservers();
if (mismatched == 0)
{
LL_DEBUGS("Avatar") << "inventory updated, wearable assets not changed, bailing out" << LL_ENDL;
mCOFChangeInProgress = false;
return;
}
// updating agent avatar
if (isAgentAvatarValid())
{
gAgentAvatarp->setCompositeUpdatesEnabled(TRUE);

View File

@ -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;

View File

@ -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);

View File

@ -1786,9 +1786,15 @@ bool LLAppearanceMgr::getCanRemoveFromCOF(const LLUUID& outfit_cat_id)
{
return false;
}
LLInventoryModel::cat_array_t cats;
LLInventoryModel::item_array_t items;
LLFindWearablesEx is_worn(/*is_worn=*/ true, /*include_body_parts=*/ false);
return gInventory.hasMatchingDirectDescendent(outfit_cat_id, is_worn);
gInventory.collectDescendentsIf(outfit_cat_id,
cats,
items,
LLInventoryModel::EXCLUDE_TRASH,
is_worn);
return items.size() > 0;
}
// static
@ -2465,7 +2471,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();
}

View File

@ -3091,8 +3091,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;

View File

@ -934,7 +934,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);

View File

@ -86,7 +86,7 @@ public:
virtual void move( LLFolderViewModelItem* parent_listener ) { }
virtual BOOL isItemCopyable() const { return FALSE; }
virtual BOOL copyToClipboard() const { return FALSE; }
virtual BOOL cutToClipboard() const { return FALSE; }
virtual BOOL cutToClipboard() { return FALSE; }
virtual BOOL isClipboardPasteable() const { return FALSE; }
virtual void pasteFromClipboard() { }
virtual void pasteLinkFromClipboard() { }

View File

@ -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;

View File

@ -1728,6 +1728,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,6 +1746,7 @@ 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);
}
@ -1760,16 +1772,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.

View File

@ -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);
}

View File

@ -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 );
}

View File

@ -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:
};

View File

@ -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";
@ -2444,33 +2446,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);
}
@ -2490,33 +2492,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 +2921,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 +2984,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

View File

@ -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

View File

@ -0,0 +1,949 @@
/**
* @file llfloatermarketplacelistings.cpp
* @brief Implementation of the marketplace listings floater and panels
* @author merov@lindenlab.com
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloatermarketplacelistings.h"
#include "llfloaterreg.h"
#include "llfiltereditor.h"
#include "llfolderview.h"
#include "llinventorybridge.h"
#include "llinventorymodelbackgroundfetch.h"
#include "llinventoryobserver.h"
#include "llinventoryfunctions.h"
#include "llmarketplacefunctions.h"
#include "llnotificationhandler.h"
#include "llnotificationmanager.h"
#include "llnotificationsutil.h"
#include "llsidepaneliteminfo.h"
#include "lltextbox.h"
#include "lltrans.h"
///----------------------------------------------------------------------------
/// LLPanelMarketplaceListings
///----------------------------------------------------------------------------
static LLPanelInjector<LLPanelMarketplaceListings> t_panel_status("llpanelmarketplacelistings");
LLPanelMarketplaceListings::LLPanelMarketplaceListings()
: mRootFolder(NULL)
, mSortOrder(LLInventoryFilter::SO_FOLDERS_BY_NAME)
, mFilterListingFoldersOnly(false)
{
mCommitCallbackRegistrar.add("Marketplace.ViewSort.Action", boost::bind(&LLPanelMarketplaceListings::onViewSortMenuItemClicked, this, _2));
mEnableCallbackRegistrar.add("Marketplace.ViewSort.CheckItem", boost::bind(&LLPanelMarketplaceListings::onViewSortMenuItemCheck, this, _2));
}
BOOL LLPanelMarketplaceListings::postBuild()
{
childSetAction("add_btn", boost::bind(&LLPanelMarketplaceListings::onAddButtonClicked, this));
childSetAction("audit_btn", boost::bind(&LLPanelMarketplaceListings::onAuditButtonClicked, this));
mFilterEditor = getChild<LLFilterEditor>("filter_editor");
mFilterEditor->setCommitCallback(boost::bind(&LLPanelMarketplaceListings::onFilterEdit, this, _2));
mAuditBtn = getChild<LLButton>("audit_btn");
mAuditBtn->setEnabled(FALSE);
return LLPanel::postBuild();
}
BOOL LLPanelMarketplaceListings::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EDragAndDropType cargo_type,
void* cargo_data,
EAcceptance* accept,
std::string& tooltip_msg)
{
LLView * handled_view = childrenHandleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
BOOL handled = (handled_view != NULL);
// Special case the drop zone
if (handled && (handled_view->getName() == "marketplace_drop_zone"))
{
LLFolderView* root_folder = getRootFolder();
handled = root_folder->handleDragAndDropToThisFolder(mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
}
return handled;
}
void LLPanelMarketplaceListings::buildAllPanels()
{
// Build the All panel first
LLInventoryPanel* panel_all_items;
panel_all_items = buildInventoryPanel("All Items", "panel_marketplace_listings_inventory.xml");
panel_all_items->getFilter().setEmptyLookupMessage("MarketplaceNoMatchingItems");
panel_all_items->getFilter().markDefault();
// Build the other panels
LLInventoryPanel* panel;
panel = buildInventoryPanel("Active Items", "panel_marketplace_listings_listed.xml");
panel->getFilter().setFilterMarketplaceActiveFolders();
panel->getFilter().setEmptyLookupMessage("MarketplaceNoMatchingItems");
panel->getFilter().markDefault();
panel = buildInventoryPanel("Inactive Items", "panel_marketplace_listings_unlisted.xml");
panel->getFilter().setFilterMarketplaceInactiveFolders();
panel->getFilter().setEmptyLookupMessage("MarketplaceNoMatchingItems");
panel->getFilter().markDefault();
panel = buildInventoryPanel("Unassociated Items", "panel_marketplace_listings_unassociated.xml");
panel->getFilter().setFilterMarketplaceUnassociatedFolders();
panel->getFilter().setEmptyLookupMessage("MarketplaceNoMatchingItems");
panel->getFilter().markDefault();
// Set the tab panel
LLTabContainer* tabs_panel = getChild<LLTabContainer>("marketplace_filter_tabs");
tabs_panel->setCommitCallback(boost::bind(&LLPanelMarketplaceListings::onTabChange, this));
tabs_panel->selectTabPanel(panel_all_items); // All panel selected by default
mRootFolder = panel_all_items->getRootFolder(); // Keep the root of the all panel
// Set the default sort order
setSortOrder(gSavedSettings.getU32("MarketplaceListingsSortOrder"));
}
LLInventoryPanel* LLPanelMarketplaceListings::buildInventoryPanel(const std::string& childname, const std::string& filename)
{
LLTabContainer* tabs_panel = getChild<LLTabContainer>("marketplace_filter_tabs");
LLInventoryPanel* panel = LLUICtrlFactory::createFromFile<LLInventoryPanel>(filename, tabs_panel, LLInventoryPanel::child_registry_t::instance());
llassert(panel != NULL);
// Set sort order and callbacks
panel = getChild<LLInventoryPanel>(childname);
panel->getFolderViewModel()->setSorter(LLInventoryFilter::SO_FOLDERS_BY_NAME);
panel->setSelectCallback(boost::bind(&LLPanelMarketplaceListings::onSelectionChange, this, panel, _1, _2));
return panel;
}
void LLPanelMarketplaceListings::setSortOrder(U32 sort_order)
{
mSortOrder = sort_order;
gSavedSettings.setU32("MarketplaceListingsSortOrder", sort_order);
// Set each panel with that sort order
LLTabContainer* tabs_panel = getChild<LLTabContainer>("marketplace_filter_tabs");
LLInventoryPanel* panel = (LLInventoryPanel*)tabs_panel->getPanelByName("All Items");
panel->setSortOrder(mSortOrder);
panel = (LLInventoryPanel*)tabs_panel->getPanelByName("Active Items");
panel->setSortOrder(mSortOrder);
panel = (LLInventoryPanel*)tabs_panel->getPanelByName("Inactive Items");
panel->setSortOrder(mSortOrder);
panel = (LLInventoryPanel*)tabs_panel->getPanelByName("Unassociated Items");
panel->setSortOrder(mSortOrder);
}
void LLPanelMarketplaceListings::onFilterEdit(const std::string& search_string)
{
// Find active panel
LLInventoryPanel* panel = (LLInventoryPanel*)getChild<LLTabContainer>("marketplace_filter_tabs")->getCurrentPanel();
if (panel)
{
// Save filter string (needed when switching tabs)
mFilterSubString = search_string;
// Set filter string on active panel
panel->setFilterSubString(mFilterSubString);
}
}
void LLPanelMarketplaceListings::draw()
{
if (LLMarketplaceData::instance().checkDirtyCount())
{
update_all_marketplace_count();
}
// Get the audit button enabled only after the whole inventory is fetched
if (!mAuditBtn->getEnabled())
{
mAuditBtn->setEnabled(LLInventoryModelBackgroundFetch::instance().isEverythingFetched());
}
LLPanel::draw();
}
void LLPanelMarketplaceListings::onSelectionChange(LLInventoryPanel *panel, const std::deque<LLFolderViewItem*>& items, BOOL user_action)
{
panel->onSelectionChange(items, user_action);
}
bool LLPanelMarketplaceListings::allowDropOnRoot()
{
LLInventoryPanel* panel = (LLInventoryPanel*)getChild<LLTabContainer>("marketplace_filter_tabs")->getCurrentPanel();
return (panel ? panel->getAllowDropOnRoot() : false);
}
void LLPanelMarketplaceListings::onTabChange()
{
// Find active panel
LLInventoryPanel* panel = (LLInventoryPanel*)getChild<LLTabContainer>("marketplace_filter_tabs")->getCurrentPanel();
if (panel)
{
// If the panel doesn't allow drop on root, it doesn't allow the creation of new folder on root either
LLButton* add_btn = getChild<LLButton>("add_btn");
add_btn->setEnabled(panel->getAllowDropOnRoot());
// Set filter string on active panel
panel->setFilterSubString(mFilterSubString);
// Show/hide the drop zone and resize the inventory tabs panel accordingly
LLPanel* drop_zone = (LLPanel*)getChild<LLPanel>("marketplace_drop_zone");
bool drop_zone_visible = drop_zone->getVisible();
if (drop_zone_visible != panel->getAllowDropOnRoot())
{
LLPanel* tabs = (LLPanel*)getChild<LLPanel>("tab_container_panel");
S32 delta_height = drop_zone->getRect().getHeight();
delta_height = (drop_zone_visible ? delta_height : -delta_height);
tabs->reshape(tabs->getRect().getWidth(),tabs->getRect().getHeight() + delta_height);
tabs->translate(0,-delta_height);
}
drop_zone->setVisible(panel->getAllowDropOnRoot());
}
}
void LLPanelMarketplaceListings::onAddButtonClicked()
{
// Find active panel
LLInventoryPanel* panel = (LLInventoryPanel*)getChild<LLTabContainer>("marketplace_filter_tabs")->getCurrentPanel();
if (panel)
{
LLUUID marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
llassert(marketplacelistings_id.notNull());
LLFolderType::EType preferred_type = LLFolderType::lookup("category");
LLUUID category = gInventory.createNewCategory(marketplacelistings_id, preferred_type, LLStringUtil::null);
gInventory.notifyObservers();
panel->setSelectionByID(category, TRUE);
panel->getRootFolder()->setNeedsAutoRename(TRUE);
}
}
void LLPanelMarketplaceListings::onAuditButtonClicked()
{
LLSD data(LLSD::emptyMap());
LLFloaterReg::showInstance("marketplace_validation", data);
}
void LLPanelMarketplaceListings::onViewSortMenuItemClicked(const LLSD& userdata)
{
std::string chosen_item = userdata.asString();
// Sort options
if ((chosen_item == "sort_by_stock_amount") || (chosen_item == "sort_by_name") || (chosen_item == "sort_by_recent"))
{
// We're making sort options exclusive, default is SO_FOLDERS_BY_NAME
if (chosen_item == "sort_by_stock_amount")
{
setSortOrder(LLInventoryFilter::SO_FOLDERS_BY_WEIGHT);
}
else if (chosen_item == "sort_by_name")
{
setSortOrder(LLInventoryFilter::SO_FOLDERS_BY_NAME);
}
else if (chosen_item == "sort_by_recent")
{
setSortOrder(LLInventoryFilter::SO_DATE);
}
}
// Filter option
else if (chosen_item == "show_only_listing_folders")
{
mFilterListingFoldersOnly = !mFilterListingFoldersOnly;
// Set each panel with that filter flag
LLTabContainer* tabs_panel = getChild<LLTabContainer>("marketplace_filter_tabs");
LLInventoryPanel* panel = (LLInventoryPanel*)tabs_panel->getPanelByName("All Items");
panel->getFilter().setFilterMarketplaceListingFolders(mFilterListingFoldersOnly);
panel = (LLInventoryPanel*)tabs_panel->getPanelByName("Active Items");
panel->getFilter().setFilterMarketplaceListingFolders(mFilterListingFoldersOnly);
panel = (LLInventoryPanel*)tabs_panel->getPanelByName("Inactive Items");
panel->getFilter().setFilterMarketplaceListingFolders(mFilterListingFoldersOnly);
panel = (LLInventoryPanel*)tabs_panel->getPanelByName("Unassociated Items");
panel->getFilter().setFilterMarketplaceListingFolders(mFilterListingFoldersOnly);
}
}
bool LLPanelMarketplaceListings::onViewSortMenuItemCheck(const LLSD& userdata)
{
std::string chosen_item = userdata.asString();
if ((chosen_item == "sort_by_stock_amount") || (chosen_item == "sort_by_name") || (chosen_item == "sort_by_recent"))
{
if (chosen_item == "sort_by_stock_amount")
{
return (mSortOrder & LLInventoryFilter::SO_FOLDERS_BY_WEIGHT);
}
else if (chosen_item == "sort_by_name")
{
return (mSortOrder & LLInventoryFilter::SO_FOLDERS_BY_NAME);
}
else if (chosen_item == "sort_by_recent")
{
return (mSortOrder & LLInventoryFilter::SO_DATE);
}
}
else if (chosen_item == "show_only_listing_folders")
{
return mFilterListingFoldersOnly;
}
return false;
}
///----------------------------------------------------------------------------
/// LLMarketplaceListingsAddedObserver helper class
///----------------------------------------------------------------------------
class LLMarketplaceListingsAddedObserver : public LLInventoryCategoryAddedObserver
{
public:
LLMarketplaceListingsAddedObserver(LLFloaterMarketplaceListings * marketplace_listings_floater)
: LLInventoryCategoryAddedObserver()
, mMarketplaceListingsFloater(marketplace_listings_floater)
{
}
void done()
{
for (cat_vec_t::iterator it = mAddedCategories.begin(); it != mAddedCategories.end(); ++it)
{
LLViewerInventoryCategory* added_category = *it;
LLFolderType::EType added_category_type = added_category->getPreferredType();
if (added_category_type == LLFolderType::FT_MARKETPLACE_LISTINGS)
{
mMarketplaceListingsFloater->initializeMarketPlace();
}
}
}
private:
LLFloaterMarketplaceListings * mMarketplaceListingsFloater;
};
///----------------------------------------------------------------------------
/// LLFloaterMarketplaceListings
///----------------------------------------------------------------------------
LLFloaterMarketplaceListings::LLFloaterMarketplaceListings(const LLSD& key)
: LLFloater(key)
, mCategoriesObserver(NULL)
, mCategoryAddedObserver(NULL)
, mRootFolderId(LLUUID::null)
, mInventoryStatus(NULL)
, mInventoryInitializationInProgress(NULL)
, mInventoryPlaceholder(NULL)
, mInventoryText(NULL)
, mInventoryTitle(NULL)
, mPanelListings(NULL)
, mPanelListingsSet(false)
{
}
LLFloaterMarketplaceListings::~LLFloaterMarketplaceListings()
{
if (mCategoriesObserver && gInventory.containsObserver(mCategoriesObserver))
{
gInventory.removeObserver(mCategoriesObserver);
}
delete mCategoriesObserver;
if (mCategoryAddedObserver && gInventory.containsObserver(mCategoryAddedObserver))
{
gInventory.removeObserver(mCategoryAddedObserver);
}
delete mCategoryAddedObserver;
}
BOOL LLFloaterMarketplaceListings::postBuild()
{
mInventoryStatus = getChild<LLTextBox>("marketplace_status");
mInventoryInitializationInProgress = getChild<LLView>("initialization_progress_indicator");
mInventoryPlaceholder = getChild<LLView>("marketplace_listings_inventory_placeholder_panel");
mInventoryText = mInventoryPlaceholder->getChild<LLTextBox>("marketplace_listings_inventory_placeholder_text");
mInventoryTitle = mInventoryPlaceholder->getChild<LLTextBox>("marketplace_listings_inventory_placeholder_title");
mPanelListings = static_cast<LLPanelMarketplaceListings*>(getChild<LLUICtrl>("panel_marketplace_listing"));
LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLFloaterMarketplaceListings::onFocusReceived, this));
// Observe category creation to catch marketplace listings creation (moot if already existing)
mCategoryAddedObserver = new LLMarketplaceListingsAddedObserver(this);
gInventory.addObserver(mCategoryAddedObserver);
// Fetch aggressively so we can interact with listings right onOpen()
fetchContents();
return TRUE;
}
void LLFloaterMarketplaceListings::onClose(bool app_quitting)
{
}
void LLFloaterMarketplaceListings::onOpen(const LLSD& key)
{
//
// Initialize the Market Place or go update the marketplace listings
//
if (LLMarketplaceData::instance().getSLMStatus() <= MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE)
{
initializeMarketPlace();
}
else
{
updateView();
}
}
void LLFloaterMarketplaceListings::onFocusReceived()
{
updateView();
}
void LLFloaterMarketplaceListings::fetchContents()
{
if (mRootFolderId.notNull() &&
(LLMarketplaceData::instance().getSLMDataFetched() != MarketplaceFetchCodes::MARKET_FETCH_LOADING) &&
(LLMarketplaceData::instance().getSLMDataFetched() != MarketplaceFetchCodes::MARKET_FETCH_DONE))
{
LLMarketplaceData::instance().setDataFetchedSignal(boost::bind(&LLFloaterMarketplaceListings::updateView, this));
LLMarketplaceData::instance().setSLMDataFetched(MarketplaceFetchCodes::MARKET_FETCH_LOADING);
LLInventoryModelBackgroundFetch::instance().start(mRootFolderId);
LLMarketplaceData::instance().getSLMListings();
}
}
void LLFloaterMarketplaceListings::setRootFolder()
{
if ((LLMarketplaceData::instance().getSLMStatus() != MarketplaceStatusCodes::MARKET_PLACE_MERCHANT) &&
(LLMarketplaceData::instance().getSLMStatus() != MarketplaceStatusCodes::MARKET_PLACE_MIGRATED_MERCHANT))
{
// If we are *not* a merchant or we have no market place connection established yet, do nothing
return;
}
// We are a merchant. Get the Marketplace listings folder, create it if needs be.
LLUUID marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, true);
if (marketplacelistings_id.isNull())
{
// We should never get there unless the inventory fails badly
LL_ERRS("SLM") << "Inventory problem: failure to create the marketplace listings folder for a merchant!" << LL_ENDL;
return;
}
// No longer need to observe new category creation
if (mCategoryAddedObserver && gInventory.containsObserver(mCategoryAddedObserver))
{
gInventory.removeObserver(mCategoryAddedObserver);
delete mCategoryAddedObserver;
mCategoryAddedObserver = NULL;
}
llassert(!mCategoryAddedObserver);
if (marketplacelistings_id == mRootFolderId)
{
LL_WARNS("SLM") << "Inventory warning: Marketplace listings folder already set" << LL_ENDL;
return;
}
mRootFolderId = marketplacelistings_id;
}
void LLFloaterMarketplaceListings::setPanels()
{
if (mRootFolderId.isNull())
{
return;
}
// Consolidate Marketplace listings
// We shouldn't have to do that but with a client/server system relying on a "well known folder" convention,
// things get messy and conventions get broken down eventually
gInventory.consolidateForType(mRootFolderId, LLFolderType::FT_MARKETPLACE_LISTINGS);
// Now that we do have a non NULL root, we can build the inventory panels
mPanelListings->buildAllPanels();
// Create observer for marketplace listings modifications
if (!mCategoriesObserver)
{
mCategoriesObserver = new LLInventoryCategoriesObserver();
llassert(mCategoriesObserver);
gInventory.addObserver(mCategoriesObserver);
mCategoriesObserver->addCategory(mRootFolderId, boost::bind(&LLFloaterMarketplaceListings::onChanged, this));
}
// Get the content of the marketplace listings folder
fetchContents();
// Flag that this is done
mPanelListingsSet = true;
}
void LLFloaterMarketplaceListings::initializeMarketPlace()
{
LLMarketplaceData::instance().initializeSLM(boost::bind(&LLFloaterMarketplaceListings::updateView, this));
}
S32 LLFloaterMarketplaceListings::getFolderCount()
{
if (mPanelListings && mRootFolderId.notNull())
{
LLInventoryModel::cat_array_t * cats;
LLInventoryModel::item_array_t * items;
gInventory.getDirectDescendentsOf(mRootFolderId, cats, items);
return (cats->size() + items->size());
}
else
{
return 0;
}
}
void LLFloaterMarketplaceListings::setStatusString(const std::string& statusString)
{
mInventoryStatus->setText(statusString);
}
void LLFloaterMarketplaceListings::updateView()
{
U32 mkt_status = LLMarketplaceData::instance().getSLMStatus();
bool is_merchant = (mkt_status == MarketplaceStatusCodes::MARKET_PLACE_MERCHANT) || (mkt_status == MarketplaceStatusCodes::MARKET_PLACE_MIGRATED_MERCHANT);
U32 data_fetched = LLMarketplaceData::instance().getSLMDataFetched();
// Get or create the root folder if we are a merchant and it hasn't been done already
if (mRootFolderId.isNull() && is_merchant)
{
setRootFolder();
}
// Update the bottom initializing status and progress dial if we are initializing or if we're a merchant and still loading
if ((mkt_status <= MarketplaceStatusCodes::MARKET_PLACE_INITIALIZING) || (is_merchant && (data_fetched <= MarketplaceFetchCodes::MARKET_FETCH_LOADING)) )
{
// Just show the loading indicator in that case and fetch the data (fetch will be skipped if it's already loading)
mInventoryInitializationInProgress->setVisible(true);
mPanelListings->setVisible(FALSE);
fetchContents();
return;
}
else
{
mInventoryInitializationInProgress->setVisible(false);
}
// Update the middle portion : tabs or messages
if (getFolderCount() > 0)
{
if (!mPanelListingsSet)
{
// We need to rebuild the tabs cleanly the first time we make them visible
setPanels();
}
mPanelListings->setVisible(TRUE);
mInventoryPlaceholder->setVisible(FALSE);
}
else
{
mPanelListings->setVisible(FALSE);
mInventoryPlaceholder->setVisible(TRUE);
std::string text;
std::string title;
std::string tooltip;
const LLSD& subs = getMarketplaceStringSubstitutions();
// Update the top message or flip to the tabs and folders view
// *TODO : check those messages and create better appropriate ones in strings.xml
if (mRootFolderId.notNull())
{
// "Marketplace listings is empty!" message strings
text = LLTrans::getString("InventoryMarketplaceListingsNoItems", subs);
title = LLTrans::getString("InventoryMarketplaceListingsNoItemsTitle");
tooltip = LLTrans::getString("InventoryMarketplaceListingsNoItemsTooltip");
}
else if (mkt_status <= MarketplaceStatusCodes::MARKET_PLACE_INITIALIZING)
{
// "Initializing!" message strings
text = LLTrans::getString("InventoryOutboxInitializing", subs);
title = LLTrans::getString("InventoryOutboxInitializingTitle");
tooltip = LLTrans::getString("InventoryOutboxInitializingTooltip");
}
else if (mkt_status == MarketplaceStatusCodes::MARKET_PLACE_NOT_MERCHANT)
{
// "Not a merchant!" message strings
text = LLTrans::getString("InventoryOutboxNotMerchant", subs);
title = LLTrans::getString("InventoryOutboxNotMerchantTitle");
tooltip = LLTrans::getString("InventoryOutboxNotMerchantTooltip");
}
else
{
// "Errors!" message strings
text = LLTrans::getString("InventoryMarketplaceError", subs);
title = LLTrans::getString("InventoryOutboxErrorTitle");
tooltip = LLTrans::getString("InventoryOutboxErrorTooltip");
}
mInventoryText->setValue(text);
mInventoryTitle->setValue(title);
mInventoryPlaceholder->getParent()->setToolTip(tooltip);
}
}
bool LLFloaterMarketplaceListings::isAccepted(EAcceptance accept)
{
return (accept >= ACCEPT_YES_COPY_SINGLE);
}
BOOL LLFloaterMarketplaceListings::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EDragAndDropType cargo_type,
void* cargo_data,
EAcceptance* accept,
std::string& tooltip_msg)
{
// If there's no panel to accept drops or no existing marketplace listings folder, we refuse all drop
if (!mPanelListings || mRootFolderId.isNull())
{
return FALSE;
}
tooltip_msg = "";
// Pass to the children
LLView * handled_view = childrenHandleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
BOOL handled = (handled_view != NULL);
// If no one handled it or it was not accepted and we drop on an empty panel, we try to accept it at the floater level
// as if it was dropped on the marketplace listings root folder
if ((!handled || !isAccepted(*accept)) && !mPanelListings->getVisible() && mRootFolderId.notNull())
{
if (!mPanelListingsSet)
{
setPanels();
}
LLFolderView* root_folder = mPanelListings->getRootFolder();
handled = root_folder->handleDragAndDropToThisFolder(mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
}
return handled;
}
BOOL LLFloaterMarketplaceListings::handleHover(S32 x, S32 y, MASK mask)
{
return LLFloater::handleHover(x, y, mask);
}
void LLFloaterMarketplaceListings::onMouseLeave(S32 x, S32 y, MASK mask)
{
LLFloater::onMouseLeave(x, y, mask);
}
void LLFloaterMarketplaceListings::onChanged()
{
LLViewerInventoryCategory* category = gInventory.getCategory(mRootFolderId);
if (mRootFolderId.notNull() && category)
{
updateView();
}
else
{
// Invalidate the marketplace listings data
mRootFolderId.setNull();
}
}
//-----------------------------------------------------------------------------
// LLFloaterAssociateListing
//-----------------------------------------------------------------------------
// Tell if a listing has one only version folder
bool hasUniqueVersionFolder(const LLUUID& folder_id)
{
LLInventoryModel::cat_array_t* categories;
LLInventoryModel::item_array_t* items;
gInventory.getDirectDescendentsOf(folder_id, categories, items);
return (categories->size() == 1);
}
LLFloaterAssociateListing::LLFloaterAssociateListing(const LLSD& key)
: LLFloater(key)
, mUUID()
{
}
LLFloaterAssociateListing::~LLFloaterAssociateListing()
{
gFocusMgr.releaseFocusIfNeeded( this );
}
BOOL LLFloaterAssociateListing::postBuild()
{
getChild<LLButton>("OK")->setCommitCallback(boost::bind(&LLFloaterAssociateListing::apply, this, TRUE));
getChild<LLButton>("Cancel")->setCommitCallback(boost::bind(&LLFloaterAssociateListing::cancel, this));
getChild<LLLineEditor>("listing_id")->setPrevalidate(&LLTextValidate::validateNonNegativeS32);
center();
return LLFloater::postBuild();
}
BOOL LLFloaterAssociateListing::handleKeyHere(KEY key, MASK mask)
{
if (key == KEY_RETURN && mask == MASK_NONE)
{
apply();
return TRUE;
}
else if (key == KEY_ESCAPE && mask == MASK_NONE)
{
cancel();
return TRUE;
}
return LLFloater::handleKeyHere(key, mask);
}
// static
LLFloaterAssociateListing* LLFloaterAssociateListing::show(const LLUUID& folder_id)
{
LLFloaterAssociateListing* floater = LLFloaterReg::showTypedInstance<LLFloaterAssociateListing>("associate_listing");
floater->mUUID = folder_id;
return floater;
}
// Callback for apply if DAMA required...
void LLFloaterAssociateListing::callback_apply(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if (option == 0) // YES
{
apply(FALSE);
}
}
void LLFloaterAssociateListing::apply(BOOL user_confirm)
{
if (mUUID.notNull())
{
S32 id = (S32)getChild<LLUICtrl>("listing_id")->getValue().asInteger();
if (id > 0)
{
// Check if the id exists in the merchant SLM DB: note that this record might exist in the LLMarketplaceData
// structure even if unseen in the UI, for instance, if its listing_uuid doesn't exist in the merchant inventory
LLUUID listing_uuid = LLMarketplaceData::instance().getListingFolder(id);
if (listing_uuid.notNull() && user_confirm && LLMarketplaceData::instance().getActivationState(listing_uuid) && !hasUniqueVersionFolder(mUUID))
{
// Look for user confirmation before unlisting
LLNotificationsUtil::add("ConfirmMerchantUnlist", LLSD(), LLSD(), boost::bind(&LLFloaterAssociateListing::callback_apply, this, _1, _2));
return;
}
// Associate the id with the user chosen folder
LLMarketplaceData::instance().associateListing(mUUID,listing_uuid,id);
}
else
{
LLNotificationsUtil::add("AlertMerchantListingInvalidID");
}
}
closeFloater();
}
void LLFloaterAssociateListing::cancel()
{
closeFloater();
}
//-----------------------------------------------------------------------------
// LLFloaterMarketplaceValidation
//-----------------------------------------------------------------------------
// Note: The key is the UUID of the folder to validate.
// Validates the whole marketplace listings content if UUID is null.
LLFloaterMarketplaceValidation::LLFloaterMarketplaceValidation(const LLSD& key)
: LLFloater(key),
mEditor(NULL)
{
}
BOOL LLFloaterMarketplaceValidation::postBuild()
{
childSetAction("OK", onOK, this);
// This widget displays the validation messages
mEditor = getChild<LLTextEditor>("validation_text");
mEditor->setEnabled(FALSE);
mEditor->setFocus(TRUE);
mEditor->setValue(LLSD());
return TRUE;
}
LLFloaterMarketplaceValidation::~LLFloaterMarketplaceValidation()
{
}
// virtual
void LLFloaterMarketplaceValidation::draw()
{
// draw children
LLFloater::draw();
}
void LLFloaterMarketplaceValidation::onOpen(const LLSD& key)
{
// Clear the messages
clearMessages();
// Get the folder UUID to validate. Use the whole marketplace listing if none provided.
LLUUID cat_id(key.asUUID());
if (cat_id.isNull())
{
cat_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
}
// Validates the folder
if (cat_id.notNull())
{
LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
validate_marketplacelistings(cat, boost::bind(&LLFloaterMarketplaceValidation::appendMessage, this, _1, _2, _3), false);
}
// Handle the listing folder being processed
handleCurrentListing();
// Dump result to the editor panel
if (mEditor)
{
mEditor->setValue(LLSD());
if (mMessages.empty())
{
// Display a no error message
mEditor->appendText(LLTrans::getString("Marketplace Validation No Error"), false);
}
else
{
// Print out all the messages to the panel
message_list_t::iterator mCurrentLine = mMessages.begin();
bool new_line = false;
while (mCurrentLine != mMessages.end())
{
// Errors are printed in bold, other messages in normal font
LLStyle::Params style;
LLFontDescriptor new_desc(mEditor->getFont()->getFontDesc());
new_desc.setStyle(mCurrentLine->mErrorLevel == LLError::LEVEL_ERROR ? LLFontGL::BOLD : LLFontGL::NORMAL);
LLFontGL* new_font = LLFontGL::getFont(new_desc);
style.font = new_font;
mEditor->appendText(mCurrentLine->mMessage, new_line, style);
new_line = true;
mCurrentLine++;
}
}
}
// We don't need the messages anymore
clearMessages();
}
// static
void LLFloaterMarketplaceValidation::onOK( void* userdata )
{
// destroys this object
LLFloaterMarketplaceValidation* self = (LLFloaterMarketplaceValidation*) userdata;
self->clearMessages();
self->closeFloater();
}
void LLFloaterMarketplaceValidation::appendMessage(std::string& message, S32 depth, LLError::ELevel log_level)
{
// Dump previous listing messages if we're starting a new listing
if (depth == 1)
{
handleCurrentListing();
}
// Store the message in the current listing message list
Message current_message;
current_message.mErrorLevel = log_level;
current_message.mMessage = message;
mCurrentListingMessages.push_back(current_message);
mCurrentListingErrorLevel = (mCurrentListingErrorLevel < log_level ? log_level : mCurrentListingErrorLevel);
}
// Move the current listing messages to the general list if needs be and reset the current listing data
void LLFloaterMarketplaceValidation::handleCurrentListing()
{
// Dump the current folder messages to the general message list if level warrants it
if (mCurrentListingErrorLevel > LLError::LEVEL_INFO)
{
message_list_t::iterator mCurrentLine = mCurrentListingMessages.begin();
while (mCurrentLine != mCurrentListingMessages.end())
{
mMessages.push_back(*mCurrentLine);
mCurrentLine++;
}
}
// Reset the current listing
mCurrentListingMessages.clear();
mCurrentListingErrorLevel = LLError::LEVEL_INFO;
}
void LLFloaterMarketplaceValidation::clearMessages()
{
mMessages.clear();
mCurrentListingMessages.clear();
mCurrentListingErrorLevel = LLError::LEVEL_INFO;
}
//-----------------------------------------------------------------------------
// LLFloaterItemProperties
//-----------------------------------------------------------------------------
LLFloaterItemProperties::LLFloaterItemProperties(const LLSD& key)
: LLFloater(key)
{
}
LLFloaterItemProperties::~LLFloaterItemProperties()
{
}
BOOL LLFloaterItemProperties::postBuild()
{
// On the standalone properties floater, we have no need for a back button...
LLSidepanelItemInfo* panel = getChild<LLSidepanelItemInfo>("item_panel");
LLButton* back_btn = panel->getChild<LLButton>("back_btn");
back_btn->setVisible(FALSE);
return LLFloater::postBuild();
}
void LLFloaterItemProperties::onOpen(const LLSD& key)
{
// Tell the panel which item it needs to visualize
LLSidepanelItemInfo* panel = getChild<LLSidepanelItemInfo>("item_panel");
panel->setItemID(key["id"].asUUID());
}

View File

@ -0,0 +1,226 @@
/**
* @file llfloatermarketplacelistings.h
* @brief Implementation of the marketplace listings floater and panels
* @author merov@lindenlab.com
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* ABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLFLOATERMARKETPLACELISTINGS_H
#define LL_LLFLOATERMARKETPLACELISTINGS_H
#include "llfloater.h"
#include "llinventoryfilter.h"
#include "llinventorypanel.h"
#include "llnotificationptr.h"
#include "llmodaldialog.h"
#include "lltexteditor.h"
class LLInventoryCategoriesObserver;
class LLInventoryCategoryAddedObserver;
class LLTextBox;
class LLView;
class LLFilterEditor;
class LLFloaterMarketplaceListings;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLPanelMarketplaceListings
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLPanelMarketplaceListings : public LLPanel
{
public:
LLPanelMarketplaceListings();
BOOL postBuild();
BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EDragAndDropType cargo_type,
void* cargo_data,
EAcceptance* accept,
std::string& tooltip_msg);
void draw();
LLFolderView* getRootFolder() { return mRootFolder; }
bool allowDropOnRoot();
void buildAllPanels();
private:
LLInventoryPanel* buildInventoryPanel(const std::string& childname, const std::string& filename);
// UI callbacks
void onViewSortMenuItemClicked(const LLSD& userdata);
bool onViewSortMenuItemCheck(const LLSD& userdata);
void onAddButtonClicked();
void onAuditButtonClicked();
void onSelectionChange(LLInventoryPanel *panel, const std::deque<LLFolderViewItem*>& items, BOOL user_action);
void onTabChange();
void onFilterEdit(const std::string& search_string);
void setSortOrder(U32 sort_order);
LLFolderView* mRootFolder;
LLButton* mAuditBtn;
LLFilterEditor* mFilterEditor;
std::string mFilterSubString;
bool mFilterListingFoldersOnly;
U32 mSortOrder;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLFloaterMarketplaceListings
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLFloaterMarketplaceListings : public LLFloater
{
public:
LLFloaterMarketplaceListings(const LLSD& key);
~LLFloaterMarketplaceListings();
void initializeMarketPlace();
// virtuals
BOOL postBuild();
BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EDragAndDropType cargo_type,
void* cargo_data,
EAcceptance* accept,
std::string& tooltip_msg);
void showNotification(const LLNotificationPtr& notification);
BOOL handleHover(S32 x, S32 y, MASK mask);
void onMouseLeave(S32 x, S32 y, MASK mask);
protected:
void setRootFolder();
void setPanels();
void fetchContents();
void setStatusString(const std::string& statusString);
void onClose(bool app_quitting);
void onOpen(const LLSD& key);
void onFocusReceived();
void onChanged();
bool isAccepted(EAcceptance accept);
void updateView();
private:
S32 getFolderCount();
LLInventoryCategoriesObserver * mCategoriesObserver;
LLInventoryCategoryAddedObserver * mCategoryAddedObserver;
LLTextBox * mInventoryStatus;
LLView * mInventoryInitializationInProgress;
LLView * mInventoryPlaceholder;
LLTextBox * mInventoryText;
LLTextBox * mInventoryTitle;
LLUUID mRootFolderId;
LLPanelMarketplaceListings * mPanelListings;
bool mPanelListingsSet;
};
//-----------------------------------------------------------------------------
// LLFloaterAssociateListing
//-----------------------------------------------------------------------------
class LLFloaterAssociateListing : public LLFloater
{
friend class LLFloaterReg;
public:
virtual BOOL postBuild();
virtual BOOL handleKeyHere(KEY key, MASK mask);
static LLFloaterAssociateListing* show(const LLUUID& folder_id);
private:
LLFloaterAssociateListing(const LLSD& key);
virtual ~LLFloaterAssociateListing();
// UI Callbacks
void apply(BOOL user_confirm = TRUE);
void cancel();
void callback_apply(const LLSD& notification, const LLSD& response);
LLUUID mUUID;
};
//-----------------------------------------------------------------------------
// LLFloaterMarketplaceValidation
//-----------------------------------------------------------------------------
// Note: The key is the UUID of the folder to validate. Validates the whole
// marketplace listings content if UUID is null.
// Note: For the moment, we just display the validation text. Eventually, we should
// get the validation triggered on the server and display the html report.
// *TODO : morph into an html/text window using the pattern in llfloatertos
class LLFloaterMarketplaceValidation : public LLFloater
{
public:
LLFloaterMarketplaceValidation(const LLSD& key);
virtual ~LLFloaterMarketplaceValidation();
virtual BOOL postBuild();
virtual void draw();
virtual void onOpen(const LLSD& key);
void clearMessages();
void appendMessage(std::string& message, S32 depth, LLError::ELevel log_level);
static void onOK( void* userdata );
private:
struct Message {
LLError::ELevel mErrorLevel;
std::string mMessage;
};
typedef std::vector<Message> message_list_t;
void handleCurrentListing();
message_list_t mCurrentListingMessages;
LLError::ELevel mCurrentListingErrorLevel;
message_list_t mMessages;
LLTextEditor* mEditor;
};
//-----------------------------------------------------------------------------
// LLFloaterItemProperties
//-----------------------------------------------------------------------------
class LLFloaterItemProperties : public LLFloater
{
public:
LLFloaterItemProperties(const LLSD& key);
virtual ~LLFloaterItemProperties();
BOOL postBuild();
virtual void onOpen(const LLSD& key);
private:
};
#endif // LL_LLFLOATERMARKETPLACELISTINGS_H

View File

@ -3810,11 +3810,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 +4851,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 +5135,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 +5243,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 +5273,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 +5291,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 +5566,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 +5635,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];

View File

@ -160,6 +160,12 @@ BOOL LLFloaterOutbox::postBuild()
mCategoryAddedObserver = new LLOutboxAddedObserver(this);
gInventory.addObserver(mCategoryAddedObserver);
// Setup callbacks for importer
LLMarketplaceInventoryImporter& importer = LLMarketplaceInventoryImporter::instance();
importer.setInitializationErrorCallback(boost::bind(&LLFloaterOutbox::initializationReportError, this, _1, _2));
importer.setStatusChangedCallback(boost::bind(&LLFloaterOutbox::importStatusChanged, this, _1));
importer.setStatusReportCallback(boost::bind(&LLFloaterOutbox::importReportResults, this, _1, _2));
return TRUE;
}
@ -298,12 +304,8 @@ void LLFloaterOutbox::initializeMarketPlace()
// Initialize the marketplace import API
//
LLMarketplaceInventoryImporter& importer = LLMarketplaceInventoryImporter::instance();
if (!importer.isInitialized())
{
importer.setInitializationErrorCallback(boost::bind(&LLFloaterOutbox::initializationReportError, this, _1, _2));
importer.setStatusChangedCallback(boost::bind(&LLFloaterOutbox::importStatusChanged, this, _1));
importer.setStatusReportCallback(boost::bind(&LLFloaterOutbox::importReportResults, this, _1, _2));
importer.initialize();
}
}
@ -516,7 +518,7 @@ void LLFloaterOutbox::onImportButtonClicked()
{
mOutboxInventoryPanel.get()->clearSelection();
}
mImportBusy = LLMarketplaceInventoryImporter::instance().triggerImport();
}
@ -617,3 +619,5 @@ void LLFloaterOutbox::showNotification(const LLNotificationPtr& notification)
notification_handler->processNotification(notification);
}

View File

@ -1,7 +1,6 @@
/**
* @file llfloateroutbox.h
* @brief LLFloaterOutbox
* class definition
* @brief Implementation of the merchant outbox window
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
@ -30,6 +29,7 @@
#include "llfloater.h"
#include "llfoldertype.h"
#include "llinventoryfilter.h"
#include "llnotificationptr.h"

View File

@ -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 );

View File

@ -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:

View File

@ -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);
}
}

View File

@ -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*)

View File

@ -201,11 +201,13 @@ private:
std::map<std::string, std::string> mStatusText;
protected:
LLSD mMediaSettings;
public:
static bool sShowObjectCost;
static bool sPreviousFocusOnAvatar;
};

View File

@ -27,6 +27,7 @@
#include "llviewerprecompiledheaders.h"
#include "llfolderviewmodelinventory.h"
#include "llinventorymodelbackgroundfetch.h"
#include "llinventoryfunctions.h"
#include "llinventorypanel.h"
#include "lltooldraganddrop.h"
#include "llfavoritesbar.h"
@ -277,7 +278,7 @@ bool LLInventorySort::operator()(const LLFolderViewModelItemInventory* const& a,
// We sort by name if we aren't sorting by date
// OR if these are folders and we are sorting folders by name.
bool by_name = (!mByDate || (mFoldersByName && (a->getSortGroup() != SG_ITEM)));
bool by_name = ((!mByDate || (mFoldersByName && (a->getSortGroup() != SG_ITEM))) && !mFoldersByWeight);
if (a->getSortGroup() != b->getSortGroup())
{
@ -309,6 +310,31 @@ bool LLInventorySort::operator()(const LLFolderViewModelItemInventory* const& a,
return (compare < 0);
}
}
else if (mFoldersByWeight)
{
S32 weight_a = compute_stock_count(a->getUUID());
S32 weight_b = compute_stock_count(b->getUUID());
if (weight_a == weight_b)
{
// Equal weight -> use alphabetical order
return (LLStringUtil::compareDict(a->getDisplayName(), b->getDisplayName()) < 0);
}
else if (weight_a == COMPUTE_STOCK_INFINITE)
{
// No stock -> move a at the end of the list
return false;
}
else if (weight_b == COMPUTE_STOCK_INFINITE)
{
// No stock -> move b at the end of the list
return true;
}
else
{
// Lighter is first (sorted in increasing order of weight)
return (weight_a < weight_b);
}
}
else
{
time_t first_create = a->getCreationDate();

View File

@ -89,6 +89,7 @@ public:
mByDate = (mSortOrder & LLInventoryFilter::SO_DATE);
mSystemToTop = (mSortOrder & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP);
mFoldersByName = (mSortOrder & LLInventoryFilter::SO_FOLDERS_BY_NAME);
mFoldersByWeight = (mSortOrder & LLInventoryFilter::SO_FOLDERS_BY_WEIGHT);
}
bool operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b) const;
@ -97,6 +98,7 @@ private:
bool mByDate;
bool mSystemToTop;
bool mFoldersByName;
bool mFoldersByWeight;
};
class LLFolderViewModelInventory

View File

@ -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)

View File

@ -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);

View File

@ -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);

File diff suppressed because it is too large Load Diff

View File

@ -77,6 +77,7 @@ public:
bool canShare() const;
bool canListOnMarketplace() const;
bool canListOnOutboxNow() const;
bool canListOnMarketplaceNow() const;
//--------------------------------------------------------------------
@ -115,7 +116,7 @@ public:
virtual void move(LLFolderViewModelItem* new_parent_bridge) {}
virtual BOOL isItemCopyable() const { return FALSE; }
virtual BOOL copyToClipboard() const;
virtual BOOL cutToClipboard() const;
virtual BOOL cutToClipboard();
virtual BOOL isClipboardPasteable() const;
virtual BOOL isClipboardPasteableAsLink() const;
virtual void pasteFromClipboard() {}
@ -147,6 +148,9 @@ protected:
virtual void addOutboxContextMenuOptions(U32 flags,
menuentry_vec_t &items,
menuentry_vec_t &disabled_items);
virtual void addMarketplaceContextMenuOptions(U32 flags,
menuentry_vec_t &items,
menuentry_vec_t &disabled_items);
protected:
LLInvFVBridge(LLInventoryPanel* inventory, LLFolderView* root, const LLUUID& uuid);
@ -161,6 +165,7 @@ protected:
BOOL isInboxFolder() const; // true if COF or descendant of marketplace inbox
BOOL isOutboxFolderDirectParent() const;
BOOL isMarketplaceListingsFolder() const; // true if descendant of Marketplace listings folder
const LLUUID getOutboxFolder() const;
virtual BOOL isItemPermissive() const;
@ -173,6 +178,9 @@ protected:
const LLUUID& new_parent,
BOOL restamp);
void removeBatchNoCheck(std::vector<LLFolderViewModelItem*>& batch);
BOOL callback_cutToClipboard(const LLSD& notification, const LLSD& response);
BOOL perform_cutToClipboard();
public:
BOOL isOutboxFolder() const; // true if COF or descendant of marketplace outbox
@ -188,6 +196,7 @@ protected:
mutable std::string mSearchableName;
void purgeItem(LLInventoryModel *model, const LLUUID &uuid);
void removeObject(LLInventoryModel *model, const LLUUID &uuid);
virtual void buildDisplayName() const {}
};
@ -264,8 +273,10 @@ public:
mIsLoading(false)
{}
BOOL dragItemIntoFolder(LLInventoryItem* inv_item, BOOL drop, std::string& tooltip_msg);
BOOL dragCategoryIntoFolder(LLInventoryCategory* inv_category, BOOL drop, std::string& tooltip_msg);
BOOL dragItemIntoFolder(LLInventoryItem* inv_item, BOOL drop, std::string& tooltip_msg, BOOL user_confirm = TRUE);
BOOL dragCategoryIntoFolder(LLInventoryCategory* inv_category, BOOL drop, std::string& tooltip_msg, BOOL user_confirm = TRUE);
void callback_dropItemIntoFolder(const LLSD& notification, const LLSD& response, LLInventoryItem* inv_item);
void callback_dropCategoryIntoFolder(const LLSD& notification, const LLSD& response, LLInventoryCategory* inv_category);
virtual void buildDisplayName() const;
@ -280,10 +291,9 @@ public:
virtual LLUIImagePtr getIcon() const;
virtual LLUIImagePtr getIconOpen() const;
virtual LLUIImagePtr getIconOverlay() const;
static LLUIImagePtr getIcon(LLFolderType::EType preferred_type);
virtual std::string getLabelSuffix() const;
virtual LLFontGL::StyleFlags getLabelStyle() const;
virtual BOOL renameItem(const std::string& new_name);
@ -355,12 +365,17 @@ public:
static LLHandle<LLFolderBridge> sSelf;
static void staticFolderOptionsMenu();
private:
protected:
void callback_pasteFromClipboard(const LLSD& notification, const LLSD& response);
void perform_pasteFromClipboard();
void gatherMessage(std::string& message, S32 depth, LLError::ELevel log_level);
LLUIImagePtr getFolderIcon(BOOL is_open) const;
bool mCallingCards;
bool mWearables;
bool mIsLoading;
LLTimer mTimeSinceRequestStart;
std::string mMessage;
LLRootHandle<LLFolderBridge> mHandle;
};
@ -441,6 +456,7 @@ public:
const LLUUID& uuid) :
LLItemBridge(inventory, root, uuid) {}
virtual void openItem();
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
};
class LLGestureBridge : public LLItemBridge
@ -484,6 +500,7 @@ public:
virtual LLUIImagePtr getIcon() const;
virtual void performAction(LLInventoryModel* model, std::string action);
virtual void openItem();
virtual BOOL isItemWearable() const { return TRUE; }
virtual std::string getLabelSuffix() const;
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
virtual BOOL renameItem(const std::string& new_name);
@ -516,6 +533,7 @@ public:
virtual LLUIImagePtr getIcon() const;
virtual void performAction(LLInventoryModel* model, std::string action);
virtual void openItem();
virtual BOOL isItemWearable() const { return TRUE; }
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
virtual std::string getLabelSuffix() const;
virtual BOOL renameItem(const std::string& new_name);
@ -669,6 +687,31 @@ public:
U32 flags = 0x00) const;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Marketplace Inventory Panel related classes
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLMarketplaceFolderBridge : public LLFolderBridge
{
public:
// Overloads some display related methods specific to folders in a marketplace floater context
LLMarketplaceFolderBridge(LLInventoryPanel* inventory,
LLFolderView* root,
const LLUUID& uuid);
virtual LLUIImagePtr getIcon() const;
virtual LLUIImagePtr getIconOpen() const;
virtual std::string getLabelSuffix() const;
virtual LLFontGL::StyleFlags getLabelStyle() const;
private:
LLUIImagePtr getMarketplaceFolderIcon(BOOL is_open) const;
// Those members are mutable because they are cached variablse to speed up display, not a state variables
mutable S32 m_depth;
mutable S32 m_stockCountCache;
};
void rez_attachment(LLViewerInventoryItem* item,
LLViewerJointAttachment* attachment,
bool replace = false);

View File

@ -33,6 +33,8 @@
#include "llfolderviewitem.h"
#include "llinventorymodel.h"
#include "llinventorymodelbackgroundfetch.h"
#include "llinventoryfunctions.h"
#include "llmarketplacefunctions.h"
#include "llviewercontrol.h"
#include "llfolderview.h"
#include "llinventorybridge.h"
@ -68,7 +70,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),
@ -136,12 +139,64 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
}
// when applying a filter, matching folders get their contents downloaded first
if (mFilterSubString.size()
if (isNotDefault()
&& !gInventory.isCategoryComplete(folder_id))
{
LLInventoryModelBackgroundFetch::instance().start(folder_id);
}
// Marketplace folder filtering
const U32 filterTypes = mFilterOps.mFilterTypes;
const U32 marketplace_filter = FILTERTYPE_MARKETPLACE_ACTIVE | FILTERTYPE_MARKETPLACE_INACTIVE |
FILTERTYPE_MARKETPLACE_UNASSOCIATED | FILTERTYPE_MARKETPLACE_LISTING_FOLDER |
FILTERTYPE_NO_MARKETPLACE_ITEMS;
if (filterTypes & marketplace_filter)
{
S32 depth = depth_nesting_in_marketplace(folder_id);
if (filterTypes & FILTERTYPE_NO_MARKETPLACE_ITEMS)
{
if (depth >= 0)
{
return false;
}
}
if (filterTypes & FILTERTYPE_MARKETPLACE_LISTING_FOLDER)
{
if (depth > 1)
{
return false;
}
}
if (depth > 0)
{
LLUUID listing_uuid = nested_parent_id(folder_id, depth);
if (filterTypes & FILTERTYPE_MARKETPLACE_ACTIVE)
{
if (!LLMarketplaceData::instance().getActivationState(listing_uuid))
{
return false;
}
}
else if (filterTypes & FILTERTYPE_MARKETPLACE_INACTIVE)
{
if (!LLMarketplaceData::instance().isListed(listing_uuid) || LLMarketplaceData::instance().getActivationState(listing_uuid))
{
return false;
}
}
else if (filterTypes & FILTERTYPE_MARKETPLACE_UNASSOCIATED)
{
if (LLMarketplaceData::instance().isListed(listing_uuid))
{
return false;
}
}
}
}
// show folder links
LLViewerInventoryItem* item = gInventory.getItem(folder_id);
if (item && item->getActualType() == LLAssetType::AT_LINK_FOLDER)
@ -501,6 +556,40 @@ void LLInventoryFilter::setFilterEmptySystemFolders()
mFilterOps.mFilterTypes |= FILTERTYPE_EMPTYFOLDERS;
}
void LLInventoryFilter::setFilterMarketplaceActiveFolders()
{
mFilterOps.mFilterTypes |= FILTERTYPE_MARKETPLACE_ACTIVE;
}
void LLInventoryFilter::setFilterMarketplaceInactiveFolders()
{
mFilterOps.mFilterTypes |= FILTERTYPE_MARKETPLACE_INACTIVE;
}
void LLInventoryFilter::setFilterMarketplaceUnassociatedFolders()
{
mFilterOps.mFilterTypes |= FILTERTYPE_MARKETPLACE_UNASSOCIATED;
}
void LLInventoryFilter::setFilterMarketplaceListingFolders(bool select_only_listing_folders)
{
if (select_only_listing_folders)
{
mFilterOps.mFilterTypes |= FILTERTYPE_MARKETPLACE_LISTING_FOLDER;
setModified(FILTER_MORE_RESTRICTIVE);
}
else
{
mFilterOps.mFilterTypes &= ~FILTERTYPE_MARKETPLACE_LISTING_FOLDER;
setModified(FILTER_LESS_RESTRICTIVE);
}
}
void LLInventoryFilter::setFilterNoMarketplaceFolder()
{
mFilterOps.mFilterTypes |= FILTERTYPE_NO_MARKETPLACE_ITEMS;
}
void LLInventoryFilter::setFilterUUID(const LLUUID& object_id)
{
if (mFilterOps.mFilterUUID == LLUUID::null)
@ -546,6 +635,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 +657,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 +847,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;

View File

@ -52,7 +52,12 @@ public:
FILTERTYPE_UUID = 0x1 << 2, // find the object with UUID and any links to it
FILTERTYPE_DATE = 0x1 << 3, // search by date range
FILTERTYPE_WEARABLE = 0x1 << 4, // search by wearable type
FILTERTYPE_EMPTYFOLDERS = 0x1 << 5 // pass if folder is not a system folder to be hidden if
FILTERTYPE_EMPTYFOLDERS = 0x1 << 5, // pass if folder is not a system folder to be hidden if empty
FILTERTYPE_MARKETPLACE_ACTIVE = 0x1 << 6, // pass if folder is a marketplace active folder
FILTERTYPE_MARKETPLACE_INACTIVE = 0x1 << 7, // pass if folder is a marketplace inactive folder
FILTERTYPE_MARKETPLACE_UNASSOCIATED = 0x1 << 8, // pass if folder is a marketplace non associated (no market ID) folder
FILTERTYPE_MARKETPLACE_LISTING_FOLDER = 0x1 << 9, // pass iff folder is a listing folder
FILTERTYPE_NO_MARKETPLACE_ITEMS = 0x1 << 10 // pass iff folder is not under the marketplace
};
enum EFilterDateDirection
@ -73,7 +78,8 @@ public:
SO_NAME = 0, // Sort inventory by name
SO_DATE = 0x1, // Sort inventory by date
SO_FOLDERS_BY_NAME = 0x1 << 1, // Force folder sort by name
SO_SYSTEM_FOLDERS_TO_TOP = 0x1 << 2 // Force system folders to be on top
SO_SYSTEM_FOLDERS_TO_TOP = 0x1 << 2,// Force system folders to be on top
SO_FOLDERS_BY_WEIGHT = 0x1 << 3, // Force folder sort by weight, usually, amount of some elements in their descendents
};
struct FilterOps
@ -170,6 +176,11 @@ public:
void setFilterUUID(const LLUUID &object_id);
void setFilterWearableTypes(U64 types);
void setFilterEmptySystemFolders();
void setFilterMarketplaceActiveFolders();
void setFilterMarketplaceInactiveFolders();
void setFilterMarketplaceUnassociatedFolders();
void setFilterMarketplaceListingFolders(bool select_only_listing_folders);
void setFilterNoMarketplaceFolder();
void updateFilterTypes(U64 types, U64& current_types);
void setFilterSubString(const std::string& string);
@ -193,6 +204,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 +281,7 @@ private:
FilterOps mFilterOps;
FilterOps mDefaultFilterOps;
FilterOps mBackupFilterOps; // for backup purposes when leaving 'search link' mode
std::string mFilterSubString;
std::string mFilterSubStringOrig;

File diff suppressed because it is too large Load Diff

View File

@ -30,8 +30,13 @@
#include "llinventorymodel.h"
#include "llinventory.h"
#include "llhandle.h"
#include "llwearabletype.h"
// compute_stock_count() return error code
const S32 COMPUTE_STOCK_INFINITE = -1;
const S32 COMPUTE_STOCK_NOT_EVALUATED = -2;
/********************************************************************************
** **
** MISCELLANEOUS GLOBAL FUNCTIONS
@ -58,18 +63,33 @@ void show_task_item_profile(const LLUUID& item_uuid, const LLUUID& object_id);
void show_item_original(const LLUUID& item_uuid);
void reset_inventory_filter();
// Nudge the listing categories in the inventory to signal that their marketplace status changed
void update_marketplace_category(const LLUUID& cat_id, bool perform_consistency_enforcement = true);
// Nudge all listing categories to signal that their marketplace status changed
void update_all_marketplace_count();
void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::string& new_name);
void copy_inventory_category(LLInventoryModel* model, LLViewerInventoryCategory* cat, const LLUUID& parent_id, const LLUUID& root_copy_id = LLUUID::null);
void copy_inventory_category(LLInventoryModel* model, LLViewerInventoryCategory* cat, const LLUUID& parent_id, const LLUUID& root_copy_id = LLUUID::null, bool move_no_copy_items = false);
// Generates a string containing the path to the item specified by item_id.
void append_path(const LLUUID& id, std::string& path);
void copy_item_to_outbox(LLInventoryItem* inv_item, LLUUID dest_folder, const LLUUID& top_level_folder, S32 operation_id);
void move_item_within_outbox(LLInventoryItem* inv_item, LLUUID dest_folder, S32 operation_id);
void copy_folder_to_outbox(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, const LLUUID& top_level_folder, S32 operation_id);
typedef boost::function<void(std::string& validation_message, S32 depth, LLError::ELevel log_level)> validation_callback_t;
bool can_move_item_to_marketplace(const LLInventoryCategory* root_folder, LLInventoryCategory* dest_folder, LLInventoryItem* inv_item, std::string& tooltip_msg, S32 bundle_size = 1, bool from_paste = false);
bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLInventoryCategory* dest_folder, LLInventoryCategory* inv_cat, std::string& tooltip_msg, S32 bundle_size = 1, bool check_items = true, bool from_paste = false);
bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_folder, bool copy = false);
bool move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, bool copy = false, bool move_no_copy_items = false);
bool validate_marketplacelistings(LLInventoryCategory* inv_cat, validation_callback_t cb = NULL, bool fix_hierarchy = true, S32 depth = -1);
S32 depth_nesting_in_marketplace(LLUUID cur_uuid);
LLUUID nested_parent_id(LLUUID cur_uuid, S32 depth);
S32 compute_stock_count(LLUUID cat_uuid, bool force_count = false);
/** Miscellaneous global functions
** **
*******************************************************************************/
@ -425,7 +445,8 @@ public:
*******************************************************************************/
class LLFolderViewItem;
class LLFolderViewFolder;
class LLInventoryModel;
class LLFolderView;
class LLInventoryState
{
@ -437,10 +458,16 @@ public:
struct LLInventoryAction
{
static void doToSelected(class LLInventoryModel* model, class LLFolderView* root, const std::string& action);
static void doToSelected(LLInventoryModel* model, LLFolderView* root, const std::string& action, BOOL user_confirm = TRUE);
static void callback_doToSelected(const LLSD& notification, const LLSD& response, class LLInventoryModel* model, class LLFolderView* root, const std::string& action);
static void callback_copySelected(const LLSD& notification, const LLSD& response, class LLInventoryModel* model, class LLFolderView* root, const std::string& action);
static void onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response, LLHandle<LLFolderView> root);
static void removeItemFromDND(LLFolderView* root);
static void onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response, LLFolderView* root);
static void removeItemFromDND(LLFolderView* root);
private:
static void buildMarketplaceFolders(LLFolderView* root);
static void updateMarketplaceFolders();
static std::list<LLUUID> sMarketplaceFolders; // Marketplace folders that will need update once the action is completed
};

View File

@ -41,6 +41,7 @@
#include "llinventoryobserver.h"
#include "llinventorypanel.h"
#include "llnotificationsutil.h"
#include "llmarketplacefunctions.h"
#include "llwindow.h"
#include "llviewercontrol.h"
#include "llpreview.h"
@ -1023,7 +1024,7 @@ LLInventoryModel::item_array_t* LLInventoryModel::getUnlockedItemArray(const LLU
// an existing item with the matching id, or it will add the category.
void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat, U32 mask)
{
if(cat->getUUID().isNull())
if(!cat || cat->getUUID().isNull())
{
return;
}
@ -1037,7 +1038,8 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat, U32
LLPointer<LLViewerInventoryCategory> old_cat = getCategory(cat->getUUID());
if(old_cat)
{
// We already have an old category, modify it's values
// We already have an old category, modify its values
U32 mask = LLInventoryObserver::NONE;
LLUUID old_parent_id = old_cat->getParentUUID();
LLUUID new_parent_id = cat->getParentUUID();
if(old_parent_id != new_parent_id)
@ -1061,7 +1063,13 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat, U32
{
mask |= LLInventoryObserver::LABEL;
}
old_cat->copyViewerCategory(cat);
// Under marketplace, category labels are quite complex and need extra upate
const LLUUID marketplace_id = findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
if (marketplace_id.notNull() && isObjectDescendentOf(cat->getUUID(), marketplace_id))
{
mask |= LLInventoryObserver::LABEL;
}
old_cat->copyViewerCategory(cat);
addChangedMask(mask, cat->getUUID());
}
else
@ -1411,6 +1419,11 @@ void LLInventoryModel::deleteObject(const LLUUID& id, bool fix_broken_links, boo
LLPointer<LLViewerInventoryCategory> cat = (LLViewerInventoryCategory*)((LLInventoryObject*)obj);
vector_replace_with_last(*cat_list, cat);
}
// Note : We need to tell the inventory observers that those things are going to be deleted *before* the tree is cleared or they won't know what to delete (in views and view models)
addChangedMask(LLInventoryObserver::REMOVE, id);
gInventory.notifyObservers();
item_list = getUnlockedItemArray(id);
if(item_list)
{
@ -1558,10 +1571,11 @@ void LLInventoryModel::addChangedMask(U32 mask, const LLUUID& referent)
}
}
mModifyMask |= mask;
if (referent.notNull())
mModifyMask |= mask;
if (referent.notNull() && (mChangedItemIDs.find(referent) == mChangedItemIDs.end()))
{
mChangedItemIDs.insert(referent);
update_marketplace_category(referent, false);
if (mask & LLInventoryObserver::ADD)
{
@ -1981,17 +1995,22 @@ bool LLInventoryModel::loadSkeleton(
// we can safely ignore anything loaded from file, but
// not sent down in the skeleton. Must have been removed from inventory.
if(cit == not_cached)
if (cit == not_cached)
{
continue;
}
if(cat->getVersion() != tcat->getVersion())
else if (cat->getVersion() != tcat->getVersion())
{
// if the cached version does not match the server version,
// throw away the version we have so we can fetch the
// correct contents the next time the viewer opens the folder.
tcat->setVersion(NO_VERSION);
}
else if (tcat->getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK)
{
// Do not trust stock folders being updated
tcat->setVersion(NO_VERSION);
}
else
{
cached_ids.insert(tcat->getUUID());
@ -3046,7 +3065,18 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**)
LL_DEBUGS("Inventory") << "unpacked folder '" << tfolder->getName() << "' ("
<< tfolder->getUUID() << ") in " << tfolder->getParentUUID()
<< LL_ENDL;
if(tfolder->getUUID().notNull())
// If the folder is a listing or a version folder, all we need to do is update the SLM data
int depth_folder = depth_nesting_in_marketplace(tfolder->getUUID());
if ((depth_folder == 1) || (depth_folder == 2))
{
// Trigger an SLM listing update
LLUUID listing_uuid = (depth_folder == 1 ? tfolder->getUUID() : tfolder->getParentUUID());
S32 listing_id = LLMarketplaceData::instance().getListingID(listing_uuid);
LLMarketplaceData::instance().getListing(listing_id);
// In that case, there is no item to update so no callback -> we skip the rest of the update
}
else if(tfolder->getUUID().notNull())
{
folders.push_back(tfolder);
LLViewerInventoryCategory* folderp = gInventory.getCategory(tfolder->getUUID());

View File

@ -193,6 +193,7 @@ LLFolderView * LLInventoryPanel::createFolderRoot(LLUUID root_id )
p.show_empty_message = mShowEmptyMessage;
p.show_item_link_overlays = mShowItemLinkOverlays;
p.root = NULL;
p.allow_drop = mParams.allow_drop_on_root;
p.options_menu = "menu_inventory.xml";
return LLUICtrlFactory::create<LLFolderView>(p);
@ -292,7 +293,12 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_INBOX));
getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_OUTBOX));
}
// hide marketplace listing box, unless we are a marketplace panel
if (!gSavedSettings.getBOOL("InventoryOutboxMakeVisible") && !mParams.use_marketplace_folders)
{
getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_MARKETPLACE_LISTINGS));
}
// set the filter for the empty folder if the debug setting is on
if (gSavedSettings.getBOOL("DebugHideEmptySystemFolders"))
{
@ -601,13 +607,13 @@ void LLInventoryPanel::modelChanged(U32 mask)
LLUUID LLInventoryPanel::getRootFolderID()
{
LLUUID root_id;
if (mFolderRoot.get() && mFolderRoot.get()->getViewModelItem())
{
return static_cast<LLFolderViewModelItemInventory*>(mFolderRoot.get()->getViewModelItem())->getUUID();
root_id = static_cast<LLFolderViewModelItemInventory*>(mFolderRoot.get()->getViewModelItem())->getUUID();
}
else
{
LLUUID root_id;
if (mParams.start_folder.id.isChosen())
{
root_id = mParams.start_folder.id;
@ -635,8 +641,8 @@ LLUUID LLInventoryPanel::getRootFolderID()
}
}
}
return root_id;
}
return root_id;
}
// static
@ -758,7 +764,7 @@ void LLInventoryPanel::initializeViews()
}
LLFolderViewFolder * LLInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge)
LLFolderViewFolder * LLInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge, bool allow_drop)
{
LLFolderViewFolder::Params params(mParams.folder);
@ -766,6 +772,7 @@ LLFolderViewFolder * LLInventoryPanel::createFolderViewFolder(LLInvFVBridge * br
params.root = mFolderRoot.get();
params.listener = bridge;
params.tool_tip = params.name;
params.allow_drop = allow_drop;
params.font_color = (bridge->isLibraryItem() ? sLibraryColor : (bridge->isLink() ? sLinkColor : sDefaultColor));
params.font_highlight_color = (bridge->isLibraryItem() ? sLibraryColor : (bridge->isLink() ? sLinkColor : sDefaultHighlightColor));
@ -794,37 +801,56 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
{
LLInventoryObject const* objectp = gInventory.getObject(id);
if (!objectp) return NULL;
if (!objectp)
{
return NULL;
}
LLFolderViewItem* folder_view_item = getItemByID(id);
const LLUUID &parent_id = objectp->getParentUUID();
const LLUUID &parent_id = objectp->getParentUUID();
LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)getItemByID(parent_id);
// Force the creation of an extra root level folder item if required by the inventory panel (default is "false")
bool allow_drop = true;
bool create_root = false;
if (mParams.show_root_folder)
{
LLUUID root_id = getRootFolderID();
if (root_id == id)
{
// We insert an extra level that's seen by the UI but has no influence on the model
parent_folder = dynamic_cast<LLFolderViewFolder*>(folder_view_item);
folder_view_item = NULL;
allow_drop = mParams.allow_drop_on_root;
create_root = true;
}
}
if (!folder_view_item && parent_folder)
{
if (objectp->getType() <= LLAssetType::AT_NONE ||
objectp->getType() >= LLAssetType::AT_COUNT)
{
LL_WARNS() << "LLInventoryPanel::buildNewViews called with invalid objectp->mType : "
<< ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID()
<< LL_ENDL;
<< ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID()
<< LL_ENDL;
return NULL;
}
if ((objectp->getType() == LLAssetType::AT_CATEGORY) &&
(objectp->getActualType() != LLAssetType::AT_LINK_FOLDER))
{
LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(objectp->getType(),
objectp->getType(),
LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY,
(mParams.use_marketplace_folders ? LLAssetType::AT_MARKETPLACE_FOLDER : LLAssetType::AT_CATEGORY),
LLInventoryType::IT_CATEGORY,
this,
&mInventoryViewModel,
&mInventoryViewModel,
mFolderRoot.get(),
objectp->getUUID());
if (new_listener)
{
folder_view_item = createFolderViewFolder(new_listener);
folder_view_item = createFolderViewFolder(new_listener,allow_drop);
}
}
else
@ -847,11 +873,16 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
}
if (folder_view_item)
{
{
llassert(parent_folder != NULL);
folder_view_item->addToFolder(parent_folder);
addItemID(id, folder_view_item);
}
// In the case of the root folder been shown, open that folder by default once the widget is created
if (create_root)
{
folder_view_item->setOpen(TRUE);
}
}
}
// If this is a folder, add the children of the folder and recursively add any
@ -960,7 +991,7 @@ BOOL LLInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
// If folder view is empty the (x, y) point won't be in its rect
// so the handler must be called explicitly.
// but only if was not handled before. See EXT-6746.
if (!handled && !mFolderRoot.get()->hasVisibleChildren())
if (!handled && mParams.allow_drop_on_root && !mFolderRoot.get()->hasVisibleChildren())
{
handled = mFolderRoot.get()->handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
}
@ -1482,6 +1513,8 @@ public:
LLInventoryPanel::initFromParams(p);
// turn on inbox for recent items
getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() | (1ULL << LLFolderType::FT_INBOX));
// turn off marketplace for recent items
getFilter().setFilterNoMarketplaceFolder();
}
protected:
@ -1525,5 +1558,8 @@ namespace LLInitParam
declare(LLFolderType::lookup(LLFolderType::FT_INBOX) , LLFolderType::FT_INBOX);
declare(LLFolderType::lookup(LLFolderType::FT_OUTBOX) , LLFolderType::FT_OUTBOX);
declare(LLFolderType::lookup(LLFolderType::FT_BASIC_ROOT) , LLFolderType::FT_BASIC_ROOT);
declare(LLFolderType::lookup(LLFolderType::FT_MARKETPLACE_LISTINGS) , LLFolderType::FT_MARKETPLACE_LISTINGS);
declare(LLFolderType::lookup(LLFolderType::FT_MARKETPLACE_STOCK), LLFolderType::FT_MARKETPLACE_STOCK);
declare(LLFolderType::lookup(LLFolderType::FT_MARKETPLACE_VERSION), LLFolderType::FT_MARKETPLACE_VERSION);
}
}

View File

@ -97,6 +97,9 @@ public:
Optional<StartFolder> start_folder;
Optional<bool> use_label_suffix;
Optional<bool> show_empty_message;
Optional<bool> show_root_folder;
Optional<bool> allow_drop_on_root;
Optional<bool> use_marketplace_folders;
Optional<LLScrollContainer::Params> scroll;
Optional<bool> accepts_drag_and_drop;
Optional<LLFolderView::Params> folder_view;
@ -111,7 +114,10 @@ public:
filter("filter"),
start_folder("start_folder"),
use_label_suffix("use_label_suffix", true),
show_empty_message("show_empty_message", true),
show_empty_message("show_empty_message", true),
show_root_folder("show_root_folder", false),
allow_drop_on_root("allow_drop_on_root", true),
use_marketplace_folders("use_marketplace_folders", false),
scroll("scroll"),
accepts_drag_and_drop("accepts_drag_and_drop"),
folder_view("folder_view"),
@ -185,6 +191,7 @@ public:
LLFolderView* getRootFolder() { return mFolderRoot.get(); }
LLUUID getRootFolderID();
LLScrollContainer* getScrollableContainer() { return mScroller; }
bool getAllowDropOnRoot() { return mParams.allow_drop_on_root; }
void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
@ -293,7 +300,7 @@ protected:
BOOL getIsHiddenFolderType(LLFolderType::EType folder_type) const;
virtual LLFolderView * createFolderRoot(LLUUID root_id );
virtual LLFolderViewFolder* createFolderViewFolder(LLInvFVBridge * bridge);
virtual LLFolderViewFolder* createFolderViewFolder(LLInvFVBridge * bridge, bool allow_drop);
virtual LLFolderViewItem* createFolderViewItem(LLInvFVBridge * bridge);
private:
bool mBuildDefaultHierarchy; // default inventory hierarchy should be created in postBuild()

View File

@ -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();

View File

@ -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);

File diff suppressed because it is too large Load Diff

View File

@ -66,8 +66,21 @@ namespace MarketplaceStatusCodes
MARKET_PLACE_NOT_INITIALIZED = 0,
MARKET_PLACE_INITIALIZING = 1,
MARKET_PLACE_CONNECTION_FAILURE = 2,
MARKET_PLACE_MERCHANT = 3,
MARKET_PLACE_NOT_MERCHANT = 4,
MARKET_PLACE_NOT_MERCHANT = 3,
MARKET_PLACE_MERCHANT = 4,
MARKET_PLACE_NOT_MIGRATED_MERCHANT = 5,
MARKET_PLACE_MIGRATED_MERCHANT = 6
};
}
namespace MarketplaceFetchCodes
{
enum sCode
{
MARKET_FETCH_NOT_DONE = 0,
MARKET_FETCH_LOADING = 1,
MARKET_FETCH_FAILED = 2,
MARKET_FETCH_DONE = 3
};
}
@ -109,6 +122,166 @@ private:
};
// Classes handling the data coming from and going to the Marketplace SLM Server DB:
// * implement the Marketplace API
// * cache the current Marketplace data (tuples)
// * provide methods to get Marketplace data on any inventory item
// * set Marketplace data
// * signal Marketplace updates to inventory
namespace SLMErrorCodes
{
enum eCode
{
SLM_SUCCESS = 200,
SLM_RECORD_CREATED = 201,
SLM_MALFORMED_PAYLOAD = 400,
SLM_NOT_FOUND = 404,
};
}
class LLMarketplaceData;
class LLInventoryObserver;
// A Marketplace item is known by its tuple
class LLMarketplaceTuple
{
public:
friend class LLMarketplaceData;
LLMarketplaceTuple();
LLMarketplaceTuple(const LLUUID& folder_id);
LLMarketplaceTuple(const LLUUID& folder_id, S32 listing_id, const LLUUID& version_id, bool is_listed = false);
private:
// Representation of a marketplace item in the Marketplace DB (well, what we know of it...)
LLUUID mListingFolderId;
S32 mListingId;
LLUUID mVersionFolderId;
bool mIsActive;
S32 mCountOnHand;
std::string mEditURL;
};
// Notes:
// * The mListingFolderId is used as a key to this map. It could therefore be taken off the LLMarketplaceTuple objects themselves.
// * The SLM DB however uses mListingId as its primary key and it shows in its API. In the viewer though, the mListingFolderId is what we use to grab an inventory record.
typedef std::map<LLUUID, LLMarketplaceTuple> marketplace_items_list_t;
typedef std::map<LLUUID, LLUUID> version_folders_list_t;
// Session cache of all Marketplace tuples
// Notes:
// * There's one and only one possible set of Marketplace dataset per agent and per session thus making it an LLSingleton
// * Some of those records might correspond to folders that do not exist in the inventory anymore. We do not clear them out though. They just won't show up in the UI.
class LLSLMGetMerchantResponder;
class LLSLMGetListingsResponder;
class LLSLMCreateListingsResponder;
class LLSLMGetListingResponder;
class LLSLMUpdateListingsResponder;
class LLSLMAssociateListingsResponder;
class LLSLMDeleteListingsResponder;
class LLMarketplaceData
: public LLSingleton<LLMarketplaceData>
{
public:
friend class LLSLMGetMerchantResponder;
friend class LLSLMGetListingsResponder;
friend class LLSLMCreateListingsResponder;
friend class LLSLMGetListingResponder;
friend class LLSLMUpdateListingsResponder;
friend class LLSLMAssociateListingsResponder;
friend class LLSLMDeleteListingsResponder;
LLMarketplaceData();
virtual ~LLMarketplaceData();
// Public SLM API : Initialization and status
typedef boost::signals2::signal<void ()> status_updated_signal_t;
void initializeSLM(const status_updated_signal_t::slot_type& cb);
U32 getSLMStatus() const { return mMarketPlaceStatus; }
void setSLMStatus(U32 status);
void getSLMListings();
bool isEmpty() { return (mMarketplaceItems.size() == 0); }
void setDataFetchedSignal(const status_updated_signal_t::slot_type& cb);
void setSLMDataFetched(U32 status);
U32 getSLMDataFetched() { return mMarketPlaceDataFetched; }
// High level create/delete/set Marketplace data: each method returns true if the function succeeds, false if error
bool createListing(const LLUUID& folder_id);
bool activateListing(const LLUUID& folder_id, bool activate, S32 depth = -1);
bool clearListing(const LLUUID& folder_id, S32 depth = -1);
bool setVersionFolder(const LLUUID& folder_id, const LLUUID& version_id, S32 depth = -1);
bool associateListing(const LLUUID& folder_id, const LLUUID& source_folder_id, S32 listing_id);
bool updateCountOnHand(const LLUUID& folder_id, S32 depth = -1);
bool getListing(const LLUUID& folder_id, S32 depth = -1);
bool getListing(S32 listing_id);
bool deleteListing(S32 listing_id, bool update = true);
// Probe the Marketplace data set to identify folders
bool isListed(const LLUUID& folder_id); // returns true if folder_id is a Listing folder
bool isListedAndActive(const LLUUID& folder_id); // returns true if folder_id is an active (listed) Listing folder
bool isVersionFolder(const LLUUID& folder_id); // returns true if folder_id is a Version folder
bool isInActiveFolder(const LLUUID& obj_id, S32 depth = -1); // returns true if the obj_id is buried in an active version folder
LLUUID getActiveFolder(const LLUUID& obj_id, S32 depth = -1); // returns the UUID of the active version folder obj_id is in
bool isUpdating(const LLUUID& folder_id, S32 depth = -1); // returns true if we're waiting from SLM incoming data for folder_id
// Access Marketplace data set : each method returns a default value if the argument can't be found
bool getActivationState(const LLUUID& folder_id);
S32 getListingID(const LLUUID& folder_id);
LLUUID getVersionFolder(const LLUUID& folder_id);
std::string getListingURL(const LLUUID& folder_id, S32 depth = -1);
LLUUID getListingFolder(S32 listing_id);
S32 getCountOnHand(const LLUUID& folder_id);
// Used to flag if stock count values for Marketplace have to be updated
bool checkDirtyCount() { if (mDirtyCount) { mDirtyCount = false; return true; } else { return false; } }
void setDirtyCount() { mDirtyCount = true; }
void setUpdating(const LLUUID& folder_id, bool isUpdating);
// Used to decide when to run a validation on listing folders
void setValidationWaiting(const LLUUID& folder_id, S32 count);
void decrementValidationWaiting(const LLUUID& folder_id, S32 count = 1);
private:
// Modify Marketplace data set : each method returns true if the function succeeds, false if error
// Used internally only by SLM Responders when data are received from the SLM Server
bool addListing(const LLUUID& folder_id, S32 listing_id, const LLUUID& version_id, bool is_listed, const std::string& edit_url, S32 count);
bool deleteListing(const LLUUID& folder_id, bool update = true);
bool setListingID(const LLUUID& folder_id, S32 listing_id, bool update = true);
bool setVersionFolderID(const LLUUID& folder_id, const LLUUID& version_id, bool update = true);
bool setActivationState(const LLUUID& folder_id, bool activate, bool update = true);
bool setListingURL(const LLUUID& folder_id, const std::string& edit_url, bool update = true);
bool setCountOnHand(const LLUUID& folder_id, S32 count, bool update = true);
// Private SLM API : package data and get/post/put requests to the SLM Server through the SLM API
void createSLMListing(const LLUUID& folder_id, const LLUUID& version_id, S32 count);
void getSLMListing(S32 listing_id);
void updateSLMListing(const LLUUID& folder_id, S32 listing_id, const LLUUID& version_id, bool is_listed, S32 count);
void associateSLMListing(const LLUUID& folder_id, S32 listing_id, const LLUUID& version_id, const LLUUID& source_folder_id);
void deleteSLMListing(S32 listing_id);
std::string getSLMConnectURL(const std::string& route);
// Handling Marketplace connection and inventory connection
U32 mMarketPlaceStatus;
status_updated_signal_t* mStatusUpdatedSignal;
LLInventoryObserver* mInventoryObserver;
bool mDirtyCount; // If true, stock count value need to be updated at the next check
// Update data
U32 mMarketPlaceDataFetched;
status_updated_signal_t* mDataFetchedSignal;
std::set<LLUUID> mPendingUpdateSet;
// Listing folders waiting for validation
typedef std::map<LLUUID,S32> waiting_list_t;
waiting_list_t mValidationWaitingList;
// The cache of SLM data (at last...)
marketplace_items_list_t mMarketplaceItems;
// We need a list (version folder -> listing folder) because such reverse lookups are frequent
version_folders_list_t mVersionFolders;
};
#endif // LL_LLMARKETPLACEFUNCTIONS_H

View File

@ -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()

View File

@ -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()
//-----------------------------------------------------------------------------

View File

@ -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); };

View File

@ -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();

View File

@ -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.

View File

@ -97,6 +97,7 @@ void LLPanelGroupBulkImpl::callbackClickAdd(void* userdata)
if(picker)
{
root_floater->addDependentFloater(picker);
LLGroupMgr::getInstance()->sendCapGroupMembersRequest(panelp->mImplementation->mGroupID);
}
}
}

View File

@ -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.

View File

@ -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,

View File

@ -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);
LLInventoryFilter &filter = mActivePanel->getFilter();
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);
}
}

View File

@ -62,7 +62,7 @@ LLInboxInventoryPanel::LLInboxInventoryPanel(const LLInboxInventoryPanel::Params
LLInboxInventoryPanel::~LLInboxInventoryPanel()
{}
LLFolderViewFolder * LLInboxInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge)
LLFolderViewFolder * LLInboxInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge, bool allow_drop)
{
LLUIColor item_color = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
@ -74,6 +74,7 @@ LLFolderViewFolder * LLInboxInventoryPanel::createFolderViewFolder(LLInvFVBridge
params.tool_tip = params.name;
params.font_color = item_color;
params.font_highlight_color = item_color;
params.allow_drop = allow_drop;
return LLUICtrlFactory::create<LLInboxFolderViewFolder>(params);
}

View File

@ -46,7 +46,7 @@ public:
~LLInboxInventoryPanel();
// virtual
LLFolderViewFolder * createFolderViewFolder(LLInvFVBridge * bridge);
LLFolderViewFolder* createFolderViewFolder(LLInvFVBridge * bridge, bool allow_drop);
LLFolderViewItem * createFolderViewItem(LLInvFVBridge * bridge);
};

View File

@ -130,7 +130,7 @@ public:
virtual void move(LLFolderViewModelItem* parent_listener);
virtual BOOL isItemCopyable() const;
virtual BOOL copyToClipboard() const;
virtual BOOL cutToClipboard() const;
virtual BOOL cutToClipboard();
virtual BOOL isClipboardPasteable() const;
virtual void pasteFromClipboard();
virtual void pasteLinkFromClipboard();
@ -542,7 +542,7 @@ BOOL LLTaskInvFVBridge::copyToClipboard() const
return FALSE;
}
BOOL LLTaskInvFVBridge::cutToClipboard() const
BOOL LLTaskInvFVBridge::cutToClipboard()
{
return FALSE;
}
@ -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)

View File

@ -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;

View File

@ -71,6 +71,7 @@ private:
*/
S32 mSelectedParcelID;
LLUUID mLastSelectedRegionID;
F64 mNextCovenantUpdateTime; //seconds since client start
LLPanel* mForSalePanel;
LLPanel* mYouAreHerePanel;

View File

@ -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();

View File

@ -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));
}

0
indra/newview/llpanelsnapshotpostcard.cpp Executable file → Normal file
View File

View File

@ -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);

View File

@ -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

View File

@ -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();

View File

@ -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;
}

View File

@ -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)

View File

@ -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;

View File

@ -620,10 +620,33 @@ bool LLSelectMgr::linkObjects()
bool LLSelectMgr::unlinkObjects()
{
S32 min_objects_for_confirm = gSavedSettings.getS32("MinObjectsForUnlinkConfirm");
S32 unlink_object_count = mSelectedObjects->getObjectCount(); // clears out nodes with NULL objects
if (unlink_object_count >= min_objects_for_confirm
&& unlink_object_count > mSelectedObjects->getRootObjectCount())
{
// total count > root count means that there are childer inside and that there are linksets that will be unlinked
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

View File

@ -506,6 +506,8 @@ public:
bool unlinkObjects();
void confirmUnlinkObjects(const LLSD& notification, const LLSD& response);
bool enableLinkObjects();
bool enableUnlinkObjects();

View File

@ -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());
@ -1880,6 +1881,11 @@ bool idle_startup()
}
display_startup();
// *TODO : Uncomment that line once the whole grid migrated to SLM and suppress it from LLAgent::handleTeleportFinished() (llagent.cpp)
//check_merchant_status();
display_startup();
if (gSavedSettings.getBOOL("HelpFloaterOpen"))
{
@ -3504,15 +3510,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;
}

View File

@ -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 )

View File

@ -67,19 +67,19 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
mLabel(notification->getName()),
mLineEditor(NULL)
{
// EXP-1822
// save currently focused view, so that return focus to it
// on destroying this toast.
LLView* current_selection = dynamic_cast<LLView*>(gFocusMgr.getKeyboardFocus());
while(current_selection)
{
if (current_selection->isFocusRoot())
{
mPreviouslyFocusedView = current_selection->getHandle();
break;
}
current_selection = current_selection->getParent();
}
// EXP-1822
// save currently focused view, so that return focus to it
// on destroying this toast.
LLView* current_selection = dynamic_cast<LLView*>(gFocusMgr.getKeyboardFocus());
while(current_selection)
{
if (current_selection->isFocusRoot())
{
mPreviouslyFocusedView = current_selection->getHandle();
break;
}
current_selection = current_selection->getParent();
}
const LLFontGL* font = LLFontGL::getFontSansSerif();
const S32 LINE_HEIGHT = font->getLineHeight();
@ -431,7 +431,24 @@ LLToastAlertPanel::~LLToastAlertPanel()
// return focus to the previously focused view if the viewer is not exiting
if (mPreviouslyFocusedView.get() && !LLApp::isExiting())
{
mPreviouslyFocusedView.get()->setFocus(TRUE);
LLView* current_selection = dynamic_cast<LLView*>(gFocusMgr.getKeyboardFocus());
while(current_selection)
{
if (current_selection->isFocusRoot())
{
break;
}
current_selection = current_selection->getParent();
}
if (current_selection)
{
// If the focus moved to some other view though, move the focus there
current_selection->setFocus(TRUE);
}
else
{
mPreviouslyFocusedView.get()->setFocus(TRUE);
}
}
}

Some files were not shown because too many files have changed in this diff Show More