diff options
82 files changed, 1569 insertions, 605 deletions
| @@ -495,3 +495,5 @@ 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 +d3d0101e980ec95043e0af9b7903045d3bc447e4 3.7.24-release diff --git a/doc/contributions.txt b/doc/contributions.txt index 901ac1fb78..b55f2179b9 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -1059,10 +1059,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 diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index 6fdf9e2e07..d1eb389013 100755 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -584,8 +584,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 ); @@ -677,6 +675,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. diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h index 1e898026c0..a0ef49b7cb 100755 --- a/indra/llappearance/llavatarappearance.h +++ b/indra/llappearance/llavatarappearance.h @@ -152,11 +152,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: diff --git a/indra/llappearance/llpolyskeletaldistortion.cpp b/indra/llappearance/llpolyskeletaldistortion.cpp index ea29cbd451..fbc312c426 100644 --- a/indra/llappearance/llpolyskeletaldistortion.cpp +++ b/indra/llappearance/llpolyskeletaldistortion.cpp @@ -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);          } diff --git a/indra/llcharacter/lljoint.cpp b/indra/llcharacter/lljoint.cpp index dbd6d48a95..6f22a7c6b7 100755 --- a/indra/llcharacter/lljoint.cpp +++ b/indra/llcharacter/lljoint.cpp @@ -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);  } +void showJointPosOverrides( const LLJoint& joint, const std::string& note, const std::string& av_info ) +{ +        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; +}  //-------------------------------------------------------------------- -// setPosition() +// addAttachmentPosOverride()  //-------------------------------------------------------------------- -void LLJoint::setDefaultFromCurrentXform( void ) -{		 -	mDefaultXform = mXform; +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);  }  //-------------------------------------------------------------------- -// storeCurrentXform() +// removeAttachmentPosOverride()  //-------------------------------------------------------------------- -void LLJoint::storeCurrentXform( const LLVector3& pos ) -{	 -	mOldXform = mXform; -	mResetAfterRestoreOldXform = true;	 -	setPosition( pos ); -	touch(ALL_DIRTY);	 +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); +	} +  }  //-------------------------------------------------------------------- -// storeScaleForReset() + // hasAttachmentPosOverride() + //-------------------------------------------------------------------- +bool LLJoint::hasAttachmentPosOverride( LLVector3& pos, LLUUID& mesh_id ) const +{ +	return m_attachmentOverrides.findActiveOverride(mesh_id,pos); +} + +//-------------------------------------------------------------------- +// clearAttachmentPosOverrides()  //-------------------------------------------------------------------- -void LLJoint::storeScaleForReset( const LLVector3& scale ) +void LLJoint::clearAttachmentPosOverrides()  { -	mOldXform.setScale( scale ); +	if (m_attachmentOverrides.count()) +	{ +		m_attachmentOverrides.clear(); +		setPosition(m_posBeforeOverrides); +		setId( LLUUID::null ); +	}  } +  //-------------------------------------------------------------------- -// restoreOldXform() +// updatePos()  //-------------------------------------------------------------------- -void LLJoint::restoreOldXform( void ) -{	 -	mXform = mDefaultXform; -	mResetAfterRestoreOldXform = false; -	mDirtyFlags = ALL_DIRTY;	 +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 diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h index b65d6979d4..2abe1d6db1 100755 --- a/indra/llcharacter/lljoint.h +++ b/indra/llcharacter/lljoint.h @@ -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 diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp index a6df3ad5b2..b9632a7921 100755 --- a/indra/llcorehttp/_httpoprequest.cpp +++ b/indra/llcorehttp/_httpoprequest.cpp @@ -631,8 +631,23 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)  		// a handwave but bump the transfer timeout up by the pipelining  		// depth to give some room.  		// +		// BUG-7698, BUG-7688, BUG-7694 (others).  Scylla and Charybdis +		// situation.  Operating against a CDN having service issues may +		// lead to requests stalling for an arbitrarily long time with only +		// the CURLOPT_TIMEOUT value leading to a closed connection.  Sadly +		// for pipelining, libcurl (7.39.0 and earlier, at minimum) starts +		// the clock on this value as soon as a request is started down +		// the wire.  We want a short value to recover and retry from the +		// CDN.  We need a long value to safely deal with a succession of +		// piled-up pipelined requests. +		//  		// *TODO:  Find a better scheme than timeouts to guarantee liveness. -		xfer_timeout *= cpolicy.mPipelining; +		// Progress on the connection is what we really want, not timeouts. +		// But we don't have access to that and the request progress indicators +		// (various libcurl callbacks) have the same problem TIMEOUT does. +		// +		// xfer_timeout *= cpolicy.mPipelining; +		xfer_timeout *= 2L;  	}  	// *DEBUG:  Enable following override for timeout handling and "[curl:bugs] #1420" tests  	// xfer_timeout = 1L; diff --git a/indra/llmath/llquaternion.h b/indra/llmath/llquaternion.h index e56929ed0f..aa0b1752f4 100755 --- a/indra/llmath/llquaternion.h +++ b/indra/llmath/llquaternion.h @@ -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)  { diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index b19df0200d..aa8dd7697c 100755 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -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))  			{ diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 388d3a4f1a..0af402efea 100755 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -1168,7 +1168,7 @@ void LLRender::syncMatrices()  {  	stop_glerror(); -	U32 name[] =  +	static const U32 name[] =   	{  		LLShaderMgr::MODELVIEW_MATRIX,  		LLShaderMgr::PROJECTION_MATRIX, diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp index ffbc02fd08..747b472ac2 100644 --- a/indra/llui/llfolderviewitem.cpp +++ b/indra/llui/llfolderviewitem.cpp @@ -258,20 +258,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 - -	LLFolderViewModelItem* model = getViewModelItem(); -	if (model->getLastFilterGeneration() < 0 && !getFolderViewModel()->getFilter().isModified()) +	if (filter_generation < 0)  	{ -		return model->descendantsPassedFilter(filter_generation) || getVisible(); +		filter_generation = getFolderViewModel()->getFilter().getFirstSuccessGeneration();  	} -	else +	LLFolderViewModelItem* model = getViewModelItem(); +	BOOL visible = model->passedFilter(filter_generation); +	if (model->getMarkedDirtyGeneration() >= filter_generation)  	{ -		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() diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h index 8d98363c5f..f6550eae42 100755 --- a/indra/llui/llfolderviewmodel.h +++ b/indra/llui/llfolderviewmodel.h @@ -185,11 +185,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; @@ -230,6 +232,7 @@ public:  		mFolderViewItem(NULL),  		mLastFilterGeneration(-1),  		mLastFolderFilterGeneration(-1), +		mMarkedDirtyGeneration(-1),  		mMostFilteredDescendantGeneration(-1),  		mParent(NULL),  		mRootViewModel(root_view_model) @@ -243,8 +246,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; @@ -254,6 +262,14 @@ public:  			mParent->dirtyFilter();  		}	  	} +	void dirtyDescendantsFilter() +	{ +		mMostFilteredDescendantGeneration = -1; +		if (mParent) +		{ +			mParent->dirtyDescendantsFilter(); +		} +	}  	bool hasFilterStringMatch();  	std::string::size_type getFilterStringOffset();  	std::string::size_type getFilterStringSize(); @@ -272,7 +288,7 @@ public:  				return;  			}  		} -		mChildren.push_back(child);  +		mChildren.push_back(child);  		child->setParent(this);   		dirtyFilter();  		requestSort(); @@ -280,7 +296,8 @@ public:  	virtual void removeChild(LLFolderViewModelItem* child)   	{   		mChildren.remove(child);  -		child->setParent(NULL);  +		child->setParent(NULL); +		dirtyDescendantsFilter();  		dirtyFilter();  	} @@ -290,6 +307,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();  	} @@ -303,6 +321,7 @@ public:  		mLastFilterGeneration = filter_generation;  		mStringMatchOffsetFilter = string_offset;  		mStringFilterSize = string_size; +		mMarkedDirtyGeneration = -1;  	}  	void setPassedFolderFilter(bool passed, S32 filter_generation) @@ -351,7 +370,8 @@ protected:  	S32							mLastFilterGeneration,  								mLastFolderFilterGeneration, -								mMostFilteredDescendantGeneration; +								mMostFilteredDescendantGeneration, +								mMarkedDirtyGeneration;  	child_list_t				mChildren;  	LLFolderViewModelItem*		mParent; diff --git a/indra/llui/llkeywords.cpp b/indra/llui/llkeywords.cpp index 75773d7dfd..6750ee482a 100755 --- a/indra/llui/llkeywords.cpp +++ b/indra/llui/llkeywords.cpp @@ -505,7 +505,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW  			}  			// Skip white space -			while( *cur && isspace(*cur) && (*cur != '\n')  ) +			while( *cur && iswspace(*cur) && (*cur != '\n')  )  			{  				cur++;  			} @@ -548,7 +548,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW  		}  		// Skip white space -		while( *cur && isspace(*cur) && (*cur != '\n')  ) +		while( *cur && iswspace(*cur) && (*cur != '\n')  )  		{  			cur++;  		} @@ -655,10 +655,10 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW  			// check against words  			llwchar prev = cur > base ? *(cur-1) : 0; -			if( !isalnum( prev ) && (prev != '_') ) +			if( !iswalnum( prev ) && (prev != '_') )  			{  				const llwchar* p = cur; -				while( isalnum( *p ) || (*p == '_') ) +				while( iswalnum( *p ) || (*p == '_') )  				{  					p++;  				} diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 6b0acb5fb4..e5081ee1d5 100755 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -1269,7 +1269,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 ) @@ -3251,6 +3259,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);  } diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp index a972b65f4a..35f5330a3f 100755 --- a/indra/llui/llstatbar.cpp +++ b/indra/llui/llstatbar.cpp @@ -638,7 +638,7 @@ void LLStatBar::drawLabelAndValue( F32 value, std::string &label, LLRect &bar_re  void LLStatBar::drawTicks( F32 min, F32 max, F32 value_scale, LLRect &bar_rect )  { -	if (mAutoScaleMax || mAutoScaleMin) +	if (!llisnan(min) && (mAutoScaleMax || mAutoScaleMin))  	{  		F32 u = LLSmoothInterpolation::getInterpolant(10.f);  		mFloatingTargetMinBar = llmin(min, lerp(mFloatingTargetMinBar, min, u)); diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 9c470b5cca..c058ad6f7d 100755 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -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); diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index d4684e2e1e..ffcd45dfde 100755 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -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; diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index bccc646821..ef0789e0e4 100755 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -45,7 +45,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()); @@ -64,7 +65,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());	 @@ -128,6 +130,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;  } @@ -175,6 +182,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; diff --git a/indra/llui/llurlregistry.h b/indra/llui/llurlregistry.h index 6270df1bbb..1cb403dfc9 100755 --- a/indra/llui/llurlregistry.h +++ b/indra/llui/llurlregistry.h @@ -94,6 +94,8 @@ private:  	std::vector<LLUrlEntryBase *> mUrlEntry;  	LLUrlEntryBase*	mUrlEntryIcon; +	LLUrlEntryBase* mUrlEntryHTTPLabel; +	LLUrlEntryBase* mUrlEntrySLLabel;  };  #endif diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index bdab4331e9..a8beb9cfc9 100755 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -885,7 +885,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;  			}  		}  	} diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm index 773c093e2f..959dbc1040 100644 --- a/indra/llwindow/llopenglview-objc.mm +++ b/indra/llwindow/llopenglview-objc.mm @@ -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]; @@ -349,9 +367,14 @@ attributedStringInfo getSegments(NSAttributedString *str)  	callMiddleMouseUp(mMousePos, [theEvent modifierFlags]);  } +- (void) rightMouseDragged:(NSEvent *)theEvent +{ +	[self mouseDragged:theEvent]; +} +  - (void) otherMouseDragged:(NSEvent *)theEvent  { -	 +	[self mouseDragged:theEvent];          }  - (void) scrollWheel:(NSEvent *)theEvent diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h index d64525fbdd..f02052ca6a 100755 --- a/indra/llwindow/llwindowmacosx-objc.h +++ b/indra/llwindow/llwindowmacosx-objc.h @@ -116,6 +116,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); diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index e50999dc36..b2f1d618ef 100755 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -346,6 +346,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); diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index a4de059bbc..c282746153 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -3.7.23 +3.7.25 diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index f2fb9e854f..94d3c8a59f 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -6171,7 +6171,7 @@          <key>Type</key>              <string>F32</string>          <key>Value</key> -    <real>30.0</real> +            <real>600.0</real>          </map>      <key>MemoryPrivatePoolEnabled</key>      <map> @@ -13554,6 +13554,28 @@        <key>Value</key>        <string>0</string>      </map> +    <key>VivoxLogDirectory</key> +    <map> +        <key>Comment</key> +        <string>Default log path is Application Support/SecondLife/logs specify alternate absolute path here.</string> +        <key>Persist</key> +        <integer>1</integer> +        <key>Type</key> +        <string>String</string> +        <key>Value</key> +        <string></string> +    </map> +    <key>VivoxShutdownTimeout</key> +    <map> +      <key>Comment</key> +      <string>shutdown timeout in miliseconds.  The amount of time to wait for the service to shutdown gracefully after the last disconnect</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>String</string> +      <key>Value</key> +      <string>5</string> +    </map>      <key>VivoxDebugSIPURIHostName</key>      <map>        <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl index b40785bbd7..506118d381 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl @@ -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; diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index cd01ea1868..f151b15e29 100755 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -3804,6 +3804,10 @@ void LLAgent::restartFailedTeleportRequest()  void LLAgent::clearTeleportRequest()  { +    if(LLVoiceClient::instanceExists()) +    { +        LLVoiceClient::getInstance()->setHidden(FALSE); +    }  	mTeleportRequest.reset();  } @@ -3822,6 +3826,10 @@ bool LLAgent::hasPendingTeleportRequest()  void LLAgent::startTeleportRequest()  { +    if(LLVoiceClient::instanceExists()) +    { +        LLVoiceClient::getInstance()->setHidden(TRUE); +    }  	if (hasPendingTeleportRequest())  	{  		if  (!isMaturityPreferenceSyncedWithServer()) @@ -3867,6 +3875,11 @@ void LLAgent::handleTeleportFinished()  void LLAgent::handleTeleportFailed()  { +    if(LLVoiceClient::instanceExists()) +    { +        LLVoiceClient::getInstance()->setHidden(FALSE); +    } +  	if (mTeleportRequest != NULL)  	{  		mTeleportRequest->setStatus(LLTeleportRequest::kFailed); @@ -4112,8 +4125,8 @@ void LLAgent::stopCurrentAnimations()  		      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 diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 49fedb8df8..f06ffb4fb3 100755 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -1009,6 +1009,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())  		{ @@ -1019,6 +1023,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it  			mismatched++;  			continue;  		} +#endif  		// If we got here, everything matches.  		matched++;  	} @@ -1083,7 +1088,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 @@ -1101,6 +1105,12 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it  	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; @@ -1243,9 +1253,12 @@ void LLAgentWearables::userRemoveWearablesOfType(const LLWearableType::EType &ty  	}  } -// 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. @@ -1264,7 +1277,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();)  	{ @@ -1299,12 +1311,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) @@ -1323,12 +1335,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) @@ -1348,6 +1354,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());  	} diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index cdb1bdbe05..1004482020 100755 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -178,7 +178,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); diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index 96de15bf75..9d887a61f1 100755 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -34,6 +34,7 @@  #include "llsdutil.h"  #include "llviewerregion.h"  #include "llinventoryobserver.h" +#include "llviewercontrol.h"  ///----------------------------------------------------------------------------  /// Classes for AISv3 support. diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm index aad5dbae7d..549df80fa1 100644..100755 --- a/indra/newview/llappdelegate-objc.mm +++ b/indra/newview/llappdelegate-objc.mm @@ -84,7 +84,17 @@  	callWindowUnfocus();  } -- (NSApplicationTerminateReply) applicationShouldTerminate:(NSApplication *)sender +- (void) applicationDidHide:(NSNotification *)notification +{ +	callWindowHide(); +} + +- (void) applicationDidUnhide:(NSNotification *)notification +{ +	callWindowUnhide(); +} + +- (NSApplicationDelegateReply) applicationShouldTerminate:(NSApplication *)sender  {  	if (!runMainLoop())  	{ diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index b3b8a40d39..a64d5b50b3 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -807,15 +807,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()) @@ -2699,7 +2732,12 @@ void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, LLPointer<LLInve  		const LLInventoryItem* 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);  		}  	}  } @@ -4056,17 +4094,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 diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index c1234edfeb..4bf719ec31 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -4898,7 +4898,10 @@ void LLAppViewer::idle()  	// Handle the regular UI idle callbacks as well as  	// hover callbacks  	// - +     +#ifdef LL_DARWIN +	if (!mQuitRequested)  //MAINT-4243 +#endif  	{  // 		LL_RECORD_BLOCK_TIME(FTM_IDLE_CB); diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 5b151bdcda..f74164aea6 100755 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -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)  	{ diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index 3bde0d29be..bc299cc89f 100755 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -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); diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index ef121cd910..e1d3d1a905 100755 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -373,7 +373,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 diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp index 514411aef5..f92320490a 100644 --- a/indra/newview/lldrawpoolmaterials.cpp +++ b/indra/newview/lldrawpoolmaterials.cpp @@ -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, diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index fbdaca0e6f..2864f018b2 100755 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -47,7 +47,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), diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index ab702c3645..ec905558aa 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -1929,7 +1929,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  										{ @@ -3236,7 +3238,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; diff --git a/indra/newview/llfloateropenobject.cpp b/indra/newview/llfloateropenobject.cpp index 9986bdbd7f..ef746d308d 100755 --- a/indra/newview/llfloateropenobject.cpp +++ b/indra/newview/llfloateropenobject.cpp @@ -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(); +} diff --git a/indra/newview/llfloateropenobject.h b/indra/newview/llfloateropenobject.h index 8e472804a4..2e761f99bf 100755 --- a/indra/newview/llfloateropenobject.h +++ b/indra/newview/llfloateropenobject.h @@ -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: diff --git a/indra/newview/llfloaterpay.cpp b/indra/newview/llfloaterpay.cpp index 099a8828a4..172f81d078 100755 --- a/indra/newview/llfloaterpay.cpp +++ b/indra/newview/llfloaterpay.cpp @@ -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,13 +116,11 @@ protected:  	LLGiveMoneyInfo* mQuickPayInfo[MAX_PAY_BUTTONS];  	LLSafeHandle<LLObjectSelection> mObjectSelection; - -	static S32 sLastAmount;  }; -S32 LLFloaterPay::sLastAmount = 0;  const S32 FASTPAY_BUTTON_WIDTH = 80; +const S32 PAY_AMOUNT_NOTIFICATION = 200;  LLFloaterPay::LLFloaterPay(const LLSD& key)  	: LLFloater(key), @@ -187,17 +190,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); @@ -206,7 +201,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); @@ -418,7 +413,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; @@ -469,10 +481,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(); +		}  	}  } @@ -486,7 +528,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()) diff --git a/indra/newview/llfloaterwebcontent.cpp b/indra/newview/llfloaterwebcontent.cpp index 3f3d87b564..024e315632 100755 --- a/indra/newview/llfloaterwebcontent.cpp +++ b/indra/newview/llfloaterwebcontent.cpp @@ -293,6 +293,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)      { @@ -302,7 +303,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()) @@ -311,7 +313,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()) diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp index 7615c12043..3271a40ea0 100755 --- a/indra/newview/llfolderviewmodelinventory.cpp +++ b/indra/newview/llfolderviewmodelinventory.cpp @@ -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(); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 33e557cddd..1910656066 100755 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -87,6 +87,8 @@ void copy_slurl_to_clipboard_callback_inv(const std::string& slurl);  typedef std::pair<LLUUID, LLUUID> two_uuids_t;  typedef std::list<two_uuids_t> two_uuids_list_t; +const F32 SOUND_GAIN = 1.0f; +  struct LLMoveInv  {  	LLUUID mObjectID; @@ -2785,8 +2787,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); @@ -2794,6 +2796,7 @@ protected:  	LLUUID mCatID;  	int    mContentsCount;  	bool   mFolderAdded; +	bool   mReplace;  }; @@ -2832,7 +2835,7 @@ void LLInventoryCopyAndWearObserver::changed(U32 mask)  				    mContentsCount)  				{  					gInventory.removeObserver(this); -					LLAppearanceMgr::instance().wearInventoryCategory(category, FALSE, TRUE); +					LLAppearanceMgr::instance().wearInventoryCategory(category, FALSE, !mReplace);  					delete this;  				}  			} @@ -3779,24 +3782,21 @@ void LLFolderBridge::modifyOutfit(BOOL append)  	// 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); - -		if (items.size() > max_items) -		{ -			LLSD args; -			args["AMOUNT"] = llformat("%d", max_items); -			LLNotificationsUtil::add("TooManyWearables", args); -			return; -		} +	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;  	}  	LLAppearanceMgr::instance().wearInventoryCategory( cat, FALSE, append ); @@ -3816,7 +3816,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);  		} @@ -4526,6 +4527,23 @@ void LLSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  	hide_context_entries(menu, items, disabled_items);  } +void LLSoundBridge::performAction(LLInventoryModel* model, std::string action) +{ +	if ("sound_play" == action) +	{ +		LLViewerInventoryItem* item = getItem(); +		if(item) +		{ +			send_sound_trigger(item->getAssetUUID(), SOUND_GAIN); +		} +	} +	else if ("open" == action) +	{ +		openSoundPreview((void*)this); +	} +	else LLItemBridge::performAction(model, action); +} +  // +=================================================+  // |        LLLandmarkBridge                         |  // +=================================================+ @@ -5326,16 +5344,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();  } @@ -6138,7 +6160,7 @@ public:  		LLViewerInventoryItem* item = getItem();  		if (item)  		{ -			LLFloaterReg::showInstance("preview_sound", LLSD(mUUID), TAKE_FOCUS_YES); +			send_sound_trigger(item->getAssetUUID(), SOUND_GAIN);  		}  		LLInvFVBridgeAction::doIt();  	} diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 2b27ff1862..f8ef15991d 100755 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -390,6 +390,7 @@ public:  		LLItemBridge(inventory, root, uuid) {}  	virtual void openItem();  	virtual void buildContextMenu(LLMenuGL& menu, U32 flags); +	virtual void performAction(LLInventoryModel* model, std::string action);  	static void openSoundPreview(void*);  }; diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index 9f06c4d601..c66e9da4a9 100755 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -126,13 +126,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  	const BOOL passed_clipboard = checkAgainstClipboard(folder_id); @@ -142,6 +135,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) diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index e18ecd2e2a..3546317471 100755 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -542,12 +542,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)  						{ @@ -573,6 +574,7 @@ void LLInventoryPanel::modelChanged(U32 mask)  							// doesn't include trash).  Just remove the item's UI.  							view_item->destroyView();  						} +						old_parent->getViewModelItem()->dirtyDescendantsFilter();  					}  				}  			} @@ -583,27 +585,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() diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index de2d315480..cc8b7d2a52 100755 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -1846,6 +1846,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);  } diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index a5063de0f4..37273a7793 100755 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -153,7 +153,9 @@ BOOL LLPanelMainInventory::postBuild()  		recent_items_panel->setSinceLogoff(TRUE);  		recent_items_panel->setSortOrder(LLInventoryFilter::SO_DATE);  		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));  	} @@ -853,9 +855,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);  	} diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index 6b74d90708..6354b5a02b 100755 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -698,6 +698,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())  	{ diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 45447b742b..5415c273e2 100755 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -660,12 +660,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; @@ -676,7 +677,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;  		} @@ -705,6 +707,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(); diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h index 515f277c4a..66727bceee 100755 --- a/indra/newview/llpreviewscript.h +++ b/indra/newview/llpreviewscript.h @@ -133,6 +133,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); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 0a8257f42b..5e342099d7 100755 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -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, diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp index 89302c3c64..e80756e4de 100755 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -544,10 +544,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 diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index eebed63ef2..3e5b91c8fc 100755 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -112,7 +112,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); @@ -226,7 +226,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)  	{ @@ -247,6 +247,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);  		}  	} @@ -455,7 +459,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"); @@ -814,7 +821,7 @@ void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem  			{  				mNoCopyTextureSelected = TRUE;  			} -			setImageID(itemp->getAssetUUID()); +			setImageID(itemp->getAssetUUID(),false);  			mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?  			if (user_action && mCanPreview)  			{ diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 75620be69a..e8f6c35662 100755 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -2172,23 +2172,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) -		{ -			LLStringUtil::format_map_t args; -			args["AMOUNT"] = llformat("%d", max_items); -			mCustomMsg = LLTrans::getString("TooltipTooManyWearables",args); -			return ACCEPT_NO_CUSTOM; -		} +	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;  	}  	if(mSource == SOURCE_AGENT) diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index d364fce45a..d6c8ba10f6 100755 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -1456,7 +1456,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(); @@ -1468,12 +1469,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  	{ @@ -1483,7 +1485,8 @@ void remove_inventory_item(  void remove_inventory_item(  	LLPointer<LLInventoryObject> obj, -	LLPointer<LLInventoryCallback> cb) +	LLPointer<LLInventoryCallback> cb, +	bool immediate_delete)  {  	if(obj)  	{ @@ -1493,6 +1496,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  		{ diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index d345c49cfb..ca92565600 100755 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -394,11 +394,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, diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index 0a9bc2a56c..9b8c913c6b 100755 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -87,18 +87,25 @@ void agent_push_down( EKeystate s )  	gAgent.moveUp(-1);  } +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()); +	} +} +  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()); -		} +		// 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 && @@ -217,7 +224,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 ) );  	} @@ -240,7 +252,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 ) );  	} diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 4f992fc184..820249e181 100755 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -359,10 +359,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; @@ -2274,7 +2281,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) @@ -5006,6 +5013,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(); @@ -6193,6 +6216,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  { diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index bab107cc57..05c87c153b 100755 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -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; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 7bf90ef79e..6bfa522822 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -700,7 +700,6 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,  	mVisualComplexity(0),  	mVisualComplexityStale(TRUE),  	mLoadedCallbacksPaused(FALSE), -	mHasPelvisOffset( FALSE ),  	mRenderUnloadedAvatar(LLCachedControl<bool>(gSavedSettings, "RenderUnloadedAvatar", false)),  	mLastRezzedStatus(-1),  	mIsEditingAppearance(FALSE), @@ -762,10 +761,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())  	{ @@ -1251,17 +1246,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  	{ @@ -3200,6 +3196,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);  	}  	if (gSavedSettings.getBOOL("DebugAvatarCompositeBaked")) @@ -3710,21 +3707,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 ) @@ -3734,15 +3716,6 @@ void LLVOAvatar::postPelvisSetRecalc( void )  	dirtyMesh(2);  }  //------------------------------------------------------------------------ -// setPelvisOffset -//------------------------------------------------------------------------ -void LLVOAvatar::setPelvisOffset( F32 pelvisFixupAmount ) -{		 -	mHasPelvisOffset  = true; -	mLastPelvisFixup  = mPelvisFixup;	 -	mPelvisFixup	  = pelvisFixupAmount;	 -} -//------------------------------------------------------------------------  // updateVisibility()  //------------------------------------------------------------------------  void LLVOAvatar::updateVisibility() @@ -4871,6 +4844,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;  	} @@ -5044,10 +5023,162 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name )  	return jointp;  } + +//----------------------------------------------------------------------------- +// getRiggedMeshID +// +// If viewer object is a rigged mesh, set the mesh id and return true. +// Otherwise, null out the id and return false. +//----------------------------------------------------------------------------- +// 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(); +	}		 +} +  //----------------------------------------------------------------------------- -// resetJointPositionsToDefault +// resetJointPositionsOnDetach  //----------------------------------------------------------------------------- -void LLVOAvatar::resetJointPositionsToDefault( void ) +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(); @@ -5059,23 +5190,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();	  }  //----------------------------------------------------------------------------- @@ -5612,7 +5738,7 @@ const LLViewerJointAttachment *LLVOAvatar::attachObject(LLViewerObject *viewer_o  }  //----------------------------------------------------------------------------- -// attachObject() +// getNumAttachments()  //-----------------------------------------------------------------------------  U32 LLVOAvatar::getNumAttachments() const  { @@ -5722,30 +5848,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() @@ -7647,6 +7761,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" ); @@ -7656,8 +7803,8 @@ 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();  	} +	// File will close when handle goes out of scope  } diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 42ff7bff92..9a2aaf8aa3 100755 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -199,7 +199,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); @@ -356,19 +359,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; @@ -719,6 +714,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; diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 42a7c2e576..0be8df349d 100755 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -262,7 +262,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. @@ -718,13 +718,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); @@ -734,6 +729,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(); @@ -1093,9 +1099,19 @@ LLViewerObject* LLVOAvatarSelf::getWornAttachment(const LLUUID& inv_item_id)  	return NULL;  } -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) @@ -1103,11 +1119,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 @@ -1142,8 +1160,6 @@ BOOL LLVOAvatarSelf::detachObject(LLViewerObject *viewer_object)  	const LLUUID attachment_id = viewer_object->getAttachmentItemID();  	if ( LLVOAvatar::detachObject(viewer_object) )  	{ -		LLVOAvatar::cleanupAttachedMesh( viewer_object ); -		  		// the simulator should automatically handle permission revocation  		stopMotionFromSource(attachment_id); diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index e03de9fa0b..13ffc057b0 100755 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -86,12 +86,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: @@ -293,7 +292,7 @@ public:  	void				addAttachmentRequest(const LLUUID& inv_item_id);  	void				removeAttachmentRequest(const LLUUID& inv_item_id);  	LLViewerObject* 	getWornAttachment(const LLUUID& inv_item_id); -	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); diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp index 9a84cae403..426ca332e4 100755 --- a/indra/newview/llvoicechannel.cpp +++ b/indra/newview/llvoicechannel.cpp @@ -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())  		{ diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 0bf373f478..962cdf0268 100755 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -161,6 +161,13 @@ void LLVoiceClient::userAuthorized(const std::string& user_id, const LLUUID &age  	mVoiceModule->userAuthorized(user_id, agentID);  } +void LLVoiceClient::setHidden(bool hidden) +{ +    if (mVoiceModule) +    { +        mVoiceModule->setHidden(hidden); +    } +}  void LLVoiceClient::terminate()  { diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index 1e20a814a0..fb387301be 100755 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -105,6 +105,8 @@ public:  	virtual void updateSettings()=0; // call after loading settings and whenever they change  	virtual bool isVoiceWorking() const = 0; // connected to a voice server and voice channel +     +    virtual void setHidden(bool hidden)=0;  //  Hides the user from voice.  	virtual const LLVoiceVersionInfo& getVersion()=0; @@ -342,6 +344,7 @@ public:  	void setCaptureDevice(const std::string& name);  	void setRenderDevice(const std::string& name); +    void setHidden(bool hidden);  	const LLVoiceDeviceList& getCaptureDevices();  	const LLVoiceDeviceList& getRenderDevices(); diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index f288a18bca..a6a7a35b03 100755 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -70,6 +70,7 @@  #include "apr_base64.h"  #define USE_SESSION_GROUPS 0 +#define VX_NULL_POSITION -2147483648.0 /*The Silence*/  extern LLMenuBarGL* gMenuBarView;  extern void handle_voice_morphing_subscribe(); @@ -322,6 +323,7 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() :  	mCaptureBufferRecording(false),  	mCaptureBufferRecorded(false),  	mCaptureBufferPlaying(false), +	mShutdownComplete(true),  	mPlayRequestCount(0),  	mAvatarNameCacheConnection() @@ -376,7 +378,16 @@ void LLVivoxVoiceClient::terminate()  	if(mConnected)  	{  		logout(); -		connectorShutdown(); +		connectorShutdown();  +#ifdef LL_WINDOWS +		int count=0; +		while (!mShutdownComplete && 10 > count++) +		{ +			stateMachine(); +			_sleep(1000); +		} + +#endif  		closeSocket();		// Need to do this now -- bad things happen if the destructor does it later.  		cleanUp();  	} @@ -476,10 +487,9 @@ void LLVivoxVoiceClient::connectorCreate()  	std::string savedLogLevel = gSavedSettings.getString("VivoxDebugLevel"); -	if(savedLogLevel != "-0") +	if(savedLogLevel != "0")  	{  		LL_DEBUGS("Voice") << "creating connector with logging enabled" << LL_ENDL; -		loglevel = "0";  	}  	stream  @@ -488,13 +498,14 @@ void LLVivoxVoiceClient::connectorCreate()  		<< "<AccountManagementServer>" << mVoiceAccountServerURI << "</AccountManagementServer>"  		<< "<Mode>Normal</Mode>"  		<< "<Logging>" -			<< "<Folder>" << logpath << "</Folder>" -			<< "<FileNamePrefix>Connector</FileNamePrefix>" -			<< "<FileNameSuffix>.log</FileNameSuffix>" -			<< "<LogLevel>" << loglevel << "</LogLevel>" +        << "<Folder>" << logpath << "</Folder>" +        << "<FileNamePrefix>Connector</FileNamePrefix>" +        << "<FileNameSuffix>.log</FileNameSuffix>" +        << "<LogLevel>" << loglevel << "</LogLevel>"  		<< "</Logging>" -		<< "<Application>SecondLifeViewer.1</Application>" -	<< "</Request>\n\n\n"; +		<< "<Application></Application>"  //Name can cause problems per vivox. +        << "<MaxCalls>12</MaxCalls>" +        << "</Request>\n\n\n";  	writeString(stream.str());  } @@ -512,6 +523,7 @@ void LLVivoxVoiceClient::connectorShutdown()  		<< "</Request>"  		<< "\n\n\n"; +		mShutdownComplete = false;  		mConnectorHandle.clear();  		writeString(stream.str()); @@ -788,15 +800,32 @@ void LLVivoxVoiceClient::stateMachine()  						// vivox executable exists.  Build the command line and launch the daemon.  						LLProcess::Params params;  						params.executable = exe_path; -						// SLIM SDK: these arguments are no longer necessary. -//						std::string args = " -p tcp -h -c"; +  						std::string loglevel = gSavedSettings.getString("VivoxDebugLevel"); +						std::string shutdown_timeout = gSavedSettings.getString("VivoxShutdownTimeout");  						if(loglevel.empty())  						{  							loglevel = "0";	// turn logging off completely  						} +							  						params.args.add("-ll");  						params.args.add(loglevel); + +						std::string log_folder = gSavedSettings.getString("VivoxLogDirectory"); +                         +                        if (log_folder.empty()) +                        { +                            log_folder = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ""); +                        } +                         +						params.args.add("-lf"); +						params.args.add(log_folder); + +						if(!shutdown_timeout.empty()) +						{ +							params.args.add("-st"); +							params.args.add(shutdown_timeout); +						}  						params.cwd = gDirUtilp->getAppRODataDir();  						sGatewayPtr = LLProcess::create(params); @@ -1334,7 +1363,7 @@ void LLVivoxVoiceClient::stateMachine()  				{  					// Connect to a session by URI  					sessionCreateSendMessage(mAudioSession, true, false); -				} +				}    				notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_JOINING);  				setState(stateJoiningSession); @@ -1510,7 +1539,7 @@ void LLVivoxVoiceClient::stateMachine()  			// Always reset the terminate request flag when we get here.  			mSessionTerminateRequested = false; -			if((mVoiceEnabled || !mIsInitialized) && !mRelogRequested) +			if((mVoiceEnabled || !mIsInitialized) && !mRelogRequested  && !LLApp::isExiting())  			{				  				// Just leaving a channel, go back to stateNoChannel (the "logged in but have no channel" state).  				setState(stateNoChannel); @@ -1553,6 +1582,7 @@ void LLVivoxVoiceClient::stateMachine()  		//MARK: stateConnectorStopping  		case stateConnectorStopping:	// waiting for connector stop  			// The handler for the Connector.InitiateShutdown response will transition from here to stateConnectorStopped. +			mShutdownComplete = true;  		break;  		//MARK: stateConnectorStopped @@ -2318,6 +2348,14 @@ static void oldSDKTransform (LLVector3 &left, LLVector3 &up, LLVector3 &at, LLVe  #endif  } +void LLVivoxVoiceClient::setHidden(bool hidden) +{ +    mHidden = hidden; +     +    sendPositionalUpdate(); +    return; +} +  void LLVivoxVoiceClient::sendPositionalUpdate(void)  {	  	std::ostringstream stream; @@ -2339,14 +2377,23 @@ void LLVivoxVoiceClient::sendPositionalUpdate(void)  		l = mAvatarRot.getLeftRow();  		u = mAvatarRot.getUpRow();  		a = mAvatarRot.getFwdRow(); -		pos = mAvatarPosition; + +        pos = mAvatarPosition;  		vel = mAvatarVelocity;  		// SLIM SDK: the old SDK was doing a transform on the passed coordinates that the new one doesn't do anymore.  		// The old transform is replicated by this function.  		oldSDKTransform(l, u, a, pos, vel); +         +        if (mHidden) +        { +            for (int i=0;i<3;++i) +            { +                pos.mdV[i] = VX_NULL_POSITION; +            } +        } -		stream  +		stream  			<< "<Position>"  				<< "<X>" << pos.mdV[VX] << "</X>"  				<< "<Y>" << pos.mdV[VY] << "</Y>" @@ -2406,14 +2453,23 @@ void LLVivoxVoiceClient::sendPositionalUpdate(void)  		l = earRot.getLeftRow();  		u = earRot.getUpRow();  		a = earRot.getFwdRow(); -		pos = earPosition; + +        pos = earPosition;  		vel = earVelocity;  //		LL_DEBUGS("Voice") << "Sending listener position " << earPosition << LL_ENDL;  		oldSDKTransform(l, u, a, pos, vel); -		stream  +        if (mHidden) +        { +            for (int i=0;i<3;++i) +            { +                pos.mdV[i] = VX_NULL_POSITION; +            } +        } +         +		stream  			<< "<Position>"  				<< "<X>" << pos.mdV[VX] << "</X>"  				<< "<Y>" << pos.mdV[VY] << "</Y>" @@ -3169,7 +3225,7 @@ void LLVivoxVoiceClient::mediaStreamUpdatedEvent(  				session->mErrorStatusCode = statusCode;  			break;  		} -		 +  		switch(state)  		{  			case streamStateIdle: @@ -5433,7 +5489,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)  	{  		bool voice_status = LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking(); diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index 5e876fa2ef..a4ec9f2a69 100755 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -723,6 +723,7 @@ private:  	bool mRenderDeviceDirty;  	bool mIsInitialized; +	bool mShutdownComplete;  	bool checkParcelChanged(bool update = false); @@ -747,6 +748,7 @@ private:  	std::string getAudioSessionURI();  	std::string getAudioSessionHandle(); +    void setHidden(bool hidden); //virtual  	void sendPositionalUpdate(void);  	void buildSetCaptureDevice(std::ostringstream &stream); @@ -775,6 +777,7 @@ private:  	bool		mMuteMic;  	bool		mMuteMicDirty; +    bool        mHidden;       //Set to true during teleport to hide the agent's position.  	// Set to true when the friends list is known to have changed.  	bool		mFriendsListDirty; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 703334a6da..18cc6d32a5 100755 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2038,7 +2038,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; @@ -4326,7 +4337,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, @@ -4515,7 +4526,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); @@ -4600,53 +4613,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(); -					}		  					if (pool)  					{ @@ -5004,14 +4976,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  			}  		} - -		 -		 -			 -		 -					 - -		  	}  	group->mBufferUsage = useage; @@ -5650,7 +5614,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, diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index ca60b79f9d..fac0fd63ee 100755 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -364,8 +364,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); diff --git a/indra/newview/skins/default/xui/en/floater_joystick.xml b/indra/newview/skins/default/xui/en/floater_joystick.xml index 259acccb68..3dfdf8e1a5 100755 --- a/indra/newview/skins/default/xui/en/floater_joystick.xml +++ b/indra/newview/skins/default/xui/en/floater_joystick.xml @@ -4,7 +4,7 @@   height="500"   layout="topleft"   name="Joystick" - help_topic="joystick" + help_topic="Viewerhelp:Joystick_Configuration"   title="JOYSTICK CONFIGURATION"   width="569">      <floater.string diff --git a/indra/newview/skins/default/xui/en/floater_openobject.xml b/indra/newview/skins/default/xui/en/floater_openobject.xml index bf6e0c4917..912db80bcc 100755 --- a/indra/newview/skins/default/xui/en/floater_openobject.xml +++ b/indra/newview/skins/default/xui/en/floater_openobject.xml @@ -3,10 +3,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 @@       background_visible="false"       draw_border="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> diff --git a/indra/newview/skins/default/xui/en/floater_pay.xml b/indra/newview/skins/default/xui/en/floater_pay.xml index 41a7134b1d..9d91f801a6 100755 --- a/indra/newview/skins/default/xui/en/floater_pay.xml +++ b/indra/newview/skins/default/xui/en/floater_pay.xml @@ -2,12 +2,12 @@  <floater   legacy_header_height="18"   can_minimize="false" - height="200" + height="186"   layout="topleft"   name="Give Money"   help_topic="give_money"   save_rect="true" - width="250"> + width="261">     <string      name="payee_group">          Pay Group @@ -21,88 +21,129 @@       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" -     layout="topleft" -     left="130" -     max_length_bytes="9" -     name="amount" -     width="80" /> -    <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" +    <panel +     border_thickness="0" +     height="104" +     label="Search"       layout="topleft" +     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" -     name="cancel btn" -     width="100" /> +     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" /> +      <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> diff --git a/indra/newview/skins/default/xui/en/floater_pay_object.xml b/indra/newview/skins/default/xui/en/floater_pay_object.xml index d3a35c2051..f1e27b918e 100755 --- a/indra/newview/skins/default/xui/en/floater_pay_object.xml +++ b/indra/newview/skins/default/xui/en/floater_pay_object.xml @@ -2,12 +2,12 @@  <floater   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 @@ -16,12 +16,25 @@       name="payee_resident">          Pay Resident      </string> +      <text +     type="string" +     length="1"       follows="left|top"       height="16"       layout="topleft"       left="10" -     top_pad="24" +     top="24" +     name="paying_text" +     width="180"> +      You are paying: +    </text> +    <text +     follows="left|top" +     height="16" +     layout="topleft" +     left="10" +     top_pad="5"       name="payee_name"       use_ellipses="true"        width="225"> @@ -40,7 +53,7 @@       width="180">          Via object:      </text> -   <icon +    <icon       height="16"       width="16"       image_name="Inv_Object" @@ -64,78 +77,107 @@       width="188">          My awesome object with a really damn long name      </text> -   <button -     height="23" -     label="L$1" -     label_selected="L$1" -     layout="topleft" -     left="25" -     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="25" -     name="fastpay 10" -     top_pad="8" -     width="80" /> -    <button -     height="23" -     label="L$20" -     label_selected="L$20" +    <panel +     border_thickness="0" +     height="104" +     label="Search"       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" +     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="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> diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index 6fa45d7d66..7099db63ab 100755 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -531,7 +531,7 @@       name="Sound Play">          <menu_item_call.on_click           function="Inventory.DoToSelected" -         parameter="open" /> +         parameter="sound_play" />      </menu_item_call>      <menu_item_separator       layout="topleft" diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index de441983d0..560f81a6fd 100755 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -2105,6 +2105,18 @@                 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"               shortcut="control|shift|9" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index f1d34a1449..ea1bc66236 100755 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -5246,6 +5246,19 @@ Warning: The 'Pay object' click action has been set, but it will only    <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"     type="alertmodal">  There are no items in this object that you are allowed to copy. diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 5dcb8e2cdf..945a77c071 100755 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2307,6 +2307,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> @@ -2433,9 +2434,12 @@ The [[MARKETPLACE_CREATE_STORE_URL] Marketplace store] is returning errors.  	<string name="Stomach">Stomach</string>  	<string name="Left Pec">Left Pec</string>  	<string name="Right Pec">Right Pec</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] old</string> | 
