Merge LL V3.7.23

Ansariel 2015-01-15 15:44:43 +01:00
commit e52d57cba2
74 changed files with 1430 additions and 610 deletions

View File

@ -525,3 +525,4 @@ bcc2770e21c125e0bab59141c51db9145aec068d 3.7.17-release
27094824773b907c2e559396e6f9ec3a963de52d 3.7.20-release
9ecab4b0c7d8614767724a3422d3c1dca6bd4e4f 3.7.21-release
bc61801f614022c920cb5c3df1d7d67a9561ce1f 3.7.22-release
3be800e1afad9615442159e388d6d137be7b951e 3.7.23-release

View File

@ -1742,9 +1742,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>54e46715e72b7805d9d3f84d45b6b1b7</string>
<string>0e15751836ac0492250001b80aea379f</string>
<key>url</key>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/llappearanceutility-source/rev/290120/arch/Linux/installer/llappearanceutility_source-0.1-linux-20140519.tar.bz2</string>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/llappearanceutility-source/rev/293888/arch/Linux/installer/llappearanceutility_source-0.1-linux-20140908.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>

View File

@ -1058,10 +1058,11 @@ Peekay Semyorka
VWR-49
VWR-79
Pell Smit
STORM-2069
STORM-2070
STORM-2071
STORM-2072
MAINT-4323
STORM-2069
STORM-2070
STORM-2071
STORM-2072
Peter Lameth
VWR-7331
PeterPunk Mooney

View File

@ -603,8 +603,6 @@ BOOL LLAvatarAppearance::setupBone(const LLAvatarBoneInfo* info, LLJoint* parent
info->mRot.mV[VZ], LLQuaternion::XYZ));
joint->setScale(info->mScale);
joint->setDefaultFromCurrentXform();
if (info->mIsJoint)
{
joint->setSkinOffset( info->mPivot );
@ -696,6 +694,42 @@ void LLAvatarAppearance::clearSkeleton()
mSkeleton.clear();
}
//------------------------------------------------------------------------
// addPelvisFixup
//------------------------------------------------------------------------
void LLAvatarAppearance::addPelvisFixup( F32 fixup, const LLUUID& mesh_id )
{
LLVector3 pos(0.0,0.0,fixup);
mPelvisFixups.add(mesh_id,pos);
}
//------------------------------------------------------------------------
// addPelvisFixup
//------------------------------------------------------------------------
void LLAvatarAppearance::removePelvisFixup( const LLUUID& mesh_id )
{
mPelvisFixups.remove(mesh_id);
}
//------------------------------------------------------------------------
// hasPelvisFixup
//------------------------------------------------------------------------
bool LLAvatarAppearance::hasPelvisFixup( F32& fixup, LLUUID& mesh_id ) const
{
LLVector3 pos;
if (mPelvisFixups.findActiveOverride(mesh_id,pos))
{
fixup = pos[2];
return true;
}
return false;
}
bool LLAvatarAppearance::hasPelvisFixup( F32& fixup ) const
{
LLUUID mesh_id;
return hasPelvisFixup( fixup, mesh_id );
}
//-----------------------------------------------------------------------------
// LLAvatarAppearance::buildCharacter()
// Deferred initialization and rebuild of the avatar.

View File

@ -159,11 +159,17 @@ protected:
BOOL mIsBuilt; // state of deferred character building
typedef std::vector<LLAvatarJoint*> avatar_joint_list_t;
avatar_joint_list_t mSkeleton;
LLPosOverrideMap mPelvisFixups;
//--------------------------------------------------------------------
// Pelvis height adjustment members.
//--------------------------------------------------------------------
public:
void addPelvisFixup( F32 fixup, const LLUUID& mesh_id );
void removePelvisFixup( const LLUUID& mesh_id );
bool hasPelvisFixup( F32& fixup, LLUUID& mesh_id ) const;
bool hasPelvisFixup( F32& fixup ) const;
LLVector3 mBodySize;
LLVector3 mAvatarOffset;
protected:

View File

@ -213,7 +213,7 @@ void LLPolySkeletalDistortion::apply( ESex avatar_sex )
LLVector3 scaleDelta = iter->second;
newScale = newScale + (effective_weight * scaleDelta) - (mLastWeight * scaleDelta);
//An aspect of attached mesh objects (which contain joint offsets) that need to be cleaned up when detached
joint->storeScaleForReset( newScale );
// needed? // joint->storeScaleForReset( newScale );
joint->setScale(newScale);
}

View File

@ -36,6 +36,64 @@
S32 LLJoint::sNumUpdates = 0;
S32 LLJoint::sNumTouches = 0;
template <class T>
bool attachment_map_iter_compare_key(const T& a, const T& b)
{
return a.first < b.first;
}
bool LLPosOverrideMap::findActiveOverride(LLUUID& mesh_id, LLVector3& pos) const
{
pos = LLVector3(0,0,0);
mesh_id = LLUUID();
bool found = false;
map_type::const_iterator it = std::max_element(m_map.begin(),
m_map.end(),
attachment_map_iter_compare_key<map_type::value_type>);
if (it != m_map.end())
{
found = true;
pos = it->second;
mesh_id = it->first;
}
return found;
}
void LLPosOverrideMap::showJointPosOverrides( std::ostringstream& os ) const
{
map_type::const_iterator max_it = std::max_element(m_map.begin(),
m_map.end(),
attachment_map_iter_compare_key<map_type::value_type>);
for (map_type::const_iterator it = m_map.begin();
it != m_map.end(); ++it)
{
const LLVector3& pos = it->second;
os << " " << "[" << it->first <<": " << pos << "]" << ((it==max_it) ? "*" : "");
}
}
U32 LLPosOverrideMap::count() const
{
return m_map.size();
}
void LLPosOverrideMap::add(const LLUUID& mesh_id, const LLVector3& pos)
{
m_map[mesh_id] = pos;
}
bool LLPosOverrideMap::remove(const LLUUID& mesh_id)
{
U32 remove_count = m_map.erase(mesh_id);
return (remove_count > 0);
}
void LLPosOverrideMap::clear()
{
m_map.clear();
}
//-----------------------------------------------------------------------------
// LLJoint()
// Class Constructor
@ -48,11 +106,8 @@ void LLJoint::init()
mParent = NULL;
mXform.setScaleChildOffset(TRUE);
mXform.setScale(LLVector3(1.0f, 1.0f, 1.0f));
mOldXform.setScaleChildOffset(TRUE);
mOldXform.setScale(LLVector3(1.0f, 1.0f, 1.0f));
mDirtyFlags = MATRIX_DIRTY | ROTATION_DIRTY | POSITION_DIRTY;
mUpdateXform = TRUE;
mResetAfterRestoreOldXform = false;
}
LLJoint::LLJoint() :
@ -233,52 +288,123 @@ const LLVector3& LLJoint::getPosition()
return mXform.getPosition();
}
bool do_debug_joint(const std::string& name)
{
return true;
}
//--------------------------------------------------------------------
// setPosition()
//--------------------------------------------------------------------
void LLJoint::setPosition( const LLVector3& pos )
{
if (pos != getPosition())
{
if (do_debug_joint(getName()))
{
LL_DEBUGS("Avatar") << " joint " << getName() << " set pos " << pos << LL_ENDL;
}
}
mXform.setPosition(pos);
touch(MATRIX_DIRTY | POSITION_DIRTY);
}
//--------------------------------------------------------------------
// setPosition()
//--------------------------------------------------------------------
void LLJoint::setDefaultFromCurrentXform( void )
{
mDefaultXform = mXform;
}
//--------------------------------------------------------------------
// storeCurrentXform()
//--------------------------------------------------------------------
void LLJoint::storeCurrentXform( const LLVector3& pos )
{
mOldXform = mXform;
mResetAfterRestoreOldXform = true;
setPosition( pos );
touch(ALL_DIRTY);
}
//--------------------------------------------------------------------
// storeScaleForReset()
//--------------------------------------------------------------------
void LLJoint::storeScaleForReset( const LLVector3& scale )
void showJointPosOverrides( const LLJoint& joint, const std::string& note, const std::string& av_info )
{
mOldXform.setScale( scale );
std::ostringstream os;
os << joint.m_posBeforeOverrides;
joint.m_attachmentOverrides.showJointPosOverrides(os);
LL_DEBUGS("Avatar") << av_info << " joint " << joint.getName() << " " << note << " " << os.str() << LL_ENDL;
}
//--------------------------------------------------------------------
// restoreOldXform()
// addAttachmentPosOverride()
//--------------------------------------------------------------------
void LLJoint::restoreOldXform( void )
{
mXform = mDefaultXform;
mResetAfterRestoreOldXform = false;
mDirtyFlags = ALL_DIRTY;
void LLJoint::addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh_id, const std::string& av_info )
{
if (mesh_id.isNull())
{
return;
}
if (!m_attachmentOverrides.count())
{
if (do_debug_joint(getName()))
{
LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " saving m_posBeforeOverrides " << getPosition() << LL_ENDL;
}
m_posBeforeOverrides = getPosition();
}
m_attachmentOverrides.add(mesh_id,pos);
if (do_debug_joint(getName()))
{
LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " addAttachmentPosOverride for mesh " << mesh_id << " pos " << pos << LL_ENDL;
}
updatePos(av_info);
}
//--------------------------------------------------------------------
// removeAttachmentPosOverride()
//--------------------------------------------------------------------
void LLJoint::removeAttachmentPosOverride( const LLUUID& mesh_id, const std::string& av_info )
{
if (mesh_id.isNull())
{
return;
}
if (m_attachmentOverrides.remove(mesh_id))
{
if (do_debug_joint(getName()))
{
LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName()
<< " removeAttachmentPosOverride for " << mesh_id << LL_ENDL;
showJointPosOverrides(*this, "remove", av_info);
}
updatePos(av_info);
}
}
//--------------------------------------------------------------------
// hasAttachmentPosOverride()
//--------------------------------------------------------------------
bool LLJoint::hasAttachmentPosOverride( LLVector3& pos, LLUUID& mesh_id ) const
{
return m_attachmentOverrides.findActiveOverride(mesh_id,pos);
}
//--------------------------------------------------------------------
// clearAttachmentPosOverrides()
//--------------------------------------------------------------------
void LLJoint::clearAttachmentPosOverrides()
{
if (m_attachmentOverrides.count())
{
m_attachmentOverrides.clear();
setPosition(m_posBeforeOverrides);
setId( LLUUID::null );
}
}
//--------------------------------------------------------------------
// updatePos()
//--------------------------------------------------------------------
void LLJoint::updatePos(const std::string& av_info)
{
LLVector3 pos, found_pos;
LLUUID mesh_id;
if (m_attachmentOverrides.findActiveOverride(mesh_id,found_pos))
{
LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updatePos, winner of " << m_attachmentOverrides.count() << " is mesh " << mesh_id << " pos " << found_pos << LL_ENDL;
pos = found_pos;
}
else
{
LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updatePos, winner is posBeforeOverrides " << m_posBeforeOverrides << LL_ENDL;
pos = m_posBeforeOverrides;
}
setPosition(pos);
}
//--------------------------------------------------------------------
// getWorldPosition()
//--------------------------------------------------------------------
@ -325,7 +451,7 @@ void LLJoint::setWorldPosition( const LLVector3& pos )
//--------------------------------------------------------------------
// mXform.getRotation()
// getRotation()
//--------------------------------------------------------------------
const LLQuaternion& LLJoint::getRotation()
{
@ -432,7 +558,7 @@ const LLMatrix4 &LLJoint::getWorldMatrix()
//--------------------------------------------------------------------
void LLJoint::setWorldMatrix( const LLMatrix4& mat )
{
LL_INFOS() << "WARNING: LLJoint::setWorldMatrix() not correctly implemented yet" << LL_ENDL;
LL_INFOS() << "WARNING: LLJoint::setWorldMatrix() not correctly implemented yet" << LL_ENDL;
// extract global translation
LLVector3 trans( mat.mMatrix[VW][VX],
mat.mMatrix[VW][VY],
@ -548,20 +674,6 @@ void LLJoint::clampRotation(LLQuaternion old_rot, LLQuaternion new_rot)
break;
}
}
// 2003.03.26 - This code was just using up cpu cycles. AB
// LLVector3 old_axis = main_axis * old_rot;
// LLVector3 new_axis = main_axis * new_rot;
// for (S32 i = 0; i < mConstraintSilhouette.size() - 1; i++)
// {
// LLVector3 vert1 = mConstraintSilhouette[i];
// LLVector3 vert2 = mConstraintSilhouette[i + 1];
// figure out how to clamp rotation to line on 3-sphere
// }
}
// End

View File

@ -46,6 +46,21 @@ const U32 LL_FACE_JOINT_NUM = 30;
const S32 LL_CHARACTER_MAX_PRIORITY = 7;
const F32 LL_MAX_PELVIS_OFFSET = 5.f;
class LLPosOverrideMap
{
public:
LLPosOverrideMap() {}
bool findActiveOverride(LLUUID& mesh_id, LLVector3& pos) const;
void showJointPosOverrides(std::ostringstream& os) const;
U32 count() const;
void add(const LLUUID& mesh_id, const LLVector3& pos);
bool remove(const LLUUID& mesh_id);
void clear();
private:
typedef std::map<LLUUID,LLVector3> map_type;
map_type m_map;
};
//-----------------------------------------------------------------------------
// class LLJoint
//-----------------------------------------------------------------------------
@ -79,8 +94,6 @@ protected:
// explicit transformation members
LLXformMatrix mXform;
LLXformMatrix mOldXform;
LLXformMatrix mDefaultXform;
LLUUID mId;
@ -88,8 +101,6 @@ public:
U32 mDirtyFlags;
BOOL mUpdateXform;
BOOL mResetAfterRestoreOldXform;
// describes the skin binding pose
LLVector3 mSkinOffset;
@ -103,6 +114,11 @@ public:
static S32 sNumTouches;
static S32 sNumUpdates;
LLPosOverrideMap m_attachmentOverrides;
LLVector3 m_posBeforeOverrides;
void updatePos(const std::string& av_info);
public:
LLJoint();
LLJoint(S32 joint_num);
@ -160,7 +176,7 @@ public:
// get/set local scale
const LLVector3& getScale();
void setScale( const LLVector3& scale );
void storeScaleForReset( const LLVector3& scale );
// get/set world matrix
const LLMatrix4 &getWorldMatrix();
void setWorldMatrix( const LLMatrix4& mat );
@ -183,20 +199,16 @@ public:
virtual BOOL isAnimatable() const { return TRUE; }
S32 getJointNum() const { return mJointNum; }
void restoreOldXform( void );
void setDefaultFromCurrentXform( void );
void storeCurrentXform( const LLVector3& pos );
void addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh_id, const std::string& av_info );
void removeAttachmentPosOverride( const LLUUID& mesh_id, const std::string& av_info );
bool hasAttachmentPosOverride( LLVector3& pos, LLUUID& mesh_id ) const;
void clearAttachmentPosOverrides();
//Accessor for the joint id
LLUUID getId( void ) { return mId; }
//Setter for the joints id
void setId( const LLUUID& id ) { mId = id;}
//If the old transform flag has been set, then the reset logic in avatar needs to be aware(test) of it
const BOOL doesJointNeedToBeReset( void ) const { return mResetAfterRestoreOldXform; }
void setJointResetFlag( bool val ) { mResetAfterRestoreOldXform = val; }
};
#endif // LL_LLJOINT_H

View File

@ -71,6 +71,9 @@ public:
void quantize8(F32 lower, F32 upper); // changes the vector to reflect quatization
void loadIdentity(); // Loads the quaternion that represents the identity rotation
bool isEqualEps(const LLQuaternion &quat, F32 epsilon) const;
bool isNotEqualEps(const LLQuaternion &quat, F32 epsilon) const;
const LLQuaternion& set(F32 x, F32 y, F32 z, F32 w); // Sets Quaternion to normalize(x, y, z, w)
const LLQuaternion& set(const LLQuaternion &quat); // Copies Quaternion
const LLQuaternion& set(const F32 *q); // Sets Quaternion to normalize(quat[VX], quat[VY], quat[VZ], quat[VW])
@ -239,6 +242,21 @@ inline void LLQuaternion::loadIdentity()
mQ[VW] = 1.0f;
}
inline bool LLQuaternion::isEqualEps(const LLQuaternion &quat, F32 epsilon) const
{
return ( fabs(mQ[VX] - quat.mQ[VX]) < epsilon
&& fabs(mQ[VY] - quat.mQ[VY]) < epsilon
&& fabs(mQ[VZ] - quat.mQ[VZ]) < epsilon
&& fabs(mQ[VS] - quat.mQ[VS]) < epsilon );
}
inline bool LLQuaternion::isNotEqualEps(const LLQuaternion &quat, F32 epsilon) const
{
return ( fabs(mQ[VX] - quat.mQ[VX]) > epsilon
|| fabs(mQ[VY] - quat.mQ[VY]) > epsilon
|| fabs(mQ[VZ] - quat.mQ[VZ]) > epsilon
|| fabs(mQ[VS] - quat.mQ[VS]) > epsilon );
}
inline const LLQuaternion& LLQuaternion::set(F32 x, F32 y, F32 z, F32 w)
{

View File

@ -180,18 +180,18 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa
domListOfUInts& idx = p->getValue();
domListOfFloats dummy ;
domListOfFloats& v = pos_source ? pos_source->getFloat_array()->getValue() : dummy ;
domListOfFloats& tc = tc_source ? tc_source->getFloat_array()->getValue() : dummy ;
domListOfFloats& n = norm_source ? norm_source->getFloat_array()->getValue() : dummy ;
domListOfFloats& v = (pos_source && pos_source->getFloat_array()) ? pos_source->getFloat_array()->getValue() : dummy ;
domListOfFloats& tc = (tc_source && tc_source->getFloat_array()) ? tc_source->getFloat_array()->getValue() : dummy ;
domListOfFloats& n = (norm_source && norm_source->getFloat_array()) ? norm_source->getFloat_array()->getValue() : dummy ;
LLVolumeFace::VertexMapData::PointMap point_map;
U32 index_count = idx.getCount();
U32 vertex_count = pos_source ? v.getCount() : 0;
U32 tc_count = tc_source ? tc.getCount() : 0;
U32 norm_count = norm_source ? n.getCount() : 0;
U32 vertex_count = (pos_source && pos_source->getFloat_array()) ? v.getCount() : 0;
U32 tc_count = (tc_source && tc_source->getFloat_array()) ? tc.getCount() : 0;
U32 norm_count = (norm_source && norm_source->getFloat_array()) ? n.getCount(): 0;
if ((vertex_count == 0) || (tc_count == 0))
if ((vertex_count == 0))
{
LL_WARNS() << "Unable to process mesh with empty position array; invalid model." << LL_ENDL;
return LLModel::BAD_ELEMENT;
@ -229,7 +229,7 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa
{
// guard against model data specifiying out of range indices or tcs
//
if (((i + tc_offset) > index_count)
|| ((idx[i+tc_offset]*2+1) > tc_count))
{

View File

@ -1168,7 +1168,7 @@ void LLRender::syncMatrices()
{
stop_glerror();
U32 name[] =
static const U32 name[] =
{
LLShaderMgr::MODELVIEW_MATRIX,
LLShaderMgr::PROJECTION_MATRIX,

View File

@ -277,20 +277,19 @@ BOOL LLFolderViewItem::passedFilter(S32 filter_generation)
BOOL LLFolderViewItem::isPotentiallyVisible(S32 filter_generation)
{
// Item should be visible if:
// 1. item passed current filter
// 2. item was updated (gen < 0) but has descendants that passed filter
// 3. item was recently updated and was visible before update
if (filter_generation < 0)
{
filter_generation = getFolderViewModel()->getFilter().getFirstSuccessGeneration();
}
LLFolderViewModelItem* model = getViewModelItem();
if (model->getLastFilterGeneration() < 0 && !getFolderViewModel()->getFilter().isModified())
BOOL visible = model->passedFilter(filter_generation);
if (model->getMarkedDirtyGeneration() >= filter_generation)
{
return model->descendantsPassedFilter(filter_generation) || getVisible();
}
else
{
return model->passedFilter(filter_generation);
// unsure visibility state
// retaining previous visibility until item is updated or filter generation changes
visible |= getVisible();
}
return visible;
}
void LLFolderViewItem::refresh()

View File

@ -203,11 +203,13 @@ public:
virtual void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0) = 0;
virtual void setPassedFolderFilter(bool passed, S32 filter_generation) = 0;
virtual void dirtyFilter() = 0;
virtual void dirtyDescendantsFilter() = 0;
virtual bool hasFilterStringMatch() = 0;
virtual std::string::size_type getFilterStringOffset() = 0;
virtual std::string::size_type getFilterStringSize() = 0;
virtual S32 getLastFilterGeneration() const = 0;
virtual S32 getMarkedDirtyGeneration() const = 0;
virtual bool hasChildren() const = 0;
virtual void addChild(LLFolderViewModelItem* child) = 0;
@ -251,6 +253,7 @@ public:
mFolderViewItem(NULL),
mLastFilterGeneration(-1),
mLastFolderFilterGeneration(-1),
mMarkedDirtyGeneration(-1),
mMostFilteredDescendantGeneration(-1),
mParent(NULL),
mRootViewModel(root_view_model)
@ -264,8 +267,13 @@ public:
S32 getLastFilterGeneration() const { return mLastFilterGeneration; }
S32 getLastFolderFilterGeneration() const { return mLastFolderFilterGeneration; }
S32 getMarkedDirtyGeneration() const { return mMarkedDirtyGeneration; }
void dirtyFilter()
{
if(mMarkedDirtyGeneration < 0)
{
mMarkedDirtyGeneration = mLastFilterGeneration;
}
mLastFilterGeneration = -1;
mLastFolderFilterGeneration = -1;
@ -275,6 +283,14 @@ public:
mParent->dirtyFilter();
}
}
void dirtyDescendantsFilter()
{
mMostFilteredDescendantGeneration = -1;
if (mParent)
{
mParent->dirtyDescendantsFilter();
}
}
bool hasFilterStringMatch();
std::string::size_type getFilterStringOffset();
std::string::size_type getFilterStringSize();
@ -293,7 +309,7 @@ public:
return;
}
}
mChildren.push_back(child);
mChildren.push_back(child);
child->setParent(this);
dirtyFilter();
requestSort();
@ -301,7 +317,8 @@ public:
virtual void removeChild(LLFolderViewModelItem* child)
{
mChildren.remove(child);
child->setParent(NULL);
child->setParent(NULL);
dirtyDescendantsFilter();
dirtyFilter();
}
@ -311,6 +328,7 @@ public:
// This is different and not equivalent to calling removeChild() on each child
std::for_each(mChildren.begin(), mChildren.end(), DeletePointer());
mChildren.clear();
dirtyDescendantsFilter();
dirtyFilter();
}
@ -324,6 +342,7 @@ public:
mLastFilterGeneration = filter_generation;
mStringMatchOffsetFilter = string_offset;
mStringFilterSize = string_size;
mMarkedDirtyGeneration = -1;
}
void setPassedFolderFilter(bool passed, S32 filter_generation)
@ -372,7 +391,8 @@ protected:
S32 mLastFilterGeneration,
mLastFolderFilterGeneration,
mMostFilteredDescendantGeneration;
mMostFilteredDescendantGeneration,
mMarkedDirtyGeneration;
child_list_t mChildren;
LLFolderViewModelItem* mParent;

View File

@ -528,11 +528,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
}
// Skip white space
// <FS:ND> use iswspace in case *cur > 0xFF
// while( *cur && isspace(*cur) && (*cur != '\n') )
while( *cur && iswspace(*cur) && (*cur != '\n') )
// </FS:ND>
{
cur++;
}
@ -575,11 +571,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
}
// Skip white space
// <FS:ND> use iswspace in case *cur > 0xFF
// while( *cur && isspace(*cur) && (*cur != '\n') )
while( *cur && iswspace(*cur) && (*cur != '\n') )
// </FS:ND>
{
cur++;
}
@ -687,9 +679,11 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
// check against words
llwchar prev = cur > base ? *(cur-1) : 0;
// NaCl - LSL Preprocessor
//if( !iswalnum( prev ) && (prev != '_') )
if( !iswalnum( prev ) && (prev != '_') && (prev != '#'))
{
const llwchar* p = cur;
//while( iswalnum( *p ) || (*p == '_') )
while( *p && ( iswalnum( *p ) || (*p == '_') || (*p == '#') ) )
// NaCl End
{

View File

@ -1281,7 +1281,15 @@ void LLMenuItemBranchGL::openMenu()
{
// open upwards if menu extends past bottom
// adjust by the height of the menu item branch since it is a submenu
delta_y = branch_rect.getHeight() - getRect().getHeight();
if (y + 2 * branch_rect.getHeight() - getRect().getHeight() > menu_region_rect.mTop)
{
// overlaps with top border, align with top
delta_y = menu_region_rect.mTop - y - branch_rect.getHeight();
}
else
{
delta_y = branch_rect.getHeight() - getRect().getHeight();
}
}
if( x + branch_rect.getWidth() > menu_region_rect.mRight )
@ -3271,6 +3279,11 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
CURSOR_WIDTH + MOUSE_CURSOR_PADDING * 2,
CURSOR_HEIGHT + MOUSE_CURSOR_PADDING * 2);
menu->translateIntoRectWithExclusion( menu_region_rect, mouse_rect );
if (menu->getRect().mTop > menu_region_rect.mTop)
{
// not enough space: align with top, ignore exclusion
menu->translateIntoRect( menu_region_rect );
}
menu->getParent()->sendChildToFront(menu);
}

View File

@ -178,6 +178,12 @@ bool LLUrlEntryBase::isLinkDisabled() const
return globally_disabled;
}
bool LLUrlEntryBase::isWikiLinkCorrect(std::string url)
{
std::string label = getLabelFromWikiLink(url);
return (LLUrlRegistry::instance().hasUrl(label)) ? false : true;
}
static std::string getStringAfterToken(const std::string str, const std::string token)
{
size_t pos = str.find(token);

View File

@ -100,6 +100,8 @@ public:
bool isLinkDisabled() const;
bool isWikiLinkCorrect(std::string url);
protected:
std::string getIDStringFromUrl(const std::string &url) const;
std::string escapeUrl(const std::string &url) const;

View File

@ -49,7 +49,8 @@ LLUrlRegistry::LLUrlRegistry()
registerUrl(mUrlEntryIcon);
registerUrl(new LLUrlEntrySLURL());
registerUrl(new LLUrlEntryHTTP());
registerUrl(new LLUrlEntryHTTPLabel());
mUrlEntryHTTPLabel = new LLUrlEntryHTTPLabel();
registerUrl(mUrlEntryHTTPLabel);
registerUrl(new LLUrlEntryAgentCompleteName());
registerUrl(new LLUrlEntryAgentDisplayName());
registerUrl(new LLUrlEntryAgentUserName());
@ -70,7 +71,8 @@ LLUrlRegistry::LLUrlRegistry()
//LLUrlEntrySL and LLUrlEntrySLLabel have more common pattern,
//so it should be registered in the end of list
registerUrl(new LLUrlEntrySL());
registerUrl(new LLUrlEntrySLLabel());
mUrlEntrySLLabel = new LLUrlEntrySLLabel();
registerUrl(mUrlEntrySLLabel);
// most common pattern is a URL without any protocol,
// e.g., "secondlife.com"
registerUrl(new LLUrlEntryHTTPNoProtocol());
@ -136,6 +138,11 @@ static bool matchRegex(const char *text, boost::regex regex, U32 &start, U32 &en
end--;
}
else if (text[end] == ']' && std::string(text+start, end-start).find('[') == std::string::npos)
{
end--;
}
return true;
}
@ -227,6 +234,15 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL
// does this match occur in the string before any other match
if (start < match_start || match_entry == NULL)
{
if((mUrlEntryHTTPLabel == *it) || (mUrlEntrySLLabel == *it))
{
if(url_entry && !url_entry->isWikiLinkCorrect(text.substr(start, end - start + 1)))
{
continue;
}
}
match_start = start;
match_end = end;
match_entry = url_entry;

View File

@ -94,6 +94,8 @@ private:
std::vector<LLUrlEntryBase *> mUrlEntry;
LLUrlEntryBase* mUrlEntryIcon;
LLUrlEntryBase* mUrlEntryHTTPLabel;
LLUrlEntryBase* mUrlEntrySLLabel;
};
#endif

View File

@ -946,7 +946,7 @@ BOOL LLView::handleKey(KEY key, MASK mask, BOOL called_from_parent)
handled = handleKeyHere( key, mask );
if (handled)
{
LL_WARNS() << "Key handled by " << getName() << LL_ENDL;
LL_DEBUGS() << "Key handled by " << getName() << LL_ENDL;
}
}
}

View File

@ -124,6 +124,14 @@ attributedStringInfo getSegments(NSAttributedString *str)
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(windowResized:) name:NSWindowDidResizeNotification
object:[self window]];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(windowWillMiniaturize:) name:NSWindowWillMiniaturizeNotification
object:[self window]];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(windowDidDeminiaturize:) name:NSWindowDidDeminiaturizeNotification
object:[self window]];
}
@ -141,6 +149,16 @@ attributedStringInfo getSegments(NSAttributedString *str)
}
}
- (void)windowWillMiniaturize:(NSNotification *)notification;
{
callWindowHide();
}
- (void)windowDidDeminiaturize:(NSNotification *)notification;
{
callWindowUnhide();
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
@ -326,13 +344,6 @@ attributedStringInfo getSegments(NSAttributedString *str)
callRightMouseUp(mMousePos, [theEvent modifierFlags]);
}
// <FS:LO> Fix FIRE-14282/BUG-6875 with the solution provided in LL's jira.
- (void) rightMouseDragged:(NSEvent *)theEvent
{
[self mouseDragged:theEvent];
}
// </FS:LO>
- (void)mouseMoved:(NSEvent *)theEvent
{
float mouseDeltas[2] = {
@ -379,9 +390,14 @@ attributedStringInfo getSegments(NSAttributedString *str)
callMiddleMouseUp(mMousePos, [theEvent modifierFlags]);
}
- (void) rightMouseDragged:(NSEvent *)theEvent
{
[self mouseDragged:theEvent];
}
- (void) otherMouseDragged:(NSEvent *)theEvent
{
[self mouseDragged:theEvent]; // <FS:LO> Fix FIRE-14282/BUG-6875 with the solution provided in LL's jira.
[self mouseDragged:theEvent];
}
- (void) scrollWheel:(NSEvent *)theEvent

View File

@ -117,6 +117,8 @@ void callScrollMoved(float delta);
void callMouseExit();
void callWindowFocus();
void callWindowUnfocus();
void callWindowHide();
void callWindowUnhide();
void callDeltaUpdate(float *delta, unsigned int mask);
void callMiddleMouseDown(float *pos, unsigned int mask);
void callMiddleMouseUp(float *pos, unsigned int mask);

View File

@ -361,6 +361,22 @@ void callWindowUnfocus()
gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation);
}
void callWindowHide()
{
if ( gWindowImplementation && gWindowImplementation->getCallbacks() )
{
gWindowImplementation->getCallbacks()->handleActivate(gWindowImplementation, false);
}
}
void callWindowUnhide()
{
if ( gWindowImplementation && gWindowImplementation->getCallbacks() )
{
gWindowImplementation->getCallbacks()->handleActivate(gWindowImplementation, true);
}
}
void callDeltaUpdate(float *delta, MASK mask)
{
gWindowImplementation->updateMouseDeltas(delta);

View File

@ -8486,7 +8486,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>30.0</real>
<real>600.0</real>
</map>
<key>MemoryPrivatePoolEnabled</key>
<map>

View File

@ -111,10 +111,9 @@ void main()
#ifdef USE_INDEXED_TEX
passTextureIndex();
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
#else
vary_texcoord0 = texcoord0;
#endif
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
vary_norm = norm;
vary_position = pos.xyz;

View File

@ -4779,8 +4779,8 @@ void LLAgent::stopCurrentAnimations(bool force_keep_script_perms /*= false*/)
anim_it != gAgentAvatarp->mPlayingAnimations.end();
anim_it++)
{
if (anim_it->first ==
ANIM_AGENT_SIT_GROUND_CONSTRAINED)
if ((anim_it->first == ANIM_AGENT_DO_NOT_DISTURB)||
(anim_it->first == ANIM_AGENT_SIT_GROUND_CONSTRAINED))
{
// don't cancel a ground-sit anim, as viewers
// use this animation's status in

View File

@ -1048,6 +1048,10 @@ 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.
// 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())
{
@ -1058,6 +1062,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
mismatched++;
continue;
}
#endif
// If we got here, everything matches.
matched++;
}
@ -1122,7 +1127,6 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
if (isAgentAvatarValid())
{
gAgentAvatarp->setCompositeUpdatesEnabled(TRUE);
gAgentAvatarp->updateVisualParams();
// If we have not yet declouded, we may want to use
// baked texture UUIDs sent from the first objectUpdate message
@ -1147,6 +1151,12 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
// [/SL:KB]
notifyLoadingFinished();
// Copy wearable params to avatar.
gAgentAvatarp->writeWearablesToAvatar();
// Then update the avatar based on the copied params.
gAgentAvatarp->updateVisualParams();
gAgentAvatarp->dumpAvatarTEs("setWearableOutfit");
LL_DEBUGS("Avatar") << "setWearableOutfit() end" << LL_ENDL;
@ -1289,9 +1299,12 @@ void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLViewerWeara
// }
//}
// Combines userRemoveMulipleAttachments() and userAttachMultipleAttachments() logic to
// get attachments into desired state with minimal number of adds/removes.
void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array)
// Given a desired set of attachments, find what objects need to be
// removed, and what additional inventory items need to be added.
void LLAgentWearables::findAttachmentsAddRemoveInfo(LLInventoryModel::item_array_t& obj_item_array,
llvo_vec_t& objects_to_remove,
llvo_vec_t& objects_to_retain,
LLInventoryModel::item_array_t& items_to_add)
{
// Possible cases:
// already wearing but not in request set -> take off.
@ -1310,7 +1323,6 @@ void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj
}
// Build up list of objects to be removed and items currently attached.
llvo_vec_t objects_to_remove;
for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
iter != gAgentAvatarp->mAttachmentPoints.end();)
{
@ -1345,12 +1357,12 @@ void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj
{
// LL_INFOS() << "found object to keep, id " << objectp->getID() << ", item " << objectp->getAttachmentItemID() << LL_ENDL;
current_item_ids.insert(object_item_id);
objects_to_retain.push_back(objectp);
}
}
}
}
LLInventoryModel::item_array_t items_to_add;
for (LLInventoryModel::item_array_t::iterator it = obj_item_array.begin();
it != obj_item_array.end();
++it)
@ -1369,12 +1381,6 @@ void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj
// S32 remove_count = objects_to_remove.size();
// S32 add_count = items_to_add.size();
// LL_INFOS() << "remove " << remove_count << " add " << add_count << LL_ENDL;
// Remove everything in objects_to_remove
userRemoveMultipleAttachments(objects_to_remove);
// Add everything in items_to_add
userAttachMultipleAttachments(items_to_add);
}
void LLAgentWearables::userRemoveMultipleAttachments(llvo_vec_t& objects_to_remove)
@ -1422,6 +1428,7 @@ void LLAgentWearables::userRemoveMultipleAttachments(llvo_vec_t& objects_to_remo
++it)
{
LLViewerObject *objectp = *it;
//gAgentAvatarp->resetJointPositionsOnDetach(objectp);
gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, objectp->getLocalID());
}

View File

@ -188,7 +188,10 @@ public:
typedef std::vector<LLViewerObject*> llvo_vec_t;
static void userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array);
static void findAttachmentsAddRemoveInfo(LLInventoryModel::item_array_t& obj_item_array,
llvo_vec_t& objects_to_remove,
llvo_vec_t& objects_to_retain,
LLInventoryModel::item_array_t& items_to_add);
static void userRemoveMultipleAttachments(llvo_vec_t& llvo_array);
static void userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array);

View File

@ -34,6 +34,7 @@
#include "llsdutil.h"
#include "llviewerregion.h"
#include "llinventoryobserver.h"
#include "llviewercontrol.h"
///----------------------------------------------------------------------------
/// Classes for AISv3 support.

12
indra/newview/llappdelegate-objc.mm Normal file → Executable file
View File

@ -99,7 +99,17 @@
callWindowUnfocus();
}
- (NSApplicationTerminateReply) applicationShouldTerminate:(NSApplication *)sender
- (void) applicationDidHide:(NSNotification *)notification
{
callWindowHide();
}
- (void) applicationDidUnhide:(NSNotification *)notification
{
callWindowUnhide();
}
- (NSApplicationDelegateReply) applicationShouldTerminate:(NSApplication *)sender
{
if (!runMainLoop())
{

View File

@ -815,15 +815,48 @@ void LLWearableHoldingPattern::onAllComplete()
}
}
// Update wearables.
LL_INFOS("Avatar") << self_av_string() << "HP " << index() << " updating agent wearables with " << mResolved << " wearable items " << LL_ENDL;
LLAppearanceMgr::instance().updateAgentWearables(this);
// Update attachments to match those requested.
if (isAgentAvatarValid())
{
LL_DEBUGS("Avatar") << self_av_string() << "Updating " << mObjItems.size() << " attachments" << LL_ENDL;
LLAgentWearables::userUpdateAttachments(mObjItems);
LLAgentWearables::llvo_vec_t objects_to_remove;
LLAgentWearables::llvo_vec_t objects_to_retain;
LLInventoryModel::item_array_t items_to_add;
LLAgentWearables::findAttachmentsAddRemoveInfo(mObjItems,
objects_to_remove,
objects_to_retain,
items_to_add);
LL_DEBUGS("Avatar") << self_av_string() << "Removing " << objects_to_remove.size()
<< " attachments" << LL_ENDL;
// Here we remove the attachment pos overrides for *all*
// attachments, even those that are not being removed. This is
// needed to get joint positions all slammed down to their
// pre-attachment states.
gAgentAvatarp->clearAttachmentPosOverrides();
// Take off the attachments that will no longer be in the outfit.
LLAgentWearables::userRemoveMultipleAttachments(objects_to_remove);
// Update wearables.
LL_INFOS("Avatar") << self_av_string() << "HP " << index() << " updating agent wearables with "
<< mResolved << " wearable items " << LL_ENDL;
LLAppearanceMgr::instance().updateAgentWearables(this);
// Restore attachment pos overrides for the attachments that
// are remaining in the outfit.
for (LLAgentWearables::llvo_vec_t::iterator it = objects_to_retain.begin();
it != objects_to_retain.end();
++it)
{
LLViewerObject *objectp = *it;
gAgentAvatarp->addAttachmentPosOverridesForObject(objectp);
}
// Add new attachments to match those requested.
LL_DEBUGS("Avatar") << self_av_string() << "Adding " << items_to_add.size() << " attachments" << LL_ENDL;
LLAgentWearables::userAttachMultipleAttachments(items_to_add);
}
if (isFetchCompleted() && isMissingCompleted())
@ -2993,7 +3026,12 @@ void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, LLPointer<LLInve
const LLViewerInventoryItem* item = item_array.at(i).get();
if (item->getIsLinkType() && item->getLinkedUUID() == item_id)
{
remove_inventory_item(item->getUUID(), cb);
bool immediate_delete = false;
if (item->getType() == LLAssetType::AT_OBJECT)
{
immediate_delete = true;
}
remove_inventory_item(item->getUUID(), cb, immediate_delete);
}
// [/RLVa:KB]
// const LLInventoryItem* item = item_array.get(i).get();
@ -4407,17 +4445,33 @@ public:
bool handle(const LLSD& tokens, const LLSD& query_map,
LLMediaCtrl* web)
{
LLPointer<LLInventoryCategory> category = new LLInventoryCategory(query_map["folder_id"],
LLUUID::null,
LLFolderType::FT_CLOTHING,
"Quick Appearance");
LLSD::UUID folder_uuid = query_map["folder_id"].asUUID();
if ( gInventory.getCategory( folder_uuid ) != NULL )
{
LLAppearanceMgr::getInstance()->wearInventoryCategory(category, true, false);
LLSD::UUID folder_uuid;
// *TODOw: This may not be necessary if initial outfit is chosen already -- josh
gAgent.setOutfitChosen(TRUE);
if (folder_uuid.isNull() && query_map.has("folder_name"))
{
std::string outfit_folder_name = query_map["folder_name"];
folder_uuid = findDescendentCategoryIDByName(
gInventory.getLibraryRootFolderID(),
outfit_folder_name);
}
if (folder_uuid.isNull() && query_map.has("folder_id"))
{
folder_uuid = query_map["folder_id"].asUUID();
}
if (folder_uuid.notNull())
{
LLPointer<LLInventoryCategory> category = new LLInventoryCategory(folder_uuid,
LLUUID::null,
LLFolderType::FT_CLOTHING,
"Quick Appearance");
if ( gInventory.getCategory( folder_uuid ) != NULL )
{
LLAppearanceMgr::getInstance()->wearInventoryCategory(category, true, false);
// *TODOw: This may not be necessary if initial outfit is chosen already -- josh
gAgent.setOutfitChosen(TRUE);
}
}
// release avatar picker keyboard focus

View File

@ -443,7 +443,7 @@ void LLRenderPass::pushMaskBatches(U32 type, U32 mask, BOOL texture, BOOL batch_
}
}
void LLRenderPass::applyModelMatrix(LLDrawInfo& params)
void LLRenderPass::applyModelMatrix(const LLDrawInfo& params)
{
if (params.mModelMatrix != gGLLastMatrix)
{

View File

@ -168,7 +168,7 @@ public:
BOOL isDead() { return FALSE; }
void resetDrawOrders() { }
static void applyModelMatrix(LLDrawInfo& params);
static void applyModelMatrix(const LLDrawInfo& params);
virtual void pushBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);
virtual void pushMaskBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);
virtual void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE);

View File

@ -383,7 +383,7 @@ void LLDrawPoolAvatar::endPostDeferredAlpha()
void LLDrawPoolAvatar::renderPostDeferred(S32 pass)
{
const S32 actual_pass[] =
static const S32 actual_pass[] =
{ //map post deferred pass numbers to what render() expects
2, //skinned
4, // rigged fullbright

View File

@ -96,7 +96,7 @@ void LLDrawPoolMaterials::endDeferredPass(S32 pass)
void LLDrawPoolMaterials::renderDeferred(S32 pass)
{
U32 type_list[] =
static const U32 type_list[] =
{
LLRenderPass::PASS_MATERIAL,
//LLRenderPass::PASS_MATERIAL_ALPHA,

View File

@ -49,7 +49,7 @@
const F32 REFRESH_INTERVAL = 1.0f;
LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
: LLTransientDockableFloater(NULL, true, session_id),
: LLTransientDockableFloater(NULL, false, session_id),
mIsP2PChat(false),
mExpandCollapseBtn(NULL),
mTearOffBtn(NULL),

View File

@ -1990,7 +1990,9 @@ bool LLModelLoader::doLoadModel()
LLJoint* pJoint = mPreview->getPreviewAvatar()->getJoint( lookingForJoint );
if ( pJoint )
{
pJoint->storeCurrentXform( jointTransform.getTranslation() );
LLUUID fake_mesh_id;
fake_mesh_id.generate();
pJoint->addAttachmentPosOverride( jointTransform.getTranslation(), fake_mesh_id, gAgentAvatarp->avString());
}
else
{
@ -3302,7 +3304,11 @@ U32 LLModelPreview::calcResourceCost()
if ( mFMP && mFMP->childGetValue("upload_joints").asBoolean() )
{
getPreviewAvatar()->setPelvisOffset( mPelvisZOffset );
// FIXME if preview avatar ever gets reused, this fake mesh ID stuff will fail.
// see also call to addAttachmentPosOverride.
LLUUID fake_mesh_id;
fake_mesh_id.generate();
getPreviewAvatar()->addPelvisFixup( mPelvisZOffset, fake_mesh_id );
}
F32 streaming_cost = 0.f;

View File

@ -58,6 +58,8 @@ LLFloaterOpenObject::LLFloaterOpenObject(const LLSD& key)
{
mCommitCallbackRegistrar.add("OpenObject.MoveToInventory", boost::bind(&LLFloaterOpenObject::onClickMoveToInventory, this));
mCommitCallbackRegistrar.add("OpenObject.MoveAndWear", boost::bind(&LLFloaterOpenObject::onClickMoveAndWear, this));
mCommitCallbackRegistrar.add("OpenObject.ReplaceOutfit", boost::bind(&LLFloaterOpenObject::onClickReplace, this));
mCommitCallbackRegistrar.add("OpenObject.Cancel", boost::bind(&LLFloaterOpenObject::onClickCancel, this));
}
LLFloaterOpenObject::~LLFloaterOpenObject()
@ -115,6 +117,7 @@ void LLFloaterOpenObject::refresh()
getChild<LLUICtrl>("object_name")->setTextArg("[DESC]", name);
getChildView("copy_to_inventory_button")->setEnabled(enabled);
getChildView("copy_and_wear_button")->setEnabled(enabled);
getChildView("copy_and_replace_button")->setEnabled(enabled);
}
@ -135,7 +138,7 @@ void LLFloaterOpenObject::dirty()
void LLFloaterOpenObject::moveToInventory(bool wear)
void LLFloaterOpenObject::moveToInventory(bool wear, bool replace)
{
if (mObjectSelection->getRootObjectCount() != 1)
{
@ -163,7 +166,7 @@ void LLFloaterOpenObject::moveToInventory(bool wear)
parent_category_id = gInventory.getRootFolderID();
}
inventory_func_type func = boost::bind(LLFloaterOpenObject::callbackCreateInventoryCategory,_1,object_id,wear);
inventory_func_type func = boost::bind(LLFloaterOpenObject::callbackCreateInventoryCategory,_1,object_id,wear,replace);
LLUUID category_id = gInventory.createNewCategory(parent_category_id,
LLFolderType::FT_NONE,
name,
@ -177,6 +180,7 @@ void LLFloaterOpenObject::moveToInventory(bool wear)
data->mCatID = category_id;
data->mWear = wear;
data->mFolderResponded = false;
data->mReplace = replace;
// Copy and/or move the items into the newly created folder.
// Ignore any "you're going to break this item" messages.
@ -194,13 +198,14 @@ void LLFloaterOpenObject::moveToInventory(bool wear)
}
// static
void LLFloaterOpenObject::callbackCreateInventoryCategory(const LLUUID& category_id, LLUUID object_id, bool wear)
void LLFloaterOpenObject::callbackCreateInventoryCategory(const LLUUID& category_id, LLUUID object_id, bool wear, bool replace)
{
LLCatAndWear* wear_data = new LLCatAndWear;
wear_data->mCatID = category_id;
wear_data->mWear = wear;
wear_data->mFolderResponded = true;
wear_data->mReplace = replace;
// Copy and/or move the items into the newly created folder.
// Ignore any "you're going to break this item" messages.
@ -241,7 +246,17 @@ void LLFloaterOpenObject::onClickMoveToInventory()
void LLFloaterOpenObject::onClickMoveAndWear()
{
moveToInventory(true);
moveToInventory(true, false);
closeFloater();
}
void LLFloaterOpenObject::onClickReplace()
{
moveToInventory(true, true);
closeFloater();
}
void LLFloaterOpenObject::onClickCancel()
{
closeFloater();
}

View File

@ -50,6 +50,7 @@ public:
LLUUID mCatID;
bool mWear;
bool mFolderResponded;
bool mReplace;
};
protected:
@ -59,11 +60,13 @@ protected:
void draw();
virtual void onOpen(const LLSD& key);
void moveToInventory(bool wear);
void moveToInventory(bool wear, bool replace = false);
void onClickMoveToInventory();
void onClickMoveAndWear();
static void callbackCreateInventoryCategory(const LLUUID& category_id, LLUUID object_id, bool wear);
void onClickReplace();
void onClickCancel();
static void callbackCreateInventoryCategory(const LLUUID& category_id, LLUUID object_id, bool wear, bool replace = false);
static void callbackMoveInventory(S32 result, void* data);
private:

View File

@ -40,8 +40,10 @@
#include "lltextbox.h"
#include "lllineeditor.h"
#include "llmutelist.h"
#include "llnotificationsutil.h"
#include "llfloaterreporter.h"
#include "llslurl.h"
#include "llstatusbar.h"
#include "llviewerobject.h"
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
@ -90,6 +92,9 @@ public:
static void payDirectly(money_callback callback,
const LLUUID& target_id,
bool is_group);
static bool payConfirmationCallback(const LLSD& notification,
const LLSD& response,
LLGiveMoneyInfo* info);
private:
static void onCancel(void* data);
@ -111,14 +116,12 @@ protected:
LLGiveMoneyInfo* mQuickPayInfo[MAX_PAY_BUTTONS];
LLSafeHandle<LLObjectSelection> mObjectSelection;
static S32 sLastAmount;
};
S32 LLFloaterPay::sLastAmount = 0;
const S32 MAX_AMOUNT_LENGTH = 10;
const S32 FASTPAY_BUTTON_WIDTH = 80;
const S32 PAY_AMOUNT_NOTIFICATION = 200;
LLFloaterPay::LLFloaterPay(const LLSD& key)
: LLFloater(key),
@ -188,17 +191,9 @@ BOOL LLFloaterPay::postBuild()
getChildView("amount text")->setVisible(FALSE);
std::string last_amount;
if(sLastAmount > 0)
{
last_amount = llformat("%d", sLastAmount);
}
getChildView("amount")->setVisible(FALSE);
getChild<LLLineEditor>("amount")->setKeystrokeCallback(&LLFloaterPay::onKeystroke, this);
getChild<LLUICtrl>("amount")->setValue(last_amount);
getChild<LLLineEditor>("amount")->setPrevalidate(LLTextValidate::validateNonNegativeS32);
info = new LLGiveMoneyInfo(this, 0);
@ -207,7 +202,7 @@ BOOL LLFloaterPay::postBuild()
childSetAction("pay btn",&LLFloaterPay::onGive,info);
setDefaultBtn("pay btn");
getChildView("pay btn")->setVisible(FALSE);
getChildView("pay btn")->setEnabled((sLastAmount > 0));
getChildView("pay btn")->setEnabled(FALSE);
childSetAction("cancel btn",&LLFloaterPay::onCancel,this);
@ -422,7 +417,24 @@ void LLFloaterPay::payDirectly(money_callback callback,
floater->finishPayUI(target_id, is_group);
}
bool LLFloaterPay::payConfirmationCallback(const LLSD& notification, const LLSD& response, LLGiveMoneyInfo* info)
{
if (!info || !info->mFloater)
{
return false;
}
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if (option == 0)
{
info->mFloater->give(info->mAmount);
info->mFloater->closeFloater();
}
return false;
}
void LLFloaterPay::finishPayUI(const LLUUID& target_id, BOOL is_group)
{
std::string slurl;
@ -473,10 +485,40 @@ void LLFloaterPay::onKeystroke(LLLineEditor*, void* data)
void LLFloaterPay::onGive(void* data)
{
LLGiveMoneyInfo* info = reinterpret_cast<LLGiveMoneyInfo*>(data);
if(info && info->mFloater)
LLFloaterPay* floater = info->mFloater;
if(info && floater)
{
info->mFloater->give(info->mAmount);
info->mFloater->closeFloater();
S32 amount = info->mAmount;
if(amount == 0)
{
amount = atoi(floater->getChild<LLUICtrl>("amount")->getValue().asString().c_str());
}
if (amount > PAY_AMOUNT_NOTIFICATION && gStatusBar && gStatusBar->getBalance() > amount)
{
LLUUID payee_id;
BOOL is_group;
if (floater->mObjectSelection.notNull())
{
LLSelectNode* node = floater->mObjectSelection->getFirstRootNode();
node->mPermissions->getOwnership(payee_id, is_group);
}
else
{
is_group = floater->mTargetIsGroup;
payee_id = floater->mTargetUUID;
}
LLSD args;
args["TARGET"] = LLSLURL( is_group ? "group" : "agent", payee_id, "completename").getSLURLString();
args["AMOUNT"] = amount;
LLNotificationsUtil::add("PayConfirmation", args, LLSD(), boost::bind(&LLFloaterPay::payConfirmationCallback, _1, _2, info));
}
else
{
floater->give(amount);
floater->closeFloater();
}
}
}
@ -490,7 +532,6 @@ void LLFloaterPay::give(S32 amount)
{
amount = atoi(getChild<LLUICtrl>("amount")->getValue().asString().c_str());
}
sLastAmount = amount;
// Try to pay an object.
if (mObjectSelection.notNull())

View File

@ -299,6 +299,7 @@ void LLFloaterWebContent::onOpen(const LLSD& key)
void LLFloaterWebContent::onClose(bool app_quitting)
{
// If we close the web browsing window showing the facebook login, we need to signal to this object that the connection will not happen
// MAINT-3440 note change here to use findInstance and not getInstance - latter creates an instance if it's not there which is bad.
LLFloater* fbc_web = LLFloaterReg::findInstance("fbc_web");
if (fbc_web == this)
@ -309,7 +310,8 @@ void LLFloaterWebContent::onClose(bool app_quitting)
}
}
// Same with Flickr
LLFloater* flickr_web = LLFloaterReg::getInstance("flickr_web");
// MAINT-3440 note change here to use findInstance and not getInstance - latter creates an instance if it's not there which is bad.
LLFloater* flickr_web = LLFloaterReg::findInstance("flickr_web");
if (flickr_web == this)
{
if (!LLFlickrConnect::instance().isConnected())
@ -318,7 +320,8 @@ void LLFloaterWebContent::onClose(bool app_quitting)
}
}
// And Twitter
LLFloater* twitter_web = LLFloaterReg::getInstance("twitter_web");
// MAINT-3440 note change here to use findInstance and not getInstance - latter creates an instance if it's not there which is bad.
LLFloater* twitter_web = LLFloaterReg::findInstance("twitter_web");
if (twitter_web == this)
{
if (!LLTwitterConnect::instance().isConnected())

View File

@ -129,13 +129,18 @@ void LLFolderViewModelItemInventory::requestSort()
void LLFolderViewModelItemInventory::setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset, std::string::size_type string_size)
{
bool generation_skip = mMarkedDirtyGeneration >= 0
&& mPrevPassedAllFilters
&& mMarkedDirtyGeneration < mRootViewModel.getFilter().getFirstSuccessGeneration();
LLFolderViewModelItemCommon::setPassedFilter(passed, filter_generation, string_offset, string_size);
bool before = mPrevPassedAllFilters;
mPrevPassedAllFilters = passedFilter(filter_generation);
if (before != mPrevPassedAllFilters)
if (before != mPrevPassedAllFilters || generation_skip)
{
// Need to rearrange the folder if the filtered state of the item changed
// Need to rearrange the folder if the filtered state of the item changed,
// previously passed item skipped filter generation changes while being dirty
// or previously passed not yet filtered item was marked dirty
LLFolderViewFolder* parent_folder = mFolderViewItem->getParentFolder();
if (parent_folder)
{
@ -144,6 +149,9 @@ void LLFolderViewModelItemInventory::setPassedFilter(bool passed, S32 filter_gen
}
}
bool LLFolderViewModelItemInventory::filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter )
{
S32 filter_generation = filter.getCurrentGeneration();

View File

@ -3059,8 +3059,8 @@ void LLRightClickInventoryFetchDescendentsObserver::execute(bool clear_observer)
class LLInventoryCopyAndWearObserver : public LLInventoryObserver
{
public:
LLInventoryCopyAndWearObserver(const LLUUID& cat_id, int count, bool folder_added=false) :
mCatID(cat_id), mContentsCount(count), mFolderAdded(folder_added) {}
LLInventoryCopyAndWearObserver(const LLUUID& cat_id, int count, bool folder_added=false, bool replace=false) :
mCatID(cat_id), mContentsCount(count), mFolderAdded(folder_added), mReplace(replace){}
virtual ~LLInventoryCopyAndWearObserver() {}
virtual void changed(U32 mask);
@ -3068,6 +3068,7 @@ protected:
LLUUID mCatID;
int mContentsCount;
bool mFolderAdded;
bool mReplace;
};
@ -3106,7 +3107,7 @@ void LLInventoryCopyAndWearObserver::changed(U32 mask)
mContentsCount)
{
gInventory.removeObserver(this);
LLAppearanceMgr::instance().wearInventoryCategory(category, FALSE, TRUE);
LLAppearanceMgr::instance().wearInventoryCategory(category, FALSE, !mReplace);
delete this;
}
}
@ -4165,24 +4166,21 @@ void LLFolderBridge::modifyOutfit(BOOL append, BOOL replace)
// checking amount of items to wear
U32 max_items = gSavedSettings.getU32("WearFolderLimit");
if (cat->getDescendentCount() > max_items)
{
LLInventoryModel::cat_array_t cats;
LLInventoryModel::item_array_t items;
LLFindWearablesEx not_worn(/*is_worn=*/ false, /*include_body_parts=*/ false);
gInventory.collectDescendentsIf(cat->getUUID(),
cats,
items,
LLInventoryModel::EXCLUDE_TRASH,
not_worn);
LLInventoryModel::cat_array_t cats;
LLInventoryModel::item_array_t items;
LLFindWearablesEx not_worn(/*is_worn=*/ false, /*include_body_parts=*/ false);
gInventory.collectDescendentsIf(cat->getUUID(),
cats,
items,
LLInventoryModel::EXCLUDE_TRASH,
not_worn);
if (items.size() > max_items)
{
LLSD args;
args["AMOUNT"] = llformat("%d", max_items);
LLNotificationsUtil::add("TooManyWearables", args);
return;
}
if (items.size() > max_items)
{
LLSD args;
args["AMOUNT"] = llformat("%d", max_items);
LLNotificationsUtil::add("TooManyWearables", args);
return;
}
LLAppearanceMgr::instance().wearInventoryCategory( cat, FALSE, append, replace );
@ -4202,7 +4200,8 @@ bool move_task_inventory_callback(const LLSD& notification, const LLSD& response
LLInventoryObject::object_list_t inventory_objects;
object->getInventoryContents(inventory_objects);
int contents_count = inventory_objects.size()-1; //subtract one for containing folder
LLInventoryCopyAndWearObserver* inventoryObserver = new LLInventoryCopyAndWearObserver(cat_and_wear->mCatID, contents_count, cat_and_wear->mFolderResponded);
LLInventoryCopyAndWearObserver* inventoryObserver = new LLInventoryCopyAndWearObserver(cat_and_wear->mCatID, contents_count, cat_and_wear->mFolderResponded,
cat_and_wear->mReplace);
gInventory.addObserver(inventoryObserver);
}
@ -5942,16 +5941,20 @@ std::string LLObjectBridge::getLabelSuffix() const
{
return LLItemBridge::getLabelSuffix() + LLTrans::getString("worn");
}
std::string attachment_point_name = gAgentAvatarp->getAttachedPointName(mUUID);
if (attachment_point_name == LLStringUtil::null) // Error condition, invalid attach point
std::string attachment_point_name;
if (gAgentAvatarp->getAttachedPointName(mUUID, attachment_point_name))
{
attachment_point_name = "Invalid Attachment";
}
// e.g. "(worn on ...)" / "(attached to ...)"
LLStringUtil::format_map_t args;
args["[ATTACHMENT_POINT]"] = LLTrans::getString(attachment_point_name);
LLStringUtil::format_map_t args;
args["[ATTACHMENT_POINT]"] = LLTrans::getString(attachment_point_name);
return LLItemBridge::getLabelSuffix() + LLTrans::getString("WornOnAttachmentPoint", args);
return LLItemBridge::getLabelSuffix() + LLTrans::getString("WornOnAttachmentPoint", args);
}
else
{
LLStringUtil::format_map_t args;
args["[ATTACHMENT_ERROR]"] = LLTrans::getString(attachment_point_name);
return LLItemBridge::getLabelSuffix() + LLTrans::getString("AttachmentErrorMessage", args);
}
}
return LLItemBridge::getLabelSuffix();
}

View File

@ -223,13 +223,6 @@ bool LLInventoryFilter::checkFolder(const LLFolderViewModelItem* item) const
bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
{
// when applying a filter, matching folders get their contents downloaded first
if (isNotDefault()
&& !gInventory.isCategoryComplete(folder_id))
{
LLInventoryModelBackgroundFetch::instance().start(folder_id);
}
// Always check against the clipboard
// <FS:Ansariel> FIRE-6714: Don't move objects to trash during cut&paste
// Don't hide cut items in inventory
@ -243,6 +236,13 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
return passed_clipboard;
}
// when applying a filter, matching folders get their contents downloaded first
if (mFilterSubString.size()
&& !gInventory.isCategoryComplete(folder_id))
{
LLInventoryModelBackgroundFetch::instance().start(folder_id);
}
// show folder links
LLViewerInventoryItem* item = gInventory.getItem(folder_id);
if (item && item->getActualType() == LLAssetType::AT_LINK_FOLDER)

View File

@ -590,12 +590,13 @@ void LLInventoryPanel::modelChanged(U32 mask)
// This item already exists in both memory and UI. It was probably reparented.
else if (model_item && view_item)
{
LLFolderViewFolder* old_parent = view_item->getParentFolder();
// Don't process the item if it is the root
if (view_item->getParentFolder())
if (old_parent)
{
LLFolderViewFolder* new_parent = (LLFolderViewFolder*)getItemByID(model_item->getParentUUID());
// Item has been moved.
if (view_item->getParentFolder() != new_parent)
if (old_parent != new_parent)
{
if (new_parent != NULL)
{
@ -621,6 +622,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
// doesn't include trash). Just remove the item's UI.
view_item->destroyView();
}
old_parent->getViewModelItem()->dirtyDescendantsFilter();
}
}
}
@ -631,27 +633,16 @@ void LLInventoryPanel::modelChanged(U32 mask)
else if (!model_item && view_item && viewmodel_item)
{
// Remove the item's UI.
removeItemID(viewmodel_item->getUUID());
LLFolderViewFolder* parent = view_item->getParentFolder();
removeItemID(viewmodel_item->getUUID());
view_item->destroyView();
if(parent)
{
parent->getViewModelItem()->dirtyDescendantsFilter();
}
}
}
}
if (mask & (LLInventoryObserver::STRUCTURE | LLInventoryObserver::REMOVE))
{
// STRUCTURE and REMOVE model changes usually fail to update (clean)
// mMostFilteredDescendantGeneration of parent folder and dirtyFilter()
// is not sufficient for successful filter update, so we need to check
// all already passed element over again to remove obsolete elements.
// New items or moved items should be sufficiently covered by
// dirtyFilter().
LLInventoryFilter& filter = getFilter();
if (filter.getFilterTypes() & LLInventoryFilter::FILTERTYPE_DATE
|| filter.isNotDefault())
{
filter.setModified(LLFolderViewFilter::FILTER_MORE_RESTRICTIVE);
}
}
}
LLUUID LLInventoryPanel::getRootFolderID()

View File

@ -1987,6 +1987,8 @@ void LLPanelFace::onCancelNormalTexture(const LLSD& data)
U8 bumpy = 0;
bool identical_bumpy = false;
LLSelectedTE::getBumpmap(bumpy, identical_bumpy);
LLUUID spec_map_id = getChild<LLTextureCtrl>("bumpytexture control")->getImageAssetID();
bumpy = spec_map_id.isNull() ? bumpy : BUMPY_TEXTURE;
sendBump(bumpy);
}

View File

@ -213,7 +213,9 @@ BOOL LLPanelMainInventory::postBuild()
recent_items_panel->setSortOrder(gSavedSettings.getU32(LLInventoryPanel::RECENTITEMS_SORT_ORDER));
// </FS:Zi>
recent_items_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
recent_items_panel->getFilter().markDefault();
LLInventoryFilter& recent_filter = recent_items_panel->getFilter();
recent_filter.setFilterObjectTypes(recent_filter.getFilterObjectTypes() & ~(0x1 << LLInventoryType::IT_CATEGORY));
recent_filter.markDefault();
recent_items_panel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, recent_items_panel, _1, _2));
}
@ -1159,9 +1161,9 @@ void LLFloaterInventoryFinder::draw()
filtered_by_all_types = FALSE;
}
if (!filtered_by_all_types)
if (!filtered_by_all_types || (mPanelMainInventory->getPanel()->getFilter().getFilterTypes() & LLInventoryFilter::FILTERTYPE_DATE))
{
// don't include folders in filter, unless I've selected everything
// don't include folders in filter, unless I've selected everything or filtering by date
filter &= ~(0x1 << LLInventoryType::IT_CATEGORY);
}

View File

@ -777,6 +777,10 @@ void LLTaskInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
// if(isItemRenameable())
// {
// items.push_back(std::string("Task Rename"));
// if ((flags & FIRST_SELECTED_ITEM) == 0)
// {
// disabled_items.push_back(std::string("Task Rename"));
// }
// }
// if(isItemRemovable())
// {

View File

@ -915,12 +915,13 @@ void LLScriptEdCore::updateDynamicHelp(BOOL immediate)
LLTextSegmentPtr segment = NULL;
std::vector<LLTextSegmentPtr> selected_segments;
mEditor->getSelectedSegments(selected_segments);
LLKeywordToken* token;
// try segments in selection range first
std::vector<LLTextSegmentPtr>::iterator segment_iter;
for (segment_iter = selected_segments.begin(); segment_iter != selected_segments.end(); ++segment_iter)
{
if((*segment_iter)->getToken() && (*segment_iter)->getToken()->getType() == LLKeywordToken::TT_WORD)
token = (*segment_iter)->getToken();
if(token && isKeyword(token))
{
segment = *segment_iter;
break;
@ -931,7 +932,8 @@ void LLScriptEdCore::updateDynamicHelp(BOOL immediate)
if (!segment)
{
const LLTextSegmentPtr test_segment = mEditor->getPreviousSegment();
if(test_segment->getToken() && test_segment->getToken()->getType() == LLKeywordToken::TT_WORD)
token = test_segment->getToken();
if(token && isKeyword(token))
{
segment = test_segment;
}
@ -960,6 +962,24 @@ void LLScriptEdCore::updateDynamicHelp(BOOL immediate)
}
}
bool LLScriptEdCore::isKeyword(LLKeywordToken* token)
{
switch(token->getType())
{
case LLKeywordToken::TT_CONSTANT:
case LLKeywordToken::TT_CONTROL:
case LLKeywordToken::TT_EVENT:
case LLKeywordToken::TT_FUNCTION:
case LLKeywordToken::TT_SECTION:
case LLKeywordToken::TT_TYPE:
case LLKeywordToken::TT_WORD:
return true;
default:
return false;
}
}
void LLScriptEdCore::setHelpPage(const std::string& help_string)
{
LLFloater* help_floater = mLiveHelpHandle.get();

View File

@ -161,6 +161,7 @@ protected:
void deleteBridges();
void setHelpPage(const std::string& help_string);
void updateDynamicHelp(BOOL immediate = FALSE);
bool isKeyword(LLKeywordToken* token);
void addHelpItemToHistory(const std::string& help_string);
static void onErrorList(LLUICtrl*, void* user_data);

View File

@ -1632,7 +1632,7 @@ void pushVertsColorCoded(LLSpatialGroup* group, U32 mask)
{
LLDrawInfo* params = NULL;
LLColor4 colors[] = {
static const LLColor4 colors[] = {
LLColor4::green,
LLColor4::green1,
LLColor4::green2,

View File

@ -550,10 +550,18 @@ void LLSpeakerMgr::updateSpeakerList()
LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id);
if (session->isGroupSessionType() && (mSpeakers.size() <= 1))
{
const F32 load_group_timeout = gSavedSettings.getF32("ChatLoadGroupTimeout");
// For groups, we need to hit the group manager.
// Note: The session uuid and the group uuid are actually one and the same. If that was to change, this will fail.
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(session_id);
F32 large_group_delay = 0.f;
if (gdatap)
{
//This is a viewer-side bandaid for maint-4414 it does not fix the core issue.
large_group_delay = (F32)(gdatap->mMemberCount / 5000);
}
const F32 load_group_timeout = gSavedSettings.getF32("ChatLoadGroupTimeout") + large_group_delay;
if (!gdatap && (mGetListTime.getElapsedTimeF32() >= load_group_timeout))
{
// Request the data the first time around

View File

@ -118,7 +118,7 @@ public:
/*virtual*/ void onClose(bool app_settings);
// New functions
void setImageID( const LLUUID& image_asset_id);
void setImageID( const LLUUID& image_asset_id, bool set_selection = true);
void updateImageStats();
const LLUUID& getAssetID() { return mImageAssetID; }
const LLUUID& findItemID(const LLUUID& asset_id, BOOL copyable_only);
@ -235,7 +235,7 @@ LLFloaterTexturePicker::~LLFloaterTexturePicker()
{
}
void LLFloaterTexturePicker::setImageID(const LLUUID& image_id)
void LLFloaterTexturePicker::setImageID(const LLUUID& image_id, bool set_selection /*=true*/)
{
if( mImageAssetID != image_id && mActive)
{
@ -256,6 +256,10 @@ void LLFloaterTexturePicker::setImageID(const LLUUID& image_id)
getChild<LLUICtrl>("apply_immediate_check")->setValue(FALSE);
mNoCopyTextureSelected = TRUE;
}
}
if (set_selection)
{
mInventoryPanel->setSelection(item_id, TAKE_FOCUS_NO);
}
}
@ -468,7 +472,10 @@ BOOL LLFloaterTexturePicker::postBuild()
// don't put keyboard focus on selected item, because the selection callback
// will assume that this was user input
mInventoryPanel->setSelection(findItemID(mImageAssetID, FALSE), TAKE_FOCUS_NO);
if(!mImageAssetID.isNull())
{
mInventoryPanel->setSelection(findItemID(mImageAssetID, FALSE), TAKE_FOCUS_NO);
}
}
mModeSelector = getChild<LLRadioGroup>("mode_selection");
@ -844,7 +851,7 @@ void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem
// <FS:Ansariel> FIRE-8298: Apply now checkbox has no effect
setCanApply(true, true);
// </FS:Ansariel>
setImageID(itemp->getAssetUUID());
setImageID(itemp->getAssetUUID(),false);
mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
if (user_action && mCanPreview)
{

View File

@ -2278,23 +2278,20 @@ EAcceptance LLToolDragAndDrop::dad3dWearCategory(
}
U32 max_items = gSavedSettings.getU32("WearFolderLimit");
if (category->getDescendentCount()>max_items)
LLInventoryModel::cat_array_t cats;
LLInventoryModel::item_array_t items;
LLFindWearablesEx not_worn(/*is_worn=*/ false, /*include_body_parts=*/ false);
gInventory.collectDescendentsIf(category->getUUID(),
cats,
items,
LLInventoryModel::EXCLUDE_TRASH,
not_worn);
if (items.size() > max_items)
{
LLInventoryModel::cat_array_t cats;
LLInventoryModel::item_array_t items;
LLFindWearablesEx not_worn(/*is_worn=*/ false, /*include_body_parts=*/ false);
gInventory.collectDescendentsIf(category->getUUID(),
cats,
items,
LLInventoryModel::EXCLUDE_TRASH,
not_worn);
if (items.size() > max_items)
{
LLStringUtil::format_map_t args;
args["AMOUNT"] = llformat("%d", max_items);
mCustomMsg = LLTrans::getString("TooltipTooManyWearables",args);
return ACCEPT_NO_CUSTOM;
}
LLStringUtil::format_map_t args;
args["AMOUNT"] = llformat("%d", max_items);
mCustomMsg = LLTrans::getString("TooltipTooManyWearables",args);
return ACCEPT_NO_CUSTOM;
}
if(mSource == SOURCE_AGENT)

View File

@ -1477,7 +1477,8 @@ void update_inventory_category(
void remove_inventory_items(
LLInventoryObject::object_list_t& items_to_kill,
LLPointer<LLInventoryCallback> cb)
LLPointer<LLInventoryCallback> cb
)
{
for (LLInventoryObject::object_list_t::iterator it = items_to_kill.begin();
it != items_to_kill.end();
@ -1489,12 +1490,13 @@ void remove_inventory_items(
void remove_inventory_item(
const LLUUID& item_id,
LLPointer<LLInventoryCallback> cb)
LLPointer<LLInventoryCallback> cb,
bool immediate_delete)
{
LLPointer<LLInventoryObject> obj = gInventory.getItem(item_id);
if (obj)
{
remove_inventory_item(obj, cb);
remove_inventory_item(obj, cb, immediate_delete);
}
else
{
@ -1504,7 +1506,8 @@ void remove_inventory_item(
void remove_inventory_item(
LLPointer<LLInventoryObject> obj,
LLPointer<LLInventoryCallback> cb)
LLPointer<LLInventoryCallback> cb,
bool immediate_delete)
{
if(obj)
{
@ -1514,6 +1517,11 @@ void remove_inventory_item(
{
LLPointer<AISCommand> cmd_ptr = new RemoveItemCommand(item_id, cb);
cmd_ptr->run_command();
if (immediate_delete)
{
gInventory.onObjectDeletedFromServer(item_id);
}
}
else // no cap
{

View File

@ -397,11 +397,13 @@ void remove_inventory_items(
void remove_inventory_item(
LLPointer<LLInventoryObject> obj,
LLPointer<LLInventoryCallback> cb);
LLPointer<LLInventoryCallback> cb,
bool immediate_delete = false);
void remove_inventory_item(
const LLUUID& item_id,
LLPointer<LLInventoryCallback> cb);
LLPointer<LLInventoryCallback> cb,
bool immediate_delete = false);
void remove_inventory_category(
const LLUUID& cat_id,

View File

@ -121,22 +121,29 @@ void agent_push_down( EKeystate s )
// </FS:Ansariel>
}
static void agent_check_temporary_run(LLAgent::EDoubleTapRunMode mode)
{
// if (gAgent.mDoubleTapRunMode == mode &&
// gAgent.getRunning() &&
// !gAgent.getAlwaysRun())
// {
// // Turn off temporary running.
// gAgent.clearRunning();
// gAgent.sendWalkRun(gAgent.getRunning());
// }
// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i
if ( (gAgent.mDoubleTapRunMode == mode) && (gAgent.getTempRun()) )
gAgent.clearTempRun();
// [/RLVa:KB]
}
static void agent_handle_doubletap_run(EKeystate s, LLAgent::EDoubleTapRunMode mode)
{
if (KEYSTATE_UP == s)
{
// if (gAgent.mDoubleTapRunMode == mode &&
// gAgent.getRunning() &&
// !gAgent.getAlwaysRun())
// {
// // Turn off temporary running.
// gAgent.clearRunning();
// gAgent.sendWalkRun(gAgent.getRunning());
// }
// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i
if ( (gAgent.mDoubleTapRunMode == mode) && (gAgent.getTempRun()) )
gAgent.clearTempRun();
// [/RLVa:KB]
// Note: in case shift is already released, slide left/right run
// will be released in agent_turn_left()/agent_turn_right()
agent_check_temporary_run(mode);
}
else if (gSavedSettings.getBOOL("AllowTapTapHoldRun") &&
KEYSTATE_DOWN == s &&
@ -258,7 +265,12 @@ void agent_turn_left( EKeystate s )
}
else
{
if (KEYSTATE_UP == s) return;
if (KEYSTATE_UP == s)
{
// Check temporary running. In case user released 'left' key with shift already released.
agent_check_temporary_run(LLAgent::DOUBLETAP_SLIDELEFT);
return;
}
F32 time = gKeyboard->getCurKeyElapsedTime();
gAgent.moveYaw( LLFloaterMove::getYawRate( time ) );
}
@ -281,7 +293,12 @@ void agent_turn_right( EKeystate s )
}
else
{
if (KEYSTATE_UP == s) return;
if (KEYSTATE_UP == s)
{
// Check temporary running. In case user released 'right' key with shift already released.
agent_check_temporary_run(LLAgent::DOUBLETAP_SLIDERIGHT);
return;
}
F32 time = gKeyboard->getCurKeyElapsedTime();
gAgent.moveYaw( -LLFloaterMove::getYawRate( time ) );
}

View File

@ -364,10 +364,17 @@ void LLViewerObject::markDead()
//LL_INFOS() << "Marking self " << mLocalID << " as dead." << LL_ENDL;
// Root object of this hierarchy unlinks itself.
LLVOAvatar *av = getAvatarAncestor();
if (getParent())
{
((LLViewerObject *)getParent())->removeChild(this);
}
LLUUID mesh_id;
if (av && LLVOAvatar::getRiggedMeshID(this,mesh_id))
{
// This case is needed for indirectly attached mesh objects.
av->resetJointPositionsOnDetach(mesh_id);
}
// Mark itself as dead
mDead = TRUE;
@ -2322,7 +2329,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
}
}
if ((new_rot != getRotation())
if ((new_rot.isNotEqualEps(getRotation(), F_ALMOST_ZERO))
|| (new_angv != old_angv))
{
if (new_rot != mPreviousRotation)
@ -5087,6 +5094,22 @@ LLVOAvatar* LLViewerObject::asAvatar()
return NULL;
}
// If this object is directly or indirectly parented by an avatar, return it.
LLVOAvatar* LLViewerObject::getAvatarAncestor()
{
LLViewerObject *pobj = (LLViewerObject*) getParent();
while (pobj)
{
LLVOAvatar *av = pobj->asAvatar();
if (av)
{
return av;
}
pobj = (LLViewerObject*) pobj->getParent();
}
return NULL;
}
BOOL LLViewerObject::isParticleSource() const
{
return !mPartSourcep.isNull() && !mPartSourcep->isDead();
@ -6285,6 +6308,17 @@ const LLUUID &LLViewerObject::extractAttachmentItemID()
return getAttachmentItemID();
}
const std::string& LLViewerObject::getAttachmentItemName()
{
static std::string empty;
LLInventoryItem *item = gInventory.getItem(getAttachmentItemID());
if (isAttachment() && item)
{
return item->getName();
}
return empty;
}
//virtual
LLVOAvatar* LLViewerObject::getAvatar() const
{

View File

@ -135,6 +135,8 @@ public:
virtual LLVOAvatar* asAvatar();
LLVOAvatar* getAvatarAncestor();
static void initVOClasses();
static void cleanupVOClasses();
@ -170,6 +172,8 @@ public:
void setOnActiveList(BOOL on_active) { mOnActiveList = on_active; }
virtual BOOL isAttachment() const { return FALSE; }
const std::string& getAttachmentItemName();
virtual LLVOAvatar* getAvatar() const; //get the avatar this object is attached to, or NULL if object is not an attachment
virtual BOOL isHUDAttachment() const { return FALSE; }
virtual BOOL isTempAttachment() const;

View File

@ -723,7 +723,6 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mVisualComplexity(0),
mVisualComplexityStale(TRUE),
mLoadedCallbacksPaused(FALSE),
mHasPelvisOffset( FALSE ),
mRenderUnloadedAvatar(LLCachedControl<bool>(gSavedSettings, "RenderUnloadedAvatar", false)),
mLastRezzedStatus(-1),
mIsEditingAppearance(FALSE),
@ -785,10 +784,6 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mRuthTimer.reset();
mRuthDebugTimer.reset();
mDebugExistenceTimer.reset();
mPelvisOffset = LLVector3(0.0f,0.0f,0.0f);
mLastPelvisToFoot = 0.0f;
mPelvisFixup = 0.0f;
mLastPelvisFixup = 0.0f;
if(LLSceneMonitor::getInstance()->isEnabled())
{
@ -1319,17 +1314,18 @@ const LLVector3 LLVOAvatar::getRenderPosition() const
}
else if (isRoot())
{
if ( !mHasPelvisOffset )
{
return mDrawable->getPositionAgent();
}
else
F32 fixup;
if ( hasPelvisFixup( fixup) )
{
//Apply a pelvis fixup (as defined by the avs skin)
LLVector3 pos = mDrawable->getPositionAgent();
pos[VZ] += mPelvisFixup;
pos[VZ] += fixup;
return pos;
}
else
{
return mDrawable->getPositionAgent();
}
}
else
{
@ -3587,6 +3583,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
{
debug_line += llformat(" - cof rcv:%d", last_received_cof_version);
}
debug_line += llformat(" bsz-z: %f avofs-z: %f", mBodySize[2], mAvatarOffset[2]);
addDebugText(debug_line);
}
// <FS:CR> Use LLCachedControl
@ -4121,21 +4118,6 @@ void LLVOAvatar::updateHeadOffset()
}
}
//------------------------------------------------------------------------
// setPelvisOffset
//------------------------------------------------------------------------
void LLVOAvatar::setPelvisOffset( bool hasOffset, const LLVector3& offsetAmount, F32 pelvisFixup )
{
mHasPelvisOffset = hasOffset;
if ( mHasPelvisOffset )
{
//Store off last pelvis to foot value
mLastPelvisToFoot = mPelvisToFoot;
mPelvisOffset = offsetAmount;
mLastPelvisFixup = mPelvisFixup;
mPelvisFixup = pelvisFixup;
}
}
//------------------------------------------------------------------------
// postPelvisSetRecalc
//------------------------------------------------------------------------
void LLVOAvatar::postPelvisSetRecalc( void )
@ -4145,15 +4127,6 @@ void LLVOAvatar::postPelvisSetRecalc( void )
dirtyMesh(2);
}
//------------------------------------------------------------------------
// setPelvisOffset
//------------------------------------------------------------------------
void LLVOAvatar::setPelvisOffset( F32 pelvisFixupAmount )
{
mHasPelvisOffset = true;
mLastPelvisFixup = mPelvisFixup;
mPelvisFixup = pelvisFixupAmount;
}
//------------------------------------------------------------------------
// updateVisibility()
//------------------------------------------------------------------------
void LLVOAvatar::updateVisibility()
@ -5295,6 +5268,12 @@ BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL
{
sitDown(FALSE);
}
if ((anim_id == ANIM_AGENT_DO_NOT_DISTURB) && gAgent.isDoNotDisturb())
{
// re-assert DND tag animation
gAgent.sendAnimationRequest(ANIM_AGENT_DO_NOT_DISTURB, ANIM_REQUEST_START);
return result;
}
stopMotion(anim_id);
result = TRUE;
}
@ -5501,10 +5480,162 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name )
return jointp;
}
//-----------------------------------------------------------------------------
// resetJointPositionsToDefault
// getRiggedMeshID
//
// If viewer object is a rigged mesh, set the mesh id and return true.
// Otherwise, null out the id and return false.
//-----------------------------------------------------------------------------
void LLVOAvatar::resetJointPositionsToDefault( void )
// static
bool LLVOAvatar::getRiggedMeshID(LLViewerObject* pVO, LLUUID& mesh_id)
{
mesh_id.setNull();
//If a VO has a skin that we'll reset the joint positions to their default
if ( pVO && pVO->mDrawable )
{
LLVOVolume* pVObj = pVO->mDrawable->getVOVolume();
if ( pVObj )
{
const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( pVObj->getVolume()->getParams().getSculptID(), pVObj );
if (pSkinData
&& pSkinData->mJointNames.size() > JOINT_COUNT_REQUIRED_FOR_FULLRIG // full rig
&& pSkinData->mAlternateBindMatrix.size() > 0 )
{
mesh_id = pSkinData->mMeshID;
return true;
}
}
}
return false;
}
void LLVOAvatar::clearAttachmentPosOverrides()
{
//Subsequent joints are relative to pelvis
avatar_joint_list_t::iterator iter = mSkeleton.begin();
avatar_joint_list_t::iterator end = mSkeleton.end();
for (; iter != end; ++iter)
{
LLJoint* pJoint = (*iter);
pJoint->clearAttachmentPosOverrides();
}
}
//-----------------------------------------------------------------------------
// addAttachmentPosOverridesForObject
//-----------------------------------------------------------------------------
void LLVOAvatar::addAttachmentPosOverridesForObject(LLViewerObject *vo)
{
LLVOAvatar *av = vo->getAvatarAncestor();
if (!av || (av != this))
{
LL_WARNS("Avatar") << "called with invalid avatar" << LL_ENDL;
}
// Process all children
LLViewerObject::const_child_list_t& children = vo->getChildren();
for (LLViewerObject::const_child_list_t::const_iterator it = children.begin();
it != children.end(); ++it)
{
LLViewerObject *childp = *it;
addAttachmentPosOverridesForObject(childp);
}
LLVOVolume *vobj = dynamic_cast<LLVOVolume*>(vo);
bool pelvisGotSet = false;
if (!vobj)
{
return;
}
if (vobj->isMesh() &&
((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded()) || !gMeshRepo.meshRezEnabled()))
{
return;
}
LLUUID currentId = vobj->getVolume()->getParams().getSculptID();
const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( currentId, vobj );
if ( vobj && vobj->isAttachment() && vobj->isMesh() && pSkinData )
{
const int bindCnt = pSkinData->mAlternateBindMatrix.size();
if ( bindCnt > 0 )
{
const int jointCnt = pSkinData->mJointNames.size();
const F32 pelvisZOffset = pSkinData->mPelvisOffset;
const LLUUID& mesh_id = pSkinData->mMeshID;
bool fullRig = (jointCnt>=JOINT_COUNT_REQUIRED_FOR_FULLRIG) ? true : false;
if ( fullRig )
{
for ( int i=0; i<jointCnt; ++i )
{
std::string lookingForJoint = pSkinData->mJointNames[i].c_str();
LLJoint* pJoint = getJoint( lookingForJoint );
if ( pJoint && pJoint->getId() != currentId )
{
pJoint->setId( currentId );
const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation();
//Set the joint position
pJoint->addAttachmentPosOverride( jointPos, mesh_id, avString() );
//If joint is a pelvis then handle old/new pelvis to foot values
if ( lookingForJoint == "mPelvis" )
{
pelvisGotSet = true;
}
}
}
if (pelvisZOffset != 0.0F)
{
addPelvisFixup( pelvisZOffset, mesh_id );
pelvisGotSet = true;
}
}
}
}
//Rebuild body data if we altered joints/pelvis
if ( pelvisGotSet )
{
postPelvisSetRecalc();
}
}
//-----------------------------------------------------------------------------
// resetJointPositionsOnDetach
//-----------------------------------------------------------------------------
void LLVOAvatar::resetJointPositionsOnDetach(LLViewerObject *vo)
{
LLVOAvatar *av = vo->getAvatarAncestor();
if (!av || (av != this))
{
LL_WARNS("Avatar") << "called with invalid avatar" << LL_ENDL;
}
// Process all children
LLViewerObject::const_child_list_t& children = vo->getChildren();
for (LLViewerObject::const_child_list_t::const_iterator it = children.begin();
it != children.end(); ++it)
{
LLViewerObject *childp = *it;
resetJointPositionsOnDetach(childp);
}
// Process self.
LLUUID mesh_id;
if (getRiggedMeshID(vo,mesh_id))
{
resetJointPositionsOnDetach(mesh_id);
}
}
//-----------------------------------------------------------------------------
// resetJointPositionsOnDetach
//-----------------------------------------------------------------------------
void LLVOAvatar::resetJointPositionsOnDetach(const LLUUID& mesh_id)
{
//Subsequent joints are relative to pelvis
avatar_joint_list_t::iterator iter = mSkeleton.begin();
@ -5516,23 +5647,18 @@ void LLVOAvatar::resetJointPositionsToDefault( void )
{
LLJoint* pJoint = (*iter);
//Reset joints except for pelvis
if ( pJoint && pJoint != pJointPelvis && pJoint->doesJointNeedToBeReset() )
if ( pJoint )
{
pJoint->setId( LLUUID::null );
pJoint->restoreOldXform();
pJoint->removeAttachmentPosOverride(mesh_id, avString());
}
else
if ( pJoint && pJoint == pJointPelvis && pJoint->doesJointNeedToBeReset() )
if ( pJoint && pJoint == pJointPelvis)
{
pJoint->setId( LLUUID::null );
removePelvisFixup( mesh_id );
pJoint->setPosition( LLVector3( 0.0f, 0.0f, 0.0f) );
pJoint->setJointResetFlag( false );
}
}
//make sure we don't apply the joint offset
mHasPelvisOffset = false;
mPelvisFixup = mLastPelvisFixup;
postPelvisSetRecalc();
}
//-----------------------------------------------------------------------------
@ -6077,7 +6203,7 @@ const LLViewerJointAttachment *LLVOAvatar::attachObject(LLViewerObject *viewer_o
}
//-----------------------------------------------------------------------------
// attachObject()
// getNumAttachments()
//-----------------------------------------------------------------------------
U32 LLVOAvatar::getNumAttachments() const
{
@ -6187,30 +6313,18 @@ void LLVOAvatar::rebuildRiggedAttachments( void )
//-----------------------------------------------------------------------------
void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO )
{
//If a VO has a skin that we'll reset the joint positions to their default
if ( pVO && pVO->mDrawable )
LLUUID mesh_id;
if (getRiggedMeshID(pVO, mesh_id))
{
LLVOVolume* pVObj = pVO->mDrawable->getVOVolume();
if ( pVObj )
resetJointPositionsOnDetach(mesh_id);
if ( gAgentCamera.cameraCustomizeAvatar() )
{
const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( pVObj->getVolume()->getParams().getSculptID(), pVObj );
if (pSkinData
&& pSkinData->mJointNames.size() > JOINT_COUNT_REQUIRED_FOR_FULLRIG // full rig
&& pSkinData->mAlternateBindMatrix.size() > 0 )
{
LLVOAvatar::resetJointPositionsToDefault();
//Need to handle the repositioning of the cam, updating rig data etc during outfit editing
//This handles the case where we detach a replacement rig.
if ( gAgentCamera.cameraCustomizeAvatar() )
{
gAgent.unpauseAnimation();
//Still want to refocus on head bone
gAgentCamera.changeCameraToCustomizeAvatar();
}
}
}
}
gAgent.unpauseAnimation();
//Still want to refocus on head bone
gAgentCamera.changeCameraToCustomizeAvatar();
}
}
}
//-----------------------------------------------------------------------------
// detachObject()
@ -8228,6 +8342,39 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara
}
}
}
avatar_joint_list_t::iterator iter = mSkeleton.begin();
avatar_joint_list_t::iterator end = mSkeleton.end();
for (; iter != end; ++iter)
{
LLJoint* pJoint = (*iter);
const LLVector3& pos = pJoint->getPosition();
const LLVector3& scale = pJoint->getScale();
apr_file_printf( file, "\t\t<joint name=\"%s\" position=\"%f %f %f\" scale=\"%f %f %f\"/>\n",
pJoint->getName().c_str(), pos[0], pos[1], pos[2], scale[0], scale[1], scale[2]);
}
for (iter = mSkeleton.begin(); iter != end; ++iter)
{
LLJoint* pJoint = (*iter);
LLVector3 pos;
LLUUID mesh_id;
if (pJoint->hasAttachmentPosOverride(pos,mesh_id))
{
apr_file_printf( file, "\t\t<joint_offset name=\"%s\" position=\"%f %f %f\" mesh_id=\"%s\"/>\n",
pJoint->getName().c_str(), pos[0], pos[1], pos[2], mesh_id.asString().c_str());
}
}
F32 pelvis_fixup;
LLUUID mesh_id;
if (hasPelvisFixup(pelvis_fixup, mesh_id))
{
apr_file_printf( file, "\t\t<pelvis_fixup z=\"%f\" mesh_id=\"%s\"/>\n",
pelvis_fixup, mesh_id.asString().c_str());
}
apr_file_printf( file, "\t</archetype>\n" );
apr_file_printf( file, "\n</linden_genepool>\n" );
@ -8237,7 +8384,6 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara
// show the cloned params inside the wearables as well.
gAgentAvatarp->dumpWearableInfo(outfile);
}
outfile.close();
// <FS:CR> FIRE-8893 - Dump archetype xml to user defined location
LL_INFOS("DumpArchetypeXML") << "Archetype xml written successfully!" << LL_ENDL;
@ -8246,6 +8392,7 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara
LLNotificationsUtil::add("DumpArchetypeSuccess", args);
// </FS:CR>
}
// File will close when handle goes out of scope
}

View File

@ -207,7 +207,10 @@ public:
virtual LLJoint* getJoint(const std::string &name);
void resetJointPositionsToDefault( void );
void addAttachmentPosOverridesForObject(LLViewerObject *vo);
void resetJointPositionsOnDetach(const LLUUID& mesh_id);
void resetJointPositionsOnDetach(LLViewerObject *vo);
void clearAttachmentPosOverrides();
/*virtual*/ const LLUUID& getID() const;
/*virtual*/ void addDebugText(const std::string& text);
@ -375,19 +378,11 @@ protected:
/*virtual*/ LLAvatarJointMesh* createAvatarJointMesh(); // Returns LLViewerJointMesh
public:
void updateHeadOffset();
void setPelvisOffset( bool hasOffset, const LLVector3& translation, F32 offset ) ;
bool hasPelvisOffset( void ) { return mHasPelvisOffset; }
void postPelvisSetRecalc( void );
void setPelvisOffset( F32 pelvixFixupAmount );
/*virtual*/ BOOL loadSkeletonNode();
/*virtual*/ void buildCharacter();
bool mHasPelvisOffset;
LLVector3 mPelvisOffset;
F32 mLastPelvisToFoot;
F32 mPelvisFixup;
F32 mLastPelvisFixup;
LLVector3 mCurRootToHeadOffset;
LLVector3 mTargetRootToHeadOffset;
@ -739,6 +734,7 @@ public:
void clampAttachmentPositions();
virtual const LLViewerJointAttachment* attachObject(LLViewerObject *viewer_object);
virtual BOOL detachObject(LLViewerObject *viewer_object);
static bool getRiggedMeshID( LLViewerObject* pVO, LLUUID& mesh_id );
void cleanupAttachedMesh( LLViewerObject* pVO );
static LLVOAvatar* findAvatarFromAttachment(LLViewerObject* obj);
/*virtual*/ BOOL isWearingWearableType(LLWearableType::EType type ) const;

View File

@ -285,7 +285,7 @@ void LLVOAvatarSelf::markDead()
{
BOOL success = LLVOAvatar::loadAvatar();
// set all parameters sotred directly in the avatar to have
// set all parameters stored directly in the avatar to have
// the isSelfParam to be TRUE - this is used to prevent
// them from being animated or trigger accidental rebakes
// when we copy params from the wearable to the base avatar.
@ -888,13 +888,8 @@ void LLVOAvatarSelf::updateVisualParams()
LLVOAvatar::updateVisualParams();
}
/*virtual*/
void LLVOAvatarSelf::idleUpdateAppearanceAnimation()
void LLVOAvatarSelf::writeWearablesToAvatar()
{
// Animate all top-level wearable visual parameters
gAgentWearables.animateAllWearableParams(calcMorphAmount());
// apply wearable visual params to avatar
for (U32 type = 0; type < LLWearableType::WT_COUNT; type++)
{
LLWearable *wearable = gAgentWearables.getTopWearable((LLWearableType::EType)type);
@ -904,6 +899,17 @@ void LLVOAvatarSelf::idleUpdateAppearanceAnimation()
}
}
}
/*virtual*/
void LLVOAvatarSelf::idleUpdateAppearanceAnimation()
{
// Animate all top-level wearable visual parameters
gAgentWearables.animateAllWearableParams(calcMorphAmount());
// Apply wearable visual params to avatar
writeWearablesToAvatar();
//allow avatar to process updates
LLVOAvatar::idleUpdateAppearanceAnimation();
@ -1297,9 +1303,19 @@ LLViewerJointAttachment* LLVOAvatarSelf::getWornAttachmentPoint(const LLUUID& id
}
// [/RLVa:KB]
const std::string LLVOAvatarSelf::getAttachedPointName(const LLUUID& inv_item_id) const
bool LLVOAvatarSelf::getAttachedPointName(const LLUUID& inv_item_id, std::string& name) const
{
if (!gInventory.getItem(inv_item_id))
{
name = "ATTACHMENT_MISSING_ITEM";
return false;
}
const LLUUID& base_inv_item_id = gInventory.getLinkedItemID(inv_item_id);
if (!gInventory.getItem(base_inv_item_id))
{
name = "ATTACHMENT_MISSING_BASE_ITEM";
return false;
}
for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
iter != mAttachmentPoints.end();
++iter)
@ -1307,11 +1323,13 @@ const std::string LLVOAvatarSelf::getAttachedPointName(const LLUUID& inv_item_id
const LLViewerJointAttachment* attachment = iter->second;
if (attachment->getAttachedObject(base_inv_item_id))
{
return attachment->getName();
name = attachment->getName();
return true;
}
}
return LLStringUtil::null;
name = "ATTACHMENT_NOT_ATTACHED";
return false;
}
//virtual
@ -1419,8 +1437,6 @@ BOOL LLVOAvatarSelf::detachObject(LLViewerObject *viewer_object)
if ( LLVOAvatar::detachObject(viewer_object) )
{
LLVOAvatar::cleanupAttachedMesh( viewer_object );
// the simulator should automatically handle permission revocation
stopMotionFromSource(attachment_id);

View File

@ -87,12 +87,11 @@ public:
/*virtual*/ void requestStopMotion(LLMotion* motion);
/*virtual*/ LLJoint* getJoint(const std::string &name);
void resetJointPositions( void );
/*virtual*/ BOOL setVisualParamWeight(const LLVisualParam *which_param, F32 weight);
/*virtual*/ BOOL setVisualParamWeight(const char* param_name, F32 weight);
/*virtual*/ BOOL setVisualParamWeight(S32 index, F32 weight);
/*virtual*/ void updateVisualParams();
void writeWearablesToAvatar();
/*virtual*/ void idleUpdateAppearanceAnimation();
private:
@ -297,7 +296,7 @@ public:
// [RLVa:KB] - Checked: 2009-12-18 (RLVa-1.1.0i) | Added: RLVa-1.1.0i
LLViewerJointAttachment* getWornAttachmentPoint(const LLUUID& inv_item_id) const;
// [/RLVa:KB]
const std::string getAttachedPointName(const LLUUID& inv_item_id) const;
bool getAttachedPointName(const LLUUID& inv_item_id, std::string& name) const;
/*virtual*/ const LLViewerJointAttachment *attachObject(LLViewerObject *viewer_object);
/*virtual*/ BOOL detachObject(LLViewerObject *viewer_object);
static BOOL detachAttachmentIntoInventory(const LLUUID& item_id);

View File

@ -725,6 +725,8 @@ void LLVoiceChannelProximal::handleStatusChange(EStatusType status)
// do not notify user when leaving proximal channel
return;
case STATUS_VOICE_DISABLED:
LLVoiceClient::getInstance()->setUserPTTState(false);
gAgent.setVoiceConnected(false);
//skip showing "Voice not available at your current location" when agent voice is disabled (EXT-4749)
if(LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking())
{

View File

@ -831,7 +831,7 @@ void LLVivoxVoiceClient::stateMachine()
{
loglevel = "0"; // turn logging off completely
}
params.args.add("-ll");
params.args.add(loglevel);
@ -2516,6 +2516,14 @@ void LLVivoxVoiceClient::sendPositionalUpdate(void)
}
// </FS:Ansariel>
if (mHidden)
{
for (int i=0;i<3;++i)
{
pos.mdV[i] = VX_NULL_POSITION;
}
}
if (mHidden)
{
for (int i=0;i<3;++i)
@ -3283,7 +3291,7 @@ void LLVivoxVoiceClient::mediaStreamUpdatedEvent(
session->mErrorStatusCode = statusCode;
break;
}
switch(state)
{
case streamStateIdle:
@ -5559,7 +5567,8 @@ void LLVivoxVoiceClient::notifyStatusObservers(LLVoiceClientStatusObserver::ESta
// skipped to avoid speak button blinking
if ( status != LLVoiceClientStatusObserver::STATUS_JOINING
&& status != LLVoiceClientStatusObserver::STATUS_LEFT_CHANNEL)
&& status != LLVoiceClientStatusObserver::STATUS_LEFT_CHANNEL
&& status != LLVoiceClientStatusObserver::STATUS_VOICE_DISABLED)
{
// <FS:Ansariel> Bypass LLCachedControls for voice status update
//bool voice_status = LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking();

View File

@ -2102,7 +2102,18 @@ S32 LLVOVolume::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID)
S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams)
{
S32 res = LLViewerObject::setTEMaterialParams(te, pMaterialParams);
S32 res = 0;
if (pMaterialParams && getTEImage(te) && 3 == getTEImage(te)->getComponents() && pMaterialParams->getDiffuseAlphaMode())
{
LLViewerObject::setTEMaterialID(te, LLMaterialID::null);
res = LLViewerObject::setTEMaterialParams(te, NULL);
}
else
{
res = LLViewerObject::setTEMaterialParams(te, pMaterialParams);
}
LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterialParams) ? pMaterialParams->asLLSD() : LLSD("null")) << " res " << res
<< ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" )
<< LL_ENDL;
@ -4451,7 +4462,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
draw_info->mBump = bump;
draw_info->mShiny = shiny;
float alpha[4] =
static const float alpha[4] =
{
0.00f,
0.25f,
@ -4650,7 +4661,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
//Determine if we've received skininfo that contains an
//alternate bind matrix - if it does then apply the translational component
//to the joints of the avatar.
#if 0
bool pelvisGotSet = false;
#endif
{
LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_FACE_LIST);
@ -4757,53 +4770,12 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
//get drawpool of avatar with rigged face
LLDrawPoolAvatar* pool = get_avatar_drawpool(vobj);
// FIXME should this be inside the face loop?
// doesn't seem to depend on any per-face state.
if ( pAvatarVO )
{
LLUUID currentId = vobj->getVolume()->getParams().getSculptID();
const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( currentId, vobj );
if ( pSkinData )
{
const int bindCnt = pSkinData->mAlternateBindMatrix.size();
if ( bindCnt > 0 )
{
const int jointCnt = pSkinData->mJointNames.size();
const F32 pelvisZOffset = pSkinData->mPelvisOffset;
bool fullRig = (jointCnt>=JOINT_COUNT_REQUIRED_FOR_FULLRIG) ? true : false;
if ( fullRig )
{
for ( int i=0; i<jointCnt; ++i )
{
std::string lookingForJoint = pSkinData->mJointNames[i].c_str();
LLJoint* pJoint = pAvatarVO->getJoint( lookingForJoint );
if ( pJoint && pJoint->getId() != currentId )
{
pJoint->setId( currentId );
const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation();
//Set the joint position
pJoint->storeCurrentXform( jointPos );
//If joint is a pelvis then handle old/new pelvis to foot values
if ( lookingForJoint == "mPelvis" )
{
if ( !pAvatarVO->hasPelvisOffset() )
{
pAvatarVO->setPelvisOffset( true, jointPos, pelvisZOffset );
pelvisGotSet = true;
}
}
}
}
}
}
}
pAvatarVO->addAttachmentPosOverridesForObject(vobj);
}
//Rebuild body data if we altered joints/pelvis
if ( pelvisGotSet && pAvatarVO )
{
pAvatarVO->postPelvisSetRecalc();
}
// <FS:ND> need an texture entry, or we crash
// if (pool)
@ -5173,14 +5145,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
}
}
}
group->mBufferUsage = useage;
@ -5832,7 +5796,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
if (material_pass)
{
U32 pass[] =
static const U32 pass[] =
{
LLRenderPass::PASS_MATERIAL,
LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_MATERIAL_ALPHA,

View File

@ -371,8 +371,14 @@ void LLPanelAttachmentListItem::updateItem(const std::string& name,
LLViewerInventoryItem* inv_item = getItem();
if (inv_item && isAgentAvatarValid() && gAgentAvatarp->isWearingAttachment(inv_item->getLinkedUUID()))
{
std::string joint = LLTrans::getString(gAgentAvatarp->getAttachedPointName(inv_item->getLinkedUUID()));
title_joint = title_joint + " (" + joint + ")";
std::string found_name;
bool found = gAgentAvatarp->getAttachedPointName(inv_item->getLinkedUUID(),found_name);
std::string trans_name = LLTrans::getString(found_name);
if (!found)
{
LL_WARNS() << "invalid attachment joint, err " << found_name << LL_ENDL;
}
title_joint = title_joint + " (" + trans_name + ")";
}
LLPanelInventoryListItemBase::updateItem(title_joint, item_state);

View File

@ -44,7 +44,11 @@ std::string rlvGetItemName(const LLViewerInventoryItem* pItem)
if ( (pItem) && ((LLAssetType::AT_BODYPART == pItem->getType()) || (LLAssetType::AT_CLOTHING == pItem->getType())) )
return llformat("%s (%s)", pItem->getName().c_str(), LLWearableType::getTypeName(pItem->getWearableType()).c_str());
else if ( (pItem) && (LLAssetType::AT_OBJECT == pItem->getType()) && (isAgentAvatarValid()) )
return llformat("%s (%s)", pItem->getName().c_str(), gAgentAvatarp->getAttachedPointName(pItem->getUUID()).c_str());
{
std::string attachment_point_name;
gAgentAvatarp->getAttachedPointName(pItem->getUUID(), attachment_point_name);
return llformat("%s (%s)", pItem->getName().c_str(), attachment_point_name.c_str());
}
return (pItem) ? pItem->getName() : LLStringUtil::null;
}

View File

@ -4,10 +4,10 @@
legacy_header_height="18"
can_resize="true"
default_tab_group="1"
height="350"
height="370"
layout="topleft"
min_height="160"
min_width="280"
min_height="190"
min_width="285"
name="objectcontents"
help_topic="objectcontents"
save_rect="true"
@ -31,36 +31,81 @@
<panel_inventory_object
background_visible="false"
follows="all"
height="276"
height="240"
layout="topleft"
left="10"
name="object_contents"
top_pad="0"
width="284" />
<view_border
bevel_style="none"
follows="bottom|left"
height="50"
highlight_light_color="0.6 0.6 0.6"
layout="topleft"
left="10"
name="border"
top_pad="5"
width="270"/>
<text
follows="bottom|left"
height="15"
layout="topleft"
left="15"
name="border_note"
text_color="White"
top_delta="5">
Copy to inventory and wear
</text>
<button
follows="bottom|left"
height="23"
label="Add to outfit"
label_selected="Add to outfit"
layout="topleft"
left="15"
name="copy_and_wear_button"
top_pad="3"
width="135">
<button.commit_callback
function="OpenObject.MoveAndWear" />
</button>
<button
follows="bottom|left"
height="23"
label="Replace outfit"
label_selected="Replace outfit"
layout="topleft"
left_pad="5"
name="copy_and_replace_button"
width="120">
<button.commit_callback
function="OpenObject.ReplaceOutfit" />
</button>
<button
follows="bottom|left"
height="23"
label="Copy to inventory"
label_selected="Copy to inventory"
label="Only copy to inventory"
label_selected="Only copy to inventory"
layout="topleft"
left="15"
name="copy_to_inventory_button"
tab_group="1"
top_pad="5"
width="120">
top_pad="9"
width="135">
<button.commit_callback
function="OpenObject.MoveToInventory" />
</button>
<button
follows="bottom|left"
height="23"
label="Copy and add to outfit"
label_selected="Copy and add to outfit"
label="Cancel"
label_selected="Cancel"
layout="topleft"
left_pad="5"
name="copy_and_wear_button"
width="135">
name="cancel_button"
width="120">
<button.commit_callback
function="OpenObject.MoveAndWear" />
function="OpenObject.Cancel" />
</button>
</floater>

View File

@ -8,7 +8,7 @@
name="Give Money"
help_topic="give_money"
save_rect="true"
width="250">
width="261">
<string
name="payee_group">
Pay Group
@ -23,72 +23,111 @@
type="string"
length="1"
follows="left|top"
font="SansSerifSmall"
height="16"
layout="topleft"
left="10"
name="payee_name"
top="25"
use_ellipses="true"
width="230">
Test Name That Is Extremely Long To Check Clipping
top="24"
name="paying_text"
width="180">
You are paying:
</text>
<button
height="23"
label="L$1"
label_selected="L$1"
layout="topleft"
left="35"
name="fastpay 1"
top_pad="8"
width="80" />
<button
height="23"
label="L$5"
label_selected="L$5"
layout="topleft"
left_pad="15"
name="fastpay 5"
width="80" />
<button
height="23"
label="L$10"
label_selected="L$10"
layout="topleft"
left="35"
name="fastpay 10"
top_pad="8"
width="80" />
<button
height="23"
label="L$20"
label_selected="L$20"
layout="topleft"
left_pad="15"
name="fastpay 20"
width="80" />
<text
type="string"
length="1"
follows="left|top"
height="18"
font="SansSerifSmall"
height="16"
layout="topleft"
left="35"
name="amount text"
top_pad="8"
left="10"
top_pad="5"
name="payee_name"
use_ellipses="true"
width="180">
Or, choose amount:
Test Name That Is Extremely Long To Check Clipping
</text>
<line_editor
border_style="line"
follows="left|top|right"
height="19"
top_pad="0"
<panel
border_thickness="0"
height="104"
label="Search"
layout="topleft"
left="130"
max_length_bytes="9"
name="amount"
width="80" />
left="0"
top_pad="10"
help_topic="avatarpicker"
name="PatternsPanel"
width="120">
<button
height="23"
label="Pay L$ 1"
label_selected="Pay L$ 1"
layout="topleft"
left="10"
top="0"
name="fastpay 1"
width="110" />
<button
height="23"
label="Pay L$ 5"
label_selected="Pay L$ 5"
layout="topleft"
left="10"
top_pad="4"
name="fastpay 5"
width="110" />
<button
height="23"
label="Pay L$ 10"
label_selected="Pay L$ 10"
layout="topleft"
left="10"
top_pad="4"
name="fastpay 10"
width="110" />
<button
height="23"
label="Pay L$ 20"
label_selected="Pay L$ 20"
layout="topleft"
left="10"
top_pad="4"
name="fastpay 20"
width="110" />
</panel>
<view_border
bevel_style="in"
width="1"
height="104"
left_pad="10"
layout="topleft" />
<panel
border_thickness="0"
height="104"
label="Search"
layout="topleft"
left_pad="0"
name="InputPanel"
width="120">
<text
type="string"
length="1"
follows="left|top"
height="18"
layout="topleft"
left="10"
top="0"
name="amount text"
width="110">
Other amount:
</text>
<line_editor
border_style="line"
follows="left|top|right"
height="19"
layout="topleft"
left="10"
top_pad="0"
max_length_bytes="9"
name="amount"
width="90" />
<text
type="string"
follows="top|left"
@ -109,22 +148,24 @@
max_length_bytes="127"
name="payment_message"
width="175" />
<button
enabled="false"
height="23"
label="Pay"
label_selected="Pay"
layout="topleft"
left="20"
name="pay btn"
top_pad="15"
width="100" />
<button
height="23"
label="Cancel"
label_selected="Cancel"
layout="topleft"
left_pad="10"
name="cancel btn"
width="100" />
<button
enabled="false"
height="23"
label="Pay"
label_selected="Pay"
layout="topleft"
left="10"
top_pad="17"
name="pay btn"
width="110" />
<button
height="23"
label="Cancel"
label_selected="Cancel"
layout="topleft"
left="10"
top_pad="4"
name="cancel btn"
width="110" />
</panel>
</floater>

View File

@ -3,12 +3,12 @@
positioning="centered"
legacy_header_height="18"
can_minimize="false"
height="225"
height="228"
layout="topleft"
name="Give Money"
help_topic="give_money"
save_rect="true"
width="250">
width="261">
<string
name="payee_group">
Pay Group
@ -17,13 +17,26 @@
name="payee_resident">
Pay Resident
</string>
<text
type="string"
length="1"
follows="left|top"
height="16"
layout="topleft"
left="10"
top="24"
name="paying_text"
width="180">
You are paying:
</text>
<text
icon_positioning="left"
follows="left|top"
height="16"
layout="topleft"
left="10"
top_pad="24"
top_pad="5"
name="payee_name"
use_ellipses="true"
width="225">
@ -42,7 +55,7 @@
width="180">
Via object:
</text>
<icon
<icon
height="16"
width="16"
image_name="Inv_Object"
@ -66,78 +79,107 @@
width="188">
My awesome object with a really damn long name
</text>
<button
height="23"
label="L$1"
label_selected="L$1"
<panel
border_thickness="0"
height="104"
label="Search"
layout="topleft"
left="25"
name="fastpay 1"
top_pad="8"
width="80" />
<button
height="23"
label="L$5"
label_selected="L$5"
left="0"
top_pad="10"
help_topic="avatarpicker"
name="PatternsPanel"
width="120">
<button
height="23"
label="Pay L$ 1"
label_selected="Pay L$ 1"
layout="topleft"
left="10"
top="0"
name="fastpay 1"
width="110" />
<button
height="23"
label="Pay L$ 5"
label_selected="Pay L$ 5"
layout="topleft"
left="10"
top_pad="4"
name="fastpay 5"
width="110" />
<button
height="23"
label="Pay L$ 10"
label_selected="Pay L$ 10"
layout="topleft"
left="10"
top_pad="4"
name="fastpay 10"
width="110" />
<button
height="23"
label="Pay L$ 20"
label_selected="Pay L$ 20"
layout="topleft"
left="10"
top_pad="4"
name="fastpay 20"
width="110" />
</panel>
<view_border
bevel_style="in"
width="1"
height="104"
left_pad="10"
layout="topleft" />
<panel
border_thickness="0"
height="104"
label="Search"
layout="topleft"
left_pad="15"
name="fastpay 5"
width="80" />
<button
height="23"
label="L$10"
label_selected="L$10"
layout="topleft"
left="25"
name="fastpay 10"
top_pad="8"
width="80" />
<button
height="23"
label="L$20"
label_selected="L$20"
layout="topleft"
left_pad="15"
name="fastpay 20"
width="80" />
<text
type="string"
length="1"
follows="left|top"
height="14"
layout="topleft"
left="25"
name="amount text"
top_pad="8"
width="180">
Or, choose amount:
</text>
<line_editor
border_style="line"
follows="left|top|right"
height="21"
top_pad="0"
layout="topleft"
left="120"
max_length_bytes="9"
name="amount"
width="80" />
<button
enabled="false"
height="23"
label="Pay"
label_selected="Pay"
layout="topleft"
left="10"
name="pay btn"
top_pad="5"
width="100" />
<button
height="23"
label="Cancel"
label_selected="Cancel"
layout="topleft"
left_pad="5"
name="cancel btn"
width="100" />
left_pad="0"
name="InputPanel"
width="120">
<text
type="string"
length="1"
follows="left|top"
height="18"
layout="topleft"
left="10"
top="0"
name="amount text"
width="180">
Other amount:
</text>
<line_editor
border_style="line"
follows="left|top|right"
height="19"
layout="topleft"
left="10"
top_pad="0"
max_length_bytes="9"
name="amount"
width="90" />
<button
enabled="false"
height="23"
label="Pay"
label_selected="Pay"
layout="topleft"
left="10"
top_pad="17"
name="pay btn"
width="110" />
<button
height="23"
label="Cancel"
label_selected="Cancel"
layout="topleft"
left="10"
top_pad="4"
name="cancel btn"
width="110" />
</panel>
</floater>

View File

@ -3130,6 +3130,18 @@
function="Floater.Toggle"
parameter="notifications_console" />
</menu_item_call>
<menu_item_check
label="Region Debug Console"
name="Region Debug Console"
shortcut="control|shift|`"
use_mac_ctrl="true">
<menu_item_check.on_check
function="Floater.Visible"
parameter="region_debug_console" />
<menu_item_check.on_click
function="Floater.Toggle"
parameter="region_debug_console" />
</menu_item_check>
<menu_item_check
label="Fast Timers"
name="Fast Timers"

View File

@ -5464,6 +5464,19 @@ Warning: The &apos;Pay object&apos; click action has been set, but it will only
</form>
</notification>
<notification
icon="alertmodal.tga"
name="PayConfirmation"
type="alertmodal">
Confirm that you want to pay L$[AMOUNT] to [TARGET].
<tag>confirm</tag>
<usetemplate
ignoretext="Confirm before paying (sums over L$200)"
name="okcancelignore"
notext="Cancel"
yestext="Pay"/>
</notification>
<notification
icon="alertmodal.tga"
name="OpenObjectCannotCopy"

View File

@ -726,6 +726,7 @@ The [[MARKETPLACE_CREATE_STORE_URL] Marketplace store] is returning errors.
<string name="LoadingContents">Loading contents...</string>
<string name="NoContents">No contents</string>
<string name="WornOnAttachmentPoint" value=" (worn on [ATTACHMENT_POINT])" />
<string name="AttachmentErrorMessage" value=" ([ATTACHMENT_ERROR])" />
<string name="ActiveGesture" value="[GESLABEL] (active)"/>
<!-- Inventory permissions -->
<string name="PermYes">Yes</string>
@ -857,9 +858,12 @@ The [[MARKETPLACE_CREATE_STORE_URL] Marketplace store] is returning errors.
<string name="Left Pec">Left Pec</string>
<string name="Right Pec">Right Pec</string>
<string name="Bridge">Bridge</string>
<string name="Neck">Neck</string>
<string name="Avatar Center">Avatar Center</string>
<string name="Neck">Neck</string>
<string name="Avatar Center">Avatar Center</string>
<string name="Invalid Attachment">Invalid Attachment Point</string>
<string name="ATTACHMENT_MISSING_ITEM">Error: missing item</string>
<string name="ATTACHMENT_MISSING_BASE_ITEM">Error: missing base item</string>
<string name="ATTACHMENT_NOT_ATTACHED">Error: object is in current outfit but not attached</string>
<!-- Avatar age computation, see LLDateUtil::ageFromDate -->
<string name="YearsMonthsOld">[AGEYEARS] [AGEMONTHS]</string>