diff options
Diffstat (limited to 'indra')
57 files changed, 818 insertions, 477 deletions
diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index 6fdf9e2e07..c0ad8315af 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 ); 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..bad9c198ad 100755 --- a/indra/llcharacter/lljoint.cpp +++ b/indra/llcharacter/lljoint.cpp @@ -36,6 +36,20 @@ S32 LLJoint::sNumUpdates = 0; S32 LLJoint::sNumTouches = 0; + +//----------------------------------------------------------------------------- +// LLJoint::AttachmentOverrideRecord::AttachmentOverrideRecord() +//----------------------------------------------------------------------------- +LLJoint::AttachmentOverrideRecord::AttachmentOverrideRecord() +{ +} + +template <class T> +bool attachment_map_iter_compare_name(const T& a, const T& b) +{ + return a.second.name < b.second.name; +} + //----------------------------------------------------------------------------- // LLJoint() // Class Constructor @@ -48,11 +62,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() : @@ -243,42 +254,69 @@ void LLJoint::setPosition( const LLVector3& pos ) touch(MATRIX_DIRTY | POSITION_DIRTY); } - //-------------------------------------------------------------------- -// setPosition() +// addAttachmentPosOverride() //-------------------------------------------------------------------- -void LLJoint::setDefaultFromCurrentXform( void ) -{ - mDefaultXform = mXform; +void LLJoint::addAttachmentPosOverride( const LLVector3& pos, const std::string& attachment_name ) +{ + if (attachment_name.empty()) + { + return; + } + if (m_attachmentOverrides.empty()) + { + LL_DEBUGS("Avatar") << getName() << " saving m_posBeforeOverrides " << getPosition() << LL_ENDL; + m_posBeforeOverrides = getPosition(); + } + AttachmentOverrideRecord rec; + rec.name = attachment_name; + rec.pos = pos; + m_attachmentOverrides[attachment_name] = rec; + LL_DEBUGS("Avatar") << getName() << " addAttachmentPosOverride for " << attachment_name << " pos " << pos << LL_ENDL; + updatePos(); } //-------------------------------------------------------------------- -// storeCurrentXform() +// removeAttachmentPosOverride() //-------------------------------------------------------------------- -void LLJoint::storeCurrentXform( const LLVector3& pos ) -{ - mOldXform = mXform; - mResetAfterRestoreOldXform = true; - setPosition( pos ); - touch(ALL_DIRTY); +void LLJoint::removeAttachmentPosOverride( const std::string& attachment_name ) +{ + if (attachment_name.empty()) + { + return; + } + attachment_map_t::iterator it = m_attachmentOverrides.find(attachment_name); + if (it != m_attachmentOverrides.end()) + { + LL_DEBUGS("Avatar") << getName() << " removeAttachmentPosOverride for " << attachment_name << LL_ENDL; + m_attachmentOverrides.erase(it); + } + updatePos(); } //-------------------------------------------------------------------- -// storeScaleForReset() +// updatePos() //-------------------------------------------------------------------- -void LLJoint::storeScaleForReset( const LLVector3& scale ) +void LLJoint::updatePos() { - mOldXform.setScale( scale ); -} -//-------------------------------------------------------------------- -// restoreOldXform() -//-------------------------------------------------------------------- -void LLJoint::restoreOldXform( void ) -{ - mXform = mDefaultXform; - mResetAfterRestoreOldXform = false; - mDirtyFlags = ALL_DIRTY; + LLVector3 pos; + attachment_map_t::iterator it = std::max_element(m_attachmentOverrides.begin(), + m_attachmentOverrides.end(), + attachment_map_iter_compare_name<LLJoint::attachment_map_t::value_type>); + if (it != m_attachmentOverrides.end()) + { + AttachmentOverrideRecord& rec = it->second; + LL_DEBUGS("Avatar") << getName() << " updatePos, winner of " << m_attachmentOverrides.size() << " is attachment " << rec.name << " pos " << rec.pos << LL_ENDL; + pos = rec.pos; + } + else + { + LL_DEBUGS("Avatar") << getName() << " updatePos, winner is posBeforeOverrides " << m_posBeforeOverrides << LL_ENDL; + pos = m_posBeforeOverrides; + } + setPosition(pos); } + //-------------------------------------------------------------------- // getWorldPosition() //-------------------------------------------------------------------- @@ -325,7 +363,7 @@ void LLJoint::setWorldPosition( const LLVector3& pos ) //-------------------------------------------------------------------- -// mXform.getRotation() +// getRotation() //-------------------------------------------------------------------- const LLQuaternion& LLJoint::getRotation() { @@ -432,7 +470,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 +586,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..0ef054d9c1 100755 --- a/indra/llcharacter/lljoint.h +++ b/indra/llcharacter/lljoint.h @@ -79,8 +79,6 @@ protected: // explicit transformation members LLXformMatrix mXform; - LLXformMatrix mOldXform; - LLXformMatrix mDefaultXform; LLUUID mId; @@ -88,8 +86,6 @@ public: U32 mDirtyFlags; BOOL mUpdateXform; - BOOL mResetAfterRestoreOldXform; - // describes the skin binding pose LLVector3 mSkinOffset; @@ -103,6 +99,18 @@ public: static S32 sNumTouches; static S32 sNumUpdates; + struct AttachmentOverrideRecord + { + AttachmentOverrideRecord(); + LLVector3 pos; + std::string name; + }; + typedef std::map<std::string,AttachmentOverrideRecord> attachment_map_t; + attachment_map_t m_attachmentOverrides; + LLVector3 m_posBeforeOverrides; + + void updatePos(); + public: LLJoint(); LLJoint(S32 joint_num); @@ -160,7 +168,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 +191,14 @@ 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 std::string& attachment_name ); + void removeAttachmentPosOverride( const std::string& attachment_name ); //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/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp index 7c88f8fb9b..6dd6f94d02 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 604dc92789..d3ed4a1286 100755 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -1276,7 +1276,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 ) @@ -3258,6 +3266,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 1bd2bc06f4..303417c337 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/lltextbase.cpp b/indra/llui/lltextbase.cpp index 2d7062e71d..9b125a85b9 100755 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -218,8 +218,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p) mParseHighlights(p.parse_highlights), mBGVisible(p.bg_visible), mScroller(NULL), - mStyleDirty(true), - mDrawRightmostCursor(false) + mStyleDirty(true) { if(p.allow_scroll) { @@ -1505,11 +1504,6 @@ void LLTextBase::reflow() // find and erase line info structs starting at start_index and going to end of document if (!mLineInfoList.empty()) { - if (mDrawRightmostCursor) - { - start_index--; - } - // find first element whose end comes after start_index line_list_t::iterator iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), start_index, line_end_compare()); line_start_index = iter->mDocIndexStart; @@ -1698,11 +1692,6 @@ S32 LLTextBase::getLineNumFromDocIndex( S32 doc_index, bool include_wordwrap) co } else { - if (mDrawRightmostCursor) - { - doc_index--; - } - line_list_t::const_iterator iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), doc_index, line_end_compare()); if (include_wordwrap) { @@ -1731,11 +1720,6 @@ S32 LLTextBase::getLineOffsetFromDocIndex( S32 startpos, bool include_wordwrap) } else { - if (mDrawRightmostCursor) - { - startpos--; - } - line_list_t::const_iterator iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), startpos, line_end_compare()); return startpos - iter->mDocIndexStart; } @@ -2456,7 +2440,7 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, } else if (hit_past_end_of_line && segmentp->getEnd() >= line_iter->mDocIndexEnd) { - if (getLineNumFromDocIndex(line_iter->mDocIndexEnd - 1) == line_iter->mLineNum && !mDrawRightmostCursor) + if (getLineNumFromDocIndex(line_iter->mDocIndexEnd - 1) == line_iter->mLineNum) { // if segment wraps to the next line we should step one char back // to compensate for the space char between words @@ -2489,13 +2473,7 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const // clamp pos to valid values pos = llclamp(pos, 0, mLineInfoList.back().mDocIndexEnd - 1); - S32 corrected_pos = pos; - if (mDrawRightmostCursor && pos > 0) - { - corrected_pos--; - } - - line_list_t::const_iterator line_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), corrected_pos, line_end_compare()); + line_list_t::const_iterator line_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), pos, line_end_compare()); doc_rect.mLeft = line_iter->mRect.mLeft; doc_rect.mBottom = line_iter->mRect.mBottom; @@ -2670,6 +2648,12 @@ void LLTextBase::changeLine( S32 delta ) LLRect visible_region = getVisibleDocumentRect(); S32 new_cursor_pos = getDocIndexFromLocalCoord(mDesiredXPixel, mLineInfoList[new_line].mRect.mBottom + mVisibleTextRect.mBottom - visible_region.mBottom, TRUE); + S32 actual_line = getLineNumFromDocIndex(new_cursor_pos); + if (actual_line != new_line) + { + // line edge, correcting position by 1 to move onto proper line + new_cursor_pos += new_line - actual_line; + } setCursorPos(new_cursor_pos, true); } } diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 9c3bc3ed98..738b4d5b8e 100755 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -618,7 +618,6 @@ protected: // cursor S32 mCursorPos; // I-beam is just after the mCursorPos-th character. - bool mDrawRightmostCursor; // When cursor is on the rightmost position on the line S32 mDesiredXPixel; // X pixel position where the user wants the cursor to be LLFrameTimer mCursorBlinkTimer; // timer that controls cursor blinking diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 9219490bf2..cf5fdef539 100755 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -1124,13 +1124,6 @@ void LLTextEditor::addChar(llwchar wc) setCursorPos(new_cursor_pos); } } - - if (mCursorPos > 0) - { - LLRect current_cursor_rect = getDocRectFromDocIndex(mCursorPos); - LLRect prev_cursor_rect = getDocRectFromDocIndex(mCursorPos - 1); - mDrawRightmostCursor = current_cursor_rect.mBottom < prev_cursor_rect.mBottom; - } } void LLTextEditor::addLineBreakChar(BOOL group_together) @@ -1277,12 +1270,6 @@ BOOL LLTextEditor::handleNavigationKey(const KEY key, const MASK mask) break; case KEY_HOME: - if(mDrawRightmostCursor && mCursorPos > 0) - { - mCursorPos--; - mDrawRightmostCursor = false; - } - startOfLine(); break; @@ -1297,23 +1284,6 @@ BOOL LLTextEditor::handleNavigationKey(const KEY key, const MASK mask) case KEY_END: endOfLine(); - { - S32 last_line_index = mLineInfoList.size() - 1; - if (getLineNumFromDocIndex(mCursorPos, true) < last_line_index) - { - mDrawRightmostCursor = true; - setCursorPos(mCursorPos + 1); - } - else if (last_line_index > 0) // only for two and more lines - { - S32 prev_line_width = mLineInfoList[last_line_index - 1].mRect.getWidth(); - S32 last_line_width = mLineInfoList[last_line_index].mRect.getWidth(); - if (prev_line_width <= last_line_width) - { - mDrawRightmostCursor = true; - } - } - } break; case KEY_LEFT: @@ -1325,18 +1295,7 @@ BOOL LLTextEditor::handleNavigationKey(const KEY key, const MASK mask) { if( 0 < mCursorPos ) { - LLRect current_cursor_rect = getDocRectFromDocIndex(mCursorPos); - LLRect next_cursor_rect = getDocRectFromDocIndex(mCursorPos - 1); - - if (current_cursor_rect.mBottom < next_cursor_rect.mBottom) - { - mDrawRightmostCursor = true; - } - else - { - mDrawRightmostCursor = false; - setCursorPos(mCursorPos - 1); - } + setCursorPos(mCursorPos - 1); } else { @@ -1354,26 +1313,7 @@ BOOL LLTextEditor::handleNavigationKey(const KEY key, const MASK mask) { if( mCursorPos < getLength() ) { - LLRect current_cursor_rect = getDocRectFromDocIndex(mCursorPos); - LLRect next_cursor_rect = getDocRectFromDocIndex(mCursorPos + 1); - - if (current_cursor_rect.mBottom > next_cursor_rect.mBottom) - { - if (mDrawRightmostCursor) - { - mDrawRightmostCursor = false; - } - else - { - mDrawRightmostCursor = true; - setCursorPos(mCursorPos + 1); - } - } - else - { - mDrawRightmostCursor = false; - setCursorPos(mCursorPos + 1); - } + setCursorPos(mCursorPos + 1); } else { diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 6f3122e7a1..be583c83d8 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/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm index f7031341eb..1bb93d05d6 100644 --- a/indra/llwindow/llopenglview-objc.mm +++ b/indra/llwindow/llopenglview-objc.mm @@ -349,9 +349,14 @@ attributedStringInfo getSegments(NSAttributedString *str) callMiddleMouseUp(mMousePos, mModifiers); } +- (void) rightMouseDragged:(NSEvent *)theEvent +{ + [self mouseDragged:theEvent]; +} + - (void) otherMouseDragged:(NSEvent *)theEvent { - + [self mouseDragged:theEvent]; } - (void) scrollWheel:(NSEvent *)theEvent diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index e5a90e8a28..ef1d528aa2 100755 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -4116,8 +4116,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..3928bbadc8 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++; } diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 29534a4382..e35cf011c7 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -4056,17 +4056,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/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/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 b17ce97a2e..195a7f5ffe 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -1935,7 +1935,7 @@ bool LLModelLoader::doLoadModel() LLJoint* pJoint = mPreview->getPreviewAvatar()->getJoint( lookingForJoint ); if ( pJoint ) { - pJoint->storeCurrentXform( jointTransform.getTranslation() ); + pJoint->addAttachmentPosOverride( jointTransform.getTranslation(), mFilename); } else { 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 f0c010b545..a4d13ce1d5 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,14 +116,12 @@ protected: LLGiveMoneyInfo* mQuickPayInfo[MAX_PAY_BUTTONS]; LLSafeHandle<LLObjectSelection> mObjectSelection; - - static S32 sLastAmount; }; -S32 LLFloaterPay::sLastAmount = 0; const S32 MAX_AMOUNT_LENGTH = 10; const S32 FASTPAY_BUTTON_WIDTH = 80; +const S32 PAY_AMOUNT_NOTIFICATION = 200; LLFloaterPay::LLFloaterPay(const LLSD& key) : LLFloater(key), @@ -188,17 +191,9 @@ BOOL LLFloaterPay::postBuild() getChildView("amount text")->setVisible(FALSE); - - std::string last_amount; - if(sLastAmount > 0) - { - last_amount = llformat("%d", sLastAmount); - } - getChildView("amount")->setVisible(FALSE); getChild<LLLineEditor>("amount")->setKeystrokeCallback(&LLFloaterPay::onKeystroke, this); - getChild<LLUICtrl>("amount")->setValue(last_amount); getChild<LLLineEditor>("amount")->setPrevalidate(LLTextValidate::validateNonNegativeS32); info = new LLGiveMoneyInfo(this, 0); @@ -207,7 +202,7 @@ BOOL LLFloaterPay::postBuild() childSetAction("pay btn",&LLFloaterPay::onGive,info); setDefaultBtn("pay btn"); getChildView("pay btn")->setVisible(FALSE); - getChildView("pay btn")->setEnabled((sLastAmount > 0)); + getChildView("pay btn")->setEnabled(FALSE); childSetAction("cancel btn",&LLFloaterPay::onCancel,this); @@ -419,7 +414,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; @@ -470,10 +482,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(); + } } } @@ -487,7 +529,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..085986dc68 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 | // +=================================================+ @@ -6138,7 +6156,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 833fbbadbb..e8d5db4437 100755 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -389,6 +389,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 f211acedf0..dc8b15a5bf 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 e3be1312e4..02e05d3d9a 100755 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -1848,6 +1848,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 a7c9dbdf7b..eb037577be 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 8eea5ea73e..a41986373e 100755 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -663,12 +663,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; @@ -679,7 +680,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; } @@ -708,6 +710,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/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index c12753acb0..a426669b5e 100755 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -118,7 +118,7 @@ public: /*virtual*/ void onClose(bool app_settings); // New functions - void setImageID( const LLUUID& image_asset_id); + void setImageID( const LLUUID& image_asset_id, bool set_selection = true); void updateImageStats(); const LLUUID& getAssetID() { return mImageAssetID; } const LLUUID& findItemID(const LLUUID& asset_id, BOOL copyable_only); @@ -232,7 +232,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) { @@ -253,6 +253,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); } } @@ -461,7 +465,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"); @@ -820,7 +827,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 575e5c5c52..8561d265de 100755 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -2173,23 +2173,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/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index b0f4802e20..a4a05587d3 100755 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -88,18 +88,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 && @@ -218,7 +225,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 ) ); } @@ -241,7 +253,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..97cefaf33c 100755 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -6193,6 +6193,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..22ac4ce0db 100755 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -170,6 +170,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 22b979aa09..904d08ac73 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -4884,6 +4884,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; } @@ -5058,9 +5064,9 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name ) return jointp; } //----------------------------------------------------------------------------- -// resetJointPositionsToDefault +// resetJointPositionsOnDetach //----------------------------------------------------------------------------- -void LLVOAvatar::resetJointPositionsToDefault( void ) +void LLVOAvatar::resetJointPositionsOnDetach(const std::string& attachment_name) { //Subsequent joints are relative to pelvis avatar_joint_list_t::iterator iter = mSkeleton.begin(); @@ -5072,17 +5078,16 @@ void LLVOAvatar::resetJointPositionsToDefault( void ) { LLJoint* pJoint = (*iter); //Reset joints except for pelvis - if ( pJoint && pJoint != pJointPelvis && pJoint->doesJointNeedToBeReset() ) + if ( pJoint && pJoint != pJointPelvis) { pJoint->setId( LLUUID::null ); - pJoint->restoreOldXform(); + pJoint->removeAttachmentPosOverride(attachment_name); } else - if ( pJoint && pJoint == pJointPelvis && pJoint->doesJointNeedToBeReset() ) + if ( pJoint && pJoint == pJointPelvis) { pJoint->setId( LLUUID::null ); pJoint->setPosition( LLVector3( 0.0f, 0.0f, 0.0f) ); - pJoint->setJointResetFlag( false ); } } @@ -5625,7 +5630,7 @@ const LLViewerJointAttachment *LLVOAvatar::attachObject(LLViewerObject *viewer_o } //----------------------------------------------------------------------------- -// attachObject() +// getNumAttachments() //----------------------------------------------------------------------------- U32 LLVOAvatar::getNumAttachments() const { @@ -5746,7 +5751,8 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO ) && pSkinData->mJointNames.size() > JOINT_COUNT_REQUIRED_FOR_FULLRIG // full rig && pSkinData->mAlternateBindMatrix.size() > 0 ) { - LLVOAvatar::resetJointPositionsToDefault(); + const std::string& attachment_name = pVO->getAttachmentItemName(); + LLVOAvatar::resetJointPositionsOnDetach(attachment_name); //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() ) @@ -7676,6 +7682,17 @@ 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]); + } + apr_file_printf( file, "\t</archetype>\n" ); apr_file_printf( file, "\n</linden_genepool>\n" ); diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 42ff7bff92..66a357ff62 100755 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -199,7 +199,7 @@ public: virtual LLJoint* getJoint(const std::string &name); - void resetJointPositionsToDefault( void ); + void resetJointPositionsOnDetach(const std::string& attachment_name); /*virtual*/ const LLUUID& getID() const; /*virtual*/ void addDebugText(const std::string& text); 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/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 54b4119331..2f3cd4d24c 100755 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -3169,7 +3169,7 @@ void LLVivoxVoiceClient::mediaStreamUpdatedEvent( session->mErrorStatusCode = statusCode; break; } - + switch(state) { case streamStateIdle: @@ -5433,7 +5433,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/llvovolume.cpp b/indra/newview/llvovolume.cpp index a83e2e020e..9d16ce5a7b 100755 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2040,7 +2040,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; @@ -4328,7 +4339,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, @@ -4626,7 +4637,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation(); //Set the joint position - pJoint->storeCurrentXform( jointPos ); + const std::string& attachment_name = drawablep->getVObj()->getAttachmentItemName(); + pJoint->addAttachmentPosOverride( jointPos, attachment_name ); //If joint is a pelvis then handle old/new pelvis to foot values if ( lookingForJoint == "mPelvis" ) @@ -5652,7 +5664,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/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..a130439baa 100755 --- a/indra/newview/skins/default/xui/en/floater_openobject.xml +++ b/indra/newview/skins/default/xui/en/floater_openobject.xml @@ -6,7 +6,7 @@ height="350" layout="topleft" min_height="160" - min_width="280" + min_width="285" name="objectcontents" help_topic="objectcontents" save_rect="true" @@ -31,36 +31,63 @@ background_visible="false" draw_border="false" follows="all" - height="276" + height="250" layout="topleft" left="10" name="object_contents" top_pad="0" width="284" /> + + <button + follows="bottom|left" + height="23" + label="Copy and add to outfit" + label_selected="Copy and add to outfit" + layout="topleft" + left="15" + name="copy_and_wear_button" + top_pad="5" + 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"> + 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..570ecf241e 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" + 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. |